@webiny/app-file-manager 6.4.11 → 6.6.0-alpha.1
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/app.js +21 -2
- package/app.js.map +1 -1
- package/domain/tagsHelpers.d.ts +2 -2
- package/domain/types.d.ts +0 -8
- package/features/permissions/abstractions.d.ts +2 -2
- package/features/permissions/feature.d.ts +3 -3
- package/features/shared/FILE_FIELDS.js +4 -0
- package/features/shared/FILE_FIELDS.js.map +1 -1
- package/features/shared/FileFieldsProviderWithWcp.d.ts +5 -5
- package/features/shared/FileFieldsProviderWithWcp.js +7 -7
- package/features/shared/FileFieldsProviderWithWcp.js.map +1 -1
- package/modules/AiEnrichment/AiImageEnrichmentEventHandler.d.ts +18 -0
- package/modules/AiEnrichment/AiImageEnrichmentEventHandler.js +33 -0
- package/modules/AiEnrichment/AiImageEnrichmentEventHandler.js.map +1 -0
- package/modules/AiEnrichment/ReenrichFileGateway.d.ts +12 -0
- package/modules/AiEnrichment/ReenrichFileGateway.js +23 -0
- package/modules/AiEnrichment/ReenrichFileGateway.js.map +1 -0
- package/modules/AiEnrichment/ReenrichWithAi.d.ts +11 -0
- package/modules/AiEnrichment/ReenrichWithAi.js +57 -0
- package/modules/AiEnrichment/ReenrichWithAi.js.map +1 -0
- package/modules/AiEnrichment/ReenrichWithAiPresenter.d.ts +50 -0
- package/modules/AiEnrichment/ReenrichWithAiPresenter.js +114 -0
- package/modules/AiEnrichment/ReenrichWithAiPresenter.js.map +1 -0
- package/modules/AiEnrichment/StreamingPlaceholder.d.ts +15 -0
- package/modules/AiEnrichment/StreamingPlaceholder.js +32 -0
- package/modules/AiEnrichment/StreamingPlaceholder.js.map +1 -0
- package/modules/AiEnrichment/abstractions.d.ts +70 -0
- package/modules/AiEnrichment/abstractions.js +6 -0
- package/modules/AiEnrichment/abstractions.js.map +1 -0
- package/modules/AiEnrichment/feature.d.ts +3 -0
- package/modules/AiEnrichment/feature.js +21 -0
- package/modules/AiEnrichment/feature.js.map +1 -0
- package/modules/AiEnrichment/index.d.ts +2 -0
- package/modules/AiEnrichment/index.js +9 -0
- package/modules/AiEnrichment/index.js.map +1 -0
- package/modules/Enterprise/index.js +3 -3
- package/modules/Enterprise/index.js.map +1 -1
- package/modules/HeadlessCms/fieldType/AssetFieldSettingsModifier.d.ts +26 -0
- package/modules/HeadlessCms/fieldType/AssetFieldSettingsModifier.js +39 -0
- package/modules/HeadlessCms/fieldType/AssetFieldSettingsModifier.js.map +1 -0
- package/modules/HeadlessCms/fieldType/AssetFieldType.d.ts +34 -0
- package/modules/HeadlessCms/fieldType/AssetFieldType.js +42 -0
- package/modules/HeadlessCms/fieldType/AssetFieldType.js.map +1 -0
- package/modules/HeadlessCms/fieldType/AssetFormFieldType.d.ts +21 -0
- package/modules/HeadlessCms/fieldType/AssetFormFieldType.js +42 -0
- package/modules/HeadlessCms/fieldType/AssetFormFieldType.js.map +1 -0
- package/modules/HeadlessCms/fieldType/AssetInputRenderer.d.ts +15 -0
- package/modules/HeadlessCms/fieldType/AssetInputRenderer.js +20 -0
- package/modules/HeadlessCms/fieldType/AssetInputRenderer.js.map +1 -0
- package/modules/HeadlessCms/fieldType/AssetInputsRenderer.d.ts +15 -0
- package/modules/HeadlessCms/fieldType/AssetInputsRenderer.js +20 -0
- package/modules/HeadlessCms/fieldType/AssetInputsRenderer.js.map +1 -0
- package/modules/HeadlessCms/fieldType/FileFieldSettingsModifier.d.ts +16 -0
- package/modules/HeadlessCms/fieldType/FileFieldSettingsModifier.js +33 -0
- package/modules/HeadlessCms/fieldType/FileFieldSettingsModifier.js.map +1 -0
- package/modules/HeadlessCms/fieldType/FileFieldType.d.ts +25 -0
- package/modules/HeadlessCms/fieldType/FileFieldType.js +38 -0
- package/modules/HeadlessCms/fieldType/FileFieldType.js.map +1 -0
- package/modules/HeadlessCms/fieldType/FileInputRenderer.d.ts +15 -0
- package/modules/HeadlessCms/fieldType/FileInputRenderer.js +19 -0
- package/modules/HeadlessCms/fieldType/FileInputRenderer.js.map +1 -0
- package/modules/HeadlessCms/fieldType/FileInputsRenderer.d.ts +15 -0
- package/modules/HeadlessCms/fieldType/FileInputsRenderer.js +19 -0
- package/modules/HeadlessCms/fieldType/FileInputsRenderer.js.map +1 -0
- package/modules/HeadlessCms/fieldType/feature.d.ts +1 -0
- package/modules/HeadlessCms/fieldType/feature.js +27 -0
- package/modules/HeadlessCms/fieldType/feature.js.map +1 -0
- package/modules/HeadlessCms/fieldType/isAssetField.d.ts +2 -0
- package/modules/HeadlessCms/fieldType/isAssetField.js +4 -0
- package/modules/HeadlessCms/fieldType/isAssetField.js.map +1 -0
- package/package.json +24 -34
- package/presentation/FileActions/FileDetails/EditImage.d.ts +2 -0
- package/presentation/FileActions/FileDetails/EditImage.js +39 -0
- package/presentation/FileActions/FileDetails/EditImage.js.map +1 -0
- package/presentation/FileActions/index.js +8 -0
- package/presentation/FileActions/index.js.map +1 -1
- package/presentation/FileDetails/FileDetailsPresenter.d.ts +5 -4
- package/presentation/FileDetails/FileDetailsPresenter.js +40 -46
- package/presentation/FileDetails/FileDetailsPresenter.js.map +1 -1
- package/presentation/FileDetails/FileDetailsPresenter.test.js +39 -56
- package/presentation/FileDetails/FileDetailsPresenter.test.js.map +1 -1
- package/presentation/FileDetails/abstractions.d.ts +2 -0
- package/presentation/FileDetails/abstractions.js.map +1 -1
- package/presentation/FileDetails/components/Content.d.ts +6 -4
- package/presentation/FileDetails/components/Content.js +2 -2
- package/presentation/FileDetails/components/Content.js.map +1 -1
- package/presentation/FileDetails/components/FileDetailsDrawer.d.ts +2 -2
- package/presentation/FileDetails/components/FileDetailsDrawer.js +11 -5
- package/presentation/FileDetails/components/FileDetailsDrawer.js.map +1 -1
- package/presentation/FileList/FileListDataSource.d.ts +8 -12
- package/presentation/FileList/FileListDataSource.js +47 -87
- package/presentation/FileList/FileListDataSource.js.map +1 -1
- package/presentation/FileList/FileListPresenter.test.js +9 -3
- package/presentation/FileList/FileListPresenter.test.js.map +1 -1
- package/presentation/FileList/FileManagerPresenter.d.ts +1 -0
- package/presentation/FileList/FileManagerPresenter.js +15 -5
- package/presentation/FileList/FileManagerPresenter.js.map +1 -1
- package/presentation/FileList/abstractions.d.ts +3 -0
- package/presentation/FileList/abstractions.js.map +1 -1
- package/presentation/FileList/components/BulkActions/BulkActionBar.d.ts +2 -2
- package/presentation/FileList/components/BulkActions/BulkActionDelete.d.ts +2 -2
- package/presentation/FileList/components/BulkActions/BulkActionMove.d.ts +2 -2
- package/presentation/FileList/components/BulkActions/index.d.ts +0 -1
- package/presentation/FileList/components/BulkActions/index.js +0 -1
- package/presentation/FileList/components/BulkActions/useBulkActionWorker.d.ts +9 -8
- package/presentation/FileList/components/BulkActions/useBulkActionWorker.js +3 -9
- package/presentation/FileList/components/BulkActions/useBulkActionWorker.js.map +1 -1
- package/presentation/FileList/components/Filters/SubFoldersToggle.d.ts +2 -2
- package/presentation/FileList/components/Filters/TagsFilter.d.ts +2 -2
- package/presentation/FileList/components/Filters/TypeFilter.d.ts +2 -2
- package/presentation/FileList/components/Grid/FileGrid.d.ts +2 -2
- package/presentation/FileList/components/Grid/FileGrid.js +1 -1
- package/presentation/FileList/components/Grid/FileGrid.js.map +1 -1
- package/presentation/FileList/components/Grid/FileGrid.test.js +18 -7
- package/presentation/FileList/components/Grid/FileGrid.test.js.map +1 -1
- package/presentation/FileList/components/Header/FileManagerHeader.d.ts +2 -2
- package/presentation/FileList/components/Search/SearchBar.d.ts +2 -2
- package/presentation/FileList/components/Table/FileTable.d.ts +2 -2
- package/presentation/FileList/components/Table/FileTable.js +1 -1
- package/presentation/FileList/components/Table/FileTable.js.map +1 -1
- package/presentation/FileList/components/Table/FileTable.test.js +9 -4
- package/presentation/FileList/components/Table/FileTable.test.js.map +1 -1
- package/presentation/FileList/components/Upload/UploadProgress.d.ts +2 -2
- package/presentation/FileManager/FileManagerBreadcrumbs.d.ts +12 -0
- package/presentation/FileManager/FileManagerBreadcrumbs.js +37 -0
- package/presentation/FileManager/FileManagerBreadcrumbs.js.map +1 -0
- package/presentation/FileManager/FileManagerView.js +36 -2
- package/presentation/FileManager/FileManagerView.js.map +1 -1
- package/presentation/FileManager/RouteParamsSync.d.ts +2 -0
- package/presentation/FileManager/RouteParamsSync.js +30 -0
- package/presentation/FileManager/RouteParamsSync.js.map +1 -0
- package/presentation/Settings/components/SettingsView.d.ts +2 -2
- package/presentation/config/DefaultFileManagerConfig.js +13 -11
- package/presentation/config/DefaultFileManagerConfig.js.map +1 -1
- package/presentation/config/FileManagerViewConfig.d.ts +19 -25
- package/presentation/config/configComponents/Browser/BulkAction.d.ts +10 -8
- package/presentation/config/configComponents/Browser/BulkAction.js +3 -9
- package/presentation/config/configComponents/Browser/BulkAction.js.map +1 -1
- package/presentation/config/configComponents/Browser/FileAction.d.ts +2 -1
- package/presentation/config/configComponents/Browser/FolderAction.d.ts +2 -1
- package/presentation/config/configComponents/Browser/Table/Column.d.ts +9 -8
- package/presentation/config/configComponents/Browser/Table/index.d.ts +9 -9
- package/presentation/config/configComponents/Browser/index.d.ts +20 -20
- package/presentation/config/configComponents/Browser/index.js +0 -8
- package/presentation/config/configComponents/Browser/index.js.map +1 -1
- package/presentation/config/configComponents/FileDetails/index.d.ts +4 -2
- package/presentation/config/thumbnailRenderers/CroppedFileImage.d.ts +18 -0
- package/presentation/config/thumbnailRenderers/CroppedFileImage.js +66 -0
- package/presentation/config/thumbnailRenderers/CroppedFileImage.js.map +1 -0
- package/presentation/config/thumbnailRenderers/FilePreviewImageRenderer.js +6 -9
- package/presentation/config/thumbnailRenderers/FilePreviewImageRenderer.js.map +1 -1
- package/presentation/config/thumbnailRenderers/GridItemImageRenderer.js +6 -9
- package/presentation/config/thumbnailRenderers/GridItemImageRenderer.js.map +1 -1
- package/presentation/config/thumbnailRenderers/TableItemImageRenderer.js +6 -9
- package/presentation/config/thumbnailRenderers/TableItemImageRenderer.js.map +1 -1
- package/presentation/fieldRenderers/CmsAssetPickerRenderer.d.ts +22 -0
- package/presentation/fieldRenderers/CmsAssetPickerRenderer.js +56 -0
- package/presentation/fieldRenderers/CmsAssetPickerRenderer.js.map +1 -0
- package/presentation/fieldRenderers/CmsFilePickerRenderer.d.ts +13 -0
- package/presentation/fieldRenderers/CmsFilePickerRenderer.js +36 -0
- package/presentation/fieldRenderers/CmsFilePickerRenderer.js.map +1 -0
- package/presentation/fieldRenderers/CmsImageEditorDialog.d.ts +7 -0
- package/presentation/fieldRenderers/CmsImageEditorDialog.js +32 -0
- package/presentation/fieldRenderers/CmsImageEditorDialog.js.map +1 -0
- package/presentation/fieldRenderers/CmsMultiAssetPickerRenderer.d.ts +18 -0
- package/presentation/fieldRenderers/CmsMultiAssetPickerRenderer.js +88 -0
- package/presentation/fieldRenderers/CmsMultiAssetPickerRenderer.js.map +1 -0
- package/presentation/fieldRenderers/CmsMultiFilePickerRenderer.d.ts +13 -0
- package/presentation/fieldRenderers/CmsMultiFilePickerRenderer.js +60 -0
- package/presentation/fieldRenderers/CmsMultiFilePickerRenderer.js.map +1 -0
- package/presentation/fieldRenderers/CroppedAssetThumb.d.ts +15 -0
- package/presentation/fieldRenderers/CroppedAssetThumb.js +25 -0
- package/presentation/fieldRenderers/CroppedAssetThumb.js.map +1 -0
- package/presentation/fieldRenderers/assetValue.d.ts +10 -0
- package/presentation/fieldRenderers/assetValue.js +88 -0
- package/presentation/fieldRenderers/assetValue.js.map +1 -0
- package/presentation/hooks/useCmsImageEditor.d.ts +10 -0
- package/presentation/hooks/useCmsImageEditor.js +76 -0
- package/presentation/hooks/useCmsImageEditor.js.map +1 -0
- package/presentation/hooks/useEditImage.d.ts +14 -0
- package/presentation/hooks/useEditImage.js +67 -0
- package/presentation/hooks/useEditImage.js.map +1 -0
- package/routes.d.ts +1 -0
- package/routes.js +2 -1
- package/routes.js.map +1 -1
- package/modules/HeadlessCms/fileField.d.ts +0 -2
- package/modules/HeadlessCms/fileField.js +0 -44
- package/modules/HeadlessCms/fileField.js.map +0 -1
- package/modules/HeadlessCms/fileRenderer/fileField.d.ts +0 -2
- package/modules/HeadlessCms/fileRenderer/fileField.js +0 -53
- package/modules/HeadlessCms/fileRenderer/fileField.js.map +0 -1
- package/modules/HeadlessCms/fileRenderer/fileFields.d.ts +0 -2
- package/modules/HeadlessCms/fileRenderer/fileFields.js +0 -73
- package/modules/HeadlessCms/fileRenderer/fileFields.js.map +0 -1
- package/modules/HeadlessCms/fileRenderer/utils.d.ts +0 -2
- package/modules/HeadlessCms/fileRenderer/utils.js +0 -15
- package/modules/HeadlessCms/fileRenderer/utils.js.map +0 -1
- package/modules/HeadlessCms/index.d.ts +0 -1
- package/modules/HeadlessCms/index.js +0 -14
- package/modules/HeadlessCms/index.js.map +0 -1
- package/modules/Settings/graphql.d.ts +0 -12
- package/modules/Settings/graphql.js +0 -36
- package/modules/Settings/graphql.js.map +0 -1
- package/modules/Settings/views/FileManagerSettings.d.ts +0 -2
- package/modules/Settings/views/FileManagerSettings.js +0 -134
- package/modules/Settings/views/FileManagerSettings.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/AddOperation.d.ts +0 -7
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/AddOperation.js +0 -15
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/AddOperation.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditor.d.ts +0 -15
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditor.js +0 -44
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditor.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialog.d.ts +0 -15
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialog.js +0 -52
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialog.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialogPresenter.d.ts +0 -61
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialogPresenter.js +0 -111
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialogPresenter.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialogPresenter.test.d.ts +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialogPresenter.test.js +0 -372
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/BatchEditorDialogPresenter.test.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/FieldRenderer.d.ts +0 -8
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/FieldRenderer.js +0 -31
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/FieldRenderer.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/Operation.d.ts +0 -11
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/Operation.js +0 -33
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/Operation.js.map +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/index.d.ts +0 -1
- package/presentation/FileList/components/BulkActions/BatchEditorDialog/index.js +0 -1
- package/presentation/FileList/components/BulkActions/BulkActionEdit.d.ts +0 -4
- package/presentation/FileList/components/BulkActions/BulkActionEdit.js +0 -105
- package/presentation/FileList/components/BulkActions/BulkActionEdit.js.map +0 -1
- package/presentation/config/configComponents/Browser/FolderFieldDecorator.d.ts +0 -7
- package/presentation/config/configComponents/Browser/FolderFieldDecorator.js +0 -11
- package/presentation/config/configComponents/Browser/FolderFieldDecorator.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/FileList/components/BulkActions/useBulkActionWorker.js","sources":["../../../../../src/presentation/FileList/components/BulkActions/useBulkActionWorker.ts"],"sourcesContent":["import { useCallback,
|
|
1
|
+
{"version":3,"file":"presentation/FileList/components/BulkActions/useBulkActionWorker.js","sources":["../../../../../src/presentation/FileList/components/BulkActions/useBulkActionWorker.ts"],"sourcesContent":["import { useCallback, useMemo, useRef } from \"react\";\nimport type { CallbackParams } from \"@webiny/app-admin\";\nimport { useButtons, useDialogWithReport, Worker } from \"@webiny/app-admin\";\nimport { useFileManagerPresenter } from \"../../FileManagerPresenterProvider.js\";\nimport type { FmFile } from \"~/features/shared/types.js\";\nimport { getFilesLabel } from \"./BulkActionBar.js\";\n\n// Hook that bridges the new presenter-based selection with the Worker pattern.\nconst useWorker = () => {\n const { vm, actions } = useFileManagerPresenter();\n const { current: worker } = useRef(new Worker<FmFile>());\n\n const selectedFiles = useMemo(() => {\n const { selectedIds } = vm.list.selection;\n return vm.list.rows.filter(row => selectedIds.has(row.id));\n }, [vm.list.selection.selectedIds, vm.list.rows]);\n\n const resetItems = useCallback(() => {\n actions.selection.deselectAll();\n }, []);\n\n const resetResults = useCallback(async () => {\n worker.resetResults();\n }, []);\n\n return {\n items: selectedFiles,\n process: (callback: (items: FmFile[]) => void) => worker.process(selectedFiles, callback),\n processInSeries: async (\n callback: ({ item, allItems, report }: CallbackParams<FmFile>) => Promise<void>,\n chunkSize?: number\n ) => worker.processInSeries(selectedFiles, callback, chunkSize),\n resetItems,\n results: worker.results,\n resetResults\n };\n};\n\n// Compose the BulkAction utilities for the new v2 architecture.\nexport const BulkAction = {\n useButtons,\n useWorker,\n useDialog: useDialogWithReport\n};\n\nexport { getFilesLabel };\n"],"names":["useWorker","vm","actions","useFileManagerPresenter","worker","useRef","Worker","selectedFiles","useMemo","selectedIds","row","resetItems","useCallback","resetResults","callback","chunkSize","BulkAction","useButtons","useDialogWithReport"],"mappings":";;;AAQA,MAAMA,YAAY;IACd,MAAM,EAAEC,EAAE,EAAEC,OAAO,EAAE,GAAGC;IACxB,MAAM,EAAE,SAASC,MAAM,EAAE,GAAGC,OAAO,IAAIC;IAEvC,MAAMC,gBAAgBC,QAAQ;QAC1B,MAAM,EAAEC,WAAW,EAAE,GAAGR,GAAG,IAAI,CAAC,SAAS;QACzC,OAAOA,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAACS,CAAAA,MAAOD,YAAY,GAAG,CAACC,IAAI,EAAE;IAC5D,GAAG;QAACT,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW;QAAEA,GAAG,IAAI,CAAC,IAAI;KAAC;IAEhD,MAAMU,aAAaC,YAAY;QAC3BV,QAAQ,SAAS,CAAC,WAAW;IACjC,GAAG,EAAE;IAEL,MAAMW,eAAeD,YAAY;QAC7BR,OAAO,YAAY;IACvB,GAAG,EAAE;IAEL,OAAO;QACH,OAAOG;QACP,SAAS,CAACO,WAAwCV,OAAO,OAAO,CAACG,eAAeO;QAChF,iBAAiB,OACbA,UACAC,YACCX,OAAO,eAAe,CAACG,eAAeO,UAAUC;QACrDJ;QACA,SAASP,OAAO,OAAO;QACvBS;IACJ;AACJ;AAGO,MAAMG,aAAa;IACtBC,YAAUA;IACVjB,WAAAA;IACA,WAAWkB;AACf"}
|
|
@@ -4,6 +4,6 @@ import React from "react";
|
|
|
4
4
|
* Sets the "includeSubFolders" filter which the FileListDataSource uses
|
|
5
5
|
* to expand the folder scope via GetDescendantFoldersUseCase.
|
|
6
6
|
*/
|
|
7
|
-
export declare const SubFoldersToggle: (() => React.JSX.Element) & {
|
|
8
|
-
|
|
7
|
+
export declare const SubFoldersToggle: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
8
|
+
readonly type: () => React.JSX.Element;
|
|
9
9
|
};
|
|
@@ -4,6 +4,6 @@ import React from "react";
|
|
|
4
4
|
* Reads available tags from vm.tags, supports AND/OR filter modes,
|
|
5
5
|
* and dispatches changes via presenter.actions.filter.set("tags", ...).
|
|
6
6
|
*/
|
|
7
|
-
export declare const TagsFilter: (() => React.JSX.Element) & {
|
|
8
|
-
|
|
7
|
+
export declare const TagsFilter: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
8
|
+
readonly type: () => React.JSX.Element;
|
|
9
9
|
};
|
|
@@ -3,6 +3,6 @@ import React from "react";
|
|
|
3
3
|
* File type filter component wired to the FileListPresenter.
|
|
4
4
|
* Sets the "type" filter via presenter.actions.filter.set/clear.
|
|
5
5
|
*/
|
|
6
|
-
export declare const TypeFilter: (() => React.JSX.Element) & {
|
|
7
|
-
|
|
6
|
+
export declare const TypeFilter: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
7
|
+
readonly type: () => React.JSX.Element;
|
|
8
8
|
};
|
|
@@ -4,6 +4,6 @@ import React from "react";
|
|
|
4
4
|
* Renders file thumbnail cards and folder cards in a responsive grid layout.
|
|
5
5
|
* Wires click-to-select through presenter.actions.selection.
|
|
6
6
|
*/
|
|
7
|
-
export declare const FileGrid: (() => React.JSX.Element) & {
|
|
8
|
-
|
|
7
|
+
export declare const FileGrid: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
8
|
+
readonly type: () => React.JSX.Element;
|
|
9
9
|
};
|
|
@@ -116,7 +116,7 @@ const FileGrid_FileGrid = observer(function() {
|
|
|
116
116
|
const presenter = useFileManagerPresenter();
|
|
117
117
|
const { vm, actions } = presenter;
|
|
118
118
|
const overlay = useOverlay();
|
|
119
|
-
const childFolders = vm.
|
|
119
|
+
const childFolders = vm.childFolders;
|
|
120
120
|
const handleFolderNavigate = useCallback((folderId)=>{
|
|
121
121
|
actions.folders.selectFolder(folderId);
|
|
122
122
|
}, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/FileList/components/Grid/FileGrid.js","sources":["../../../../../src/presentation/FileList/components/Grid/FileGrid.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport LazyLoad from \"react-lazy-load\";\nimport { cn, CheckboxPrimitive, Text, TimeAgo } from \"@webiny/admin-ui\";\nimport { useOverlay } from \"~/presentation/FileManager/OverlayContext.js\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { FolderIcon } from \"@webiny/app-aco\";\nimport { useFileManagerPresenter } from \"../../FileManagerPresenterProvider.js\";\nimport { useFileManagerConfig } from \"~/presentation/config/FileManagerViewConfig.js\";\nimport { FileProvider } from \"~/presentation/contexts/FileProvider.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\nimport type { FileItem } from \"~/domain/types.js\";\n\nconst t = i18n.ns(\"app-file-manager/presentation/file-grid\");\n\n// ---------------------------------------------------------------------------\n// FolderCard — renders a single folder in the grid.\n// ---------------------------------------------------------------------------\n\ninterface FolderCardProps {\n folder: FolderDto;\n onNavigate: (folderId: string) => void;\n}\n\nconst FolderCard = ({ folder, onNavigate }: FolderCardProps) => {\n return (\n <div\n className={cn([\n \"group\",\n \"bg-neutral-base rounded-lg\",\n \"shadow-sm hover:shadow-lg\",\n \"border-sm border-solid border-neutral-base hover:border-neutral-dimmed-darker\",\n \"transition-shadow duration-250 ease-in-out\",\n \"overflow-hidden\",\n \"cursor-pointer\"\n ])}\n onClick={() => onNavigate(folder.id)}\n data-testid={\"fm-grid-folder-card\"}\n data-folder-id={folder.id}\n >\n <div style={{ height: 150 }} className={\"flex items-center justify-center\"}>\n <FolderIcon width={90} height={90} />\n </div>\n <div className={\"px-md py-sm-extra\"}>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-primary\"}>\n {folder.title}\n </Text>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-dimmed\"}>\n {t`Folder`}\n </Text>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// FileCard — renders a single file in the grid.\n// ---------------------------------------------------------------------------\n\ninterface FileCardProps {\n file: FileItem;\n selected: boolean;\n onToggle: (id: string, shiftKey: boolean) => void;\n}\n\nconst FileCard = observer(function FileCard({ file, selected, onToggle }: FileCardProps) {\n const { browser, getThumbnailRenderer } = useFileManagerConfig();\n const { itemActions } = browser.grid;\n\n const renderer = getThumbnailRenderer(browser.grid.itemThumbnails, file);\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onToggle(file.id, e.shiftKey);\n },\n [file.id, onToggle]\n );\n\n return (\n <FileProvider file={file}>\n <div\n onClick={handleClick}\n className={cn([\n \"group\",\n \"bg-neutral-base rounded-lg\",\n \"shadow-sm hover:shadow-lg\",\n \"border-sm border-solid border-neutral-base hover:border-neutral-dimmed-darker\",\n selected && \"ring-md ring-primary-strong\",\n \"transition-shadow duration-250 ease-in-out\",\n \"overflow-hidden\",\n \"cursor-pointer\"\n ])}\n data-testid={\"fm-grid-file-card\"}\n data-file-id={file.id}\n >\n <div className={\"relative\"}>\n {/* Selection checkbox. */}\n <div\n className={cn([\n \"p-xs rounded-md\",\n \"bg-neutral-base/30\",\n \"absolute top-sm left-sm z-[1]\",\n selected ? \"visible\" : \"invisible group-hover:visible\"\n ])}\n >\n <CheckboxPrimitive\n onClick={handleClick}\n checked={selected}\n onChange={() => void 0}\n />\n </div>\n {/* Item actions (hover). */}\n <div\n className={cn([\n \"invisible group-hover:visible\",\n \"flex items-center gap-xxs\",\n \"p-xs\",\n \"absolute top-xs-plus right-xs-plus z-[1]\"\n ])}\n >\n {itemActions.map(action => (\n <React.Fragment key={action.name}>{action.element}</React.Fragment>\n ))}\n </div>\n {/* Thumbnail. */}\n <LazyLoad\n height={150}\n offset={\"300px\"}\n className={cn([\n \"bg-neutral-muted\",\n \"flex items-center justify-center\",\n \"text-neutral-strong text-sm\"\n ])}\n >\n {renderer?.element || null}\n </LazyLoad>\n </div>\n {/* File label. */}\n <div className={\"px-md py-sm-extra\"}>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-primary\"}>\n {file.name}\n </Text>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-dimmed\"}>\n {file.type} {\" // \"} <TimeAgo datetime={file.createdOn} />\n </Text>\n </div>\n </div>\n </FileProvider>\n );\n});\n\n// ---------------------------------------------------------------------------\n// FileGrid — the main grid view component.\n// ---------------------------------------------------------------------------\n\n/**\n * Grid/Gallery View component driven by FileListPresenter vm.\n * Renders file thumbnail cards and folder cards in a responsive grid layout.\n * Wires click-to-select through presenter.actions.selection.\n */\nexport const FileGrid = observer(function FileGrid() {\n const presenter = useFileManagerPresenter();\n const { vm, actions } = presenter;\n\n const overlay = useOverlay();\n const childFolders = vm.folders.childFolders;\n\n // Handle folder navigation.\n const handleFolderNavigate = useCallback(\n (folderId: string) => {\n actions.folders.selectFolder(folderId);\n },\n [actions.filter]\n );\n\n const handleToggle = (id: string, shiftKey: boolean) => {\n // Shift-click always does range selection, regardless of overlay mode.\n if (shiftKey) {\n actions.selection.selectRangeTo(id);\n return;\n }\n\n if (overlay) {\n const file = vm.list.rows.find(f => f.id === id);\n if (file) {\n overlay.onFileClick(file);\n }\n return;\n }\n\n actions.selection.toggle(id);\n };\n\n // Deselect all when clicking the grid background.\n const handleBackgroundClick = useCallback(() => {\n actions.selection.deselectAll();\n }, [actions.selection]);\n\n return (\n <div\n className={cn([\"p-lg\", \"grid gap-md\"])}\n style={{ gridTemplateColumns: \"repeat(auto-fill, minmax(200px, 1fr))\" }}\n onClick={handleBackgroundClick}\n data-testid={\"fm-file-grid\"}\n >\n {vm.showFolders &&\n childFolders.map(folder => (\n <FolderCard key={folder.id} folder={folder} onNavigate={handleFolderNavigate} />\n ))}\n {vm.list.rows.map(file => (\n <FileCard\n key={file.id}\n file={file}\n selected={vm.list.selection.selectedIds.has(file.id)}\n onToggle={handleToggle}\n />\n ))}\n </div>\n );\n});\n"],"names":["t","i18n","FolderCard","folder","onNavigate","cn","FolderIcon","Text","FileCard","observer","file","selected","onToggle","browser","getThumbnailRenderer","useFileManagerConfig","itemActions","renderer","handleClick","useCallback","e","FileProvider","CheckboxPrimitive","action","React","LazyLoad","TimeAgo","FileGrid","presenter","useFileManagerPresenter","vm","actions","overlay","useOverlay","childFolders","handleFolderNavigate","folderId","handleToggle","id","shiftKey","f","handleBackgroundClick"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"presentation/FileList/components/Grid/FileGrid.js","sources":["../../../../../src/presentation/FileList/components/Grid/FileGrid.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport LazyLoad from \"react-lazy-load\";\nimport { cn, CheckboxPrimitive, Text, TimeAgo } from \"@webiny/admin-ui\";\nimport { useOverlay } from \"~/presentation/FileManager/OverlayContext.js\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { FolderIcon } from \"@webiny/app-aco\";\nimport { useFileManagerPresenter } from \"../../FileManagerPresenterProvider.js\";\nimport { useFileManagerConfig } from \"~/presentation/config/FileManagerViewConfig.js\";\nimport { FileProvider } from \"~/presentation/contexts/FileProvider.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\nimport type { FileItem } from \"~/domain/types.js\";\n\nconst t = i18n.ns(\"app-file-manager/presentation/file-grid\");\n\n// ---------------------------------------------------------------------------\n// FolderCard — renders a single folder in the grid.\n// ---------------------------------------------------------------------------\n\ninterface FolderCardProps {\n folder: FolderDto;\n onNavigate: (folderId: string) => void;\n}\n\nconst FolderCard = ({ folder, onNavigate }: FolderCardProps) => {\n return (\n <div\n className={cn([\n \"group\",\n \"bg-neutral-base rounded-lg\",\n \"shadow-sm hover:shadow-lg\",\n \"border-sm border-solid border-neutral-base hover:border-neutral-dimmed-darker\",\n \"transition-shadow duration-250 ease-in-out\",\n \"overflow-hidden\",\n \"cursor-pointer\"\n ])}\n onClick={() => onNavigate(folder.id)}\n data-testid={\"fm-grid-folder-card\"}\n data-folder-id={folder.id}\n >\n <div style={{ height: 150 }} className={\"flex items-center justify-center\"}>\n <FolderIcon width={90} height={90} />\n </div>\n <div className={\"px-md py-sm-extra\"}>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-primary\"}>\n {folder.title}\n </Text>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-dimmed\"}>\n {t`Folder`}\n </Text>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// FileCard — renders a single file in the grid.\n// ---------------------------------------------------------------------------\n\ninterface FileCardProps {\n file: FileItem;\n selected: boolean;\n onToggle: (id: string, shiftKey: boolean) => void;\n}\n\nconst FileCard = observer(function FileCard({ file, selected, onToggle }: FileCardProps) {\n const { browser, getThumbnailRenderer } = useFileManagerConfig();\n const { itemActions } = browser.grid;\n\n const renderer = getThumbnailRenderer(browser.grid.itemThumbnails, file);\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onToggle(file.id, e.shiftKey);\n },\n [file.id, onToggle]\n );\n\n return (\n <FileProvider file={file}>\n <div\n onClick={handleClick}\n className={cn([\n \"group\",\n \"bg-neutral-base rounded-lg\",\n \"shadow-sm hover:shadow-lg\",\n \"border-sm border-solid border-neutral-base hover:border-neutral-dimmed-darker\",\n selected && \"ring-md ring-primary-strong\",\n \"transition-shadow duration-250 ease-in-out\",\n \"overflow-hidden\",\n \"cursor-pointer\"\n ])}\n data-testid={\"fm-grid-file-card\"}\n data-file-id={file.id}\n >\n <div className={\"relative\"}>\n {/* Selection checkbox. */}\n <div\n className={cn([\n \"p-xs rounded-md\",\n \"bg-neutral-base/30\",\n \"absolute top-sm left-sm z-[1]\",\n selected ? \"visible\" : \"invisible group-hover:visible\"\n ])}\n >\n <CheckboxPrimitive\n onClick={handleClick}\n checked={selected}\n onChange={() => void 0}\n />\n </div>\n {/* Item actions (hover). */}\n <div\n className={cn([\n \"invisible group-hover:visible\",\n \"flex items-center gap-xxs\",\n \"p-xs\",\n \"absolute top-xs-plus right-xs-plus z-[1]\"\n ])}\n >\n {itemActions.map(action => (\n <React.Fragment key={action.name}>{action.element}</React.Fragment>\n ))}\n </div>\n {/* Thumbnail. */}\n <LazyLoad\n height={150}\n offset={\"300px\"}\n className={cn([\n \"bg-neutral-muted\",\n \"flex items-center justify-center\",\n \"text-neutral-strong text-sm\"\n ])}\n >\n {renderer?.element || null}\n </LazyLoad>\n </div>\n {/* File label. */}\n <div className={\"px-md py-sm-extra\"}>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-primary\"}>\n {file.name}\n </Text>\n <Text size={\"sm\"} as={\"div\"} className={\"truncate text-neutral-dimmed\"}>\n {file.type} {\" // \"} <TimeAgo datetime={file.createdOn} />\n </Text>\n </div>\n </div>\n </FileProvider>\n );\n});\n\n// ---------------------------------------------------------------------------\n// FileGrid — the main grid view component.\n// ---------------------------------------------------------------------------\n\n/**\n * Grid/Gallery View component driven by FileListPresenter vm.\n * Renders file thumbnail cards and folder cards in a responsive grid layout.\n * Wires click-to-select through presenter.actions.selection.\n */\nexport const FileGrid = observer(function FileGrid() {\n const presenter = useFileManagerPresenter();\n const { vm, actions } = presenter;\n\n const overlay = useOverlay();\n const childFolders = vm.childFolders;\n\n // Handle folder navigation.\n const handleFolderNavigate = useCallback(\n (folderId: string) => {\n actions.folders.selectFolder(folderId);\n },\n [actions.filter]\n );\n\n const handleToggle = (id: string, shiftKey: boolean) => {\n // Shift-click always does range selection, regardless of overlay mode.\n if (shiftKey) {\n actions.selection.selectRangeTo(id);\n return;\n }\n\n if (overlay) {\n const file = vm.list.rows.find(f => f.id === id);\n if (file) {\n overlay.onFileClick(file);\n }\n return;\n }\n\n actions.selection.toggle(id);\n };\n\n // Deselect all when clicking the grid background.\n const handleBackgroundClick = useCallback(() => {\n actions.selection.deselectAll();\n }, [actions.selection]);\n\n return (\n <div\n className={cn([\"p-lg\", \"grid gap-md\"])}\n style={{ gridTemplateColumns: \"repeat(auto-fill, minmax(200px, 1fr))\" }}\n onClick={handleBackgroundClick}\n data-testid={\"fm-file-grid\"}\n >\n {vm.showFolders &&\n childFolders.map(folder => (\n <FolderCard key={folder.id} folder={folder} onNavigate={handleFolderNavigate} />\n ))}\n {vm.list.rows.map(file => (\n <FileCard\n key={file.id}\n file={file}\n selected={vm.list.selection.selectedIds.has(file.id)}\n onToggle={handleToggle}\n />\n ))}\n </div>\n );\n});\n"],"names":["t","i18n","FolderCard","folder","onNavigate","cn","FolderIcon","Text","FileCard","observer","file","selected","onToggle","browser","getThumbnailRenderer","useFileManagerConfig","itemActions","renderer","handleClick","useCallback","e","FileProvider","CheckboxPrimitive","action","React","LazyLoad","TimeAgo","FileGrid","presenter","useFileManagerPresenter","vm","actions","overlay","useOverlay","childFolders","handleFolderNavigate","folderId","handleToggle","id","shiftKey","f","handleBackgroundClick"],"mappings":"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"}
|
|
@@ -59,6 +59,8 @@ function createMockFolderDto(overrides = {}) {
|
|
|
59
59
|
function createMockPresenter(vmOverrides = {}) {
|
|
60
60
|
const defaultVm = observable({
|
|
61
61
|
fileModel: null,
|
|
62
|
+
loading: false,
|
|
63
|
+
empty: true,
|
|
62
64
|
list: {
|
|
63
65
|
rows: [],
|
|
64
66
|
sort: null,
|
|
@@ -75,8 +77,10 @@ function createMockPresenter(vmOverrides = {}) {
|
|
|
75
77
|
selection: {
|
|
76
78
|
selectedIds: new Set(),
|
|
77
79
|
selectedCount: 0,
|
|
78
|
-
allSelected: false
|
|
80
|
+
allSelected: false,
|
|
81
|
+
label: ""
|
|
79
82
|
},
|
|
83
|
+
showingFilters: false,
|
|
80
84
|
empty: true,
|
|
81
85
|
emptyWithFilters: false,
|
|
82
86
|
error: null
|
|
@@ -114,9 +118,8 @@ function createMockPresenter(vmOverrides = {}) {
|
|
|
114
118
|
isUploading: false
|
|
115
119
|
},
|
|
116
120
|
tags: [],
|
|
117
|
-
loading: false,
|
|
118
|
-
empty: false,
|
|
119
121
|
showFolders: true,
|
|
122
|
+
childFolders: [],
|
|
120
123
|
viewMode: "grid",
|
|
121
124
|
dragging: false,
|
|
122
125
|
showingFilters: false,
|
|
@@ -141,7 +144,9 @@ function createMockPresenter(vmOverrides = {}) {
|
|
|
141
144
|
filter: {
|
|
142
145
|
set: vi.fn(),
|
|
143
146
|
clear: vi.fn(),
|
|
144
|
-
clearAll: vi.fn()
|
|
147
|
+
clearAll: vi.fn(),
|
|
148
|
+
show: vi.fn(),
|
|
149
|
+
hide: vi.fn()
|
|
145
150
|
},
|
|
146
151
|
selection: {
|
|
147
152
|
toggle: vi.fn(),
|
|
@@ -305,8 +310,10 @@ describe("FileGrid — selection action wiring", ()=>{
|
|
|
305
310
|
"file-1"
|
|
306
311
|
]),
|
|
307
312
|
selectedCount: 1,
|
|
308
|
-
allSelected: false
|
|
313
|
+
allSelected: false,
|
|
314
|
+
label: "1 item"
|
|
309
315
|
},
|
|
316
|
+
showingFilters: false,
|
|
310
317
|
empty: false,
|
|
311
318
|
emptyWithFilters: false,
|
|
312
319
|
appliedQuery: null,
|
|
@@ -343,8 +350,10 @@ describe("FileGrid — loading state", ()=>{
|
|
|
343
350
|
selection: {
|
|
344
351
|
selectedIds: new Set(),
|
|
345
352
|
selectedCount: 0,
|
|
346
|
-
allSelected: false
|
|
353
|
+
allSelected: false,
|
|
354
|
+
label: ""
|
|
347
355
|
},
|
|
356
|
+
showingFilters: false,
|
|
348
357
|
empty: true,
|
|
349
358
|
emptyWithFilters: false,
|
|
350
359
|
appliedQuery: null,
|
|
@@ -373,8 +382,10 @@ describe("FileGrid — loading state", ()=>{
|
|
|
373
382
|
selection: {
|
|
374
383
|
selectedIds: new Set(),
|
|
375
384
|
selectedCount: 0,
|
|
376
|
-
allSelected: false
|
|
385
|
+
allSelected: false,
|
|
386
|
+
label: ""
|
|
377
387
|
},
|
|
388
|
+
showingFilters: false,
|
|
378
389
|
empty: false,
|
|
379
390
|
emptyWithFilters: false,
|
|
380
391
|
appliedQuery: null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/FileList/components/Grid/FileGrid.test.js","sources":["../../../../../src/presentation/FileList/components/Grid/FileGrid.test.ts"],"sourcesContent":["// @vitest-environment jsdom\nimport { describe, it, expect, vi } from \"vitest\";\nimport { observable } from \"mobx\";\nimport type { IFileManagerPresenter, IFileManagerViewModel } from \"../../abstractions.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\nimport type { FmFile } from \"~/features/shared/types.js\";\n\n// ---------------------------------------------------------------------------\n// Mock factories.\n// ---------------------------------------------------------------------------\n\nfunction createMockFile(overrides: Partial<FmFile> = {}): FmFile {\n return {\n id: \"file-1\",\n name: \"photo.jpg\",\n key: \"files/photo.jpg\",\n src: \"https://cdn.example.com/files/photo.jpg\",\n type: \"image/jpeg\",\n size: 1024,\n metadata: {},\n tags: [],\n createdOn: \"2025-01-01T00:00:00Z\",\n savedOn: \"2025-01-02T00:00:00Z\",\n createdBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n savedBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n location: { folderId: \"root\" },\n ...overrides\n };\n}\n\nconst emptyIdentity = { id: \"\", displayName: \"\", type: \"\" };\n\nfunction createMockFolderDto(overrides: Partial<FolderDto> = {}): FolderDto {\n return {\n id: \"folder-1\",\n title: \"Documents\",\n slug: \"documents\",\n type: \"\",\n parentId: null,\n path: \"\",\n permissions: [],\n hasNonInheritedPermissions: false,\n canManagePermissions: false,\n canManageStructure: true,\n canManageContent: false,\n createdBy: emptyIdentity,\n createdOn: \"\",\n savedBy: emptyIdentity,\n savedOn: \"\",\n modifiedBy: null,\n modifiedOn: null,\n extensions: {},\n ...overrides\n };\n}\n\nfunction createMockPresenter(\n vmOverrides: Partial<IFileManagerViewModel> = {}\n): IFileManagerPresenter {\n const defaultVm: IFileManagerViewModel = observable({\n fileModel: null,\n list: {\n rows: [],\n sort: null,\n filters: {},\n search: \"\",\n appliedQuery: null,\n pagination: {\n hasMore: false,\n loading: false,\n loadingMore: false,\n totalCount: 0,\n currentCount: 0\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false\n },\n empty: true,\n emptyWithFilters: false,\n error: null\n },\n folders: {\n folders: [],\n tree: [],\n currentFolderId: null,\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: true,\n currentFolderTitle: \"All Files\",\n childFolders: [],\n loadingNodeIds: []\n },\n permissions: {\n canRead: true,\n canCreate: true,\n canEdit: true,\n canDelete: true,\n canEditFile: () => true,\n canDeleteFile: () => true\n },\n upload: {\n jobs: [],\n overallProgress: { percentage: 0, bytesSent: 0, totalBytes: 0 },\n isUploading: false\n },\n tags: [],\n loading: false,\n empty: false,\n showFolders: true,\n viewMode: \"grid\" as const,\n dragging: false,\n showingFilters: false,\n isOverlay: false,\n accept: [],\n multiple: false,\n scope: undefined,\n fileDetails: null,\n ...vmOverrides\n });\n\n return {\n vm: defaultVm,\n actions: {\n search: { set: vi.fn(), clear: vi.fn() },\n sort: { set: vi.fn(), toggle: vi.fn() },\n filter: { set: vi.fn(), clear: vi.fn(), clearAll: vi.fn() },\n selection: {\n toggle: vi.fn(),\n selectRangeTo: vi.fn(),\n selectAll: vi.fn(),\n deselectAll: vi.fn(),\n selectRows: vi.fn(),\n isSelected: vi.fn().mockReturnValue(false)\n },\n loadMore: vi.fn().mockResolvedValue(undefined),\n refresh: vi.fn().mockResolvedValue(undefined),\n upload: vi.fn().mockResolvedValue(undefined),\n setViewMode: vi.fn(),\n showFileDetails: vi.fn(),\n hideFileDetails: vi.fn(),\n setDragging: vi.fn(),\n showFilters: vi.fn(),\n hideFilters: vi.fn(),\n folders: {\n selectFolder: vi.fn(),\n createFolder: vi.fn(),\n editFolder: vi.fn(),\n deleteFolder: vi.fn().mockResolvedValue(undefined),\n moveFolder: vi.fn().mockResolvedValue(undefined),\n loadChildFolders: vi.fn().mockResolvedValue(undefined),\n canManageStructure: vi.fn().mockReturnValue(true),\n getAncestorIds: vi.fn().mockReturnValue([]),\n submitOperation: vi.fn().mockResolvedValue(true),\n cancelOperation: vi.fn()\n }\n },\n init: vi.fn(),\n dispose: vi.fn()\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tests — Grid data composition logic.\n// ---------------------------------------------------------------------------\n\ndescribe(\"FileGrid — child folder resolution\", () => {\n it(\"should use vm.folders.childFolders when no current folder is selected\", () => {\n const childFolders = [\n createMockFolderDto({ id: \"f1\", title: \"Docs\" }),\n createMockFolderDto({ id: \"f2\", title: \"Photos\" })\n ];\n const presenter = createMockPresenter({\n folders: observable({\n folders: childFolders,\n tree: [],\n currentFolderId: null,\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: true,\n currentFolderTitle: \"All Files\",\n childFolders,\n loadingNodeIds: []\n })\n });\n\n expect(presenter.vm.folders.childFolders).toHaveLength(2);\n expect(presenter.vm.folders.childFolders[0].id).toBe(\"f1\");\n expect(presenter.vm.folders.childFolders[1].id).toBe(\"f2\");\n });\n\n it(\"should expose child folders via vm.folders.childFolders when a folder is selected\", () => {\n const childA = createMockFolderDto({ id: \"child-a\", title: \"Sub A\" });\n const childB = createMockFolderDto({ id: \"child-b\", title: \"Sub B\" });\n\n const presenter = createMockPresenter({\n folders: observable({\n folders: [],\n tree: [],\n currentFolderId: \"parent\",\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: false,\n currentFolderTitle: \"Parent\",\n childFolders: [childA, childB],\n loadingNodeIds: []\n })\n });\n\n expect(presenter.vm.folders.childFolders).toHaveLength(2);\n expect(presenter.vm.folders.childFolders[0].id).toBe(\"child-a\");\n expect(presenter.vm.folders.childFolders[1].id).toBe(\"child-b\");\n });\n\n it(\"should return empty childFolders when current folder has no children\", () => {\n const presenter = createMockPresenter({\n folders: observable({\n folders: [],\n tree: [],\n currentFolderId: \"leaf\",\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: false,\n currentFolderTitle: \"Leaf\",\n childFolders: [],\n loadingNodeIds: []\n })\n });\n\n expect(presenter.vm.folders.childFolders).toHaveLength(0);\n });\n});\n\ndescribe(\"FileGrid — selection action wiring\", () => {\n it(\"should call actions.selection.toggle with file id on file click\", () => {\n const presenter = createMockPresenter();\n\n // Simulate what the component does when a file card is clicked.\n const fileId = \"file-1\";\n presenter.actions.selection.toggle(fileId);\n\n expect(presenter.actions.selection.toggle).toHaveBeenCalledWith(\"file-1\");\n });\n\n it(\"should call actions.selection.deselectAll on background click\", () => {\n const presenter = createMockPresenter();\n\n // Simulate background click handler.\n presenter.actions.selection.deselectAll();\n\n expect(presenter.actions.selection.deselectAll).toHaveBeenCalled();\n });\n\n it(\"should correctly determine selected state from vm.list.selection.selectedIds\", () => {\n const file1 = createMockFile({ id: \"file-1\" });\n const file2 = createMockFile({ id: \"file-2\", name: \"doc.pdf\" });\n\n const presenter = createMockPresenter({\n list: observable({\n rows: [file1, file2],\n sort: null,\n filters: {},\n search: \"\",\n pagination: {\n hasMore: false,\n loading: false,\n loadingMore: false,\n totalCount: 2,\n currentCount: 2\n },\n selection: {\n selectedIds: new Set<string>([\"file-1\"]),\n selectedCount: 1,\n allSelected: false\n },\n empty: false,\n emptyWithFilters: false,\n appliedQuery: null,\n error: null\n })\n });\n\n expect(presenter.vm.list.selection.selectedIds.has(\"file-1\")).toBe(true);\n expect(presenter.vm.list.selection.selectedIds.has(\"file-2\")).toBe(false);\n });\n});\n\ndescribe(\"FileGrid — folder navigation wiring\", () => {\n it(\"should call actions.filter.set with folderId on folder card click\", () => {\n const presenter = createMockPresenter();\n\n // Simulate what the component does when a folder card is clicked.\n const folderId = \"folder-1\";\n presenter.actions.filter.set(\"folderId\", folderId);\n\n expect(presenter.actions.filter.set).toHaveBeenCalledWith(\"folderId\", \"folder-1\");\n });\n});\n\ndescribe(\"FileGrid — loading state\", () => {\n it(\"should show loading state when loading with no rows\", () => {\n const presenter = createMockPresenter({\n list: observable({\n rows: [],\n sort: null,\n filters: {},\n search: \"\",\n pagination: {\n hasMore: false,\n loading: true,\n loadingMore: false,\n totalCount: 0,\n currentCount: 0\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false\n },\n empty: true,\n emptyWithFilters: false,\n appliedQuery: null,\n error: null\n })\n });\n\n // Replicate the component's loading check.\n const showLoader =\n presenter.vm.list.pagination.loading && presenter.vm.list.rows.length === 0;\n\n expect(showLoader).toBe(true);\n });\n\n it(\"should not show loading state when loading with existing rows\", () => {\n const presenter = createMockPresenter({\n list: observable({\n rows: [createMockFile()],\n sort: null,\n filters: {},\n search: \"\",\n pagination: {\n hasMore: false,\n loading: true,\n loadingMore: false,\n totalCount: 1,\n currentCount: 1\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false\n },\n empty: false,\n emptyWithFilters: false,\n appliedQuery: null,\n error: null\n })\n });\n\n const showLoader =\n presenter.vm.list.pagination.loading && presenter.vm.list.rows.length === 0;\n\n expect(showLoader).toBe(false);\n });\n});\n"],"names":["createMockFile","overrides","emptyIdentity","createMockFolderDto","createMockPresenter","vmOverrides","defaultVm","observable","Set","undefined","vi","describe","it","childFolders","presenter","expect","childA","childB","fileId","file1","file2","folderId","showLoader"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"presentation/FileList/components/Grid/FileGrid.test.js","sources":["../../../../../src/presentation/FileList/components/Grid/FileGrid.test.ts"],"sourcesContent":["// @vitest-environment jsdom\nimport { describe, it, expect, vi } from \"vitest\";\nimport { observable } from \"mobx\";\nimport type { IFileManagerPresenter, IFileManagerViewModel } from \"../../abstractions.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\nimport type { FmFile } from \"~/features/shared/types.js\";\n\n// ---------------------------------------------------------------------------\n// Mock factories.\n// ---------------------------------------------------------------------------\n\nfunction createMockFile(overrides: Partial<FmFile> = {}): FmFile {\n return {\n id: \"file-1\",\n name: \"photo.jpg\",\n key: \"files/photo.jpg\",\n src: \"https://cdn.example.com/files/photo.jpg\",\n type: \"image/jpeg\",\n size: 1024,\n metadata: {},\n tags: [],\n createdOn: \"2025-01-01T00:00:00Z\",\n savedOn: \"2025-01-02T00:00:00Z\",\n createdBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n savedBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n location: { folderId: \"root\" },\n ...overrides\n };\n}\n\nconst emptyIdentity = { id: \"\", displayName: \"\", type: \"\" };\n\nfunction createMockFolderDto(overrides: Partial<FolderDto> = {}): FolderDto {\n return {\n id: \"folder-1\",\n title: \"Documents\",\n slug: \"documents\",\n type: \"\",\n parentId: null,\n path: \"\",\n permissions: [],\n hasNonInheritedPermissions: false,\n canManagePermissions: false,\n canManageStructure: true,\n canManageContent: false,\n createdBy: emptyIdentity,\n createdOn: \"\",\n savedBy: emptyIdentity,\n savedOn: \"\",\n modifiedBy: null,\n modifiedOn: null,\n extensions: {},\n ...overrides\n };\n}\n\nfunction createMockPresenter(\n vmOverrides: Partial<IFileManagerViewModel> = {}\n): IFileManagerPresenter {\n const defaultVm: IFileManagerViewModel = observable({\n fileModel: null,\n loading: false,\n empty: true,\n list: {\n rows: [],\n sort: null,\n filters: {},\n search: \"\",\n appliedQuery: null,\n pagination: {\n hasMore: false,\n loading: false,\n loadingMore: false,\n totalCount: 0,\n currentCount: 0\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false,\n label: \"\"\n },\n showingFilters: false,\n empty: true,\n emptyWithFilters: false,\n error: null\n },\n folders: {\n folders: [],\n tree: [],\n currentFolderId: null,\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: true,\n currentFolderTitle: \"All Files\",\n childFolders: [],\n loadingNodeIds: []\n },\n permissions: {\n canRead: true,\n canCreate: true,\n canEdit: true,\n canDelete: true,\n canEditFile: () => true,\n canDeleteFile: () => true\n },\n upload: {\n jobs: [],\n overallProgress: { percentage: 0, bytesSent: 0, totalBytes: 0 },\n isUploading: false\n },\n tags: [],\n showFolders: true,\n childFolders: [],\n viewMode: \"grid\" as const,\n dragging: false,\n showingFilters: false,\n isOverlay: false,\n accept: [],\n multiple: false,\n scope: undefined,\n fileDetails: null,\n ...vmOverrides\n });\n\n return {\n vm: defaultVm,\n actions: {\n search: { set: vi.fn(), clear: vi.fn() },\n sort: { set: vi.fn(), toggle: vi.fn() },\n filter: {\n set: vi.fn(),\n clear: vi.fn(),\n clearAll: vi.fn(),\n show: vi.fn(),\n hide: vi.fn()\n },\n selection: {\n toggle: vi.fn(),\n selectRangeTo: vi.fn(),\n selectAll: vi.fn(),\n deselectAll: vi.fn(),\n selectRows: vi.fn(),\n isSelected: vi.fn().mockReturnValue(false)\n },\n loadMore: vi.fn().mockResolvedValue(undefined),\n refresh: vi.fn().mockResolvedValue(undefined),\n upload: vi.fn().mockResolvedValue(undefined),\n setViewMode: vi.fn(),\n showFileDetails: vi.fn(),\n hideFileDetails: vi.fn(),\n setDragging: vi.fn(),\n showFilters: vi.fn(),\n hideFilters: vi.fn(),\n folders: {\n selectFolder: vi.fn(),\n createFolder: vi.fn(),\n editFolder: vi.fn(),\n deleteFolder: vi.fn().mockResolvedValue(undefined),\n moveFolder: vi.fn().mockResolvedValue(undefined),\n loadChildFolders: vi.fn().mockResolvedValue(undefined),\n canManageStructure: vi.fn().mockReturnValue(true),\n getAncestorIds: vi.fn().mockReturnValue([]),\n submitOperation: vi.fn().mockResolvedValue(true),\n cancelOperation: vi.fn()\n }\n },\n init: vi.fn(),\n dispose: vi.fn()\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tests — Grid data composition logic.\n// ---------------------------------------------------------------------------\n\ndescribe(\"FileGrid — child folder resolution\", () => {\n it(\"should use vm.folders.childFolders when no current folder is selected\", () => {\n const childFolders = [\n createMockFolderDto({ id: \"f1\", title: \"Docs\" }),\n createMockFolderDto({ id: \"f2\", title: \"Photos\" })\n ];\n const presenter = createMockPresenter({\n folders: observable({\n folders: childFolders,\n tree: [],\n currentFolderId: null,\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: true,\n currentFolderTitle: \"All Files\",\n childFolders,\n loadingNodeIds: []\n })\n });\n\n expect(presenter.vm.folders.childFolders).toHaveLength(2);\n expect(presenter.vm.folders.childFolders[0].id).toBe(\"f1\");\n expect(presenter.vm.folders.childFolders[1].id).toBe(\"f2\");\n });\n\n it(\"should expose child folders via vm.folders.childFolders when a folder is selected\", () => {\n const childA = createMockFolderDto({ id: \"child-a\", title: \"Sub A\" });\n const childB = createMockFolderDto({ id: \"child-b\", title: \"Sub B\" });\n\n const presenter = createMockPresenter({\n folders: observable({\n folders: [],\n tree: [],\n currentFolderId: \"parent\",\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: false,\n currentFolderTitle: \"Parent\",\n childFolders: [childA, childB],\n loadingNodeIds: []\n })\n });\n\n expect(presenter.vm.folders.childFolders).toHaveLength(2);\n expect(presenter.vm.folders.childFolders[0].id).toBe(\"child-a\");\n expect(presenter.vm.folders.childFolders[1].id).toBe(\"child-b\");\n });\n\n it(\"should return empty childFolders when current folder has no children\", () => {\n const presenter = createMockPresenter({\n folders: observable({\n folders: [],\n tree: [],\n currentFolderId: \"leaf\",\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: false,\n currentFolderTitle: \"Leaf\",\n childFolders: [],\n loadingNodeIds: []\n })\n });\n\n expect(presenter.vm.folders.childFolders).toHaveLength(0);\n });\n});\n\ndescribe(\"FileGrid — selection action wiring\", () => {\n it(\"should call actions.selection.toggle with file id on file click\", () => {\n const presenter = createMockPresenter();\n\n // Simulate what the component does when a file card is clicked.\n const fileId = \"file-1\";\n presenter.actions.selection.toggle(fileId);\n\n expect(presenter.actions.selection.toggle).toHaveBeenCalledWith(\"file-1\");\n });\n\n it(\"should call actions.selection.deselectAll on background click\", () => {\n const presenter = createMockPresenter();\n\n // Simulate background click handler.\n presenter.actions.selection.deselectAll();\n\n expect(presenter.actions.selection.deselectAll).toHaveBeenCalled();\n });\n\n it(\"should correctly determine selected state from vm.list.selection.selectedIds\", () => {\n const file1 = createMockFile({ id: \"file-1\" });\n const file2 = createMockFile({ id: \"file-2\", name: \"doc.pdf\" });\n\n const presenter = createMockPresenter({\n list: observable({\n rows: [file1, file2],\n sort: null,\n filters: {},\n search: \"\",\n pagination: {\n hasMore: false,\n loading: false,\n loadingMore: false,\n totalCount: 2,\n currentCount: 2\n },\n selection: {\n selectedIds: new Set<string>([\"file-1\"]),\n selectedCount: 1,\n allSelected: false,\n label: \"1 item\"\n },\n showingFilters: false,\n empty: false,\n emptyWithFilters: false,\n appliedQuery: null,\n error: null\n })\n });\n\n expect(presenter.vm.list.selection.selectedIds.has(\"file-1\")).toBe(true);\n expect(presenter.vm.list.selection.selectedIds.has(\"file-2\")).toBe(false);\n });\n});\n\ndescribe(\"FileGrid — folder navigation wiring\", () => {\n it(\"should call actions.filter.set with folderId on folder card click\", () => {\n const presenter = createMockPresenter();\n\n // Simulate what the component does when a folder card is clicked.\n const folderId = \"folder-1\";\n presenter.actions.filter.set(\"folderId\", folderId);\n\n expect(presenter.actions.filter.set).toHaveBeenCalledWith(\"folderId\", \"folder-1\");\n });\n});\n\ndescribe(\"FileGrid — loading state\", () => {\n it(\"should show loading state when loading with no rows\", () => {\n const presenter = createMockPresenter({\n list: observable({\n rows: [],\n sort: null,\n filters: {},\n search: \"\",\n pagination: {\n hasMore: false,\n loading: true,\n loadingMore: false,\n totalCount: 0,\n currentCount: 0\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false,\n label: \"\"\n },\n showingFilters: false,\n empty: true,\n emptyWithFilters: false,\n appliedQuery: null,\n error: null\n })\n });\n\n // Replicate the component's loading check.\n const showLoader =\n presenter.vm.list.pagination.loading && presenter.vm.list.rows.length === 0;\n\n expect(showLoader).toBe(true);\n });\n\n it(\"should not show loading state when loading with existing rows\", () => {\n const presenter = createMockPresenter({\n list: observable({\n rows: [createMockFile()],\n sort: null,\n filters: {},\n search: \"\",\n pagination: {\n hasMore: false,\n loading: true,\n loadingMore: false,\n totalCount: 1,\n currentCount: 1\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false,\n label: \"\"\n },\n showingFilters: false,\n empty: false,\n emptyWithFilters: false,\n appliedQuery: null,\n error: null\n })\n });\n\n const showLoader =\n presenter.vm.list.pagination.loading && presenter.vm.list.rows.length === 0;\n\n expect(showLoader).toBe(false);\n });\n});\n"],"names":["createMockFile","overrides","emptyIdentity","createMockFolderDto","createMockPresenter","vmOverrides","defaultVm","observable","Set","undefined","vi","describe","it","childFolders","presenter","expect","childA","childB","fileId","file1","file2","folderId","showLoader"],"mappings":"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"}
|
|
@@ -2,6 +2,6 @@ import React from "react";
|
|
|
2
2
|
export interface FileManagerHeaderProps {
|
|
3
3
|
browseFiles?: () => void;
|
|
4
4
|
}
|
|
5
|
-
export declare const FileManagerHeader: (({ browseFiles }: FileManagerHeaderProps) => React.JSX.Element) & {
|
|
6
|
-
|
|
5
|
+
export declare const FileManagerHeader: (({ browseFiles }: FileManagerHeaderProps) => React.JSX.Element) & React.NamedExoticComponent<FileManagerHeaderProps> & {
|
|
6
|
+
readonly type: ({ browseFiles }: FileManagerHeaderProps) => React.JSX.Element;
|
|
7
7
|
};
|
|
@@ -4,6 +4,6 @@ import React from "react";
|
|
|
4
4
|
* Uses DelayedOnChange for debounced input, reads current search from vm.list.search,
|
|
5
5
|
* and dispatches changes via presenter.actions.search.set().
|
|
6
6
|
*/
|
|
7
|
-
export declare const SearchBar: (() => React.JSX.Element) & {
|
|
8
|
-
|
|
7
|
+
export declare const SearchBar: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
8
|
+
readonly type: () => React.JSX.Element;
|
|
9
9
|
};
|
|
@@ -7,6 +7,6 @@ export type FileTableItem = FolderTableRow | RecordTableRow<FmFile>;
|
|
|
7
7
|
* Bridges the presenter's state to the ACO Table component,
|
|
8
8
|
* wiring sort and selection actions back to the presenter.
|
|
9
9
|
*/
|
|
10
|
-
export declare const FileTable: (() => React.JSX.Element) & {
|
|
11
|
-
|
|
10
|
+
export declare const FileTable: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
11
|
+
readonly type: () => React.JSX.Element;
|
|
12
12
|
};
|
|
@@ -28,7 +28,7 @@ const FileTable_FileTable = observer(function() {
|
|
|
28
28
|
const overlay = useOverlay();
|
|
29
29
|
const fileRows = createRecordsData(vm.list.rows);
|
|
30
30
|
const data = vm.showFolders ? [
|
|
31
|
-
...toFolderTableRows(vm.
|
|
31
|
+
...toFolderTableRows(vm.childFolders),
|
|
32
32
|
...fileRows
|
|
33
33
|
] : fileRows;
|
|
34
34
|
const selected = createRecordsData(vm.list.rows.filter((file)=>vm.list.selection.selectedIds.has(file.id)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/FileList/components/Table/FileTable.js","sources":["../../../../../src/presentation/FileList/components/Table/FileTable.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport type { DataTableSorting, OnDataTableSortingChange } from \"@webiny/admin-ui\";\nimport { useShiftKey } from \"@webiny/app-admin\";\nimport { useOverlay } from \"~/presentation/FileManager/OverlayContext.js\";\nimport { createRecordsData, Table as AcoTable } from \"@webiny/app-aco\";\nimport type { FolderTableRow, RecordTableRow } from \"@webiny/app-aco\";\nimport { useFileManagerPresenter } from \"../../FileManagerPresenterProvider.js\";\nimport { useFileManagerConfig } from \"~/presentation/config/FileManagerViewConfig.js\";\nimport type { FmFile } from \"~/features/shared/types.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\n\nexport type FileTableItem = FolderTableRow | RecordTableRow<FmFile>;\n\nconst toFolderTableRows = (folders: FolderDto[]): FolderTableRow[] => {\n return folders.map(folder => ({\n id: folder.id,\n $type: \"FOLDER\" as const,\n $selectable: false,\n data: folder\n }));\n};\n\n/**\n * Convert presenter sort state to DataTable sorting format.\n */\nconst toDataTableSorting = (\n sort: { field: string; direction: \"ASC\" | \"DESC\" } | null\n): DataTableSorting => {\n if (!sort) {\n return [];\n }\n return [{ id: sort.field, desc: sort.direction === \"DESC\" }];\n};\n\n/**\n * Table View component driven by FileListPresenter vm.\n * Bridges the presenter's state to the ACO Table component,\n * wiring sort and selection actions back to the presenter.\n */\nexport const FileTable = observer(function FileTable() {\n const presenter = useFileManagerPresenter();\n const { browser } = useFileManagerConfig();\n const { vm, actions } = presenter;\n\n const { isPressed: isShiftPressed } = useShiftKey();\n const overlay = useOverlay();\n\n // No useMemo — MobX observer needs to track these observable accesses during render.\n const fileRows = createRecordsData(vm.list.rows);\n const data: FileTableItem[] = vm.showFolders\n ? [...toFolderTableRows(vm.
|
|
1
|
+
{"version":3,"file":"presentation/FileList/components/Table/FileTable.js","sources":["../../../../../src/presentation/FileList/components/Table/FileTable.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport type { DataTableSorting, OnDataTableSortingChange } from \"@webiny/admin-ui\";\nimport { useShiftKey } from \"@webiny/app-admin\";\nimport { useOverlay } from \"~/presentation/FileManager/OverlayContext.js\";\nimport { createRecordsData, Table as AcoTable } from \"@webiny/app-aco\";\nimport type { FolderTableRow, RecordTableRow } from \"@webiny/app-aco\";\nimport { useFileManagerPresenter } from \"../../FileManagerPresenterProvider.js\";\nimport { useFileManagerConfig } from \"~/presentation/config/FileManagerViewConfig.js\";\nimport type { FmFile } from \"~/features/shared/types.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\n\nexport type FileTableItem = FolderTableRow | RecordTableRow<FmFile>;\n\nconst toFolderTableRows = (folders: FolderDto[]): FolderTableRow[] => {\n return folders.map(folder => ({\n id: folder.id,\n $type: \"FOLDER\" as const,\n $selectable: false,\n data: folder\n }));\n};\n\n/**\n * Convert presenter sort state to DataTable sorting format.\n */\nconst toDataTableSorting = (\n sort: { field: string; direction: \"ASC\" | \"DESC\" } | null\n): DataTableSorting => {\n if (!sort) {\n return [];\n }\n return [{ id: sort.field, desc: sort.direction === \"DESC\" }];\n};\n\n/**\n * Table View component driven by FileListPresenter vm.\n * Bridges the presenter's state to the ACO Table component,\n * wiring sort and selection actions back to the presenter.\n */\nexport const FileTable = observer(function FileTable() {\n const presenter = useFileManagerPresenter();\n const { browser } = useFileManagerConfig();\n const { vm, actions } = presenter;\n\n const { isPressed: isShiftPressed } = useShiftKey();\n const overlay = useOverlay();\n\n // No useMemo — MobX observer needs to track these observable accesses during render.\n const fileRows = createRecordsData(vm.list.rows);\n const data: FileTableItem[] = vm.showFolders\n ? [...toFolderTableRows(vm.childFolders), ...fileRows]\n : fileRows;\n\n const selected: FileTableItem[] = createRecordsData(\n vm.list.rows.filter(file => vm.list.selection.selectedIds.has(file.id))\n );\n\n // Convert presenter sort state to DataTable format.\n const sorting = useMemo(() => toDataTableSorting(vm.list.sort), [vm.list.sort]);\n\n // Handle sorting changes from the DataTable.\n const onSortingChange: OnDataTableSortingChange = useCallback(\n updater => {\n const newSorting = typeof updater === \"function\" ? updater(sorting) : updater;\n if (newSorting.length > 0) {\n const { id, desc } = newSorting[0];\n actions.sort.set(id, desc ? \"DESC\" : \"ASC\");\n }\n },\n [sorting, actions.sort]\n );\n\n const onToggleRow = (row: FileTableItem) => {\n if (row.$type !== \"RECORD\") {\n return;\n }\n\n if (isShiftPressed()) {\n actions.selection.selectRangeTo(row.id);\n return;\n }\n\n if (overlay) {\n const file = vm.list.rows.find(f => f.id === row.id);\n if (file) {\n overlay.onFileClick(file);\n }\n return;\n }\n\n actions.selection.toggle(row.id);\n };\n\n // Handle select all / bulk selection.\n const onSelectRow = useCallback(\n (rows: FileTableItem[] | []) => {\n if (rows.length === 0) {\n actions.selection.deselectAll();\n return;\n }\n const ids = rows\n .filter((row): row is RecordTableRow<FmFile> => row.$type === \"RECORD\")\n .map(row => row.id);\n actions.selection.selectRows(ids);\n },\n [actions.selection]\n );\n\n return (\n <AcoTable<FileTableItem>\n columns={browser.table.columns}\n data={data}\n loading={vm.list.pagination.loading}\n onSelectRow={onSelectRow}\n onToggleRow={onToggleRow}\n sorting={sorting}\n onSortingChange={onSortingChange}\n selected={selected}\n namespace={\"fm/file/list\"}\n />\n );\n});\n"],"names":["toFolderTableRows","folders","folder","toDataTableSorting","sort","FileTable","observer","presenter","useFileManagerPresenter","browser","useFileManagerConfig","vm","actions","isShiftPressed","useShiftKey","overlay","useOverlay","fileRows","createRecordsData","data","selected","file","sorting","useMemo","onSortingChange","useCallback","updater","newSorting","id","desc","onToggleRow","row","f","onSelectRow","rows","ids","AcoTable"],"mappings":";;;;;;;AAcA,MAAMA,oBAAoB,CAACC,UAChBA,QAAQ,GAAG,CAACC,CAAAA,SAAW;YAC1B,IAAIA,OAAO,EAAE;YACb,OAAO;YACP,aAAa;YACb,MAAMA;QACV;AAMJ,MAAMC,qBAAqB,CACvBC;IAEA,IAAI,CAACA,MACD,OAAO,EAAE;IAEb,OAAO;QAAC;YAAE,IAAIA,KAAK,KAAK;YAAE,MAAMA,AAAmB,WAAnBA,KAAK,SAAS;QAAY;KAAE;AAChE;AAOO,MAAMC,sBAAYC,SAAS;IAC9B,MAAMC,YAAYC;IAClB,MAAM,EAAEC,OAAO,EAAE,GAAGC;IACpB,MAAM,EAAEC,EAAE,EAAEC,OAAO,EAAE,GAAGL;IAExB,MAAM,EAAE,WAAWM,cAAc,EAAE,GAAGC;IACtC,MAAMC,UAAUC;IAGhB,MAAMC,WAAWC,kBAAkBP,GAAG,IAAI,CAAC,IAAI;IAC/C,MAAMQ,OAAwBR,GAAG,WAAW,GACtC;WAAIX,kBAAkBW,GAAG,YAAY;WAAMM;KAAS,GACpDA;IAEN,MAAMG,WAA4BF,kBAC9BP,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAACU,CAAAA,OAAQV,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAACU,KAAK,EAAE;IAIzE,MAAMC,UAAUC,QAAQ,IAAMpB,mBAAmBQ,GAAG,IAAI,CAAC,IAAI,GAAG;QAACA,GAAG,IAAI,CAAC,IAAI;KAAC;IAG9E,MAAMa,kBAA4CC,YAC9CC,CAAAA;QACI,MAAMC,aAAa,AAAmB,cAAnB,OAAOD,UAAyBA,QAAQJ,WAAWI;QACtE,IAAIC,WAAW,MAAM,GAAG,GAAG;YACvB,MAAM,EAAEC,EAAE,EAAEC,IAAI,EAAE,GAAGF,UAAU,CAAC,EAAE;YAClCf,QAAQ,IAAI,CAAC,GAAG,CAACgB,IAAIC,OAAO,SAAS;QACzC;IACJ,GACA;QAACP;QAASV,QAAQ,IAAI;KAAC;IAG3B,MAAMkB,cAAc,CAACC;QACjB,IAAIA,AAAc,aAAdA,IAAI,KAAK,EACT;QAGJ,IAAIlB,kBAAkB,YAClBD,QAAQ,SAAS,CAAC,aAAa,CAACmB,IAAI,EAAE;QAI1C,IAAIhB,SAAS;YACT,MAAMM,OAAOV,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAACqB,CAAAA,IAAKA,EAAE,EAAE,KAAKD,IAAI,EAAE;YACnD,IAAIV,MACAN,QAAQ,WAAW,CAACM;YAExB;QACJ;QAEAT,QAAQ,SAAS,CAAC,MAAM,CAACmB,IAAI,EAAE;IACnC;IAGA,MAAME,cAAcR,YAChB,CAACS;QACG,IAAIA,AAAgB,MAAhBA,KAAK,MAAM,EAAQ,YACnBtB,QAAQ,SAAS,CAAC,WAAW;QAGjC,MAAMuB,MAAMD,KACP,MAAM,CAAC,CAACH,MAAuCA,AAAc,aAAdA,IAAI,KAAK,EACxD,GAAG,CAACA,CAAAA,MAAOA,IAAI,EAAE;QACtBnB,QAAQ,SAAS,CAAC,UAAU,CAACuB;IACjC,GACA;QAACvB,QAAQ,SAAS;KAAC;IAGvB,OAAO,WAAP,GACI,oBAACwB,OAAQA;QACL,SAAS3B,QAAQ,KAAK,CAAC,OAAO;QAC9B,MAAMU;QACN,SAASR,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO;QACnC,aAAasB;QACb,aAAaH;QACb,SAASR;QACT,iBAAiBE;QACjB,UAAUJ;QACV,WAAW;;AAGvB"}
|
|
@@ -86,6 +86,8 @@ function createMockFolderNode(overrides = {}) {
|
|
|
86
86
|
function createMockPresenter(vmOverrides = {}) {
|
|
87
87
|
const defaultVm = observable({
|
|
88
88
|
fileModel: null,
|
|
89
|
+
loading: false,
|
|
90
|
+
empty: true,
|
|
89
91
|
list: {
|
|
90
92
|
rows: [],
|
|
91
93
|
sort: null,
|
|
@@ -102,8 +104,10 @@ function createMockPresenter(vmOverrides = {}) {
|
|
|
102
104
|
selection: {
|
|
103
105
|
selectedIds: new Set(),
|
|
104
106
|
selectedCount: 0,
|
|
105
|
-
allSelected: false
|
|
107
|
+
allSelected: false,
|
|
108
|
+
label: ""
|
|
106
109
|
},
|
|
110
|
+
showingFilters: false,
|
|
107
111
|
empty: true,
|
|
108
112
|
emptyWithFilters: false,
|
|
109
113
|
error: null
|
|
@@ -141,9 +145,8 @@ function createMockPresenter(vmOverrides = {}) {
|
|
|
141
145
|
isUploading: false
|
|
142
146
|
},
|
|
143
147
|
tags: [],
|
|
144
|
-
loading: false,
|
|
145
|
-
empty: false,
|
|
146
148
|
showFolders: true,
|
|
149
|
+
childFolders: [],
|
|
147
150
|
viewMode: "table",
|
|
148
151
|
dragging: false,
|
|
149
152
|
showingFilters: false,
|
|
@@ -168,7 +171,9 @@ function createMockPresenter(vmOverrides = {}) {
|
|
|
168
171
|
filter: {
|
|
169
172
|
set: vi.fn(),
|
|
170
173
|
clear: vi.fn(),
|
|
171
|
-
clearAll: vi.fn()
|
|
174
|
+
clearAll: vi.fn(),
|
|
175
|
+
show: vi.fn(),
|
|
176
|
+
hide: vi.fn()
|
|
172
177
|
},
|
|
173
178
|
selection: {
|
|
174
179
|
toggle: vi.fn(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/FileList/components/Table/FileTable.test.js","sources":["../../../../../src/presentation/FileList/components/Table/FileTable.test.ts"],"sourcesContent":["// @vitest-environment jsdom\nimport { describe, it, expect, vi } from \"vitest\";\nimport { observable } from \"mobx\";\nimport type { IFileManagerPresenter, IFileManagerViewModel } from \"../../abstractions.js\";\nimport type { IFolderTreeNode } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport type { FmFile } from \"~/features/shared/types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers — extracted from FileTable.tsx for unit testing.\n// ---------------------------------------------------------------------------\n\n/**\n * Convert presenter sort state to DataTable sorting format.\n */\nfunction toDataTableSorting(\n sort: { field: string; direction: \"ASC\" | \"DESC\" } | null\n): Array<{ id: string; desc: boolean }> {\n if (!sort) {\n return [];\n }\n return [{ id: sort.field, desc: sort.direction === \"DESC\" }];\n}\n\n/**\n * Map IFolderTreeNode to FolderTableRow-compatible shape.\n */\nfunction toFolderTableRows(nodes: IFolderTreeNode[]) {\n return nodes.map(node => ({\n id: node.id,\n $type: \"FOLDER\" as const,\n $selectable: false,\n data: {\n id: node.id,\n title: node.name,\n slug: node.slug,\n type: \"\",\n parentId: node.parentId,\n path: \"\",\n permissions: [],\n hasNonInheritedPermissions: false,\n canManagePermissions: false,\n canManageStructure: false,\n canManageContent: false,\n createdBy: { id: \"\", displayName: \"\" },\n createdOn: \"\",\n savedBy: { id: \"\", displayName: \"\" },\n savedOn: \"\",\n modifiedBy: null,\n modifiedOn: null,\n extensions: {}\n }\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Mock file factory.\n// ---------------------------------------------------------------------------\n\nfunction createMockFile(overrides: Partial<FmFile> = {}): FmFile {\n return {\n id: \"file-1\",\n name: \"photo.jpg\",\n key: \"files/photo.jpg\",\n src: \"https://cdn.example.com/files/photo.jpg\",\n type: \"image/jpeg\",\n size: 1024,\n metadata: {},\n tags: [],\n createdOn: \"2025-01-01T00:00:00Z\",\n savedOn: \"2025-01-02T00:00:00Z\",\n createdBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n savedBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n location: { folderId: \"root\" },\n ...overrides\n };\n}\n\nfunction createMockFolderNode(overrides: Partial<IFolderTreeNode> = {}): IFolderTreeNode {\n return {\n id: \"folder-1\",\n name: \"Documents\",\n slug: \"documents\",\n parentId: null,\n children: [],\n hasNonInheritedPermissions: false,\n canManagePermissions: false,\n canManageStructure: true,\n ...overrides\n };\n}\n\nfunction createMockPresenter(\n vmOverrides: Partial<IFileManagerViewModel> = {}\n): IFileManagerPresenter {\n const defaultVm: IFileManagerViewModel = observable({\n fileModel: null,\n list: {\n rows: [],\n sort: null,\n filters: {},\n search: \"\",\n appliedQuery: null,\n pagination: {\n hasMore: false,\n loading: false,\n loadingMore: false,\n totalCount: 0,\n currentCount: 0\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false\n },\n empty: true,\n emptyWithFilters: false,\n error: null\n },\n folders: {\n folders: [],\n tree: [],\n currentFolderId: null,\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: true,\n currentFolderTitle: \"All Files\",\n childFolders: [],\n loadingNodeIds: []\n },\n permissions: {\n canRead: true,\n canCreate: true,\n canEdit: true,\n canDelete: true,\n canEditFile: () => true,\n canDeleteFile: () => true\n },\n upload: {\n jobs: [],\n overallProgress: { percentage: 0, bytesSent: 0, totalBytes: 0 },\n isUploading: false\n },\n tags: [],\n loading: false,\n empty: false,\n showFolders: true,\n viewMode: \"table\" as const,\n dragging: false,\n showingFilters: false,\n isOverlay: false,\n accept: [],\n multiple: false,\n scope: undefined,\n fileDetails: null,\n ...vmOverrides\n });\n\n return {\n vm: defaultVm,\n actions: {\n search: { set: vi.fn(), clear: vi.fn() },\n sort: { set: vi.fn(), toggle: vi.fn() },\n filter: { set: vi.fn(), clear: vi.fn(), clearAll: vi.fn() },\n selection: {\n toggle: vi.fn(),\n selectRangeTo: vi.fn(),\n selectAll: vi.fn(),\n deselectAll: vi.fn(),\n selectRows: vi.fn(),\n isSelected: vi.fn().mockReturnValue(false)\n },\n loadMore: vi.fn().mockResolvedValue(undefined),\n refresh: vi.fn().mockResolvedValue(undefined),\n upload: vi.fn().mockResolvedValue(undefined),\n setViewMode: vi.fn(),\n showFileDetails: vi.fn(),\n hideFileDetails: vi.fn(),\n setDragging: vi.fn(),\n showFilters: vi.fn(),\n hideFilters: vi.fn(),\n folders: {\n selectFolder: vi.fn(),\n createFolder: vi.fn(),\n editFolder: vi.fn(),\n deleteFolder: vi.fn().mockResolvedValue(undefined),\n moveFolder: vi.fn().mockResolvedValue(undefined),\n loadChildFolders: vi.fn().mockResolvedValue(undefined),\n canManageStructure: vi.fn().mockReturnValue(true),\n getAncestorIds: vi.fn().mockReturnValue([]),\n submitOperation: vi.fn().mockResolvedValue(true),\n cancelOperation: vi.fn()\n }\n },\n init: vi.fn(),\n dispose: vi.fn()\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\ndescribe(\"FileTable — sorting conversion\", () => {\n it(\"should convert null sort to empty DataTable sorting\", () => {\n expect(toDataTableSorting(null)).toEqual([]);\n });\n\n it(\"should convert ASC sort to DataTable format\", () => {\n const result = toDataTableSorting({ field: \"name\", direction: \"ASC\" });\n expect(result).toEqual([{ id: \"name\", desc: false }]);\n });\n\n it(\"should convert DESC sort to DataTable format\", () => {\n const result = toDataTableSorting({ field: \"createdOn\", direction: \"DESC\" });\n expect(result).toEqual([{ id: \"createdOn\", desc: true }]);\n });\n});\n\ndescribe(\"FileTable — folder data mapping\", () => {\n it(\"should map IFolderTreeNode to FolderTableRow with $type FOLDER\", () => {\n const node = createMockFolderNode({ id: \"f1\", name: \"Images\", slug: \"images\" });\n const rows = toFolderTableRows([node]);\n\n expect(rows).toHaveLength(1);\n expect(rows[0].id).toBe(\"f1\");\n expect(rows[0].$type).toBe(\"FOLDER\");\n expect(rows[0].$selectable).toBe(false);\n expect(rows[0].data.title).toBe(\"Images\");\n expect(rows[0].data.slug).toBe(\"images\");\n });\n\n it(\"should map multiple folder nodes\", () => {\n const nodes = [\n createMockFolderNode({ id: \"f1\", name: \"Docs\" }),\n createMockFolderNode({ id: \"f2\", name: \"Photos\" })\n ];\n const rows = toFolderTableRows(nodes);\n\n expect(rows).toHaveLength(2);\n expect(rows[0].id).toBe(\"f1\");\n expect(rows[1].id).toBe(\"f2\");\n });\n\n it(\"should return empty array for empty folder list\", () => {\n expect(toFolderTableRows([])).toEqual([]);\n });\n});\n\ndescribe(\"FileTable — sort action wiring\", () => {\n it(\"should call actions.sort.set when sorting changes to DESC\", () => {\n const presenter = createMockPresenter();\n\n // Simulate what the component does when onSortingChange fires.\n const newSorting = [{ id: \"size\", desc: true }];\n if (newSorting.length > 0) {\n const { id, desc } = newSorting[0];\n presenter.actions.sort.set(id, desc ? \"DESC\" : \"ASC\");\n }\n\n expect(presenter.actions.sort.set).toHaveBeenCalledWith(\"size\", \"DESC\");\n });\n\n it(\"should call actions.sort.set when sorting changes to ASC\", () => {\n const presenter = createMockPresenter();\n\n const newSorting = [{ id: \"name\", desc: false }];\n if (newSorting.length > 0) {\n const { id, desc } = newSorting[0];\n presenter.actions.sort.set(id, desc ? \"DESC\" : \"ASC\");\n }\n\n expect(presenter.actions.sort.set).toHaveBeenCalledWith(\"name\", \"ASC\");\n });\n});\n\ndescribe(\"FileTable — selection action wiring\", () => {\n it(\"should call actions.selection.toggle for RECORD row toggle\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onToggleRow for a file row.\n const row = {\n id: \"file-1\",\n $type: \"RECORD\" as const,\n $selectable: true,\n data: createMockFile()\n };\n if (row.$type === \"RECORD\") {\n presenter.actions.selection.toggle(row.id);\n }\n\n expect(presenter.actions.selection.toggle).toHaveBeenCalledWith(\"file-1\");\n });\n\n it(\"should not call actions.selection.toggle for FOLDER row toggle\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onToggleRow for a folder row — folders are not selectable.\n const row = { id: \"folder-1\", $type: \"FOLDER\" as const, $selectable: false, data: {} };\n if ((row.$type as string) === \"RECORD\") {\n presenter.actions.selection.toggle(row.id);\n }\n\n expect(presenter.actions.selection.toggle).not.toHaveBeenCalled();\n });\n\n it(\"should call actions.selection.deselectAll when empty selection\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onSelectRow with empty array.\n const rows: Array<{ id: string; $type: string }> = [];\n if (rows.length === 0) {\n presenter.actions.selection.deselectAll();\n }\n\n expect(presenter.actions.selection.deselectAll).toHaveBeenCalled();\n });\n\n it(\"should call actions.selection.selectRows with file IDs only\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onSelectRow with mixed rows.\n const rows = [\n {\n id: \"file-1\",\n $type: \"RECORD\" as const,\n $selectable: true,\n data: createMockFile({ id: \"file-1\" })\n },\n { id: \"folder-1\", $type: \"FOLDER\" as const, $selectable: false, data: {} },\n {\n id: \"file-2\",\n $type: \"RECORD\" as const,\n $selectable: true,\n data: createMockFile({ id: \"file-2\" })\n }\n ];\n\n const ids = rows.filter(row => row.$type === \"RECORD\").map(row => row.id);\n presenter.actions.selection.selectRows(ids);\n\n expect(presenter.actions.selection.selectRows).toHaveBeenCalledWith([\"file-1\", \"file-2\"]);\n });\n});\n"],"names":["toDataTableSorting","sort","toFolderTableRows","nodes","node","createMockFile","overrides","createMockFolderNode","createMockPresenter","vmOverrides","defaultVm","observable","Set","undefined","vi","describe","it","expect","result","rows","presenter","newSorting","id","desc","row","ids"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"presentation/FileList/components/Table/FileTable.test.js","sources":["../../../../../src/presentation/FileList/components/Table/FileTable.test.ts"],"sourcesContent":["// @vitest-environment jsdom\nimport { describe, it, expect, vi } from \"vitest\";\nimport { observable } from \"mobx\";\nimport type { IFileManagerPresenter, IFileManagerViewModel } from \"../../abstractions.js\";\nimport type { IFolderTreeNode } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport type { FmFile } from \"~/features/shared/types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers — extracted from FileTable.tsx for unit testing.\n// ---------------------------------------------------------------------------\n\n/**\n * Convert presenter sort state to DataTable sorting format.\n */\nfunction toDataTableSorting(\n sort: { field: string; direction: \"ASC\" | \"DESC\" } | null\n): Array<{ id: string; desc: boolean }> {\n if (!sort) {\n return [];\n }\n return [{ id: sort.field, desc: sort.direction === \"DESC\" }];\n}\n\n/**\n * Map IFolderTreeNode to FolderTableRow-compatible shape.\n */\nfunction toFolderTableRows(nodes: IFolderTreeNode[]) {\n return nodes.map(node => ({\n id: node.id,\n $type: \"FOLDER\" as const,\n $selectable: false,\n data: {\n id: node.id,\n title: node.name,\n slug: node.slug,\n type: \"\",\n parentId: node.parentId,\n path: \"\",\n permissions: [],\n hasNonInheritedPermissions: false,\n canManagePermissions: false,\n canManageStructure: false,\n canManageContent: false,\n createdBy: { id: \"\", displayName: \"\" },\n createdOn: \"\",\n savedBy: { id: \"\", displayName: \"\" },\n savedOn: \"\",\n modifiedBy: null,\n modifiedOn: null,\n extensions: {}\n }\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Mock file factory.\n// ---------------------------------------------------------------------------\n\nfunction createMockFile(overrides: Partial<FmFile> = {}): FmFile {\n return {\n id: \"file-1\",\n name: \"photo.jpg\",\n key: \"files/photo.jpg\",\n src: \"https://cdn.example.com/files/photo.jpg\",\n type: \"image/jpeg\",\n size: 1024,\n metadata: {},\n tags: [],\n createdOn: \"2025-01-01T00:00:00Z\",\n savedOn: \"2025-01-02T00:00:00Z\",\n createdBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n savedBy: { id: \"user-1\", displayName: \"Alice\", type: \"admin\" },\n location: { folderId: \"root\" },\n ...overrides\n };\n}\n\nfunction createMockFolderNode(overrides: Partial<IFolderTreeNode> = {}): IFolderTreeNode {\n return {\n id: \"folder-1\",\n name: \"Documents\",\n slug: \"documents\",\n parentId: null,\n children: [],\n hasNonInheritedPermissions: false,\n canManagePermissions: false,\n canManageStructure: true,\n ...overrides\n };\n}\n\nfunction createMockPresenter(\n vmOverrides: Partial<IFileManagerViewModel> = {}\n): IFileManagerPresenter {\n const defaultVm: IFileManagerViewModel = observable({\n fileModel: null,\n loading: false,\n empty: true,\n list: {\n rows: [],\n sort: null,\n filters: {},\n search: \"\",\n appliedQuery: null,\n pagination: {\n hasMore: false,\n loading: false,\n loadingMore: false,\n totalCount: 0,\n currentCount: 0\n },\n selection: {\n selectedIds: new Set<string>(),\n selectedCount: 0,\n allSelected: false,\n label: \"\"\n },\n showingFilters: false,\n empty: true,\n emptyWithFilters: false,\n error: null\n },\n folders: {\n folders: [],\n tree: [],\n currentFolderId: null,\n currentFolder: null,\n loading: false,\n operation: { active: false, mode: null },\n isRootFolder: true,\n currentFolderTitle: \"All Files\",\n childFolders: [],\n loadingNodeIds: []\n },\n permissions: {\n canRead: true,\n canCreate: true,\n canEdit: true,\n canDelete: true,\n canEditFile: () => true,\n canDeleteFile: () => true\n },\n upload: {\n jobs: [],\n overallProgress: { percentage: 0, bytesSent: 0, totalBytes: 0 },\n isUploading: false\n },\n tags: [],\n showFolders: true,\n childFolders: [],\n viewMode: \"table\" as const,\n dragging: false,\n showingFilters: false,\n isOverlay: false,\n accept: [],\n multiple: false,\n scope: undefined,\n fileDetails: null,\n ...vmOverrides\n });\n\n return {\n vm: defaultVm,\n actions: {\n search: { set: vi.fn(), clear: vi.fn() },\n sort: { set: vi.fn(), toggle: vi.fn() },\n filter: {\n set: vi.fn(),\n clear: vi.fn(),\n clearAll: vi.fn(),\n show: vi.fn(),\n hide: vi.fn()\n },\n selection: {\n toggle: vi.fn(),\n selectRangeTo: vi.fn(),\n selectAll: vi.fn(),\n deselectAll: vi.fn(),\n selectRows: vi.fn(),\n isSelected: vi.fn().mockReturnValue(false)\n },\n loadMore: vi.fn().mockResolvedValue(undefined),\n refresh: vi.fn().mockResolvedValue(undefined),\n upload: vi.fn().mockResolvedValue(undefined),\n setViewMode: vi.fn(),\n showFileDetails: vi.fn(),\n hideFileDetails: vi.fn(),\n setDragging: vi.fn(),\n showFilters: vi.fn(),\n hideFilters: vi.fn(),\n folders: {\n selectFolder: vi.fn(),\n createFolder: vi.fn(),\n editFolder: vi.fn(),\n deleteFolder: vi.fn().mockResolvedValue(undefined),\n moveFolder: vi.fn().mockResolvedValue(undefined),\n loadChildFolders: vi.fn().mockResolvedValue(undefined),\n canManageStructure: vi.fn().mockReturnValue(true),\n getAncestorIds: vi.fn().mockReturnValue([]),\n submitOperation: vi.fn().mockResolvedValue(true),\n cancelOperation: vi.fn()\n }\n },\n init: vi.fn(),\n dispose: vi.fn()\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\ndescribe(\"FileTable — sorting conversion\", () => {\n it(\"should convert null sort to empty DataTable sorting\", () => {\n expect(toDataTableSorting(null)).toEqual([]);\n });\n\n it(\"should convert ASC sort to DataTable format\", () => {\n const result = toDataTableSorting({ field: \"name\", direction: \"ASC\" });\n expect(result).toEqual([{ id: \"name\", desc: false }]);\n });\n\n it(\"should convert DESC sort to DataTable format\", () => {\n const result = toDataTableSorting({ field: \"createdOn\", direction: \"DESC\" });\n expect(result).toEqual([{ id: \"createdOn\", desc: true }]);\n });\n});\n\ndescribe(\"FileTable — folder data mapping\", () => {\n it(\"should map IFolderTreeNode to FolderTableRow with $type FOLDER\", () => {\n const node = createMockFolderNode({ id: \"f1\", name: \"Images\", slug: \"images\" });\n const rows = toFolderTableRows([node]);\n\n expect(rows).toHaveLength(1);\n expect(rows[0].id).toBe(\"f1\");\n expect(rows[0].$type).toBe(\"FOLDER\");\n expect(rows[0].$selectable).toBe(false);\n expect(rows[0].data.title).toBe(\"Images\");\n expect(rows[0].data.slug).toBe(\"images\");\n });\n\n it(\"should map multiple folder nodes\", () => {\n const nodes = [\n createMockFolderNode({ id: \"f1\", name: \"Docs\" }),\n createMockFolderNode({ id: \"f2\", name: \"Photos\" })\n ];\n const rows = toFolderTableRows(nodes);\n\n expect(rows).toHaveLength(2);\n expect(rows[0].id).toBe(\"f1\");\n expect(rows[1].id).toBe(\"f2\");\n });\n\n it(\"should return empty array for empty folder list\", () => {\n expect(toFolderTableRows([])).toEqual([]);\n });\n});\n\ndescribe(\"FileTable — sort action wiring\", () => {\n it(\"should call actions.sort.set when sorting changes to DESC\", () => {\n const presenter = createMockPresenter();\n\n // Simulate what the component does when onSortingChange fires.\n const newSorting = [{ id: \"size\", desc: true }];\n if (newSorting.length > 0) {\n const { id, desc } = newSorting[0];\n presenter.actions.sort.set(id, desc ? \"DESC\" : \"ASC\");\n }\n\n expect(presenter.actions.sort.set).toHaveBeenCalledWith(\"size\", \"DESC\");\n });\n\n it(\"should call actions.sort.set when sorting changes to ASC\", () => {\n const presenter = createMockPresenter();\n\n const newSorting = [{ id: \"name\", desc: false }];\n if (newSorting.length > 0) {\n const { id, desc } = newSorting[0];\n presenter.actions.sort.set(id, desc ? \"DESC\" : \"ASC\");\n }\n\n expect(presenter.actions.sort.set).toHaveBeenCalledWith(\"name\", \"ASC\");\n });\n});\n\ndescribe(\"FileTable — selection action wiring\", () => {\n it(\"should call actions.selection.toggle for RECORD row toggle\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onToggleRow for a file row.\n const row = {\n id: \"file-1\",\n $type: \"RECORD\" as const,\n $selectable: true,\n data: createMockFile()\n };\n if (row.$type === \"RECORD\") {\n presenter.actions.selection.toggle(row.id);\n }\n\n expect(presenter.actions.selection.toggle).toHaveBeenCalledWith(\"file-1\");\n });\n\n it(\"should not call actions.selection.toggle for FOLDER row toggle\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onToggleRow for a folder row — folders are not selectable.\n const row = { id: \"folder-1\", $type: \"FOLDER\" as const, $selectable: false, data: {} };\n if ((row.$type as string) === \"RECORD\") {\n presenter.actions.selection.toggle(row.id);\n }\n\n expect(presenter.actions.selection.toggle).not.toHaveBeenCalled();\n });\n\n it(\"should call actions.selection.deselectAll when empty selection\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onSelectRow with empty array.\n const rows: Array<{ id: string; $type: string }> = [];\n if (rows.length === 0) {\n presenter.actions.selection.deselectAll();\n }\n\n expect(presenter.actions.selection.deselectAll).toHaveBeenCalled();\n });\n\n it(\"should call actions.selection.selectRows with file IDs only\", () => {\n const presenter = createMockPresenter();\n\n // Simulate onSelectRow with mixed rows.\n const rows = [\n {\n id: \"file-1\",\n $type: \"RECORD\" as const,\n $selectable: true,\n data: createMockFile({ id: \"file-1\" })\n },\n { id: \"folder-1\", $type: \"FOLDER\" as const, $selectable: false, data: {} },\n {\n id: \"file-2\",\n $type: \"RECORD\" as const,\n $selectable: true,\n data: createMockFile({ id: \"file-2\" })\n }\n ];\n\n const ids = rows.filter(row => row.$type === \"RECORD\").map(row => row.id);\n presenter.actions.selection.selectRows(ids);\n\n expect(presenter.actions.selection.selectRows).toHaveBeenCalledWith([\"file-1\", \"file-2\"]);\n });\n});\n"],"names":["toDataTableSorting","sort","toFolderTableRows","nodes","node","createMockFile","overrides","createMockFolderNode","createMockPresenter","vmOverrides","defaultVm","observable","Set","undefined","vi","describe","it","expect","result","rows","presenter","newSorting","id","desc","row","ids"],"mappings":"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"}
|
|
@@ -4,6 +4,6 @@ import React from "react";
|
|
|
4
4
|
* Reuses the original UploadStatus markup — a bottom-center bar with progress
|
|
5
5
|
* and a close button.
|
|
6
6
|
*/
|
|
7
|
-
export declare const UploadProgress: (() => React.JSX.Element | null) & {
|
|
8
|
-
|
|
7
|
+
export declare const UploadProgress: (() => React.JSX.Element | null) & React.NamedExoticComponent<unknown> & {
|
|
8
|
+
readonly type: () => React.JSX.Element | null;
|
|
9
9
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Emits the current folder path as breadcrumbs (`File Manager › Marketing › Demo`) through the
|
|
4
|
+
* React Config API. Dynamic values (folder titles) come from the scoped folder-tree VM, so
|
|
5
|
+
* this is a plain observer component that renders `<Breadcrumb>` config entries — the header
|
|
6
|
+
* marks the last one as the current location automatically.
|
|
7
|
+
*
|
|
8
|
+
* Rendered in page mode only (not the overlay file picker), where the admin header exists.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FileManagerBreadcrumbs: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
11
|
+
readonly type: () => React.JSX.Element;
|
|
12
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import react from "react";
|
|
2
|
+
import { observer } from "mobx-react-lite";
|
|
3
|
+
import { Breadcrumb } from "@webiny/app-admin";
|
|
4
|
+
import { useFileManagerPresenter } from "../FileList/FileManagerPresenterProvider.js";
|
|
5
|
+
import { Routes } from "../../routes.js";
|
|
6
|
+
const FileManagerBreadcrumbs_FileManagerBreadcrumbs = observer(function() {
|
|
7
|
+
const presenter = useFileManagerPresenter();
|
|
8
|
+
const { folders } = presenter.vm;
|
|
9
|
+
const foldersActions = presenter.actions.folders;
|
|
10
|
+
const ancestorIds = folders.currentFolderId ? [
|
|
11
|
+
...foldersActions.getAncestorIds(folders.currentFolderId)
|
|
12
|
+
].reverse() : [];
|
|
13
|
+
const titleById = new Map(folders.folders.map((folder)=>[
|
|
14
|
+
folder.id,
|
|
15
|
+
folder.title
|
|
16
|
+
]));
|
|
17
|
+
return /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(Breadcrumb, {
|
|
18
|
+
name: "fm-root",
|
|
19
|
+
label: "File Manager",
|
|
20
|
+
to: {
|
|
21
|
+
route: Routes.List
|
|
22
|
+
}
|
|
23
|
+
}), ancestorIds.map((id)=>/*#__PURE__*/ react.createElement(Breadcrumb, {
|
|
24
|
+
key: id,
|
|
25
|
+
name: id,
|
|
26
|
+
label: titleById.get(id) ?? "…",
|
|
27
|
+
to: {
|
|
28
|
+
route: Routes.List,
|
|
29
|
+
params: {
|
|
30
|
+
folderId: id
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
})));
|
|
34
|
+
});
|
|
35
|
+
export { FileManagerBreadcrumbs_FileManagerBreadcrumbs as FileManagerBreadcrumbs };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=FileManagerBreadcrumbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/FileManager/FileManagerBreadcrumbs.js","sources":["../../../src/presentation/FileManager/FileManagerBreadcrumbs.tsx"],"sourcesContent":["import React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { Breadcrumb } from \"@webiny/app-admin\";\nimport { useFileManagerPresenter } from \"~/presentation/FileList/FileManagerPresenterProvider.js\";\nimport { Routes } from \"~/routes.js\";\n\n/**\n * Emits the current folder path as breadcrumbs (`File Manager › Marketing › Demo`) through the\n * React Config API. Dynamic values (folder titles) come from the scoped folder-tree VM, so\n * this is a plain observer component that renders `<Breadcrumb>` config entries — the header\n * marks the last one as the current location automatically.\n *\n * Rendered in page mode only (not the overlay file picker), where the admin header exists.\n */\nexport const FileManagerBreadcrumbs = observer(function FileManagerBreadcrumbs() {\n const presenter = useFileManagerPresenter();\n const { folders } = presenter.vm;\n const foldersActions = presenter.actions.folders;\n\n // `getAncestorIds` walks self → root; reverse it to render root → current.\n const ancestorIds = folders.currentFolderId\n ? [...foldersActions.getAncestorIds(folders.currentFolderId)].reverse()\n : [];\n const titleById = new Map(folders.folders.map(folder => [folder.id, folder.title]));\n\n return (\n <>\n <Breadcrumb name={\"fm-root\"} label={\"File Manager\"} to={{ route: Routes.List }} />\n {ancestorIds.map(id => (\n <Breadcrumb\n key={id}\n name={id}\n label={titleById.get(id) ?? \"…\"}\n to={{ route: Routes.List, params: { folderId: id } }}\n />\n ))}\n </>\n );\n});\n"],"names":["FileManagerBreadcrumbs","observer","presenter","useFileManagerPresenter","folders","foldersActions","ancestorIds","titleById","Map","folder","Breadcrumb","Routes","id"],"mappings":";;;;;AAcO,MAAMA,gDAAyBC,SAAS;IAC3C,MAAMC,YAAYC;IAClB,MAAM,EAAEC,OAAO,EAAE,GAAGF,UAAU,EAAE;IAChC,MAAMG,iBAAiBH,UAAU,OAAO,CAAC,OAAO;IAGhD,MAAMI,cAAcF,QAAQ,eAAe,GACrC;WAAIC,eAAe,cAAc,CAACD,QAAQ,eAAe;KAAE,CAAC,OAAO,KACnE,EAAE;IACR,MAAMG,YAAY,IAAIC,IAAIJ,QAAQ,OAAO,CAAC,GAAG,CAACK,CAAAA,SAAU;YAACA,OAAO,EAAE;YAAEA,OAAO,KAAK;SAAC;IAEjF,OAAO,WAAP,GACI,wDACI,oBAACC,YAAUA;QAAC,MAAM;QAAW,OAAO;QAAgB,IAAI;YAAE,OAAOC,OAAO,IAAI;QAAC;QAC5EL,YAAY,GAAG,CAACM,CAAAA,KAAAA,WAAAA,GACb,oBAACF,YAAUA;YACP,KAAKE;YACL,MAAMA;YACN,OAAOL,UAAU,GAAG,CAACK,OAAO;YAC5B,IAAI;gBAAE,OAAOD,OAAO,IAAI;gBAAE,QAAQ;oBAAE,UAAUC;gBAAG;YAAE;;AAKvE"}
|