From eb63c53c7f56150441e630e6efed8a5be9b21d93 Mon Sep 17 00:00:00 2001 From: Jon Tyson <6943745+jahjedtieson@users.noreply.github.com> Date: Tue, 18 Jan 2022 15:57:44 -0800 Subject: [PATCH 01/25] Navigation: * Combine capture data-and model-based filters with "OR" Client: * Update model and capture data date pickers to close when a date is picked --- client/src/components/controls/DateInputField.tsx | 1 + .../impl/NavigationSolr/NavigationSolr.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/client/src/components/controls/DateInputField.tsx b/client/src/components/controls/DateInputField.tsx index c65dfc706..7eab435a4 100644 --- a/client/src/components/controls/DateInputField.tsx +++ b/client/src/components/controls/DateInputField.tsx @@ -54,6 +54,7 @@ function DateInputField(props: DateInputFieldProps): React.ReactElement { className={classes.date} InputProps={{ disableUnderline: true }} onChange={onChange} + autoOk /> ); diff --git a/server/navigation/impl/NavigationSolr/NavigationSolr.ts b/server/navigation/impl/NavigationSolr/NavigationSolr.ts index bea33754c..7cfc1e114 100644 --- a/server/navigation/impl/NavigationSolr/NavigationSolr.ts +++ b/server/navigation/impl/NavigationSolr/NavigationSolr.ts @@ -98,10 +98,10 @@ export class NavigationSolr implements NAV.INavigation { // variantType: number[]; // idVocabulary[] for variant type filter // modelPurpose: number[]; // idVocabulary[] for model purpose filter // modelFileType: number[]; // idVocabulary[] for model file type filter - SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.captureMethod, 'ChildrenCaptureMethods'); - SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.variantType, 'ChildrenVariantTypes'); - SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.modelPurpose, 'ChildrenModelPurposes'); - SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.modelFileType, 'ChildrenModelFileTypes'); + SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.captureMethod, 'ChildrenCaptureMethods', '||'); + SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.variantType, 'ChildrenVariantTypes', '||'); + SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.modelPurpose, 'ChildrenModelPurposes', '||'); + SQ = await this.computeFilterParamFromVocabIDArray(SQ, filter.modelFileType, 'ChildrenModelFileTypes', '||'); // dateCreatedFrom: Date | null; // Date Created filter // dateCreatedTo: Date | null; // Date Created filter @@ -154,9 +154,11 @@ export class NavigationSolr implements NAV.INavigation { return this.computeFilterParamFromStrings(SQ, filterValueList, filterSchema, operator); } - private async computeFilterParamFromVocabIDArray(SQ: solr.Query, vocabFilterIDs: number[], filterSchema: string): Promise { + private async computeFilterParamFromVocabIDArray(SQ: solr.Query, vocabFilterIDs: number[], filterSchema: string, operator?: string | undefined): Promise { + if (operator === undefined) + operator = '&&'; const filterValueList: string[] | null = await this.transformVocabIDArrayToStrings(vocabFilterIDs); - return this.computeFilterParamFromStrings(SQ, filterValueList, filterSchema, '&&'); + return this.computeFilterParamFromStrings(SQ, filterValueList, filterSchema, operator); } private computeFilterParamFromStrings(SQ: solr.Query, filterValueList: string[] | null, filterSchema: string, operator: string): solr.Query { From 15d2f49d5d6ddec95a7c31dfed9405f92fc4e079 Mon Sep 17 00:00:00 2001 From: Jon Tyson <6943745+jahjedtieson@users.noreply.github.com> Date: Tue, 18 Jan 2022 16:15:49 -0800 Subject: [PATCH 02/25] DBAPI: * Handle invalid subject list input in Item.fetchDerivedFromSubjects() (avoid Prisma failure, which was otherwise handled gracefully) Client: * Default Item should have "Entire Subject" selected --- client/src/store/item.ts | 2 +- server/db/api/Item.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/store/item.ts b/client/src/store/item.ts index 109bba8b7..8a0ab09d2 100644 --- a/client/src/store/item.ts +++ b/client/src/store/item.ts @@ -9,7 +9,7 @@ import lodash from 'lodash'; export const defaultItem: StateItem = { id: 'default', name: '', - entireSubject: false, + entireSubject: true, selected: true }; diff --git a/server/db/api/Item.ts b/server/db/api/Item.ts index 7007d0660..486de62c5 100644 --- a/server/db/api/Item.ts +++ b/server/db/api/Item.ts @@ -158,6 +158,9 @@ export class Item extends DBC.DBObject implements ItemBase, SystemObje /* istanbul ignore if */ if (!idItems1) return null; + /* istanbul ignore if */ + if (idItems1.length === 0) + return []; // next, for those item IDs, find those with total relationships to subjects that equal our subject count // (i.e. all of their subject relationships are with our desired subjects and none other) From 21706b67f3bc961a4077ecceef2445342974517a Mon Sep 17 00:00:00 2001 From: Jon Tyson <6943745+jahjedtieson@users.noreply.github.com> Date: Tue, 18 Jan 2022 17:26:20 -0800 Subject: [PATCH 03/25] Client: * Display full date and time as a hover for the date created in the asset grid and asset version grid --- .../DetailsView/DetailsTab/AssetGrid.tsx | 16 ++++++++++++---- .../DetailsTab/AssetVersionsTable.tsx | 6 ++++-- client/src/utils/shared.ts | 7 +++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetGrid.tsx b/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetGrid.tsx index cdc03b132..63e4cbc15 100644 --- a/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetGrid.tsx +++ b/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetGrid.tsx @@ -9,14 +9,14 @@ * This component renders asset grid tab for the DetailsTab component. */ -import { Box, Button } from '@material-ui/core'; +import { Box, Button, Typography, Tooltip } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import { NewTabLink, EmptyTable } from '../../../../../components'; +import { NewTabLink, EmptyTable, ToolTip } from '../../../../../components'; import { eSystemObjectType, eIcon, eAssetGridColumnType, eLinkOrigin } from '../../../../../types/server'; import { getObjectAssets } from '../../../hooks/useDetailsView'; import { getDownloadAllAssetsUrlForObject } from '../../../../../utils/repository'; import { formatBytes } from '../../../../../utils/upload'; -import { sharedButtonProps, formatDate } from '../../../../../utils/shared'; +import { sharedButtonProps, formatDate, formatDateAndTime } from '../../../../../utils/shared'; import { updateSystemObjectUploadRedirect, attachSystemObjectUploadRedirect } from '../../../../../constants'; import { useHistory } from 'react-router-dom'; import React, { useEffect, useState } from 'react'; @@ -64,6 +64,10 @@ export const useStyles = makeStyles(({ palette }) => ({ fontSize: '0.8em', color: palette.primary.dark }, + date: { + fontSize: '0.9em', + color: palette.primary.dark + }, empty: { display: 'flex', alignItems: 'center', @@ -205,7 +209,11 @@ function AssetGrid(props: AssetGridProps): React.ReactElement { gridColumnObject.options = { ...gridColumnObject.options, customBodyRender(value) { - return formatDate(value); + return ( + }> + {formatDate(value)} + + ); } }; break; diff --git a/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetVersionsTable.tsx b/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetVersionsTable.tsx index 928dd1631..22af33e64 100644 --- a/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetVersionsTable.tsx +++ b/client/src/pages/Repository/components/DetailsView/DetailsTab/AssetVersionsTable.tsx @@ -11,7 +11,7 @@ import React, { useState } from 'react'; import { EmptyTable, NewTabLink, TextArea, ToolTip } from '../../../../../components'; import { StateDetailVersion } from '../../../../../store'; import { getDetailsUrlForObject, getDownloadAssetVersionUrlForObject } from '../../../../../utils/repository'; -import { formatDate } from '../../../../../utils/shared'; +import { formatDate, formatDateAndTime } from '../../../../../utils/shared'; import { formatBytes } from '../../../../../utils/upload'; import { useObjectVersions, rollbackAssetVersion } from '../../../hooks/useDetailsView'; import { useStyles } from './AssetGrid'; @@ -128,7 +128,9 @@ function AssetVersionsTable(props: AssetVersionsTableProps): React.ReactElement {version.creator} - {formatDate(version.dateCreated)} + }> + {formatDate(version.dateCreated)} + {formatBytes(version.size)} diff --git a/client/src/utils/shared.ts b/client/src/utils/shared.ts index 0ae82721a..65e687d83 100644 --- a/client/src/utils/shared.ts +++ b/client/src/utils/shared.ts @@ -86,3 +86,10 @@ export function formatDate(value: any): string { return ''; return date.toLocaleDateString(); } + +export function formatDateAndTime(value: any): string { + const date: Date | null = safeDate(value); + if (!date) + return ''; + return date.toLocaleString(); +} From ed8ae433d5dca75977bfc461d0554be6b5a51e7b Mon Sep 17 00:00:00 2001 From: Jon Tyson <6943745+jahjedtieson@users.noreply.github.com> Date: Tue, 18 Jan 2022 17:44:00 -0800 Subject: [PATCH 04/25] Client: * Rename parent(s) -> parents; child(ren) -> children GraphQL: * Sort related objects by object type and then by name in getSystemObjectDetails --- .../Metadata/Model/ObjectSelectModal.tsx | 14 +++++++------- .../Ingestion/components/Metadata/Model/index.tsx | 4 ++-- .../components/Metadata/Photogrammetry/index.tsx | 4 ++-- .../Ingestion/components/Metadata/Scene/index.tsx | 4 ++-- .../components/DetailsView/DetailsTab/index.tsx | 4 ++-- .../resolvers/queries/getSystemObjectDetails.ts | 8 ++++++++ 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/client/src/pages/Ingestion/components/Metadata/Model/ObjectSelectModal.tsx b/client/src/pages/Ingestion/components/Metadata/Model/ObjectSelectModal.tsx index 0e21458ed..fc0635517 100644 --- a/client/src/pages/Ingestion/components/Metadata/Model/ObjectSelectModal.tsx +++ b/client/src/pages/Ingestion/components/Metadata/Model/ObjectSelectModal.tsx @@ -85,18 +85,18 @@ function ObjectSelectModal(props: ObjectSelectModalProps): React.ReactElement { if (props.relationship === 'Source' && idSystemObject) { const { data } = await updateSourceObjects(idSystemObject, objectType, selectedRelationships, previouslySelectedObjects); if (data.updateSourceObjects.success) { - if (data.updateSourceObjects.status === 'success') toast.success('Parent(s) successfully added'); - if (data.updateSourceObjects.status === 'warn') toast.warn(`The following parent(s) had mismatched relationship: ${data.updateSourceObjects.message}`); + if (data.updateSourceObjects.status === 'success') toast.success('Parents successfully added'); + if (data.updateSourceObjects.status === 'warn') toast.warn(`The following parents had mismatched relationship: ${data.updateSourceObjects.message}`); } else { - toast.error('Parent(s) could not be added. Please try again later'); + toast.error('Parents could not be added. Please try again later'); } } else if (props.relationship === 'Derived' && idSystemObject) { const { data } = await updateDerivedObjects(idSystemObject, objectType, selectedRelationships, []); if (data.updateDerivedObjects.success) { - if (data.updateDerivedObjects.status === 'success') toast.success('Child(ren) successfully added'); - if (data.updateDerivedObjects.status === 'warn') toast.warn(`The following child(ren) had mismatched relationship: ${data.updateDerivedObjects.message}`); + if (data.updateDerivedObjects.status === 'success') toast.success('Children successfully added'); + if (data.updateDerivedObjects.status === 'warn') toast.warn(`The following children had mismatched relationship: ${data.updateDerivedObjects.message}`); } else { - toast.error('Child(ren) could not be added. Please try again later'); + toast.error('Children could not be added. Please try again later'); } } } catch (error) { @@ -186,7 +186,7 @@ function ObjectSelectModal(props: ObjectSelectModalProps): React.ReactElement { Close - Select {props?.relationship === 'Source' ? 'Parent(s)' : 'Child(ren)'} + Select {props?.relationship === 'Source' ? 'Parents' : 'Children'}