box-ui-elements 24.0.0-beta.3 → 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/common/withBlueprintModernization.js +16 -0
- package/es/elements/common/withBlueprintModernization.js.map +1 -0
- 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 +21 -6
- 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/ContentExplorer-visual.stories.js +5 -0
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js.flow +6 -0
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.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/elements/content-picker/ContentPicker.js +4 -1
- package/es/elements/content-picker/ContentPicker.js.flow +4 -1
- package/es/elements/content-picker/ContentPicker.js.map +1 -1
- package/es/elements/content-picker/stories/tests/ContentPicker-visual.stories.js +5 -0
- package/es/elements/content-picker/stories/tests/ContentPicker-visual.stories.js.flow +6 -0
- package/es/elements/content-picker/stories/tests/ContentPicker-visual.stories.js.map +1 -1
- package/es/elements/content-preview/ContentPreview.js +3 -1
- package/es/elements/content-preview/ContentPreview.js.flow +3 -0
- package/es/elements/content-preview/ContentPreview.js.map +1 -1
- package/es/elements/content-preview/stories/tests/ContentPreview-visual.stories.js +5 -0
- package/es/elements/content-preview/stories/tests/ContentPreview-visual.stories.js.flow +7 -1
- package/es/elements/content-preview/stories/tests/ContentPreview-visual.stories.js.map +1 -1
- package/es/elements/content-sharing/ContentSharing.js +4 -1
- package/es/elements/content-sharing/ContentSharing.js.flow +4 -1
- package/es/elements/content-sharing/ContentSharing.js.map +1 -1
- package/es/elements/content-sidebar/ContentSidebar.js +3 -1
- package/es/elements/content-sidebar/ContentSidebar.js.flow +3 -0
- package/es/elements/content-sidebar/ContentSidebar.js.map +1 -1
- package/es/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.js +5 -0
- package/es/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.js.map +1 -1
- package/es/elements/content-uploader/ContentUploader.js +3 -1
- package/es/elements/content-uploader/ContentUploader.js.map +1 -1
- package/es/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js +5 -0
- package/es/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js.flow +6 -0
- package/es/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js.map +1 -1
- package/es/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.js +51 -0
- package/es/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.js.map +1 -0
- package/es/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.scss +29 -0
- package/es/features/classification/applied-by-ai-classification-reason/messages.js +13 -0
- package/es/features/classification/applied-by-ai-classification-reason/messages.js.map +1 -0
- package/es/features/classification/types.js +2 -0
- package/es/features/classification/types.js.map +1 -0
- package/es/src/elements/common/__tests__/withBlueprintModernization.test.d.ts +1 -0
- package/es/src/elements/common/withBlueprintModernization.d.ts +3 -0
- 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/es/src/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.d.ts +5 -0
- package/es/src/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.d.ts +6 -0
- package/es/src/features/classification/applied-by-ai-classification-reason/__tests__/AppliedByAiClassificationReason.test.d.ts +1 -0
- package/es/src/features/classification/applied-by-ai-classification-reason/messages.d.ts +13 -0
- package/es/src/features/classification/types.d.ts +6 -0
- package/i18n/bn-IN.js +8 -2
- package/i18n/bn-IN.properties +6 -2
- package/i18n/da-DK.js +8 -2
- package/i18n/da-DK.properties +6 -2
- package/i18n/de-DE.js +8 -2
- package/i18n/de-DE.properties +6 -2
- package/i18n/en-AU.js +6 -0
- package/i18n/en-AU.properties +4 -0
- package/i18n/en-CA.js +6 -0
- package/i18n/en-CA.properties +4 -0
- package/i18n/en-GB.js +6 -0
- package/i18n/en-GB.properties +4 -0
- package/i18n/en-US.js +6 -0
- package/i18n/en-US.properties +12 -0
- package/i18n/en-x-pseudo.js +6 -0
- package/i18n/es-419.js +8 -2
- package/i18n/es-419.properties +6 -2
- package/i18n/es-ES.js +8 -2
- package/i18n/es-ES.properties +6 -2
- package/i18n/fi-FI.js +8 -2
- package/i18n/fi-FI.properties +6 -2
- package/i18n/fr-CA.js +8 -2
- package/i18n/fr-CA.properties +6 -2
- package/i18n/fr-FR.js +8 -2
- package/i18n/fr-FR.properties +6 -2
- package/i18n/hi-IN.js +8 -2
- package/i18n/hi-IN.properties +6 -2
- package/i18n/it-IT.js +8 -2
- package/i18n/it-IT.properties +6 -2
- package/i18n/ja-JP.js +8 -2
- package/i18n/ja-JP.properties +6 -2
- package/i18n/ko-KR.js +8 -2
- package/i18n/ko-KR.properties +6 -2
- package/i18n/nb-NO.js +8 -2
- package/i18n/nb-NO.properties +6 -2
- package/i18n/nl-NL.js +8 -2
- package/i18n/nl-NL.properties +6 -2
- package/i18n/pl-PL.js +8 -2
- package/i18n/pl-PL.properties +6 -2
- package/i18n/pt-BR.js +8 -2
- package/i18n/pt-BR.properties +6 -2
- package/i18n/ru-RU.js +8 -2
- package/i18n/ru-RU.properties +6 -2
- package/i18n/sv-SE.js +8 -2
- package/i18n/sv-SE.properties +6 -2
- package/i18n/tr-TR.js +8 -2
- package/i18n/tr-TR.properties +6 -2
- package/i18n/zh-CN.js +8 -2
- package/i18n/zh-CN.properties +6 -2
- package/i18n/zh-TW.js +8 -2
- package/i18n/zh-TW.properties +6 -2
- 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/__tests__/withBlueprintModernization.test.tsx +91 -0
- package/src/elements/common/messages.js +25 -0
- package/src/elements/common/withBlueprintModernization.tsx +24 -0
- package/src/elements/content-explorer/Content.tsx +1 -0
- package/src/elements/content-explorer/ContentExplorer.tsx +224 -182
- 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/ContentExplorer-visual.stories.js +6 -0
- package/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.tsx +54 -8
- package/src/elements/content-explorer/utils.ts +150 -13
- package/src/elements/content-picker/ContentPicker.js +4 -1
- package/src/elements/content-picker/stories/tests/ContentPicker-visual.stories.js +6 -0
- package/src/elements/content-preview/ContentPreview.js +3 -0
- package/src/elements/content-preview/stories/tests/ContentPreview-visual.stories.js +7 -1
- package/src/elements/content-sharing/ContentSharing.js +4 -1
- package/src/elements/content-sidebar/ContentSidebar.js +3 -0
- package/src/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.tsx +6 -0
- package/src/elements/content-uploader/ContentUploader.tsx +3 -1
- package/src/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js +6 -0
- package/src/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.scss +29 -0
- package/src/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.tsx +55 -0
- package/src/features/classification/applied-by-ai-classification-reason/__tests__/AppliedByAiClassificationReason.test.tsx +105 -0
- package/src/features/classification/applied-by-ai-classification-reason/messages.ts +18 -0
- package/src/features/classification/types.ts +7 -0
package/es/api/Metadata.js
CHANGED
|
@@ -23,7 +23,7 @@ import partition from 'lodash/partition';
|
|
|
23
23
|
import uniq from 'lodash/uniq';
|
|
24
24
|
import uniqueId from 'lodash/uniqueId';
|
|
25
25
|
import { getBadItemError, getBadPermissionsError, isUserCorrectableError } from '../utils/error';
|
|
26
|
-
import { getTypedFileId } from '../utils/file';
|
|
26
|
+
import { getTypedFileId, getTypedFolderId } from '../utils/file';
|
|
27
27
|
import { handleOnAbort, formatMetadataFieldValue } from './utils';
|
|
28
28
|
import File from './File';
|
|
29
29
|
import { HEADER_CONTENT_TYPE, METADATA_SCOPE_ENTERPRISE, METADATA_SCOPE_GLOBAL, METADATA_TEMPLATE_FETCH_LIMIT, METADATA_TEMPLATE_PROPERTIES, METADATA_TEMPLATE_CLASSIFICATION, METADATA_TEMPLATE_SKILLS, METADATA_SUGGESTIONS_CONFIDENCE_EXPERIMENTAL, FIELD_METADATA_SKILLS, CACHE_PREFIX_METADATA, ERROR_CODE_UPDATE_SKILLS, ERROR_CODE_UPDATE_METADATA, ERROR_CODE_CREATE_METADATA, ERROR_CODE_DELETE_METADATA, ERROR_CODE_FETCH_METADATA, ERROR_CODE_FETCH_METADATA_TEMPLATES, ERROR_CODE_FETCH_SKILLS, ERROR_CODE_FETCH_METADATA_OPTIONS, ERROR_CODE_FETCH_METADATA_SUGGESTIONS, ERROR_CODE_EMPTY_METADATA_SUGGESTIONS, TYPE_FILE, ERROR_CODE_FETCH_METADATA_TAXONOMY_NODE, ERROR_CODE_FETCH_METADATA_TAXONOMY } from '../constants';
|
|
@@ -58,6 +58,16 @@ class Metadata extends File {
|
|
|
58
58
|
return `${this.getMetadataCacheKey(id)}_classification`;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Creates a key for the metadata template schema cache
|
|
63
|
+
*
|
|
64
|
+
* @param {string} templateKey - template key
|
|
65
|
+
* @return {string} key
|
|
66
|
+
*/
|
|
67
|
+
getMetadataTemplateSchemaCacheKey(templateKey) {
|
|
68
|
+
return `${CACHE_PREFIX_METADATA}template_schema_${templateKey}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
/**
|
|
62
72
|
* API URL for metadata
|
|
63
73
|
*
|
|
@@ -73,6 +83,21 @@ class Metadata extends File {
|
|
|
73
83
|
return baseUrl;
|
|
74
84
|
}
|
|
75
85
|
|
|
86
|
+
/**
|
|
87
|
+
* API URL for metadata
|
|
88
|
+
*
|
|
89
|
+
* @param {string} id - a Box folder id
|
|
90
|
+
* @param {string} field - metadata field
|
|
91
|
+
* @return {string} base url for files
|
|
92
|
+
*/
|
|
93
|
+
getMetadataUrlForFolder(id, scope, template) {
|
|
94
|
+
const baseUrl = `${this.getBaseApiUrl()}/folders/${id}/metadata`;
|
|
95
|
+
if (scope && template) {
|
|
96
|
+
return `${baseUrl}/${scope}/${template}`;
|
|
97
|
+
}
|
|
98
|
+
return baseUrl;
|
|
99
|
+
}
|
|
100
|
+
|
|
76
101
|
/**
|
|
77
102
|
* API URL for metadata templates for a scope
|
|
78
103
|
*
|
|
@@ -276,11 +301,24 @@ class Metadata extends File {
|
|
|
276
301
|
* @param {string} templateKey - template key
|
|
277
302
|
* @return {Promise} Promise object of metadata template
|
|
278
303
|
*/
|
|
279
|
-
getSchemaByTemplateKey(templateKey) {
|
|
304
|
+
async getSchemaByTemplateKey(templateKey) {
|
|
305
|
+
const cache = this.getCache();
|
|
306
|
+
const key = this.getMetadataTemplateSchemaCacheKey(templateKey);
|
|
307
|
+
|
|
308
|
+
// Return cached value if it exists
|
|
309
|
+
if (cache.has(key)) {
|
|
310
|
+
return cache.get(key);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Fetch from API if not cached
|
|
280
314
|
const url = this.getMetadataTemplateSchemaUrl(templateKey);
|
|
281
|
-
|
|
315
|
+
const response = await this.xhr.get({
|
|
282
316
|
url
|
|
283
317
|
});
|
|
318
|
+
|
|
319
|
+
// Cache the response
|
|
320
|
+
cache.set(key, response);
|
|
321
|
+
return response;
|
|
284
322
|
}
|
|
285
323
|
|
|
286
324
|
/**
|
|
@@ -631,23 +669,29 @@ class Metadata extends File {
|
|
|
631
669
|
}
|
|
632
670
|
|
|
633
671
|
/**
|
|
634
|
-
* API for patching metadata on file
|
|
672
|
+
* API for patching metadata on item (file/folder)
|
|
635
673
|
*
|
|
636
|
-
* @param {BoxItem}
|
|
674
|
+
* @param {BoxItem} item - File/Folder object for which we are changing the description
|
|
637
675
|
* @param {Object} template - Metadata template
|
|
638
676
|
* @param {Array} operations - Array of JSON patch operations
|
|
639
677
|
* @param {Function} successCallback - Success callback
|
|
640
678
|
* @param {Function} errorCallback - Error callback
|
|
679
|
+
* @param {boolean} suppressCallbacks - Boolean to decide whether suppress callbacks or not
|
|
641
680
|
* @return {Promise}
|
|
642
681
|
*/
|
|
643
|
-
async updateMetadata(
|
|
682
|
+
async updateMetadata(item, template, operations, successCallback, errorCallback, suppressCallbacks) {
|
|
644
683
|
this.errorCode = ERROR_CODE_UPDATE_METADATA;
|
|
645
|
-
|
|
646
|
-
|
|
684
|
+
if (!suppressCallbacks) {
|
|
685
|
+
// Only set callbacks when we intend to invoke them for this call
|
|
686
|
+
// so that callers performing bulk operations can suppress per-item callbacks
|
|
687
|
+
this.successCallback = successCallback;
|
|
688
|
+
this.errorCallback = errorCallback;
|
|
689
|
+
}
|
|
647
690
|
const {
|
|
648
691
|
id,
|
|
649
|
-
permissions
|
|
650
|
-
|
|
692
|
+
permissions,
|
|
693
|
+
type
|
|
694
|
+
} = item;
|
|
651
695
|
if (!id || !permissions) {
|
|
652
696
|
this.errorHandler(getBadItemError());
|
|
653
697
|
return;
|
|
@@ -659,11 +703,11 @@ class Metadata extends File {
|
|
|
659
703
|
}
|
|
660
704
|
try {
|
|
661
705
|
const metadata = await this.xhr.put({
|
|
662
|
-
url: this.getMetadataUrl(id, template.scope, template.templateKey),
|
|
706
|
+
url: type === 'file' ? this.getMetadataUrl(id, template.scope, template.templateKey) : this.getMetadataUrlForFolder(id, template.scope, template.templateKey),
|
|
663
707
|
headers: {
|
|
664
708
|
[HEADER_CONTENT_TYPE]: 'application/json-patch+json'
|
|
665
709
|
},
|
|
666
|
-
id: getTypedFileId(id),
|
|
710
|
+
id: type === 'file' ? getTypedFileId(id) : getTypedFolderId(id),
|
|
667
711
|
data: operations
|
|
668
712
|
});
|
|
669
713
|
if (!this.isDestroyed()) {
|
|
@@ -676,13 +720,54 @@ class Metadata extends File {
|
|
|
676
720
|
instance
|
|
677
721
|
}) => instance.id === editor.instance.id), 1, editor);
|
|
678
722
|
}
|
|
679
|
-
|
|
723
|
+
if (!suppressCallbacks) {
|
|
724
|
+
this.successHandler(editor);
|
|
725
|
+
}
|
|
680
726
|
}
|
|
681
727
|
} catch (e) {
|
|
728
|
+
if (suppressCallbacks) {
|
|
729
|
+
// Let the caller decide how to handle errors (e.g., aggregate for bulk operations)
|
|
730
|
+
throw e;
|
|
731
|
+
}
|
|
682
732
|
this.errorHandler(e);
|
|
683
733
|
}
|
|
684
734
|
}
|
|
685
735
|
|
|
736
|
+
/**
|
|
737
|
+
* API for bulk patching metadata on items (file/folder)
|
|
738
|
+
*
|
|
739
|
+
* @param {BoxItem[]} items - File/Folder object for which we are changing the description
|
|
740
|
+
* @param {Object} template - Metadata template
|
|
741
|
+
* @param {Array} operations - Array of JSON patch operations for each item
|
|
742
|
+
* @param {Function} successCallback - Success callback
|
|
743
|
+
* @param {Function} errorCallback - Error callback
|
|
744
|
+
* @return {Promise}
|
|
745
|
+
*/
|
|
746
|
+
async bulkUpdateMetadata(items, template, operations, successCallback, errorCallback) {
|
|
747
|
+
this.errorCode = ERROR_CODE_UPDATE_METADATA;
|
|
748
|
+
this.successCallback = successCallback;
|
|
749
|
+
this.errorCallback = errorCallback;
|
|
750
|
+
try {
|
|
751
|
+
const updatePromises = items.map(async (item, index) => {
|
|
752
|
+
try {
|
|
753
|
+
// Suppress per-item callbacks; aggregate outcome at the bulk level only
|
|
754
|
+
await this.updateMetadata(item, template, operations[index], successCallback, errorCallback, true);
|
|
755
|
+
} catch (e) {
|
|
756
|
+
// Re-throw to be caught by Promise.all and handled once below
|
|
757
|
+
throw new Error(`Failed to update metadata: ${e.message || e}`);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
await Promise.all(updatePromises);
|
|
761
|
+
if (!this.isDestroyed()) {
|
|
762
|
+
this.successHandler();
|
|
763
|
+
}
|
|
764
|
+
} catch (e) {
|
|
765
|
+
if (!this.isDestroyed()) {
|
|
766
|
+
this.errorHandler(e);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
686
771
|
/**
|
|
687
772
|
* API for patching metadata on file
|
|
688
773
|
*
|
package/es/api/Metadata.js.flow
CHANGED
|
@@ -16,7 +16,7 @@ import partition from 'lodash/partition';
|
|
|
16
16
|
import uniq from 'lodash/uniq';
|
|
17
17
|
import uniqueId from 'lodash/uniqueId';
|
|
18
18
|
import { getBadItemError, getBadPermissionsError, isUserCorrectableError } from '../utils/error';
|
|
19
|
-
import { getTypedFileId } from '../utils/file';
|
|
19
|
+
import { getTypedFileId, getTypedFolderId } from '../utils/file';
|
|
20
20
|
import { handleOnAbort, formatMetadataFieldValue } from './utils';
|
|
21
21
|
import File from './File';
|
|
22
22
|
import {
|
|
@@ -90,6 +90,16 @@ class Metadata extends File {
|
|
|
90
90
|
return `${this.getMetadataCacheKey(id)}_classification`;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Creates a key for the metadata template schema cache
|
|
95
|
+
*
|
|
96
|
+
* @param {string} templateKey - template key
|
|
97
|
+
* @return {string} key
|
|
98
|
+
*/
|
|
99
|
+
getMetadataTemplateSchemaCacheKey(templateKey: string): string {
|
|
100
|
+
return `${CACHE_PREFIX_METADATA}template_schema_${templateKey}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
93
103
|
/**
|
|
94
104
|
* API URL for metadata
|
|
95
105
|
*
|
|
@@ -105,6 +115,21 @@ class Metadata extends File {
|
|
|
105
115
|
return baseUrl;
|
|
106
116
|
}
|
|
107
117
|
|
|
118
|
+
/**
|
|
119
|
+
* API URL for metadata
|
|
120
|
+
*
|
|
121
|
+
* @param {string} id - a Box folder id
|
|
122
|
+
* @param {string} field - metadata field
|
|
123
|
+
* @return {string} base url for files
|
|
124
|
+
*/
|
|
125
|
+
getMetadataUrlForFolder(id: string, scope?: string, template?: string): string {
|
|
126
|
+
const baseUrl = `${this.getBaseApiUrl()}/folders/${id}/metadata`;
|
|
127
|
+
if (scope && template) {
|
|
128
|
+
return `${baseUrl}/${scope}/${template}`;
|
|
129
|
+
}
|
|
130
|
+
return baseUrl;
|
|
131
|
+
}
|
|
132
|
+
|
|
108
133
|
/**
|
|
109
134
|
* API URL for metadata templates for a scope
|
|
110
135
|
*
|
|
@@ -337,9 +362,23 @@ class Metadata extends File {
|
|
|
337
362
|
* @param {string} templateKey - template key
|
|
338
363
|
* @return {Promise} Promise object of metadata template
|
|
339
364
|
*/
|
|
340
|
-
getSchemaByTemplateKey(templateKey: string): Promise<MetadataTemplateSchemaResponse> {
|
|
365
|
+
async getSchemaByTemplateKey(templateKey: string): Promise<MetadataTemplateSchemaResponse> {
|
|
366
|
+
const cache: APICache = this.getCache();
|
|
367
|
+
const key = this.getMetadataTemplateSchemaCacheKey(templateKey);
|
|
368
|
+
|
|
369
|
+
// Return cached value if it exists
|
|
370
|
+
if (cache.has(key)) {
|
|
371
|
+
return cache.get(key);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Fetch from API if not cached
|
|
341
375
|
const url = this.getMetadataTemplateSchemaUrl(templateKey);
|
|
342
|
-
|
|
376
|
+
const response = await this.xhr.get({ url });
|
|
377
|
+
|
|
378
|
+
// Cache the response
|
|
379
|
+
cache.set(key, response);
|
|
380
|
+
|
|
381
|
+
return response;
|
|
343
382
|
}
|
|
344
383
|
|
|
345
384
|
/**
|
|
@@ -786,27 +825,33 @@ class Metadata extends File {
|
|
|
786
825
|
}
|
|
787
826
|
|
|
788
827
|
/**
|
|
789
|
-
* API for patching metadata on file
|
|
828
|
+
* API for patching metadata on item (file/folder)
|
|
790
829
|
*
|
|
791
|
-
* @param {BoxItem}
|
|
830
|
+
* @param {BoxItem} item - File/Folder object for which we are changing the description
|
|
792
831
|
* @param {Object} template - Metadata template
|
|
793
832
|
* @param {Array} operations - Array of JSON patch operations
|
|
794
833
|
* @param {Function} successCallback - Success callback
|
|
795
834
|
* @param {Function} errorCallback - Error callback
|
|
835
|
+
* @param {boolean} suppressCallbacks - Boolean to decide whether suppress callbacks or not
|
|
796
836
|
* @return {Promise}
|
|
797
837
|
*/
|
|
798
838
|
async updateMetadata(
|
|
799
|
-
|
|
839
|
+
item: BoxItem,
|
|
800
840
|
template: MetadataTemplate,
|
|
801
841
|
operations: JSONPatchOperations,
|
|
802
842
|
successCallback: Function,
|
|
803
843
|
errorCallback: ElementsErrorCallback,
|
|
844
|
+
suppressCallbacks?: boolean,
|
|
804
845
|
): Promise<void> {
|
|
805
846
|
this.errorCode = ERROR_CODE_UPDATE_METADATA;
|
|
806
|
-
|
|
807
|
-
|
|
847
|
+
if (!suppressCallbacks) {
|
|
848
|
+
// Only set callbacks when we intend to invoke them for this call
|
|
849
|
+
// so that callers performing bulk operations can suppress per-item callbacks
|
|
850
|
+
this.successCallback = successCallback;
|
|
851
|
+
this.errorCallback = errorCallback;
|
|
852
|
+
}
|
|
808
853
|
|
|
809
|
-
const { id, permissions } =
|
|
854
|
+
const { id, permissions, type } = item;
|
|
810
855
|
if (!id || !permissions) {
|
|
811
856
|
this.errorHandler(getBadItemError());
|
|
812
857
|
return;
|
|
@@ -821,11 +866,14 @@ class Metadata extends File {
|
|
|
821
866
|
|
|
822
867
|
try {
|
|
823
868
|
const metadata = await this.xhr.put({
|
|
824
|
-
url:
|
|
869
|
+
url:
|
|
870
|
+
type === 'file'
|
|
871
|
+
? this.getMetadataUrl(id, template.scope, template.templateKey)
|
|
872
|
+
: this.getMetadataUrlForFolder(id, template.scope, template.templateKey),
|
|
825
873
|
headers: {
|
|
826
874
|
[HEADER_CONTENT_TYPE]: 'application/json-patch+json',
|
|
827
875
|
},
|
|
828
|
-
id: getTypedFileId(id),
|
|
876
|
+
id: type === 'file' ? getTypedFileId(id) : getTypedFolderId(id),
|
|
829
877
|
data: operations,
|
|
830
878
|
});
|
|
831
879
|
if (!this.isDestroyed()) {
|
|
@@ -840,13 +888,63 @@ class Metadata extends File {
|
|
|
840
888
|
editor,
|
|
841
889
|
);
|
|
842
890
|
}
|
|
843
|
-
|
|
891
|
+
if (!suppressCallbacks) {
|
|
892
|
+
this.successHandler(editor);
|
|
893
|
+
}
|
|
844
894
|
}
|
|
845
895
|
} catch (e) {
|
|
896
|
+
if (suppressCallbacks) {
|
|
897
|
+
// Let the caller decide how to handle errors (e.g., aggregate for bulk operations)
|
|
898
|
+
throw e;
|
|
899
|
+
}
|
|
846
900
|
this.errorHandler(e);
|
|
847
901
|
}
|
|
848
902
|
}
|
|
849
903
|
|
|
904
|
+
/**
|
|
905
|
+
* API for bulk patching metadata on items (file/folder)
|
|
906
|
+
*
|
|
907
|
+
* @param {BoxItem[]} items - File/Folder object for which we are changing the description
|
|
908
|
+
* @param {Object} template - Metadata template
|
|
909
|
+
* @param {Array} operations - Array of JSON patch operations for each item
|
|
910
|
+
* @param {Function} successCallback - Success callback
|
|
911
|
+
* @param {Function} errorCallback - Error callback
|
|
912
|
+
* @return {Promise}
|
|
913
|
+
*/
|
|
914
|
+
async bulkUpdateMetadata(
|
|
915
|
+
items: BoxItem[],
|
|
916
|
+
template: MetadataTemplate,
|
|
917
|
+
operations: JSONPatchOperations[],
|
|
918
|
+
successCallback: Function,
|
|
919
|
+
errorCallback: ElementsErrorCallback,
|
|
920
|
+
): Promise<void> {
|
|
921
|
+
this.errorCode = ERROR_CODE_UPDATE_METADATA;
|
|
922
|
+
this.successCallback = successCallback;
|
|
923
|
+
this.errorCallback = errorCallback;
|
|
924
|
+
|
|
925
|
+
try {
|
|
926
|
+
const updatePromises = items.map(async (item, index) => {
|
|
927
|
+
try {
|
|
928
|
+
// Suppress per-item callbacks; aggregate outcome at the bulk level only
|
|
929
|
+
await this.updateMetadata(item, template, operations[index], successCallback, errorCallback, true);
|
|
930
|
+
} catch (e) {
|
|
931
|
+
// Re-throw to be caught by Promise.all and handled once below
|
|
932
|
+
throw new Error(`Failed to update metadata: ${e.message || e}`);
|
|
933
|
+
}
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
await Promise.all(updatePromises);
|
|
937
|
+
|
|
938
|
+
if (!this.isDestroyed()) {
|
|
939
|
+
this.successHandler();
|
|
940
|
+
}
|
|
941
|
+
} catch (e) {
|
|
942
|
+
if (!this.isDestroyed()) {
|
|
943
|
+
this.errorHandler(e);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
850
948
|
/**
|
|
851
949
|
* API for patching metadata on file
|
|
852
950
|
*
|