@box/metadata-editor 2.9.1 → 2.10.0

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/README.md CHANGED
@@ -5,6 +5,7 @@
5
5
  - [Running commands](#running-commands)
6
6
  - [Available commands](#available-commands)
7
7
  - [Ownership](#ownership)
8
+ - [Item type](#item-type)
8
9
  - [Translations](#translations)
9
10
 
10
11
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -45,10 +46,25 @@ All commands used with Nx can be found in `project.json` file within your packag
45
46
 
46
47
  ## Ownership
47
48
 
48
- Code of the feature belongs to @Box/role_metadata. Responsibilities of owning team include control over code quality, providing guidelines for changes, and alignment with other teams regarding changes.
49
+ Code of the feature belongs to @Box/role_metadata. Responsibilities of owning team include control over code quality, providing guidelines for changes, and alignment with other teams regarding changes.
49
50
 
50
51
  If you have any questions or needs related to this feature, please reach out to the Metadata team on Slack: [#eng-metadata-team](https://grid-box.enterprise.slack.com/archives/C16HCR4QG)
51
52
 
53
+ ## Item type
54
+
55
+ `itemType` selects item-specific copy only; it does not gate any feature. Autofill, confidence score review, and bounding boxes are controlled solely by their own flags. Those features are supported for files only, so folder hosts should leave their flags off.
56
+
57
+ `MetadataInstanceForm` accepts an optional `itemType` of `'file' | 'folder'`. It defaults to `'file'` and is passed through to `DeleteConfirmationModal`. `MetadataInstanceList` does not take `itemType`.
58
+
59
+ Folder empty-state copy is a separate prop. Pass `level="folder"` on `MetadataEmptyState` together with `itemType="folder"` on the form, so the delete modal and the empty state describe the same item.
60
+
61
+ ```tsx
62
+ import { MetadataEmptyState, MetadataInstanceForm } from '@box/metadata-editor';
63
+
64
+ <MetadataInstanceForm itemType="folder" {...formProps} />
65
+ <MetadataEmptyState level="folder" />
66
+ ```
67
+
52
68
  ## Translations
53
69
 
54
70
  Per-locale `i18n/*.js` files are generated and committed by the Moji Jenkins pipeline. The shared-feature builder copies them into `dist/i18n/` during `build`. Consuming applications list this package in `i18n.config.js` under `translationDependencies`.
@@ -1 +1 @@
1
- import messages from"../esm/lib/components/metadata-instance-editor/subcomponents/delete-confirmation-modal/messages.js";import{useState}from"react";import{FormattedMessage,useIntl}from"react-intl";import{jsx,jsxs}from"react/jsx-runtime";import{Checkbox,Modal,Text,TextInput}from"@box/blueprint-web";import '../styles/delete-confirmation-modal.css';var delete_confirmation_modal_module_default={modalBody:`_modalBody_1wc7x_1`},DeleteConfirmationModal=({onConfirm,templateName,onDismiss,open,isCheckboxEnabled})=>{let intl=useIntl(),[inputValue,setInputValue]=useState(``),[isChecked,setIsChecked]=useState(!1),handleOpenChange=openState=>{openState||(onDismiss(),setInputValue(``),setIsChecked(!1))},formattedTemplateName=templateName||intl.formatMessage(messages.deleteConfirmationModalCustomMetadata),isInputValueValid=inputValue===formattedTemplateName,handleCheckboxChange=()=>{setIsChecked(!isChecked)},handleConfirm=()=>{onConfirm(),handleOpenChange(!1)};return jsx(Modal,{onOpenChange:handleOpenChange,open,children:jsxs(Modal.Content,{onEscapeKeyDown:e=>e.stopPropagation(),size:`small`,children:[jsx(Modal.Header,{"aria-label":intl.formatMessage(messages.deleteConfirmationModalHeaderAriaLabel),children:jsx(FormattedMessage,{...messages.deleteConfirmationModalHeader,values:{templateName:formattedTemplateName}})}),jsx(Modal.ScrollableContainer,{children:jsxs(Modal.Body,{className:delete_confirmation_modal_module_default.modalBody,children:[jsx(Text,{as:`p`,children:isCheckboxEnabled?jsx(FormattedMessage,{...messages.deleteConfirmationModalBodyFirstParagraphCheckboxVersion,values:{templateName:formattedTemplateName}}):jsx(FormattedMessage,{...messages.deleteConfirmationModalBodyFirstParagraph,values:{templateName:formattedTemplateName}})}),!isCheckboxEnabled&&jsx(Text,{as:`p`,children:jsx(FormattedMessage,{...messages.deleteConfirmationModalBodySecondParagraph})}),isCheckboxEnabled?jsx(Checkbox.Item,{checked:isChecked,"data-resin-target":`checkbox`,label:intl.formatMessage(messages.deleteConfirmationModalBodyCheckboxLabel),onCheckedChange:handleCheckboxChange,value:`overageCheckbox`}):jsx(TextInput,{label:intl.formatMessage(messages.deleteConfirmationModalBodyInputFieldLabel),onChange:event=>setInputValue(event.target.value),placeholder:formattedTemplateName,required:!0,value:inputValue})]})}),jsxs(Modal.Footer,{children:[jsx(Modal.Footer.SecondaryButton,{onClick:()=>handleOpenChange(!1),size:`large`,"data-target-id":`Modal.Footer.SecondaryButton-deleteConfirmationModalCancelButton`,children:intl.formatMessage(messages.deleteConfirmationModalCancelButton)}),jsx(Modal.Footer.PrimaryButton,{disabled:isCheckboxEnabled?!isChecked:!isInputValueValid,onClick:handleConfirm,size:`large`,children:intl.formatMessage(isCheckboxEnabled?messages.deleteConfirmationModalConfirmButtonCheckboxVersion:messages.deleteConfirmationModalConfirmButton)})]}),jsx(Modal.Close,{"aria-label":intl.formatMessage(messages.deleteConfirmationModalDismissButton)})]})})};export{DeleteConfirmationModal as t};
1
+ import messages from"../esm/lib/components/metadata-instance-editor/subcomponents/delete-confirmation-modal/messages.js";import{useState}from"react";import{FormattedMessage,useIntl}from"react-intl";import{jsx,jsxs}from"react/jsx-runtime";import{Checkbox,Modal,Text,TextInput}from"@box/blueprint-web";import '../styles/delete-confirmation-modal.css';var delete_confirmation_modal_module_default={modalBody:`_modalBody_1wc7x_1`},getDeleteConfirmationBodyMessage=itemType=>itemType===`folder`?messages.deleteConfirmationModalBodyFirstParagraphFolder:messages.deleteConfirmationModalBodyFirstParagraph,DeleteConfirmationModal=({onConfirm,templateName,onDismiss,open,isCheckboxEnabled,itemType=`file`})=>{let intl=useIntl(),[inputValue,setInputValue]=useState(``),[isChecked,setIsChecked]=useState(!1),handleOpenChange=openState=>{openState||(onDismiss(),setInputValue(``),setIsChecked(!1))},formattedTemplateName=templateName||intl.formatMessage(messages.deleteConfirmationModalCustomMetadata),isInputValueValid=inputValue===formattedTemplateName,handleCheckboxChange=()=>{setIsChecked(!isChecked)},handleConfirm=()=>{onConfirm(),handleOpenChange(!1)};return jsx(Modal,{onOpenChange:handleOpenChange,open,children:jsxs(Modal.Content,{onEscapeKeyDown:e=>e.stopPropagation(),size:`small`,children:[jsx(Modal.Header,{"aria-label":intl.formatMessage(messages.deleteConfirmationModalHeaderAriaLabel),children:jsx(FormattedMessage,{...messages.deleteConfirmationModalHeader,values:{templateName:formattedTemplateName}})}),jsx(Modal.ScrollableContainer,{children:jsxs(Modal.Body,{className:delete_confirmation_modal_module_default.modalBody,children:[jsx(Text,{as:`p`,children:isCheckboxEnabled?jsx(FormattedMessage,{...messages.deleteConfirmationModalBodyFirstParagraphCheckboxVersion,values:{templateName:formattedTemplateName}}):jsx(FormattedMessage,{...getDeleteConfirmationBodyMessage(itemType),values:{templateName:formattedTemplateName}})}),!isCheckboxEnabled&&jsx(Text,{as:`p`,children:jsx(FormattedMessage,{...messages.deleteConfirmationModalBodySecondParagraph})}),isCheckboxEnabled?jsx(Checkbox.Item,{checked:isChecked,"data-resin-target":`checkbox`,label:intl.formatMessage(messages.deleteConfirmationModalBodyCheckboxLabel),onCheckedChange:handleCheckboxChange,value:`overageCheckbox`}):jsx(TextInput,{label:intl.formatMessage(messages.deleteConfirmationModalBodyInputFieldLabel),onChange:event=>setInputValue(event.target.value),placeholder:formattedTemplateName,required:!0,value:inputValue})]})}),jsxs(Modal.Footer,{children:[jsx(Modal.Footer.SecondaryButton,{onClick:()=>handleOpenChange(!1),size:`large`,"data-target-id":`Modal.Footer.SecondaryButton-deleteConfirmationModalCancelButton`,children:intl.formatMessage(messages.deleteConfirmationModalCancelButton)}),jsx(Modal.Footer.PrimaryButton,{disabled:isCheckboxEnabled?!isChecked:!isInputValueValid,onClick:handleConfirm,size:`large`,children:intl.formatMessage(isCheckboxEnabled?messages.deleteConfirmationModalConfirmButtonCheckboxVersion:messages.deleteConfirmationModalConfirmButton)})]}),jsx(Modal.Close,{"aria-label":intl.formatMessage(messages.deleteConfirmationModalDismissButton)})]})})};export{DeleteConfirmationModal as t};
@@ -1 +1 @@
1
- import{defineMessages}from"react-intl";var messages=defineMessages({managerLevelEmptyStateHeading:{id:`metadataEditor.managerLevel.emptyState.heading`,defaultMessage:`Apply Metadata Templates`},managerLevelEmptyStateBody:{id:`metadataEditor.managerLevel.emptyState.body`,defaultMessage:`Browse or search for your items to apply and edit metadata`},fileLevelEmptyStateBoxAiEnabledHeading:{id:`metadataEditor.fileLevel.emptyState.boxAiEnabled.heading`,defaultMessage:`Autofill Metadata with Box AI`},fileLevelEmptyStateBoxAiEnabledBody:{id:`metadataEditor.fileLevel.emptyState.boxAiEnabled.body`,defaultMessage:`Use the power of Box AI to quickly capture document metadata, with ever-increasing accuracy.`},fileLevelEmptyStateDefaultHeading:{id:`metadataEditor.fileLevel.emptyState.default.heading`,defaultMessage:`Add Metadata Templates`},fileLevelEmptyStateDefaultBody:{id:`metadataEditor.fileLevel.emptyState.default.body`,defaultMessage:`Add Metadata to your file to support business operations, workflows, and more!`},instanceLevelEmptyStateHeading:{id:`metadataEditor.instanceLevel.emptyState.heading`,defaultMessage:`This template has no values`},instanceLevelEmptyStateHeadingNoAttributes:{id:`metadataEditor.instanceLevel.emptyState.noAttributes.heading`,defaultMessage:`This template has no attributes`},instanceLevelEmptyStateNoEmptyValuesBody:{id:`metadataEditor.instanceLevel.emptyState.noEmptyValues.body`,defaultMessage:`This template has no values`},instanceLevelSeeEmptyValuesCTA:{id:`metadataEditor.instanceLevel.emptyState.emptyValues.Cta`,defaultMessage:`See empty values`}});export{messages as default};
1
+ import{defineMessages}from"react-intl";var messages=defineMessages({managerLevelEmptyStateHeading:{id:`metadataEditor.managerLevel.emptyState.heading`,defaultMessage:`Apply Metadata Templates`},managerLevelEmptyStateBody:{id:`metadataEditor.managerLevel.emptyState.body`,defaultMessage:`Browse or search for your items to apply and edit metadata`},fileLevelEmptyStateBoxAiEnabledHeading:{id:`metadataEditor.fileLevel.emptyState.boxAiEnabled.heading`,defaultMessage:`Autofill Metadata with Box AI`},fileLevelEmptyStateBoxAiEnabledBody:{id:`metadataEditor.fileLevel.emptyState.boxAiEnabled.body`,defaultMessage:`Use the power of Box AI to quickly capture document metadata, with ever-increasing accuracy.`},fileLevelEmptyStateDefaultHeading:{id:`metadataEditor.fileLevel.emptyState.default.heading`,defaultMessage:`Add Metadata Templates`},fileLevelEmptyStateDefaultBody:{id:`metadataEditor.fileLevel.emptyState.default.body`,defaultMessage:`Add Metadata to your file to support business operations, workflows, and more!`},folderLevelEmptyStateDefaultHeading:{id:`metadataEditor.folderLevel.emptyState.default.heading`,defaultMessage:`Add Metadata Templates`},folderLevelEmptyStateDefaultBody:{id:`metadataEditor.folderLevel.emptyState.default.body`,defaultMessage:`Add Metadata to your folder to support business operations, workflows, and more!`},instanceLevelEmptyStateHeading:{id:`metadataEditor.instanceLevel.emptyState.heading`,defaultMessage:`This template has no values`},instanceLevelEmptyStateHeadingNoAttributes:{id:`metadataEditor.instanceLevel.emptyState.noAttributes.heading`,defaultMessage:`This template has no attributes`},instanceLevelEmptyStateNoEmptyValuesBody:{id:`metadataEditor.instanceLevel.emptyState.noEmptyValues.body`,defaultMessage:`This template has no values`},instanceLevelSeeEmptyValuesCTA:{id:`metadataEditor.instanceLevel.emptyState.emptyValues.Cta`,defaultMessage:`See empty values`}});export{messages as default};
@@ -1 +1 @@
1
- import messages from"./messages.js";import{useCallback}from"react";import{useIntl}from"react-intl";import{jsx}from"react/jsx-runtime";import{EmptyState,Text}from"@box/blueprint-web";import{JobAnalyzeData}from"@box/blueprint-web-assets/illustrations/Small";function MetadataEmptyState({isAnyEmptyValueHidden=!1,isBoxAiSuggestionsFeatureEnabled=!1,level,onShowEmptyValues}){let intl=useIntl(),getBody=useCallback(()=>level===`manager`?jsx(Text,{as:`p`,children:intl.formatMessage(messages.managerLevelEmptyStateBody)}):level===`instance`?isAnyEmptyValueHidden?jsx(EmptyState.PrimaryAction,{onClick:onShowEmptyValues,children:intl.formatMessage(messages.instanceLevelSeeEmptyValuesCTA)}):jsx(Text,{as:`h1`,variant:`titleSmall`,children:intl.formatMessage(messages.instanceLevelEmptyStateHeadingNoAttributes)}):jsx(Text,{as:`p`,children:intl.formatMessage(messages.fileLevelEmptyStateDefaultBody)}),[intl,isAnyEmptyValueHidden,level,onShowEmptyValues]),getHeading=useCallback(()=>level===`manager`?jsx(Text,{as:`h2`,children:intl.formatMessage(messages.managerLevelEmptyStateHeading)}):level===`instance`?isAnyEmptyValueHidden?jsx(Text,{as:`h2`,children:intl.formatMessage(messages.instanceLevelEmptyStateHeading)}):null:jsx(Text,{as:`h2`,children:intl.formatMessage(messages.fileLevelEmptyStateDefaultHeading)}),[intl,isAnyEmptyValueHidden,level]);return jsx(EmptyState,{body:getBody(),heading:getHeading(),illustration:JobAnalyzeData,size:`small`})}export{MetadataEmptyState,MetadataEmptyState as default};
1
+ import messages from"./messages.js";import{useCallback}from"react";import{useIntl}from"react-intl";import{jsx}from"react/jsx-runtime";import{EmptyState,Text}from"@box/blueprint-web";import{JobAnalyzeData}from"@box/blueprint-web-assets/illustrations/Small";function MetadataEmptyState({isAnyEmptyValueHidden=!1,isBoxAiSuggestionsFeatureEnabled=!1,level,onShowEmptyValues}){let intl=useIntl(),getBody=useCallback(()=>level===`manager`?jsx(Text,{as:`p`,children:intl.formatMessage(messages.managerLevelEmptyStateBody)}):level===`instance`?isAnyEmptyValueHidden?jsx(EmptyState.PrimaryAction,{onClick:onShowEmptyValues,children:intl.formatMessage(messages.instanceLevelSeeEmptyValuesCTA)}):jsx(Text,{as:`h1`,variant:`titleSmall`,children:intl.formatMessage(messages.instanceLevelEmptyStateHeadingNoAttributes)}):jsx(Text,{as:`p`,children:level===`folder`?intl.formatMessage(messages.folderLevelEmptyStateDefaultBody):intl.formatMessage(messages.fileLevelEmptyStateDefaultBody)}),[intl,isAnyEmptyValueHidden,level,onShowEmptyValues]),getHeading=useCallback(()=>level===`manager`?jsx(Text,{as:`h2`,children:intl.formatMessage(messages.managerLevelEmptyStateHeading)}):level===`instance`?isAnyEmptyValueHidden?jsx(Text,{as:`h2`,children:intl.formatMessage(messages.instanceLevelEmptyStateHeading)}):null:jsx(Text,{as:`h2`,children:level===`folder`?intl.formatMessage(messages.folderLevelEmptyStateDefaultHeading):intl.formatMessage(messages.fileLevelEmptyStateDefaultHeading)}),[intl,isAnyEmptyValueHidden,level]);return jsx(EmptyState,{body:getBody(),heading:getHeading(),illustration:JobAnalyzeData,size:`small`})}export{MetadataEmptyState,MetadataEmptyState as default};
@@ -1 +1 @@
1
- import{defineMessages}from"react-intl";var messages=defineMessages({deleteConfirmationModalCustomMetadata:{id:`metadataEditor.editInstance.deleteConfirmationModal.customMedatata`,defaultMessage:`Custom Metadata`},deleteConfirmationModalHeader:{id:`metadataEditor.editInstance.deleteConfirmationModal.header`,defaultMessage:`Delete "{templateName}"`},deleteConfirmationModalHeaderAriaLabel:{id:`metadataEditor.editInstance.deleteConfirmationModal.headerAriaLabel`,defaultMessage:`Delete Metadata Template`},deleteConfirmationModalBodyFirstParagraph:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.firstParagraph`,defaultMessage:`Are you sure you want to delete the "{templateName}" Metadata template, and all of its values from this file?`},deleteConfirmationModalBodyFirstParagraphCheckboxVersion:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.firstParagraphCheckboxVersion`,defaultMessage:`Are you sure you want to delete the "{templateName}" Metadata instance, and its values?`},deleteConfirmationModalBodySecondParagraph:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.secondParagraph`,defaultMessage:`Once deleted, Metadata values cannot be restored.`},deleteConfirmationModalBodyInputFieldLabel:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.inputFieldLabel`,defaultMessage:`Type the Metadata Template’s name to confirm deletion`},deleteConfirmationModalBodyCheckboxLabel:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.checkboxLabel`,defaultMessage:`Confirm deletion of Metadata instance`},deleteConfirmationModalCancelButton:{id:`metadataEditor.editInstance.deleteConfirmationModal.cancelButton`,defaultMessage:`Cancel`},deleteConfirmationModalConfirmButton:{id:`metadataEditor.editInstance.deleteConfirmationModal.confirmButton`,defaultMessage:`Confirm`},deleteConfirmationModalConfirmButtonCheckboxVersion:{id:`metadataEditor.editInstance.deleteConfirmationModal.confirmButtonCheckboxVersion`,defaultMessage:`Delete`},deleteConfirmationModalDismissButton:{id:`metadataEditor.editInstance.deleteConfirmationModal.dismissButton`,defaultMessage:`Dismiss`}});export{messages as default};
1
+ import{defineMessages}from"react-intl";var messages=defineMessages({deleteConfirmationModalCustomMetadata:{id:`metadataEditor.editInstance.deleteConfirmationModal.customMedatata`,defaultMessage:`Custom Metadata`},deleteConfirmationModalHeader:{id:`metadataEditor.editInstance.deleteConfirmationModal.header`,defaultMessage:`Delete "{templateName}"`},deleteConfirmationModalHeaderAriaLabel:{id:`metadataEditor.editInstance.deleteConfirmationModal.headerAriaLabel`,defaultMessage:`Delete Metadata Template`},deleteConfirmationModalBodyFirstParagraph:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.firstParagraph`,defaultMessage:`Are you sure you want to delete the "{templateName}" Metadata template, and all of its values from this file?`},deleteConfirmationModalBodyFirstParagraphFolder:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.firstParagraph.folder`,defaultMessage:`Are you sure you want to delete the "{templateName}" Metadata template, and all of its values from this folder?`},deleteConfirmationModalBodyFirstParagraphCheckboxVersion:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.firstParagraphCheckboxVersion`,defaultMessage:`Are you sure you want to delete the "{templateName}" Metadata instance, and its values?`},deleteConfirmationModalBodySecondParagraph:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.secondParagraph`,defaultMessage:`Once deleted, Metadata values cannot be restored.`},deleteConfirmationModalBodyInputFieldLabel:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.inputFieldLabel`,defaultMessage:`Type the Metadata Template’s name to confirm deletion`},deleteConfirmationModalBodyCheckboxLabel:{id:`metadataEditor.editInstance.deleteConfirmationModal.body.checkboxLabel`,defaultMessage:`Confirm deletion of Metadata instance`},deleteConfirmationModalCancelButton:{id:`metadataEditor.editInstance.deleteConfirmationModal.cancelButton`,defaultMessage:`Cancel`},deleteConfirmationModalConfirmButton:{id:`metadataEditor.editInstance.deleteConfirmationModal.confirmButton`,defaultMessage:`Confirm`},deleteConfirmationModalConfirmButtonCheckboxVersion:{id:`metadataEditor.editInstance.deleteConfirmationModal.confirmButtonCheckboxVersion`,defaultMessage:`Delete`},deleteConfirmationModalDismissButton:{id:`metadataEditor.editInstance.deleteConfirmationModal.dismissButton`,defaultMessage:`Dismiss`}});export{messages as default};
@@ -1 +1 @@
1
- import{TEMPLATE_CUSTOM_PROPERTIES}from"../../../../constants.js";import{MetadataEmptyState}from"../../../metadata-empty-state/metadata-empty-state.js";import{useMetadataEditorAnalytics}from"../../../../utils/analytics/analytics-context.js";import{useAutofill}from"../../../../utils/autofill-context.js";import{TemplateInstance}from"../../../metadata-editor-fields/metadata-editor-fields.js";import{UnsavedChangesModal}from"../../../unsaved-changes-modal/unsaved-changes-modal.js";import{t as AutofillOverlay}from"../../../../../../chunks/autofill-overlay.js";import{t as CustomInstance}from"../../../../../../chunks/custom-instance.js";import{t as DeleteConfirmationModal}from"../../../../../../chunks/delete-confirmation-modal.js";import{t as createJSONPatch}from"../../../../../../chunks/utils2.js";import{n as metadata_instance_form_module_default,t as MetadataInstanceFormCardWrapper}from"../../../../../../chunks/metadata-instance-form-card-wrapper.js";import{useEffect,useMemo,useRef,useState}from"react";import{jsx,jsxs}from"react/jsx-runtime";import clsx from"clsx";import{Form,Formik}from"formik";import isEqual from"lodash/isEqual";var FormikObserver=({dirty,onChange,values})=>{let prevValuesRef=useRef(values);return dirty&&!isEqual(prevValuesRef.current.metadata.fields,values.metadata.fields)&&(prevValuesRef.current=values,onChange(values)),null},MetadataInstanceForm=props=>{let{areAiSuggestionsAvailable,customRef,isLargeFile,errorCode,isAiSuggestionsFeatureEnabled,isAdvancedExtractAgentEnabled=!1,isBetaLanguageEnabled,isDeleteButtonDisabled,isDeleteConfirmationModalCheckboxEnabled,isMultilevelTaxonomyFieldEnabled,isTaxonomyPickerEnabled,createTaxonomyItemsService,isUnsavedChangesModalOpen=!1,MetadataInstanceFormCustomWrapper,selectedTemplateInstance,onCancel,onChange,onDelete,onDiscardUnsavedChanges,onSubmit,onToggleReviewFilter,setIsUnsavedChangesModalOpen,shouldShowOnlyReviewFields=!1,taxonomyOptionsFetcher,isConfidenceScoreReviewEnabled=!1,isBoundingBoxEnabled=!1,onSelectMetadataField,selectedMetadataFieldId,isUserFieldEnabled=!1,fetchUsers,fetchAvatarUrls,resolveUsersByEmail}=props,isBoundingBoxOrConfidenceScoreReviewEnabled=isBoundingBoxEnabled||isConfidenceScoreReviewEnabled,FormWrapper=MetadataInstanceFormCustomWrapper??MetadataInstanceFormCardWrapper,[isDeleteConfirmationModalOpen,setIsDeleteConfirmationModalOpen]=useState(!1),{isFetchingSuggestions,isLongLoading,getAiSuggestions,clearState,suggestions}=useAutofill(),{trackEvent}=useMetadataEditorAnalytics();useEffect(()=>()=>{clearState()},[clearState,selectedTemplateInstance?.id]);let isCustomMetadata=selectedTemplateInstance?.templateKey===TEMPLATE_CUSTOM_PROPERTIES,handleSubmit=async values=>{await onSubmit(values,createJSONPatch(values,selectedTemplateInstance))},handleCancel=isFormDirty=>{isFormDirty?setIsUnsavedChangesModalOpen(!0):onCancel()},handleDelete=()=>{setIsDeleteConfirmationModalOpen(!0)},initialValues={metadata:{...selectedTemplateInstance}},formRef=useRef(null),[portalElement,setPortalElement]=useState(null);useEffect(()=>{setPortalElement(customRef??formRef.current)},[customRef,selectedTemplateInstance?.templateKey,selectedTemplateInstance?.scope]);let content=useMemo(()=>{let isEmpty=selectedTemplateInstance?.fields.length===0;if(isCustomMetadata)return jsx(CustomInstance,{isLoading:isFetchingSuggestions});if(isEmpty)return jsx(MetadataEmptyState,{isBoxAiSuggestionsFeatureEnabled:isAiSuggestionsFeatureEnabled,level:`instance`});let showOverlay=!!(isFetchingSuggestions||errorCode);return jsxs(`div`,{className:clsx(metadata_instance_form_module_default.metadataInstanceFormContent,showOverlay&&metadata_instance_form_module_default.showOverlay,isBoundingBoxOrConfidenceScoreReviewEnabled&&metadata_instance_form_module_default.metadataInstanceFormContentReducedGap),children:[jsx(AutofillOverlay,{errorCode,isFetchingSuggestions,isLongLoading}),jsx(TemplateInstance,{disableForm:isFetchingSuggestions,isConfidenceScoreReviewEnabled,isBoundingBoxEnabled,isExternallyOwned:selectedTemplateInstance?.isExternallyOwned,isMultilevelTaxonomyFieldEnabled,isTaxonomyPickerEnabled,isUserFieldEnabled,createTaxonomyItemsService,onSelectMetadataField,selectedMetadataFieldId,portalElement:customRef??portalElement,shouldShowOnlyReviewFields,taxonomyOptionsFetcher,fetchAvatarUrls,fetchUsers,resolveUsersByEmail})]})},[selectedTemplateInstance?.fields.length,selectedTemplateInstance?.isExternallyOwned,isCustomMetadata,isFetchingSuggestions,isLongLoading,customRef,portalElement,taxonomyOptionsFetcher,isAiSuggestionsFeatureEnabled,isConfidenceScoreReviewEnabled,isBoundingBoxEnabled,isMultilevelTaxonomyFieldEnabled,isTaxonomyPickerEnabled,createTaxonomyItemsService,errorCode,shouldShowOnlyReviewFields,onSelectMetadataField,selectedMetadataFieldId,isUserFieldEnabled,fetchUsers,fetchAvatarUrls,resolveUsersByEmail]);return jsx(Formik,{initialValues,onSubmit:handleSubmit,children:({values,dirty})=>jsxs(Form,{children:[jsx(FormWrapper,{areAiSuggestionsAvailable,className:metadata_instance_form_module_default.metadataInstanceForm,formRef,formValues:values,getAiSuggestions,handleCancel,handleDelete,isAdvancedExtractAgentEnabled,isAiSuggestionsFeatureEnabled,isBetaLanguageEnabled,isConfidenceScoreReviewEnabled,isBoundingBoxEnabled,isDeleteButtonDisabled,isFetchingSuggestions,isFormDirty:dirty,isLargeFile,onToggleReviewFilter,selectedTemplateInstance,shouldShowOnlyReviewFields,suggestions,children:selectedTemplateInstance&&content}),onChange&&jsx(FormikObserver,{dirty,onChange,values}),jsx(UnsavedChangesModal,{onBackToEdit:()=>setIsUnsavedChangesModalOpen(!1),onDiscardChanges:onDiscardUnsavedChanges,open:isUnsavedChangesModalOpen,trackEvent}),jsx(DeleteConfirmationModal,{isCheckboxEnabled:isDeleteConfirmationModalCheckboxEnabled,onConfirm:()=>onDelete(selectedTemplateInstance),onDismiss:()=>setIsDeleteConfirmationModalOpen(!1),open:isDeleteConfirmationModalOpen,templateName:selectedTemplateInstance?.displayName})]})},`${selectedTemplateInstance?.scope}.${selectedTemplateInstance?.templateKey}`)};export{MetadataInstanceForm};
1
+ import{TEMPLATE_CUSTOM_PROPERTIES}from"../../../../constants.js";import{MetadataEmptyState}from"../../../metadata-empty-state/metadata-empty-state.js";import{useMetadataEditorAnalytics}from"../../../../utils/analytics/analytics-context.js";import{useAutofill}from"../../../../utils/autofill-context.js";import{TemplateInstance}from"../../../metadata-editor-fields/metadata-editor-fields.js";import{UnsavedChangesModal}from"../../../unsaved-changes-modal/unsaved-changes-modal.js";import{t as AutofillOverlay}from"../../../../../../chunks/autofill-overlay.js";import{t as CustomInstance}from"../../../../../../chunks/custom-instance.js";import{t as DeleteConfirmationModal}from"../../../../../../chunks/delete-confirmation-modal.js";import{t as createJSONPatch}from"../../../../../../chunks/utils2.js";import{n as metadata_instance_form_module_default,t as MetadataInstanceFormCardWrapper}from"../../../../../../chunks/metadata-instance-form-card-wrapper.js";import{useEffect,useMemo,useRef,useState}from"react";import{jsx,jsxs}from"react/jsx-runtime";import clsx from"clsx";import{Form,Formik}from"formik";import isEqual from"lodash/isEqual";var FormikObserver=({dirty,onChange,values})=>{let prevValuesRef=useRef(values);return dirty&&!isEqual(prevValuesRef.current.metadata.fields,values.metadata.fields)&&(prevValuesRef.current=values,onChange(values)),null},MetadataInstanceForm=props=>{let{itemType=`file`,areAiSuggestionsAvailable,customRef,isLargeFile,errorCode,isAiSuggestionsFeatureEnabled,isAdvancedExtractAgentEnabled=!1,isBetaLanguageEnabled,isDeleteButtonDisabled,isDeleteConfirmationModalCheckboxEnabled,isMultilevelTaxonomyFieldEnabled,isTaxonomyPickerEnabled,createTaxonomyItemsService,isUnsavedChangesModalOpen=!1,MetadataInstanceFormCustomWrapper,selectedTemplateInstance,onCancel,onChange,onDelete,onDiscardUnsavedChanges,onSubmit,onToggleReviewFilter,setIsUnsavedChangesModalOpen,shouldShowOnlyReviewFields=!1,taxonomyOptionsFetcher,isConfidenceScoreReviewEnabled=!1,isBoundingBoxEnabled=!1,onSelectMetadataField,selectedMetadataFieldId,isUserFieldEnabled=!1,fetchUsers,fetchAvatarUrls,resolveUsersByEmail}=props,isBoundingBoxOrConfidenceScoreReviewEnabled=isBoundingBoxEnabled||isConfidenceScoreReviewEnabled,FormWrapper=MetadataInstanceFormCustomWrapper??MetadataInstanceFormCardWrapper,[isDeleteConfirmationModalOpen,setIsDeleteConfirmationModalOpen]=useState(!1),{isFetchingSuggestions,isLongLoading,getAiSuggestions,clearState,suggestions}=useAutofill(),{trackEvent}=useMetadataEditorAnalytics();useEffect(()=>()=>{clearState()},[clearState,selectedTemplateInstance?.id]);let isCustomMetadata=selectedTemplateInstance?.templateKey===TEMPLATE_CUSTOM_PROPERTIES,handleSubmit=async values=>{await onSubmit(values,createJSONPatch(values,selectedTemplateInstance))},handleCancel=isFormDirty=>{isFormDirty?setIsUnsavedChangesModalOpen(!0):onCancel()},handleDelete=()=>{setIsDeleteConfirmationModalOpen(!0)},initialValues={metadata:{...selectedTemplateInstance}},formRef=useRef(null),[portalElement,setPortalElement]=useState(null);useEffect(()=>{setPortalElement(customRef??formRef.current)},[customRef,selectedTemplateInstance?.templateKey,selectedTemplateInstance?.scope]);let content=useMemo(()=>{let isEmpty=selectedTemplateInstance?.fields.length===0;if(isCustomMetadata)return jsx(CustomInstance,{isLoading:isFetchingSuggestions});if(isEmpty)return jsx(MetadataEmptyState,{isBoxAiSuggestionsFeatureEnabled:isAiSuggestionsFeatureEnabled,level:`instance`});let showOverlay=!!(isFetchingSuggestions||errorCode);return jsxs(`div`,{className:clsx(metadata_instance_form_module_default.metadataInstanceFormContent,showOverlay&&metadata_instance_form_module_default.showOverlay,isBoundingBoxOrConfidenceScoreReviewEnabled&&metadata_instance_form_module_default.metadataInstanceFormContentReducedGap),children:[jsx(AutofillOverlay,{errorCode,isFetchingSuggestions,isLongLoading}),jsx(TemplateInstance,{disableForm:isFetchingSuggestions,isConfidenceScoreReviewEnabled,isBoundingBoxEnabled,isExternallyOwned:selectedTemplateInstance?.isExternallyOwned,isMultilevelTaxonomyFieldEnabled,isTaxonomyPickerEnabled,isUserFieldEnabled,createTaxonomyItemsService,onSelectMetadataField,selectedMetadataFieldId,portalElement:customRef??portalElement,shouldShowOnlyReviewFields,taxonomyOptionsFetcher,fetchAvatarUrls,fetchUsers,resolveUsersByEmail})]})},[selectedTemplateInstance?.fields.length,selectedTemplateInstance?.isExternallyOwned,isCustomMetadata,isFetchingSuggestions,isLongLoading,customRef,portalElement,taxonomyOptionsFetcher,isAiSuggestionsFeatureEnabled,isConfidenceScoreReviewEnabled,isBoundingBoxEnabled,isBoundingBoxOrConfidenceScoreReviewEnabled,isMultilevelTaxonomyFieldEnabled,isTaxonomyPickerEnabled,createTaxonomyItemsService,errorCode,shouldShowOnlyReviewFields,onSelectMetadataField,selectedMetadataFieldId,isUserFieldEnabled,fetchUsers,fetchAvatarUrls,resolveUsersByEmail]);return jsx(Formik,{initialValues,onSubmit:handleSubmit,children:({values,dirty})=>jsxs(Form,{children:[jsx(FormWrapper,{areAiSuggestionsAvailable,className:metadata_instance_form_module_default.metadataInstanceForm,formRef,formValues:values,getAiSuggestions,handleCancel,handleDelete,isAdvancedExtractAgentEnabled,isAiSuggestionsFeatureEnabled,isBetaLanguageEnabled,isConfidenceScoreReviewEnabled,isBoundingBoxEnabled,isDeleteButtonDisabled,isFetchingSuggestions,isFormDirty:dirty,isLargeFile,onToggleReviewFilter,selectedTemplateInstance,shouldShowOnlyReviewFields,suggestions,children:selectedTemplateInstance&&content}),onChange&&jsx(FormikObserver,{dirty,onChange,values}),jsx(UnsavedChangesModal,{onBackToEdit:()=>setIsUnsavedChangesModalOpen(!1),onDiscardChanges:onDiscardUnsavedChanges,open:isUnsavedChangesModalOpen,trackEvent}),jsx(DeleteConfirmationModal,{isCheckboxEnabled:isDeleteConfirmationModalCheckboxEnabled,itemType,onConfirm:()=>onDelete(selectedTemplateInstance),onDismiss:()=>setIsDeleteConfirmationModalOpen(!1),open:isDeleteConfirmationModalOpen,templateName:selectedTemplateInstance?.displayName})]})},`${selectedTemplateInstance?.scope}.${selectedTemplateInstance?.templateKey}`)};export{MetadataInstanceForm};
@@ -29,6 +29,16 @@ declare const messages: {
29
29
  description: string;
30
30
  id: string;
31
31
  };
32
+ folderLevelEmptyStateDefaultHeading: {
33
+ defaultMessage: string;
34
+ description: string;
35
+ id: string;
36
+ };
37
+ folderLevelEmptyStateDefaultBody: {
38
+ defaultMessage: string;
39
+ description: string;
40
+ id: string;
41
+ };
32
42
  instanceLevelEmptyStateHeading: {
33
43
  defaultMessage: string;
34
44
  description: string;
@@ -1,2 +1,2 @@
1
1
  import { DeleteConfirmationModalProps } from './types';
2
- export declare const DeleteConfirmationModal: ({ onConfirm, templateName, onDismiss, open, isCheckboxEnabled, }: DeleteConfirmationModalProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DeleteConfirmationModal: ({ onConfirm, templateName, onDismiss, open, isCheckboxEnabled, itemType, }: DeleteConfirmationModalProps) => import("react/jsx-runtime").JSX.Element;
@@ -19,6 +19,11 @@ declare const messages: {
19
19
  description: string;
20
20
  id: string;
21
21
  };
22
+ deleteConfirmationModalBodyFirstParagraphFolder: {
23
+ defaultMessage: string;
24
+ description: string;
25
+ id: string;
26
+ };
22
27
  deleteConfirmationModalBodyFirstParagraphCheckboxVersion: {
23
28
  defaultMessage: string;
24
29
  description: string;
@@ -1,5 +1,8 @@
1
+ import { MetadataItemType } from '../../../../types';
1
2
  export type DeleteConfirmationModalProps = {
2
3
  isCheckboxEnabled: boolean;
4
+ /** Item metadata is being removed from. Defaults to `file`. */
5
+ itemType?: MetadataItemType;
3
6
  onConfirm: () => void | Promise<void>;
4
7
  onDismiss: () => void;
5
8
  open: boolean;
@@ -1,10 +1,16 @@
1
- import { AutofillSuggestions, MetadataTemplateField, MetadataTemplateInstance } from '../../../../types';
1
+ import { AutofillSuggestions, MetadataItemType, MetadataTemplateField, MetadataTemplateInstance } from '../../../../types';
2
2
  import { CreateTaxonomyItemsService, TaxonomyOptionsFetcher } from '../../../metadata-editor-fields/components/metadata-taxonomy-field/types';
3
3
  import { FetchAvatarUrls, FetchUsers, ResolveUsersByEmail } from '../../../metadata-editor-fields/components/metadata-user-field/types';
4
4
  import { FormValues } from '../../types';
5
5
  import { ERROR_CODE_METADATA_AUTOFILL_TIMEOUT, ERROR_CODE_METADATA_PRECONDITION_FAILED, ERROR_CODE_MISSING_PERMISSIONS, ERROR_CODE_UNKNOWN } from './constants';
6
6
  export type errorCodeTypes = typeof ERROR_CODE_METADATA_AUTOFILL_TIMEOUT | typeof ERROR_CODE_METADATA_PRECONDITION_FAILED | typeof ERROR_CODE_MISSING_PERMISSIONS | typeof ERROR_CODE_UNKNOWN;
7
7
  export type MetadataInstanceFormProps = {
8
+ /**
9
+ * Selects item-specific copy, including the delete confirmation. Defaults to `file`.
10
+ * Does not gate any feature: autofill, confidence score review, and bounding boxes are
11
+ * controlled solely by their own flags, and are supported for files only.
12
+ */
13
+ itemType?: MetadataItemType;
8
14
  areAiSuggestionsAvailable: boolean;
9
15
  errorCode?: errorCodeTypes;
10
16
  isAiSuggestionsFeatureEnabled: boolean;
@@ -3,6 +3,8 @@ import { UserContactType } from '@box/user-selector';
3
3
  import { default as React } from 'react';
4
4
  import { BaseOptionType } from './components/combobox-with-api-pagination/types';
5
5
  export type { FormValues } from './components/metadata-instance-editor/types';
6
+ /** Host item the editor is bound to. Defaults to `file` when omitted. */
7
+ export type MetadataItemType = 'file' | 'folder';
6
8
  export type StoredAgentType = 'standard' | 'enhanced' | null;
7
9
  export type ExtractAgent = {
8
10
  AGENT_TYPE: StoredAgentType;
@@ -13,7 +15,11 @@ export type ExtractAgent = {
13
15
  export type MetadataEmptyStateProps = {
14
16
  isBoxAiSuggestionsFeatureEnabled?: boolean;
15
17
  isAnyEmptyValueHidden?: boolean;
16
- level: 'manager' | 'file' | 'instance';
18
+ /**
19
+ * Surface copy. For a file or folder, use the same item as `itemType` on `MetadataInstanceForm`
20
+ * (`level="file"` or `level="folder"`) so the empty state and the delete modal agree.
21
+ */
22
+ level: 'manager' | 'file' | 'folder' | 'instance';
17
23
  onShowEmptyValues?: () => void;
18
24
  };
19
25
  export type MetadataFormFieldValue = string | Array<string> | number | Array<BaseOptionType> | Array<UserContactType>;
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@box/metadata-editor",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "peerDependencies": {
5
5
  "@ariakit/react": "0.4.21",
6
- "@box/blueprint-web": "^17.18.1",
7
- "@box/blueprint-web-assets": "^5.11.1",
8
- "@box/box-ai-agent-selector": "^2.3.1",
9
- "@box/combobox-with-api": "^2.3.1",
10
- "@box/metadata-taxonomy-picker": "^3.4.1",
11
- "@box/metadata-template-browser": "^2.5.1",
12
- "@box/user-selector": "^3.1.1",
6
+ "@box/blueprint-web": "^17.18.2",
7
+ "@box/blueprint-web-assets": "^5.11.2",
8
+ "@box/box-ai-agent-selector": "^2.3.2",
9
+ "@box/combobox-with-api": "^2.3.2",
10
+ "@box/metadata-taxonomy-picker": "^3.4.2",
11
+ "@box/metadata-template-browser": "^2.5.2",
12
+ "@box/user-selector": "^3.1.2",
13
13
  "formik": "^2.0.3",
14
14
  "lodash": "^4.17.15",
15
15
  "react": "^17.0.0 || ^18.0.0",
@@ -19,12 +19,12 @@
19
19
  "devDependencies": {
20
20
  "@ariakit/react": "0.4.21",
21
21
  "@box/babel-plugin-target-attributes": "2.2.25",
22
- "@box/blueprint-web": "^17.18.1",
23
- "@box/blueprint-web-assets": "^5.11.1",
24
- "@box/box-ai-agent-selector": "^2.3.1",
25
- "@box/metadata-taxonomy-picker": "^3.4.1",
26
- "@box/storybook-utils": "^1.3.1",
27
- "@box/user-selector": "^3.1.1",
22
+ "@box/blueprint-web": "^17.18.2",
23
+ "@box/blueprint-web-assets": "^5.11.2",
24
+ "@box/box-ai-agent-selector": "^2.3.2",
25
+ "@box/metadata-taxonomy-picker": "^3.4.2",
26
+ "@box/storybook-utils": "^1.3.2",
27
+ "@box/user-selector": "^3.1.2",
28
28
  "@testing-library/react": "^15.0.6",
29
29
  "react": "^18.3.0",
30
30
  "react-dom": "^18.3.0",