box-ui-elements 24.0.0-beta.4 → 24.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/explorer.js +1 -1
- package/dist/openwith.js +1 -1
- package/dist/picker.js +1 -1
- package/dist/preview.js +1 -1
- package/dist/sharing.js +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/uploader.js +1 -1
- package/es/api/Metadata.js +98 -13
- package/es/api/Metadata.js.flow +110 -12
- package/es/api/Metadata.js.map +1 -1
- package/es/elements/common/messages.js +16 -0
- package/es/elements/common/messages.js.flow +25 -0
- package/es/elements/common/messages.js.map +1 -1
- package/es/elements/content-explorer/Content.js +2 -1
- package/es/elements/content-explorer/Content.js.map +1 -1
- package/es/elements/content-explorer/ContentExplorer.js +19 -5
- package/es/elements/content-explorer/ContentExplorer.js.map +1 -1
- package/es/elements/content-explorer/MetadataQueryAPIHelper.js +61 -4
- package/es/elements/content-explorer/MetadataQueryAPIHelper.js.map +1 -1
- package/es/elements/content-explorer/MetadataSidePanel.js +40 -14
- package/es/elements/content-explorer/MetadataSidePanel.js.map +1 -1
- package/es/elements/content-explorer/MetadataViewContainer.js +55 -4
- package/es/elements/content-explorer/MetadataViewContainer.js.map +1 -1
- package/es/elements/content-explorer/stories/tests/MetadataView-visual.stories.js +61 -13
- package/es/elements/content-explorer/stories/tests/MetadataView-visual.stories.js.map +1 -1
- package/es/elements/content-explorer/utils.js +140 -12
- package/es/elements/content-explorer/utils.js.map +1 -1
- package/es/src/elements/content-explorer/ContentExplorer.d.ts +11 -3
- package/es/src/elements/content-explorer/MetadataQueryAPIHelper.d.ts +11 -1
- package/es/src/elements/content-explorer/MetadataSidePanel.d.ts +6 -3
- package/es/src/elements/content-explorer/MetadataViewContainer.d.ts +3 -1
- package/es/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.d.ts +1 -0
- package/es/src/elements/content-explorer/utils.d.ts +9 -3
- package/i18n/bn-IN.js +4 -0
- package/i18n/bn-IN.properties +4 -0
- package/i18n/da-DK.js +4 -0
- package/i18n/da-DK.properties +4 -0
- package/i18n/de-DE.js +5 -1
- package/i18n/de-DE.properties +4 -0
- package/i18n/en-AU.js +4 -0
- package/i18n/en-AU.properties +4 -0
- package/i18n/en-CA.js +4 -0
- package/i18n/en-CA.properties +4 -0
- package/i18n/en-GB.js +4 -0
- package/i18n/en-GB.properties +4 -0
- package/i18n/en-US.js +4 -0
- package/i18n/en-US.properties +8 -0
- package/i18n/en-x-pseudo.js +4 -0
- package/i18n/es-419.js +5 -1
- package/i18n/es-419.properties +4 -0
- package/i18n/es-ES.js +5 -1
- package/i18n/es-ES.properties +4 -0
- package/i18n/fi-FI.js +4 -0
- package/i18n/fi-FI.properties +4 -0
- package/i18n/fr-CA.js +4 -0
- package/i18n/fr-CA.properties +4 -0
- package/i18n/fr-FR.js +4 -0
- package/i18n/fr-FR.properties +4 -0
- package/i18n/hi-IN.js +4 -0
- package/i18n/hi-IN.properties +4 -0
- package/i18n/it-IT.js +4 -0
- package/i18n/it-IT.properties +4 -0
- package/i18n/ja-JP.js +6 -2
- package/i18n/ja-JP.properties +6 -2
- package/i18n/ko-KR.js +4 -0
- package/i18n/ko-KR.properties +4 -0
- package/i18n/nb-NO.js +4 -0
- package/i18n/nb-NO.properties +4 -0
- package/i18n/nl-NL.js +4 -0
- package/i18n/nl-NL.properties +4 -0
- package/i18n/pl-PL.js +4 -0
- package/i18n/pl-PL.properties +4 -0
- package/i18n/pt-BR.js +4 -0
- package/i18n/pt-BR.properties +4 -0
- package/i18n/ru-RU.js +5 -1
- package/i18n/ru-RU.properties +4 -0
- package/i18n/sv-SE.js +4 -0
- package/i18n/sv-SE.properties +4 -0
- package/i18n/tr-TR.js +5 -1
- package/i18n/tr-TR.properties +4 -0
- package/i18n/zh-CN.js +4 -0
- package/i18n/zh-CN.properties +4 -0
- package/i18n/zh-TW.js +4 -0
- package/i18n/zh-TW.properties +4 -0
- package/package.json +1 -1
- package/src/api/Metadata.js +110 -12
- package/src/api/__tests__/Metadata.test.js +120 -0
- package/src/elements/common/messages.js +25 -0
- package/src/elements/content-explorer/Content.tsx +1 -0
- package/src/elements/content-explorer/ContentExplorer.tsx +220 -181
- package/src/elements/content-explorer/MetadataQueryAPIHelper.ts +89 -4
- package/src/elements/content-explorer/MetadataSidePanel.tsx +55 -14
- package/src/elements/content-explorer/MetadataViewContainer.tsx +61 -1
- package/src/elements/content-explorer/__tests__/ContentExplorer.test.tsx +36 -2
- package/src/elements/content-explorer/__tests__/MetadataQueryAPIHelper.test.ts +8 -5
- package/src/elements/content-explorer/__tests__/MetadataSidePanel.test.tsx +145 -3
- package/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.tsx +54 -8
- package/src/elements/content-explorer/utils.ts +150 -13
|
@@ -6,18 +6,22 @@ import find from 'lodash/find';
|
|
|
6
6
|
import getProp from 'lodash/get';
|
|
7
7
|
import includes from 'lodash/includes';
|
|
8
8
|
import isArray from 'lodash/isArray';
|
|
9
|
-
import
|
|
9
|
+
import { areFieldValuesEqual, isEmptyValue, isMultiValuesField } from './utils';
|
|
10
10
|
import { JSON_PATCH_OP_ADD, JSON_PATCH_OP_REMOVE, JSON_PATCH_OP_REPLACE, JSON_PATCH_OP_TEST, METADATA_FIELD_TYPE_ENUM, METADATA_FIELD_TYPE_MULTISELECT } from '../../common/constants';
|
|
11
|
-
import { FIELD_NAME, FIELD_METADATA, FIELD_EXTENSION } from '../../constants';
|
|
11
|
+
import { FIELD_NAME, FIELD_METADATA, FIELD_EXTENSION, FIELD_PERMISSIONS } from '../../constants';
|
|
12
12
|
const SELECT_TYPES = [METADATA_FIELD_TYPE_ENUM, METADATA_FIELD_TYPE_MULTISELECT];
|
|
13
13
|
export default class MetadataQueryAPIHelper {
|
|
14
14
|
constructor(api) {
|
|
15
15
|
_defineProperty(this, "createJSONPatchOperations", (field, oldValue, newValue) => {
|
|
16
|
+
// check if two values are the same, return empty operations if so
|
|
17
|
+
if (areFieldValuesEqual(oldValue, newValue)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
16
20
|
let operation = JSON_PATCH_OP_REPLACE;
|
|
17
|
-
if (
|
|
21
|
+
if (isEmptyValue(oldValue) && !isEmptyValue(newValue)) {
|
|
18
22
|
operation = JSON_PATCH_OP_ADD;
|
|
19
23
|
}
|
|
20
|
-
if (oldValue &&
|
|
24
|
+
if (!isEmptyValue(oldValue) && isEmptyValue(newValue)) {
|
|
21
25
|
operation = JSON_PATCH_OP_REMOVE;
|
|
22
26
|
}
|
|
23
27
|
const testOp = {
|
|
@@ -113,6 +117,43 @@ export default class MetadataQueryAPIHelper {
|
|
|
113
117
|
this.templateKey = Object.keys(instance)[0];
|
|
114
118
|
return this.api.getMetadataAPI(true).getSchemaByTemplateKey(this.templateKey);
|
|
115
119
|
});
|
|
120
|
+
/**
|
|
121
|
+
* Generate operations for all fields update in the metadata sidepanel
|
|
122
|
+
*
|
|
123
|
+
* @private
|
|
124
|
+
* @return {JSONPatchOperations}
|
|
125
|
+
*/
|
|
126
|
+
_defineProperty(this, "generateOperations", (item, templateOldFields, templateNewFields) => {
|
|
127
|
+
const {
|
|
128
|
+
scope,
|
|
129
|
+
templateKey
|
|
130
|
+
} = this.metadataTemplate;
|
|
131
|
+
const itemFields = item.metadata[scope][templateKey];
|
|
132
|
+
const operations = templateNewFields.flatMap(newField => {
|
|
133
|
+
let newFieldValue = newField.value;
|
|
134
|
+
const {
|
|
135
|
+
key,
|
|
136
|
+
type
|
|
137
|
+
} = newField;
|
|
138
|
+
// when retrieve value from float type field, it gives a string instead
|
|
139
|
+
if (type === 'float' && newFieldValue !== '') {
|
|
140
|
+
newFieldValue = Number(newFieldValue);
|
|
141
|
+
}
|
|
142
|
+
const oldField = templateOldFields.find(f => f.key === key);
|
|
143
|
+
const oldFieldValue = oldField.value;
|
|
144
|
+
|
|
145
|
+
/*
|
|
146
|
+
Generate operations array based on all the fields' orignal value and the incoming updated value.
|
|
147
|
+
Edge Case:
|
|
148
|
+
If there are multiple items shared different value for enum or multi-select field, the form will
|
|
149
|
+
return 'Multiple values' as the value. In this case, it needs to generate operation based on the
|
|
150
|
+
actual item's field value.
|
|
151
|
+
*/
|
|
152
|
+
const shouldUseItemFieldValue = isMultiValuesField(type, oldFieldValue) && !isMultiValuesField(type, newFieldValue);
|
|
153
|
+
return this.createJSONPatchOperations(key, shouldUseItemFieldValue ? itemFields[key] : oldFieldValue, newFieldValue);
|
|
154
|
+
});
|
|
155
|
+
return operations;
|
|
156
|
+
});
|
|
116
157
|
_defineProperty(this, "queryMetadata", () => {
|
|
117
158
|
return new Promise((resolve, reject) => {
|
|
118
159
|
this.api.getMetadataQueryAPI().queryMetadata(this.metadataQuery, resolve, reject, {
|
|
@@ -130,6 +171,17 @@ export default class MetadataQueryAPIHelper {
|
|
|
130
171
|
const operations = this.createJSONPatchOperations(field, oldValue, newValue);
|
|
131
172
|
return this.api.getMetadataAPI(true).updateMetadata(file, this.metadataTemplate, operations, successCallback, errorCallback);
|
|
132
173
|
});
|
|
174
|
+
_defineProperty(this, "updateMetadataWithOperations", (item, operations, successCallback, errorCallback) => {
|
|
175
|
+
return this.api.getMetadataAPI(true).updateMetadata(item, this.metadataTemplate, operations, successCallback, errorCallback);
|
|
176
|
+
});
|
|
177
|
+
_defineProperty(this, "bulkUpdateMetadata", (items, templateOldFields, templateNewFields, successCallback, errorCallback) => {
|
|
178
|
+
const operations = [];
|
|
179
|
+
items.forEach(item => {
|
|
180
|
+
const operation = this.generateOperations(item, templateOldFields, templateNewFields);
|
|
181
|
+
operations.push(operation);
|
|
182
|
+
});
|
|
183
|
+
return this.api.getMetadataAPI(true).bulkUpdateMetadata(items, this.metadataTemplate, operations, successCallback, errorCallback);
|
|
184
|
+
});
|
|
133
185
|
/**
|
|
134
186
|
* Verify that the metadata query has required fields and update it if necessary
|
|
135
187
|
* For a file item, default fields included in the response are "type", "id", "etag"
|
|
@@ -148,6 +200,11 @@ export default class MetadataQueryAPIHelper {
|
|
|
148
200
|
if (!clonedFields.includes(FIELD_EXTENSION)) {
|
|
149
201
|
clonedFields.push(FIELD_EXTENSION);
|
|
150
202
|
}
|
|
203
|
+
|
|
204
|
+
// This field is necessary to check if the user has permission to update metadata
|
|
205
|
+
if (!clonedFields.includes(FIELD_PERMISSIONS)) {
|
|
206
|
+
clonedFields.push(FIELD_PERMISSIONS);
|
|
207
|
+
}
|
|
151
208
|
clonedQuery.fields = clonedFields;
|
|
152
209
|
return clonedQuery;
|
|
153
210
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetadataQueryAPIHelper.js","names":["cloneDeep","find","getProp","includes","isArray","isNil","JSON_PATCH_OP_ADD","JSON_PATCH_OP_REMOVE","JSON_PATCH_OP_REPLACE","JSON_PATCH_OP_TEST","METADATA_FIELD_TYPE_ENUM","METADATA_FIELD_TYPE_MULTISELECT","FIELD_NAME","FIELD_METADATA","FIELD_EXTENSION","SELECT_TYPES","MetadataQueryAPIHelper","constructor","api","_defineProperty","field","oldValue","newValue","operation","testOp","op","path","value","patchOp","fields","from","metadataQuery","filter","map","split","pop","metadata","templateFields","metadataTemplate","instance","templateScope","templateKey","queryFields","getMetadataQueryFields","queryField","templateField","type","displayName","key","options","enterprise","id","$id","templateSchemaResponse","entries","items","next_marker","nextMarker","metadataQueryResponseData","data","length","Promise","resolve","Object","keys","getMetadataAPI","getSchemaByTemplateKey","reject","getMetadataQueryAPI","queryMetadata","forceFetch","successCallback","errorCallback","verifyQueryFields","then","getTemplateSchemaInfo","getDataWithTypes","collection","catch","file","operations","createJSONPatchOperations","updateMetadata","clonedQuery","clonedFields","push"],"sources":["../../../src/elements/content-explorer/MetadataQueryAPIHelper.ts"],"sourcesContent":["import cloneDeep from 'lodash/cloneDeep';\nimport find from 'lodash/find';\nimport getProp from 'lodash/get';\nimport includes from 'lodash/includes';\nimport isArray from 'lodash/isArray';\nimport isNil from 'lodash/isNil';\nimport API from '../../api';\n\nimport {\n JSON_PATCH_OP_ADD,\n JSON_PATCH_OP_REMOVE,\n JSON_PATCH_OP_REPLACE,\n JSON_PATCH_OP_TEST,\n METADATA_FIELD_TYPE_ENUM,\n METADATA_FIELD_TYPE_MULTISELECT,\n} from '../../common/constants';\nimport { FIELD_NAME, FIELD_METADATA, FIELD_EXTENSION } from '../../constants';\n\nimport type { MetadataQuery as MetadataQueryType, MetadataQueryResponseData } from '../../common/types/metadataQueries';\nimport type {\n MetadataTemplateSchemaResponse,\n MetadataTemplate,\n MetadataFieldValue,\n MetadataType,\n MetadataQueryInstanceTypeField,\n} from '../../common/types/metadata';\nimport type { ElementsXhrError, JSONPatchOperations } from '../../common/types/api';\nimport type { Collection, BoxItem } from '../../common/types/core';\n\ntype SuccessCallback = (metadataQueryCollection: Collection, metadataTemplate: MetadataTemplate) => void;\ntype ErrorCallback = (e: ElementsXhrError) => void;\n\nconst SELECT_TYPES: Array<typeof METADATA_FIELD_TYPE_ENUM | typeof METADATA_FIELD_TYPE_MULTISELECT> = [\n METADATA_FIELD_TYPE_ENUM,\n METADATA_FIELD_TYPE_MULTISELECT,\n];\n\nexport default class MetadataQueryAPIHelper {\n api: API;\n\n metadataQueryResponseData: MetadataQueryResponseData;\n\n metadataTemplate: MetadataTemplate;\n\n templateKey: string;\n\n templateScope: string;\n\n metadataQuery: MetadataQueryType;\n\n constructor(api: API) {\n this.api = api;\n }\n\n createJSONPatchOperations = (\n field: string,\n oldValue: MetadataFieldValue | null,\n newValue: MetadataFieldValue | null,\n ): JSONPatchOperations => {\n let operation = JSON_PATCH_OP_REPLACE;\n\n if (isNil(oldValue) && newValue) {\n operation = JSON_PATCH_OP_ADD;\n }\n\n if (oldValue && isNil(newValue)) {\n operation = JSON_PATCH_OP_REMOVE;\n }\n\n const testOp = {\n op: JSON_PATCH_OP_TEST,\n path: `/${field}`,\n value: oldValue,\n };\n const patchOp = {\n op: operation,\n path: `/${field}`,\n value: newValue,\n };\n\n if (operation === JSON_PATCH_OP_REMOVE) {\n delete patchOp.value;\n }\n\n return operation === JSON_PATCH_OP_ADD ? [patchOp] : [testOp, patchOp];\n };\n\n getMetadataQueryFields = (): string[] => {\n /*\n Example metadata query:\n const query = {\n from: 'enterprise_12345.myAwesomeTemplateKey',\n fields: [\n 'name', // base representation field for an item (name, size, etag etc.)\n 'metadata.enterprise_12345.myAwesomeTemplateKey.field_1', // metadata instance field\n 'metadata.enterprise_12345.myAwesomeTemplateKey.field_2', // metadata instance field\n 'metadata.enterprise_12345.myAwesomeTemplateKey.field_3' // metadata instance field\n ],\n ancestor_folder_id: 0,\n };\n\n This function will return ['field_1', 'field_2', 'field_3']\n */\n const { fields = [], from } = this.metadataQuery;\n return fields.filter(field => field.includes(from)).map(field => field.split('.').pop());\n };\n\n flattenMetadata = (metadata?: MetadataType): MetadataType => {\n const templateFields = getProp(this.metadataTemplate, 'fields', []);\n const instance = getProp(metadata, `${this.templateScope}.${this.templateKey}`);\n\n if (!instance) {\n return {};\n }\n\n const queryFields = this.getMetadataQueryFields();\n\n const fields = queryFields.map((queryField: string) => {\n const templateField = find(templateFields, ['key', queryField]);\n const type = getProp(templateField, 'type'); // get data type\n const displayName = getProp(templateField, 'displayName', queryField); // get displayName, defaults to key\n\n const field: MetadataQueryInstanceTypeField = {\n key: `${FIELD_METADATA}.${this.templateScope}.${this.templateKey}.${queryField}`,\n value: instance[queryField],\n type,\n displayName,\n };\n\n if (includes(SELECT_TYPES, type)) {\n // get \"options\" for enums or multiselects\n field.options = getProp(templateField, 'options');\n }\n\n return field;\n });\n\n return {\n enterprise: {\n fields,\n id: instance.$id,\n },\n };\n };\n\n getDataWithTypes = (templateSchemaResponse?: MetadataTemplateSchemaResponse): Collection => {\n this.metadataTemplate = getProp(templateSchemaResponse, 'data');\n\n const { entries: items, next_marker: nextMarker }: MetadataQueryResponseData = this.metadataQueryResponseData;\n\n return {\n items,\n nextMarker,\n };\n };\n\n getTemplateSchemaInfo = (data: MetadataQueryResponseData): Promise<MetadataTemplateSchemaResponse | void> => {\n const { entries } = data;\n this.metadataQueryResponseData = data;\n if (!entries || entries.length === 0) {\n // Don't make metadata API call to get template info\n return Promise.resolve();\n }\n\n const metadata = getProp(entries, '[0].metadata');\n this.templateScope = Object.keys(metadata)[0];\n const instance = metadata[this.templateScope];\n this.templateKey = Object.keys(instance)[0];\n\n return this.api.getMetadataAPI(true).getSchemaByTemplateKey(this.templateKey);\n };\n\n queryMetadata = (): Promise<MetadataQueryResponseData> => {\n return new Promise((resolve, reject) => {\n this.api.getMetadataQueryAPI().queryMetadata(this.metadataQuery, resolve, reject, { forceFetch: true });\n });\n };\n\n fetchMetadataQueryResults = (\n metadataQuery: MetadataQueryType,\n successCallback: SuccessCallback,\n errorCallback: ErrorCallback,\n ): Promise<void> => {\n this.metadataQuery = this.verifyQueryFields(metadataQuery);\n return this.queryMetadata()\n .then(this.getTemplateSchemaInfo)\n .then(this.getDataWithTypes)\n .then((collection: Collection) => {\n return successCallback(collection, this.metadataTemplate);\n })\n .catch(errorCallback);\n };\n\n updateMetadata = (\n file: BoxItem,\n field: string,\n oldValue: MetadataFieldValue | null,\n newValue: MetadataFieldValue | null,\n successCallback: () => void,\n errorCallback: ErrorCallback,\n ): Promise<void> => {\n const operations = this.createJSONPatchOperations(field, oldValue, newValue);\n return this.api\n .getMetadataAPI(true)\n .updateMetadata(file, this.metadataTemplate, operations, successCallback, errorCallback);\n };\n\n /**\n * Verify that the metadata query has required fields and update it if necessary\n * For a file item, default fields included in the response are \"type\", \"id\", \"etag\"\n *\n * @param {MetadataQueryType} metadataQuery metadata query object\n * @return {MetadataQueryType} updated metadata query object with required fields\n */\n verifyQueryFields = (metadataQuery: MetadataQueryType): MetadataQueryType => {\n const clonedQuery = cloneDeep(metadataQuery);\n const clonedFields = isArray(clonedQuery.fields) ? clonedQuery.fields : [];\n\n // Make sure the query fields array has \"name\" field which is necessary to display info.\n if (!clonedFields.includes(FIELD_NAME)) {\n clonedFields.push(FIELD_NAME);\n }\n\n if (!clonedFields.includes(FIELD_EXTENSION)) {\n clonedFields.push(FIELD_EXTENSION);\n }\n\n clonedQuery.fields = clonedFields;\n\n return clonedQuery;\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MetadataQueryAPIHelper.js","names":["cloneDeep","find","getProp","includes","isArray","areFieldValuesEqual","isEmptyValue","isMultiValuesField","JSON_PATCH_OP_ADD","JSON_PATCH_OP_REMOVE","JSON_PATCH_OP_REPLACE","JSON_PATCH_OP_TEST","METADATA_FIELD_TYPE_ENUM","METADATA_FIELD_TYPE_MULTISELECT","FIELD_NAME","FIELD_METADATA","FIELD_EXTENSION","FIELD_PERMISSIONS","SELECT_TYPES","MetadataQueryAPIHelper","constructor","api","_defineProperty","field","oldValue","newValue","operation","testOp","op","path","value","patchOp","fields","from","metadataQuery","filter","map","split","pop","metadata","templateFields","metadataTemplate","instance","templateScope","templateKey","queryFields","getMetadataQueryFields","queryField","templateField","type","displayName","key","options","enterprise","id","$id","templateSchemaResponse","entries","items","next_marker","nextMarker","metadataQueryResponseData","data","length","Promise","resolve","Object","keys","getMetadataAPI","getSchemaByTemplateKey","item","templateOldFields","templateNewFields","scope","itemFields","operations","flatMap","newField","newFieldValue","Number","oldField","f","oldFieldValue","shouldUseItemFieldValue","createJSONPatchOperations","reject","getMetadataQueryAPI","queryMetadata","forceFetch","successCallback","errorCallback","verifyQueryFields","then","getTemplateSchemaInfo","getDataWithTypes","collection","catch","file","updateMetadata","forEach","generateOperations","push","bulkUpdateMetadata","clonedQuery","clonedFields"],"sources":["../../../src/elements/content-explorer/MetadataQueryAPIHelper.ts"],"sourcesContent":["import cloneDeep from 'lodash/cloneDeep';\nimport find from 'lodash/find';\nimport getProp from 'lodash/get';\nimport includes from 'lodash/includes';\nimport isArray from 'lodash/isArray';\nimport type { MetadataTemplateField } from '@box/metadata-editor';\nimport type { MetadataFieldType } from '@box/metadata-view';\nimport API from '../../api';\nimport { areFieldValuesEqual, isEmptyValue, isMultiValuesField } from './utils';\n\nimport {\n JSON_PATCH_OP_ADD,\n JSON_PATCH_OP_REMOVE,\n JSON_PATCH_OP_REPLACE,\n JSON_PATCH_OP_TEST,\n METADATA_FIELD_TYPE_ENUM,\n METADATA_FIELD_TYPE_MULTISELECT,\n} from '../../common/constants';\nimport { FIELD_NAME, FIELD_METADATA, FIELD_EXTENSION, FIELD_PERMISSIONS } from '../../constants';\n\nimport type { MetadataQuery as MetadataQueryType, MetadataQueryResponseData } from '../../common/types/metadataQueries';\nimport type {\n MetadataTemplateSchemaResponse,\n MetadataTemplate,\n MetadataFieldValue,\n MetadataType,\n MetadataQueryInstanceTypeField,\n} from '../../common/types/metadata';\nimport type { ElementsXhrError, JSONPatchOperations } from '../../common/types/api';\nimport type { Collection, BoxItem } from '../../common/types/core';\n\ntype SuccessCallback = (metadataQueryCollection: Collection, metadataTemplate: MetadataTemplate) => void;\ntype ErrorCallback = (e: ElementsXhrError) => void;\n\nconst SELECT_TYPES: Array<typeof METADATA_FIELD_TYPE_ENUM | typeof METADATA_FIELD_TYPE_MULTISELECT> = [\n METADATA_FIELD_TYPE_ENUM,\n METADATA_FIELD_TYPE_MULTISELECT,\n];\n\nexport default class MetadataQueryAPIHelper {\n api: API;\n\n metadataQueryResponseData: MetadataQueryResponseData;\n\n metadataTemplate: MetadataTemplate;\n\n templateKey: string;\n\n templateScope: string;\n\n metadataQuery: MetadataQueryType;\n\n constructor(api: API) {\n this.api = api;\n }\n\n createJSONPatchOperations = (\n field: string,\n oldValue: MetadataFieldValue | null,\n newValue: MetadataFieldValue | null,\n ): JSONPatchOperations => {\n // check if two values are the same, return empty operations if so\n if (areFieldValuesEqual(oldValue, newValue)) {\n return [];\n }\n\n let operation = JSON_PATCH_OP_REPLACE;\n\n if (isEmptyValue(oldValue) && !isEmptyValue(newValue)) {\n operation = JSON_PATCH_OP_ADD;\n }\n\n if (!isEmptyValue(oldValue) && isEmptyValue(newValue)) {\n operation = JSON_PATCH_OP_REMOVE;\n }\n\n const testOp = {\n op: JSON_PATCH_OP_TEST,\n path: `/${field}`,\n value: oldValue,\n };\n const patchOp = {\n op: operation,\n path: `/${field}`,\n value: newValue,\n };\n\n if (operation === JSON_PATCH_OP_REMOVE) {\n delete patchOp.value;\n }\n\n return operation === JSON_PATCH_OP_ADD ? [patchOp] : [testOp, patchOp];\n };\n\n getMetadataQueryFields = (): string[] => {\n /*\n Example metadata query:\n const query = {\n from: 'enterprise_12345.myAwesomeTemplateKey',\n fields: [\n 'name', // base representation field for an item (name, size, etag etc.)\n 'metadata.enterprise_12345.myAwesomeTemplateKey.field_1', // metadata instance field\n 'metadata.enterprise_12345.myAwesomeTemplateKey.field_2', // metadata instance field\n 'metadata.enterprise_12345.myAwesomeTemplateKey.field_3' // metadata instance field\n ],\n ancestor_folder_id: 0,\n };\n\n This function will return ['field_1', 'field_2', 'field_3']\n */\n const { fields = [], from } = this.metadataQuery;\n return fields.filter(field => field.includes(from)).map(field => field.split('.').pop());\n };\n\n flattenMetadata = (metadata?: MetadataType): MetadataType => {\n const templateFields = getProp(this.metadataTemplate, 'fields', []);\n const instance = getProp(metadata, `${this.templateScope}.${this.templateKey}`);\n\n if (!instance) {\n return {};\n }\n\n const queryFields = this.getMetadataQueryFields();\n\n const fields = queryFields.map((queryField: string) => {\n const templateField = find(templateFields, ['key', queryField]);\n const type = getProp(templateField, 'type'); // get data type\n const displayName = getProp(templateField, 'displayName', queryField); // get displayName, defaults to key\n\n const field: MetadataQueryInstanceTypeField = {\n key: `${FIELD_METADATA}.${this.templateScope}.${this.templateKey}.${queryField}`,\n value: instance[queryField],\n type,\n displayName,\n };\n\n if (includes(SELECT_TYPES, type)) {\n // get \"options\" for enums or multiselects\n field.options = getProp(templateField, 'options');\n }\n\n return field;\n });\n\n return {\n enterprise: {\n fields,\n id: instance.$id,\n },\n };\n };\n\n getDataWithTypes = (templateSchemaResponse?: MetadataTemplateSchemaResponse): Collection => {\n this.metadataTemplate = getProp(templateSchemaResponse, 'data');\n\n const { entries: items, next_marker: nextMarker }: MetadataQueryResponseData = this.metadataQueryResponseData;\n\n return {\n items,\n nextMarker,\n };\n };\n\n getTemplateSchemaInfo = (data: MetadataQueryResponseData): Promise<MetadataTemplateSchemaResponse | void> => {\n const { entries } = data;\n this.metadataQueryResponseData = data;\n if (!entries || entries.length === 0) {\n // Don't make metadata API call to get template info\n return Promise.resolve();\n }\n\n const metadata = getProp(entries, '[0].metadata');\n this.templateScope = Object.keys(metadata)[0];\n const instance = metadata[this.templateScope];\n this.templateKey = Object.keys(instance)[0];\n\n return this.api.getMetadataAPI(true).getSchemaByTemplateKey(this.templateKey);\n };\n\n /**\n * Generate operations for all fields update in the metadata sidepanel\n *\n * @private\n * @return {JSONPatchOperations}\n */\n generateOperations = (\n item: BoxItem,\n templateOldFields: MetadataTemplateField[],\n templateNewFields: MetadataTemplateField[],\n ): JSONPatchOperations => {\n const { scope, templateKey } = this.metadataTemplate;\n const itemFields = item.metadata[scope][templateKey];\n const operations = templateNewFields.flatMap(newField => {\n let newFieldValue = newField.value;\n const { key, type } = newField;\n // when retrieve value from float type field, it gives a string instead\n if (type === 'float' && newFieldValue !== '') {\n newFieldValue = Number(newFieldValue);\n }\n const oldField = templateOldFields.find(f => f.key === key);\n const oldFieldValue = oldField.value;\n\n /*\n Generate operations array based on all the fields' orignal value and the incoming updated value.\n\n Edge Case:\n If there are multiple items shared different value for enum or multi-select field, the form will\n return 'Multiple values' as the value. In this case, it needs to generate operation based on the\n actual item's field value.\n */\n const shouldUseItemFieldValue =\n isMultiValuesField(type as MetadataFieldType, oldFieldValue) &&\n !isMultiValuesField(type as MetadataFieldType, newFieldValue);\n\n return this.createJSONPatchOperations(\n key,\n shouldUseItemFieldValue ? itemFields[key] : oldFieldValue,\n newFieldValue,\n );\n });\n\n return operations;\n };\n\n queryMetadata = (): Promise<MetadataQueryResponseData> => {\n return new Promise((resolve, reject) => {\n this.api.getMetadataQueryAPI().queryMetadata(this.metadataQuery, resolve, reject, { forceFetch: true });\n });\n };\n\n fetchMetadataQueryResults = (\n metadataQuery: MetadataQueryType,\n successCallback: SuccessCallback,\n errorCallback: ErrorCallback,\n ): Promise<void> => {\n this.metadataQuery = this.verifyQueryFields(metadataQuery);\n return this.queryMetadata()\n .then(this.getTemplateSchemaInfo)\n .then(this.getDataWithTypes)\n .then((collection: Collection) => {\n return successCallback(collection, this.metadataTemplate);\n })\n .catch(errorCallback);\n };\n\n updateMetadata = (\n file: BoxItem,\n field: string,\n oldValue: MetadataFieldValue | null,\n newValue: MetadataFieldValue | null,\n successCallback: () => void,\n errorCallback: ErrorCallback,\n ): Promise<void> => {\n const operations = this.createJSONPatchOperations(field, oldValue, newValue);\n return this.api\n .getMetadataAPI(true)\n .updateMetadata(file, this.metadataTemplate, operations, successCallback, errorCallback);\n };\n\n updateMetadataWithOperations = (\n item: BoxItem,\n operations: JSONPatchOperations,\n successCallback: () => void,\n errorCallback: ErrorCallback,\n ): Promise<void> => {\n return this.api\n .getMetadataAPI(true)\n .updateMetadata(item, this.metadataTemplate, operations, successCallback, errorCallback);\n };\n\n bulkUpdateMetadata = (\n items: BoxItem[],\n templateOldFields: MetadataTemplateField[],\n templateNewFields: MetadataTemplateField[],\n successCallback: () => void,\n errorCallback: ErrorCallback,\n ): Promise<void> => {\n const operations: JSONPatchOperations = [];\n items.forEach(item => {\n const operation = this.generateOperations(item, templateOldFields, templateNewFields);\n operations.push(operation);\n });\n return this.api\n .getMetadataAPI(true)\n .bulkUpdateMetadata(items, this.metadataTemplate, operations, successCallback, errorCallback);\n };\n\n /**\n * Verify that the metadata query has required fields and update it if necessary\n * For a file item, default fields included in the response are \"type\", \"id\", \"etag\"\n *\n * @param {MetadataQueryType} metadataQuery metadata query object\n * @return {MetadataQueryType} updated metadata query object with required fields\n */\n verifyQueryFields = (metadataQuery: MetadataQueryType): MetadataQueryType => {\n const clonedQuery = cloneDeep(metadataQuery);\n const clonedFields = isArray(clonedQuery.fields) ? clonedQuery.fields : [];\n\n // Make sure the query fields array has \"name\" field which is necessary to display info.\n if (!clonedFields.includes(FIELD_NAME)) {\n clonedFields.push(FIELD_NAME);\n }\n\n if (!clonedFields.includes(FIELD_EXTENSION)) {\n clonedFields.push(FIELD_EXTENSION);\n }\n\n // This field is necessary to check if the user has permission to update metadata\n if (!clonedFields.includes(FIELD_PERMISSIONS)) {\n clonedFields.push(FIELD_PERMISSIONS);\n }\n\n clonedQuery.fields = clonedFields;\n\n return clonedQuery;\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl';
|
|
3
|
-
import { IconButton, SidePanel, Text } from '@box/blueprint-web';
|
|
3
|
+
import { IconButton, SidePanel, Text, useNotification } from '@box/blueprint-web';
|
|
4
4
|
import { XMark } from '@box/blueprint-web-assets/icons/Fill/index';
|
|
5
5
|
import { FileDefault } from '@box/blueprint-web-assets/icons/Line/index';
|
|
6
6
|
import { AutofillContextProvider, MetadataInstance, MetadataInstanceForm } from '@box/metadata-editor';
|
|
7
|
-
import {
|
|
7
|
+
import { useTemplateInstance, useSelectedItemText } from './utils';
|
|
8
8
|
import messages from '../common/messages';
|
|
9
9
|
import './MetadataSidePanel.scss';
|
|
10
10
|
const MetadataSidePanel = ({
|
|
11
11
|
currentCollection,
|
|
12
|
+
metadataTemplate,
|
|
12
13
|
onClose,
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
onUpdate,
|
|
15
|
+
refreshCollection,
|
|
16
|
+
selectedItemIds
|
|
15
17
|
}) => {
|
|
18
|
+
const {
|
|
19
|
+
addNotification
|
|
20
|
+
} = useNotification();
|
|
16
21
|
const {
|
|
17
22
|
formatMessage
|
|
18
23
|
} = useIntl();
|
|
@@ -20,26 +25,47 @@ const MetadataSidePanel = ({
|
|
|
20
25
|
const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = useState(false);
|
|
21
26
|
const selectedItemText = useSelectedItemText(currentCollection, selectedItemIds);
|
|
22
27
|
const selectedItems = selectedItemIds === 'all' ? currentCollection.items : currentCollection.items.filter(item => selectedItemIds.has(item.id));
|
|
23
|
-
const templateInstance =
|
|
28
|
+
const templateInstance = useTemplateInstance(metadataTemplate, selectedItems, isEditing);
|
|
24
29
|
const handleMetadataInstanceEdit = () => {
|
|
25
30
|
setIsEditing(true);
|
|
26
31
|
};
|
|
27
32
|
const handleMetadataInstanceFormCancel = () => {
|
|
28
33
|
setIsEditing(false);
|
|
29
34
|
};
|
|
30
|
-
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
32
|
-
const handleMetadataInstanceFormChange = values => {
|
|
33
|
-
// TODO: Implement on form change
|
|
34
|
-
};
|
|
35
35
|
const handleMetadataInstanceFormDiscardUnsavedChanges = () => {
|
|
36
36
|
setIsUnsavedChangesModalOpen(false);
|
|
37
37
|
setIsEditing(false);
|
|
38
38
|
};
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const handleUpdateMetadataSuccess = () => {
|
|
40
|
+
addNotification({
|
|
41
|
+
closeButtonAriaLabel: formatMessage(messages.close),
|
|
42
|
+
sensitivity: 'foreground',
|
|
43
|
+
styledText: formatMessage(messages.metadataUpdateSuccessNotification, {
|
|
44
|
+
numSelected: selectedItems.length
|
|
45
|
+
}),
|
|
46
|
+
typeIconAriaLabel: formatMessage(messages.success),
|
|
47
|
+
variant: 'success'
|
|
48
|
+
});
|
|
49
|
+
setIsEditing(false);
|
|
50
|
+
refreshCollection();
|
|
51
|
+
};
|
|
52
|
+
const handleUpdateMetadataError = () => {
|
|
53
|
+
addNotification({
|
|
54
|
+
closeButtonAriaLabel: formatMessage(messages.close),
|
|
55
|
+
sensitivity: 'foreground',
|
|
56
|
+
styledText: formatMessage(messages.metadataUpdateErrorNotification),
|
|
57
|
+
typeIconAriaLabel: formatMessage(messages.error),
|
|
58
|
+
variant: 'error'
|
|
59
|
+
});
|
|
60
|
+
};
|
|
41
61
|
const handleMetadataInstanceFormSubmit = async (values, operations) => {
|
|
42
|
-
|
|
62
|
+
const {
|
|
63
|
+
fields: templateNewFields
|
|
64
|
+
} = values.metadata;
|
|
65
|
+
const {
|
|
66
|
+
fields: templateOldFields
|
|
67
|
+
} = templateInstance;
|
|
68
|
+
await onUpdate(selectedItems, operations, templateOldFields, templateNewFields, handleUpdateMetadataSuccess, handleUpdateMetadataError);
|
|
43
69
|
};
|
|
44
70
|
return /*#__PURE__*/React.createElement(SidePanel, {
|
|
45
71
|
variant: "persistent"
|
|
@@ -73,7 +99,7 @@ const MetadataSidePanel = ({
|
|
|
73
99
|
isUnsavedChangesModalOpen: isUnsavedChangesModalOpen,
|
|
74
100
|
selectedTemplateInstance: templateInstance,
|
|
75
101
|
onCancel: handleMetadataInstanceFormCancel,
|
|
76
|
-
onChange:
|
|
102
|
+
onChange: null,
|
|
77
103
|
onDelete: null,
|
|
78
104
|
onDiscardUnsavedChanges: handleMetadataInstanceFormDiscardUnsavedChanges,
|
|
79
105
|
onSubmit: handleMetadataInstanceFormSubmit,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetadataSidePanel.js","names":["React","useState","useIntl","IconButton","SidePanel","Text","XMark","FileDefault","AutofillContextProvider","MetadataInstance","MetadataInstanceForm","getTemplateInstance","useSelectedItemText","messages","MetadataSidePanel","currentCollection","onClose","selectedItemIds","metadataTemplate","formatMessage","isEditing","setIsEditing","isUnsavedChangesModalOpen","setIsUnsavedChangesModalOpen","selectedItemText","selectedItems","items","filter","item","has","id","templateInstance","handleMetadataInstanceEdit","handleMetadataInstanceFormCancel","handleMetadataInstanceFormChange","values","handleMetadataInstanceFormDiscardUnsavedChanges","handleMetadataInstanceFormSubmit","operations","createElement","variant","Header","as","sidebarMetadataTitle","className","color","close","icon","onClick","size","ScrollableContainer","fetchSuggestions","isAiSuggestionsFeatureEnabled","areAiSuggestionsAvailable","isBetaLanguageEnabled","isDeleteButtonDisabled","isDeleteConfirmationModalCheckboxEnabled","isLargeFile","isMultilevelTaxonomyFieldEnabled","selectedTemplateInstance","onCancel","onChange","onDelete","onDiscardUnsavedChanges","onSubmit","taxonomyOptionsFetcher","onEdit","taxonomyNodeFetcher"],"sources":["../../../src/elements/content-explorer/MetadataSidePanel.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { IconButton, SidePanel, Text } from '@box/blueprint-web';\nimport { XMark } from '@box/blueprint-web-assets/icons/Fill/index';\nimport { FileDefault } from '@box/blueprint-web-assets/icons/Line/index';\nimport {\n AutofillContextProvider,\n FormValues,\n JSONPatchOperations,\n MetadataInstance,\n MetadataInstanceForm,\n} from '@box/metadata-editor';\n\nimport type { Selection } from 'react-aria-components';\nimport type { Collection } from '../../common/types/core';\nimport type { MetadataTemplate } from '../../common/types/metadata';\nimport { getTemplateInstance, useSelectedItemText } from './utils';\n\nimport messages from '../common/messages';\n\nimport './MetadataSidePanel.scss';\n\nexport interface MetadataSidePanelProps {\n currentCollection: Collection;\n onClose: () => void;\n metadataTemplate: MetadataTemplate;\n selectedItemIds: Selection;\n}\n\nconst MetadataSidePanel = ({\n currentCollection,\n onClose,\n selectedItemIds,\n metadataTemplate,\n}: MetadataSidePanelProps) => {\n const { formatMessage } = useIntl();\n const [isEditing, setIsEditing] = useState<boolean>(false);\n const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = useState<boolean>(false);\n\n const selectedItemText = useSelectedItemText(currentCollection, selectedItemIds);\n const selectedItems =\n selectedItemIds === 'all'\n ? currentCollection.items\n : currentCollection.items.filter(item => selectedItemIds.has(item.id));\n const templateInstance = getTemplateInstance(metadataTemplate, selectedItems);\n\n const handleMetadataInstanceEdit = () => {\n setIsEditing(true);\n };\n\n const handleMetadataInstanceFormCancel = () => {\n setIsEditing(false);\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const handleMetadataInstanceFormChange = (values: FormValues) => {\n // TODO: Implement on form change\n };\n\n const handleMetadataInstanceFormDiscardUnsavedChanges = () => {\n setIsUnsavedChangesModalOpen(false);\n setIsEditing(false);\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const handleMetadataInstanceFormSubmit = async (values: FormValues, operations: JSONPatchOperations) => {\n // TODO: Implement onSave callback\n };\n\n return (\n <SidePanel variant=\"persistent\">\n <SidePanel.Header>\n <div>\n <Text as=\"span\" variant=\"titleLarge\">\n {formatMessage(messages.sidebarMetadataTitle)}\n </Text>\n <div className=\"bce-MetadataSidePanel-subtitle\">\n <FileDefault />\n <Text as=\"span\" color=\"textOnLightSecondary\" variant=\"subtitle\">\n {selectedItemText}\n </Text>\n </div>\n </div>\n <IconButton aria-label={formatMessage(messages.close)} icon={XMark} onClick={onClose} size=\"large\" />\n </SidePanel.Header>\n <SidePanel.ScrollableContainer>\n <div className=\"bce-MetadataSidePanel-content\">\n <AutofillContextProvider fetchSuggestions={null} isAiSuggestionsFeatureEnabled={false}>\n {isEditing ? (\n <MetadataInstanceForm\n areAiSuggestionsAvailable={false}\n isAiSuggestionsFeatureEnabled={false}\n isBetaLanguageEnabled={false}\n isDeleteButtonDisabled={true}\n isDeleteConfirmationModalCheckboxEnabled={false}\n isLargeFile={false}\n isMultilevelTaxonomyFieldEnabled={false}\n isUnsavedChangesModalOpen={isUnsavedChangesModalOpen}\n selectedTemplateInstance={templateInstance}\n onCancel={handleMetadataInstanceFormCancel}\n onChange={handleMetadataInstanceFormChange}\n onDelete={null}\n onDiscardUnsavedChanges={handleMetadataInstanceFormDiscardUnsavedChanges}\n onSubmit={handleMetadataInstanceFormSubmit}\n setIsUnsavedChangesModalOpen={setIsUnsavedChangesModalOpen}\n taxonomyOptionsFetcher={null}\n />\n ) : (\n <MetadataInstance\n areAiSuggestionsAvailable={false}\n isAiSuggestionsFeatureEnabled={false}\n isBetaLanguageEnabled={false}\n onEdit={handleMetadataInstanceEdit}\n templateInstance={templateInstance}\n taxonomyNodeFetcher={null}\n />\n )}\n </AutofillContextProvider>\n </div>\n </SidePanel.ScrollableContainer>\n </SidePanel>\n );\n};\n\nexport default MetadataSidePanel;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MetadataSidePanel.js","names":["React","useState","useIntl","IconButton","SidePanel","Text","useNotification","XMark","FileDefault","AutofillContextProvider","MetadataInstance","MetadataInstanceForm","useTemplateInstance","useSelectedItemText","messages","MetadataSidePanel","currentCollection","metadataTemplate","onClose","onUpdate","refreshCollection","selectedItemIds","addNotification","formatMessage","isEditing","setIsEditing","isUnsavedChangesModalOpen","setIsUnsavedChangesModalOpen","selectedItemText","selectedItems","items","filter","item","has","id","templateInstance","handleMetadataInstanceEdit","handleMetadataInstanceFormCancel","handleMetadataInstanceFormDiscardUnsavedChanges","handleUpdateMetadataSuccess","closeButtonAriaLabel","close","sensitivity","styledText","metadataUpdateSuccessNotification","numSelected","length","typeIconAriaLabel","success","variant","handleUpdateMetadataError","metadataUpdateErrorNotification","error","handleMetadataInstanceFormSubmit","values","operations","fields","templateNewFields","metadata","templateOldFields","createElement","Header","as","sidebarMetadataTitle","className","color","icon","onClick","size","ScrollableContainer","fetchSuggestions","isAiSuggestionsFeatureEnabled","areAiSuggestionsAvailable","isBetaLanguageEnabled","isDeleteButtonDisabled","isDeleteConfirmationModalCheckboxEnabled","isLargeFile","isMultilevelTaxonomyFieldEnabled","selectedTemplateInstance","onCancel","onChange","onDelete","onDiscardUnsavedChanges","onSubmit","taxonomyOptionsFetcher","onEdit","taxonomyNodeFetcher"],"sources":["../../../src/elements/content-explorer/MetadataSidePanel.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { IconButton, SidePanel, Text, useNotification } from '@box/blueprint-web';\nimport { XMark } from '@box/blueprint-web-assets/icons/Fill/index';\nimport { FileDefault } from '@box/blueprint-web-assets/icons/Line/index';\nimport {\n AutofillContextProvider,\n FormValues,\n JSONPatchOperations,\n MetadataInstance,\n MetadataInstanceForm,\n type MetadataTemplateField,\n} from '@box/metadata-editor';\n\nimport type { Selection } from 'react-aria-components';\nimport type { BoxItem, Collection } from '../../common/types/core';\nimport type { MetadataTemplate } from '../../common/types/metadata';\nimport { useTemplateInstance, useSelectedItemText } from './utils';\n\nimport messages from '../common/messages';\n\nimport './MetadataSidePanel.scss';\n\nexport interface MetadataSidePanelProps {\n currentCollection: Collection;\n metadataTemplate: MetadataTemplate;\n onClose: () => void;\n onUpdate: (\n items: BoxItem[],\n operations: JSONPatchOperations,\n templateOldFields: MetadataTemplateField[],\n templateNewFields: MetadataTemplateField[],\n successCallback: () => void,\n errorCallback: ErrorCallback,\n ) => Promise<void>;\n refreshCollection: () => void;\n selectedItemIds: Selection;\n}\n\nconst MetadataSidePanel = ({\n currentCollection,\n metadataTemplate,\n onClose,\n onUpdate,\n refreshCollection,\n selectedItemIds,\n}: MetadataSidePanelProps) => {\n const { addNotification } = useNotification();\n const { formatMessage } = useIntl();\n const [isEditing, setIsEditing] = useState<boolean>(false);\n const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = useState<boolean>(false);\n\n const selectedItemText = useSelectedItemText(currentCollection, selectedItemIds);\n const selectedItems =\n selectedItemIds === 'all'\n ? currentCollection.items\n : currentCollection.items.filter(item => selectedItemIds.has(item.id));\n const templateInstance = useTemplateInstance(metadataTemplate, selectedItems, isEditing);\n\n const handleMetadataInstanceEdit = () => {\n setIsEditing(true);\n };\n\n const handleMetadataInstanceFormCancel = () => {\n setIsEditing(false);\n };\n\n const handleMetadataInstanceFormDiscardUnsavedChanges = () => {\n setIsUnsavedChangesModalOpen(false);\n setIsEditing(false);\n };\n\n const handleUpdateMetadataSuccess = () => {\n addNotification({\n closeButtonAriaLabel: formatMessage(messages.close),\n sensitivity: 'foreground',\n styledText: formatMessage(messages.metadataUpdateSuccessNotification, {\n numSelected: selectedItems.length,\n }),\n typeIconAriaLabel: formatMessage(messages.success),\n variant: 'success',\n });\n setIsEditing(false);\n refreshCollection();\n };\n\n const handleUpdateMetadataError = () => {\n addNotification({\n closeButtonAriaLabel: formatMessage(messages.close),\n sensitivity: 'foreground',\n styledText: formatMessage(messages.metadataUpdateErrorNotification),\n typeIconAriaLabel: formatMessage(messages.error),\n variant: 'error',\n });\n };\n\n const handleMetadataInstanceFormSubmit = async (values: FormValues, operations: JSONPatchOperations) => {\n const { fields: templateNewFields } = values.metadata;\n const { fields: templateOldFields } = templateInstance;\n\n await onUpdate(\n selectedItems,\n operations,\n templateOldFields,\n templateNewFields,\n handleUpdateMetadataSuccess,\n handleUpdateMetadataError,\n );\n };\n\n return (\n <SidePanel variant=\"persistent\">\n <SidePanel.Header>\n <div>\n <Text as=\"span\" variant=\"titleLarge\">\n {formatMessage(messages.sidebarMetadataTitle)}\n </Text>\n <div className=\"bce-MetadataSidePanel-subtitle\">\n <FileDefault />\n <Text as=\"span\" color=\"textOnLightSecondary\" variant=\"subtitle\">\n {selectedItemText}\n </Text>\n </div>\n </div>\n <IconButton aria-label={formatMessage(messages.close)} icon={XMark} onClick={onClose} size=\"large\" />\n </SidePanel.Header>\n <SidePanel.ScrollableContainer>\n <div className=\"bce-MetadataSidePanel-content\">\n <AutofillContextProvider fetchSuggestions={null} isAiSuggestionsFeatureEnabled={false}>\n {isEditing ? (\n <MetadataInstanceForm\n areAiSuggestionsAvailable={false}\n isAiSuggestionsFeatureEnabled={false}\n isBetaLanguageEnabled={false}\n isDeleteButtonDisabled={true}\n isDeleteConfirmationModalCheckboxEnabled={false}\n isLargeFile={false}\n isMultilevelTaxonomyFieldEnabled={false}\n isUnsavedChangesModalOpen={isUnsavedChangesModalOpen}\n selectedTemplateInstance={templateInstance}\n onCancel={handleMetadataInstanceFormCancel}\n onChange={null}\n onDelete={null}\n onDiscardUnsavedChanges={handleMetadataInstanceFormDiscardUnsavedChanges}\n onSubmit={handleMetadataInstanceFormSubmit}\n setIsUnsavedChangesModalOpen={setIsUnsavedChangesModalOpen}\n taxonomyOptionsFetcher={null}\n />\n ) : (\n <MetadataInstance\n areAiSuggestionsAvailable={false}\n isAiSuggestionsFeatureEnabled={false}\n isBetaLanguageEnabled={false}\n onEdit={handleMetadataInstanceEdit}\n templateInstance={templateInstance}\n taxonomyNodeFetcher={null}\n />\n )}\n </AutofillContextProvider>\n </div>\n </SidePanel.ScrollableContainer>\n </SidePanel>\n );\n};\n\nexport default MetadataSidePanel;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const _excluded = ["actionBarProps", "columns", "currentCollection", "metadataTemplate"]
|
|
1
|
+
const _excluded = ["actionBarProps", "columns", "currentCollection", "metadataTemplate", "onSortChange"],
|
|
2
|
+
_excluded2 = ["tableProps"];
|
|
2
3
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
3
4
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
5
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -13,6 +14,20 @@ import { MetadataView } from '@box/metadata-view';
|
|
|
13
14
|
// Public-friendly version of MetadataFormFieldValue from @box/metadata-filter
|
|
14
15
|
// (string[] for enum type, range/float objects stay the same)
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Helper function to trim metadataFieldNamePrefix from column names
|
|
19
|
+
* For example: 'metadata.enterprise_1515946.mdViewTemplate1.industry' -> 'industry'
|
|
20
|
+
*/
|
|
21
|
+
function trimMetadataFieldPrefix(column) {
|
|
22
|
+
// Check if the column starts with 'metadata.' and contains at least 2 dots
|
|
23
|
+
if (column.startsWith('metadata.') && column.split('.').length >= 3) {
|
|
24
|
+
// Split by dots and take everything after the first 3 parts
|
|
25
|
+
// metadata.enterprise_1515946.mdViewTemplate1.industry -> industry
|
|
26
|
+
const parts = column.split('.');
|
|
27
|
+
return parts.slice(3).join('.');
|
|
28
|
+
}
|
|
29
|
+
return column;
|
|
30
|
+
}
|
|
16
31
|
function transformInitialFilterValuesToInternal(publicValues) {
|
|
17
32
|
if (!publicValues) return undefined;
|
|
18
33
|
return Object.entries(publicValues).reduce((acc, [key, {
|
|
@@ -45,7 +60,8 @@ const MetadataViewContainer = _ref => {
|
|
|
45
60
|
actionBarProps,
|
|
46
61
|
columns,
|
|
47
62
|
currentCollection,
|
|
48
|
-
metadataTemplate
|
|
63
|
+
metadataTemplate,
|
|
64
|
+
onSortChange: onSortChangeInternal
|
|
49
65
|
} = _ref,
|
|
50
66
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
51
67
|
const {
|
|
@@ -86,11 +102,46 @@ const MetadataViewContainer = _ref => {
|
|
|
86
102
|
filterGroups
|
|
87
103
|
});
|
|
88
104
|
}, [actionBarProps, initialFilterValues, onFilterSubmit, filterGroups]);
|
|
105
|
+
|
|
106
|
+
// Extract the original tableProps.onSortChange from rest
|
|
107
|
+
const {
|
|
108
|
+
tableProps
|
|
109
|
+
} = rest,
|
|
110
|
+
otherRest = _objectWithoutProperties(rest, _excluded2);
|
|
111
|
+
const onSortChangeExternal = tableProps?.onSortChange;
|
|
112
|
+
|
|
113
|
+
// Create a wrapper function that calls both. The wrapper function should follow the signature of onSortChange from RAC
|
|
114
|
+
const handleSortChange = React.useCallback(({
|
|
115
|
+
column,
|
|
116
|
+
direction
|
|
117
|
+
}) => {
|
|
118
|
+
// Call the internal onSortChange first
|
|
119
|
+
// API accepts asc/desc "https://developer.box.com/reference/post-metadata-queries-execute-read/"
|
|
120
|
+
if (onSortChangeInternal) {
|
|
121
|
+
const trimmedColumn = trimMetadataFieldPrefix(String(column));
|
|
122
|
+
onSortChangeInternal(trimmedColumn, direction === 'ascending' ? 'ASC' : 'DESC');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Then call the original customer-provided onSortChange if it exists
|
|
126
|
+
// Accepts "ascending" / "descending" (https://react-spectrum.adobe.com/react-aria/Table.html)
|
|
127
|
+
if (onSortChangeExternal) {
|
|
128
|
+
onSortChangeExternal({
|
|
129
|
+
column,
|
|
130
|
+
direction
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}, [onSortChangeInternal, onSortChangeExternal]);
|
|
134
|
+
|
|
135
|
+
// Create new tableProps with our wrapper function
|
|
136
|
+
const newTableProps = _objectSpread(_objectSpread({}, tableProps), {}, {
|
|
137
|
+
onSortChange: handleSortChange
|
|
138
|
+
});
|
|
89
139
|
return /*#__PURE__*/React.createElement(MetadataView, _extends({
|
|
90
140
|
actionBarProps: transformedActionBarProps,
|
|
91
141
|
columns: columns,
|
|
92
|
-
items: items
|
|
93
|
-
|
|
142
|
+
items: items,
|
|
143
|
+
tableProps: newTableProps
|
|
144
|
+
}, otherRest));
|
|
94
145
|
};
|
|
95
146
|
export default MetadataViewContainer;
|
|
96
147
|
//# sourceMappingURL=MetadataViewContainer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetadataViewContainer.js","names":["React","MetadataView","transformInitialFilterValuesToInternal","publicValues","undefined","Object","entries","reduce","acc","key","value","Array","isArray","enum","transformInternalFieldsToPublic","fields","MetadataViewContainer","_ref","actionBarProps","columns","currentCollection","metadataTemplate","rest","_objectWithoutProperties","_excluded","items","initialFilterValues","initialFilterValuesProp","onFilterSubmit","onFilterSubmitProp","filterGroups","useMemo","toggleable","filters","map","field","id","name","displayName","fieldType","type","options","shouldRenderChip","useCallback","transformed","transformedActionBarProps","_objectSpread","createElement","_extends"],"sources":["../../../src/elements/content-explorer/MetadataViewContainer.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { EnumType, FloatType, MetadataFormFieldValue, RangeType } from '@box/metadata-filter';\nimport { MetadataView, type MetadataViewProps } from '@box/metadata-view';\n\nimport type { Collection } from '../../common/types/core';\nimport type { MetadataTemplate } from '../../common/types/metadata';\n\n// Public-friendly version of MetadataFormFieldValue from @box/metadata-filter\n// (string[] for enum type, range/float objects stay the same)\ntype EnumToStringArray<T> = T extends EnumType ? string[] : T;\ntype ExternalMetadataFormFieldValue = EnumToStringArray<MetadataFormFieldValue>;\n\ntype ExternalFilterValues = Record<\n string,\n {\n value: ExternalMetadataFormFieldValue;\n }\n>;\n\ntype ActionBarProps = Omit<\n MetadataViewProps['actionBarProps'],\n 'initialFilterValues' | 'onFilterSubmit' | 'filterGroups'\n> & {\n initialFilterValues?: ExternalFilterValues;\n onFilterSubmit?: (filterValues: ExternalFilterValues) => void;\n};\n\nfunction transformInitialFilterValuesToInternal(\n publicValues?: ExternalFilterValues,\n): Record<string, { value: MetadataFormFieldValue }> | undefined {\n if (!publicValues) return undefined;\n\n return Object.entries(publicValues).reduce<Record<string, { value: MetadataFormFieldValue }>>(\n (acc, [key, { value }]) => {\n acc[key] = Array.isArray(value) ? { value: { enum: value } } : { value };\n return acc;\n },\n {},\n );\n}\n\nfunction transformInternalFieldsToPublic(\n fields: Record<string, { value: MetadataFormFieldValue }>,\n): ExternalFilterValues {\n return Object.entries(fields).reduce<ExternalFilterValues>((acc, [key, { value }]) => {\n acc[key] =\n 'enum' in value && Array.isArray(value.enum)\n ? { value: value.enum }\n : { value: value as RangeType | FloatType };\n return acc;\n }, {});\n}\n\nexport interface MetadataViewContainerProps extends Omit<MetadataViewProps, 'items' | 'actionBarProps'> {\n actionBarProps?: ActionBarProps;\n currentCollection: Collection;\n metadataTemplate: MetadataTemplate;\n}\n\nconst MetadataViewContainer = ({\n actionBarProps,\n columns,\n currentCollection,\n metadataTemplate,\n ...rest\n}: MetadataViewContainerProps) => {\n const { items = [] } = currentCollection;\n const { initialFilterValues: initialFilterValuesProp, onFilterSubmit: onFilterSubmitProp } = actionBarProps ?? {};\n\n const filterGroups = React.useMemo(\n () => [\n {\n toggleable: true,\n filters:\n metadataTemplate?.fields?.map(field => {\n return {\n id: `${field.key}-filter`,\n name: field.displayName,\n fieldType: field.type,\n options: field.options?.map(({ key }) => key) || [],\n shouldRenderChip: true,\n };\n }) || [],\n },\n ],\n [metadataTemplate],\n );\n\n // Transform initial filter values to internal field format\n const initialFilterValues = React.useMemo(\n () => transformInitialFilterValuesToInternal(initialFilterValuesProp),\n [initialFilterValuesProp],\n );\n\n // Transform field values to public-friendly format\n const onFilterSubmit = React.useCallback(\n (fields: Record<string, { value: MetadataFormFieldValue }>) => {\n if (!onFilterSubmitProp) return;\n const transformed = transformInternalFieldsToPublic(fields);\n onFilterSubmitProp(transformed);\n },\n [onFilterSubmitProp],\n );\n\n const transformedActionBarProps = React.useMemo(() => {\n return {\n ...actionBarProps,\n initialFilterValues,\n onFilterSubmit,\n filterGroups,\n };\n }, [actionBarProps, initialFilterValues, onFilterSubmit, filterGroups]);\n\n return <MetadataView actionBarProps={transformedActionBarProps} columns={columns} items={items} {...rest} />;\n};\n\nexport default MetadataViewContainer;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MetadataViewContainer.js","names":["React","MetadataView","trimMetadataFieldPrefix","column","startsWith","split","length","parts","slice","join","transformInitialFilterValuesToInternal","publicValues","undefined","Object","entries","reduce","acc","key","value","Array","isArray","enum","transformInternalFieldsToPublic","fields","MetadataViewContainer","_ref","actionBarProps","columns","currentCollection","metadataTemplate","onSortChange","onSortChangeInternal","rest","_objectWithoutProperties","_excluded","items","initialFilterValues","initialFilterValuesProp","onFilterSubmit","onFilterSubmitProp","filterGroups","useMemo","toggleable","filters","map","field","id","name","displayName","fieldType","type","options","shouldRenderChip","useCallback","transformed","transformedActionBarProps","_objectSpread","tableProps","otherRest","_excluded2","onSortChangeExternal","handleSortChange","direction","trimmedColumn","String","newTableProps","createElement","_extends"],"sources":["../../../src/elements/content-explorer/MetadataViewContainer.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { EnumType, FloatType, MetadataFormFieldValue, RangeType } from '@box/metadata-filter';\nimport { MetadataView, type MetadataViewProps } from '@box/metadata-view';\nimport { type Key } from '@react-types/shared';\n\nimport { SortDescriptor } from 'react-aria-components';\nimport type { Collection } from '../../common/types/core';\nimport type { MetadataTemplate } from '../../common/types/metadata';\n\n// Public-friendly version of MetadataFormFieldValue from @box/metadata-filter\n// (string[] for enum type, range/float objects stay the same)\ntype EnumToStringArray<T> = T extends EnumType ? string[] : T;\ntype ExternalMetadataFormFieldValue = EnumToStringArray<MetadataFormFieldValue>;\n\ntype ExternalFilterValues = Record<\n string,\n {\n value: ExternalMetadataFormFieldValue;\n }\n>;\n\ntype ActionBarProps = Omit<\n MetadataViewProps['actionBarProps'],\n 'initialFilterValues' | 'onFilterSubmit' | 'filterGroups'\n> & {\n initialFilterValues?: ExternalFilterValues;\n onFilterSubmit?: (filterValues: ExternalFilterValues) => void;\n};\n\n/**\n * Helper function to trim metadataFieldNamePrefix from column names\n * For example: 'metadata.enterprise_1515946.mdViewTemplate1.industry' -> 'industry'\n */\nfunction trimMetadataFieldPrefix(column: string): string {\n // Check if the column starts with 'metadata.' and contains at least 2 dots\n if (column.startsWith('metadata.') && column.split('.').length >= 3) {\n // Split by dots and take everything after the first 3 parts\n // metadata.enterprise_1515946.mdViewTemplate1.industry -> industry\n const parts = column.split('.');\n return parts.slice(3).join('.');\n }\n return column;\n}\n\nfunction transformInitialFilterValuesToInternal(\n publicValues?: ExternalFilterValues,\n): Record<string, { value: MetadataFormFieldValue }> | undefined {\n if (!publicValues) return undefined;\n\n return Object.entries(publicValues).reduce<Record<string, { value: MetadataFormFieldValue }>>(\n (acc, [key, { value }]) => {\n acc[key] = Array.isArray(value) ? { value: { enum: value } } : { value };\n return acc;\n },\n {},\n );\n}\n\nfunction transformInternalFieldsToPublic(\n fields: Record<string, { value: MetadataFormFieldValue }>,\n): ExternalFilterValues {\n return Object.entries(fields).reduce<ExternalFilterValues>((acc, [key, { value }]) => {\n acc[key] =\n 'enum' in value && Array.isArray(value.enum)\n ? { value: value.enum }\n : { value: value as RangeType | FloatType };\n return acc;\n }, {});\n}\n\nexport interface MetadataViewContainerProps extends Omit<MetadataViewProps, 'items' | 'actionBarProps'> {\n actionBarProps?: ActionBarProps;\n currentCollection: Collection;\n metadataTemplate: MetadataTemplate;\n /* Internally controlled onSortChange prop for the MetadataView component. */\n onSortChange?: (sortBy: Key, sortDirection: string) => void;\n}\n\nconst MetadataViewContainer = ({\n actionBarProps,\n columns,\n currentCollection,\n metadataTemplate,\n onSortChange: onSortChangeInternal,\n ...rest\n}: MetadataViewContainerProps) => {\n const { items = [] } = currentCollection;\n const { initialFilterValues: initialFilterValuesProp, onFilterSubmit: onFilterSubmitProp } = actionBarProps ?? {};\n\n const filterGroups = React.useMemo(\n () => [\n {\n toggleable: true,\n filters:\n metadataTemplate?.fields?.map(field => {\n return {\n id: `${field.key}-filter`,\n name: field.displayName,\n fieldType: field.type,\n options: field.options?.map(({ key }) => key) || [],\n shouldRenderChip: true,\n };\n }) || [],\n },\n ],\n [metadataTemplate],\n );\n\n // Transform initial filter values to internal field format\n const initialFilterValues = React.useMemo(\n () => transformInitialFilterValuesToInternal(initialFilterValuesProp),\n [initialFilterValuesProp],\n );\n\n // Transform field values to public-friendly format\n const onFilterSubmit = React.useCallback(\n (fields: Record<string, { value: MetadataFormFieldValue }>) => {\n if (!onFilterSubmitProp) return;\n const transformed = transformInternalFieldsToPublic(fields);\n onFilterSubmitProp(transformed);\n },\n [onFilterSubmitProp],\n );\n\n const transformedActionBarProps = React.useMemo(() => {\n return {\n ...actionBarProps,\n initialFilterValues,\n onFilterSubmit,\n filterGroups,\n };\n }, [actionBarProps, initialFilterValues, onFilterSubmit, filterGroups]);\n\n // Extract the original tableProps.onSortChange from rest\n const { tableProps, ...otherRest } = rest;\n const onSortChangeExternal = tableProps?.onSortChange;\n\n // Create a wrapper function that calls both. The wrapper function should follow the signature of onSortChange from RAC\n const handleSortChange = React.useCallback(\n ({ column, direction }: SortDescriptor) => {\n // Call the internal onSortChange first\n // API accepts asc/desc \"https://developer.box.com/reference/post-metadata-queries-execute-read/\"\n if (onSortChangeInternal) {\n const trimmedColumn = trimMetadataFieldPrefix(String(column));\n onSortChangeInternal(trimmedColumn, direction === 'ascending' ? 'ASC' : 'DESC');\n }\n\n // Then call the original customer-provided onSortChange if it exists\n // Accepts \"ascending\" / \"descending\" (https://react-spectrum.adobe.com/react-aria/Table.html)\n if (onSortChangeExternal) {\n onSortChangeExternal({\n column,\n direction,\n });\n }\n },\n [onSortChangeInternal, onSortChangeExternal],\n );\n\n // Create new tableProps with our wrapper function\n const newTableProps = {\n ...tableProps,\n onSortChange: handleSortChange,\n };\n\n return (\n <MetadataView\n actionBarProps={transformedActionBarProps}\n columns={columns}\n items={items}\n tableProps={newTableProps}\n {...otherRest}\n />\n );\n};\n\nexport default MetadataViewContainer;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -8,6 +8,7 @@ import { Download, SignMeOthers } from '@box/blueprint-web-assets/icons/Fill/ind
|
|
|
8
8
|
import { Sign } from '@box/blueprint-web-assets/icons/Line';
|
|
9
9
|
import { expect, fn, userEvent, waitFor, within, screen } from 'storybook/test';
|
|
10
10
|
import noop from 'lodash/noop';
|
|
11
|
+
import orderBy from 'lodash/orderBy';
|
|
11
12
|
import ContentExplorer from '../../ContentExplorer';
|
|
12
13
|
import { DEFAULT_HOSTNAME_API } from '../../../../constants';
|
|
13
14
|
import { mockMetadata, mockSchema } from '../../../common/__mocks__/mockMetadata';
|
|
@@ -131,25 +132,20 @@ const metadataViewV2WithBulkItemActions = _objectSpread(_objectSpread({}, metada
|
|
|
131
132
|
export const metadataViewV2 = {
|
|
132
133
|
args: metadataViewV2ElementProps
|
|
133
134
|
};
|
|
134
|
-
|
|
135
|
-
// @TODO Assert that rows are actually sorted in a different order, once handleSortChange is implemented
|
|
136
135
|
export const metadataViewV2SortsFromHeader = {
|
|
137
136
|
args: metadataViewV2ElementProps,
|
|
138
137
|
play: async ({
|
|
139
138
|
canvas
|
|
140
139
|
}) => {
|
|
141
|
-
await
|
|
142
|
-
expect(canvas.getByRole('row', {
|
|
143
|
-
name: /Industry/i
|
|
144
|
-
})).toBeInTheDocument();
|
|
145
|
-
});
|
|
146
|
-
const firstRow = canvas.getByRole('row', {
|
|
147
|
-
name: /Industry/i
|
|
148
|
-
});
|
|
149
|
-
const industryHeader = within(firstRow).getByRole('columnheader', {
|
|
140
|
+
const industryHeader = await canvas.findByRole('columnheader', {
|
|
150
141
|
name: 'Industry'
|
|
151
142
|
});
|
|
152
|
-
|
|
143
|
+
expect(industryHeader).toBeInTheDocument();
|
|
144
|
+
const firstRow = await canvas.findByRole('row', {
|
|
145
|
+
name: /Child 2/i
|
|
146
|
+
});
|
|
147
|
+
expect(firstRow).toBeInTheDocument();
|
|
148
|
+
await userEvent.click(industryHeader);
|
|
153
149
|
}
|
|
154
150
|
};
|
|
155
151
|
export const metadataViewV2WithCustomActions = {
|
|
@@ -263,6 +259,43 @@ export const metadataViewV2WithBulkItemActionMenuShowsItemActionMenu = {
|
|
|
263
259
|
expect(downloadAction).toBeInTheDocument();
|
|
264
260
|
}
|
|
265
261
|
};
|
|
262
|
+
export const sidePanelOpenWithMultipleItemsSelected = {
|
|
263
|
+
args: _objectSpread(_objectSpread({}, metadataViewV2ElementProps), {}, {
|
|
264
|
+
metadataViewProps: {
|
|
265
|
+
columns,
|
|
266
|
+
tableProps: {
|
|
267
|
+
isSelectAllEnabled: true
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}),
|
|
271
|
+
play: async ({
|
|
272
|
+
canvas
|
|
273
|
+
}) => {
|
|
274
|
+
await waitFor(() => {
|
|
275
|
+
expect(canvas.getByRole('row', {
|
|
276
|
+
name: /Child 2/i
|
|
277
|
+
})).toBeInTheDocument();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Select the first row by clicking its checkbox
|
|
281
|
+
const firstItem = canvas.getByRole('row', {
|
|
282
|
+
name: /Child 2/i
|
|
283
|
+
});
|
|
284
|
+
const checkbox = within(firstItem).getByRole('checkbox');
|
|
285
|
+
await userEvent.click(checkbox);
|
|
286
|
+
|
|
287
|
+
// Select the second row by clicking its checkbox
|
|
288
|
+
const secondItem = canvas.getAllByRole('row', {
|
|
289
|
+
name: /Child 1/i
|
|
290
|
+
})[0];
|
|
291
|
+
const secondCheckbox = within(secondItem).getByRole('checkbox');
|
|
292
|
+
await userEvent.click(secondCheckbox);
|
|
293
|
+
const metadataButton = canvas.getByRole('button', {
|
|
294
|
+
name: 'Metadata'
|
|
295
|
+
});
|
|
296
|
+
await userEvent.click(metadataButton);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
266
299
|
const meta = {
|
|
267
300
|
title: 'Elements/ContentExplorer/tests/MetadataView/visual',
|
|
268
301
|
component: ContentExplorer,
|
|
@@ -273,7 +306,22 @@ const meta = {
|
|
|
273
306
|
},
|
|
274
307
|
parameters: {
|
|
275
308
|
msw: {
|
|
276
|
-
handlers: [
|
|
309
|
+
handlers: [
|
|
310
|
+
// Note that the Metadata API backend normally handles the sorting. The mocks below simulate the sorting for specific cases, but may not 100% accurately reflect the backend behavior.
|
|
311
|
+
http.post(`${DEFAULT_HOSTNAME_API}/2.0/metadata_queries/execute_read`, async ({
|
|
312
|
+
request
|
|
313
|
+
}) => {
|
|
314
|
+
const body = await request.clone().json();
|
|
315
|
+
const orderByDirection = body.order_by[0].direction;
|
|
316
|
+
const orderByFieldKey = body.order_by[0].field_key;
|
|
317
|
+
|
|
318
|
+
// Hardcoded case for sorting by industry
|
|
319
|
+
if (orderByFieldKey === `industry` && orderByDirection === 'ASC') {
|
|
320
|
+
const sortedMetadata = orderBy(mockMetadata.entries, 'metadata.enterprise_0.templateName.industry', 'asc');
|
|
321
|
+
return HttpResponse.json(_objectSpread(_objectSpread({}, mockMetadata), {}, {
|
|
322
|
+
entries: sortedMetadata
|
|
323
|
+
}));
|
|
324
|
+
}
|
|
277
325
|
return HttpResponse.json(mockMetadata);
|
|
278
326
|
}), http.get(`${DEFAULT_HOSTNAME_API}/2.0/metadata_templates/enterprise/templateName/schema`, () => {
|
|
279
327
|
return HttpResponse.json(mockSchema);
|