@webiny/app-website-builder 6.5.0-beta.0 → 6.5.0-beta.10

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 (167) hide show
  1. package/BaseEditor/config/Sidebar/Tab.d.ts +0 -4
  2. package/BaseEditor/config/Sidebar/Tab.js +5 -21
  3. package/BaseEditor/config/Sidebar/Tab.js.map +1 -1
  4. package/BaseEditor/defaultConfig/Content/AddressBar/PreviewDomain.js +6 -66
  5. package/BaseEditor/defaultConfig/Content/AddressBar/PreviewDomain.js.map +1 -1
  6. package/BaseEditor/defaultConfig/Content/Preview/DropZoneManager.js.map +1 -1
  7. package/BaseEditor/defaultConfig/Content/Preview/Iframe.d.ts +2 -2
  8. package/BaseEditor/defaultConfig/Content/Preview/Overlays/ElementOverlays.d.ts +2 -2
  9. package/BaseEditor/defaultConfig/Content/Preview/PreviewContainer.js +1 -1
  10. package/BaseEditor/defaultConfig/Content/Preview/PreviewContainer.js.map +1 -1
  11. package/BaseEditor/defaultConfig/Content/usePreviewDomain.d.ts +1 -6
  12. package/BaseEditor/defaultConfig/Content/usePreviewDomain.js +1 -26
  13. package/BaseEditor/defaultConfig/DocumentStateEditor/DocumentStateEditor.d.ts +2 -2
  14. package/BaseEditor/defaultConfig/ElementInputRenderers.js +12 -0
  15. package/BaseEditor/defaultConfig/ElementInputRenderers.js.map +1 -1
  16. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/ElementSettingsGroup.js +2 -5
  17. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/ElementSettingsGroup.js.map +1 -1
  18. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/PreviewedBindings.d.ts +22 -0
  19. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/PreviewedBindings.js +17 -0
  20. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/PreviewedBindings.js.map +1 -0
  21. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/PreviewedBindings.test.d.ts +1 -0
  22. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/PreviewedBindings.test.js +64 -0
  23. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/PreviewedBindings.test.js.map +1 -0
  24. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/useInputValue.js +7 -2
  25. package/BaseEditor/defaultConfig/Sidebar/ElementSettings/useInputValue.js.map +1 -1
  26. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundColor.d.ts +6 -2
  27. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundImage.d.ts +6 -2
  28. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundImage.js +8 -1
  29. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundImage.js.map +1 -1
  30. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundPosition.d.ts +6 -2
  31. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundScaling.d.ts +6 -2
  32. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderColor.d.ts +2 -2
  33. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderRadius.d.ts +2 -2
  34. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderStyle.d.ts +2 -2
  35. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderWidth.d.ts +2 -2
  36. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Layout/Alignment.d.ts +6 -2
  37. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Layout/LengthWithUnitInput.d.ts +2 -2
  38. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/MarginPadding/Margin.d.ts +2 -2
  39. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/MarginPadding/Padding.d.ts +2 -2
  40. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Visibility/Visibility.d.ts +2 -2
  41. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/SidebarRow.js +1 -1
  42. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/SidebarRow.js.map +1 -1
  43. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/StyleSettingsGroup.js +2 -5
  44. package/BaseEditor/defaultConfig/Sidebar/StyleSettings/StyleSettingsGroup.js.map +1 -1
  45. package/BaseEditor/defaultConfig/Toolbar/Navigator/Navigator.d.ts +2 -2
  46. package/DocumentEditor/DocumentEditor.d.ts +2 -2
  47. package/DocumentEditor/StateInspector.d.ts +4 -2
  48. package/Extension.js +3 -0
  49. package/Extension.js.map +1 -1
  50. package/domain/Page/Page.d.ts +2 -0
  51. package/domain/Page/Page.js +1 -0
  52. package/domain/Page/Page.js.map +1 -1
  53. package/domain/PageRevision/PageRevision.d.ts +11 -0
  54. package/domain/PageRevision/PageRevision.js +20 -0
  55. package/domain/PageRevision/PageRevision.js.map +1 -1
  56. package/ecommerce/components/ResourcePage.d.ts +6 -2
  57. package/ecommerce/components/ResourcesList.d.ts +4 -4
  58. package/ecommerce/components/ResourcesPicker.d.ts +9 -4
  59. package/editorSdk/CommandBus.js.map +1 -1
  60. package/features/pages/createPageRevisionFrom/CreatePageRevisionFrom.test.js +41 -1
  61. package/features/pages/createPageRevisionFrom/CreatePageRevisionFrom.test.js.map +1 -1
  62. package/features/pages/createPageRevisionFrom/CreatePageRevisionFromRepository.d.ts +3 -2
  63. package/features/pages/createPageRevisionFrom/CreatePageRevisionFromRepository.js +8 -2
  64. package/features/pages/createPageRevisionFrom/CreatePageRevisionFromRepository.js.map +1 -1
  65. package/features/pages/deletePageRevision/DeletePageRevision.test.d.ts +1 -0
  66. package/features/pages/deletePageRevision/DeletePageRevision.test.js +67 -0
  67. package/features/pages/deletePageRevision/DeletePageRevision.test.js.map +1 -0
  68. package/features/pages/deletePageRevision/DeletePageRevisionGateway.d.ts +1 -1
  69. package/features/pages/deletePageRevision/DeletePageRevisionGateway.js +2 -3
  70. package/features/pages/deletePageRevision/DeletePageRevisionGateway.js.map +1 -1
  71. package/features/pages/deletePageRevision/DeletePageRevisionRepository.d.ts +4 -2
  72. package/features/pages/deletePageRevision/DeletePageRevisionRepository.js +7 -3
  73. package/features/pages/deletePageRevision/DeletePageRevisionRepository.js.map +1 -1
  74. package/features/pages/deletePageRevision/DeletePageRevisionUseCase.js +1 -1
  75. package/features/pages/deletePageRevision/DeletePageRevisionUseCase.js.map +1 -1
  76. package/features/pages/deletePageRevision/abstractions.d.ts +2 -3
  77. package/features/pages/deletePageRevision/abstractions.js.map +1 -1
  78. package/features/pages/getPage/PageGatewayDto.d.ts +2 -0
  79. package/features/pages/publishPage/PublishPage.test.js +41 -1
  80. package/features/pages/publishPage/PublishPage.test.js.map +1 -1
  81. package/features/pages/publishPage/PublishPageRepository.d.ts +3 -2
  82. package/features/pages/publishPage/PublishPageRepository.js +15 -4
  83. package/features/pages/publishPage/PublishPageRepository.js.map +1 -1
  84. package/features/pages/shared/pageGraphQLFields.js +1 -0
  85. package/features/pages/shared/pageGraphQLFields.js.map +1 -1
  86. package/features/pages/unpublishPage/UnpublishPage.test.js +4 -1
  87. package/features/pages/unpublishPage/UnpublishPage.test.js.map +1 -1
  88. package/features/pages/unpublishPage/UnpublishPageRepository.d.ts +3 -2
  89. package/features/pages/unpublishPage/UnpublishPageRepository.js +12 -4
  90. package/features/pages/unpublishPage/UnpublishPageRepository.js.map +1 -1
  91. package/inputRenderers/DateTimeInput.d.ts +9 -0
  92. package/inputRenderers/DateTimeInput.js +21 -0
  93. package/inputRenderers/DateTimeInput.js.map +1 -0
  94. package/inputRenderers/DateTimeInput.test.d.ts +1 -0
  95. package/inputRenderers/DateTimeInput.test.js +27 -0
  96. package/inputRenderers/DateTimeInput.test.js.map +1 -0
  97. package/inputRenderers/FileInput.js +1 -1
  98. package/inputRenderers/FileInput.js.map +1 -1
  99. package/inputRenderers/RadioInput.d.ts +3 -0
  100. package/inputRenderers/RadioInput.js +20 -0
  101. package/inputRenderers/RadioInput.js.map +1 -0
  102. package/inputRenderers/TagsInput.d.ts +3 -0
  103. package/inputRenderers/TagsInput.js +22 -0
  104. package/inputRenderers/TagsInput.js.map +1 -0
  105. package/package.json +31 -31
  106. package/presentation/pages/CreatePage/CreatePageDialog.d.ts +2 -2
  107. package/presentation/pages/PageEditor/Revisions/RevisionListDrawer.js +4 -0
  108. package/presentation/pages/PageEditor/Revisions/RevisionListDrawer.js.map +1 -1
  109. package/presentation/pages/PageEditor/Revisions/RevisionListItem.d.ts +3 -3
  110. package/presentation/pages/PageEditor/Revisions/RevisionListItem.js +9 -20
  111. package/presentation/pages/PageEditor/Revisions/RevisionListItem.js.map +1 -1
  112. package/presentation/pages/PageEditor/Revisions/RevisionsList.js +7 -19
  113. package/presentation/pages/PageEditor/Revisions/RevisionsList.js.map +1 -1
  114. package/presentation/pages/PageEditor/Revisions/useRevision.d.ts +1 -1
  115. package/presentation/pages/PageEditor/Revisions/useRevision.js +84 -14
  116. package/presentation/pages/PageEditor/Revisions/useRevision.js.map +1 -1
  117. package/presentation/pages/PageEditor/Revisions/useRevisionList.d.ts +3 -0
  118. package/presentation/pages/PageEditor/Revisions/useRevisionList.js +31 -0
  119. package/presentation/pages/PageEditor/Revisions/useRevisionList.js.map +1 -0
  120. package/presentation/pages/PageEditor/TopBar/PageSettingsDrawer.d.ts +2 -2
  121. package/presentation/pages/PageEditor/TopBar/RevisionsMenu.js +7 -19
  122. package/presentation/pages/PageEditor/TopBar/RevisionsMenu.js.map +1 -1
  123. package/presentation/pages/PageList/PageListDataSource.js +1 -1
  124. package/presentation/pages/PageList/PageListDataSource.js.map +1 -1
  125. package/presentation/pages/PageList/PageListPresenter.test.d.ts +1 -0
  126. package/presentation/pages/PageList/PageListPresenter.test.js +293 -0
  127. package/presentation/pages/PageList/PageListPresenter.test.js.map +1 -0
  128. package/presentation/pages/PageList/components/BulkActions/BulkActionDelete.d.ts +2 -2
  129. package/presentation/pages/PageList/components/BulkActions/BulkActionDuplicate.d.ts +2 -2
  130. package/presentation/pages/PageList/components/BulkActions/BulkActionMovePage.d.ts +2 -2
  131. package/presentation/pages/PageList/components/BulkActions/BulkActionPublish.d.ts +2 -2
  132. package/presentation/pages/PageList/components/BulkActions/BulkActionUnpublish.d.ts +2 -2
  133. package/presentation/pages/PageList/components/DocumentList.d.ts +2 -2
  134. package/presentation/pages/PageList/components/Table/Table.d.ts +2 -2
  135. package/presentation/pages/RevisionList/RevisionListPresenter.d.ts +27 -0
  136. package/presentation/pages/RevisionList/RevisionListPresenter.js +73 -0
  137. package/presentation/pages/RevisionList/RevisionListPresenter.js.map +1 -0
  138. package/presentation/pages/RevisionList/RevisionListPresenter.test.d.ts +1 -0
  139. package/presentation/pages/RevisionList/RevisionListPresenter.test.js +219 -0
  140. package/presentation/pages/RevisionList/RevisionListPresenter.test.js.map +1 -0
  141. package/presentation/pages/RevisionList/abstractions.d.ts +34 -0
  142. package/presentation/pages/RevisionList/abstractions.js +5 -0
  143. package/presentation/pages/RevisionList/abstractions.js.map +1 -0
  144. package/presentation/pages/RevisionList/feature.d.ts +3 -0
  145. package/presentation/pages/RevisionList/feature.js +17 -0
  146. package/presentation/pages/RevisionList/feature.js.map +1 -0
  147. package/presentation/pages/RevisionList/index.d.ts +2 -0
  148. package/presentation/pages/RevisionList/index.js +1 -0
  149. package/presentation/pages/TrashBin/WbTrashBin.d.ts +2 -2
  150. package/presentation/redirects/RedirectList/RedirectListDataSource.js +1 -1
  151. package/presentation/redirects/RedirectList/RedirectListDataSource.js.map +1 -1
  152. package/presentation/redirects/RedirectList/RedirectListPresenter.js.map +1 -1
  153. package/presentation/redirects/RedirectList/RedirectListPresenter.test.d.ts +1 -0
  154. package/presentation/redirects/RedirectList/RedirectListPresenter.test.js +273 -0
  155. package/presentation/redirects/RedirectList/RedirectListPresenter.test.js.map +1 -0
  156. package/presentation/redirects/RedirectList/components/BulkActionDelete.d.ts +2 -2
  157. package/presentation/redirects/RedirectList/components/BulkActionMove.d.ts +2 -2
  158. package/presentation/redirects/RedirectList/components/CreateRedirectDialog.d.ts +2 -2
  159. package/presentation/redirects/RedirectList/components/DocumentList.d.ts +2 -2
  160. package/presentation/redirects/RedirectList/components/EditRedirectDialog.d.ts +2 -2
  161. package/presentation/redirects/RedirectList/components/Table/Table.d.ts +2 -2
  162. package/shared/fileManagerItemToValue.js +3 -1
  163. package/shared/fileManagerItemToValue.js.map +1 -1
  164. package/shared/fileManagerItemToValue.test.d.ts +1 -0
  165. package/shared/fileManagerItemToValue.test.js +73 -0
  166. package/shared/fileManagerItemToValue.test.js.map +1 -0
  167. package/BaseEditor/defaultConfig/Content/usePreviewDomain.js.map +0 -1
@@ -0,0 +1,219 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { Container } from "@webiny/di";
3
+ import { WbPageStatus } from "../../../constants.js";
4
+ import { PageRevision, pageRevisionsCacheFactory } from "../../../domain/PageRevision/index.js";
5
+ import { GetPageRevisionsUseCase } from "../../../features/pages/getPageRevisions/abstractions.js";
6
+ import { PageRevisionsCache, WbPageLoadingRepository, WbPageRevisionsLoadingRepository } from "../../../features/pages/shared/abstractions.js";
7
+ import { WbPermissions } from "../../../features/permissions/abstractions.js";
8
+ import { RevisionListPresenter } from "./abstractions.js";
9
+ import { RevisionListPresenter as external_RevisionListPresenter_js_RevisionListPresenter } from "./RevisionListPresenter.js";
10
+ const createRevision = (id, entryId, version, savedOn)=>PageRevision.create({
11
+ id,
12
+ entryId,
13
+ version,
14
+ savedOn,
15
+ status: WbPageStatus.Draft,
16
+ title: `Page ${entryId}`,
17
+ locked: false,
18
+ createdBy: {
19
+ id: "admin",
20
+ displayName: "Admin",
21
+ type: "admin"
22
+ },
23
+ createdOn: savedOn,
24
+ revisionDescription: void 0
25
+ });
26
+ describe("RevisionListPresenter", ()=>{
27
+ const revisionsCache = pageRevisionsCacheFactory.getCache();
28
+ const getPageRevisions = {
29
+ execute: vi.fn().mockResolvedValue([])
30
+ };
31
+ const loadingRepository = {
32
+ isLoading: vi.fn().mockReturnValue(false)
33
+ };
34
+ const pageLoadingRepository = {
35
+ isLoading: vi.fn().mockReturnValue(false)
36
+ };
37
+ const permissions = {
38
+ canEdit: vi.fn().mockReturnValue(true),
39
+ canDelete: vi.fn().mockReturnValue(true),
40
+ canPublish: vi.fn().mockReturnValue(true),
41
+ canUnpublish: vi.fn().mockReturnValue(true)
42
+ };
43
+ const createPresenter = ()=>{
44
+ const container = new Container();
45
+ container.registerInstance(PageRevisionsCache, revisionsCache);
46
+ container.registerInstance(WbPageRevisionsLoadingRepository, loadingRepository);
47
+ container.registerInstance(WbPageLoadingRepository, pageLoadingRepository);
48
+ container.registerInstance(WbPermissions, permissions);
49
+ container.registerInstance(GetPageRevisionsUseCase, getPageRevisions);
50
+ container.register(external_RevisionListPresenter_js_RevisionListPresenter).inSingletonScope();
51
+ return container.resolve(RevisionListPresenter);
52
+ };
53
+ beforeEach(()=>{
54
+ vi.clearAllMocks();
55
+ loadingRepository.isLoading.mockReturnValue(false);
56
+ pageLoadingRepository.isLoading.mockReturnValue(false);
57
+ permissions.canEdit.mockReturnValue(true);
58
+ permissions.canDelete.mockReturnValue(true);
59
+ permissions.canPublish.mockReturnValue(true);
60
+ permissions.canUnpublish.mockReturnValue(true);
61
+ revisionsCache.clear();
62
+ });
63
+ it("should fetch the revisions when initialized", ()=>{
64
+ const presenter = createPresenter();
65
+ presenter.init({
66
+ entryId: "page-1"
67
+ });
68
+ expect(getPageRevisions.execute).toHaveBeenCalledTimes(1);
69
+ expect(getPageRevisions.execute).toHaveBeenCalledWith({
70
+ entryId: "page-1"
71
+ });
72
+ });
73
+ it("should not refetch the revisions when initialized with the same entry", ()=>{
74
+ const presenter = createPresenter();
75
+ presenter.init({
76
+ entryId: "page-1"
77
+ });
78
+ presenter.init({
79
+ entryId: "page-1"
80
+ });
81
+ expect(getPageRevisions.execute).toHaveBeenCalledTimes(1);
82
+ presenter.init({
83
+ entryId: "page-2"
84
+ });
85
+ expect(getPageRevisions.execute).toHaveBeenCalledTimes(2);
86
+ });
87
+ it("should only expose the revisions of the current page, newest first", ()=>{
88
+ const presenter = createPresenter();
89
+ revisionsCache.addItems([
90
+ createRevision("page-1#0001", "page-1", 1, "2026-09-20T00:00:00.000Z"),
91
+ createRevision("page-1#0002", "page-1", 2, "2026-09-22T00:00:00.000Z"),
92
+ createRevision("page-2#0001", "page-2", 1, "2026-09-21T00:00:00.000Z")
93
+ ]);
94
+ presenter.init({
95
+ entryId: "page-1"
96
+ });
97
+ expect(presenter.vm.revisions.map((item)=>item.revision.id)).toEqual([
98
+ "page-1#0002",
99
+ "page-1#0001"
100
+ ]);
101
+ expect(presenter.vm.isEmpty).toBeFalse();
102
+ });
103
+ it("should not report an empty list while loading", ()=>{
104
+ loadingRepository.isLoading.mockReturnValue(true);
105
+ const presenter = createPresenter();
106
+ presenter.init({
107
+ entryId: "page-1"
108
+ });
109
+ expect(presenter.vm.revisions).toBeEmpty();
110
+ expect(presenter.vm.isLoading).toBeTrue();
111
+ expect(presenter.vm.isEmpty).toBeFalse();
112
+ });
113
+ it("should report a mutation in progress", ()=>{
114
+ pageLoadingRepository.isLoading.mockImplementation((action)=>"CREATE_REVISION_FROM" === action);
115
+ const presenter = createPresenter();
116
+ presenter.init({
117
+ entryId: "page-1"
118
+ });
119
+ expect(presenter.vm.isMutating).toBeTrue();
120
+ });
121
+ it.each([
122
+ "PUBLISH",
123
+ "UNPUBLISH",
124
+ "DELETE"
125
+ ])("should not report a mutation for %s, which is confirmed through a dialog", (action)=>{
126
+ pageLoadingRepository.isLoading.mockImplementation((a)=>a === action);
127
+ const presenter = createPresenter();
128
+ presenter.init({
129
+ entryId: "page-1"
130
+ });
131
+ expect(presenter.vm.isMutating).toBeFalse();
132
+ });
133
+ it("should not report a mutation for unrelated page actions", ()=>{
134
+ pageLoadingRepository.isLoading.mockImplementation((action)=>"LIST" === action);
135
+ const presenter = createPresenter();
136
+ presenter.init({
137
+ entryId: "page-1"
138
+ });
139
+ expect(presenter.vm.isMutating).toBeFalse();
140
+ });
141
+ it("should reflect a status change made through the cache", ()=>{
142
+ const presenter = createPresenter();
143
+ revisionsCache.addItems([
144
+ createRevision("page-1#0001", "page-1", 1, "2026-09-20T00:00:00.000Z")
145
+ ]);
146
+ presenter.init({
147
+ entryId: "page-1"
148
+ });
149
+ expect(presenter.vm.revisions[0].revision.status).toEqual(WbPageStatus.Draft);
150
+ revisionsCache.updateItems((revision)=>"page-1#0001" === revision.id ? revision.withStatus(WbPageStatus.Unpublished) : revision);
151
+ expect(presenter.vm.revisions[0].revision.status).toEqual(WbPageStatus.Unpublished);
152
+ expect(getPageRevisions.execute).toHaveBeenCalledTimes(1);
153
+ });
154
+ describe("capabilities", ()=>{
155
+ const initWith = (status, locked = false)=>{
156
+ const revision = PageRevision.create({
157
+ id: "page-1#0001",
158
+ entryId: "page-1",
159
+ version: 1,
160
+ status,
161
+ locked,
162
+ savedOn: "2026-09-20T00:00:00.000Z",
163
+ title: "Page 1",
164
+ createdBy: {
165
+ id: "admin",
166
+ displayName: "Admin",
167
+ type: "admin"
168
+ },
169
+ createdOn: "2026-09-20T00:00:00.000Z",
170
+ revisionDescription: void 0
171
+ });
172
+ revisionsCache.addItems([
173
+ revision
174
+ ]);
175
+ const presenter = createPresenter();
176
+ presenter.init({
177
+ entryId: "page-1"
178
+ });
179
+ return presenter.vm.revisions[0];
180
+ };
181
+ it("should allow publishing a draft, but not unpublishing it", ()=>{
182
+ const item = initWith(WbPageStatus.Draft);
183
+ expect(item.canPublish).toBeTrue();
184
+ expect(item.canUnpublish).toBeFalse();
185
+ });
186
+ it("should allow unpublishing a published revision, but not publishing it again", ()=>{
187
+ const item = initWith(WbPageStatus.Published);
188
+ expect(item.canPublish).toBeFalse();
189
+ expect(item.canUnpublish).toBeTrue();
190
+ });
191
+ it("should not allow editing a locked revision", ()=>{
192
+ const item = initWith(WbPageStatus.Unpublished, true);
193
+ expect(item.canEdit).toBeFalse();
194
+ expect(item.canCreateFrom).toBeTrue();
195
+ });
196
+ it("should allow deleting a locked revision, matching the API", ()=>{
197
+ const item = initWith(WbPageStatus.Published, true);
198
+ expect(item.canDelete).toBeTrue();
199
+ });
200
+ it("should respect the permissions", ()=>{
201
+ permissions.canEdit.mockReturnValue(false);
202
+ permissions.canDelete.mockReturnValue(false);
203
+ permissions.canPublish.mockReturnValue(false);
204
+ const item = initWith(WbPageStatus.Draft);
205
+ expect(item.canCreateFrom).toBeFalse();
206
+ expect(item.canEdit).toBeFalse();
207
+ expect(item.canPublish).toBeFalse();
208
+ expect(item.canDelete).toBeFalse();
209
+ });
210
+ it("should check delete permission against the revision itself", ()=>{
211
+ initWith(WbPageStatus.Draft);
212
+ expect(permissions.canDelete).toHaveBeenCalledWith("page", expect.objectContaining({
213
+ id: "page-1#0001"
214
+ }));
215
+ });
216
+ });
217
+ });
218
+
219
+ //# sourceMappingURL=RevisionListPresenter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/pages/RevisionList/RevisionListPresenter.test.js","sources":["../../../../src/presentation/pages/RevisionList/RevisionListPresenter.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { WbPageStatus, type WbStatus } from \"~/constants.js\";\nimport { PageRevision, pageRevisionsCacheFactory } from \"~/domain/PageRevision/index.js\";\nimport { GetPageRevisionsUseCase } from \"~/features/pages/getPageRevisions/abstractions.js\";\nimport {\n PageRevisionsCache,\n WbPageLoadingRepository,\n WbPageRevisionsLoadingRepository\n} from \"~/features/pages/shared/abstractions.js\";\nimport { WbPermissions } from \"~/features/permissions/abstractions.js\";\nimport { RevisionListPresenter as PresenterAbstraction } from \"./abstractions.js\";\nimport { RevisionListPresenter } from \"./RevisionListPresenter.js\";\n\nconst createRevision = (id: string, entryId: string, version: number, savedOn: string) => {\n return PageRevision.create({\n id,\n entryId,\n version,\n savedOn,\n status: WbPageStatus.Draft,\n title: `Page ${entryId}`,\n locked: false,\n createdBy: { id: \"admin\", displayName: \"Admin\", type: \"admin\" },\n createdOn: savedOn,\n revisionDescription: undefined\n });\n};\n\ndescribe(\"RevisionListPresenter\", () => {\n const revisionsCache = pageRevisionsCacheFactory.getCache();\n\n const getPageRevisions = {\n execute: vi.fn().mockResolvedValue([])\n };\n\n const loadingRepository = {\n isLoading: vi.fn().mockReturnValue(false)\n };\n\n const pageLoadingRepository = {\n isLoading: vi.fn().mockReturnValue(false)\n };\n\n const permissions = {\n canEdit: vi.fn().mockReturnValue(true),\n canDelete: vi.fn().mockReturnValue(true),\n canPublish: vi.fn().mockReturnValue(true),\n canUnpublish: vi.fn().mockReturnValue(true)\n };\n\n const createPresenter = () => {\n const container = new Container();\n container.registerInstance(PageRevisionsCache, revisionsCache);\n container.registerInstance(\n WbPageRevisionsLoadingRepository,\n loadingRepository as unknown as WbPageRevisionsLoadingRepository.Interface\n );\n container.registerInstance(\n WbPageLoadingRepository,\n pageLoadingRepository as unknown as WbPageLoadingRepository.Interface\n );\n container.registerInstance(\n WbPermissions,\n permissions as unknown as WbPermissions.Interface\n );\n container.registerInstance(GetPageRevisionsUseCase, getPageRevisions);\n container.register(RevisionListPresenter).inSingletonScope();\n\n return container.resolve(PresenterAbstraction);\n };\n\n beforeEach(() => {\n vi.clearAllMocks();\n loadingRepository.isLoading.mockReturnValue(false);\n pageLoadingRepository.isLoading.mockReturnValue(false);\n permissions.canEdit.mockReturnValue(true);\n permissions.canDelete.mockReturnValue(true);\n permissions.canPublish.mockReturnValue(true);\n permissions.canUnpublish.mockReturnValue(true);\n revisionsCache.clear();\n });\n\n it(\"should fetch the revisions when initialized\", () => {\n const presenter = createPresenter();\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(getPageRevisions.execute).toHaveBeenCalledTimes(1);\n expect(getPageRevisions.execute).toHaveBeenCalledWith({ entryId: \"page-1\" });\n });\n\n it(\"should not refetch the revisions when initialized with the same entry\", () => {\n const presenter = createPresenter();\n\n presenter.init({ entryId: \"page-1\" });\n presenter.init({ entryId: \"page-1\" });\n\n expect(getPageRevisions.execute).toHaveBeenCalledTimes(1);\n\n presenter.init({ entryId: \"page-2\" });\n\n expect(getPageRevisions.execute).toHaveBeenCalledTimes(2);\n });\n\n it(\"should only expose the revisions of the current page, newest first\", () => {\n const presenter = createPresenter();\n\n revisionsCache.addItems([\n createRevision(\"page-1#0001\", \"page-1\", 1, \"2026-09-20T00:00:00.000Z\"),\n createRevision(\"page-1#0002\", \"page-1\", 2, \"2026-09-22T00:00:00.000Z\"),\n createRevision(\"page-2#0001\", \"page-2\", 1, \"2026-09-21T00:00:00.000Z\")\n ]);\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(presenter.vm.revisions.map(item => item.revision.id)).toEqual([\n \"page-1#0002\",\n \"page-1#0001\"\n ]);\n expect(presenter.vm.isEmpty).toBeFalse();\n });\n\n it(\"should not report an empty list while loading\", () => {\n loadingRepository.isLoading.mockReturnValue(true);\n const presenter = createPresenter();\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(presenter.vm.revisions).toBeEmpty();\n expect(presenter.vm.isLoading).toBeTrue();\n expect(presenter.vm.isEmpty).toBeFalse();\n });\n\n it(\"should report a mutation in progress\", () => {\n pageLoadingRepository.isLoading.mockImplementation(\n action => action === \"CREATE_REVISION_FROM\"\n );\n const presenter = createPresenter();\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(presenter.vm.isMutating).toBeTrue();\n });\n\n it.each([\"PUBLISH\", \"UNPUBLISH\", \"DELETE\"])(\n \"should not report a mutation for %s, which is confirmed through a dialog\",\n action => {\n // Those dialogs show their own loader, so a second one on the drawer is just noise.\n pageLoadingRepository.isLoading.mockImplementation(a => a === action);\n const presenter = createPresenter();\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(presenter.vm.isMutating).toBeFalse();\n }\n );\n\n it(\"should not report a mutation for unrelated page actions\", () => {\n // The \"WbPage\" namespace is shared with the pages table.\n pageLoadingRepository.isLoading.mockImplementation(action => action === \"LIST\");\n const presenter = createPresenter();\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(presenter.vm.isMutating).toBeFalse();\n });\n\n it(\"should reflect a status change made through the cache\", () => {\n // The revisions menu and the drawer share this presenter, so a mutation made in one of\n // them must be visible in the other without a refetch.\n const presenter = createPresenter();\n\n revisionsCache.addItems([\n createRevision(\"page-1#0001\", \"page-1\", 1, \"2026-09-20T00:00:00.000Z\")\n ]);\n\n presenter.init({ entryId: \"page-1\" });\n\n expect(presenter.vm.revisions[0].revision.status).toEqual(WbPageStatus.Draft);\n\n revisionsCache.updateItems(revision =>\n revision.id === \"page-1#0001\" ? revision.withStatus(WbPageStatus.Unpublished) : revision\n );\n\n expect(presenter.vm.revisions[0].revision.status).toEqual(WbPageStatus.Unpublished);\n expect(getPageRevisions.execute).toHaveBeenCalledTimes(1);\n });\n\n describe(\"capabilities\", () => {\n const initWith = (status: WbStatus, locked = false) => {\n const revision = PageRevision.create({\n id: \"page-1#0001\",\n entryId: \"page-1\",\n version: 1,\n status,\n locked,\n savedOn: \"2026-09-20T00:00:00.000Z\",\n title: \"Page 1\",\n createdBy: { id: \"admin\", displayName: \"Admin\", type: \"admin\" },\n createdOn: \"2026-09-20T00:00:00.000Z\",\n revisionDescription: undefined\n });\n revisionsCache.addItems([revision]);\n\n const presenter = createPresenter();\n presenter.init({ entryId: \"page-1\" });\n return presenter.vm.revisions[0];\n };\n\n it(\"should allow publishing a draft, but not unpublishing it\", () => {\n const item = initWith(WbPageStatus.Draft);\n\n expect(item.canPublish).toBeTrue();\n expect(item.canUnpublish).toBeFalse();\n });\n\n it(\"should allow unpublishing a published revision, but not publishing it again\", () => {\n const item = initWith(WbPageStatus.Published);\n\n expect(item.canPublish).toBeFalse();\n expect(item.canUnpublish).toBeTrue();\n });\n\n it(\"should not allow editing a locked revision\", () => {\n const item = initWith(WbPageStatus.Unpublished, true);\n\n expect(item.canEdit).toBeFalse();\n // Creating a new revision from a locked one is still fine.\n expect(item.canCreateFrom).toBeTrue();\n });\n\n it(\"should allow deleting a locked revision, matching the API\", () => {\n const item = initWith(WbPageStatus.Published, true);\n\n expect(item.canDelete).toBeTrue();\n });\n\n it(\"should respect the permissions\", () => {\n permissions.canEdit.mockReturnValue(false);\n permissions.canDelete.mockReturnValue(false);\n permissions.canPublish.mockReturnValue(false);\n\n const item = initWith(WbPageStatus.Draft);\n\n expect(item.canCreateFrom).toBeFalse();\n expect(item.canEdit).toBeFalse();\n expect(item.canPublish).toBeFalse();\n expect(item.canDelete).toBeFalse();\n });\n\n it(\"should check delete permission against the revision itself\", () => {\n initWith(WbPageStatus.Draft);\n\n // Ownership is per revision, so the row must be passed to the permission check.\n expect(permissions.canDelete).toHaveBeenCalledWith(\n \"page\",\n expect.objectContaining({ id: \"page-1#0001\" })\n );\n });\n });\n});\n"],"names":["createRevision","id","entryId","version","savedOn","PageRevision","WbPageStatus","undefined","describe","revisionsCache","pageRevisionsCacheFactory","getPageRevisions","vi","loadingRepository","pageLoadingRepository","permissions","createPresenter","container","Container","PageRevisionsCache","WbPageRevisionsLoadingRepository","WbPageLoadingRepository","WbPermissions","GetPageRevisionsUseCase","RevisionListPresenter","PresenterAbstraction","beforeEach","it","presenter","expect","item","action","a","revision","initWith","status","locked"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { PageRevision } from "../../../domain/PageRevision/PageRevision.js";
2
+ export interface IRevisionListPresenterInit {
3
+ entryId: string;
4
+ }
5
+ /**
6
+ * A revision plus what may be done to it. Capabilities are part of the view model so that the
7
+ * view never derives policy, and so that other apps can restrict actions by decorating this
8
+ * presenter instead of the individual menu items.
9
+ */
10
+ export interface IRevisionListItemVm {
11
+ revision: PageRevision;
12
+ canCreateFrom: boolean;
13
+ canEdit: boolean;
14
+ canPublish: boolean;
15
+ canUnpublish: boolean;
16
+ canDelete: boolean;
17
+ }
18
+ export interface IRevisionListVm {
19
+ revisions: IRevisionListItemVm[];
20
+ isLoading: boolean;
21
+ isMutating: boolean;
22
+ isEmpty: boolean;
23
+ }
24
+ export interface IRevisionListPresenter {
25
+ init(params: IRevisionListPresenterInit): void;
26
+ vm: IRevisionListVm;
27
+ }
28
+ export declare const RevisionListPresenter: import("@webiny/di").Abstraction<IRevisionListPresenter>;
29
+ export declare namespace RevisionListPresenter {
30
+ type Interface = IRevisionListPresenter;
31
+ type Init = IRevisionListPresenterInit;
32
+ type ViewModel = IRevisionListVm;
33
+ type ItemViewModel = IRevisionListItemVm;
34
+ }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/admin";
2
+ const RevisionListPresenter = createAbstraction("WebsiteBuilder/RevisionListPresenter");
3
+ export { RevisionListPresenter };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/pages/RevisionList/abstractions.js","sources":["../../../../src/presentation/pages/RevisionList/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { PageRevision } from \"~/domain/PageRevision/PageRevision.js\";\n\nexport interface IRevisionListPresenterInit {\n entryId: string;\n}\n\n/**\n * A revision plus what may be done to it. Capabilities are part of the view model so that the\n * view never derives policy, and so that other apps can restrict actions by decorating this\n * presenter instead of the individual menu items.\n */\nexport interface IRevisionListItemVm {\n revision: PageRevision;\n canCreateFrom: boolean;\n canEdit: boolean;\n canPublish: boolean;\n canUnpublish: boolean;\n canDelete: boolean;\n}\n\nexport interface IRevisionListVm {\n revisions: IRevisionListItemVm[];\n isLoading: boolean;\n isMutating: boolean;\n isEmpty: boolean;\n}\n\nexport interface IRevisionListPresenter {\n init(params: IRevisionListPresenterInit): void;\n vm: IRevisionListVm;\n}\n\nexport const RevisionListPresenter = createAbstraction<IRevisionListPresenter>(\n \"WebsiteBuilder/RevisionListPresenter\"\n);\n\nexport namespace RevisionListPresenter {\n export type Interface = IRevisionListPresenter;\n export type Init = IRevisionListPresenterInit;\n export type ViewModel = IRevisionListVm;\n export type ItemViewModel = IRevisionListItemVm;\n}\n"],"names":["RevisionListPresenter","createAbstraction"],"mappings":";AAiCO,MAAMA,wBAAwBC,kBACjC"}
@@ -0,0 +1,3 @@
1
+ export declare const RevisionListFeature: import("@webiny/feature/admin").FeatureDefinition<{
2
+ presenter: import("./abstractions.js").IRevisionListPresenter;
3
+ }, []>;
@@ -0,0 +1,17 @@
1
+ import { createFeature } from "@webiny/feature/admin";
2
+ import { RevisionListPresenter } from "./abstractions.js";
3
+ import { RevisionListPresenter as external_RevisionListPresenter_js_RevisionListPresenter } from "./RevisionListPresenter.js";
4
+ const RevisionListFeature = createFeature({
5
+ name: "WebsiteBuilder/RevisionList",
6
+ register (container) {
7
+ container.register(external_RevisionListPresenter_js_RevisionListPresenter).inSingletonScope();
8
+ },
9
+ resolve (container) {
10
+ return {
11
+ presenter: container.resolve(RevisionListPresenter)
12
+ };
13
+ }
14
+ });
15
+ export { RevisionListFeature };
16
+
17
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/pages/RevisionList/feature.js","sources":["../../../../src/presentation/pages/RevisionList/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { RevisionListPresenter as PresenterAbstraction } from \"./abstractions.js\";\nimport { RevisionListPresenter } from \"./RevisionListPresenter.js\";\n\nexport const RevisionListFeature = createFeature({\n name: \"WebsiteBuilder/RevisionList\",\n register(container) {\n container.register(RevisionListPresenter).inSingletonScope();\n },\n resolve(container) {\n return { presenter: container.resolve(PresenterAbstraction) };\n }\n});\n"],"names":["RevisionListFeature","createFeature","container","RevisionListPresenter","PresenterAbstraction"],"mappings":";;;AAIO,MAAMA,sBAAsBC,cAAc;IAC7C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,yDAAuB,gBAAgB;IAC9D;IACA,SAAQD,SAAS;QACb,OAAO;YAAE,WAAWA,UAAU,OAAO,CAACE;QAAsB;IAChE;AACJ"}
@@ -0,0 +1,2 @@
1
+ export { RevisionListFeature } from "./feature.js";
2
+ export type { IRevisionListVm } from "./abstractions.js";
@@ -0,0 +1 @@
1
+ export { RevisionListFeature } from "./feature.js";
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
- export declare const WbTrashBin: (() => React.JSX.Element | null) & {
3
- displayName: string;
2
+ export declare const WbTrashBin: (() => React.JSX.Element | null) & React.NamedExoticComponent<unknown> & {
3
+ readonly type: () => React.JSX.Element | null;
4
4
  };
@@ -7,7 +7,7 @@ class RedirectListDataSource extends FolderAwareDataSource {
7
7
  }), this.listRedirectsUseCase = listRedirectsUseCase, this.cache = cache;
8
8
  }
9
9
  get rows() {
10
- return this.queryMatcher.filter(this.cache.getItems());
10
+ return this.queryMatcher.select(this.cache.getItems());
11
11
  }
12
12
  async fetch(params) {
13
13
  return this.listRedirectsUseCase.execute({
@@ -1 +1 @@
1
- {"version":3,"file":"presentation/redirects/RedirectList/RedirectListDataSource.js","sources":["../../../../src/presentation/redirects/RedirectList/RedirectListDataSource.ts"],"sourcesContent":["import { FolderAwareDataSource } from \"@webiny/app-admin/presentation/listPresenter/FolderAwareDataSource.js\";\nimport type {\n FetchParams,\n FetchResult\n} from \"@webiny/app-admin/presentation/listPresenter/FolderAwareDataSource.js\";\nimport type { IListRedirectsUseCase } from \"~/features/redirects/listRedirects/abstractions.js\";\nimport type { IGetDescendantFoldersUseCase } from \"@webiny/app-aco/features/folders/getDescendantFolders/abstractions.js\";\nimport type { IListCache } from \"@webiny/app-admin/features/listCache/index.js\";\nimport type { Redirect } from \"~/domain/Redirect/Redirect.js\";\n\nexport class RedirectListDataSource extends FolderAwareDataSource<Redirect> {\n constructor(\n private listRedirectsUseCase: IListRedirectsUseCase,\n private cache: IListCache<Redirect>,\n getDescendantFoldersUseCase?: IGetDescendantFoldersUseCase\n ) {\n super({\n keyField: \"id\",\n getDescendantFolders: getDescendantFoldersUseCase\n });\n }\n\n get rows(): Redirect[] {\n return this.queryMatcher.filter(this.cache.getItems());\n }\n\n async fetch(params: FetchParams): Promise<FetchResult<Redirect>> {\n return this.listRedirectsUseCase.execute({\n search: params.search,\n where: params.where,\n sort: params.sort,\n limit: params.limit,\n after: params.after\n });\n }\n}\n"],"names":["RedirectListDataSource","FolderAwareDataSource","listRedirectsUseCase","cache","getDescendantFoldersUseCase","params"],"mappings":";AAUO,MAAMA,+BAA+BC;IACxC,YACYC,oBAA2C,EAC3CC,KAA2B,EACnCC,2BAA0D,CAC5D;QACE,KAAK,CAAC;YACF,UAAU;YACV,sBAAsBA;QAC1B,SAPQF,oBAAoB,GAApBA,sBAAAA,IAAAA,CACAC,KAAK,GAALA;IAOZ;IAEA,IAAI,OAAmB;QACnB,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;IACvD;IAEA,MAAM,MAAME,MAAmB,EAAkC;QAC7D,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;YACrC,QAAQA,OAAO,MAAM;YACrB,OAAOA,OAAO,KAAK;YACnB,MAAMA,OAAO,IAAI;YACjB,OAAOA,OAAO,KAAK;YACnB,OAAOA,OAAO,KAAK;QACvB;IACJ;AACJ"}
1
+ {"version":3,"file":"presentation/redirects/RedirectList/RedirectListDataSource.js","sources":["../../../../src/presentation/redirects/RedirectList/RedirectListDataSource.ts"],"sourcesContent":["import { FolderAwareDataSource } from \"@webiny/app-admin/presentation/listPresenter/FolderAwareDataSource.js\";\nimport type {\n FetchParams,\n FetchResult\n} from \"@webiny/app-admin/presentation/listPresenter/FolderAwareDataSource.js\";\nimport type { IListRedirectsUseCase } from \"~/features/redirects/listRedirects/abstractions.js\";\nimport type { IGetDescendantFoldersUseCase } from \"@webiny/app-aco/features/folders/getDescendantFolders/abstractions.js\";\nimport type { IListCache } from \"@webiny/app-admin/features/listCache/index.js\";\nimport type { Redirect } from \"~/domain/Redirect/Redirect.js\";\n\nexport class RedirectListDataSource extends FolderAwareDataSource<Redirect> {\n constructor(\n private listRedirectsUseCase: IListRedirectsUseCase,\n private cache: IListCache<Redirect>,\n getDescendantFoldersUseCase?: IGetDescendantFoldersUseCase\n ) {\n super({\n keyField: \"id\",\n getDescendantFolders: getDescendantFoldersUseCase\n });\n }\n\n get rows(): Redirect[] {\n return this.queryMatcher.select(this.cache.getItems());\n }\n\n async fetch(params: FetchParams): Promise<FetchResult<Redirect>> {\n return this.listRedirectsUseCase.execute({\n search: params.search,\n where: params.where,\n sort: params.sort,\n limit: params.limit,\n after: params.after\n });\n }\n}\n"],"names":["RedirectListDataSource","FolderAwareDataSource","listRedirectsUseCase","cache","getDescendantFoldersUseCase","params"],"mappings":";AAUO,MAAMA,+BAA+BC;IACxC,YACYC,oBAA2C,EAC3CC,KAA2B,EACnCC,2BAA0D,CAC5D;QACE,KAAK,CAAC;YACF,UAAU;YACV,sBAAsBA;QAC1B,SAPQF,oBAAoB,GAApBA,sBAAAA,IAAAA,CACAC,KAAK,GAALA;IAOZ;IAEA,IAAI,OAAmB;QACnB,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;IACvD;IAEA,MAAM,MAAME,MAAmB,EAAkC;QAC7D,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;YACrC,QAAQA,OAAO,MAAM;YACrB,OAAOA,OAAO,KAAK;YACnB,MAAMA,OAAO,IAAI;YACjB,OAAOA,OAAO,KAAK;YACnB,OAAOA,OAAO,KAAK;QACvB;IACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"presentation/redirects/RedirectList/RedirectListPresenter.js","sources":["../../../../src/presentation/redirects/RedirectList/RedirectListPresenter.ts"],"sourcesContent":["import { makeAutoObservable, reaction, computed } from \"mobx\";\nimport { Worker } from \"@webiny/app-admin\";\nimport { ListPresenter } from \"@webiny/app-admin/presentation/listPresenter/abstractions.js\";\nimport { FolderTreePresenter } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport { sortFolders } from \"@webiny/app-aco\";\nimport { GetDescendantFoldersUseCase } from \"@webiny/app-aco/features/folders/getDescendantFolders/abstractions.js\";\nimport { ListRedirectsUseCase } from \"~/features/redirects/listRedirects/abstractions.js\";\nimport { RedirectsListCache } from \"~/features/redirects/shared/abstractions.js\";\nimport {\n RedirectListPresenter as Abstraction,\n type IRedirectListPresenter,\n type IRedirectListViewModel,\n type IRedirectListActions,\n type IRedirectListInitConfig,\n CreateRedirectPresenter\n} from \"./abstractions.js\";\nimport { RedirectListDataSource } from \"./RedirectListDataSource.js\";\nimport type { Redirect } from \"~/domain/Redirect/Redirect.js\";\nimport { EditRedirectPresenter } from \"./abstractions.js\";\n\nclass RedirectListPresenterImpl implements IRedirectListPresenter {\n public readonly actions: IRedirectListActions;\n private _showingFilters = false;\n private _disposeReaction: (() => void) | null = null;\n private _createRedirect: CreateRedirectPresenter.Interface | null = null;\n private _editRedirect: EditRedirectPresenter.Interface | null = null;\n private _worker = new Worker<Redirect>();\n\n constructor(\n private listPresenter: ListPresenter.Interface<Redirect>,\n private folderTreePresenter: FolderTreePresenter.Interface,\n private createRedirectPresenter: CreateRedirectPresenter.Interface,\n private editRedirectPresenter: EditRedirectPresenter.Interface,\n private listRedirectsUseCase: ListRedirectsUseCase.Interface,\n private redirectsListCache: RedirectsListCache.Interface,\n private getDescendantFoldersUseCase: GetDescendantFoldersUseCase.Interface\n ) {\n this.actions = this.createActions();\n makeAutoObservable<RedirectListPresenterImpl, \"_disposeReaction\">(this, {\n _disposeReaction: false,\n vm: computed\n });\n }\n\n get vm(): IRedirectListViewModel {\n return {\n list: this.listPresenter.vm,\n folders: this.folderTreePresenter.vm,\n createRedirect: this._createRedirect,\n editRedirect: this._editRedirect,\n showFolders: this.shouldShowFolders(),\n childFolders: this.getSortedChildFolders(),\n showingFilters: this._showingFilters\n };\n }\n\n init(config?: IRedirectListInitConfig): void {\n const initialFolderId = config?.initialFolderId ?? \"root\";\n\n const dataSource = new RedirectListDataSource(\n this.listRedirectsUseCase,\n this.redirectsListCache,\n this.getDescendantFoldersUseCase\n );\n\n this.listPresenter.init({\n dataSource,\n initialSort: { field: \"createdOn\", direction: \"DESC\" },\n initialFilters: { folderId: initialFolderId },\n limit: 50\n });\n\n if (initialFolderId !== \"root\") {\n this.folderTreePresenter.selectFolder(initialFolderId);\n }\n\n this._disposeReaction = reaction(\n () => this.folderTreePresenter.vm.currentFolderId,\n folderId => {\n const effectiveFolderId = folderId ?? \"root\";\n this.listPresenter.actions.filter.set(\"folderId\", effectiveFolderId);\n }\n );\n }\n\n dispose(): void {\n if (this._disposeReaction) {\n this._disposeReaction();\n this._disposeReaction = null;\n }\n }\n\n private createActions(): IRedirectListActions {\n return {\n search: {\n set: (query: string) => this.listPresenter.actions.search.set(query),\n clear: () => this.listPresenter.actions.search.clear()\n },\n sort: {\n set: (field: string, direction: \"ASC\" | \"DESC\") =>\n this.listPresenter.actions.sort.set(field, direction),\n toggle: (field: string) => this.listPresenter.actions.sort.toggle(field)\n },\n filter: {\n show: () => this.listPresenter.actions.filter.show(),\n hide: () => this.listPresenter.actions.filter.hide(),\n set: (key: string, value: unknown) =>\n this.listPresenter.actions.filter.set(key, value),\n clear: (key: string) => this.listPresenter.actions.filter.clear(key),\n clearAll: () => this.listPresenter.actions.filter.clearAll()\n },\n selection: {\n toggle: (id: string) => this.listPresenter.actions.selection.toggle(id),\n selectRangeTo: (id: string) =>\n this.listPresenter.actions.selection.selectRangeTo(id),\n selectAll: () => this.listPresenter.actions.selection.selectAll(),\n deselectAll: () => this.listPresenter.actions.selection.deselectAll(),\n selectRows: (ids: string[]) => this.listPresenter.actions.selection.selectRows(ids),\n isSelected: (id: string) => this.listPresenter.actions.selection.isSelected(id)\n },\n worker: this.createWorkerActions(),\n loadMore: () => this.listPresenter.actions.loadMore(),\n refresh: () => this.listPresenter.actions.refresh(),\n showFilters: () => {\n this._showingFilters = true;\n },\n hideFilters: () => {\n this._showingFilters = false;\n },\n showCreateDialog: (folderId: string) => {\n this._createRedirect = this.createRedirectPresenter;\n this.createRedirectPresenter.init(folderId);\n },\n showEditDialog: (redirectId: string) => {\n this._editRedirect = this.editRedirectPresenter;\n void this.editRedirectPresenter.loadRedirect(redirectId);\n },\n hideCreateDialog: () => {\n this._createRedirect = null;\n },\n hideEditDialog: () => {\n this._editRedirect = null;\n },\n folders: {\n selectFolder: (folderId: string | null) => {\n this.listPresenter.actions.search.clear();\n this.folderTreePresenter.selectFolder(folderId);\n },\n createFolder: (parentFolderId?: string) =>\n this.folderTreePresenter.createFolder(parentFolderId),\n editFolder: (folderId: string) => this.folderTreePresenter.editFolder(folderId),\n deleteFolder: (folderId: string) => this.folderTreePresenter.deleteFolder(folderId),\n moveFolder: (folderId: string, targetParentId: string | null) =>\n this.folderTreePresenter.moveFolder(folderId, targetParentId),\n loadChildFolders: (parentIds: string[]) =>\n this.folderTreePresenter.loadChildFolders(parentIds),\n canManageStructure: (folderId: string) =>\n this.folderTreePresenter.canManageStructure(folderId),\n getAncestorIds: (folderId: string) =>\n this.folderTreePresenter.getAncestorIds(folderId),\n submitOperation: () => this.folderTreePresenter.submitOperation(),\n cancelOperation: () => this.folderTreePresenter.cancelOperation()\n }\n };\n }\n\n private getSelectedRows(): Redirect[] {\n const ids = this.listPresenter.vm.selection.selectedIds;\n return this.listPresenter.vm.rows.filter(r => ids.has(r.id));\n }\n\n private createWorkerActions(): IRedirectListActions[\"worker\"] {\n const worker = this._worker;\n return {\n process: (callback: (items: Redirect[]) => void) => {\n worker.process(this.getSelectedRows(), callback);\n },\n processInSeries: async (callback, chunkSize?) => {\n await worker.processInSeries(this.getSelectedRows(), callback, chunkSize);\n },\n get results() {\n return worker.results;\n },\n resetResults: () => worker.resetResults()\n };\n }\n\n private getSortedChildFolders() {\n if (!this.shouldShowFolders()) {\n return [];\n }\n return sortFolders(\n this.folderTreePresenter.vm.childFolders ?? [],\n this.listPresenter.vm.appliedQuery?.sort\n );\n }\n\n private shouldShowFolders(): boolean {\n const { appliedQuery } = this.listPresenter.vm;\n if (!appliedQuery) {\n return true;\n }\n\n if (appliedQuery.search) {\n return false;\n }\n\n const filterKeys = Object.keys(appliedQuery.filters ?? {}).filter(k => k !== \"folderId\");\n if (filterKeys.length > 0) {\n return false;\n }\n\n return true;\n }\n}\n\nexport const RedirectListPresenter = Abstraction.createImplementation({\n implementation: RedirectListPresenterImpl,\n dependencies: [\n ListPresenter,\n FolderTreePresenter,\n CreateRedirectPresenter,\n EditRedirectPresenter,\n ListRedirectsUseCase,\n RedirectsListCache,\n GetDescendantFoldersUseCase\n ]\n});\n"],"names":["RedirectListPresenterImpl","listPresenter","folderTreePresenter","createRedirectPresenter","editRedirectPresenter","listRedirectsUseCase","redirectsListCache","getDescendantFoldersUseCase","Worker","makeAutoObservable","computed","config","initialFolderId","dataSource","RedirectListDataSource","reaction","folderId","effectiveFolderId","query","field","direction","key","value","id","ids","redirectId","parentFolderId","targetParentId","parentIds","r","worker","callback","chunkSize","sortFolders","appliedQuery","filterKeys","Object","k","RedirectListPresenter","Abstraction","ListPresenter","FolderTreePresenter","CreateRedirectPresenter","EditRedirectPresenter","ListRedirectsUseCase","RedirectsListCache","GetDescendantFoldersUseCase"],"mappings":"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"}
1
+ {"version":3,"file":"presentation/redirects/RedirectList/RedirectListPresenter.js","sources":["../../../../src/presentation/redirects/RedirectList/RedirectListPresenter.ts"],"sourcesContent":["import { makeAutoObservable, reaction, computed } from \"mobx\";\nimport { Worker } from \"@webiny/app-admin\";\nimport { ListPresenter } from \"@webiny/app-admin/presentation/listPresenter/abstractions.js\";\nimport { FolderTreePresenter } from \"@webiny/app-aco/presentation/folderTree/abstractions.js\";\nimport { sortFolders } from \"@webiny/app-aco\";\nimport { GetDescendantFoldersUseCase } from \"@webiny/app-aco/features/folders/getDescendantFolders/abstractions.js\";\nimport { ListRedirectsUseCase } from \"~/features/redirects/listRedirects/abstractions.js\";\nimport { RedirectsListCache } from \"~/features/redirects/shared/abstractions.js\";\nimport {\n RedirectListPresenter as Abstraction,\n type IRedirectListPresenter,\n type IRedirectListViewModel,\n type IRedirectListActions,\n type IRedirectListInitConfig,\n CreateRedirectPresenter\n} from \"./abstractions.js\";\nimport { RedirectListDataSource } from \"./RedirectListDataSource.js\";\nimport type { Redirect } from \"~/domain/Redirect/Redirect.js\";\nimport { EditRedirectPresenter } from \"./abstractions.js\";\n\nclass RedirectListPresenterImpl implements IRedirectListPresenter {\n public readonly actions: IRedirectListActions;\n private _showingFilters = false;\n private _disposeReaction: (() => void) | null = null;\n private _createRedirect: CreateRedirectPresenter.Interface | null = null;\n private _editRedirect: EditRedirectPresenter.Interface | null = null;\n private _worker = new Worker<Redirect>();\n\n constructor(\n private listPresenter: ListPresenter.Interface<Redirect>,\n private folderTreePresenter: FolderTreePresenter.Interface,\n private createRedirectPresenter: CreateRedirectPresenter.Interface,\n private editRedirectPresenter: EditRedirectPresenter.Interface,\n private listRedirectsUseCase: ListRedirectsUseCase.Interface,\n private redirectsListCache: RedirectsListCache.Interface,\n private getDescendantFoldersUseCase: GetDescendantFoldersUseCase.Interface\n ) {\n this.actions = this.createActions();\n makeAutoObservable<RedirectListPresenterImpl, \"_disposeReaction\">(this, {\n _disposeReaction: false,\n vm: computed\n });\n }\n\n get vm(): IRedirectListViewModel {\n return {\n list: this.listPresenter.vm,\n folders: this.folderTreePresenter.vm,\n createRedirect: this._createRedirect,\n editRedirect: this._editRedirect,\n showFolders: this.shouldShowFolders(),\n childFolders: this.getSortedChildFolders(),\n showingFilters: this._showingFilters\n };\n }\n\n init(config?: IRedirectListInitConfig): void {\n const initialFolderId = config?.initialFolderId ?? \"root\";\n\n const dataSource = new RedirectListDataSource(\n this.listRedirectsUseCase,\n this.redirectsListCache,\n this.getDescendantFoldersUseCase\n );\n\n this.listPresenter.init({\n dataSource,\n initialSort: { field: \"createdOn\", direction: \"DESC\" },\n initialFilters: { folderId: initialFolderId },\n limit: 50\n });\n\n if (initialFolderId !== \"root\") {\n this.folderTreePresenter.selectFolder(initialFolderId);\n }\n\n this._disposeReaction = reaction(\n () => this.folderTreePresenter.vm.currentFolderId,\n folderId => {\n const effectiveFolderId = folderId ?? \"root\";\n this.listPresenter.actions.filter.set(\"folderId\", effectiveFolderId);\n }\n );\n }\n\n dispose(): void {\n if (this._disposeReaction) {\n this._disposeReaction();\n this._disposeReaction = null;\n }\n }\n\n private createActions(): IRedirectListActions {\n return {\n search: {\n set: (query: string) => this.listPresenter.actions.search.set(query),\n clear: () => this.listPresenter.actions.search.clear()\n },\n sort: {\n set: (field: string, direction: \"ASC\" | \"DESC\") =>\n this.listPresenter.actions.sort.set(field, direction),\n toggle: (field: string) => this.listPresenter.actions.sort.toggle(field)\n },\n filter: {\n show: () => this.listPresenter.actions.filter.show(),\n hide: () => this.listPresenter.actions.filter.hide(),\n set: (key: string, value: unknown) =>\n this.listPresenter.actions.filter.set(key, value),\n clear: (key: string) => this.listPresenter.actions.filter.clear(key),\n clearAll: () => this.listPresenter.actions.filter.clearAll()\n },\n selection: {\n toggle: (id: string) => this.listPresenter.actions.selection.toggle(id),\n selectRangeTo: (id: string) =>\n this.listPresenter.actions.selection.selectRangeTo(id),\n selectAll: () => this.listPresenter.actions.selection.selectAll(),\n deselectAll: () => this.listPresenter.actions.selection.deselectAll(),\n selectRows: (ids: string[]) => this.listPresenter.actions.selection.selectRows(ids),\n isSelected: (id: string) => this.listPresenter.actions.selection.isSelected(id)\n },\n worker: this.createWorkerActions(),\n loadMore: () => this.listPresenter.actions.loadMore(),\n refresh: () => this.listPresenter.actions.refresh(),\n showFilters: () => {\n this._showingFilters = true;\n },\n hideFilters: () => {\n this._showingFilters = false;\n },\n showCreateDialog: (folderId: string) => {\n this._createRedirect = this.createRedirectPresenter;\n this.createRedirectPresenter.init(folderId);\n },\n showEditDialog: (redirectId: string) => {\n this._editRedirect = this.editRedirectPresenter;\n void this.editRedirectPresenter.loadRedirect(redirectId);\n },\n hideCreateDialog: () => {\n this._createRedirect = null;\n },\n hideEditDialog: () => {\n this._editRedirect = null;\n },\n folders: {\n selectFolder: (folderId: string | null) => {\n this.listPresenter.actions.search.clear();\n this.folderTreePresenter.selectFolder(folderId);\n },\n createFolder: (parentFolderId?: string) =>\n this.folderTreePresenter.createFolder(parentFolderId),\n editFolder: (folderId: string) => this.folderTreePresenter.editFolder(folderId),\n deleteFolder: (folderId: string) => this.folderTreePresenter.deleteFolder(folderId),\n moveFolder: (folderId: string, targetParentId: string | null) =>\n this.folderTreePresenter.moveFolder(folderId, targetParentId),\n loadChildFolders: (parentIds: string[]) =>\n this.folderTreePresenter.loadChildFolders(parentIds),\n canManageStructure: (folderId: string) =>\n this.folderTreePresenter.canManageStructure(folderId),\n getAncestorIds: (folderId: string) =>\n this.folderTreePresenter.getAncestorIds(folderId),\n submitOperation: () => this.folderTreePresenter.submitOperation(),\n cancelOperation: () => this.folderTreePresenter.cancelOperation()\n }\n };\n }\n\n private getSelectedRows(): Redirect[] {\n const ids = this.listPresenter.vm.selection.selectedIds;\n return this.listPresenter.vm.rows.filter(r => ids.has(r.id));\n }\n\n private createWorkerActions(): IRedirectListActions[\"worker\"] {\n const worker = this._worker;\n return {\n process: (callback: (items: Redirect[]) => void) => {\n worker.process(this.getSelectedRows(), callback);\n },\n processInSeries: async (callback, chunkSize?) => {\n await worker.processInSeries(this.getSelectedRows(), callback, chunkSize);\n },\n get results() {\n return worker.results;\n },\n resetResults: () => worker.resetResults()\n };\n }\n\n private getSortedChildFolders() {\n if (!this.shouldShowFolders()) {\n return [];\n }\n return sortFolders(\n this.folderTreePresenter.vm.childFolders ?? [],\n this.listPresenter.vm.appliedQuery?.sort\n );\n }\n\n private shouldShowFolders(): boolean {\n const { appliedQuery } = this.listPresenter.vm;\n if (!appliedQuery) {\n return true;\n }\n\n if (appliedQuery.search) {\n return false;\n }\n\n const filterKeys = Object.keys(appliedQuery.filters ?? {}).filter(k => k !== \"folderId\");\n if (filterKeys.length > 0) {\n return false;\n }\n\n return true;\n }\n}\n\nexport const RedirectListPresenter = Abstraction.createImplementation({\n implementation: RedirectListPresenterImpl,\n dependencies: [\n ListPresenter,\n FolderTreePresenter,\n CreateRedirectPresenter,\n EditRedirectPresenter,\n ListRedirectsUseCase,\n RedirectsListCache,\n GetDescendantFoldersUseCase\n ]\n});\n"],"names":["RedirectListPresenterImpl","listPresenter","folderTreePresenter","createRedirectPresenter","editRedirectPresenter","listRedirectsUseCase","redirectsListCache","getDescendantFoldersUseCase","Worker","makeAutoObservable","computed","config","initialFolderId","dataSource","RedirectListDataSource","reaction","folderId","effectiveFolderId","query","field","direction","key","value","id","ids","redirectId","parentFolderId","targetParentId","parentIds","r","worker","callback","chunkSize","sortFolders","appliedQuery","filterKeys","Object","k","RedirectListPresenter","Abstraction","ListPresenter","FolderTreePresenter","CreateRedirectPresenter","EditRedirectPresenter","ListRedirectsUseCase","RedirectsListCache","GetDescendantFoldersUseCase"],"mappings":"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"}