1- import React , { useEffect , useMemo , useState } from 'react' ;
2- import { useFieldArray , useForm } from 'react-hook-form' ;
1+ import React , { useState } from 'react' ;
32import { useTranslation } from 'react-i18next' ;
43
4+ import { Button , ButtonWithConfirmation , Header , ListEmptyMessage , Modal , Pagination , SpaceBetween , Table } from 'components' ;
5+
6+ import { useCollection , useNotifications } from 'hooks' ;
57import {
6- Button ,
7- ButtonWithConfirmation ,
8- FormInput ,
9- Header ,
10- ListEmptyMessage ,
11- Pagination ,
12- SpaceBetween ,
13- Table ,
14- } from 'components' ;
8+ useDeleteSecretsMutation ,
9+ useGetAllSecretsQuery ,
10+ useLazyGetSecretQuery ,
11+ useUpdateSecretMutation ,
12+ } from 'services/secrets' ;
1513
16- import { useCollection } from 'hooks ' ;
17- import { useDeleteSecretsMutation , useGetAllSecretsQuery , useUpdateSecretMutation } from 'services/secrets ' ;
14+ import { getServerError } from '../../../libs ' ;
15+ import { SecretForm } from './Form ' ;
1816
19- import { IProps , TFormSecretValue , TFormValues , TProjectSecretWithIndex } from './types' ;
17+ import { IProps , TFormValues } from './types' ;
2018
2119import styles from './styles.module.scss' ;
2220
2321export const ProjectSecrets : React . FC < IProps > = ( { project, loading } ) => {
2422 const { t } = useTranslation ( ) ;
25- const [ editableRowIndex , setEditableRowIndex ] = useState < number | null > ( null ) ;
23+ const [ initialFormValues , setInitialFormValues ] = useState < TFormValues | undefined > ( ) ;
2624 const projectName = project ?. project_name ?? '' ;
25+ const [ pushNotification ] = useNotifications ( ) ;
2726
2827 const { data, isLoading, isFetching } = useGetAllSecretsQuery ( { project_name : projectName } ) ;
2928 const [ updateSecret , { isLoading : isUpdating } ] = useUpdateSecretMutation ( ) ;
3029 const [ deleteSecret , { isLoading : isDeleting } ] = useDeleteSecretsMutation ( ) ;
30+ const [ getSecret , { isLoading : isGettingSecrets } ] = useLazyGetSecretQuery ( ) ;
3131
32- const { handleSubmit, control, getValues, setValue } = useForm < TFormValues > ( {
33- defaultValues : { secrets : [ ] } ,
34- } ) ;
35-
36- useEffect ( ( ) => {
37- if ( data ) {
38- setValue (
39- 'secrets' ,
40- data . map ( ( s ) => ( { ...s , serverId : s . id } ) ) ,
41- ) ;
42- }
43- } , [ data ] ) ;
44-
45- const { fields, append, remove } = useFieldArray ( {
46- control,
47- name : 'secrets' ,
48- } ) ;
49-
50- const fieldsWithIndex = useMemo ( ( ) => {
51- return fields . map < TProjectSecretWithIndex > ( ( field , index ) => ( { ...field , index } ) ) ;
52- } , [ fields ] ) ;
53-
54- const { items, paginationProps, collectionProps } = useCollection ( fieldsWithIndex , {
32+ const { items, paginationProps, collectionProps } = useCollection ( data ?? [ ] , {
5533 filtering : {
5634 empty : (
5735 < ListEmptyMessage
@@ -70,112 +48,72 @@ export const ProjectSecrets: React.FC<IProps> = ({ project, loading }) => {
7048 const names = selectedItems ?. map ( ( s ) => s . name ?? '' ) ;
7149
7250 if ( names ?. length ) {
73- deleteSecret ( { project_name : projectName , names } ) . then ( ( ) => {
74- selectedItems ?. forEach ( ( s ) => remove ( s . index ) ) ;
75- } ) ;
51+ deleteSecret ( { project_name : projectName , names } ) ;
7652 }
7753 } ;
7854
79- const removeSecretByIndex = ( index : number ) => {
80- const secretData = getValues ( ) . secrets ?. [ index ] ;
81-
82- if ( ! secretData || ! secretData . name ) {
83- return ;
84- }
85-
86- deleteSecret ( { project_name : projectName , names : [ secretData . name ] } ) . then ( ( ) => {
87- remove ( index ) ;
88- } ) ;
55+ const removeSecretByName = ( name : IProjectSecret [ 'name' ] ) => {
56+ deleteSecret ( { project_name : projectName , names : [ name ] } ) ;
8957 } ;
9058
91- const saveSecretByIndex = ( index : number ) => {
92- const secretData = getValues ( ) . secrets ?. [ index ] ;
93-
94- if ( ! secretData || ! secretData . name || ! secretData . value ) {
59+ const updateOrCreateSecret = ( { name, value } : TFormValues ) => {
60+ if ( ! name || ! value ) {
9561 return ;
9662 }
9763
98- updateSecret ( { project_name : projectName , name : secretData . name , value : secretData . value } )
64+ updateSecret ( { project_name : projectName , name, value } )
9965 . unwrap ( )
100- . then ( ( ) => {
101- setEditableRowIndex ( null ) ;
66+ . then ( ( ) => setInitialFormValues ( undefined ) )
67+ . catch ( ( error ) => {
68+ pushNotification ( {
69+ type : 'error' ,
70+ content : t ( 'common.server_error' , { error : getServerError ( error ) } ) ,
71+ } ) ;
10272 } ) ;
10373 } ;
10474
105- const isDisabledEditableRowActions = loading || isLoading || isFetching || isUpdating ;
106- const isDisabledNotEditableRowActions = loading || isLoading || isFetching || isDeleting ;
75+ const editSecret = ( { name } : IProjectSecret ) => {
76+ getSecret ( { project_name : projectName , name } )
77+ . unwrap ( )
78+ . then ( ( secret ) => setInitialFormValues ( secret ) ) ;
79+ } ;
80+
81+ const closeModal = ( ) => setInitialFormValues ( undefined ) ;
82+
83+ const isDisabledActions = loading || isLoading || isFetching || isDeleting || isGettingSecrets ;
10784
10885 const COLUMN_DEFINITIONS = [
10986 {
11087 id : 'name' ,
11188 header : t ( 'projects.edit.secrets.name' ) ,
112- cell : ( field : TFormSecretValue & { index : number } ) => {
113- const isEditable = editableRowIndex === field . index ;
114-
115- return (
116- < div className = { styles . value } >
117- < div className = { styles . valueFieldWrapper } >
118- < FormInput
119- key = { field . name }
120- control = { control }
121- name = { `secrets.${ field . index } .name` }
122- disabled = { loading || ! isEditable || ! ! field . serverId }
123- />
124- </ div >
125- </ div >
126- ) ;
127- } ,
89+ cell : ( secret : IProjectSecret ) => secret . name ,
12890 } ,
12991 {
13092 id : 'value' ,
13193 header : t ( 'projects.edit.secrets.value' ) ,
132- cell : ( field : TFormSecretValue & { index : number } ) => {
133- const isEditable = editableRowIndex === field . index ;
134-
94+ cell : ( secret : IProjectSecret ) => {
13595 return (
13696 < div className = { styles . value } >
137- < div className = { styles . valueFieldWrapper } >
138- < FormInput
139- readOnly = { ! isEditable }
140- key = { field . value }
141- control = { control }
142- name = { `secrets.${ field . index } .value` }
143- disabled = { loading || ! isEditable }
144- />
145- </ div >
97+ < div className = { styles . valueFieldWrapper } > ************************</ div >
14698
14799 < div className = { styles . buttonsWrapper } >
148- { isEditable && (
149- < Button
150- disabled = { isDisabledEditableRowActions }
151- formAction = "none"
152- onClick = { ( ) => saveSecretByIndex ( field . index ) }
153- variant = "icon"
154- iconName = "check"
155- />
156- ) }
157-
158- { ! isEditable && (
159- < Button
160- disabled = { isDisabledNotEditableRowActions }
161- formAction = "none"
162- onClick = { ( ) => setEditableRowIndex ( field . index ) }
163- variant = "icon"
164- iconName = "edit"
165- />
166- ) }
167-
168- { ! isEditable && (
169- < ButtonWithConfirmation
170- disabled = { isDisabledNotEditableRowActions }
171- formAction = "none"
172- onClick = { ( ) => removeSecretByIndex ( field . index ) }
173- confirmTitle = { t ( 'projects.edit.secrets.delete_confirm_title' ) }
174- confirmContent = { t ( 'projects.edit.secrets.delete_confirm_message' ) }
175- variant = "icon"
176- iconName = "remove"
177- />
178- ) }
100+ < Button
101+ disabled = { isDisabledActions }
102+ formAction = "none"
103+ onClick = { ( ) => editSecret ( secret ) }
104+ variant = "icon"
105+ iconName = "edit"
106+ />
107+
108+ < ButtonWithConfirmation
109+ disabled = { isDisabledActions }
110+ formAction = "none"
111+ onClick = { ( ) => removeSecretByName ( secret . name ) }
112+ confirmTitle = { t ( 'projects.edit.secrets.delete_confirm_title' ) }
113+ confirmContent = { t ( 'projects.edit.secrets.delete_confirm_message' , { name : secret . name } ) }
114+ variant = "icon"
115+ iconName = "remove"
116+ />
179117 </ div >
180118 </ div >
181119 ) ;
@@ -184,8 +122,7 @@ export const ProjectSecrets: React.FC<IProps> = ({ project, loading }) => {
184122 ] ;
185123
186124 const addSecretHandler = ( ) => {
187- append ( { } ) ;
188- setEditableRowIndex ( fields . length ) ;
125+ setInitialFormValues ( { } ) ;
189126 } ;
190127
191128 const renderActions = ( ) => {
@@ -196,11 +133,11 @@ export const ProjectSecrets: React.FC<IProps> = ({ project, loading }) => {
196133
197134 < ButtonWithConfirmation
198135 key = "delete"
199- disabled = { isDisabledNotEditableRowActions || ! selectedItems ?. length }
136+ disabled = { isDisabledActions || ! selectedItems ?. length }
200137 formAction = "none"
201138 onClick = { deleteSelectedSecrets }
202- confirmTitle = { t ( 'projects.edit.secrets.delete_confirm_title ' ) }
203- confirmContent = { t ( 'projects.edit.secrets.delete_confirm_message' ) }
139+ confirmTitle = { t ( 'projects.edit.secrets.multiple_delete_confirm_title ' ) }
140+ confirmContent = { t ( 'projects.edit.secrets.multiple_delete_confirm_message' , { count : selectedItems ?. length } ) }
204141 >
205142 { t ( 'common.delete' ) }
206143 </ ButtonWithConfirmation > ,
@@ -213,8 +150,10 @@ export const ProjectSecrets: React.FC<IProps> = ({ project, loading }) => {
213150 ) : undefined ;
214151 } ;
215152
153+ const isShowModal = ! ! initialFormValues ;
154+
216155 return (
217- < form onSubmit = { handleSubmit ( ( ) => { } ) } >
156+ < >
218157 < Table
219158 { ...collectionProps }
220159 selectionType = "multi"
@@ -228,6 +167,23 @@ export const ProjectSecrets: React.FC<IProps> = ({ project, loading }) => {
228167 }
229168 pagination = { < Pagination { ...paginationProps } /> }
230169 />
231- </ form >
170+
171+ < Modal
172+ header = {
173+ initialFormValues ?. id ? t ( 'projects.edit.secrets.update_secret' ) : t ( 'projects.edit.secrets.create_secret' )
174+ }
175+ visible = { isShowModal }
176+ onDismiss = { closeModal }
177+ >
178+ { isShowModal && (
179+ < SecretForm
180+ initialValues = { initialFormValues }
181+ onSubmit = { updateOrCreateSecret }
182+ loading = { isLoading || isUpdating }
183+ onCancel = { closeModal }
184+ />
185+ ) }
186+ </ Modal >
187+ </ >
232188 ) ;
233189} ;
0 commit comments