@webiny/app-headless-cms 6.5.0-beta.3 → 6.5.0-beta.4
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/ContentEntriesModule.js +9 -2
- package/ContentEntriesModule.js.map +1 -1
- package/admin/components/ContentEntries/Table/Actions/DuplicateEntry.d.ts +2 -0
- package/admin/components/ContentEntries/Table/Actions/DuplicateEntry.js +34 -0
- package/admin/components/ContentEntries/Table/Actions/DuplicateEntry.js.map +1 -0
- package/admin/components/ContentEntries/Table/Actions/index.d.ts +1 -0
- package/admin/components/ContentEntries/Table/Actions/index.js +1 -0
- package/admin/components/Dialogs/DuplicateEntryConfirmDialog.d.ts +2 -0
- package/admin/components/Dialogs/DuplicateEntryConfirmDialog.js +22 -0
- package/admin/components/Dialogs/DuplicateEntryConfirmDialog.js.map +1 -0
- package/features/contentEntry/CmsEntryError.d.ts +10 -0
- package/features/contentEntry/CmsEntryError.js +11 -0
- package/features/contentEntry/CmsEntryError.js.map +1 -0
- package/features/contentEntry/createEntry/CreateEntryGateway.js +2 -1
- package/features/contentEntry/createEntry/CreateEntryGateway.js.map +1 -1
- package/features/contentEntry/createRevisionFrom/CreateRevisionFromGateway.js +2 -1
- package/features/contentEntry/createRevisionFrom/CreateRevisionFromGateway.js.map +1 -1
- package/features/contentEntry/duplicateEntry/DuplicateEntryGateway.d.ts +14 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryGateway.js +43 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryGateway.js.map +1 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryRepository.d.ts +15 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryRepository.js +34 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryRepository.js.map +1 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryUseCase.d.ts +11 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryUseCase.js +18 -0
- package/features/contentEntry/duplicateEntry/DuplicateEntryUseCase.js.map +1 -0
- package/features/contentEntry/duplicateEntry/abstractions.d.ts +26 -0
- package/features/contentEntry/duplicateEntry/abstractions.js +7 -0
- package/features/contentEntry/duplicateEntry/abstractions.js.map +1 -0
- package/features/contentEntry/duplicateEntry/feature.d.ts +3 -0
- package/features/contentEntry/duplicateEntry/feature.js +21 -0
- package/features/contentEntry/duplicateEntry/feature.js.map +1 -0
- package/features/contentEntry/feature.js +2 -0
- package/features/contentEntry/feature.js.map +1 -1
- package/features/contentEntry/singletonEntry/UpdateSingletonEntryGateway.js +2 -1
- package/features/contentEntry/singletonEntry/UpdateSingletonEntryGateway.js.map +1 -1
- package/features/contentEntry/updateEntry/UpdateEntryGateway.js +2 -1
- package/features/contentEntry/updateEntry/UpdateEntryGateway.js.map +1 -1
- package/features/formModel/CmsFormModelBuilder.d.ts +8 -0
- package/features/formModel/CmsFormModelBuilder.js +25 -2
- package/features/formModel/CmsFormModelBuilder.js.map +1 -1
- package/features/formModel/CmsFormModelBuilder.test.d.ts +1 -0
- package/features/formModel/CmsFormModelBuilder.test.js +111 -0
- package/features/formModel/CmsFormModelBuilder.test.js.map +1 -0
- package/package.json +20 -20
- package/presentation/contentEntries/form/ContentEntryFormPresenter.js +3 -1
- package/presentation/contentEntries/form/ContentEntryFormPresenter.js.map +1 -1
- package/presentation/contentEntries/form/toFormErrors.d.ts +7 -0
- package/presentation/contentEntries/form/toFormErrors.js +49 -0
- package/presentation/contentEntries/form/toFormErrors.js.map +1 -0
- package/presentation/contentEntries/form/toFormErrors.test.d.ts +1 -0
- package/presentation/contentEntries/form/toFormErrors.test.js +175 -0
- package/presentation/contentEntries/form/toFormErrors.test.js.map +1 -0
- package/presentation/contentEntries/list/ContentEntriesPresenter.d.ts +6 -2
- package/presentation/contentEntries/list/ContentEntriesPresenter.js +27 -2
- package/presentation/contentEntries/list/ContentEntriesPresenter.js.map +1 -1
- package/presentation/contentEntries/list/ContentEntriesPresenter.test.js +58 -1
- package/presentation/contentEntries/list/ContentEntriesPresenter.test.js.map +1 -1
- package/presentation/contentEntries/list/abstractions.d.ts +12 -0
- package/presentation/contentEntries/list/abstractions.js.map +1 -1
- package/presentation/contentEntries/singleEntry/SingleEntryPresenter.js +3 -1
- package/presentation/contentEntries/singleEntry/SingleEntryPresenter.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/contentEntries/list/ContentEntriesPresenter.test.js","sources":["../../../../src/presentation/contentEntries/list/ContentEntriesPresenter.test.ts"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\nimport { describe, it, expect, vi, beforeEach } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { makeAutoObservable } from \"mobx\";\nimport { ListPresenterFeature } from \"@webiny/app-admin/presentation/listPresenter/index.js\";\nimport { FolderTreePresenter } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport { GetDescendantFoldersUseCase } from \"@webiny/app-aco/features/folders/getDescendantFolders/abstractions.js\";\nimport { Confirmation } from \"@webiny/app-admin/features/confirmation/abstractions.js\";\nimport type { CmsContentEntry, CmsModel } from \"~/types.js\";\nimport { ContentEntriesCacheProvider } from \"~/features/contentEntry/ContentEntriesCacheProvider.js\";\nimport { CmsModelContext } from \"~/features/contentEntry/abstractions.js\";\nimport { CmsModelContext as CmsModelContextImpl } from \"~/features/contentEntry/CmsModelContext.js\";\nimport { ListEntriesFeature } from \"~/features/contentEntry/listEntries/feature.js\";\nimport { DeleteEntryFeature } from \"~/features/contentEntry/deleteEntry/feature.js\";\nimport { PublishEntryFeature } from \"~/features/contentEntry/publishEntry/feature.js\";\nimport { UnpublishEntryFeature } from \"~/features/contentEntry/unpublishEntry/feature.js\";\nimport { MoveEntryFeature } from \"~/features/contentEntry/moveEntry/feature.js\";\nimport { UpdateRevisionDescriptionFeature } from \"~/features/contentEntry/updateRevisionDescription/feature.js\";\nimport { ListEntriesGateway } from \"~/features/contentEntry/listEntries/abstractions.js\";\nimport { DeleteEntryGateway } from \"~/features/contentEntry/deleteEntry/abstractions.js\";\nimport {\n PublishEntryGateway,\n PublishEntryUseCase\n} from \"~/features/contentEntry/publishEntry/abstractions.js\";\nimport { UnpublishEntryGateway } from \"~/features/contentEntry/unpublishEntry/abstractions.js\";\nimport { MoveEntryGateway } from \"~/features/contentEntry/moveEntry/abstractions.js\";\nimport { UpdateRevisionDescriptionGateway } from \"~/features/contentEntry/updateRevisionDescription/abstractions.js\";\nimport { EventPublisher } from \"@webiny/app/features/eventPublisher/index.js\";\nimport { ContentEntriesPresenter as Abstraction } from \"./abstractions.js\";\nimport { ContentEntriesPresenter } from \"./ContentEntriesPresenter.js\";\nimport type { IContentEntriesPresenter } from \"./abstractions.js\";\nimport type {\n IFolderTreeViewModel,\n IFolderOperationState\n} from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\n\nconst MODEL: CmsModel = {\n modelId: \"testModel\",\n name: \"Test Model\",\n singularApiName: \"TestModel\",\n pluralApiName: \"TestModels\",\n fields: [],\n layout: [],\n group: \"group-1\",\n titleFieldId: \"title\",\n descriptionFieldId: null,\n imageFieldId: null,\n tags: [],\n savedOn: \"\"\n} as unknown as CmsModel;\n\nfunction createEntry(\n entryId: string,\n folderId: string,\n overrides: Partial<CmsContentEntry> = {}\n): CmsContentEntry {\n return {\n id: `${entryId}#0001`,\n entryId,\n meta: {\n title: entryId,\n status: \"draft\",\n version: 1,\n locked: false\n },\n wbyAco_location: { folderId },\n values: {},\n createdBy: { id: \"user-1\", displayName: \"Test\", type: \"admin\" },\n createdOn: \"2024-01-01T00:00:00Z\",\n savedOn: \"2024-01-01T00:00:00Z\",\n ...overrides\n } as unknown as CmsContentEntry;\n}\n\nclass MockFolderTreePresenter implements FolderTreePresenter.Interface {\n private _currentFolderId: string | null = null;\n\n constructor() {\n makeAutoObservable(this);\n }\n\n get vm(): IFolderTreeViewModel {\n return {\n folders: [],\n tree: [],\n currentFolderId: this._currentFolderId,\n currentFolder: null,\n isRootFolder: this._currentFolderId === null,\n currentFolderTitle: \"Home\",\n childFolders: [],\n loading: false,\n loadingNodeIds: [],\n operation: { active: false, mode: null } as IFolderOperationState\n };\n }\n\n selectFolder(folderId: string | null): void {\n this._currentFolderId = folderId;\n }\n\n createFolder(): void {}\n editFolder(): void {}\n async deleteFolder(): Promise<void> {}\n async moveFolder(): Promise<void> {}\n async loadChildFolders(): Promise<void> {}\n canManageStructure(): boolean {\n return true;\n }\n getAncestorIds(): string[] {\n return [];\n }\n async submitOperation(): Promise<boolean> {\n return true;\n }\n cancelOperation(): void {}\n onFolderChange(): () => void {\n return () => {};\n }\n}\n\ninterface TestSetup {\n presenter: IContentEntriesPresenter;\n listEntriesGateway: { execute: ReturnType<typeof vi.fn> };\n moveEntryGateway: { execute: ReturnType<typeof vi.fn> };\n deleteEntryGateway: { execute: ReturnType<typeof vi.fn> };\n getDescendantFolders: ReturnType<typeof vi.fn>;\n foldersPresenter: MockFolderTreePresenter;\n publishEntryGateway: { execute: ReturnType<typeof vi.fn> };\n container: Container;\n}\n\nfunction setup(): TestSetup {\n const container = new Container();\n\n ListPresenterFeature.register(container);\n\n const foldersPresenter = new MockFolderTreePresenter();\n container.registerInstance(FolderTreePresenter, foldersPresenter);\n\n container.registerInstance(Confirmation, {\n confirm: vi.fn(async (_name, _params, execute) => {\n if (execute) {\n await execute(undefined);\n }\n return true;\n })\n } as unknown as Confirmation.Interface);\n\n const getDescendantFolders = vi.fn().mockReturnValue([]);\n container.registerInstance(GetDescendantFoldersUseCase, {\n execute: getDescendantFolders\n });\n\n container.registerInstance(EventPublisher, { publish: vi.fn() });\n container.register(ContentEntriesCacheProvider).inSingletonScope();\n container.register(CmsModelContextImpl).inSingletonScope();\n container.resolve(CmsModelContext).setModel(MODEL);\n\n ListEntriesFeature.register(container);\n DeleteEntryFeature.register(container);\n PublishEntryFeature.register(container);\n UnpublishEntryFeature.register(container);\n MoveEntryFeature.register(container);\n UpdateRevisionDescriptionFeature.register(container);\n\n const listEntriesGateway = { execute: vi.fn() };\n const moveEntryGateway = { execute: vi.fn() };\n const deleteEntryGateway = { execute: vi.fn() };\n\n container.registerInstance(ListEntriesGateway, listEntriesGateway);\n container.registerInstance(MoveEntryGateway, moveEntryGateway);\n container.registerInstance(DeleteEntryGateway, deleteEntryGateway);\n const publishEntryGateway = { execute: vi.fn() };\n container.registerInstance(PublishEntryGateway, publishEntryGateway);\n container.registerInstance(UnpublishEntryGateway, { execute: vi.fn() });\n container.registerInstance(UpdateRevisionDescriptionGateway, { execute: vi.fn() });\n\n container.register(ContentEntriesPresenter).inSingletonScope();\n const presenter = container.resolve(Abstraction);\n\n return {\n presenter,\n listEntriesGateway,\n moveEntryGateway,\n deleteEntryGateway,\n getDescendantFolders,\n foldersPresenter,\n publishEntryGateway,\n container\n };\n}\n\nasync function initPresenter(\n t: TestSetup,\n gatewayResponse: { data: CmsContentEntry[]; meta?: object }\n) {\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: gatewayResponse.data,\n meta: gatewayResponse.meta ?? {\n cursor: null,\n hasMoreItems: false,\n totalCount: gatewayResponse.data.length\n }\n });\n\n t.presenter.init();\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.pagination.loading).toBe(false);\n });\n}\n\ndescribe(\"ContentEntriesPresenter\", () => {\n let t: TestSetup;\n\n beforeEach(() => {\n t = setup();\n });\n\n describe(\"initial load\", () => {\n it(\"should show root entries after setModel\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n\n await initPresenter(t, { data: entries });\n\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\"entry-1\", \"entry-2\"]);\n });\n\n it(\"should send folderId=root in the gateway query\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.listEntriesGateway.execute).toHaveBeenCalledWith(\n expect.objectContaining({\n where: expect.objectContaining({\n wbyAco_location: { folderId: \"root\" }\n })\n })\n );\n });\n\n it(\"should set model after init\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.presenter.vm.model).toStrictEqual(MODEL);\n });\n });\n\n describe(\"folder navigation\", () => {\n it(\"should filter to folder entries when navigating to a subfolder\", async () => {\n const rootEntries = [createEntry(\"root-1\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n const folderEntries = [\n createEntry(\"folder-1\", \"folder-a\"),\n createEntry(\"folder-2\", \"folder-a\")\n ];\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: folderEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 2 }\n });\n\n t.foldersPresenter.selectFolder(\"folder-a\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n });\n\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\"folder-1\", \"folder-2\"]);\n });\n\n it(\"should show only root entries when navigating back to root\", async () => {\n const rootEntries = [createEntry(\"root-1\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n const folderEntries = [createEntry(\"folder-1\", \"folder-a\")];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: folderEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(\"folder-a\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"folder-1\");\n });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: rootEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(null);\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"root-1\");\n });\n });\n\n it(\"should not leak subfolder entries into root view\", async () => {\n const rootEntries = [createEntry(\"root-1\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [createEntry(\"folder-1\", \"folder-a\")],\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(\"folder-a\");\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: rootEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(null);\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"root-1\");\n });\n });\n });\n\n describe(\"search\", () => {\n it(\"should show only search results from API\", async () => {\n const rootEntries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n const searchResults = [createEntry(\"entry-1\", \"root\")];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: searchResults,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.list.actions.search.set(\"entry-1\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"entry-1\");\n });\n\n it(\"should include entries from subfolders when searching from root\", async () => {\n await initPresenter(t, { data: [] });\n\n const searchResults = [\n createEntry(\"root-1\", \"root\"),\n createEntry(\"folder-1\", \"folder-a\")\n ];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: searchResults,\n meta: { cursor: null, hasMoreItems: false, totalCount: 2 }\n });\n\n t.presenter.list.actions.search.set(\"test\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n });\n });\n\n it(\"should search with folderId_in containing all descendant folders when in a subfolder\", async () => {\n const folderEntries = [createEntry(\"folder-1\", \"folder-a\")];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: folderEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.init({ initialFolderId: \"folder-a\" });\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.pagination.loading).toBe(false);\n });\n\n t.getDescendantFolders.mockReturnValue([\n { id: \"folder-a\" },\n { id: \"folder-a-1\" },\n { id: \"folder-a-2\" }\n ]);\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [\n createEntry(\"folder-1\", \"folder-a\"),\n createEntry(\"sub-1\", \"folder-a-1\"),\n createEntry(\"sub-2\", \"folder-a-2\")\n ],\n meta: { cursor: null, hasMoreItems: false, totalCount: 3 }\n });\n\n t.presenter.list.actions.search.set(\"test\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(3);\n });\n\n expect(t.getDescendantFolders).toHaveBeenCalledWith(\"folder-a\");\n\n const searchCall = t.listEntriesGateway.execute.mock.calls.at(-1) ?? [];\n expect(searchCall[0].where).toEqual(\n expect.objectContaining({\n wbyAco_location: {\n folderId_in: [\"folder-a\", \"folder-a-1\", \"folder-a-2\"]\n }\n })\n );\n });\n\n it(\"should restore folder view when clearing search\", async () => {\n const rootEntries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [createEntry(\"entry-1\", \"root\")],\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.list.actions.search.set(\"entry-1\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: rootEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 2 }\n });\n\n t.presenter.list.actions.search.clear();\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n });\n });\n });\n\n describe(\"status filter\", () => {\n it(\"should filter by status locally\", async () => {\n const entries = [\n createEntry(\"draft-1\", \"root\", {\n meta: {\n title: \"draft-1\",\n status: \"draft\",\n version: 1,\n locked: false\n }\n }),\n createEntry(\"published-1\", \"root\", {\n meta: {\n title: \"published-1\",\n status: \"published\",\n version: 1,\n locked: false\n }\n })\n ];\n await initPresenter(t, { data: entries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: entries.filter(e => (e.meta as { status: string }).status === \"published\"),\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.list.actions.filter.set(\"status\", \"published\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"published-1\");\n });\n });\n });\n\n describe(\"move entry\", () => {\n it(\"should remove entry from current view after move\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: entries });\n\n t.moveEntryGateway.execute.mockResolvedValueOnce(true);\n\n await t.presenter.moveEntry(\"entry-1#0001\", \"folder-b\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"entry-2\");\n });\n });\n });\n\n describe(\"delete entry\", () => {\n it(\"should remove entry from current view after delete\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: entries });\n\n t.deleteEntryGateway.execute.mockResolvedValueOnce(true);\n\n await t.presenter.deleteEntry(\"entry-1#0001\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"entry-2\");\n });\n });\n });\n\n describe(\"vm\", () => {\n it(\"should set model on init\", () => {\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 }\n });\n t.presenter.init();\n expect(t.presenter.vm.model).toStrictEqual(MODEL);\n });\n\n it(\"should track selected entry\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.presenter.vm.showingEntry).toBe(false);\n\n t.presenter.selectEntry(\"some-id\");\n expect(t.presenter.vm.selectedEntryId).toBe(\"some-id\");\n expect(t.presenter.vm.showingEntry).toBe(true);\n\n t.presenter.deselectEntry();\n expect(t.presenter.vm.selectedEntryId).toBeNull();\n expect(t.presenter.vm.showingEntry).toBe(false);\n });\n\n it(\"should set selectedEntryId to 'new' on createEntry\", async () => {\n await initPresenter(t, { data: [] });\n\n t.presenter.createEntry();\n expect(t.presenter.vm.selectedEntryId).toBe(\"new\");\n });\n\n it(\"should show folders when no search or non-folder filters active\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.presenter.vm.showFolders).toBe(true);\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 }\n });\n\n t.presenter.list.actions.search.set(\"test\");\n\n await vi.waitFor(() => {\n expect(t.presenter.vm.showFolders).toBe(false);\n });\n });\n });\n\n describe(\"publish entry\", () => {\n /**\n * Publishing is not a content modification: the API returns the entry with its\n * `savedOn` unchanged, so the entry must keep its position in a list sorted by `savedOn`.\n */\n const entries = [\n createEntry(\"entry-3\", \"root\", { savedOn: \"2024-01-03T00:00:00.000Z\" }),\n createEntry(\"entry-2\", \"root\", { savedOn: \"2024-01-02T00:00:00.000Z\" }),\n createEntry(\"entry-1\", \"root\", { savedOn: \"2024-01-01T00:00:00.000Z\" })\n ];\n\n const publish = async (entry: CmsContentEntry) => {\n t.publishEntryGateway.execute.mockResolvedValueOnce({\n ...entry,\n meta: { ...entry.meta, status: \"published\", locked: true }\n });\n await t.container\n .resolve(PublishEntryUseCase)\n .execute({ model: MODEL, revisionId: entry.id });\n };\n\n it(\"should keep a published entry in its position\", async () => {\n await initPresenter(t, { data: entries });\n\n await publish(entries[1]);\n\n const rows = t.presenter.list.vm.rows;\n expect(rows.map(r => r.entryId)).toEqual([\"entry-3\", \"entry-2\", \"entry-1\"]);\n expect((rows[1].meta as { status: string }).status).toBe(\"published\");\n });\n\n it(\"should keep a published entry in its position when sorted ascending\", async () => {\n await initPresenter(t, { data: entries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [...entries].reverse(),\n meta: { cursor: null, hasMoreItems: false, totalCount: entries.length }\n });\n t.presenter.list.actions.sort.set(\"savedOn\", \"ASC\");\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.appliedQuery?.sort?.direction).toBe(\"ASC\");\n });\n\n await publish(entries[1]);\n\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\n \"entry-1\",\n \"entry-2\",\n \"entry-3\"\n ]);\n });\n });\n});\n"],"names":["MODEL","createEntry","entryId","folderId","overrides","MockFolderTreePresenter","makeAutoObservable","setup","container","Container","ListPresenterFeature","foldersPresenter","FolderTreePresenter","Confirmation","vi","_name","_params","execute","undefined","getDescendantFolders","GetDescendantFoldersUseCase","EventPublisher","ContentEntriesCacheProvider","CmsModelContextImpl","CmsModelContext","ListEntriesFeature","DeleteEntryFeature","PublishEntryFeature","UnpublishEntryFeature","MoveEntryFeature","UpdateRevisionDescriptionFeature","listEntriesGateway","moveEntryGateway","deleteEntryGateway","ListEntriesGateway","MoveEntryGateway","DeleteEntryGateway","publishEntryGateway","PublishEntryGateway","UnpublishEntryGateway","UpdateRevisionDescriptionGateway","ContentEntriesPresenter","presenter","Abstraction","initPresenter","t","gatewayResponse","expect","describe","beforeEach","it","entries","r","rootEntries","folderEntries","searchResults","searchCall","e","publish","entry","PublishEntryUseCase","rows"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,MAAMA,QAAkB;IACpB,SAAS;IACT,MAAM;IACN,iBAAiB;IACjB,eAAe;IACf,QAAQ,EAAE;IACV,QAAQ,EAAE;IACV,OAAO;IACP,cAAc;IACd,oBAAoB;IACpB,cAAc;IACd,MAAM,EAAE;IACR,SAAS;AACb;AAEA,SAASC,YACLC,OAAe,EACfC,QAAgB,EAChBC,YAAsC,CAAC,CAAC;IAExC,OAAO;QACH,IAAI,GAAGF,QAAQ,KAAK,CAAC;QACrBA;QACA,MAAM;YACF,OAAOA;YACP,QAAQ;YACR,SAAS;YACT,QAAQ;QACZ;QACA,iBAAiB;YAAEC;QAAS;QAC5B,QAAQ,CAAC;QACT,WAAW;YAAE,IAAI;YAAU,aAAa;YAAQ,MAAM;QAAQ;QAC9D,WAAW;QACX,SAAS;QACT,GAAGC,SAAS;IAChB;AACJ;AAEA,MAAMC;IAGF,aAAc;aAFN,gBAAgB,GAAkB;QAGtCC,mBAAmB,IAAI;IAC3B;IAEA,IAAI,KAA2B;QAC3B,OAAO;YACH,SAAS,EAAE;YACX,MAAM,EAAE;YACR,iBAAiB,IAAI,CAAC,gBAAgB;YACtC,eAAe;YACf,cAAc,AAA0B,SAA1B,IAAI,CAAC,gBAAgB;YACnC,oBAAoB;YACpB,cAAc,EAAE;YAChB,SAAS;YACT,gBAAgB,EAAE;YAClB,WAAW;gBAAE,QAAQ;gBAAO,MAAM;YAAK;QAC3C;IACJ;IAEA,aAAaH,QAAuB,EAAQ;QACxC,IAAI,CAAC,gBAAgB,GAAGA;IAC5B;IAEA,eAAqB,CAAC;IACtB,aAAmB,CAAC;IACpB,MAAM,eAA8B,CAAC;IACrC,MAAM,aAA4B,CAAC;IACnC,MAAM,mBAAkC,CAAC;IACzC,qBAA8B;QAC1B,OAAO;IACX;IACA,iBAA2B;QACvB,OAAO,EAAE;IACb;IACA,MAAM,kBAAoC;QACtC,OAAO;IACX;IACA,kBAAwB,CAAC;IACzB,iBAA6B;QACzB,OAAO,KAAO;IAClB;AACJ;AAaA,SAASI;IACL,MAAMC,YAAY,IAAIC;IAEtBC,qBAAqB,QAAQ,CAACF;IAE9B,MAAMG,mBAAmB,IAAIN;IAC7BG,UAAU,gBAAgB,CAACI,qBAAqBD;IAEhDH,UAAU,gBAAgB,CAACK,cAAc;QACrC,SAASC,GAAG,EAAE,CAAC,OAAOC,OAAOC,SAASC;YAClC,IAAIA,SACA,MAAMA,QAAQC;YAElB,OAAO;QACX;IACJ;IAEA,MAAMC,uBAAuBL,GAAG,EAAE,GAAG,eAAe,CAAC,EAAE;IACvDN,UAAU,gBAAgB,CAACY,6BAA6B;QACpD,SAASD;IACb;IAEAX,UAAU,gBAAgB,CAACa,gBAAgB;QAAE,SAASP,GAAG,EAAE;IAAG;IAC9DN,UAAU,QAAQ,CAACc,6BAA6B,gBAAgB;IAChEd,UAAU,QAAQ,CAACe,oCAAqB,gBAAgB;IACxDf,UAAU,OAAO,CAACgB,iBAAiB,QAAQ,CAACxB;IAE5CyB,mBAAmB,QAAQ,CAACjB;IAC5BkB,mBAAmB,QAAQ,CAAClB;IAC5BmB,oBAAoB,QAAQ,CAACnB;IAC7BoB,sBAAsB,QAAQ,CAACpB;IAC/BqB,iBAAiB,QAAQ,CAACrB;IAC1BsB,iCAAiC,QAAQ,CAACtB;IAE1C,MAAMuB,qBAAqB;QAAE,SAASjB,GAAG,EAAE;IAAG;IAC9C,MAAMkB,mBAAmB;QAAE,SAASlB,GAAG,EAAE;IAAG;IAC5C,MAAMmB,qBAAqB;QAAE,SAASnB,GAAG,EAAE;IAAG;IAE9CN,UAAU,gBAAgB,CAAC0B,oBAAoBH;IAC/CvB,UAAU,gBAAgB,CAAC2B,kBAAkBH;IAC7CxB,UAAU,gBAAgB,CAAC4B,oBAAoBH;IAC/C,MAAMI,sBAAsB;QAAE,SAASvB,GAAG,EAAE;IAAG;IAC/CN,UAAU,gBAAgB,CAAC8B,qBAAqBD;IAChD7B,UAAU,gBAAgB,CAAC+B,uBAAuB;QAAE,SAASzB,GAAG,EAAE;IAAG;IACrEN,UAAU,gBAAgB,CAACgC,kCAAkC;QAAE,SAAS1B,GAAG,EAAE;IAAG;IAEhFN,UAAU,QAAQ,CAACiC,6DAAyB,gBAAgB;IAC5D,MAAMC,YAAYlC,UAAU,OAAO,CAACmC;IAEpC,OAAO;QACHD;QACAX;QACAC;QACAC;QACAd;QACAR;QACA0B;QACA7B;IACJ;AACJ;AAEA,eAAeoC,cACXC,CAAY,EACZC,eAA2D;IAE3DD,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;QAC/C,MAAMC,gBAAgB,IAAI;QAC1B,MAAMA,gBAAgB,IAAI,IAAI;YAC1B,QAAQ;YACR,cAAc;YACd,YAAYA,gBAAgB,IAAI,CAAC,MAAM;QAC3C;IACJ;IAEAD,EAAE,SAAS,CAAC,IAAI;IAEhB,MAAM/B,GAAG,OAAO,CAAC;QACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC;IACxD;AACJ;AAEAG,SAAS,2BAA2B;IAChC,IAAIH;IAEJI,WAAW;QACPJ,IAAItC;IACR;IAEAyC,SAAS,gBAAgB;QACrBE,GAAG,2CAA2C;YAC1C,MAAMC,UAAU;gBAAClD,YAAY,WAAW;gBAASA,YAAY,WAAW;aAAQ;YAEhF,MAAM2C,cAAcC,GAAG;gBAAE,MAAMM;YAAQ;YAEvCJ,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAACO,CAAAA,IAAKA,EAAE,OAAO,GAAG,OAAO,CAAC;gBAAC;gBAAW;aAAU;QACvF;QAEAF,GAAG,kDAAkD;YACjD,MAAMN,cAAcC,GAAG;gBAAE,MAAM,EAAE;YAAC;YAElCE,OAAOF,EAAE,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,CACrDE,OAAO,gBAAgB,CAAC;gBACpB,OAAOA,OAAO,gBAAgB,CAAC;oBAC3B,iBAAiB;wBAAE,UAAU;oBAAO;gBACxC;YACJ;QAER;QAEAG,GAAG,+BAA+B;YAC9B,MAAMN,cAAcC,GAAG;gBAAE,MAAM,EAAE;YAAC;YAElCE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC7C;QAC/C;IACJ;IAEAgD,SAAS,qBAAqB;QAC1BE,GAAG,kEAAkE;YACjE,MAAMG,cAAc;gBAACpD,YAAY,UAAU;aAAQ;YACnD,MAAM2C,cAAcC,GAAG;gBAAE,MAAMQ;YAAY;YAE3C,MAAMC,gBAAgB;gBAClBrD,YAAY,YAAY;gBACxBA,YAAY,YAAY;aAC3B;YAED4C,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMS;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAT,EAAE,gBAAgB,CAAC,YAAY,CAAC;YAEhC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;YAEAE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAACO,CAAAA,IAAKA,EAAE,OAAO,GAAG,OAAO,CAAC;gBAAC;gBAAY;aAAW;QACzF;QAEAF,GAAG,8DAA8D;YAC7D,MAAMG,cAAc;gBAACpD,YAAY,UAAU;aAAQ;YACnD,MAAM2C,cAAcC,GAAG;gBAAE,MAAMQ;YAAY;YAE3C,MAAMC,gBAAgB;gBAACrD,YAAY,YAAY;aAAY;YAC3D4C,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMS;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAT,EAAE,gBAAgB,CAAC,YAAY,CAAC;YAEhC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;YACrD;YAEAA,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMQ;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAR,EAAE,gBAAgB,CAAC,YAAY,CAAC;YAEhC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;YACrD;QACJ;QAEAK,GAAG,oDAAoD;YACnD,MAAMG,cAAc;gBAACpD,YAAY,UAAU;aAAQ;YACnD,MAAM2C,cAAcC,GAAG;gBAAE,MAAMQ;YAAY;YAE3CR,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAM;oBAAC5C,YAAY,YAAY;iBAAY;gBAC3C,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEA4C,EAAE,gBAAgB,CAAC,YAAY,CAAC;YAChC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;YAEAA,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMQ;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAR,EAAE,gBAAgB,CAAC,YAAY,CAAC;YAChC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;YACrD;QACJ;IACJ;IAEAG,SAAS,UAAU;QACfE,GAAG,4CAA4C;YAC3C,MAAMG,cAAc;gBAACpD,YAAY,WAAW;gBAASA,YAAY,WAAW;aAAQ;YACpF,MAAM2C,cAAcC,GAAG;gBAAE,MAAMQ;YAAY;YAE3C,MAAME,gBAAgB;gBAACtD,YAAY,WAAW;aAAQ;YACtD4C,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMU;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAV,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YAEpC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;YAEAE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;QACrD;QAEAK,GAAG,mEAAmE;YAClE,MAAMN,cAAcC,GAAG;gBAAE,MAAM,EAAE;YAAC;YAElC,MAAMU,gBAAgB;gBAClBtD,YAAY,UAAU;gBACtBA,YAAY,YAAY;aAC3B;YACD4C,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMU;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAV,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YAEpC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;QACJ;QAEAK,GAAG,wFAAwF;YACvF,MAAMI,gBAAgB;gBAACrD,YAAY,YAAY;aAAY;YAC3D4C,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMS;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAT,EAAE,SAAS,CAAC,IAAI,CAAC;gBAAE,iBAAiB;YAAW;YAE/C,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC;YACxD;YAEAA,EAAE,oBAAoB,CAAC,eAAe,CAAC;gBACnC;oBAAE,IAAI;gBAAW;gBACjB;oBAAE,IAAI;gBAAa;gBACnB;oBAAE,IAAI;gBAAa;aACtB;YAEDA,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAM;oBACF5C,YAAY,YAAY;oBACxBA,YAAY,SAAS;oBACrBA,YAAY,SAAS;iBACxB;gBACD,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEA4C,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YAEpC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;YAEAE,OAAOF,EAAE,oBAAoB,EAAE,oBAAoB,CAAC;YAEpD,MAAMW,aAAaX,EAAE,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;YACvEE,OAAOS,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAC/BT,OAAO,gBAAgB,CAAC;gBACpB,iBAAiB;oBACb,aAAa;wBAAC;wBAAY;wBAAc;qBAAa;gBACzD;YACJ;QAER;QAEAG,GAAG,mDAAmD;YAClD,MAAMG,cAAc;gBAACpD,YAAY,WAAW;gBAASA,YAAY,WAAW;aAAQ;YACpF,MAAM2C,cAAcC,GAAG;gBAAE,MAAMQ;YAAY;YAE3CR,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAM;oBAAC5C,YAAY,WAAW;iBAAQ;gBACtC,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEA4C,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YAEpC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;YAEAA,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMQ;gBACN,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAR,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;YAErC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAClD;QACJ;IACJ;IAEAG,SAAS,iBAAiB;QACtBE,GAAG,mCAAmC;YAClC,MAAMC,UAAU;gBACZlD,YAAY,WAAW,QAAQ;oBAC3B,MAAM;wBACF,OAAO;wBACP,QAAQ;wBACR,SAAS;wBACT,QAAQ;oBACZ;gBACJ;gBACAA,YAAY,eAAe,QAAQ;oBAC/B,MAAM;wBACF,OAAO;wBACP,QAAQ;wBACR,SAAS;wBACT,QAAQ;oBACZ;gBACJ;aACH;YACD,MAAM2C,cAAcC,GAAG;gBAAE,MAAMM;YAAQ;YAEvCN,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAMM,QAAQ,MAAM,CAACM,CAAAA,IAAMA,AAAyC,gBAAzCA,EAAE,IAAI,CAAwB,MAAM;gBAC/D,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAZ,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU;YAE9C,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;YACrD;QACJ;IACJ;IAEAG,SAAS,cAAc;QACnBE,GAAG,oDAAoD;YACnD,MAAMC,UAAU;gBAAClD,YAAY,WAAW;gBAASA,YAAY,WAAW;aAAQ;YAChF,MAAM2C,cAAcC,GAAG;gBAAE,MAAMM;YAAQ;YAEvCN,EAAE,gBAAgB,CAAC,OAAO,CAAC,qBAAqB,CAAC;YAEjD,MAAMA,EAAE,SAAS,CAAC,SAAS,CAAC,gBAAgB;YAE5C,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;YACrD;QACJ;IACJ;IAEAG,SAAS,gBAAgB;QACrBE,GAAG,sDAAsD;YACrD,MAAMC,UAAU;gBAAClD,YAAY,WAAW;gBAASA,YAAY,WAAW;aAAQ;YAChF,MAAM2C,cAAcC,GAAG;gBAAE,MAAMM;YAAQ;YAEvCN,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;YAEnD,MAAMA,EAAE,SAAS,CAAC,WAAW,CAAC;YAE9B,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAC9CE,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;YACrD;QACJ;IACJ;IAEAG,SAAS,MAAM;QACXE,GAAG,4BAA4B;YAC3BL,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAM,EAAE;gBACR,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YACAA,EAAE,SAAS,CAAC,IAAI;YAChBE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC7C;QAC/C;QAEAkD,GAAG,+BAA+B;YAC9B,MAAMN,cAAcC,GAAG;gBAAE,MAAM,EAAE;YAAC;YAElCE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC;YAEzCA,EAAE,SAAS,CAAC,WAAW,CAAC;YACxBE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC;YAC5CE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC;YAEzCA,EAAE,SAAS,CAAC,aAAa;YACzBE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,eAAe,EAAE,QAAQ;YAC/CE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC;QAC7C;QAEAK,GAAG,sDAAsD;YACrD,MAAMN,cAAcC,GAAG;gBAAE,MAAM,EAAE;YAAC;YAElCA,EAAE,SAAS,CAAC,WAAW;YACvBE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC;QAChD;QAEAK,GAAG,mEAAmE;YAClE,MAAMN,cAAcC,GAAG;gBAAE,MAAM,EAAE;YAAC;YAElCE,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC;YAExCA,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAM,EAAE;gBACR,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAY;gBAAE;YAC7D;YAEAA,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YAEpC,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC;YAC5C;QACJ;IACJ;IAEAG,SAAS,iBAAiB;QAKtB,MAAMG,UAAU;YACZlD,YAAY,WAAW,QAAQ;gBAAE,SAAS;YAA2B;YACrEA,YAAY,WAAW,QAAQ;gBAAE,SAAS;YAA2B;YACrEA,YAAY,WAAW,QAAQ;gBAAE,SAAS;YAA2B;SACxE;QAED,MAAMyD,UAAU,OAAOC;YACnBd,EAAE,mBAAmB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAChD,GAAGc,KAAK;gBACR,MAAM;oBAAE,GAAGA,MAAM,IAAI;oBAAE,QAAQ;oBAAa,QAAQ;gBAAK;YAC7D;YACA,MAAMd,EAAE,SAAS,CACZ,OAAO,CAACe,qBACR,OAAO,CAAC;gBAAE,OAAO5D;gBAAO,YAAY2D,MAAM,EAAE;YAAC;QACtD;QAEAT,GAAG,iDAAiD;YAChD,MAAMN,cAAcC,GAAG;gBAAE,MAAMM;YAAQ;YAEvC,MAAMO,QAAQP,OAAO,CAAC,EAAE;YAExB,MAAMU,OAAOhB,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;YACrCE,OAAOc,KAAK,GAAG,CAACT,CAAAA,IAAKA,EAAE,OAAO,GAAG,OAAO,CAAC;gBAAC;gBAAW;gBAAW;aAAU;YAC1EL,OAAQc,IAAI,CAAC,EAAE,CAAC,IAAI,CAAwB,MAAM,EAAE,IAAI,CAAC;QAC7D;QAEAX,GAAG,uEAAuE;YACtE,MAAMN,cAAcC,GAAG;gBAAE,MAAMM;YAAQ;YAEvCN,EAAE,kBAAkB,CAAC,OAAO,CAAC,qBAAqB,CAAC;gBAC/C,MAAM;uBAAIM;iBAAQ,CAAC,OAAO;gBAC1B,MAAM;oBAAE,QAAQ;oBAAM,cAAc;oBAAO,YAAYA,QAAQ,MAAM;gBAAC;YAC1E;YACAN,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW;YAC7C,MAAM/B,GAAG,OAAO,CAAC;gBACbiC,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,WAAW,IAAI,CAAC;YACnE;YAEA,MAAMa,QAAQP,OAAO,CAAC,EAAE;YAExBJ,OAAOF,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAACO,CAAAA,IAAKA,EAAE,OAAO,GAAG,OAAO,CAAC;gBACzD;gBACA;gBACA;aACH;QACL;IACJ;AACJ"}
|
|
1
|
+
{"version":3,"file":"presentation/contentEntries/list/ContentEntriesPresenter.test.js","sources":["../../../../src/presentation/contentEntries/list/ContentEntriesPresenter.test.ts"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\nimport { describe, it, expect, vi, beforeEach } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { makeAutoObservable } from \"mobx\";\nimport { ListPresenterFeature } from \"@webiny/app-admin/presentation/listPresenter/index.js\";\nimport { FolderTreePresenter } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport { GetDescendantFoldersUseCase } from \"@webiny/app-aco/features/folders/getDescendantFolders/abstractions.js\";\nimport { Confirmation } from \"@webiny/app-admin/features/confirmation/abstractions.js\";\nimport type { CmsContentEntry, CmsModel } from \"~/types.js\";\nimport { ContentEntriesCacheProvider } from \"~/features/contentEntry/ContentEntriesCacheProvider.js\";\nimport { CmsModelContext } from \"~/features/contentEntry/abstractions.js\";\nimport { CmsModelContext as CmsModelContextImpl } from \"~/features/contentEntry/CmsModelContext.js\";\nimport { ListEntriesFeature } from \"~/features/contentEntry/listEntries/feature.js\";\nimport { DeleteEntryFeature } from \"~/features/contentEntry/deleteEntry/feature.js\";\nimport { PublishEntryFeature } from \"~/features/contentEntry/publishEntry/feature.js\";\nimport { UnpublishEntryFeature } from \"~/features/contentEntry/unpublishEntry/feature.js\";\nimport { MoveEntryFeature } from \"~/features/contentEntry/moveEntry/feature.js\";\nimport { DuplicateEntryFeature } from \"~/features/contentEntry/duplicateEntry/feature.js\";\nimport { UpdateRevisionDescriptionFeature } from \"~/features/contentEntry/updateRevisionDescription/feature.js\";\nimport { ListEntriesGateway } from \"~/features/contentEntry/listEntries/abstractions.js\";\nimport { DeleteEntryGateway } from \"~/features/contentEntry/deleteEntry/abstractions.js\";\nimport {\n PublishEntryGateway,\n PublishEntryUseCase\n} from \"~/features/contentEntry/publishEntry/abstractions.js\";\nimport { UnpublishEntryGateway } from \"~/features/contentEntry/unpublishEntry/abstractions.js\";\nimport { MoveEntryGateway } from \"~/features/contentEntry/moveEntry/abstractions.js\";\nimport { DuplicateEntryGateway } from \"~/features/contentEntry/duplicateEntry/abstractions.js\";\nimport { UpdateRevisionDescriptionGateway } from \"~/features/contentEntry/updateRevisionDescription/abstractions.js\";\nimport { EventPublisher } from \"@webiny/app/features/eventPublisher/index.js\";\nimport { ContentEntriesPresenter as Abstraction } from \"./abstractions.js\";\nimport { ContentEntriesPresenter } from \"./ContentEntriesPresenter.js\";\nimport type { IContentEntriesPresenter } from \"./abstractions.js\";\nimport type {\n IFolderTreeViewModel,\n IFolderOperationState\n} from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\n\nconst MODEL: CmsModel = {\n modelId: \"testModel\",\n name: \"Test Model\",\n singularApiName: \"TestModel\",\n pluralApiName: \"TestModels\",\n fields: [],\n layout: [],\n group: \"group-1\",\n titleFieldId: \"title\",\n descriptionFieldId: null,\n imageFieldId: null,\n tags: [],\n savedOn: \"\"\n} as unknown as CmsModel;\n\nfunction createEntry(\n entryId: string,\n folderId: string,\n overrides: Partial<CmsContentEntry> = {}\n): CmsContentEntry {\n return {\n id: `${entryId}#0001`,\n entryId,\n meta: {\n title: entryId,\n status: \"draft\",\n version: 1,\n locked: false\n },\n wbyAco_location: { folderId },\n values: {},\n createdBy: { id: \"user-1\", displayName: \"Test\", type: \"admin\" },\n createdOn: \"2024-01-01T00:00:00Z\",\n savedOn: \"2024-01-01T00:00:00Z\",\n ...overrides\n } as unknown as CmsContentEntry;\n}\n\nclass MockFolderTreePresenter implements FolderTreePresenter.Interface {\n private _currentFolderId: string | null = null;\n\n constructor() {\n makeAutoObservable(this);\n }\n\n get vm(): IFolderTreeViewModel {\n return {\n folders: [],\n tree: [],\n currentFolderId: this._currentFolderId,\n currentFolder: null,\n isRootFolder: this._currentFolderId === null,\n currentFolderTitle: \"Home\",\n childFolders: [],\n loading: false,\n loadingNodeIds: [],\n operation: { active: false, mode: null } as IFolderOperationState\n };\n }\n\n selectFolder(folderId: string | null): void {\n this._currentFolderId = folderId;\n }\n\n createFolder(): void {}\n editFolder(): void {}\n async deleteFolder(): Promise<void> {}\n async moveFolder(): Promise<void> {}\n async loadChildFolders(): Promise<void> {}\n canManageStructure(): boolean {\n return true;\n }\n getAncestorIds(): string[] {\n return [];\n }\n async submitOperation(): Promise<boolean> {\n return true;\n }\n cancelOperation(): void {}\n onFolderChange(): () => void {\n return () => {};\n }\n}\n\ninterface TestSetup {\n presenter: IContentEntriesPresenter;\n listEntriesGateway: { execute: ReturnType<typeof vi.fn> };\n moveEntryGateway: { execute: ReturnType<typeof vi.fn> };\n deleteEntryGateway: { execute: ReturnType<typeof vi.fn> };\n duplicateEntryGateway: { execute: ReturnType<typeof vi.fn> };\n getDescendantFolders: ReturnType<typeof vi.fn>;\n foldersPresenter: MockFolderTreePresenter;\n publishEntryGateway: { execute: ReturnType<typeof vi.fn> };\n container: Container;\n}\n\nfunction setup(): TestSetup {\n const container = new Container();\n\n ListPresenterFeature.register(container);\n\n const foldersPresenter = new MockFolderTreePresenter();\n container.registerInstance(FolderTreePresenter, foldersPresenter);\n\n container.registerInstance(Confirmation, {\n confirm: vi.fn(async (_name, _params, execute) => {\n if (execute) {\n return await execute(undefined);\n }\n return true;\n })\n } as unknown as Confirmation.Interface);\n\n const getDescendantFolders = vi.fn().mockReturnValue([]);\n container.registerInstance(GetDescendantFoldersUseCase, {\n execute: getDescendantFolders\n });\n\n container.registerInstance(EventPublisher, { publish: vi.fn() });\n container.register(ContentEntriesCacheProvider).inSingletonScope();\n container.register(CmsModelContextImpl).inSingletonScope();\n container.resolve(CmsModelContext).setModel(MODEL);\n\n ListEntriesFeature.register(container);\n DeleteEntryFeature.register(container);\n PublishEntryFeature.register(container);\n UnpublishEntryFeature.register(container);\n MoveEntryFeature.register(container);\n DuplicateEntryFeature.register(container);\n UpdateRevisionDescriptionFeature.register(container);\n\n const listEntriesGateway = { execute: vi.fn() };\n const moveEntryGateway = { execute: vi.fn() };\n const deleteEntryGateway = { execute: vi.fn() };\n\n container.registerInstance(ListEntriesGateway, listEntriesGateway);\n container.registerInstance(MoveEntryGateway, moveEntryGateway);\n container.registerInstance(DeleteEntryGateway, deleteEntryGateway);\n const duplicateEntryGateway = { execute: vi.fn() };\n container.registerInstance(DuplicateEntryGateway, duplicateEntryGateway);\n const publishEntryGateway = { execute: vi.fn() };\n container.registerInstance(PublishEntryGateway, publishEntryGateway);\n container.registerInstance(UnpublishEntryGateway, { execute: vi.fn() });\n container.registerInstance(UpdateRevisionDescriptionGateway, { execute: vi.fn() });\n\n container.register(ContentEntriesPresenter).inSingletonScope();\n const presenter = container.resolve(Abstraction);\n\n return {\n presenter,\n listEntriesGateway,\n moveEntryGateway,\n deleteEntryGateway,\n duplicateEntryGateway,\n getDescendantFolders,\n foldersPresenter,\n publishEntryGateway,\n container\n };\n}\n\nasync function initPresenter(\n t: TestSetup,\n gatewayResponse: { data: CmsContentEntry[]; meta?: object }\n) {\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: gatewayResponse.data,\n meta: gatewayResponse.meta ?? {\n cursor: null,\n hasMoreItems: false,\n totalCount: gatewayResponse.data.length\n }\n });\n\n t.presenter.init();\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.pagination.loading).toBe(false);\n });\n}\n\ndescribe(\"ContentEntriesPresenter\", () => {\n let t: TestSetup;\n\n beforeEach(() => {\n t = setup();\n });\n\n describe(\"initial load\", () => {\n it(\"should show root entries after setModel\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n\n await initPresenter(t, { data: entries });\n\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\"entry-1\", \"entry-2\"]);\n });\n\n it(\"should send folderId=root in the gateway query\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.listEntriesGateway.execute).toHaveBeenCalledWith(\n expect.objectContaining({\n where: expect.objectContaining({\n wbyAco_location: { folderId: \"root\" }\n })\n })\n );\n });\n\n it(\"should set model after init\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.presenter.vm.model).toStrictEqual(MODEL);\n });\n });\n\n describe(\"folder navigation\", () => {\n it(\"should filter to folder entries when navigating to a subfolder\", async () => {\n const rootEntries = [createEntry(\"root-1\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n const folderEntries = [\n createEntry(\"folder-1\", \"folder-a\"),\n createEntry(\"folder-2\", \"folder-a\")\n ];\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: folderEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 2 }\n });\n\n t.foldersPresenter.selectFolder(\"folder-a\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n });\n\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\"folder-1\", \"folder-2\"]);\n });\n\n it(\"should show only root entries when navigating back to root\", async () => {\n const rootEntries = [createEntry(\"root-1\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n const folderEntries = [createEntry(\"folder-1\", \"folder-a\")];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: folderEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(\"folder-a\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"folder-1\");\n });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: rootEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(null);\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"root-1\");\n });\n });\n\n it(\"should not leak subfolder entries into root view\", async () => {\n const rootEntries = [createEntry(\"root-1\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [createEntry(\"folder-1\", \"folder-a\")],\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(\"folder-a\");\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: rootEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.foldersPresenter.selectFolder(null);\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"root-1\");\n });\n });\n });\n\n describe(\"search\", () => {\n it(\"should show only search results from API\", async () => {\n const rootEntries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n const searchResults = [createEntry(\"entry-1\", \"root\")];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: searchResults,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.list.actions.search.set(\"entry-1\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"entry-1\");\n });\n\n it(\"should include entries from subfolders when searching from root\", async () => {\n await initPresenter(t, { data: [] });\n\n const searchResults = [\n createEntry(\"root-1\", \"root\"),\n createEntry(\"folder-1\", \"folder-a\")\n ];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: searchResults,\n meta: { cursor: null, hasMoreItems: false, totalCount: 2 }\n });\n\n t.presenter.list.actions.search.set(\"test\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n });\n });\n\n it(\"should search with folderId_in containing all descendant folders when in a subfolder\", async () => {\n const folderEntries = [createEntry(\"folder-1\", \"folder-a\")];\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: folderEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.init({ initialFolderId: \"folder-a\" });\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.pagination.loading).toBe(false);\n });\n\n t.getDescendantFolders.mockReturnValue([\n { id: \"folder-a\" },\n { id: \"folder-a-1\" },\n { id: \"folder-a-2\" }\n ]);\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [\n createEntry(\"folder-1\", \"folder-a\"),\n createEntry(\"sub-1\", \"folder-a-1\"),\n createEntry(\"sub-2\", \"folder-a-2\")\n ],\n meta: { cursor: null, hasMoreItems: false, totalCount: 3 }\n });\n\n t.presenter.list.actions.search.set(\"test\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(3);\n });\n\n expect(t.getDescendantFolders).toHaveBeenCalledWith(\"folder-a\");\n\n const searchCall = t.listEntriesGateway.execute.mock.calls.at(-1) ?? [];\n expect(searchCall[0].where).toEqual(\n expect.objectContaining({\n wbyAco_location: {\n folderId_in: [\"folder-a\", \"folder-a-1\", \"folder-a-2\"]\n }\n })\n );\n });\n\n it(\"should restore folder view when clearing search\", async () => {\n const rootEntries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: rootEntries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [createEntry(\"entry-1\", \"root\")],\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.list.actions.search.set(\"entry-1\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: rootEntries,\n meta: { cursor: null, hasMoreItems: false, totalCount: 2 }\n });\n\n t.presenter.list.actions.search.clear();\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(2);\n });\n });\n });\n\n describe(\"status filter\", () => {\n it(\"should filter by status locally\", async () => {\n const entries = [\n createEntry(\"draft-1\", \"root\", {\n meta: {\n title: \"draft-1\",\n status: \"draft\",\n version: 1,\n locked: false\n }\n }),\n createEntry(\"published-1\", \"root\", {\n meta: {\n title: \"published-1\",\n status: \"published\",\n version: 1,\n locked: false\n }\n })\n ];\n await initPresenter(t, { data: entries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: entries.filter(e => (e.meta as { status: string }).status === \"published\"),\n meta: { cursor: null, hasMoreItems: false, totalCount: 1 }\n });\n\n t.presenter.list.actions.filter.set(\"status\", \"published\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"published-1\");\n });\n });\n });\n\n describe(\"move entry\", () => {\n it(\"should remove entry from current view after move\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: entries });\n\n t.moveEntryGateway.execute.mockResolvedValueOnce(true);\n\n await t.presenter.moveEntry(\"entry-1#0001\", \"folder-b\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"entry-2\");\n });\n });\n });\n\n describe(\"duplicate entry\", () => {\n it(\"should add the duplicated entry to the current view\", async () => {\n const entries = [\n createEntry(\"entry-2\", \"root\", { savedOn: \"2024-01-02T00:00:00.000Z\" }),\n createEntry(\"entry-1\", \"root\", { savedOn: \"2024-01-01T00:00:00.000Z\" })\n ];\n await initPresenter(t, { data: entries });\n\n const duplicate = createEntry(\"entry-3\", \"root\", {\n savedOn: \"2024-01-03T00:00:00.000Z\"\n });\n t.duplicateEntryGateway.execute.mockResolvedValueOnce(duplicate);\n\n const result = await t.presenter.duplicateEntry(entries[1]);\n\n expect(result).toEqual({ entry: duplicate });\n expect(t.duplicateEntryGateway.execute).toHaveBeenCalledWith({\n model: MODEL,\n revisionId: \"entry-1#0001\"\n });\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\n \"entry-3\",\n \"entry-2\",\n \"entry-1\"\n ]);\n });\n });\n\n it(\"should return the error when duplication fails\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\")];\n await initPresenter(t, { data: entries });\n\n const error = new Error(\"Not allowed.\");\n t.duplicateEntryGateway.execute.mockRejectedValueOnce(error);\n\n const result = await t.presenter.duplicateEntry(entries[0]);\n\n expect(result).toEqual({ error });\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n });\n });\n\n describe(\"delete entry\", () => {\n it(\"should remove entry from current view after delete\", async () => {\n const entries = [createEntry(\"entry-1\", \"root\"), createEntry(\"entry-2\", \"root\")];\n await initPresenter(t, { data: entries });\n\n t.deleteEntryGateway.execute.mockResolvedValueOnce(true);\n\n await t.presenter.deleteEntry(\"entry-1#0001\");\n\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.rows).toHaveLength(1);\n expect(t.presenter.list.vm.rows[0].entryId).toBe(\"entry-2\");\n });\n });\n });\n\n describe(\"vm\", () => {\n it(\"should set model on init\", () => {\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 }\n });\n t.presenter.init();\n expect(t.presenter.vm.model).toStrictEqual(MODEL);\n });\n\n it(\"should track selected entry\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.presenter.vm.showingEntry).toBe(false);\n\n t.presenter.selectEntry(\"some-id\");\n expect(t.presenter.vm.selectedEntryId).toBe(\"some-id\");\n expect(t.presenter.vm.showingEntry).toBe(true);\n\n t.presenter.deselectEntry();\n expect(t.presenter.vm.selectedEntryId).toBeNull();\n expect(t.presenter.vm.showingEntry).toBe(false);\n });\n\n it(\"should set selectedEntryId to 'new' on createEntry\", async () => {\n await initPresenter(t, { data: [] });\n\n t.presenter.createEntry();\n expect(t.presenter.vm.selectedEntryId).toBe(\"new\");\n });\n\n it(\"should show folders when no search or non-folder filters active\", async () => {\n await initPresenter(t, { data: [] });\n\n expect(t.presenter.vm.showFolders).toBe(true);\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 }\n });\n\n t.presenter.list.actions.search.set(\"test\");\n\n await vi.waitFor(() => {\n expect(t.presenter.vm.showFolders).toBe(false);\n });\n });\n });\n\n describe(\"publish entry\", () => {\n /**\n * Publishing is not a content modification: the API returns the entry with its\n * `savedOn` unchanged, so the entry must keep its position in a list sorted by `savedOn`.\n */\n const entries = [\n createEntry(\"entry-3\", \"root\", { savedOn: \"2024-01-03T00:00:00.000Z\" }),\n createEntry(\"entry-2\", \"root\", { savedOn: \"2024-01-02T00:00:00.000Z\" }),\n createEntry(\"entry-1\", \"root\", { savedOn: \"2024-01-01T00:00:00.000Z\" })\n ];\n\n const publish = async (entry: CmsContentEntry) => {\n t.publishEntryGateway.execute.mockResolvedValueOnce({\n ...entry,\n meta: { ...entry.meta, status: \"published\", locked: true }\n });\n await t.container\n .resolve(PublishEntryUseCase)\n .execute({ model: MODEL, revisionId: entry.id });\n };\n\n it(\"should keep a published entry in its position\", async () => {\n await initPresenter(t, { data: entries });\n\n await publish(entries[1]);\n\n const rows = t.presenter.list.vm.rows;\n expect(rows.map(r => r.entryId)).toEqual([\"entry-3\", \"entry-2\", \"entry-1\"]);\n expect((rows[1].meta as { status: string }).status).toBe(\"published\");\n });\n\n it(\"should keep a published entry in its position when sorted ascending\", async () => {\n await initPresenter(t, { data: entries });\n\n t.listEntriesGateway.execute.mockResolvedValueOnce({\n data: [...entries].reverse(),\n meta: { cursor: null, hasMoreItems: false, totalCount: entries.length }\n });\n t.presenter.list.actions.sort.set(\"savedOn\", \"ASC\");\n await vi.waitFor(() => {\n expect(t.presenter.list.vm.appliedQuery?.sort?.direction).toBe(\"ASC\");\n });\n\n await publish(entries[1]);\n\n expect(t.presenter.list.vm.rows.map(r => r.entryId)).toEqual([\n \"entry-1\",\n \"entry-2\",\n \"entry-3\"\n ]);\n });\n });\n});\n"],"names":["MODEL","createEntry","entryId","folderId","overrides","MockFolderTreePresenter","makeAutoObservable","setup","container","Container","ListPresenterFeature","foldersPresenter","FolderTreePresenter","Confirmation","vi","_name","_params","execute","undefined","getDescendantFolders","GetDescendantFoldersUseCase","EventPublisher","ContentEntriesCacheProvider","CmsModelContextImpl","CmsModelContext","ListEntriesFeature","DeleteEntryFeature","PublishEntryFeature","UnpublishEntryFeature","MoveEntryFeature","DuplicateEntryFeature","UpdateRevisionDescriptionFeature","listEntriesGateway","moveEntryGateway","deleteEntryGateway","ListEntriesGateway","MoveEntryGateway","DeleteEntryGateway","duplicateEntryGateway","DuplicateEntryGateway","publishEntryGateway","PublishEntryGateway","UnpublishEntryGateway","UpdateRevisionDescriptionGateway","ContentEntriesPresenter","presenter","Abstraction","initPresenter","t","gatewayResponse","expect","describe","beforeEach","it","entries","r","rootEntries","folderEntries","searchResults","searchCall","e","duplicate","result","error","Error","publish","entry","PublishEntryUseCase","rows"],"mappings":"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"}
|
|
@@ -14,6 +14,13 @@ export interface IContentEntriesViewModel {
|
|
|
14
14
|
showFolders: boolean;
|
|
15
15
|
childFolders: FolderDto[];
|
|
16
16
|
}
|
|
17
|
+
export type IDuplicateEntryResult = {
|
|
18
|
+
entry: CmsContentEntry;
|
|
19
|
+
error?: never;
|
|
20
|
+
} | {
|
|
21
|
+
entry?: never;
|
|
22
|
+
error: Error;
|
|
23
|
+
};
|
|
17
24
|
export interface IContentEntriesPresenter {
|
|
18
25
|
readonly vm: IContentEntriesViewModel;
|
|
19
26
|
readonly list: IListPresenter<CmsContentEntry>;
|
|
@@ -25,6 +32,10 @@ export interface IContentEntriesPresenter {
|
|
|
25
32
|
publishEntry(id: string): Promise<boolean>;
|
|
26
33
|
unpublishEntry(id: string): Promise<boolean>;
|
|
27
34
|
moveEntry(id: string, folderId: string): Promise<boolean>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolves to `false` when the user cancels the confirmation dialog.
|
|
37
|
+
*/
|
|
38
|
+
duplicateEntry(entry: CmsContentEntry): Promise<IDuplicateEntryResult | false>;
|
|
28
39
|
init(config?: IContentEntriesInitConfig): void;
|
|
29
40
|
dispose(): void;
|
|
30
41
|
}
|
|
@@ -33,4 +44,5 @@ export declare namespace ContentEntriesPresenter {
|
|
|
33
44
|
type Interface = IContentEntriesPresenter;
|
|
34
45
|
type ViewModel = IContentEntriesViewModel;
|
|
35
46
|
type InitConfig = IContentEntriesInitConfig;
|
|
47
|
+
type DuplicateEntryResult = IDuplicateEntryResult;
|
|
36
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/contentEntries/list/abstractions.js","sources":["../../../../src/presentation/contentEntries/list/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { IListPresenter } from \"@webiny/app-admin/presentation/listPresenter/abstractions.js\";\nimport type { IFolderTreePresenter } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\nimport type { CmsContentEntry, CmsModel } from \"~/types.js\";\n\nexport interface IContentEntriesInitConfig {\n initialFolderId?: string;\n initialSearch?: string;\n filterNames?: string[];\n}\n\nexport interface IContentEntriesViewModel {\n model: CmsModel;\n selectedEntryId: string | null;\n showingEntry: boolean;\n showFolders: boolean;\n childFolders: FolderDto[];\n}\n\nexport interface IContentEntriesPresenter {\n readonly vm: IContentEntriesViewModel;\n readonly list: IListPresenter<CmsContentEntry>;\n readonly folders: IFolderTreePresenter;\n\n selectEntry(id: string): void;\n deselectEntry(): void;\n createEntry(): void;\n deleteEntry(id: string): Promise<boolean>;\n publishEntry(id: string): Promise<boolean>;\n unpublishEntry(id: string): Promise<boolean>;\n moveEntry(id: string, folderId: string): Promise<boolean>;\n\n init(config?: IContentEntriesInitConfig): void;\n dispose(): void;\n}\n\nexport const ContentEntriesPresenter =\n createAbstraction<IContentEntriesPresenter>(\"ContentEntriesPresenter\");\n\nexport namespace ContentEntriesPresenter {\n export type Interface = IContentEntriesPresenter;\n export type ViewModel = IContentEntriesViewModel;\n export type InitConfig = IContentEntriesInitConfig;\n}\n"],"names":["ContentEntriesPresenter","createAbstraction"],"mappings":";
|
|
1
|
+
{"version":3,"file":"presentation/contentEntries/list/abstractions.js","sources":["../../../../src/presentation/contentEntries/list/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { IListPresenter } from \"@webiny/app-admin/presentation/listPresenter/abstractions.js\";\nimport type { IFolderTreePresenter } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport type { FolderDto } from \"@webiny/app-aco\";\nimport type { CmsContentEntry, CmsModel } from \"~/types.js\";\n\nexport interface IContentEntriesInitConfig {\n initialFolderId?: string;\n initialSearch?: string;\n filterNames?: string[];\n}\n\nexport interface IContentEntriesViewModel {\n model: CmsModel;\n selectedEntryId: string | null;\n showingEntry: boolean;\n showFolders: boolean;\n childFolders: FolderDto[];\n}\n\nexport type IDuplicateEntryResult =\n | { entry: CmsContentEntry; error?: never }\n | { entry?: never; error: Error };\n\nexport interface IContentEntriesPresenter {\n readonly vm: IContentEntriesViewModel;\n readonly list: IListPresenter<CmsContentEntry>;\n readonly folders: IFolderTreePresenter;\n\n selectEntry(id: string): void;\n deselectEntry(): void;\n createEntry(): void;\n deleteEntry(id: string): Promise<boolean>;\n publishEntry(id: string): Promise<boolean>;\n unpublishEntry(id: string): Promise<boolean>;\n moveEntry(id: string, folderId: string): Promise<boolean>;\n /**\n * Resolves to `false` when the user cancels the confirmation dialog.\n */\n duplicateEntry(entry: CmsContentEntry): Promise<IDuplicateEntryResult | false>;\n\n init(config?: IContentEntriesInitConfig): void;\n dispose(): void;\n}\n\nexport const ContentEntriesPresenter =\n createAbstraction<IContentEntriesPresenter>(\"ContentEntriesPresenter\");\n\nexport namespace ContentEntriesPresenter {\n export type Interface = IContentEntriesPresenter;\n export type ViewModel = IContentEntriesViewModel;\n export type InitConfig = IContentEntriesInitConfig;\n export type DuplicateEntryResult = IDuplicateEntryResult;\n}\n"],"names":["ContentEntriesPresenter","createAbstraction"],"mappings":";AA6CO,MAAMA,0BACTC,kBAA4C"}
|
|
@@ -4,6 +4,7 @@ import { GetSingletonEntryUseCase, UpdateSingletonEntryUseCase } from "../../../
|
|
|
4
4
|
import { CmsFormModelBuilder } from "../../../features/formModel/abstractions.js";
|
|
5
5
|
import { CmsModelContext } from "../../../features/contentEntry/abstractions.js";
|
|
6
6
|
import { SingleEntryPresenter } from "./abstractions.js";
|
|
7
|
+
import { toFormErrors } from "../form/toFormErrors.js";
|
|
7
8
|
class SingleEntryPresenterImpl {
|
|
8
9
|
constructor(formModelFactory, cmsFormModelBuilder, modelAccessor, getSingletonEntryUseCase, updateSingletonEntryUseCase){
|
|
9
10
|
this.formModelFactory = formModelFactory;
|
|
@@ -53,7 +54,8 @@ class SingleEntryPresenterImpl {
|
|
|
53
54
|
this.form.reset();
|
|
54
55
|
});
|
|
55
56
|
return true;
|
|
56
|
-
} catch
|
|
57
|
+
} catch (error) {
|
|
58
|
+
this.form.setErrors(toFormErrors(error, this.model));
|
|
57
59
|
return false;
|
|
58
60
|
} finally{
|
|
59
61
|
runInAction(()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/contentEntries/singleEntry/SingleEntryPresenter.js","sources":["../../../../src/presentation/contentEntries/singleEntry/SingleEntryPresenter.ts"],"sourcesContent":["import { computed, makeAutoObservable, runInAction } from \"mobx\";\nimport type { IFormModel } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport { FormModelFactory } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport type { CmsContentEntry } from \"~/types.js\";\nimport { GetSingletonEntryUseCase } from \"~/features/contentEntry/singletonEntry/abstractions.js\";\nimport { UpdateSingletonEntryUseCase } from \"~/features/contentEntry/singletonEntry/abstractions.js\";\nimport { CmsFormModelBuilder } from \"~/features/formModel/abstractions.js\";\nimport { CmsModelContext } from \"~/features/contentEntry/abstractions.js\";\nimport {\n SingleEntryPresenter as Abstraction,\n type ISingleEntryPresenter,\n type ISingleEntryViewModel\n} from \"./abstractions.js\";\n\nclass SingleEntryPresenterImpl implements ISingleEntryPresenter {\n private entry: CmsContentEntry | null = null;\n private form: IFormModel | null = null;\n private loading: string | null = null;\n\n constructor(\n private formModelFactory: FormModelFactory.Interface,\n private cmsFormModelBuilder: CmsFormModelBuilder.Interface,\n private modelAccessor: CmsModelContext.Interface,\n private getSingletonEntryUseCase: GetSingletonEntryUseCase.Interface,\n private updateSingletonEntryUseCase: UpdateSingletonEntryUseCase.Interface\n ) {\n makeAutoObservable<\n SingleEntryPresenterImpl,\n | \"formModelFactory\"\n | \"cmsFormModelBuilder\"\n | \"modelAccessor\"\n | \"getSingletonEntryUseCase\"\n | \"updateSingletonEntryUseCase\"\n >(this, {\n formModelFactory: false,\n cmsFormModelBuilder: false,\n modelAccessor: false,\n getSingletonEntryUseCase: false,\n updateSingletonEntryUseCase: false,\n vm: computed\n });\n }\n\n private get model() {\n return this.modelAccessor.getModel();\n }\n\n get vm(): ISingleEntryViewModel {\n return {\n loading: this.loading,\n entry: this.entry,\n form: this.form?.vm ?? null,\n canSave: this.form !== null,\n isDirty: this.form?.isDirty ?? false\n };\n }\n\n async save(): Promise<boolean> {\n if (!this.form) {\n return false;\n }\n\n const data = await this.form.submit();\n if (!data) {\n return false;\n }\n\n this.loading = \"Saving...\";\n\n try {\n const entry = await this.updateSingletonEntryUseCase.execute({\n model: this.model,\n data: {\n values: data\n }\n });\n\n runInAction(() => {\n this.entry = entry;\n this.form!.setData(entry.values);\n this.form!.reset();\n });\n\n return true;\n } catch {\n return false;\n } finally {\n runInAction(() => {\n this.loading = null;\n });\n }\n }\n\n async init(): Promise<void> {\n this.loading = \"Loading...\";\n\n try {\n const entry = await this.getSingletonEntryUseCase.execute({\n model: this.model\n });\n\n runInAction(() => {\n this.entry = entry;\n const formConfig = this.cmsFormModelBuilder.build(this.model);\n this.form = this.formModelFactory.create(formConfig);\n this.form.setData(entry.values);\n this.form.reset();\n });\n } finally {\n runInAction(() => {\n this.loading = null;\n });\n }\n }\n\n dispose(): void {\n this.form = null;\n this.entry = null;\n }\n}\n\nexport const SingleEntryPresenter = Abstraction.createImplementation({\n implementation: SingleEntryPresenterImpl,\n dependencies: [\n FormModelFactory,\n CmsFormModelBuilder,\n CmsModelContext,\n GetSingletonEntryUseCase,\n UpdateSingletonEntryUseCase\n ]\n});\n"],"names":["SingleEntryPresenterImpl","formModelFactory","cmsFormModelBuilder","modelAccessor","getSingletonEntryUseCase","updateSingletonEntryUseCase","makeAutoObservable","computed","data","entry","runInAction","formConfig","SingleEntryPresenter","Abstraction","FormModelFactory","CmsFormModelBuilder","CmsModelContext","GetSingletonEntryUseCase","UpdateSingletonEntryUseCase"],"mappings":"
|
|
1
|
+
{"version":3,"file":"presentation/contentEntries/singleEntry/SingleEntryPresenter.js","sources":["../../../../src/presentation/contentEntries/singleEntry/SingleEntryPresenter.ts"],"sourcesContent":["import { computed, makeAutoObservable, runInAction } from \"mobx\";\nimport type { IFormModel } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport { FormModelFactory } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport type { CmsContentEntry } from \"~/types.js\";\nimport { GetSingletonEntryUseCase } from \"~/features/contentEntry/singletonEntry/abstractions.js\";\nimport { UpdateSingletonEntryUseCase } from \"~/features/contentEntry/singletonEntry/abstractions.js\";\nimport { CmsFormModelBuilder } from \"~/features/formModel/abstractions.js\";\nimport { CmsModelContext } from \"~/features/contentEntry/abstractions.js\";\nimport {\n SingleEntryPresenter as Abstraction,\n type ISingleEntryPresenter,\n type ISingleEntryViewModel\n} from \"./abstractions.js\";\nimport { toFormErrors } from \"~/presentation/contentEntries/form/toFormErrors.js\";\n\nclass SingleEntryPresenterImpl implements ISingleEntryPresenter {\n private entry: CmsContentEntry | null = null;\n private form: IFormModel | null = null;\n private loading: string | null = null;\n\n constructor(\n private formModelFactory: FormModelFactory.Interface,\n private cmsFormModelBuilder: CmsFormModelBuilder.Interface,\n private modelAccessor: CmsModelContext.Interface,\n private getSingletonEntryUseCase: GetSingletonEntryUseCase.Interface,\n private updateSingletonEntryUseCase: UpdateSingletonEntryUseCase.Interface\n ) {\n makeAutoObservable<\n SingleEntryPresenterImpl,\n | \"formModelFactory\"\n | \"cmsFormModelBuilder\"\n | \"modelAccessor\"\n | \"getSingletonEntryUseCase\"\n | \"updateSingletonEntryUseCase\"\n >(this, {\n formModelFactory: false,\n cmsFormModelBuilder: false,\n modelAccessor: false,\n getSingletonEntryUseCase: false,\n updateSingletonEntryUseCase: false,\n vm: computed\n });\n }\n\n private get model() {\n return this.modelAccessor.getModel();\n }\n\n get vm(): ISingleEntryViewModel {\n return {\n loading: this.loading,\n entry: this.entry,\n form: this.form?.vm ?? null,\n canSave: this.form !== null,\n isDirty: this.form?.isDirty ?? false\n };\n }\n\n async save(): Promise<boolean> {\n if (!this.form) {\n return false;\n }\n\n const data = await this.form.submit();\n if (!data) {\n return false;\n }\n\n this.loading = \"Saving...\";\n\n try {\n const entry = await this.updateSingletonEntryUseCase.execute({\n model: this.model,\n data: {\n values: data\n }\n });\n\n runInAction(() => {\n this.entry = entry;\n this.form!.setData(entry.values);\n this.form!.reset();\n });\n\n return true;\n } catch (error) {\n this.form.setErrors(toFormErrors(error, this.model));\n return false;\n } finally {\n runInAction(() => {\n this.loading = null;\n });\n }\n }\n\n async init(): Promise<void> {\n this.loading = \"Loading...\";\n\n try {\n const entry = await this.getSingletonEntryUseCase.execute({\n model: this.model\n });\n\n runInAction(() => {\n this.entry = entry;\n const formConfig = this.cmsFormModelBuilder.build(this.model);\n this.form = this.formModelFactory.create(formConfig);\n this.form.setData(entry.values);\n this.form.reset();\n });\n } finally {\n runInAction(() => {\n this.loading = null;\n });\n }\n }\n\n dispose(): void {\n this.form = null;\n this.entry = null;\n }\n}\n\nexport const SingleEntryPresenter = Abstraction.createImplementation({\n implementation: SingleEntryPresenterImpl,\n dependencies: [\n FormModelFactory,\n CmsFormModelBuilder,\n CmsModelContext,\n GetSingletonEntryUseCase,\n UpdateSingletonEntryUseCase\n ]\n});\n"],"names":["SingleEntryPresenterImpl","formModelFactory","cmsFormModelBuilder","modelAccessor","getSingletonEntryUseCase","updateSingletonEntryUseCase","makeAutoObservable","computed","data","entry","runInAction","error","toFormErrors","formConfig","SingleEntryPresenter","Abstraction","FormModelFactory","CmsFormModelBuilder","CmsModelContext","GetSingletonEntryUseCase","UpdateSingletonEntryUseCase"],"mappings":";;;;;;;AAeA,MAAMA;IAKF,YACYC,gBAA4C,EAC5CC,mBAAkD,EAClDC,aAAwC,EACxCC,wBAA4D,EAC5DC,2BAAkE,CAC5E;aALUJ,gBAAgB,GAAhBA;aACAC,mBAAmB,GAAnBA;aACAC,aAAa,GAAbA;aACAC,wBAAwB,GAAxBA;aACAC,2BAA2B,GAA3BA;aATJ,KAAK,GAA2B;aAChC,IAAI,GAAsB;aAC1B,OAAO,GAAkB;QAS7BC,mBAOE,IAAI,EAAE;YACJ,kBAAkB;YAClB,qBAAqB;YACrB,eAAe;YACf,0BAA0B;YAC1B,6BAA6B;YAC7B,IAAIC;QACR;IACJ;IAEA,IAAY,QAAQ;QAChB,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ;IACtC;IAEA,IAAI,KAA4B;QAC5B,OAAO;YACH,SAAS,IAAI,CAAC,OAAO;YACrB,OAAO,IAAI,CAAC,KAAK;YACjB,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM;YACvB,SAAS,AAAc,SAAd,IAAI,CAAC,IAAI;YAClB,SAAS,IAAI,CAAC,IAAI,EAAE,WAAW;QACnC;IACJ;IAEA,MAAM,OAAyB;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,EACV,OAAO;QAGX,MAAMC,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;QACnC,IAAI,CAACA,MACD,OAAO;QAGX,IAAI,CAAC,OAAO,GAAG;QAEf,IAAI;YACA,MAAMC,QAAQ,MAAM,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC;gBACzD,OAAO,IAAI,CAAC,KAAK;gBACjB,MAAM;oBACF,QAAQD;gBACZ;YACJ;YAEAE,YAAY;gBACR,IAAI,CAAC,KAAK,GAAGD;gBACb,IAAI,CAAC,IAAI,CAAE,OAAO,CAACA,MAAM,MAAM;gBAC/B,IAAI,CAAC,IAAI,CAAE,KAAK;YACpB;YAEA,OAAO;QACX,EAAE,OAAOE,OAAO;YACZ,IAAI,CAAC,IAAI,CAAC,SAAS,CAACC,aAAaD,OAAO,IAAI,CAAC,KAAK;YAClD,OAAO;QACX,SAAU;YACND,YAAY;gBACR,IAAI,CAAC,OAAO,GAAG;YACnB;QACJ;IACJ;IAEA,MAAM,OAAsB;QACxB,IAAI,CAAC,OAAO,GAAG;QAEf,IAAI;YACA,MAAMD,QAAQ,MAAM,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;gBACtD,OAAO,IAAI,CAAC,KAAK;YACrB;YAEAC,YAAY;gBACR,IAAI,CAAC,KAAK,GAAGD;gBACb,MAAMI,aAAa,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;gBAC5D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAACA;gBACzC,IAAI,CAAC,IAAI,CAAC,OAAO,CAACJ,MAAM,MAAM;gBAC9B,IAAI,CAAC,IAAI,CAAC,KAAK;YACnB;QACJ,SAAU;YACNC,YAAY;gBACR,IAAI,CAAC,OAAO,GAAG;YACnB;QACJ;IACJ;IAEA,UAAgB;QACZ,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,KAAK,GAAG;IACjB;AACJ;AAEO,MAAMI,4CAAuBC,qBAAAA,oBAAgC,CAAC;IACjE,gBAAgBf;IAChB,cAAc;QACVgB;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
|