@webiny/app-website-builder 6.4.12-beta.2 → 6.4.12-beta.3

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.
Files changed (69) hide show
  1. package/Extension.js +2 -0
  2. package/Extension.js.map +1 -1
  3. package/domain/Page/Page.d.ts +2 -0
  4. package/domain/Page/Page.js +1 -0
  5. package/domain/Page/Page.js.map +1 -1
  6. package/domain/PageRevision/PageRevision.d.ts +11 -0
  7. package/domain/PageRevision/PageRevision.js +20 -0
  8. package/domain/PageRevision/PageRevision.js.map +1 -1
  9. package/features/pages/createPageRevisionFrom/CreatePageRevisionFrom.test.js +41 -1
  10. package/features/pages/createPageRevisionFrom/CreatePageRevisionFrom.test.js.map +1 -1
  11. package/features/pages/createPageRevisionFrom/CreatePageRevisionFromRepository.d.ts +3 -2
  12. package/features/pages/createPageRevisionFrom/CreatePageRevisionFromRepository.js +8 -2
  13. package/features/pages/createPageRevisionFrom/CreatePageRevisionFromRepository.js.map +1 -1
  14. package/features/pages/deletePageRevision/DeletePageRevision.test.d.ts +1 -0
  15. package/features/pages/deletePageRevision/DeletePageRevision.test.js +67 -0
  16. package/features/pages/deletePageRevision/DeletePageRevision.test.js.map +1 -0
  17. package/features/pages/deletePageRevision/DeletePageRevisionGateway.d.ts +1 -1
  18. package/features/pages/deletePageRevision/DeletePageRevisionGateway.js +2 -3
  19. package/features/pages/deletePageRevision/DeletePageRevisionGateway.js.map +1 -1
  20. package/features/pages/deletePageRevision/DeletePageRevisionRepository.d.ts +4 -2
  21. package/features/pages/deletePageRevision/DeletePageRevisionRepository.js +7 -3
  22. package/features/pages/deletePageRevision/DeletePageRevisionRepository.js.map +1 -1
  23. package/features/pages/deletePageRevision/DeletePageRevisionUseCase.js +1 -1
  24. package/features/pages/deletePageRevision/DeletePageRevisionUseCase.js.map +1 -1
  25. package/features/pages/deletePageRevision/abstractions.d.ts +2 -3
  26. package/features/pages/deletePageRevision/abstractions.js.map +1 -1
  27. package/features/pages/getPage/PageGatewayDto.d.ts +2 -0
  28. package/features/pages/publishPage/PublishPage.test.js +41 -1
  29. package/features/pages/publishPage/PublishPage.test.js.map +1 -1
  30. package/features/pages/publishPage/PublishPageRepository.d.ts +3 -2
  31. package/features/pages/publishPage/PublishPageRepository.js +15 -4
  32. package/features/pages/publishPage/PublishPageRepository.js.map +1 -1
  33. package/features/pages/shared/pageGraphQLFields.js +1 -0
  34. package/features/pages/shared/pageGraphQLFields.js.map +1 -1
  35. package/features/pages/unpublishPage/UnpublishPage.test.js +4 -1
  36. package/features/pages/unpublishPage/UnpublishPage.test.js.map +1 -1
  37. package/features/pages/unpublishPage/UnpublishPageRepository.d.ts +3 -2
  38. package/features/pages/unpublishPage/UnpublishPageRepository.js +12 -4
  39. package/features/pages/unpublishPage/UnpublishPageRepository.js.map +1 -1
  40. package/modules/pages/PageEditor/Revisions/RevisionListDrawer.js +4 -0
  41. package/modules/pages/PageEditor/Revisions/RevisionListDrawer.js.map +1 -1
  42. package/modules/pages/PageEditor/Revisions/RevisionListItem.d.ts +3 -3
  43. package/modules/pages/PageEditor/Revisions/RevisionListItem.js +9 -20
  44. package/modules/pages/PageEditor/Revisions/RevisionListItem.js.map +1 -1
  45. package/modules/pages/PageEditor/Revisions/RevisionsList.js +7 -19
  46. package/modules/pages/PageEditor/Revisions/RevisionsList.js.map +1 -1
  47. package/modules/pages/PageEditor/Revisions/useRevision.d.ts +1 -1
  48. package/modules/pages/PageEditor/Revisions/useRevision.js +84 -14
  49. package/modules/pages/PageEditor/Revisions/useRevision.js.map +1 -1
  50. package/modules/pages/PageEditor/Revisions/useRevisionList.d.ts +3 -0
  51. package/modules/pages/PageEditor/Revisions/useRevisionList.js +31 -0
  52. package/modules/pages/PageEditor/Revisions/useRevisionList.js.map +1 -0
  53. package/modules/pages/PageEditor/TopBar/RevisionsMenu.js +9 -21
  54. package/modules/pages/PageEditor/TopBar/RevisionsMenu.js.map +1 -1
  55. package/package.json +23 -23
  56. package/presentation/pages/RevisionList/RevisionListPresenter.d.ts +27 -0
  57. package/presentation/pages/RevisionList/RevisionListPresenter.js +73 -0
  58. package/presentation/pages/RevisionList/RevisionListPresenter.js.map +1 -0
  59. package/presentation/pages/RevisionList/RevisionListPresenter.test.d.ts +1 -0
  60. package/presentation/pages/RevisionList/RevisionListPresenter.test.js +219 -0
  61. package/presentation/pages/RevisionList/RevisionListPresenter.test.js.map +1 -0
  62. package/presentation/pages/RevisionList/abstractions.d.ts +34 -0
  63. package/presentation/pages/RevisionList/abstractions.js +5 -0
  64. package/presentation/pages/RevisionList/abstractions.js.map +1 -0
  65. package/presentation/pages/RevisionList/feature.d.ts +3 -0
  66. package/presentation/pages/RevisionList/feature.js +17 -0
  67. package/presentation/pages/RevisionList/feature.js.map +1 -0
  68. package/presentation/pages/RevisionList/index.d.ts +2 -0
  69. package/presentation/pages/RevisionList/index.js +1 -0
@@ -1,7 +1,6 @@
1
1
  import type { Page } from "../../../domain/Page/Page.js";
2
2
  export interface DeletePageRevisionParams {
3
3
  id: string;
4
- permanently: boolean;
5
4
  }
6
5
  export interface IDeletePageRevisionUseCase {
7
6
  execute(params: DeletePageRevisionParams): Promise<void>;
@@ -12,14 +11,14 @@ export declare namespace DeletePageRevisionUseCase {
12
11
  type Params = DeletePageRevisionParams;
13
12
  }
14
13
  export interface IDeletePageRevisionRepository {
15
- execute(page: Page, permanently: boolean): Promise<void>;
14
+ execute(page: Page): Promise<void>;
16
15
  }
17
16
  export declare const DeletePageRevisionRepository: import("@webiny/di").Abstraction<IDeletePageRevisionRepository>;
18
17
  export declare namespace DeletePageRevisionRepository {
19
18
  type Interface = IDeletePageRevisionRepository;
20
19
  }
21
20
  export interface IDeletePageRevisionGateway {
22
- execute(id: string, permanently: boolean): Promise<void>;
21
+ execute(id: string): Promise<void>;
23
22
  }
24
23
  export declare const DeletePageRevisionGateway: import("@webiny/di").Abstraction<IDeletePageRevisionGateway>;
25
24
  export declare namespace DeletePageRevisionGateway {
@@ -1 +1 @@
1
- {"version":3,"file":"features/pages/deletePageRevision/abstractions.js","sources":["../../../../src/features/pages/deletePageRevision/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { Page } from \"~/domain/Page/Page.js\";\n\n//\n// Params\n//\nexport interface DeletePageRevisionParams {\n id: string;\n permanently: boolean;\n}\n\n//\n// UseCase\n//\nexport interface IDeletePageRevisionUseCase {\n execute(params: DeletePageRevisionParams): Promise<void>;\n}\n\nexport const DeletePageRevisionUseCase = createAbstraction<IDeletePageRevisionUseCase>(\n \"WebsiteBuilder/DeletePageRevisionUseCase\"\n);\n\nexport namespace DeletePageRevisionUseCase {\n export type Interface = IDeletePageRevisionUseCase;\n export type Params = DeletePageRevisionParams;\n}\n\n//\n// Repository\n//\nexport interface IDeletePageRevisionRepository {\n execute(page: Page, permanently: boolean): Promise<void>;\n}\n\nexport const DeletePageRevisionRepository = createAbstraction<IDeletePageRevisionRepository>(\n \"WebsiteBuilder/DeletePageRevisionRepository\"\n);\n\nexport namespace DeletePageRevisionRepository {\n export type Interface = IDeletePageRevisionRepository;\n}\n\n//\n// Gateway\n//\nexport interface IDeletePageRevisionGateway {\n execute(id: string, permanently: boolean): Promise<void>;\n}\n\nexport const DeletePageRevisionGateway = createAbstraction<IDeletePageRevisionGateway>(\n \"WebsiteBuilder/DeletePageRevisionGateway\"\n);\n\nexport namespace DeletePageRevisionGateway {\n export type Interface = IDeletePageRevisionGateway;\n}\n"],"names":["DeletePageRevisionUseCase","createAbstraction","DeletePageRevisionRepository","DeletePageRevisionGateway"],"mappings":";AAkBO,MAAMA,4BAA4BC,kBACrC;AAeG,MAAMC,+BAA+BD,kBACxC;AAcG,MAAME,4BAA4BF,kBACrC"}
1
+ {"version":3,"file":"features/pages/deletePageRevision/abstractions.js","sources":["../../../../src/features/pages/deletePageRevision/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { Page } from \"~/domain/Page/Page.js\";\n\n//\n// Params\n//\nexport interface DeletePageRevisionParams {\n id: string;\n}\n\n//\n// UseCase\n//\nexport interface IDeletePageRevisionUseCase {\n execute(params: DeletePageRevisionParams): Promise<void>;\n}\n\nexport const DeletePageRevisionUseCase = createAbstraction<IDeletePageRevisionUseCase>(\n \"WebsiteBuilder/DeletePageRevisionUseCase\"\n);\n\nexport namespace DeletePageRevisionUseCase {\n export type Interface = IDeletePageRevisionUseCase;\n export type Params = DeletePageRevisionParams;\n}\n\n//\n// Repository\n//\nexport interface IDeletePageRevisionRepository {\n execute(page: Page): Promise<void>;\n}\n\nexport const DeletePageRevisionRepository = createAbstraction<IDeletePageRevisionRepository>(\n \"WebsiteBuilder/DeletePageRevisionRepository\"\n);\n\nexport namespace DeletePageRevisionRepository {\n export type Interface = IDeletePageRevisionRepository;\n}\n\n//\n// Gateway\n//\nexport interface IDeletePageRevisionGateway {\n execute(id: string): Promise<void>;\n}\n\nexport const DeletePageRevisionGateway = createAbstraction<IDeletePageRevisionGateway>(\n \"WebsiteBuilder/DeletePageRevisionGateway\"\n);\n\nexport namespace DeletePageRevisionGateway {\n export type Interface = IDeletePageRevisionGateway;\n}\n"],"names":["DeletePageRevisionUseCase","createAbstraction","DeletePageRevisionRepository","DeletePageRevisionGateway"],"mappings":";AAiBO,MAAMA,4BAA4BC,kBACrC;AAeG,MAAMC,+BAA+BD,kBACxC;AAcG,MAAME,4BAA4BF,kBACrC"}
@@ -4,6 +4,8 @@ export interface PageGatewayDto {
4
4
  id: string;
5
5
  entryId: string;
6
6
  status: WbStatus;
7
+ version: number;
8
+ locked: boolean;
7
9
  location: WbLocation;
8
10
  properties: Record<string, any>;
9
11
  metadata: Record<string, any>;
@@ -2,10 +2,11 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
2
2
  import { Container } from "@webiny/di";
3
3
  import { WbPageStatus } from "../../../constants.js";
4
4
  import { Page, fullPageCache, pageListCache } from "../../../domain/Page/index.js";
5
+ import { PageRevision, pageRevisionsCacheFactory } from "../../../domain/PageRevision/index.js";
5
6
  import { PublishPageGateway, PublishPageUseCase } from "./abstractions.js";
6
7
  import { PublishPageUseCase as external_PublishPageUseCase_js_PublishPageUseCase } from "./PublishPageUseCase.js";
7
8
  import { PublishPageRepository } from "./PublishPageRepository.js";
8
- import { FullPageCache, PageListCache } from "../shared/abstractions.js";
9
+ import { FullPageCache, PageListCache, PageRevisionsCache } from "../shared/abstractions.js";
9
10
  describe("PublishPage", ()=>{
10
11
  const gateway = {
11
12
  execute: vi.fn().mockResolvedValue({
@@ -90,6 +91,7 @@ describe("PublishPage", ()=>{
90
91
  const container = new Container();
91
92
  container.registerInstance(PageListCache, pagesCache);
92
93
  container.registerInstance(FullPageCache, fullPageCache);
94
+ container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());
93
95
  container.registerInstance(PublishPageGateway, gateway);
94
96
  container.register(PublishPageRepository).inSingletonScope();
95
97
  container.register(external_PublishPageUseCase_js_PublishPageUseCase);
@@ -124,6 +126,7 @@ describe("PublishPage", ()=>{
124
126
  const container = new Container();
125
127
  container.registerInstance(PageListCache, pagesCache);
126
128
  container.registerInstance(FullPageCache, fullPageCache);
129
+ container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());
127
130
  container.registerInstance(PublishPageGateway, gateway);
128
131
  container.register(PublishPageRepository).inSingletonScope();
129
132
  container.register(external_PublishPageUseCase_js_PublishPageUseCase);
@@ -136,6 +139,43 @@ describe("PublishPage", ()=>{
136
139
  expect(publishedItem?.id).toEqual("page-1#0001");
137
140
  expect(publishedItem?.status).toEqual(WbPageStatus.Draft);
138
141
  });
142
+ it("should publish the revision and unpublish the previously published one", async ()=>{
143
+ const revisionsCache = pageRevisionsCacheFactory.getCache();
144
+ revisionsCache.clear();
145
+ const makeRevision = (id, version, status)=>PageRevision.create({
146
+ id,
147
+ entryId: "page-1",
148
+ version,
149
+ status,
150
+ savedOn: "2026-09-21T00:00:00.000Z",
151
+ title: "Page 1",
152
+ locked: false,
153
+ createdBy: {
154
+ id: "admin",
155
+ displayName: "Admin",
156
+ type: "admin"
157
+ },
158
+ createdOn: "2026-09-21T00:00:00.000Z",
159
+ revisionDescription: void 0
160
+ });
161
+ revisionsCache.addItems([
162
+ makeRevision("page-1#0001", 1, WbPageStatus.Draft),
163
+ makeRevision("page-1#0002", 2, WbPageStatus.Published)
164
+ ]);
165
+ const container = new Container();
166
+ container.registerInstance(PageListCache, pagesCache);
167
+ container.registerInstance(FullPageCache, fullPageCache);
168
+ container.registerInstance(PageRevisionsCache, revisionsCache);
169
+ container.registerInstance(PublishPageGateway, gateway);
170
+ container.register(PublishPageRepository).inSingletonScope();
171
+ container.register(external_PublishPageUseCase_js_PublishPageUseCase);
172
+ const publishPage = container.resolve(PublishPageUseCase);
173
+ await publishPage.execute({
174
+ id: "page-1#0001"
175
+ });
176
+ expect(revisionsCache.getItem((r)=>"page-1#0001" === r.id)?.status).toEqual(WbPageStatus.Published);
177
+ expect(revisionsCache.getItem((r)=>"page-1#0002" === r.id)?.status).toEqual(WbPageStatus.Unpublished);
178
+ });
139
179
  });
140
180
 
141
181
  //# sourceMappingURL=PublishPage.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"features/pages/publishPage/PublishPage.test.js","sources":["../../../../src/features/pages/publishPage/PublishPage.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { WbPageStatus } from \"~/constants.js\";\nimport { Page, pageListCache, fullPageCache } from \"~/domain/Page/index.js\";\nimport {\n PublishPageUseCase as UseCaseAbstraction,\n PublishPageGateway as GatewayAbstraction\n} from \"./abstractions.js\";\nimport { PublishPageUseCase } from \"./PublishPageUseCase.js\";\nimport { PublishPageRepository } from \"./PublishPageRepository.js\";\nimport { PageListCache, FullPageCache } from \"~/features/pages/shared/abstractions.js\";\n\ndescribe(\"PublishPage\", () => {\n const gateway = {\n execute: vi.fn().mockResolvedValue({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Published,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n };\n\n const pagesCache = pageListCache;\n const detailsCache = fullPageCache;\n\n beforeEach(() => {\n vi.clearAllMocks();\n pagesCache.clear();\n detailsCache.clear();\n pagesCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Draft,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n }\n })\n ]);\n detailsCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Draft,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n ]);\n });\n\n it(\"should be able to publish a page\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, fullPageCache);\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(PublishPageRepository).inSingletonScope();\n container.register(PublishPageUseCase);\n\n const publishPage = container.resolve(UseCaseAbstraction);\n\n expect(pagesCache.hasItems()).toBeTrue();\n const item = pagesCache.getItem(page => page.id === \"page-1#0001\");\n expect(item?.id).toEqual(\"page-1#0001\");\n\n await publishPage.execute({\n id: \"page-1#0001\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n expect(gateway.execute).toHaveBeenLastCalledWith(\"page-1#0001\");\n\n expect(pagesCache.hasItems()).toBeTrue();\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Published);\n\n // Details cache is updated with the full gateway result including document fields\n const detailItem = detailsCache.getItem(page => page.entryId === \"page-1\");\n expect(detailItem).toBeDefined();\n expect(detailItem?.id).toEqual(\"page-1#0001\");\n expect(detailItem?.status).toEqual(WbPageStatus.Published);\n expect(detailItem?.elements).toMatchObject({ element1: \"element\" });\n expect(detailItem?.bindings).toMatchObject({ data: \"any-data\" });\n expect(detailItem?.extensions).toMatchObject({ ext1: \"ext-data\" });\n });\n\n it(\"should not publish a page if id is missing\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, fullPageCache);\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(PublishPageRepository).inSingletonScope();\n container.register(PublishPageUseCase);\n\n const publishPage = container.resolve(UseCaseAbstraction);\n\n await publishPage.execute({\n id: \"\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Draft);\n });\n});\n"],"names":["describe","gateway","vi","WbPageStatus","pagesCache","pageListCache","detailsCache","fullPageCache","beforeEach","Page","it","container","Container","PageListCache","FullPageCache","GatewayAbstraction","PublishPageRepository","PublishPageUseCase","publishPage","UseCaseAbstraction","expect","item","page","publishedItem","detailItem"],"mappings":"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"}
1
+ {"version":3,"file":"features/pages/publishPage/PublishPage.test.js","sources":["../../../../src/features/pages/publishPage/PublishPage.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { WbPageStatus, type WbStatus } from \"~/constants.js\";\nimport { Page, pageListCache, fullPageCache } from \"~/domain/Page/index.js\";\nimport { PageRevision, pageRevisionsCacheFactory } from \"~/domain/PageRevision/index.js\";\nimport {\n PublishPageUseCase as UseCaseAbstraction,\n PublishPageGateway as GatewayAbstraction\n} from \"./abstractions.js\";\nimport { PublishPageUseCase } from \"./PublishPageUseCase.js\";\nimport { PublishPageRepository } from \"./PublishPageRepository.js\";\nimport {\n PageListCache,\n FullPageCache,\n PageRevisionsCache\n} from \"~/features/pages/shared/abstractions.js\";\n\ndescribe(\"PublishPage\", () => {\n const gateway = {\n execute: vi.fn().mockResolvedValue({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Published,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n };\n\n const pagesCache = pageListCache;\n const detailsCache = fullPageCache;\n\n beforeEach(() => {\n vi.clearAllMocks();\n pagesCache.clear();\n detailsCache.clear();\n pagesCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Draft,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n }\n })\n ]);\n detailsCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Draft,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n ]);\n });\n\n it(\"should be able to publish a page\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, fullPageCache);\n container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(PublishPageRepository).inSingletonScope();\n container.register(PublishPageUseCase);\n\n const publishPage = container.resolve(UseCaseAbstraction);\n\n expect(pagesCache.hasItems()).toBeTrue();\n const item = pagesCache.getItem(page => page.id === \"page-1#0001\");\n expect(item?.id).toEqual(\"page-1#0001\");\n\n await publishPage.execute({\n id: \"page-1#0001\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n expect(gateway.execute).toHaveBeenLastCalledWith(\"page-1#0001\");\n\n expect(pagesCache.hasItems()).toBeTrue();\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Published);\n\n // Details cache is updated with the full gateway result including document fields\n const detailItem = detailsCache.getItem(page => page.entryId === \"page-1\");\n expect(detailItem).toBeDefined();\n expect(detailItem?.id).toEqual(\"page-1#0001\");\n expect(detailItem?.status).toEqual(WbPageStatus.Published);\n expect(detailItem?.elements).toMatchObject({ element1: \"element\" });\n expect(detailItem?.bindings).toMatchObject({ data: \"any-data\" });\n expect(detailItem?.extensions).toMatchObject({ ext1: \"ext-data\" });\n });\n\n it(\"should not publish a page if id is missing\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, fullPageCache);\n container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(PublishPageRepository).inSingletonScope();\n container.register(PublishPageUseCase);\n\n const publishPage = container.resolve(UseCaseAbstraction);\n\n await publishPage.execute({\n id: \"\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Draft);\n });\n\n it(\"should publish the revision and unpublish the previously published one\", async () => {\n const revisionsCache = pageRevisionsCacheFactory.getCache();\n revisionsCache.clear();\n\n const makeRevision = (id: string, version: number, status: WbStatus) =>\n PageRevision.create({\n id,\n entryId: \"page-1\",\n version,\n status,\n savedOn: \"2026-09-21T00:00:00.000Z\",\n title: \"Page 1\",\n locked: false,\n createdBy: { id: \"admin\", displayName: \"Admin\", type: \"admin\" },\n createdOn: \"2026-09-21T00:00:00.000Z\",\n revisionDescription: undefined\n });\n\n revisionsCache.addItems([\n makeRevision(\"page-1#0001\", 1, WbPageStatus.Draft),\n makeRevision(\"page-1#0002\", 2, WbPageStatus.Published)\n ]);\n\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, fullPageCache);\n container.registerInstance(PageRevisionsCache, revisionsCache);\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(PublishPageRepository).inSingletonScope();\n container.register(PublishPageUseCase);\n\n const publishPage = container.resolve(UseCaseAbstraction);\n\n await publishPage.execute({ id: \"page-1#0001\" });\n\n expect(revisionsCache.getItem(r => r.id === \"page-1#0001\")?.status).toEqual(\n WbPageStatus.Published\n );\n expect(revisionsCache.getItem(r => r.id === \"page-1#0002\")?.status).toEqual(\n WbPageStatus.Unpublished\n );\n });\n});\n"],"names":["describe","gateway","vi","WbPageStatus","pagesCache","pageListCache","detailsCache","fullPageCache","beforeEach","Page","it","container","Container","PageListCache","FullPageCache","PageRevisionsCache","pageRevisionsCacheFactory","GatewayAbstraction","PublishPageRepository","PublishPageUseCase","publishPage","UseCaseAbstraction","expect","item","page","publishedItem","detailItem","revisionsCache","makeRevision","id","version","status","PageRevision","undefined","r"],"mappings":"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"}
@@ -1,11 +1,12 @@
1
1
  import { PublishPageRepository as RepositoryAbstraction, PublishPageGateway } from "./abstractions.js";
2
2
  import { Page } from "../../../domain/Page/Page.js";
3
- import { PageListCache, FullPageCache } from "../../../features/pages/shared/abstractions.js";
3
+ import { PageListCache, FullPageCache, PageRevisionsCache } from "../../../features/pages/shared/abstractions.js";
4
4
  declare class PublishPageRepositoryImpl implements RepositoryAbstraction.Interface {
5
5
  private listCache;
6
6
  private detailsCache;
7
+ private revisionsCache;
7
8
  private gateway;
8
- constructor(listCache: PageListCache.Interface, detailsCache: FullPageCache.Interface, gateway: PublishPageGateway.Interface);
9
+ constructor(listCache: PageListCache.Interface, detailsCache: FullPageCache.Interface, revisionsCache: PageRevisionsCache.Interface, gateway: PublishPageGateway.Interface);
9
10
  execute(page: Page): Promise<void>;
10
11
  }
11
12
  export declare const PublishPageRepository: typeof PublishPageRepositoryImpl & {
@@ -1,22 +1,32 @@
1
1
  import { PublishPageGateway, PublishPageRepository } from "./abstractions.js";
2
2
  import { Page } from "../../../domain/Page/Page.js";
3
- import { FullPageCache, PageListCache } from "../shared/abstractions.js";
3
+ import { PageRevision } from "../../../domain/PageRevision/PageRevision.js";
4
+ import { WbPageStatus } from "../../../constants.js";
5
+ import { FullPageCache, PageListCache, PageRevisionsCache } from "../shared/abstractions.js";
4
6
  class PublishPageRepositoryImpl {
5
- constructor(listCache, detailsCache, gateway){
7
+ constructor(listCache, detailsCache, revisionsCache, gateway){
6
8
  this.listCache = listCache;
7
9
  this.detailsCache = detailsCache;
10
+ this.revisionsCache = revisionsCache;
8
11
  this.gateway = gateway;
9
12
  }
10
13
  async execute(page) {
11
14
  const result = await this.gateway.execute(page.id);
15
+ const publishedPage = Page.create(result);
12
16
  this.listCache.updateItems((existingPage)=>{
13
- if (existingPage.id === page.id) return Page.create(result);
17
+ if (existingPage.id === page.id) return publishedPage;
14
18
  return existingPage;
15
19
  });
16
20
  this.detailsCache.updateItems((existingPage)=>{
17
- if (existingPage.id === page.id) return Page.create(result);
21
+ if (existingPage.id === page.id) return publishedPage;
18
22
  return existingPage;
19
23
  });
24
+ const publishedRevision = PageRevision.createFromPage(publishedPage);
25
+ this.revisionsCache.updateItems((revision)=>{
26
+ if (revision.id === publishedPage.id) return publishedRevision;
27
+ if (revision.entryId === publishedPage.entryId && revision.status === WbPageStatus.Published) return revision.withStatus(WbPageStatus.Unpublished);
28
+ return revision;
29
+ });
20
30
  }
21
31
  }
22
32
  const PublishPageRepository_PublishPageRepository = PublishPageRepository.createImplementation({
@@ -24,6 +34,7 @@ const PublishPageRepository_PublishPageRepository = PublishPageRepository.create
24
34
  dependencies: [
25
35
  PageListCache,
26
36
  FullPageCache,
37
+ PageRevisionsCache,
27
38
  PublishPageGateway
28
39
  ]
29
40
  });
@@ -1 +1 @@
1
- {"version":3,"file":"features/pages/publishPage/PublishPageRepository.js","sources":["../../../../src/features/pages/publishPage/PublishPageRepository.ts"],"sourcesContent":["import {\n PublishPageRepository as RepositoryAbstraction,\n PublishPageGateway\n} from \"./abstractions.js\";\nimport { Page } from \"~/domain/Page/Page.js\";\nimport { PageListCache, FullPageCache } from \"~/features/pages/shared/abstractions.js\";\n\nclass PublishPageRepositoryImpl implements RepositoryAbstraction.Interface {\n constructor(\n private listCache: PageListCache.Interface,\n private detailsCache: FullPageCache.Interface,\n private gateway: PublishPageGateway.Interface\n ) {}\n\n async execute(page: Page) {\n const result = await this.gateway.execute(page.id);\n\n this.listCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return Page.create(result);\n }\n return existingPage;\n });\n\n this.detailsCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return Page.create(result);\n }\n return existingPage;\n });\n }\n}\n\nexport const PublishPageRepository = RepositoryAbstraction.createImplementation({\n implementation: PublishPageRepositoryImpl,\n dependencies: [PageListCache, FullPageCache, PublishPageGateway]\n});\n"],"names":["PublishPageRepositoryImpl","listCache","detailsCache","gateway","page","result","existingPage","Page","PublishPageRepository","RepositoryAbstraction","PageListCache","FullPageCache","PublishPageGateway"],"mappings":";;;AAOA,MAAMA;IACF,YACYC,SAAkC,EAClCC,YAAqC,EACrCC,OAAqC,CAC/C;aAHUF,SAAS,GAATA;aACAC,YAAY,GAAZA;aACAC,OAAO,GAAPA;IACT;IAEH,MAAM,QAAQC,IAAU,EAAE;QACtB,MAAMC,SAAS,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAACD,KAAK,EAAE;QAEjD,IAAI,CAAC,SAAS,CAAC,WAAW,CAACE,CAAAA;YACvB,IAAIA,aAAa,EAAE,KAAKF,KAAK,EAAE,EAC3B,OAAOG,KAAK,MAAM,CAACF;YAEvB,OAAOC;QACX;QAEA,IAAI,CAAC,YAAY,CAAC,WAAW,CAACA,CAAAA;YAC1B,IAAIA,aAAa,EAAE,KAAKF,KAAK,EAAE,EAC3B,OAAOG,KAAK,MAAM,CAACF;YAEvB,OAAOC;QACX;IACJ;AACJ;AAEO,MAAME,8CAAwBC,sBAAAA,oBAA0C,CAAC;IAC5E,gBAAgBT;IAChB,cAAc;QAACU;QAAeC;QAAeC;KAAmB;AACpE"}
1
+ {"version":3,"file":"features/pages/publishPage/PublishPageRepository.js","sources":["../../../../src/features/pages/publishPage/PublishPageRepository.ts"],"sourcesContent":["import {\n PublishPageRepository as RepositoryAbstraction,\n PublishPageGateway\n} from \"./abstractions.js\";\nimport { Page } from \"~/domain/Page/Page.js\";\nimport { PageRevision } from \"~/domain/PageRevision/PageRevision.js\";\nimport { WbPageStatus } from \"~/constants.js\";\nimport {\n PageListCache,\n FullPageCache,\n PageRevisionsCache\n} from \"~/features/pages/shared/abstractions.js\";\n\nclass PublishPageRepositoryImpl implements RepositoryAbstraction.Interface {\n constructor(\n private listCache: PageListCache.Interface,\n private detailsCache: FullPageCache.Interface,\n private revisionsCache: PageRevisionsCache.Interface,\n private gateway: PublishPageGateway.Interface\n ) {}\n\n async execute(page: Page) {\n const result = await this.gateway.execute(page.id);\n const publishedPage = Page.create(result);\n\n this.listCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return publishedPage;\n }\n return existingPage;\n });\n\n this.detailsCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return publishedPage;\n }\n return existingPage;\n });\n\n const publishedRevision = PageRevision.createFromPage(publishedPage);\n\n this.revisionsCache.updateItems(revision => {\n if (revision.id === publishedPage.id) {\n return publishedRevision;\n }\n\n // Only one revision of an entry can be published, so the previous one is now unpublished.\n if (\n revision.entryId === publishedPage.entryId &&\n revision.status === WbPageStatus.Published\n ) {\n return revision.withStatus(WbPageStatus.Unpublished);\n }\n\n return revision;\n });\n }\n}\n\nexport const PublishPageRepository = RepositoryAbstraction.createImplementation({\n implementation: PublishPageRepositoryImpl,\n dependencies: [PageListCache, FullPageCache, PageRevisionsCache, PublishPageGateway]\n});\n"],"names":["PublishPageRepositoryImpl","listCache","detailsCache","revisionsCache","gateway","page","result","publishedPage","Page","existingPage","publishedRevision","PageRevision","revision","WbPageStatus","PublishPageRepository","RepositoryAbstraction","PageListCache","FullPageCache","PageRevisionsCache","PublishPageGateway"],"mappings":";;;;;AAaA,MAAMA;IACF,YACYC,SAAkC,EAClCC,YAAqC,EACrCC,cAA4C,EAC5CC,OAAqC,CAC/C;aAJUH,SAAS,GAATA;aACAC,YAAY,GAAZA;aACAC,cAAc,GAAdA;aACAC,OAAO,GAAPA;IACT;IAEH,MAAM,QAAQC,IAAU,EAAE;QACtB,MAAMC,SAAS,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAACD,KAAK,EAAE;QACjD,MAAME,gBAAgBC,KAAK,MAAM,CAACF;QAElC,IAAI,CAAC,SAAS,CAAC,WAAW,CAACG,CAAAA;YACvB,IAAIA,aAAa,EAAE,KAAKJ,KAAK,EAAE,EAC3B,OAAOE;YAEX,OAAOE;QACX;QAEA,IAAI,CAAC,YAAY,CAAC,WAAW,CAACA,CAAAA;YAC1B,IAAIA,aAAa,EAAE,KAAKJ,KAAK,EAAE,EAC3B,OAAOE;YAEX,OAAOE;QACX;QAEA,MAAMC,oBAAoBC,aAAa,cAAc,CAACJ;QAEtD,IAAI,CAAC,cAAc,CAAC,WAAW,CAACK,CAAAA;YAC5B,IAAIA,SAAS,EAAE,KAAKL,cAAc,EAAE,EAChC,OAAOG;YAIX,IACIE,SAAS,OAAO,KAAKL,cAAc,OAAO,IAC1CK,SAAS,MAAM,KAAKC,aAAa,SAAS,EAE1C,OAAOD,SAAS,UAAU,CAACC,aAAa,WAAW;YAGvD,OAAOD;QACX;IACJ;AACJ;AAEO,MAAME,8CAAwBC,sBAAAA,oBAA0C,CAAC;IAC5E,gBAAgBf;IAChB,cAAc;QAACgB;QAAeC;QAAeC;QAAoBC;KAAmB;AACxF"}
@@ -3,6 +3,7 @@ const getPageGraphQLBaseFields = ()=>[
3
3
  "entryId",
4
4
  "status",
5
5
  "version",
6
+ "locked",
6
7
  `location {
7
8
  folderId
8
9
  }`,
@@ -1 +1 @@
1
- {"version":3,"file":"features/pages/shared/pageGraphQLFields.js","sources":["../../../../src/features/pages/shared/pageGraphQLFields.ts"],"sourcesContent":["export const getPageGraphQLBaseFields = (): string[] => {\n return [\n `id`,\n `entryId`,\n `status`,\n `version`,\n `location {\n folderId\n }`,\n `createdOn`,\n `createdBy {\n id\n displayName\n }`,\n `savedOn`,\n `savedBy {\n id\n displayName\n }`,\n `modifiedOn`,\n `modifiedBy {\n id\n displayName\n }`,\n `live {\n version\n }\n `,\n `revisionDescription`\n ];\n};\n\nexport const getPageGraphQLFields = (extraFields: string[]): string[] => {\n return [...getPageGraphQLBaseFields(), ...extraFields];\n};\n"],"names":["getPageGraphQLBaseFields","getPageGraphQLFields","extraFields"],"mappings":"AAAO,MAAMA,2BAA2B,IAC7B;QACH;QACA;QACA;QACA;QACA,CAAC;;SAEA,CAAC;QACF;QACA,CAAC;;;SAGA,CAAC;QACF;QACA,CAAC;;;SAGA,CAAC;QACF;QACA,CAAC;;;SAGA,CAAC;QACF,CAAC;;;QAGD,CAAC;QACD;KACH;AAGE,MAAMC,uBAAuB,CAACC,cAC1B;WAAIF;WAA+BE;KAAY"}
1
+ {"version":3,"file":"features/pages/shared/pageGraphQLFields.js","sources":["../../../../src/features/pages/shared/pageGraphQLFields.ts"],"sourcesContent":["export const getPageGraphQLBaseFields = (): string[] => {\n return [\n `id`,\n `entryId`,\n `status`,\n `version`,\n `locked`,\n `location {\n folderId\n }`,\n `createdOn`,\n `createdBy {\n id\n displayName\n }`,\n `savedOn`,\n `savedBy {\n id\n displayName\n }`,\n `modifiedOn`,\n `modifiedBy {\n id\n displayName\n }`,\n `live {\n version\n }\n `,\n `revisionDescription`\n ];\n};\n\nexport const getPageGraphQLFields = (extraFields: string[]): string[] => {\n return [...getPageGraphQLBaseFields(), ...extraFields];\n};\n"],"names":["getPageGraphQLBaseFields","getPageGraphQLFields","extraFields"],"mappings":"AAAO,MAAMA,2BAA2B,IAC7B;QACH;QACA;QACA;QACA;QACA;QACA,CAAC;;SAEA,CAAC;QACF;QACA,CAAC;;;SAGA,CAAC;QACF;QACA,CAAC;;;SAGA,CAAC;QACF;QACA,CAAC;;;SAGA,CAAC;QACF,CAAC;;;QAGD,CAAC;QACD;KACH;AAGE,MAAMC,uBAAuB,CAACC,cAC1B;WAAIF;WAA+BE;KAAY"}
@@ -2,10 +2,11 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
2
2
  import { Container } from "@webiny/di";
3
3
  import { WbPageStatus } from "../../../constants.js";
4
4
  import { Page, fullPageCache, pageListCache } from "../../../domain/Page/index.js";
5
+ import { pageRevisionsCacheFactory } from "../../../domain/PageRevision/index.js";
5
6
  import { UnpublishPageGateway, UnpublishPageUseCase } from "./abstractions.js";
6
7
  import { UnpublishPageUseCase as external_UnpublishPageUseCase_js_UnpublishPageUseCase } from "./UnpublishPageUseCase.js";
7
8
  import { UnpublishPageRepository } from "./UnpublishPageRepository.js";
8
- import { FullPageCache, PageListCache } from "../shared/abstractions.js";
9
+ import { FullPageCache, PageListCache, PageRevisionsCache } from "../shared/abstractions.js";
9
10
  describe("UnpublishPage", ()=>{
10
11
  const gateway = {
11
12
  execute: vi.fn().mockResolvedValue({
@@ -84,6 +85,7 @@ describe("UnpublishPage", ()=>{
84
85
  const container = new Container();
85
86
  container.registerInstance(PageListCache, pagesCache);
86
87
  container.registerInstance(FullPageCache, detailsCache);
88
+ container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());
87
89
  container.registerInstance(UnpublishPageGateway, gateway);
88
90
  container.register(UnpublishPageRepository).inSingletonScope();
89
91
  container.register(external_UnpublishPageUseCase_js_UnpublishPageUseCase);
@@ -118,6 +120,7 @@ describe("UnpublishPage", ()=>{
118
120
  const container = new Container();
119
121
  container.registerInstance(PageListCache, pagesCache);
120
122
  container.registerInstance(FullPageCache, detailsCache);
123
+ container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());
121
124
  container.registerInstance(UnpublishPageGateway, gateway);
122
125
  container.register(UnpublishPageRepository).inSingletonScope();
123
126
  container.register(external_UnpublishPageUseCase_js_UnpublishPageUseCase);
@@ -1 +1 @@
1
- {"version":3,"file":"features/pages/unpublishPage/UnpublishPage.test.js","sources":["../../../../src/features/pages/unpublishPage/UnpublishPage.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { WbPageStatus } from \"~/constants.js\";\nimport { Page, pageListCache, fullPageCache } from \"~/domain/Page/index.js\";\nimport {\n UnpublishPageUseCase as UseCaseAbstraction,\n UnpublishPageGateway as GatewayAbstraction\n} from \"./abstractions.js\";\nimport { UnpublishPageUseCase } from \"./UnpublishPageUseCase.js\";\nimport { UnpublishPageRepository } from \"./UnpublishPageRepository.js\";\nimport { PageListCache, FullPageCache } from \"~/features/pages/shared/abstractions.js\";\n\ndescribe(\"UnpublishPage\", () => {\n const gateway = {\n execute: vi.fn().mockResolvedValue({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Unpublished,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n };\n\n const pagesCache = pageListCache;\n const detailsCache = fullPageCache;\n\n beforeEach(() => {\n vi.clearAllMocks();\n pagesCache.clear();\n detailsCache.clear();\n pagesCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Published,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n }\n })\n ]);\n detailsCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Published,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n ]);\n });\n\n it(\"should be able to unpublish a page\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, detailsCache);\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(UnpublishPageRepository).inSingletonScope();\n container.register(UnpublishPageUseCase);\n\n const unpublishPage = container.resolve(UseCaseAbstraction);\n\n expect(pagesCache.hasItems()).toBeTrue();\n const item = pagesCache.getItem(page => page.id === \"page-1#0001\");\n expect(item?.id).toEqual(\"page-1#0001\");\n\n await unpublishPage.execute({\n id: \"page-1#0001\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n expect(gateway.execute).toHaveBeenLastCalledWith(\"page-1#0001\");\n\n expect(pagesCache.hasItems()).toBeTrue();\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Unpublished);\n\n // Details cache is updated with the full gateway result including document fields\n const detailItem = detailsCache.getItem(page => page.entryId === \"page-1\");\n expect(detailItem).toBeDefined();\n expect(detailItem?.id).toEqual(\"page-1#0001\");\n expect(detailItem?.status).toEqual(WbPageStatus.Unpublished);\n expect(detailItem?.elements).toMatchObject({ element1: \"element\" });\n expect(detailItem?.bindings).toMatchObject({ data: \"any-data\" });\n expect(detailItem?.extensions).toMatchObject({ ext1: \"ext-data\" });\n });\n\n it(\"should not unpublish a page if id is missing\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, detailsCache);\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(UnpublishPageRepository).inSingletonScope();\n container.register(UnpublishPageUseCase);\n\n const unpublishPage = container.resolve(UseCaseAbstraction);\n\n await unpublishPage.execute({\n id: \"\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Published);\n });\n});\n"],"names":["describe","gateway","vi","WbPageStatus","pagesCache","pageListCache","detailsCache","fullPageCache","beforeEach","Page","it","container","Container","PageListCache","FullPageCache","GatewayAbstraction","UnpublishPageRepository","UnpublishPageUseCase","unpublishPage","UseCaseAbstraction","expect","item","page","publishedItem","detailItem"],"mappings":"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"}
1
+ {"version":3,"file":"features/pages/unpublishPage/UnpublishPage.test.js","sources":["../../../../src/features/pages/unpublishPage/UnpublishPage.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { WbPageStatus } from \"~/constants.js\";\nimport { Page, pageListCache, fullPageCache } from \"~/domain/Page/index.js\";\nimport { pageRevisionsCacheFactory } from \"~/domain/PageRevision/index.js\";\nimport {\n UnpublishPageUseCase as UseCaseAbstraction,\n UnpublishPageGateway as GatewayAbstraction\n} from \"./abstractions.js\";\nimport { UnpublishPageUseCase } from \"./UnpublishPageUseCase.js\";\nimport { UnpublishPageRepository } from \"./UnpublishPageRepository.js\";\nimport {\n PageListCache,\n FullPageCache,\n PageRevisionsCache\n} from \"~/features/pages/shared/abstractions.js\";\n\ndescribe(\"UnpublishPage\", () => {\n const gateway = {\n execute: vi.fn().mockResolvedValue({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Unpublished,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n metadata: {\n metadata: \"data-1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n };\n\n const pagesCache = pageListCache;\n const detailsCache = fullPageCache;\n\n beforeEach(() => {\n vi.clearAllMocks();\n pagesCache.clear();\n detailsCache.clear();\n pagesCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Published,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n }\n })\n ]);\n detailsCache.addItems([\n Page.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n status: WbPageStatus.Published,\n location: {\n folderId: \"folder-1\"\n },\n properties: {\n title: \"Page 1\"\n },\n elements: {\n element1: \"element\"\n },\n bindings: {\n data: \"any-data\"\n },\n extensions: {\n ext1: \"ext-data\"\n }\n })\n ]);\n });\n\n it(\"should be able to unpublish a page\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, detailsCache);\n container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(UnpublishPageRepository).inSingletonScope();\n container.register(UnpublishPageUseCase);\n\n const unpublishPage = container.resolve(UseCaseAbstraction);\n\n expect(pagesCache.hasItems()).toBeTrue();\n const item = pagesCache.getItem(page => page.id === \"page-1#0001\");\n expect(item?.id).toEqual(\"page-1#0001\");\n\n await unpublishPage.execute({\n id: \"page-1#0001\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n expect(gateway.execute).toHaveBeenLastCalledWith(\"page-1#0001\");\n\n expect(pagesCache.hasItems()).toBeTrue();\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Unpublished);\n\n // Details cache is updated with the full gateway result including document fields\n const detailItem = detailsCache.getItem(page => page.entryId === \"page-1\");\n expect(detailItem).toBeDefined();\n expect(detailItem?.id).toEqual(\"page-1#0001\");\n expect(detailItem?.status).toEqual(WbPageStatus.Unpublished);\n expect(detailItem?.elements).toMatchObject({ element1: \"element\" });\n expect(detailItem?.bindings).toMatchObject({ data: \"any-data\" });\n expect(detailItem?.extensions).toMatchObject({ ext1: \"ext-data\" });\n });\n\n it(\"should not unpublish a page if id is missing\", async () => {\n const container = new Container();\n container.registerInstance(PageListCache, pagesCache);\n container.registerInstance(FullPageCache, detailsCache);\n container.registerInstance(PageRevisionsCache, pageRevisionsCacheFactory.getCache());\n container.registerInstance(GatewayAbstraction, gateway);\n container.register(UnpublishPageRepository).inSingletonScope();\n container.register(UnpublishPageUseCase);\n\n const unpublishPage = container.resolve(UseCaseAbstraction);\n\n await unpublishPage.execute({\n id: \"\"\n });\n\n expect(gateway.execute).toHaveBeenCalledTimes(1);\n\n const publishedItem = pagesCache.getItem(page => page.entryId === \"page-1\");\n\n expect(publishedItem?.id).toEqual(\"page-1#0001\");\n expect(publishedItem?.status).toEqual(WbPageStatus.Published);\n });\n});\n"],"names":["describe","gateway","vi","WbPageStatus","pagesCache","pageListCache","detailsCache","fullPageCache","beforeEach","Page","it","container","Container","PageListCache","FullPageCache","PageRevisionsCache","pageRevisionsCacheFactory","GatewayAbstraction","UnpublishPageRepository","UnpublishPageUseCase","unpublishPage","UseCaseAbstraction","expect","item","page","publishedItem","detailItem"],"mappings":"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"}
@@ -1,11 +1,12 @@
1
1
  import { UnpublishPageRepository as RepositoryAbstraction, UnpublishPageGateway } from "./abstractions.js";
2
2
  import { Page } from "../../../domain/Page/Page.js";
3
- import { PageListCache, FullPageCache } from "../../../features/pages/shared/abstractions.js";
3
+ import { PageListCache, FullPageCache, PageRevisionsCache } from "../../../features/pages/shared/abstractions.js";
4
4
  declare class UnpublishPageRepositoryImpl implements RepositoryAbstraction.Interface {
5
5
  private listCache;
6
6
  private detailsCache;
7
+ private revisionsCache;
7
8
  private gateway;
8
- constructor(listCache: PageListCache.Interface, detailsCache: FullPageCache.Interface, gateway: UnpublishPageGateway.Interface);
9
+ constructor(listCache: PageListCache.Interface, detailsCache: FullPageCache.Interface, revisionsCache: PageRevisionsCache.Interface, gateway: UnpublishPageGateway.Interface);
9
10
  execute(page: Page): Promise<void>;
10
11
  }
11
12
  export declare const UnpublishPageRepository: typeof UnpublishPageRepositoryImpl & {
@@ -1,22 +1,29 @@
1
1
  import { UnpublishPageGateway, UnpublishPageRepository } from "./abstractions.js";
2
2
  import { Page } from "../../../domain/Page/Page.js";
3
- import { FullPageCache, PageListCache } from "../shared/abstractions.js";
3
+ import { PageRevision } from "../../../domain/PageRevision/PageRevision.js";
4
+ import { FullPageCache, PageListCache, PageRevisionsCache } from "../shared/abstractions.js";
4
5
  class UnpublishPageRepositoryImpl {
5
- constructor(listCache, detailsCache, gateway){
6
+ constructor(listCache, detailsCache, revisionsCache, gateway){
6
7
  this.listCache = listCache;
7
8
  this.detailsCache = detailsCache;
9
+ this.revisionsCache = revisionsCache;
8
10
  this.gateway = gateway;
9
11
  }
10
12
  async execute(page) {
11
13
  const result = await this.gateway.execute(page.id);
14
+ const unpublishedPage = Page.create(result);
12
15
  this.listCache.updateItems((existingPage)=>{
13
- if (existingPage.id === page.id) return Page.create(result);
16
+ if (existingPage.id === page.id) return unpublishedPage;
14
17
  return existingPage;
15
18
  });
16
19
  this.detailsCache.updateItems((existingPage)=>{
17
- if (existingPage.id === page.id) return Page.create(result);
20
+ if (existingPage.id === page.id) return unpublishedPage;
18
21
  return existingPage;
19
22
  });
23
+ this.revisionsCache.updateItems((revision)=>{
24
+ if (revision.id === unpublishedPage.id) return PageRevision.createFromPage(unpublishedPage);
25
+ return revision;
26
+ });
20
27
  }
21
28
  }
22
29
  const UnpublishPageRepository_UnpublishPageRepository = UnpublishPageRepository.createImplementation({
@@ -24,6 +31,7 @@ const UnpublishPageRepository_UnpublishPageRepository = UnpublishPageRepository.
24
31
  dependencies: [
25
32
  PageListCache,
26
33
  FullPageCache,
34
+ PageRevisionsCache,
27
35
  UnpublishPageGateway
28
36
  ]
29
37
  });
@@ -1 +1 @@
1
- {"version":3,"file":"features/pages/unpublishPage/UnpublishPageRepository.js","sources":["../../../../src/features/pages/unpublishPage/UnpublishPageRepository.ts"],"sourcesContent":["import {\n UnpublishPageRepository as RepositoryAbstraction,\n UnpublishPageGateway\n} from \"./abstractions.js\";\nimport { Page } from \"~/domain/Page/Page.js\";\nimport { PageListCache, FullPageCache } from \"~/features/pages/shared/abstractions.js\";\n\nclass UnpublishPageRepositoryImpl implements RepositoryAbstraction.Interface {\n constructor(\n private listCache: PageListCache.Interface,\n private detailsCache: FullPageCache.Interface,\n private gateway: UnpublishPageGateway.Interface\n ) {}\n\n async execute(page: Page) {\n const result = await this.gateway.execute(page.id);\n\n this.listCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return Page.create(result);\n }\n return existingPage;\n });\n\n this.detailsCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return Page.create(result);\n }\n return existingPage;\n });\n }\n}\n\nexport const UnpublishPageRepository = RepositoryAbstraction.createImplementation({\n implementation: UnpublishPageRepositoryImpl,\n dependencies: [PageListCache, FullPageCache, UnpublishPageGateway]\n});\n"],"names":["UnpublishPageRepositoryImpl","listCache","detailsCache","gateway","page","result","existingPage","Page","UnpublishPageRepository","RepositoryAbstraction","PageListCache","FullPageCache","UnpublishPageGateway"],"mappings":";;;AAOA,MAAMA;IACF,YACYC,SAAkC,EAClCC,YAAqC,EACrCC,OAAuC,CACjD;aAHUF,SAAS,GAATA;aACAC,YAAY,GAAZA;aACAC,OAAO,GAAPA;IACT;IAEH,MAAM,QAAQC,IAAU,EAAE;QACtB,MAAMC,SAAS,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAACD,KAAK,EAAE;QAEjD,IAAI,CAAC,SAAS,CAAC,WAAW,CAACE,CAAAA;YACvB,IAAIA,aAAa,EAAE,KAAKF,KAAK,EAAE,EAC3B,OAAOG,KAAK,MAAM,CAACF;YAEvB,OAAOC;QACX;QAEA,IAAI,CAAC,YAAY,CAAC,WAAW,CAACA,CAAAA;YAC1B,IAAIA,aAAa,EAAE,KAAKF,KAAK,EAAE,EAC3B,OAAOG,KAAK,MAAM,CAACF;YAEvB,OAAOC;QACX;IACJ;AACJ;AAEO,MAAME,kDAA0BC,wBAAAA,oBAA0C,CAAC;IAC9E,gBAAgBT;IAChB,cAAc;QAACU;QAAeC;QAAeC;KAAqB;AACtE"}
1
+ {"version":3,"file":"features/pages/unpublishPage/UnpublishPageRepository.js","sources":["../../../../src/features/pages/unpublishPage/UnpublishPageRepository.ts"],"sourcesContent":["import {\n UnpublishPageRepository as RepositoryAbstraction,\n UnpublishPageGateway\n} from \"./abstractions.js\";\nimport { Page } from \"~/domain/Page/Page.js\";\nimport { PageRevision } from \"~/domain/PageRevision/PageRevision.js\";\nimport {\n PageListCache,\n FullPageCache,\n PageRevisionsCache\n} from \"~/features/pages/shared/abstractions.js\";\n\nclass UnpublishPageRepositoryImpl implements RepositoryAbstraction.Interface {\n constructor(\n private listCache: PageListCache.Interface,\n private detailsCache: FullPageCache.Interface,\n private revisionsCache: PageRevisionsCache.Interface,\n private gateway: UnpublishPageGateway.Interface\n ) {}\n\n async execute(page: Page) {\n const result = await this.gateway.execute(page.id);\n const unpublishedPage = Page.create(result);\n\n this.listCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return unpublishedPage;\n }\n return existingPage;\n });\n\n this.detailsCache.updateItems(existingPage => {\n if (existingPage.id === page.id) {\n return unpublishedPage;\n }\n return existingPage;\n });\n\n this.revisionsCache.updateItems(revision => {\n if (revision.id === unpublishedPage.id) {\n return PageRevision.createFromPage(unpublishedPage);\n }\n return revision;\n });\n }\n}\n\nexport const UnpublishPageRepository = RepositoryAbstraction.createImplementation({\n implementation: UnpublishPageRepositoryImpl,\n dependencies: [PageListCache, FullPageCache, PageRevisionsCache, UnpublishPageGateway]\n});\n"],"names":["UnpublishPageRepositoryImpl","listCache","detailsCache","revisionsCache","gateway","page","result","unpublishedPage","Page","existingPage","revision","PageRevision","UnpublishPageRepository","RepositoryAbstraction","PageListCache","FullPageCache","PageRevisionsCache","UnpublishPageGateway"],"mappings":";;;;AAYA,MAAMA;IACF,YACYC,SAAkC,EAClCC,YAAqC,EACrCC,cAA4C,EAC5CC,OAAuC,CACjD;aAJUH,SAAS,GAATA;aACAC,YAAY,GAAZA;aACAC,cAAc,GAAdA;aACAC,OAAO,GAAPA;IACT;IAEH,MAAM,QAAQC,IAAU,EAAE;QACtB,MAAMC,SAAS,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAACD,KAAK,EAAE;QACjD,MAAME,kBAAkBC,KAAK,MAAM,CAACF;QAEpC,IAAI,CAAC,SAAS,CAAC,WAAW,CAACG,CAAAA;YACvB,IAAIA,aAAa,EAAE,KAAKJ,KAAK,EAAE,EAC3B,OAAOE;YAEX,OAAOE;QACX;QAEA,IAAI,CAAC,YAAY,CAAC,WAAW,CAACA,CAAAA;YAC1B,IAAIA,aAAa,EAAE,KAAKJ,KAAK,EAAE,EAC3B,OAAOE;YAEX,OAAOE;QACX;QAEA,IAAI,CAAC,cAAc,CAAC,WAAW,CAACC,CAAAA;YAC5B,IAAIA,SAAS,EAAE,KAAKH,gBAAgB,EAAE,EAClC,OAAOI,aAAa,cAAc,CAACJ;YAEvC,OAAOG;QACX;IACJ;AACJ;AAEO,MAAME,kDAA0BC,wBAAAA,oBAA0C,CAAC;IAC9E,gBAAgBb;IAChB,cAAc;QAACc;QAAeC;QAAeC;QAAoBC;KAAqB;AAC1F"}
@@ -17,6 +17,10 @@ const RevisionListDrawer = (props)=>{
17
17
  title: "Entry revisions",
18
18
  open: isRevisionListOpen,
19
19
  onOpenChange: (open)=>openRevisionList(open),
20
+ onInteractOutside: (e)=>{
21
+ const target = e.target;
22
+ if (target.closest("[data-role='dialog']")) e.preventDefault();
23
+ },
20
24
  modal: true,
21
25
  bodyPadding: false,
22
26
  headerSeparator: true,
@@ -1 +1 @@
1
- {"version":3,"file":"modules/pages/PageEditor/Revisions/RevisionListDrawer.js","sources":["../../../../../src/modules/pages/PageEditor/Revisions/RevisionListDrawer.tsx"],"sourcesContent":["import React from \"react\";\nimport { useHotkeys } from \"@webiny/app-admin\";\nimport { RevisionsList } from \"./RevisionsList.js\";\nimport { Drawer } from \"@webiny/admin-ui\";\nimport type { Page } from \"~/domain/Page/Page.js\";\nimport { usePageEditorDrawer } from \"./usePageEditorDrawer.js\";\n\ninterface IRevisionListDrawerProps {\n page: Pick<Page, \"id\">;\n}\n\nexport const RevisionListDrawer = (props: IRevisionListDrawerProps) => {\n const { page } = props;\n const { isRevisionListOpen, openRevisionList } = usePageEditorDrawer();\n\n useHotkeys({\n zIndex: 55,\n disabled: !isRevisionListOpen,\n keys: {\n esc: () => openRevisionList(false)\n }\n });\n\n return (\n <Drawer\n title={\"Entry revisions\"}\n open={isRevisionListOpen}\n onOpenChange={open => openRevisionList(open)}\n modal\n bodyPadding={false}\n headerSeparator={true}\n width={1000}\n >\n <RevisionsList page={page} />\n </Drawer>\n );\n};\n"],"names":["RevisionListDrawer","props","page","isRevisionListOpen","openRevisionList","usePageEditorDrawer","useHotkeys","Drawer","open","RevisionsList"],"mappings":";;;;;AAWO,MAAMA,qBAAqB,CAACC;IAC/B,MAAM,EAAEC,IAAI,EAAE,GAAGD;IACjB,MAAM,EAAEE,kBAAkB,EAAEC,gBAAgB,EAAE,GAAGC;IAEjDC,WAAW;QACP,QAAQ;QACR,UAAU,CAACH;QACX,MAAM;YACF,KAAK,IAAMC,iBAAiB;QAChC;IACJ;IAEA,OAAO,WAAP,GACI,oBAACG,QAAMA;QACH,OAAO;QACP,MAAMJ;QACN,cAAcK,CAAAA,OAAQJ,iBAAiBI;QACvC;QACA,aAAa;QACb,iBAAiB;QACjB,OAAO;qBAEP,oBAACC,eAAaA;QAAC,MAAMP;;AAGjC"}
1
+ {"version":3,"file":"modules/pages/PageEditor/Revisions/RevisionListDrawer.js","sources":["../../../../../src/modules/pages/PageEditor/Revisions/RevisionListDrawer.tsx"],"sourcesContent":["import React from \"react\";\nimport { useHotkeys } from \"@webiny/app-admin\";\nimport { RevisionsList } from \"./RevisionsList.js\";\nimport { Drawer } from \"@webiny/admin-ui\";\nimport type { Page } from \"~/domain/Page/Page.js\";\nimport { usePageEditorDrawer } from \"./usePageEditorDrawer.js\";\n\ninterface IRevisionListDrawerProps {\n page: Pick<Page, \"id\">;\n}\n\nexport const RevisionListDrawer = (props: IRevisionListDrawerProps) => {\n const { page } = props;\n const { isRevisionListOpen, openRevisionList } = usePageEditorDrawer();\n\n useHotkeys({\n zIndex: 55,\n disabled: !isRevisionListOpen,\n keys: {\n esc: () => openRevisionList(false)\n }\n });\n\n return (\n <Drawer\n title={\"Entry revisions\"}\n open={isRevisionListOpen}\n onOpenChange={open => openRevisionList(open)}\n onInteractOutside={e => {\n // Confirmation dialogs render above the drawer; clicking their overlay must not\n // close the drawer underneath them.\n const target = e.target as HTMLElement;\n if (target.closest(\"[data-role='dialog']\")) {\n e.preventDefault();\n }\n }}\n modal\n bodyPadding={false}\n headerSeparator={true}\n width={1000}\n >\n <RevisionsList page={page} />\n </Drawer>\n );\n};\n"],"names":["RevisionListDrawer","props","page","isRevisionListOpen","openRevisionList","usePageEditorDrawer","useHotkeys","Drawer","open","e","target","RevisionsList"],"mappings":";;;;;AAWO,MAAMA,qBAAqB,CAACC;IAC/B,MAAM,EAAEC,IAAI,EAAE,GAAGD;IACjB,MAAM,EAAEE,kBAAkB,EAAEC,gBAAgB,EAAE,GAAGC;IAEjDC,WAAW;QACP,QAAQ;QACR,UAAU,CAACH;QACX,MAAM;YACF,KAAK,IAAMC,iBAAiB;QAChC;IACJ;IAEA,OAAO,WAAP,GACI,oBAACG,QAAMA;QACH,OAAO;QACP,MAAMJ;QACN,cAAcK,CAAAA,OAAQJ,iBAAiBI;QACvC,mBAAmBC,CAAAA;YAGf,MAAMC,SAASD,EAAE,MAAM;YACvB,IAAIC,OAAO,OAAO,CAAC,yBACfD,EAAE,cAAc;QAExB;QACA;QACA,aAAa;QACb,iBAAiB;QACjB,OAAO;qBAEP,oBAACE,eAAaA;QAAC,MAAMT;;AAGjC"}
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
- import type { PageRevision } from "../../../../domain/PageRevision/index.js";
2
+ import type { RevisionListPresenter } from "../../../../presentation/pages/RevisionList/abstractions.js";
3
3
  interface RevisionListItemProps {
4
- revision: PageRevision;
4
+ item: RevisionListPresenter.ItemViewModel;
5
5
  }
6
- declare const RevisionListItem: ({ revision }: RevisionListItemProps) => React.JSX.Element;
6
+ declare const RevisionListItem: ({ item }: RevisionListItemProps) => React.JSX.Element;
7
7
  export default RevisionListItem;
@@ -11,7 +11,6 @@ import { ReactComponent as visibility_off_svg_ReactComponent } from "@webiny/ico
11
11
  import { ReactComponent as delete_svg_ReactComponent } from "@webiny/icons/delete.svg";
12
12
  import { useRevision } from "./useRevision.js";
13
13
  import { i18n } from "@webiny/app/i18n/index.js";
14
- import { HasPermission } from "../../../../presentation/security/HasPermission.js";
15
14
  const DateDisplay = ({ date })=>{
16
15
  const formatted = react.useMemo(()=>{
17
16
  const d = new globalThis.Date(date);
@@ -59,7 +58,8 @@ const getIcon = (revision)=>{
59
58
  };
60
59
  }
61
60
  };
62
- const RevisionListItem = ({ revision })=>{
61
+ const RevisionListItem = ({ item })=>{
62
+ const { revision } = item;
63
63
  const { createRevision, editRevision, deleteRevision, unpublishRevision, publishRevision } = useRevision({
64
64
  revision
65
65
  });
@@ -93,44 +93,33 @@ const RevisionListItem = ({ revision })=>{
93
93
  icon: /*#__PURE__*/ react.createElement(ReactComponent, null)
94
94
  }),
95
95
  "data-testid": "page.revisions.more-options"
96
- }, /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(HasPermission, {
97
- entity: "page",
98
- action: "edit"
99
- }, /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
96
+ }, /*#__PURE__*/ react.createElement(react.Fragment, null, item.canCreateFrom ? /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
100
97
  onClick: ()=>createRevision(),
101
98
  "data-testid": "page.revisioncreate-revision",
102
99
  icon: /*#__PURE__*/ react.createElement(add_svg_ReactComponent, null),
103
100
  text: t`New revision from current`
104
- }), revision.locked ? null : /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
101
+ }) : null, item.canEdit ? /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
105
102
  onClick: ()=>{
106
103
  editRevision();
107
104
  },
108
105
  icon: /*#__PURE__*/ react.createElement(edit_svg_ReactComponent, null),
109
106
  text: t`Edit revision`
110
- })), /*#__PURE__*/ react.createElement(HasPermission, {
111
- entity: "page",
112
- action: "publish"
113
- }, "published" !== revision.status ? /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
107
+ }) : null, item.canPublish ? /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
114
108
  onClick: ()=>publishRevision(),
109
+ "data-testid": "page.revisionpublish",
115
110
  icon: /*#__PURE__*/ react.createElement(visibility_svg_ReactComponent, null),
116
111
  text: t`Publish revision`
117
- }) : null), /*#__PURE__*/ react.createElement(HasPermission, {
118
- entity: "page",
119
- action: "unpublish"
120
- }, "published" === revision.status ? /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
112
+ }) : null, item.canUnpublish ? /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
121
113
  onClick: ()=>unpublishRevision(),
122
114
  "data-testid": "page.revisionunpublish",
123
115
  icon: /*#__PURE__*/ react.createElement(visibility_off_svg_ReactComponent, null),
124
116
  text: t`Unpublish revision`
125
- }) : null), /*#__PURE__*/ react.createElement(HasPermission, {
126
- entity: "page",
127
- action: "delete"
128
- }, revision.locked ? null : /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(DropdownMenu.Separator, null), /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
117
+ }) : null, item.canDelete ? /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(DropdownMenu.Separator, null), /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
129
118
  onClick: ()=>deleteRevision(),
130
119
  icon: /*#__PURE__*/ react.createElement(delete_svg_ReactComponent, null),
131
120
  text: t`Delete revision`,
132
121
  className: "text-destructive-primary! [&_svg]:fill-destructive"
133
- })))))
122
+ })) : null))
134
123
  });
135
124
  };
136
125
  const Revisions_RevisionListItem = RevisionListItem;
@@ -1 +1 @@
1
- {"version":3,"file":"modules/pages/PageEditor/Revisions/RevisionListItem.js","sources":["../../../../../src/modules/pages/PageEditor/Revisions/RevisionListItem.tsx"],"sourcesContent":["import React from \"react\";\nconst DateDisplay = ({ date }: { date: string }) => {\n const formatted = React.useMemo(() => {\n const d = new globalThis.Date(date);\n if (isNaN(d.getTime())) {\n return \"\";\n }\n return new Intl.DateTimeFormat(navigator.language, {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\"\n }).format(d);\n }, [date]);\n return <>{formatted}</>;\n};\nimport { DropdownMenu, Icon, IconButton, List, Text, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as MoreVerticalIcon } from \"@webiny/icons/more_vert.svg\";\nimport { ReactComponent as LockIcon } from \"@webiny/icons/lock.svg\";\nimport { ReactComponent as BeenHereIcon } from \"@webiny/icons/beenhere.svg\";\nimport { ReactComponent as GestureIcon } from \"@webiny/icons/gesture.svg\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as PublishIcon } from \"@webiny/icons/visibility.svg\";\nimport { ReactComponent as UnpublishIcon } from \"@webiny/icons/visibility_off.svg\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete.svg\";\nimport { useRevision } from \"./useRevision.js\";\nimport type { PageRevision } from \"~/domain/PageRevision/index.js\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { HasPermission } from \"~/presentation/security/HasPermission.js\";\n\nconst t = i18n.ns(\"app-website-builder/modules/Pages/PageEditor/Revisions\");\n\nconst getIcon = (revision: PageRevision) => {\n switch (true) {\n case revision.locked && revision.status !== \"published\":\n return {\n icon: (\n <Icon\n label={\"Locked revision\"}\n icon={<LockIcon />}\n data-testid={\"page.revision.status.locked\"}\n />\n ),\n text: \"This revision is locked (it has already been published)\"\n };\n case revision.status === \"published\":\n return {\n icon: (\n <Icon\n label=\"Published revision\"\n icon={<BeenHereIcon />}\n color={\"accent\"}\n data-testid={\"page.revision.status.published\"}\n />\n ),\n text: \"This revision is currently published!\"\n };\n default:\n return {\n icon: (\n <Icon\n label={\"Draft revision\"}\n icon={<GestureIcon />}\n data-testid={\"page.revision.status.draft\"}\n />\n ),\n text: \"This is a draft\"\n };\n }\n};\n\ninterface RevisionListItemProps {\n revision: PageRevision;\n}\n\nconst RevisionListItem = ({ revision }: RevisionListItemProps) => {\n const { createRevision, editRevision, deleteRevision, unpublishRevision, publishRevision } =\n useRevision({\n revision\n });\n\n const { icon, text: tooltipText } = getIcon(revision);\n\n return (\n <List.Item\n icon={<Tooltip content={tooltipText} trigger={icon} />}\n title={revision.title || t`N/A`}\n description={\n <>\n {revision.revisionDescription ? (\n <Text as={\"div\"} size={\"md\"} className={\"mb-2\"}>\n {revision.revisionDescription}\n </Text>\n ) : null}\n <Text as={\"div\"} size={\"sm\"}>\n {t`Last modified by {author} on {time} (#{version})`({\n // Added this because revisionCreatedBy can be returned as null from GraphQL.\n author: revision.createdBy?.displayName,\n time: <DateDisplay date={revision.savedOn} />,\n version: revision.version\n })}\n </Text>\n </>\n }\n about={revision.revisionDescription}\n actions={\n <DropdownMenu\n trigger={\n <IconButton\n variant={\"ghost\"}\n size={\"sm\"}\n iconSize={\"lg\"}\n icon={<MoreVerticalIcon />}\n />\n }\n data-testid={\"page.revisions.more-options\"}\n >\n <>\n <HasPermission entity={\"page\"} action={\"edit\"}>\n <DropdownMenu.Item\n onClick={() => createRevision()}\n data-testid={\"page.revisioncreate-revision\"}\n icon={<AddIcon />}\n text={t`New revision from current`}\n />\n {!revision.locked ? (\n <DropdownMenu.Item\n onClick={() => {\n editRevision();\n }}\n icon={<EditIcon />}\n text={t`Edit revision`}\n />\n ) : null}\n </HasPermission>\n\n <HasPermission entity={\"page\"} action={\"publish\"}>\n {revision.status !== \"published\" ? (\n <DropdownMenu.Item\n onClick={() => publishRevision()}\n icon={<PublishIcon />}\n text={t`Publish revision`}\n />\n ) : null}\n </HasPermission>\n\n <HasPermission entity={\"page\"} action={\"unpublish\"}>\n {revision.status === \"published\" ? (\n <DropdownMenu.Item\n onClick={() => unpublishRevision()}\n data-testid={\"page.revisionunpublish\"}\n icon={<UnpublishIcon />}\n text={t`Unpublish revision`}\n />\n ) : null}\n </HasPermission>\n\n <HasPermission entity={\"page\"} action={\"delete\"}>\n {!revision.locked ? (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n onClick={() => deleteRevision()}\n icon={<DeleteIcon />}\n text={t`Delete revision`}\n className={\n \"text-destructive-primary! [&_svg]:fill-destructive\"\n }\n />\n </>\n ) : null}\n </HasPermission>\n </>\n </DropdownMenu>\n }\n />\n );\n};\n\nexport default RevisionListItem;\n"],"names":["DateDisplay","date","formatted","React","d","globalThis","isNaN","Intl","navigator","t","i18n","getIcon","revision","Icon","LockIcon","BeenHereIcon","GestureIcon","RevisionListItem","createRevision","editRevision","deleteRevision","unpublishRevision","publishRevision","useRevision","icon","tooltipText","List","Tooltip","Text","DropdownMenu","IconButton","MoreVerticalIcon","HasPermission","AddIcon","EditIcon","PublishIcon","UnpublishIcon","DeleteIcon"],"mappings":"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"}
1
+ {"version":3,"file":"modules/pages/PageEditor/Revisions/RevisionListItem.js","sources":["../../../../../src/modules/pages/PageEditor/Revisions/RevisionListItem.tsx"],"sourcesContent":["import React from \"react\";\nconst DateDisplay = ({ date }: { date: string }) => {\n const formatted = React.useMemo(() => {\n const d = new globalThis.Date(date);\n if (isNaN(d.getTime())) {\n return \"\";\n }\n return new Intl.DateTimeFormat(navigator.language, {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\"\n }).format(d);\n }, [date]);\n return <>{formatted}</>;\n};\nimport { DropdownMenu, Icon, IconButton, List, Text, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as MoreVerticalIcon } from \"@webiny/icons/more_vert.svg\";\nimport { ReactComponent as LockIcon } from \"@webiny/icons/lock.svg\";\nimport { ReactComponent as BeenHereIcon } from \"@webiny/icons/beenhere.svg\";\nimport { ReactComponent as GestureIcon } from \"@webiny/icons/gesture.svg\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as PublishIcon } from \"@webiny/icons/visibility.svg\";\nimport { ReactComponent as UnpublishIcon } from \"@webiny/icons/visibility_off.svg\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete.svg\";\nimport { useRevision } from \"./useRevision.js\";\nimport type { PageRevision } from \"~/domain/PageRevision/index.js\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport type { RevisionListPresenter } from \"~/presentation/pages/RevisionList/abstractions.js\";\n\nconst t = i18n.ns(\"app-website-builder/modules/Pages/PageEditor/Revisions\");\n\nconst getIcon = (revision: PageRevision) => {\n switch (true) {\n case revision.locked && revision.status !== \"published\":\n return {\n icon: (\n <Icon\n label={\"Locked revision\"}\n icon={<LockIcon />}\n data-testid={\"page.revision.status.locked\"}\n />\n ),\n text: \"This revision is locked (it has already been published)\"\n };\n case revision.status === \"published\":\n return {\n icon: (\n <Icon\n label=\"Published revision\"\n icon={<BeenHereIcon />}\n color={\"accent\"}\n data-testid={\"page.revision.status.published\"}\n />\n ),\n text: \"This revision is currently published!\"\n };\n default:\n return {\n icon: (\n <Icon\n label={\"Draft revision\"}\n icon={<GestureIcon />}\n data-testid={\"page.revision.status.draft\"}\n />\n ),\n text: \"This is a draft\"\n };\n }\n};\n\ninterface RevisionListItemProps {\n item: RevisionListPresenter.ItemViewModel;\n}\n\nconst RevisionListItem = ({ item }: RevisionListItemProps) => {\n const { revision } = item;\n const { createRevision, editRevision, deleteRevision, unpublishRevision, publishRevision } =\n useRevision({\n revision\n });\n\n const { icon, text: tooltipText } = getIcon(revision);\n\n return (\n <List.Item\n icon={<Tooltip content={tooltipText} trigger={icon} />}\n title={revision.title || t`N/A`}\n description={\n <>\n {revision.revisionDescription ? (\n <Text as={\"div\"} size={\"md\"} className={\"mb-2\"}>\n {revision.revisionDescription}\n </Text>\n ) : null}\n <Text as={\"div\"} size={\"sm\"}>\n {t`Last modified by {author} on {time} (#{version})`({\n // Added this because revisionCreatedBy can be returned as null from GraphQL.\n author: revision.createdBy?.displayName,\n time: <DateDisplay date={revision.savedOn} />,\n version: revision.version\n })}\n </Text>\n </>\n }\n about={revision.revisionDescription}\n actions={\n <DropdownMenu\n trigger={\n <IconButton\n variant={\"ghost\"}\n size={\"sm\"}\n iconSize={\"lg\"}\n icon={<MoreVerticalIcon />}\n />\n }\n data-testid={\"page.revisions.more-options\"}\n >\n <>\n {item.canCreateFrom ? (\n <DropdownMenu.Item\n onClick={() => createRevision()}\n data-testid={\"page.revisioncreate-revision\"}\n icon={<AddIcon />}\n text={t`New revision from current`}\n />\n ) : null}\n\n {item.canEdit ? (\n <DropdownMenu.Item\n onClick={() => {\n editRevision();\n }}\n icon={<EditIcon />}\n text={t`Edit revision`}\n />\n ) : null}\n\n {item.canPublish ? (\n <DropdownMenu.Item\n onClick={() => publishRevision()}\n data-testid={\"page.revisionpublish\"}\n icon={<PublishIcon />}\n text={t`Publish revision`}\n />\n ) : null}\n\n {item.canUnpublish ? (\n <DropdownMenu.Item\n onClick={() => unpublishRevision()}\n data-testid={\"page.revisionunpublish\"}\n icon={<UnpublishIcon />}\n text={t`Unpublish revision`}\n />\n ) : null}\n\n {item.canDelete ? (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n onClick={() => deleteRevision()}\n icon={<DeleteIcon />}\n text={t`Delete revision`}\n className={\"text-destructive-primary! [&_svg]:fill-destructive\"}\n />\n </>\n ) : null}\n </>\n </DropdownMenu>\n }\n />\n );\n};\n\nexport default RevisionListItem;\n"],"names":["DateDisplay","date","formatted","React","d","globalThis","isNaN","Intl","navigator","t","i18n","getIcon","revision","Icon","LockIcon","BeenHereIcon","GestureIcon","RevisionListItem","item","createRevision","editRevision","deleteRevision","unpublishRevision","publishRevision","useRevision","icon","tooltipText","List","Tooltip","Text","DropdownMenu","IconButton","MoreVerticalIcon","AddIcon","EditIcon","PublishIcon","UnpublishIcon","DeleteIcon"],"mappings":"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"}