Skip to content

Commit

Permalink
Adding bulk custom field update
Browse files Browse the repository at this point in the history
  • Loading branch information
galvana committed Oct 20, 2023
1 parent a36e35a commit ba7f66b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 36 deletions.
69 changes: 35 additions & 34 deletions clients/admin-ui/src/features/common/custom-fields/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useCallback, useMemo } from "react";
import { useFeatures } from "~/features/common/features";
import { useAlert } from "~/features/common/hooks";
import {
useBulkUpdateCustomFieldsMutation,
useDeleteCustomFieldMutation,
useGetAllAllowListQuery,
useGetCustomFieldDefinitionsByResourceTypeQuery,
Expand Down Expand Up @@ -55,6 +56,9 @@ export const useCustomFields = ({
const [deleteCustomFieldMutationTrigger, deleteCustomFieldMutationResult] =
useDeleteCustomFieldMutation({ fixedCacheKey: resourceFidesKey });

const [bulkUpdateCustomFieldsMutationTrigger, bulkUpdateCustomFieldsResult] =
useBulkUpdateCustomFieldsMutation();

const isLoading =
allAllowListQuery.isLoading ||
customFieldDefinitionsQuery.isLoading ||
Expand Down Expand Up @@ -134,8 +138,8 @@ export const useCustomFields = ({
return;
}

// When creating an resource, the fides key may have initially been blank. But by the time the
// form is submitted it must not be blank (not undefined, not an empty string).
// When creating a resource, the fides key may have initially been blank.
// But by the time the form is submitted it must not be blank (not undefined, not an empty string).
const fidesKey =
"fides_key" in formValues && formValues.fides_key !== ""
? formValues.fides_key
Expand All @@ -156,37 +160,36 @@ export const useCustomFields = ({
return;
}

try {
// This would be a lot simpler (and more efficient) if the API had an endpoint for updating
// all the metadata associated with a field, including deleting options that weren't passed.
await Promise.allSettled(
sortedCustomFieldDefinitionIds.map((definitionId) => {
const customField = definitionIdToCustomField.get(definitionId);
const value = customFieldValuesFromForm[definitionId];

if (
value === undefined ||
value === "" ||
(Array.isArray(value) && value.length === 0)
) {
if (!customField?.id) {
return undefined;
}
const { id } = customField;

return deleteCustomFieldMutationTrigger({ id });
}

const body = {
custom_field_definition_id: definitionId,
resource_id: fidesKey,
id: customField?.id,
value,
};
const upsertList: Array<CustomFieldWithId> = [];
const deleteList: Array<string> = [];

sortedCustomFieldDefinitionIds.forEach((definitionId) => {
const customField = definitionIdToCustomField.get(definitionId);
const value = customFieldValuesFromForm[definitionId];

if (
value === undefined ||
value === "" ||
(Array.isArray(value) && value.length === 0)
) {
if (customField?.id) {
deleteList.push(customField.id);
}
} else {
upsertList.push({
custom_field_definition_id: definitionId,
resource_id: fidesKey,
id: customField?.id,
value,
});
}
});

return upsertCustomFieldMutationTrigger(body);
})
);
try {
await bulkUpdateCustomFieldsMutationTrigger({
upsert: upsertList,
delete: deleteList,
});
} catch (e) {
errorAlert(
`One or more custom fields have failed to save, please try again.`
Expand All @@ -198,11 +201,9 @@ export const useCustomFields = ({
[
isEnabled,
definitionIdToCustomField,
deleteCustomFieldMutationTrigger,
errorAlert,
resourceFidesKey,
sortedCustomFieldDefinitionIds,
upsertCustomFieldMutationTrigger,
]
);

Expand Down
10 changes: 9 additions & 1 deletion clients/admin-ui/src/features/plus/plus.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,14 @@ const plusApi = baseApi.injectEndpoints({
}),
invalidatesTags: ["Custom Fields", "Datamap"],
}),

bulkUpdateCustomFields: build.mutation<void, any>({
query: (params) => ({
url: `plus/custom-metadata/custom-field/bulk`,
method: "POST",
body: params,
}),
invalidatesTags: ["Custom Fields", "Datamap"],
}),
getAllCustomFieldDefinitions: build.query<
CustomFieldDefinitionWithId[],
void
Expand Down Expand Up @@ -321,6 +328,7 @@ export const {
useUpdateScanMutation,
useUpsertAllowListMutation,
useUpsertCustomFieldMutation,
useBulkUpdateCustomFieldsMutation,
useGetAllCustomFieldDefinitionsQuery,
useGetAllowListQuery,
useGetAllDictionaryEntriesQuery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ const SystemCustomFieldGroup: React.FC<SystemCustomFieldGroupProps> = ({
? "custom_fields"
: "privacy_declarations[0].custom_fields";

// to ensure the order in the diff lists is the same
const sortedFieldNames = Object.keys(customFields).sort();

return (
<SystemDataGroup heading="Custom fields">
{Object.keys(customFields).map((fieldName) =>
{sortedFieldNames.map((fieldName) =>
isMultivalued(fieldName) ? (
<SystemDataTags
key={fieldName}
Expand Down

0 comments on commit ba7f66b

Please sign in to comment.