diff --git a/app/src/components/security/SecuritiesDialog.tsx b/app/src/components/security/SecuritiesDialog.tsx index b8611ee0..cfa68b5b 100644 --- a/app/src/components/security/SecuritiesDialog.tsx +++ b/app/src/components/security/SecuritiesDialog.tsx @@ -34,11 +34,7 @@ const SecuritiesDialog = (props: ISecuritiesDialogProps) => { dialogContext.setSnackbar({ snackbarMessage: ( - {ApplySecurityRulesI18N.applySecuritySuccess( - patch.stagedForApply.length, - patch.stagedForRemove.length, - props.submissionFeatureIds.length - )} + {ApplySecurityRulesI18N.applySecuritySuccess(props.submissionFeatureIds.length)} ), open: true @@ -61,7 +57,7 @@ const SecuritiesDialog = (props: ISecuritiesDialogProps) => { return ( isLoading={isLoading} - dialogTitle={hasSecurity ? 'Edit Security Reasons' : ' Add Security Reasons'} + dialogTitle={hasSecurity ? 'Edit Security' : ' Add Security'} open={props.open} dialogSaveButtonLabel="APPLY" onCancel={props.onClose} diff --git a/app/src/components/security/SecurityRuleActionCard.tsx b/app/src/components/security/SecurityRuleActionCard.tsx index 19e0d73f..8d98ce40 100644 --- a/app/src/components/security/SecurityRuleActionCard.tsx +++ b/app/src/components/security/SecurityRuleActionCard.tsx @@ -17,11 +17,10 @@ const SecurityRuleActionCard = (props: ISecurityRuleActionCardProps) => { variant="outlined" sx={{ display: 'flex', - px: 2, - py: 1.5, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', + p: 2, background: grey[100] }}> @@ -30,7 +29,15 @@ const SecurityRuleActionCard = (props: ISecurityRuleActionCardProps) => { ) : ( - )} diff --git a/app/src/components/security/SecurityRuleCard.tsx b/app/src/components/security/SecurityRuleCard.tsx index 3ca9d5f2..f4fa3300 100644 --- a/app/src/components/security/SecurityRuleCard.tsx +++ b/app/src/components/security/SecurityRuleCard.tsx @@ -1,5 +1,5 @@ -import { Box, Typography } from '@mui/material'; -import { Stack } from '@mui/system'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; export interface ISecurityRuleCardProps { key?: string | number; @@ -11,46 +11,53 @@ export interface ISecurityRuleCardProps { const SecurityRuleCard = (props: ISecurityRuleCardProps) => { return ( - - + + {props.category} - - {props.title} - - - {props.description} - + + + {props.title} + + + {props.description} + + {props.featureMembers && props.featureMembers?.length && ( - + {props.featureMembers.map((featureMember) => ( - + {featureMember} ))} )} - + ); }; diff --git a/app/src/components/security/SecurityRuleForm.tsx b/app/src/components/security/SecurityRuleForm.tsx index b3d9250e..433a6ee3 100644 --- a/app/src/components/security/SecurityRuleForm.tsx +++ b/app/src/components/security/SecurityRuleForm.tsx @@ -137,95 +137,85 @@ const SecurityRuleForm = () => { return (
- - - Specify reasons why this information should be secured. + + Secure Records + + Secure records by adding one or more security rules. + { + const searchFilter = createFilterOptions({ + ignoreCase: true, + matchFrom: 'any', + stringify: (option) => option.name + option.category_name + }); - - - Add Security Rules - - { - const searchFilter = createFilterOptions({ - ignoreCase: true, - matchFrom: 'any', - stringify: (option) => option.name + option.category_name - }); - - const selectableOptions = options.filter((securityRule) => { - return !formikProps.values.stagedForApply.some( - (applyingRule) => applyingRule.security_rule_id === securityRule.security_rule_id - ); - }); - - return searchFilter(selectableOptions, state); - }} - getOptionLabel={(option) => option.name} - isOptionEqualToValue={(option, value) => option.security_rule_id === value.security_rule_id} - inputValue={searchText} - onInputChange={(_, value, reason) => { - if (reason === 'reset') { - setSearchText(''); - } else { - setSearchText(value); - } - }} - onChange={(_, option) => { - if (option) { - toggleStageApply(option); - } - }} - renderInput={(params) => ( - - - - ) - }} - /> - )} - renderOption={(renderProps, renderOption) => { - return ( - - - + const selectableOptions = options.filter((securityRule) => { + return !formikProps.values.stagedForApply.some( + (applyingRule) => applyingRule.security_rule_id === securityRule.security_rule_id ); - }} - /> - + }); + return searchFilter(selectableOptions, state); + }} + getOptionLabel={(option) => option.name} + isOptionEqualToValue={(option, value) => option.security_rule_id === value.security_rule_id} + inputValue={searchText} + onInputChange={(_, value, reason) => { + if (reason === 'reset') { + setSearchText(''); + } else { + setSearchText(value); + } + }} + onChange={(_, option) => { + if (option) { + toggleStageApply(option); + } + }} + renderInput={(params) => ( + + + + ) + }} + /> + )} + renderOption={(renderProps, renderOption) => { + return ( + + + + ); + }} + /> {formikProps.values.stagedForApply.map((applyingRule) => { return ( @@ -241,43 +231,46 @@ const SecurityRuleForm = () => { ); })} + + + Secured Records - - Manage Existing Security - - These rules have already been applied to one or more of the selected features. - - - - {groupedAppliedSecurityRules.map((group: IAppliedSecurityRuleGroup) => { - const cardAction = formikProps.values.stagedForRemove.some( - (removingRule) => removingRule.security_rule_id === group.securityRule.security_rule_id - ) - ? 'remove' - : 'persist'; - - return ( - - - `${p(featureGroup.numFeatures, featureGroup.displayName)} (${featureGroup.numFeatures})` - )} - onRemove={() => toggleStageRemove(group.securityRule)} - /> - - ); - })} - - {hasNoSecuritySelected && ( - - Open access to all records - All users will have unrestricted access to records that have been included in this submission. + {hasNoSecuritySelected ? ( + + No security applied + All users will have unrestricted access to selected records. + ) : ( + <> + + Some of the selected records have been secured using the following rules. + + + {groupedAppliedSecurityRules.map((group: IAppliedSecurityRuleGroup) => { + const cardAction = formikProps.values.stagedForRemove.some( + (removingRule) => removingRule.security_rule_id === group.securityRule.security_rule_id + ) + ? 'remove' + : 'persist'; + + return ( + + + `${p(featureGroup.numFeatures, featureGroup.displayName)} (${featureGroup.numFeatures})` + )} + onRemove={() => toggleStageRemove(group.securityRule)} + /> + + ); + })} + + )}
diff --git a/app/src/constants/i18n.ts b/app/src/constants/i18n.ts index 58f3e7a0..fcfbbca2 100644 --- a/app/src/constants/i18n.ts +++ b/app/src/constants/i18n.ts @@ -26,22 +26,15 @@ export const DeleteSystemUserI18N = { }; export const ApplySecurityRulesI18N = { - applySecuritySuccess: (numApplied: number, numRemoved: number, featureCount: number) => { - const appliedRemoved = [ - numApplied > 0 && `applied ${numApplied} ${p(numApplied, 'security rule')}`, - numRemoved > 0 && `removed ${numRemoved} ${p(numRemoved, 'security rule')}` - ] - .filter(Boolean) - .join(' and '); - - return `Successfully ${appliedRemoved} for ${featureCount} ${p(featureCount, 'feature')}.`; + applySecuritySuccess: (featureCount: number) => { + return `Updated security for ${featureCount} ${p(featureCount, 'feature')}.`; }, - applySecurityRulesErrorTitle: 'Error Applying Security', + applySecurityRulesErrorTitle: 'Error applying security rules', applySecurityRulesErrorText: 'An error occurred while applying security to features, please try again. If the problem persists, please contact your system administrator', unApplySecurityRulesSuccess: (submissionCount: number) => `Successfully unsecured: ${submissionCount} features`, - unapplySecurityRulesErrorTitle: 'Error Unsecuring Features', + unapplySecurityRulesErrorTitle: 'Error unsecuring features', unapplySecurityRulesErrorText: 'Failed to unsecure the selected features, please try again. If the problem persists, please contact your system administrator' }; diff --git a/app/src/features/submissions/components/SubmissionDataGrid.tsx b/app/src/features/submissions/components/SubmissionDataGrid.tsx index 4cfcfb0c..035ce453 100644 --- a/app/src/features/submissions/components/SubmissionDataGrid.tsx +++ b/app/src/features/submissions/components/SubmissionDataGrid.tsx @@ -84,10 +84,10 @@ export const SubmissionDataGrid = (props: ISubmissionDataGridProps) => { alignItems="center" gap={1} sx={{ - color: 'text.secondary' + color: 'error.main' }}> - + Unsecured diff --git a/app/src/features/submissions/components/SubmissionDataGrid/useSubmissionDataGridColumns.tsx b/app/src/features/submissions/components/SubmissionDataGrid/useSubmissionDataGridColumns.tsx index 47bd927a..07d35849 100644 --- a/app/src/features/submissions/components/SubmissionDataGrid/useSubmissionDataGridColumns.tsx +++ b/app/src/features/submissions/components/SubmissionDataGrid/useSubmissionDataGridColumns.tsx @@ -81,24 +81,18 @@ const useSubmissionDataGridColumns = (featureTypeName: string): GridColDef[] => renderCell: (params) => { if (params.value.length > 0) { return ( - + - + Secured ); } return ( - + - + Unsecured