Skip to content

Commit a5c2f59

Browse files
authored
Merge pull request #372 from sherlock-protocol/feat/scoping-v2
feat: scoping v2
2 parents 3db223a + c518a58 commit a5c2f59

File tree

15 files changed

+471
-219
lines changed

15 files changed

+471
-219
lines changed

src/components/Text/Text.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
color: red;
88
}
99

10+
&.info {
11+
color: #ffa837;
12+
}
13+
14+
&.success {
15+
color: #58c322;
16+
}
17+
1018
&.strong {
1119
font-weight: 700;
1220
}

src/components/Text/Text.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import styles from "./Text.module.scss"
55

66
type TextSize = "tiny" | "small" | "normal" | "large" | "extra-large"
77

8-
type TextVariant = "normal" | "primary" | "secondary" | "alternate" | "mono" | "warning"
8+
type TextVariant = "normal" | "primary" | "secondary" | "alternate" | "mono" | "warning" | "success" | "info"
99

1010
type TextAlignment = "center" | "left" | "right" | "justify"
1111

src/hooks/api/admin/useAdminContestScope.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ type AdminContestScopeResponse = {
88
repo_name: string
99
branch_name: string
1010
commit_hash: string
11-
files: string[]
11+
files: {
12+
file_path: string
13+
nsloc?: number
14+
selected: boolean
15+
}[]
1216
solidity_metrics_report: string
1317
nsloc: number
1418
comment_to_source_ratio: number
@@ -17,14 +21,18 @@ type AdminContestScopeResponse = {
1721

1822
export const adminContestScopeQuery = (contestID: number) => ["admin-contest-scope", contestID]
1923
export const useAdminContestScope = (contestID: number) =>
20-
useQuery<Scope, Error>(adminContestScopeQuery(contestID), async () => {
24+
useQuery<Scope[], Error>(adminContestScopeQuery(contestID), async () => {
2125
const { data } = await contestsAPI.get<AdminContestScopeResponse>(getAdminContestScopeUrl(contestID))
2226

2327
return data.scope.map((d) => ({
2428
repoName: d.repo_name,
2529
branchName: d.branch_name,
2630
commitHash: d.commit_hash,
27-
files: d.files,
31+
files: d.files.map((f) => ({
32+
filePath: f.file_path,
33+
nSLOC: f.nsloc,
34+
selected: f.selected,
35+
})),
2836
solidityMetricsReport: d.solidity_metrics_report,
2937
nSLOC: d.nsloc,
3038
commentToSourceRatio: d.comment_to_source_ratio,

src/hooks/api/scope/useDeleteScope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const useDeleteScope = () => {
3636

3737
const previousScope = queryClient.getQueryData<Scope>(scopeQueryKey(params.protocolDashboardID))
3838

39-
queryClient.setQueryData<Scope | undefined>(scopeQueryKey(params.protocolDashboardID), (previous) =>
39+
queryClient.setQueryData<Scope[] | undefined>(scopeQueryKey(params.protocolDashboardID), (previous) =>
4040
previous?.filter((s) => s.repoName !== params.repoName)
4141
)
4242

src/hooks/api/scope/useRepositoryContracts.ts

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,104 @@ import { getRepositoryContracts as getRepositoryContractsUrl } from "../urls"
44

55
type GetRepositoryContractsResponse = string[]
66

7-
export type TreeValue = Tree | string
8-
export interface Tree extends Map<string, TreeValue> {}
9-
10-
export const getAllTreePaths = (parentPath: string, tree: TreeValue) => {
11-
if (typeof tree === "string") {
12-
return [`${parentPath}`]
13-
}
7+
type File = {
8+
filepath: string
9+
nsloc?: number
10+
}
1411

15-
let paths: string[] = []
12+
interface BaseEntry {
13+
name: string
14+
}
1615

17-
tree.forEach((value, key) => {
18-
paths = [...paths, ...getAllTreePaths(`${parentPath}/${key}`, value)]
19-
})
16+
export interface FileEntry extends BaseEntry {
17+
type: "file"
18+
filepath: string
19+
nsloc?: number
20+
}
2021

21-
return paths
22+
interface DirectoryEntry extends BaseEntry {
23+
type: "directory"
24+
entries: Array<Entry>
2225
}
2326

24-
type Files = {
25-
tree: Tree
26-
rawPaths: string[]
27+
export type Entry = FileEntry | DirectoryEntry
28+
29+
type AnyEntry = RootDirectory | DirectoryEntry
30+
31+
export interface RootDirectory {
32+
type: "root"
33+
entries: Array<Entry>
2734
}
2835

29-
export const convertToTree = (paths: string[]) => {
30-
const tree: Tree = new Map()
36+
export const convertToTree2 = (files: File[]) => {
37+
const root: RootDirectory = {
38+
type: "root",
39+
entries: [],
40+
}
41+
42+
files.forEach(({ filepath, nsloc }) => {
43+
const parts = filepath.split("/")
44+
45+
let current: AnyEntry = root
3146

32-
paths.forEach((d) => {
33-
const parts = d.split("/")
34-
let current: Tree = tree
3547
parts.forEach((p) => {
3648
if (p.endsWith(".sol") || p.endsWith(".vy")) {
37-
current.set(p, p)
49+
current.entries.push({
50+
type: "file",
51+
name: p,
52+
filepath,
53+
nsloc,
54+
})
3855
} else {
39-
if (!current.get(p)) current.set(p, new Map())
40-
current = current.get(p) as Tree
56+
let directory: DirectoryEntry | undefined = current.entries.find(
57+
(e) => e.type === "directory" && e.name === p
58+
) as DirectoryEntry
59+
60+
if (!directory) {
61+
directory = {
62+
type: "directory",
63+
name: p,
64+
entries: [],
65+
}
66+
current.entries.push(directory)
67+
}
68+
69+
current = directory
4170
}
4271
})
4372
})
4473

45-
return tree
74+
return root
75+
}
76+
77+
export type TreeValue = Tree | string
78+
export interface Tree extends Map<string, TreeValue> {}
79+
80+
export const getAllTreePaths = (parentPath: string, tree: Entry) => {
81+
if (tree.type === "file") {
82+
return [`${parentPath}`]
83+
}
84+
85+
let paths: string[] = []
86+
87+
tree.entries.forEach((value, key) => {
88+
paths = [...paths, ...getAllTreePaths(`${parentPath}/${value.name}`, value)]
89+
})
90+
91+
return paths
92+
}
93+
94+
type RepositoryContracts = {
95+
tree: RootDirectory
96+
rawPaths: string[]
4697
}
4798

4899
export const repositoryContractsQuery = (repo: string, commit: string) => ["repository-contracts", repo, commit]
49100
export const useRepositoryContracts = (repo: string, commit: string) =>
50-
useQuery<Files, Error>(repositoryContractsQuery(repo, commit), async () => {
101+
useQuery<RepositoryContracts, Error>(repositoryContractsQuery(repo, commit), async () => {
51102
const { data } = await contestsAPI.get<GetRepositoryContractsResponse>(getRepositoryContractsUrl(repo, commit))
52103

53-
const tree = convertToTree(data)
104+
const tree = convertToTree2(data.map((f) => ({ filepath: f })))
54105

55106
return {
56107
tree,

src/hooks/api/scope/useScope.ts

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,56 @@ export type Scope = {
66
repoName: string
77
branchName: string
88
commitHash: string
9-
files: string[]
9+
files: {
10+
filePath: string
11+
nSLOC?: number
12+
selected: boolean
13+
}[]
1014
solidityMetricsReport?: string
11-
nSLOC?: number
1215
commentToSourceRatio?: number
13-
}[]
16+
initialScope?: Scope
17+
}
1418

15-
export type GetScopeResponse = {
16-
scope: {
17-
repo_name: string
18-
branch_name: string
19-
commit_hash: string
20-
files: string[]
19+
type ScopeResponse = {
20+
repo_name: string
21+
branch_name: string
22+
commit_hash: string
23+
files: {
24+
file_path: string
2125
nsloc?: number
22-
comment_to_source_ratio?: number
26+
selected: boolean
2327
}[]
28+
comment_to_source_ratio?: number
29+
initial_scope?: Omit<ScopeResponse, "initial_scope">
30+
}
31+
32+
export type GetScopeResponse = {
33+
scope: ScopeResponse[]
34+
}
35+
36+
function parseScope(d: ScopeResponse): Scope {
37+
return {
38+
repoName: d.repo_name,
39+
branchName: d.branch_name,
40+
commitHash: d.commit_hash,
41+
files: d.files.map((f) => ({
42+
filePath: f.file_path,
43+
nSLOC: f.nsloc,
44+
selected: f.selected,
45+
})),
46+
commentToSourceRatio: d.comment_to_source_ratio,
47+
initialScope: d.initial_scope ? parseScope(d.initial_scope) : undefined,
48+
}
2449
}
2550

2651
export const scopeQueryKey = (dashboardID?: string) => ["scope", dashboardID]
2752
export const useScope = (dashboardID?: string) =>
28-
useQuery<Scope, Error>(
53+
useQuery<Scope[], Error>(
2954
scopeQueryKey(dashboardID),
3055
async () => {
3156
const { data } = await contestsAPI.get<GetScopeResponse>(getScopeUrl(dashboardID ?? ""))
3257

33-
return data.scope.map((d) => ({
34-
repoName: d.repo_name,
35-
branchName: d.branch_name,
36-
commitHash: d.commit_hash,
37-
files: d.files,
38-
nSLOC: d.nsloc,
39-
commentToSourceRatio: d.comment_to_source_ratio,
40-
}))
58+
return data.scope.map(parseScope)
4159
},
4260
{
4361
enabled: !!dashboardID,

src/hooks/api/scope/useUpdateScope.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type UpdateScopeParams = {
1414
}
1515

1616
type UpdateScopeContext = {
17-
previousScope?: Scope
17+
previousScope?: Scope[]
1818
}
1919

2020
export const useUpdateScope = () => {
@@ -38,11 +38,9 @@ export const useUpdateScope = () => {
3838
},
3939
{
4040
onMutate: async (params) => {
41-
await queryClient.invalidateQueries(scopeQueryKey(params.protocolDashboardID))
41+
const previousScope = queryClient.getQueryData<Scope[]>(scopeQueryKey(params.protocolDashboardID))
4242

43-
const previousScope = queryClient.getQueryData<Scope>(scopeQueryKey(params.protocolDashboardID))
44-
45-
queryClient.setQueryData<Scope | undefined>(scopeQueryKey(params.protocolDashboardID), (previous) => {
43+
queryClient.setQueryData<Scope[] | undefined>(scopeQueryKey(params.protocolDashboardID), (previous) => {
4644
if (!previous) return
4745

4846
const scopeIndex = previous.findIndex((s) => s.repoName === params.repoName)
@@ -54,7 +52,13 @@ export const useUpdateScope = () => {
5452
repoName: previous[scopeIndex].repoName,
5553
branchName: params.branchName ?? previous[scopeIndex].branchName,
5654
commitHash: params.commitHash ?? previous[scopeIndex].commitHash,
57-
files: params.files ?? previous[scopeIndex].files,
55+
files: params.files
56+
? previous[scopeIndex].files.map((f) => ({
57+
...f,
58+
selected: params.files!.includes(f.filePath),
59+
}))
60+
: previous[scopeIndex].files,
61+
initialScope: previous[scopeIndex].initialScope,
5862
},
5963
...previous.slice(scopeIndex + 1),
6064
]

src/pages/AuditScope/AuditScope.module.scss

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
opacity: 1;
7878
}
7979
}
80+
81+
.addedNSLOC {
82+
color: #58c322;
83+
font-weight: bold;
84+
}
8085
}
8186
}
8287
}
@@ -104,3 +109,20 @@
104109
}
105110
}
106111
}
112+
113+
.nslocDiff {
114+
color: #ffa837 !important;
115+
}
116+
117+
.fileAdded {
118+
color: #91e467 !important;
119+
}
120+
121+
.fileRemoved {
122+
color: #ef3131 !important;
123+
opacity: 1 !important;
124+
}
125+
126+
.fileSame {
127+
color: $primary-purple !important;
128+
}

0 commit comments

Comments
 (0)