Skip to content

Commit cb88d95

Browse files
authored
refactor: move branch rules to new page (#1949)
* feat: new page for repo-rules * chore: cleanup * feat: handle emtpy rule state, handle create rule navigate * fix: tsc * fix: tsc again * fix: lint * fix: lint
1 parent 8c57817 commit cb88d95

File tree

12 files changed

+236
-172
lines changed

12 files changed

+236
-172
lines changed

apps/design-system/src/subjects/views/repo-general-settings/repo-general-settings.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,12 @@ const loadingStates = {
1717
const DummyComponent = () => null
1818

1919
export const RepoGeneralSettings = () => {
20-
const [rulesSearchQuery, setRulesSearchQuery] = useState('')
2120
const [isRulesAlertDeleteDialogOpen, setIsRulesAlertDeleteDialogOpen] = useState(false)
2221
const [isRepoAlertDeleteDialogOpen, setRepoAlertDeleteDialogOpen] = useState(false)
23-
const [alertDeleteParams, setAlertDeleteParams] = useState('')
22+
const [alertDeleteParams] = useState('')
2423
const [apiError, _setApiError] = useState<{ type: ErrorTypes; message: string } | null>(null)
2524

2625
const closeRulesAlertDeleteDialog = () => setIsRulesAlertDeleteDialogOpen(false)
27-
const openRulesAlertDeleteDialog = (identifier: string) => {
28-
setAlertDeleteParams(identifier)
29-
setIsRulesAlertDeleteDialogOpen(true)
30-
}
3126

3227
const closeRepoAlertDeleteDialog = () => setRepoAlertDeleteDialogOpen(false)
3328
const openRepoAlertDeleteDialog = () => setRepoAlertDeleteDialogOpen(true)
@@ -41,11 +36,7 @@ export const RepoGeneralSettings = () => {
4136
loadingStates={loadingStates}
4237
isRepoUpdateSuccess={false}
4338
useRepoRulesStore={useRepoRulesStore}
44-
handleRuleClick={() => {}}
45-
openRulesAlertDeleteDialog={openRulesAlertDeleteDialog}
4639
openRepoAlertDeleteDialog={openRepoAlertDeleteDialog}
47-
rulesSearchQuery={rulesSearchQuery}
48-
setRulesSearchQuery={setRulesSearchQuery}
4940
branchSelectorRenderer={DummyComponent}
5041
/>
5142

apps/gitness/src/framework/routing/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ export enum RouteConstants {
8686
toRepoWebhookCreate = 'toRepoWebhookCreate',
8787
toImportProject = 'toImportProject',
8888
toRepoFileDetails = 'toRepoFileDetails',
89-
toRepoTags = 'toRepoTags'
89+
toRepoTags = 'toRepoTags',
90+
toRepoBranchRuleCreate = 'toRepoBranchRuleCreate'
9091
}
9192

9293
export interface RouteEntry {

apps/gitness/src/pages-v2/repo/repo-branch-rules-container.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const RepoBranchSettingsRulesPageContainer = () => {
8282
{
8383
onSuccess: () => {
8484
setIsSubmitSuccess(true)
85-
navigate(routes.toRepoGeneralSettings({ spaceId, repoId: repoName }))
85+
navigate(routes.toRepoBranchRules({ spaceId, repoId: repoName }))
8686
}
8787
}
8888
)
@@ -106,7 +106,7 @@ export const RepoBranchSettingsRulesPageContainer = () => {
106106
{
107107
onSuccess: () => {
108108
setIsSubmitSuccess(true)
109-
navigate(routes.toRepoGeneralSettings({ spaceId, repoId: repoName }))
109+
navigate(routes.toRepoBranchRules({ spaceId, repoId: repoName }))
110110
}
111111
}
112112
)

apps/gitness/src/pages-v2/repo/repo-settings-general-container.tsx

Lines changed: 3 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@ import {
77
DeleteRepositoryErrorResponse,
88
FindRepositoryErrorResponse,
99
FindSecuritySettingsErrorResponse,
10-
RepoRuleDeleteErrorResponse,
11-
RepoRuleListErrorResponse,
1210
UpdateDefaultBranchErrorResponse,
1311
UpdatePublicAccessErrorResponse,
1412
UpdateRepositoryErrorResponse,
1513
UpdateSecuritySettingsErrorResponse,
1614
useDeleteRepositoryMutation,
1715
useFindRepositoryQuery,
1816
useFindSecuritySettingsQuery,
19-
useRepoRuleDeleteMutation,
20-
useRepoRuleListQuery,
2117
useUpdateDefaultBranchMutation,
2218
useUpdatePublicAccessMutation,
2319
useUpdateRepositoryMutation,
@@ -29,34 +25,23 @@ import { AccessLevel, ErrorTypes, RepoSettingsGeneralPage, RepoUpdateData, Secur
2925

3026
import { BranchSelectorContainer } from '../../components-v2/branch-selector-container'
3127
import { useRoutes } from '../../framework/context/NavigationContext'
32-
import { useGetRepoId } from '../../framework/hooks/useGetRepoId'
3328
import { useGetRepoRef } from '../../framework/hooks/useGetRepoPath'
3429
import { PathParams } from '../../RouteDefinitions'
3530
import { useRepoRulesStore } from './stores/repo-settings-store'
3631

3732
export const RepoSettingsGeneralPageContainer = () => {
3833
const routes = useRoutes()
3934
const repoRef = useGetRepoRef()
40-
const repoName = useGetRepoId()
4135
const navigate = useNavigate()
4236
const { spaceId } = useParams<PathParams>()
4337
const queryClient = useQueryClient()
44-
const { setRepoData, setRules, setSecurityScanning } = useRepoRulesStore()
45-
const [rulesSearchQuery, setRulesSearchQuery] = useState('')
38+
const { setRepoData, setSecurityScanning } = useRepoRulesStore()
4639
const [apiError, setApiError] = useState<{ type: ErrorTypes; message: string } | null>(null)
47-
const [isRuleAlertDeleteDialogOpen, setRuleIsAlertDeleteDialogOpen] = useState(false)
4840
const [isRepoAlertDeleteDialogOpen, setRepoIsAlertDeleteDialogOpen] = useState(false)
49-
const [alertDeleteParams, setAlertDeleteParams] = useState('')
5041

5142
const closeAlertDeleteDialog = () => {
52-
isRuleAlertDeleteDialogOpen && setRuleIsAlertDeleteDialogOpen(false)
5343
isRepoAlertDeleteDialogOpen && setRepoIsAlertDeleteDialogOpen(false)
5444
}
55-
const openRulesAlertDeleteDialog = (identifier: string) => {
56-
setAlertDeleteParams(identifier)
57-
setRuleIsAlertDeleteDialogOpen(true)
58-
}
59-
6045
const openRepoAlertDeleteDialog = () => setRepoIsAlertDeleteDialogOpen(true)
6146

6247
const { data: { body: repoData } = {}, isLoading: isLoadingRepoData } = useFindRepositoryQuery(
@@ -69,20 +54,6 @@ export const RepoSettingsGeneralPageContainer = () => {
6954
}
7055
)
7156

72-
const {
73-
data: { body: rulesData } = {},
74-
refetch: refetchRulesList,
75-
isLoading: isRulesLoading
76-
} = useRepoRuleListQuery(
77-
{ repo_ref: repoRef, queryParams: { query: rulesSearchQuery } },
78-
{
79-
onError: (error: RepoRuleListErrorResponse) => {
80-
const message = error.message || 'Error fetching rules'
81-
setApiError({ type: ErrorTypes.FETCH_RULES, message })
82-
}
83-
}
84-
)
85-
8657
const {
8758
mutateAsync: updateDescription,
8859
isLoading: updatingDescription,
@@ -103,24 +74,6 @@ export const RepoSettingsGeneralPageContainer = () => {
10374
}
10475
)
10576

106-
const { mutate: deleteRule, isLoading: isDeletingRule } = useRepoRuleDeleteMutation(
107-
{ repo_ref: repoRef },
108-
{
109-
onSuccess: () => {
110-
refetchRulesList()
111-
setRepoIsAlertDeleteDialogOpen(false)
112-
setApiError(null)
113-
},
114-
onError: (error: RepoRuleDeleteErrorResponse) => {
115-
// Invalidate queries to refetch data from server
116-
queryClient.invalidateQueries(['ruleList', repoRef])
117-
118-
const message = error.message || 'Error deleting rule'
119-
setApiError({ type: ErrorTypes.DELETE_RULE, message })
120-
}
121-
}
122-
)
123-
12477
const {
12578
mutateAsync: updateBranch,
12679
isLoading: updatingBranch,
@@ -226,32 +179,15 @@ export const RepoSettingsGeneralPageContainer = () => {
226179
setApiError(null)
227180
}, [repoData?.default_branch, repoData, setRepoData])
228181

229-
useEffect(() => {
230-
if (rulesData) {
231-
setRules(rulesData)
232-
setApiError(null)
233-
}
234-
}, [rulesData, setRules])
235-
236182
const handleUpdateSecuritySettings = (data: SecurityScanning) => {
237183
updateSecuritySettings({ body: { secret_scanning_enabled: data.secretScanning } })
238184
}
239185

240-
const handleRuleClick = (identifier: string) => {
241-
navigate(routes.toRepoBranchRule({ spaceId, repoId: repoName, identifier }))
242-
}
243-
244-
const handleDeleteRule = (identifier: string) => {
245-
deleteRule({ rule_identifier: identifier })
246-
navigate(routes.toRepoBranchRules({ spaceId, repoId: repoName, identifier }))
247-
}
248-
249186
const loadingStates = {
250187
isLoadingRepoData: isLoadingRepoData || isLoadingSecuritySettings,
251188
isUpdatingRepoData: updatingPublicAccess || updatingDescription || updatingBranch,
252189
isLoadingSecuritySettings,
253-
isUpdatingSecuritySettings,
254-
isRulesLoading
190+
isUpdatingSecuritySettings
255191
}
256192

257193
return (
@@ -263,27 +199,13 @@ export const RepoSettingsGeneralPageContainer = () => {
263199
loadingStates={loadingStates}
264200
isRepoUpdateSuccess={updatePublicAccessSuccess || updateDescriptionSuccess || updateBranchSuccess}
265201
useRepoRulesStore={useRepoRulesStore}
266-
handleRuleClick={handleRuleClick}
267-
openRulesAlertDeleteDialog={openRulesAlertDeleteDialog}
268202
openRepoAlertDeleteDialog={openRepoAlertDeleteDialog}
269-
rulesSearchQuery={rulesSearchQuery}
270-
setRulesSearchQuery={setRulesSearchQuery}
271203
branchSelectorRenderer={BranchSelectorContainer}
272204
/>
273205

274206
<DeleteAlertDialog
275-
open={isRuleAlertDeleteDialogOpen || isRepoAlertDeleteDialogOpen}
207+
open={isRepoAlertDeleteDialogOpen}
276208
onClose={closeAlertDeleteDialog}
277-
{...wrapConditionalObjectElement(
278-
{
279-
identifier: alertDeleteParams,
280-
deleteFn: handleDeleteRule,
281-
isLoading: isDeletingRule,
282-
error: apiError?.type === ErrorTypes.DELETE_RULE ? apiError : null,
283-
type: 'rule'
284-
},
285-
isRuleAlertDeleteDialogOpen
286-
)}
287209
{...wrapConditionalObjectElement(
288210
{
289211
identifier: repoRef,
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { useEffect, useState } from 'react'
2+
import { useNavigate, useParams } from 'react-router-dom'
3+
4+
import { useQueryClient } from '@tanstack/react-query'
5+
6+
import {
7+
RepoRuleDeleteErrorResponse,
8+
RepoRuleListErrorResponse,
9+
useRepoRuleDeleteMutation,
10+
useRepoRuleListQuery
11+
} from '@harnessio/code-service-client'
12+
import { DeleteAlertDialog } from '@harnessio/ui/components'
13+
import { wrapConditionalObjectElement } from '@harnessio/ui/utils'
14+
import { ErrorTypes, RepoSettingsRulesPage } from '@harnessio/ui/views'
15+
16+
import { useRoutes } from '../../framework/context/NavigationContext'
17+
import { useGetRepoId } from '../../framework/hooks/useGetRepoId'
18+
import { useGetRepoRef } from '../../framework/hooks/useGetRepoPath'
19+
import { PathParams } from '../../RouteDefinitions'
20+
import { useRepoRulesStore } from './stores/repo-settings-store'
21+
22+
export const RepoSettingsRulesListContainer = () => {
23+
const routes = useRoutes()
24+
const repoRef = useGetRepoRef()
25+
const repoName = useGetRepoId()
26+
const navigate = useNavigate()
27+
const { spaceId } = useParams<PathParams>()
28+
const queryClient = useQueryClient()
29+
const { setRules } = useRepoRulesStore()
30+
const [rulesSearchQuery, setRulesSearchQuery] = useState('')
31+
const [apiError, setApiError] = useState<{ type: ErrorTypes; message: string } | null>(null)
32+
const [isRuleAlertDeleteDialogOpen, setRuleIsAlertDeleteDialogOpen] = useState(false)
33+
const [alertDeleteParams, setAlertDeleteParams] = useState('')
34+
35+
const closeAlertDeleteDialog = () => {
36+
isRuleAlertDeleteDialogOpen && setRuleIsAlertDeleteDialogOpen(false)
37+
}
38+
const openRulesAlertDeleteDialog = (identifier: string) => {
39+
setAlertDeleteParams(identifier)
40+
setRuleIsAlertDeleteDialogOpen(true)
41+
}
42+
43+
const {
44+
data: { body: rulesData } = {},
45+
refetch: refetchRulesList,
46+
isLoading: isRulesLoading
47+
} = useRepoRuleListQuery(
48+
{ repo_ref: repoRef, queryParams: { query: rulesSearchQuery } },
49+
{
50+
onError: (error: RepoRuleListErrorResponse) => {
51+
const message = error.message || 'Error fetching rules'
52+
setApiError({ type: ErrorTypes.FETCH_RULES, message })
53+
}
54+
}
55+
)
56+
57+
const { mutate: deleteRule, isLoading: isDeletingRule } = useRepoRuleDeleteMutation(
58+
{ repo_ref: repoRef },
59+
{
60+
onSuccess: () => {
61+
refetchRulesList()
62+
setRuleIsAlertDeleteDialogOpen(false)
63+
setApiError(null)
64+
},
65+
onError: (error: RepoRuleDeleteErrorResponse) => {
66+
// Invalidate queries to refetch data from server
67+
queryClient.invalidateQueries(['ruleList', repoRef])
68+
69+
const message = error.message || 'Error deleting rule'
70+
setApiError({ type: ErrorTypes.DELETE_RULE, message })
71+
}
72+
}
73+
)
74+
75+
useEffect(() => {
76+
if (rulesData) {
77+
setRules(rulesData)
78+
setApiError(null)
79+
}
80+
}, [rulesData, setRules])
81+
82+
const handleRuleClick = (identifier: string) => {
83+
navigate(routes.toRepoBranchRule({ spaceId, repoId: repoName, identifier }))
84+
}
85+
86+
const handleDeleteRule = (identifier: string) => {
87+
deleteRule({ rule_identifier: identifier })
88+
navigate(routes.toRepoBranchRules({ spaceId, repoId: repoName, identifier }))
89+
}
90+
91+
return (
92+
<>
93+
<RepoSettingsRulesPage
94+
handleRuleClick={handleRuleClick}
95+
openRulesAlertDeleteDialog={openRulesAlertDeleteDialog}
96+
useRepoRulesStore={useRepoRulesStore}
97+
rulesSearchQuery={rulesSearchQuery}
98+
setRulesSearchQuery={setRulesSearchQuery}
99+
isRulesLoading={isRulesLoading}
100+
apiError={apiError}
101+
toRepoBranchRuleCreate={() => routes.toRepoBranchRuleCreate({ spaceId, repoId: repoName })}
102+
/>
103+
104+
<DeleteAlertDialog
105+
open={isRuleAlertDeleteDialogOpen}
106+
onClose={closeAlertDeleteDialog}
107+
{...wrapConditionalObjectElement(
108+
{
109+
identifier: alertDeleteParams,
110+
deleteFn: handleDeleteRule,
111+
isLoading: isDeletingRule,
112+
error: apiError?.type === ErrorTypes.DELETE_RULE ? apiError : null,
113+
type: 'rule'
114+
},
115+
isRuleAlertDeleteDialogOpen
116+
)}
117+
/>
118+
</>
119+
)
120+
}

apps/gitness/src/routes.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { ImportRepo } from './pages-v2/repo/repo-import-page'
5252
import RepoLayout from './pages-v2/repo/repo-layout'
5353
import ReposListPage from './pages-v2/repo/repo-list'
5454
import { RepoSettingsGeneralPageContainer } from './pages-v2/repo/repo-settings-general-container'
55+
import { RepoSettingsRulesListContainer } from './pages-v2/repo/repo-settings-rules-list-container'
5556
import { RepoSidebar } from './pages-v2/repo/repo-sidebar'
5657
import RepoSummaryPage from './pages-v2/repo/repo-summary'
5758
import { RepoTagsListContainer } from './pages-v2/repo/repo-tags-list-container'
@@ -495,7 +496,7 @@ export const repoRoutes: CustomRouteObject[] = [
495496
children: [
496497
{
497498
index: true,
498-
element: <RepoSettingsGeneralPageContainer />,
499+
element: <RepoSettingsRulesListContainer />,
499500
handle: {
500501
pageTitle: Page.Branch_Rules
501502
}
@@ -504,7 +505,8 @@ export const repoRoutes: CustomRouteObject[] = [
504505
path: 'create',
505506
element: <RepoBranchSettingsRulesPageContainer />,
506507
handle: {
507-
breadcrumb: () => <span>Create a rule</span>
508+
breadcrumb: () => <span>Create a rule</span>,
509+
routeName: RouteConstants.toRepoBranchRuleCreate
508510
}
509511
},
510512
{

0 commit comments

Comments
 (0)