-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
resourceadm: change available fields for resource type "MaskinportenS…
…chema" (#11933) * refactor: create a common fieldset wrapper component to use for contact points and resource references * remove self_identified user, enterprise user and available for type fields from about resource page when resource type is MaskinportenSchema * add fields for resource references fields for resourceType MaskinportenSchema * replace Select component with radio buttons for resource type and resource status * hide translation panel when any non-translateable field is focused * hide migrate tab unless resource has a reference with Altinn2 source
- Loading branch information
Showing
21 changed files
with
825 additions
and
377 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
frontend/resourceadm/components/FieldsetWrapper/FieldsetWrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import React, { useRef, useState } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { Button, Modal } from '@digdir/design-system-react'; | ||
import classes from './FieldsetWrapper.module.css'; | ||
|
||
const DELETE_ID_NOT_SET = -1; | ||
|
||
export type FieldsetWrapperProps<T> = { | ||
/** | ||
* The current list | ||
*/ | ||
list: T[]; | ||
/** | ||
* Function to be executed when list is changed | ||
* @param list the updated list | ||
* @returns void | ||
*/ | ||
onListFieldChanged: (list: T[]) => void; | ||
/** | ||
* Translation keys for texts displayed by the wrapper | ||
*/ | ||
translations: { | ||
deleteButton: string; | ||
deleteHeader: string; | ||
deleteConfirmation: string; | ||
deleteConfirmationButton: string; | ||
addButton: string; | ||
}; | ||
/** | ||
* List object where all values are default values | ||
*/ | ||
emptyItem: T; | ||
/** | ||
* Render function for rendering a list item. | ||
* @param listItem the list item to render | ||
* @param onChange function to call when item is changed. Call this function from child fieldset render on change | ||
*/ | ||
renderItem: (listItem: T, onChange: (item: T) => void) => React.ReactNode; | ||
}; | ||
|
||
/** | ||
* @component | ||
* Renders the list and calls the renderItem prop function for each list item | ||
* | ||
* @property {T[]}[list] - The current list | ||
* @property {function}[onListFieldChanged] - Function to be executed when list is changed | ||
* @property {Object}[translations] - Translation keys for texts displayed by the wrapper | ||
* @property {T}[emptyItem] - List object where all values are default values | ||
* @property {function}[renderItem] - Render function for rendering a list item. | ||
* | ||
* @returns {React.ReactNode} - The rendered component | ||
*/ | ||
export const FieldsetWrapper = <T,>({ | ||
list, | ||
onListFieldChanged, | ||
emptyItem, | ||
translations, | ||
renderItem, | ||
}: FieldsetWrapperProps<T>): React.ReactNode => { | ||
const { t } = useTranslation(); | ||
const deleteModalRef = useRef<HTMLDialogElement>(null); | ||
|
||
const [deleteId, setDeleteId] = useState<number>(DELETE_ID_NOT_SET); | ||
const [listItems, setListItems] = useState<T[]>(list ?? [emptyItem]); | ||
|
||
/** | ||
* Adds a new empty list item to the list | ||
*/ | ||
const handleClickAddButton = () => { | ||
const updatedList = [...listItems, emptyItem]; | ||
setListItems(updatedList); | ||
onListFieldChanged(updatedList); | ||
}; | ||
|
||
/** | ||
* Removes a list item in the deleteId position from the list | ||
*/ | ||
const handleClickRemoveButton = () => { | ||
const updatedList = listItems.filter((_item, index) => index !== deleteId); | ||
onCloseDeleteModal(); | ||
setListItems(updatedList); | ||
onListFieldChanged(updatedList); | ||
}; | ||
|
||
/** | ||
* Updates the list item when a field is changed | ||
* @param listItem | ||
* @param pos | ||
*/ | ||
const onChangeListItemField = (listItem: T, pos: number) => { | ||
const updatedList = [...listItems]; | ||
updatedList[pos] = listItem; | ||
setListItems(updatedList); | ||
onListFieldChanged(updatedList); | ||
}; | ||
|
||
/** | ||
* Closes the delete list item modal | ||
*/ | ||
const onCloseDeleteModal = (): void => { | ||
deleteModalRef.current?.close(); | ||
setDeleteId(DELETE_ID_NOT_SET); | ||
}; | ||
/** | ||
* Render each list item with renderItem() and display a delete button for each | ||
*/ | ||
const displayFields = listItems.map((listItem: T, pos: number) => ( | ||
<div key={`${pos}/${listItems.length}`} className={classes.fieldset}> | ||
<div className={classes.divider} /> | ||
{renderItem(listItem, (item: T) => { | ||
onChangeListItemField(item, pos); | ||
})} | ||
<div className={classes.buttonWrapper}> | ||
<Button | ||
size='small' | ||
color='danger' | ||
aria-disabled={listItems.length < 2} | ||
onClick={() => { | ||
if (listItems.length > 1) { | ||
deleteModalRef.current?.showModal(); | ||
setDeleteId(pos); | ||
} | ||
}} | ||
> | ||
{t(translations.deleteButton)} | ||
</Button> | ||
</div> | ||
</div> | ||
)); | ||
|
||
return ( | ||
<> | ||
<Modal ref={deleteModalRef} onClose={onCloseDeleteModal}> | ||
<Modal.Header>{t(translations.deleteHeader)}</Modal.Header> | ||
<Modal.Content>{t(translations.deleteConfirmation)}</Modal.Content> | ||
<Modal.Footer> | ||
<Button color='danger' size='small' onClick={handleClickRemoveButton}> | ||
{t(translations.deleteConfirmationButton)} | ||
</Button> | ||
<Button size='small' variant='tertiary' onClick={onCloseDeleteModal}> | ||
{t('general.cancel')} | ||
</Button> | ||
</Modal.Footer> | ||
</Modal> | ||
<div className={classes.divider} /> | ||
{displayFields} | ||
<Button size='small' onClick={handleClickAddButton}> | ||
{t(translations.addButton)} | ||
</Button> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { FieldsetWrapper } from './FieldsetWrapper'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.