fix(striker-ui): only send changed properties when edit file

main
Tsu-ba-me 3 years ago
parent eab3abd7db
commit 131c50863e
  1. 112
      striker-ui/components/Files/FileEditForm.tsx
  2. 27
      striker-ui/components/Files/FileInfo.tsx

@ -1,3 +1,4 @@
import { AxiosResponse } from 'axios';
import { import {
FormEventHandler, FormEventHandler,
MouseEventHandler, MouseEventHandler,
@ -17,6 +18,16 @@ import Spinner from '../Spinner';
import fetchJSON from '../../lib/fetchers/fetchJSON'; import fetchJSON from '../../lib/fetchers/fetchJSON';
import mainAxiosInstance from '../../lib/singletons/mainAxiosInstance'; import mainAxiosInstance from '../../lib/singletons/mainAxiosInstance';
type ReducedFileLocation = Partial<
Pick<FileLocation, 'fileLocationUUID' | 'isFileLocationActive'>
>;
type EditRequestContent = Partial<
Pick<FileDetailMetadata, 'fileName' | 'fileType' | 'fileUUID'>
> & {
fileLocations: ReducedFileLocation[];
};
type FileEditProps = { type FileEditProps = {
filesOverview: FileOverviewMetadata[]; filesOverview: FileOverviewMetadata[];
onEditFilesComplete?: () => void; onEditFilesComplete?: () => void;
@ -40,6 +51,9 @@ const FileEditForm = (
onPurgeFilesComplete, onPurgeFilesComplete,
}: FileEditProps = FILE_EDIT_FORM_DEFAULT_PROPS as FileEditProps, }: FileEditProps = FILE_EDIT_FORM_DEFAULT_PROPS as FileEditProps,
): JSX.Element => { ): JSX.Element => {
const [editRequestContents, setEditRequestContents] = useState<
EditRequestContent[]
>([]);
const [filesToEdit, setFilesToEdit] = useState<FileToEdit[]>([]); const [filesToEdit, setFilesToEdit] = useState<FileToEdit[]>([]);
const [isLoadingFilesToEdit, setIsLoadingFilesToEdit] = const [isLoadingFilesToEdit, setIsLoadingFilesToEdit] =
useState<boolean>(false); useState<boolean>(false);
@ -57,14 +71,14 @@ const FileEditForm = (
const generateFileInfoChangeHandler = const generateFileInfoChangeHandler =
(fileIndex: number): FileInfoChangeHandler => (fileIndex: number): FileInfoChangeHandler =>
(inputValues, { fileLocationIndex } = {}) => { (inputValues, { fileLocationIndex } = {}) => {
if (fileLocationIndex) { if (fileLocationIndex !== undefined) {
filesToEdit[fileIndex].fileLocations[fileLocationIndex] = { editRequestContents[fileIndex].fileLocations[fileLocationIndex] = {
...filesToEdit[fileIndex].fileLocations[fileLocationIndex], ...editRequestContents[fileIndex].fileLocations[fileLocationIndex],
...inputValues, ...inputValues,
}; };
} else { } else {
filesToEdit[fileIndex] = { editRequestContents[fileIndex] = {
...filesToEdit[fileIndex], ...editRequestContents[fileIndex],
...inputValues, ...inputValues,
}; };
} }
@ -75,24 +89,61 @@ const FileEditForm = (
setIsLoadingFilesToEdit(true); setIsLoadingFilesToEdit(true);
const editPromises = filesToEdit.map( const editPromises = editRequestContents.reduce<Promise<AxiosResponse>[]>(
({ fileLocations, fileName, fileType, fileUUID }) => (
mainAxiosInstance.put( reducedEditPromises,
`/files/${fileUUID}`, { fileLocations, fileName, fileType, fileUUID },
JSON.stringify({ ) => {
fileName, const editRequestContent: Partial<EditRequestContent> = {};
fileType,
fileLocations: fileLocations.map( if (fileName !== undefined) {
({ fileLocationUUID, isFileLocationActive }) => ({ editRequestContent.fileName = fileName;
}
if (fileType !== undefined) {
editRequestContent.fileType = fileType;
}
const changedFileLocations = fileLocations.reduce<
ReducedFileLocation[]
>(
(
reducedFileLocations,
{ fileLocationUUID, isFileLocationActive },
) => {
if (isFileLocationActive !== undefined) {
reducedFileLocations.push({
fileLocationUUID, fileLocationUUID,
isFileLocationActive, isFileLocationActive,
}), });
), }
}),
{ return reducedFileLocations;
headers: { 'Content-Type': 'application/json' },
}, },
), [],
);
if (changedFileLocations.length > 0) {
editRequestContent.fileLocations = changedFileLocations;
}
const stringEditFileRequestContent = JSON.stringify(editRequestContent);
if (stringEditFileRequestContent !== '{}') {
reducedEditPromises.push(
mainAxiosInstance.put(
`/files/${fileUUID}`,
stringEditFileRequestContent,
{
headers: { 'Content-Type': 'application/json' },
},
),
);
}
return reducedEditPromises;
},
[],
); );
Promise.all(editPromises) Promise.all(editPromises)
@ -180,6 +231,27 @@ const FileEditForm = (
}), }),
).then((fetchedFilesDetail) => { ).then((fetchedFilesDetail) => {
setFilesToEdit(fetchedFilesDetail); setFilesToEdit(fetchedFilesDetail);
const initialEditRequestContents: EditRequestContent[] = [];
for (
let fileIndex = 0;
fileIndex < fetchedFilesDetail.length;
fileIndex += 1
) {
const fetchedFileDetail = fetchedFilesDetail[fileIndex];
initialEditRequestContents.push({
fileUUID: fetchedFileDetail.fileUUID,
fileLocations: fetchedFileDetail.fileLocations.map(
({ fileLocationUUID }) => ({
fileLocationUUID,
}),
),
});
}
setEditRequestContents(initialEditRequestContents);
setIsLoadingFilesToEdit(false); setIsLoadingFilesToEdit(false);
}); });
}, [filesOverview]); }, [filesOverview]);

@ -93,9 +93,11 @@ const FileInfo = (
disabled={isReadonly} disabled={isReadonly}
id={fileNameElementId} id={fileNameElementId}
label={fileNameElementLabel} label={fileNameElementLabel}
onChange={({ target: { value } }) => onChange={({ target: { value } }) => {
onChange?.call(null, { fileName: value }) onChange?.call(null, {
} fileName: value === fileName ? undefined : value,
});
}}
/> />
</FormControl> </FormControl>
{fileType && ( {fileType && (
@ -108,9 +110,11 @@ const FileInfo = (
disabled={isReadonly} disabled={isReadonly}
id={fileTypeElementId} id={fileTypeElementId}
input={<OutlinedInput label={fileTypeElementLabel} />} input={<OutlinedInput label={fileTypeElementLabel} />}
onChange={({ target: { value } }) => onChange={({ target: { value } }) => {
onChange?.call(null, { fileType: value as FileType }) onChange?.call(null, {
} fileType: value === fileType ? undefined : (value as FileType),
});
}}
> >
{UPLOAD_FILE_TYPES_ARRAY.map( {UPLOAD_FILE_TYPES_ARRAY.map(
([fileTypeKey, [, fileTypeDisplayString]]) => { ([fileTypeKey, [, fileTypeDisplayString]]) => {
@ -136,13 +140,16 @@ const FileInfo = (
defaultChecked={isFileLocationActive} defaultChecked={isFileLocationActive}
disabled={isReadonly} disabled={isReadonly}
icon={<SyncDisabledIcon />} icon={<SyncDisabledIcon />}
onChange={({ target: { checked } }) => onChange={({ target: { checked } }) => {
onChange?.call( onChange?.call(
null, null,
{ isFileLocationActive: checked }, {
isFileLocationActive:
checked === isFileLocationActive ? undefined : checked,
},
{ fileLocationIndex }, { fileLocationIndex },
) );
} }}
/> />
} }
key={anvilUUID} key={anvilUUID}

Loading…
Cancel
Save