@webiny/app-record-locking 6.4.5 → 6.6.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/RecordLockingModule.d.ts +2 -0
  2. package/RecordLockingModule.js +74 -0
  3. package/RecordLockingModule.js.map +1 -0
  4. package/{components/SecurityPermissions.js → SecurityPermissions.js} +1 -1
  5. package/SecurityPermissions.js.map +1 -0
  6. package/features/acquireLock/AcquireLockGateway.d.ts +12 -0
  7. package/features/acquireLock/AcquireLockGateway.js +43 -0
  8. package/features/acquireLock/AcquireLockGateway.js.map +1 -0
  9. package/features/acquireLock/AcquireLockUseCase.d.ts +10 -0
  10. package/features/acquireLock/AcquireLockUseCase.js +18 -0
  11. package/features/acquireLock/AcquireLockUseCase.js.map +1 -0
  12. package/features/acquireLock/abstractions.d.ts +19 -0
  13. package/features/acquireLock/abstractions.js +6 -0
  14. package/features/acquireLock/abstractions.js.map +1 -0
  15. package/features/acquireLock/feature.d.ts +3 -0
  16. package/features/acquireLock/feature.js +19 -0
  17. package/features/acquireLock/feature.js.map +1 -0
  18. package/features/checkLockStatus/CheckLockStatusGateway.d.ts +12 -0
  19. package/features/checkLockStatus/CheckLockStatusGateway.js +43 -0
  20. package/features/checkLockStatus/CheckLockStatusGateway.js.map +1 -0
  21. package/features/checkLockStatus/CheckLockStatusUseCase.d.ts +10 -0
  22. package/features/checkLockStatus/CheckLockStatusUseCase.js +18 -0
  23. package/features/checkLockStatus/CheckLockStatusUseCase.js.map +1 -0
  24. package/features/checkLockStatus/abstractions.d.ts +19 -0
  25. package/features/checkLockStatus/abstractions.js +6 -0
  26. package/features/checkLockStatus/abstractions.js.map +1 -0
  27. package/features/checkLockStatus/feature.d.ts +3 -0
  28. package/features/checkLockStatus/feature.js +19 -0
  29. package/features/checkLockStatus/feature.js.map +1 -0
  30. package/features/feature.d.ts +1 -0
  31. package/features/feature.js +19 -0
  32. package/features/feature.js.map +1 -0
  33. package/features/forceUnlock/ForceUnlockGateway.d.ts +12 -0
  34. package/features/forceUnlock/ForceUnlockGateway.js +44 -0
  35. package/features/forceUnlock/ForceUnlockGateway.js.map +1 -0
  36. package/features/forceUnlock/ForceUnlockUseCase.d.ts +10 -0
  37. package/features/forceUnlock/ForceUnlockUseCase.js +18 -0
  38. package/features/forceUnlock/ForceUnlockUseCase.js.map +1 -0
  39. package/features/forceUnlock/abstractions.d.ts +19 -0
  40. package/features/forceUnlock/abstractions.js +6 -0
  41. package/features/forceUnlock/abstractions.js.map +1 -0
  42. package/features/forceUnlock/feature.d.ts +3 -0
  43. package/features/forceUnlock/feature.js +19 -0
  44. package/features/forceUnlock/feature.js.map +1 -0
  45. package/{domain/graphql/fields.js → features/graphqlFields.js} +1 -1
  46. package/features/graphqlFields.js.map +1 -0
  47. package/features/listLockRecords/ListLockRecordsGateway.d.ts +12 -0
  48. package/features/listLockRecords/ListLockRecordsGateway.js +48 -0
  49. package/features/listLockRecords/ListLockRecordsGateway.js.map +1 -0
  50. package/features/listLockRecords/ListLockRecordsUseCase.d.ts +10 -0
  51. package/features/listLockRecords/ListLockRecordsUseCase.js +18 -0
  52. package/features/listLockRecords/ListLockRecordsUseCase.js.map +1 -0
  53. package/features/listLockRecords/abstractions.d.ts +22 -0
  54. package/features/listLockRecords/abstractions.js +6 -0
  55. package/features/listLockRecords/abstractions.js.map +1 -0
  56. package/features/listLockRecords/feature.d.ts +3 -0
  57. package/features/listLockRecords/feature.js +19 -0
  58. package/features/listLockRecords/feature.js.map +1 -0
  59. package/features/permissions/abstractions.d.ts +1 -1
  60. package/features/permissions/abstractions.js +1 -1
  61. package/features/permissions/abstractions.js.map +1 -1
  62. package/features/permissions/feature.js +1 -1
  63. package/features/permissions/feature.js.map +1 -1
  64. package/features/releaseLock/ReleaseLockGateway.d.ts +12 -0
  65. package/features/releaseLock/ReleaseLockGateway.js +44 -0
  66. package/features/releaseLock/ReleaseLockGateway.js.map +1 -0
  67. package/features/releaseLock/ReleaseLockUseCase.d.ts +10 -0
  68. package/features/releaseLock/ReleaseLockUseCase.js +18 -0
  69. package/features/releaseLock/ReleaseLockUseCase.js.map +1 -0
  70. package/features/releaseLock/abstractions.d.ts +19 -0
  71. package/features/releaseLock/abstractions.js +6 -0
  72. package/features/releaseLock/abstractions.js.map +1 -0
  73. package/features/releaseLock/feature.d.ts +3 -0
  74. package/features/releaseLock/feature.js +19 -0
  75. package/features/releaseLock/feature.js.map +1 -0
  76. package/index.d.ts +0 -5
  77. package/index.js +12 -13
  78. package/index.js.map +1 -1
  79. package/package.json +13 -17
  80. package/permissions/permissionsSchema.js.map +1 -0
  81. package/presentation/entryLocking/ContentEntryFormPresenterDecorator.d.ts +22 -0
  82. package/presentation/entryLocking/ContentEntryFormPresenterDecorator.js +61 -0
  83. package/presentation/entryLocking/ContentEntryFormPresenterDecorator.js.map +1 -0
  84. package/presentation/entryLocking/RecordLockingPresenter.d.ts +32 -0
  85. package/presentation/entryLocking/RecordLockingPresenter.js +164 -0
  86. package/presentation/entryLocking/RecordLockingPresenter.js.map +1 -0
  87. package/presentation/entryLocking/SingleEntryContentDecorator.d.ts +2 -0
  88. package/presentation/entryLocking/SingleEntryContentDecorator.js +72 -0
  89. package/presentation/entryLocking/SingleEntryContentDecorator.js.map +1 -0
  90. package/presentation/entryLocking/SingleEntryPresenterDecorator.d.ts +15 -0
  91. package/presentation/entryLocking/SingleEntryPresenterDecorator.js +40 -0
  92. package/presentation/entryLocking/SingleEntryPresenterDecorator.js.map +1 -0
  93. package/presentation/entryLocking/abstractions.d.ts +26 -0
  94. package/presentation/entryLocking/abstractions.js +5 -0
  95. package/presentation/entryLocking/abstractions.js.map +1 -0
  96. package/presentation/entryLocking/components/ForceUnlockButton.d.ts +11 -0
  97. package/presentation/entryLocking/components/ForceUnlockButton.js +37 -0
  98. package/presentation/entryLocking/components/ForceUnlockButton.js.map +1 -0
  99. package/presentation/entryLocking/components/LockedEntryOverlay.d.ts +10 -0
  100. package/presentation/entryLocking/components/LockedEntryOverlay.js +52 -0
  101. package/presentation/entryLocking/components/LockedEntryOverlay.js.map +1 -0
  102. package/presentation/entryLocking/components/RecordLockingGuard.d.ts +12 -0
  103. package/presentation/entryLocking/components/RecordLockingGuard.js +74 -0
  104. package/presentation/entryLocking/components/RecordLockingGuard.js.map +1 -0
  105. package/presentation/entryLocking/feature.d.ts +3 -0
  106. package/presentation/entryLocking/feature.js +21 -0
  107. package/presentation/entryLocking/feature.js.map +1 -0
  108. package/presentation/listLocking/ContentEntriesPresenterDecorator.d.ts +24 -0
  109. package/presentation/listLocking/ContentEntriesPresenterDecorator.js +67 -0
  110. package/presentation/listLocking/ContentEntriesPresenterDecorator.js.map +1 -0
  111. package/presentation/listLocking/ListLockRecordsPresenter.d.ts +17 -0
  112. package/presentation/listLocking/ListLockRecordsPresenter.js +52 -0
  113. package/presentation/listLocking/ListLockRecordsPresenter.js.map +1 -0
  114. package/presentation/listLocking/abstractions.d.ts +16 -0
  115. package/presentation/listLocking/abstractions.js +5 -0
  116. package/presentation/listLocking/abstractions.js.map +1 -0
  117. package/presentation/listLocking/components/ListLockRecordsSync.d.ts +3 -0
  118. package/presentation/listLocking/components/ListLockRecordsSync.js +26 -0
  119. package/presentation/listLocking/components/ListLockRecordsSync.js.map +1 -0
  120. package/presentation/listLocking/components/LockIndicatorCell.d.ts +2 -0
  121. package/presentation/listLocking/components/LockIndicatorCell.js +39 -0
  122. package/presentation/listLocking/components/LockIndicatorCell.js.map +1 -0
  123. package/presentation/listLocking/feature.d.ts +3 -0
  124. package/presentation/listLocking/feature.js +19 -0
  125. package/presentation/listLocking/feature.js.map +1 -0
  126. package/types.d.ts +1 -62
  127. package/components/HeadlessCmsActionsAcoCell.d.ts +0 -2
  128. package/components/HeadlessCmsActionsAcoCell.js +0 -38
  129. package/components/HeadlessCmsActionsAcoCell.js.map +0 -1
  130. package/components/HeadlessCmsContentEntry/ContentEntryGuard.d.ts +0 -9
  131. package/components/HeadlessCmsContentEntry/ContentEntryGuard.js +0 -34
  132. package/components/HeadlessCmsContentEntry/ContentEntryGuard.js.map +0 -1
  133. package/components/HeadlessCmsContentEntry/ContentEntryLocker.d.ts +0 -18
  134. package/components/HeadlessCmsContentEntry/ContentEntryLocker.js +0 -80
  135. package/components/HeadlessCmsContentEntry/ContentEntryLocker.js.map +0 -1
  136. package/components/HeadlessCmsContentEntry/HeadlessCmsContentEntry.d.ts +0 -2
  137. package/components/HeadlessCmsContentEntry/HeadlessCmsContentEntry.js +0 -44
  138. package/components/HeadlessCmsContentEntry/HeadlessCmsContentEntry.js.map +0 -1
  139. package/components/HeadlessCmsContentEntry/index.d.ts +0 -1
  140. package/components/HeadlessCmsContentEntry/index.js +0 -1
  141. package/components/LockedRecord/LockedRecord.d.ts +0 -6
  142. package/components/LockedRecord/LockedRecord.js +0 -54
  143. package/components/LockedRecord/LockedRecord.js.map +0 -1
  144. package/components/LockedRecord/LockedRecordForceUnlock.d.ts +0 -9
  145. package/components/LockedRecord/LockedRecordForceUnlock.js +0 -57
  146. package/components/LockedRecord/LockedRecordForceUnlock.js.map +0 -1
  147. package/components/LockedRecord/index.d.ts +0 -1
  148. package/components/LockedRecord/index.js +0 -1
  149. package/components/RecordLockingProvider.d.ts +0 -7
  150. package/components/RecordLockingProvider.js +0 -111
  151. package/components/RecordLockingProvider.js.map +0 -1
  152. package/components/SecurityPermissions.js.map +0 -1
  153. package/components/decorators/UseContentEntriesListHookDecorator.d.ts +0 -1
  154. package/components/decorators/UseContentEntriesListHookDecorator.js +0 -23
  155. package/components/decorators/UseContentEntriesListHookDecorator.js.map +0 -1
  156. package/components/decorators/UseRecordsDecorator.d.ts +0 -8
  157. package/components/decorators/UseRecordsDecorator.js +0 -16
  158. package/components/decorators/UseRecordsDecorator.js.map +0 -1
  159. package/components/decorators/UseSaveEntryDecorator.d.ts +0 -1
  160. package/components/decorators/UseSaveEntryDecorator.js +0 -41
  161. package/components/decorators/UseSaveEntryDecorator.js.map +0 -1
  162. package/domain/RecordLocking.d.ts +0 -28
  163. package/domain/RecordLocking.js +0 -259
  164. package/domain/RecordLocking.js.map +0 -1
  165. package/domain/RecordLockingClient.d.ts +0 -12
  166. package/domain/RecordLockingClient.js +0 -20
  167. package/domain/RecordLockingClient.js.map +0 -1
  168. package/domain/RecordLockingGetLockRecord.d.ts +0 -11
  169. package/domain/RecordLockingGetLockRecord.js +0 -19
  170. package/domain/RecordLockingGetLockRecord.js.map +0 -1
  171. package/domain/RecordLockingGetLockedEntryLockRecord.d.ts +0 -11
  172. package/domain/RecordLockingGetLockedEntryLockRecord.js +0 -18
  173. package/domain/RecordLockingGetLockedEntryLockRecord.js.map +0 -1
  174. package/domain/RecordLockingIsEntryLocked.d.ts +0 -11
  175. package/domain/RecordLockingIsEntryLocked.js +0 -20
  176. package/domain/RecordLockingIsEntryLocked.js.map +0 -1
  177. package/domain/RecordLockingListLockRecords.d.ts +0 -12
  178. package/domain/RecordLockingListLockRecords.js +0 -25
  179. package/domain/RecordLockingListLockRecords.js.map +0 -1
  180. package/domain/RecordLockingLockEntry.d.ts +0 -11
  181. package/domain/RecordLockingLockEntry.js +0 -12
  182. package/domain/RecordLockingLockEntry.js.map +0 -1
  183. package/domain/RecordLockingUnlockEntry.d.ts +0 -11
  184. package/domain/RecordLockingUnlockEntry.js +0 -18
  185. package/domain/RecordLockingUnlockEntry.js.map +0 -1
  186. package/domain/RecordLockingUpdateEntryLock.d.ts +0 -11
  187. package/domain/RecordLockingUpdateEntryLock.js +0 -18
  188. package/domain/RecordLockingUpdateEntryLock.js.map +0 -1
  189. package/domain/abstractions/IRecordLocking.d.ts +0 -25
  190. package/domain/abstractions/IRecordLocking.js +0 -0
  191. package/domain/abstractions/IRecordLockingClient.d.ts +0 -6
  192. package/domain/abstractions/IRecordLockingClient.js +0 -0
  193. package/domain/abstractions/IRecordLockingGetLockRecord.d.ts +0 -12
  194. package/domain/abstractions/IRecordLockingGetLockRecord.js +0 -0
  195. package/domain/abstractions/IRecordLockingGetLockedEntryLockRecord.d.ts +0 -12
  196. package/domain/abstractions/IRecordLockingGetLockedEntryLockRecord.js +0 -0
  197. package/domain/abstractions/IRecordLockingIsEntryLocked.d.ts +0 -8
  198. package/domain/abstractions/IRecordLockingIsEntryLocked.js +0 -0
  199. package/domain/abstractions/IRecordLockingListLockRecords.d.ts +0 -19
  200. package/domain/abstractions/IRecordLockingListLockRecords.js +0 -0
  201. package/domain/abstractions/IRecordLockingLockEntry.d.ts +0 -12
  202. package/domain/abstractions/IRecordLockingLockEntry.js +0 -0
  203. package/domain/abstractions/IRecordLockingUnlockEntry.d.ts +0 -13
  204. package/domain/abstractions/IRecordLockingUnlockEntry.js +0 -0
  205. package/domain/abstractions/IRecordLockingUpdateEntryLock.d.ts +0 -12
  206. package/domain/abstractions/IRecordLockingUpdateEntryLock.js +0 -0
  207. package/domain/graphql/fields.js.map +0 -1
  208. package/domain/graphql/getLockRecord.d.ts +0 -12
  209. package/domain/graphql/getLockRecord.js +0 -19
  210. package/domain/graphql/getLockRecord.js.map +0 -1
  211. package/domain/graphql/getLockedEntryLockRecord.d.ts +0 -12
  212. package/domain/graphql/getLockedEntryLockRecord.js +0 -19
  213. package/domain/graphql/getLockedEntryLockRecord.js.map +0 -1
  214. package/domain/graphql/isEntryLocked.d.ts +0 -12
  215. package/domain/graphql/isEntryLocked.js +0 -17
  216. package/domain/graphql/isEntryLocked.js.map +0 -1
  217. package/domain/graphql/listLockRecords.d.ts +0 -17
  218. package/domain/graphql/listLockRecords.js +0 -25
  219. package/domain/graphql/listLockRecords.js.map +0 -1
  220. package/domain/graphql/lockEntry.d.ts +0 -12
  221. package/domain/graphql/lockEntry.js +0 -19
  222. package/domain/graphql/lockEntry.js.map +0 -1
  223. package/domain/graphql/unlockEntry.d.ts +0 -12
  224. package/domain/graphql/unlockEntry.js +0 -19
  225. package/domain/graphql/unlockEntry.js.map +0 -1
  226. package/domain/graphql/updateEntryLock.d.ts +0 -12
  227. package/domain/graphql/updateEntryLock.js +0 -19
  228. package/domain/graphql/updateEntryLock.js.map +0 -1
  229. package/domain/permissionsSchema.js.map +0 -1
  230. package/domain/utils/createRecordLockingClient.d.ts +0 -3
  231. package/domain/utils/createRecordLockingClient.js +0 -11
  232. package/domain/utils/createRecordLockingClient.js.map +0 -1
  233. package/domain/utils/createRecordLockingError.d.ts +0 -6
  234. package/domain/utils/createRecordLockingError.js +0 -15
  235. package/domain/utils/createRecordLockingError.js.map +0 -1
  236. package/hooks/index.d.ts +0 -2
  237. package/hooks/index.js +0 -2
  238. package/hooks/usePermission.d.ts +0 -3
  239. package/hooks/usePermission.js +0 -19
  240. package/hooks/usePermission.js.map +0 -1
  241. package/hooks/useRecordLocking.d.ts +0 -2
  242. package/hooks/useRecordLocking.js +0 -11
  243. package/hooks/useRecordLocking.js.map +0 -1
  244. package/utils/createCacheKey.d.ts +0 -3
  245. package/utils/createCacheKey.js +0 -14
  246. package/utils/createCacheKey.js.map +0 -1
  247. /package/{components/SecurityPermissions.d.ts → SecurityPermissions.d.ts} +0 -0
  248. /package/{domain/graphql/fields.d.ts → features/graphqlFields.d.ts} +0 -0
  249. /package/{domain → permissions}/permissionsSchema.d.ts +0 -0
  250. /package/{domain → permissions}/permissionsSchema.js +0 -0
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ interface RecordLockingGuardProps {
3
+ entryId: string;
4
+ modelId: string;
5
+ entryTitle?: string;
6
+ onNavigateBack: () => void;
7
+ children: React.ReactNode;
8
+ }
9
+ export declare const RecordLockingGuard: (({ entryId, modelId, entryTitle, onNavigateBack, children }: RecordLockingGuardProps) => React.JSX.Element) & {
10
+ displayName: string;
11
+ };
12
+ export {};
@@ -0,0 +1,74 @@
1
+ import react, { useEffect } from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { useContainer, useRouter } from "@webiny/app";
4
+ import { useDialogs } from "@webiny/app-admin";
5
+ import { OverlayLoader } from "@webiny/admin-ui";
6
+ import { useWebsockets } from "@webiny/app-websockets";
7
+ import { parseIdentifier } from "@webiny/utils";
8
+ import { RecordLockingPresenter } from "../abstractions.js";
9
+ import { LockedEntryOverlay } from "./LockedEntryOverlay.js";
10
+ const RecordLockingGuard = observer(({ entryId, modelId, entryTitle, onNavigateBack, children })=>{
11
+ const container = useContainer();
12
+ const presenter = react.useMemo(()=>container.resolve(RecordLockingPresenter), [
13
+ container
14
+ ]);
15
+ const websockets = useWebsockets();
16
+ const router = useRouter();
17
+ const { showDialog } = useDialogs();
18
+ useEffect(()=>{
19
+ presenter.init(entryId, modelId);
20
+ return ()=>{
21
+ presenter.dispose();
22
+ };
23
+ }, [
24
+ entryId,
25
+ modelId
26
+ ]);
27
+ useEffect(()=>{
28
+ const { id } = parseIdentifier(entryId);
29
+ const sub = websockets.onMessage(`recordLocking.entry.kickOut.${id}`, (incoming)=>{
30
+ presenter.handleKickOut(incoming.data);
31
+ });
32
+ return ()=>{
33
+ sub.off();
34
+ };
35
+ }, [
36
+ entryId,
37
+ modelId
38
+ ]);
39
+ useEffect(()=>{
40
+ if ("kicked-out" !== presenter.vm.status) return;
41
+ router.unblockTransition();
42
+ showDialog({
43
+ title: "Entry was forcefully unlocked!",
44
+ content: /*#__PURE__*/ react.createElement(react.Fragment, null, "The entry you were editing was forcefully unlocked by", " ", /*#__PURE__*/ react.createElement("strong", null, presenter.vm.lockRecord?.lockedBy?.displayName || "Unknown user"), ". Unfortunately, this means you lost the unsaved changes."),
45
+ acceptLabel: "Ok",
46
+ onClose: void 0,
47
+ cancelLabel: null
48
+ });
49
+ onNavigateBack();
50
+ }, [
51
+ presenter.vm.status
52
+ ]);
53
+ const { vm } = presenter;
54
+ if ("checking" === vm.status) return /*#__PURE__*/ react.createElement("div", {
55
+ className: "h-screen w-screen fixed top-0 left-0 z-20"
56
+ }, /*#__PURE__*/ react.createElement(OverlayLoader, {
57
+ text: "Checking record status..."
58
+ }));
59
+ if ("locked" === vm.status) return /*#__PURE__*/ react.createElement(LockedEntryOverlay, {
60
+ vm: vm,
61
+ entryTitle: entryTitle,
62
+ onForceUnlock: ()=>presenter.forceUnlock(),
63
+ onNavigateBack: onNavigateBack
64
+ });
65
+ if ("error" === vm.status) return /*#__PURE__*/ react.createElement("div", {
66
+ className: "h-screen w-screen fixed top-0 left-0 z-20"
67
+ }, /*#__PURE__*/ react.createElement(OverlayLoader, {
68
+ text: "Failed to check record lock status."
69
+ }));
70
+ return /*#__PURE__*/ react.createElement(react.Fragment, null, children);
71
+ });
72
+ export { RecordLockingGuard };
73
+
74
+ //# sourceMappingURL=RecordLockingGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/entryLocking/components/RecordLockingGuard.js","sources":["../../../../src/presentation/entryLocking/components/RecordLockingGuard.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useContainer, useRouter } from \"@webiny/app\";\nimport { useDialogs } from \"@webiny/app-admin\";\nimport { OverlayLoader } from \"@webiny/admin-ui\";\nimport { useWebsockets } from \"@webiny/app-websockets\";\nimport { parseIdentifier } from \"@webiny/utils\";\nimport { RecordLockingPresenter } from \"../abstractions.js\";\nimport { LockedEntryOverlay } from \"./LockedEntryOverlay.js\";\nimport type { IKickOutData } from \"../abstractions.js\";\nimport type { IncomingGenericData } from \"@webiny/app-websockets\";\n\ninterface KickOutMessage extends IncomingGenericData {\n data: IKickOutData;\n}\n\ninterface RecordLockingGuardProps {\n entryId: string;\n modelId: string;\n entryTitle?: string;\n onNavigateBack: () => void;\n children: React.ReactNode;\n}\n\nexport const RecordLockingGuard = observer(\n ({ entryId, modelId, entryTitle, onNavigateBack, children }: RecordLockingGuardProps) => {\n const container = useContainer();\n const presenter = React.useMemo(\n () => container.resolve(RecordLockingPresenter),\n [container]\n );\n const websockets = useWebsockets();\n const router = useRouter();\n const { showDialog } = useDialogs();\n\n useEffect(() => {\n presenter.init(entryId, modelId);\n\n return () => {\n presenter.dispose();\n };\n }, [entryId, modelId]);\n\n useEffect(() => {\n const { id } = parseIdentifier(entryId);\n\n const sub = websockets.onMessage<KickOutMessage>(\n `recordLocking.entry.kickOut.${id}`,\n incoming => {\n presenter.handleKickOut(incoming.data);\n }\n );\n\n return () => {\n sub.off();\n };\n }, [entryId, modelId]);\n\n useEffect(() => {\n if (presenter.vm.status !== \"kicked-out\") {\n return;\n }\n\n router.unblockTransition();\n\n showDialog({\n title: \"Entry was forcefully unlocked!\",\n content: (\n <>\n The entry you were editing was forcefully unlocked by{\" \"}\n <strong>\n {presenter.vm.lockRecord?.lockedBy?.displayName || \"Unknown user\"}\n </strong>\n . Unfortunately, this means you lost the unsaved changes.\n </>\n ),\n acceptLabel: \"Ok\",\n onClose: undefined,\n cancelLabel: null\n });\n\n onNavigateBack();\n }, [presenter.vm.status]);\n\n const { vm } = presenter;\n\n if (vm.status === \"checking\") {\n return (\n <div className={\"h-screen w-screen fixed top-0 left-0 z-20\"}>\n <OverlayLoader text={\"Checking record status...\"} />\n </div>\n );\n }\n\n if (vm.status === \"locked\") {\n return (\n <LockedEntryOverlay\n vm={vm}\n entryTitle={entryTitle}\n onForceUnlock={() => presenter.forceUnlock()}\n onNavigateBack={onNavigateBack}\n />\n );\n }\n\n if (vm.status === \"error\") {\n return (\n <div className={\"h-screen w-screen fixed top-0 left-0 z-20\"}>\n <OverlayLoader text={\"Failed to check record lock status.\"} />\n </div>\n );\n }\n\n return <>{children}</>;\n }\n);\n"],"names":["RecordLockingGuard","observer","entryId","modelId","entryTitle","onNavigateBack","children","container","useContainer","presenter","React","RecordLockingPresenter","websockets","useWebsockets","router","useRouter","showDialog","useDialogs","useEffect","id","parseIdentifier","sub","incoming","undefined","vm","OverlayLoader","LockedEntryOverlay"],"mappings":";;;;;;;;;AAwBO,MAAMA,qBAAqBC,SAC9B,CAAC,EAAEC,OAAO,EAAEC,OAAO,EAAEC,UAAU,EAAEC,cAAc,EAAEC,QAAQ,EAA2B;IAChF,MAAMC,YAAYC;IAClB,MAAMC,YAAYC,MAAAA,OAAa,CAC3B,IAAMH,UAAU,OAAO,CAACI,yBACxB;QAACJ;KAAU;IAEf,MAAMK,aAAaC;IACnB,MAAMC,SAASC;IACf,MAAM,EAAEC,UAAU,EAAE,GAAGC;IAEvBC,UAAU;QACNT,UAAU,IAAI,CAACP,SAASC;QAExB,OAAO;YACHM,UAAU,OAAO;QACrB;IACJ,GAAG;QAACP;QAASC;KAAQ;IAErBe,UAAU;QACN,MAAM,EAAEC,EAAE,EAAE,GAAGC,gBAAgBlB;QAE/B,MAAMmB,MAAMT,WAAW,SAAS,CAC5B,CAAC,4BAA4B,EAAEO,IAAI,EACnCG,CAAAA;YACIb,UAAU,aAAa,CAACa,SAAS,IAAI;QACzC;QAGJ,OAAO;YACHD,IAAI,GAAG;QACX;IACJ,GAAG;QAACnB;QAASC;KAAQ;IAErBe,UAAU;QACN,IAAIT,AAAwB,iBAAxBA,UAAU,EAAE,CAAC,MAAM,EACnB;QAGJK,OAAO,iBAAiB;QAExBE,WAAW;YACP,OAAO;YACP,SAAS,WAAT,GACI,0CAAE,yDACwD,mBACtD,oBAAC,gBACIP,UAAU,EAAE,CAAC,UAAU,EAAE,UAAU,eAAe,iBAC9C;YAIjB,aAAa;YACb,SAASc;YACT,aAAa;QACjB;QAEAlB;IACJ,GAAG;QAACI,UAAU,EAAE,CAAC,MAAM;KAAC;IAExB,MAAM,EAAEe,EAAE,EAAE,GAAGf;IAEf,IAAIe,AAAc,eAAdA,GAAG,MAAM,EACT,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACC,eAAaA;QAAC,MAAM;;IAKjC,IAAID,AAAc,aAAdA,GAAG,MAAM,EACT,OAAO,WAAP,GACI,oBAACE,oBAAkBA;QACf,IAAIF;QACJ,YAAYpB;QACZ,eAAe,IAAMK,UAAU,WAAW;QAC1C,gBAAgBJ;;IAK5B,IAAImB,AAAc,YAAdA,GAAG,MAAM,EACT,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACC,eAAaA;QAAC,MAAM;;IAKjC,OAAO,WAAP,GAAO,0CAAGnB;AACd"}
@@ -0,0 +1,3 @@
1
+ export declare const RecordLockingPresenterFeature: import("@webiny/feature/admin").FeatureDefinition<{
2
+ presenter: import("./abstractions.js").IRecordLockingPresenter;
3
+ }, []>;
@@ -0,0 +1,21 @@
1
+ import { createFeature } from "@webiny/feature/admin";
2
+ import { RecordLockingPresenter } from "./abstractions.js";
3
+ import { RecordLockingPresenter as external_RecordLockingPresenter_js_RecordLockingPresenter } from "./RecordLockingPresenter.js";
4
+ import { ContentEntryFormPresenterLockingDecorator } from "./ContentEntryFormPresenterDecorator.js";
5
+ import { SingleEntryPresenterLockingDecorator } from "./SingleEntryPresenterDecorator.js";
6
+ const RecordLockingPresenterFeature = createFeature({
7
+ name: "RecordLocking/EntryLockingPresenter",
8
+ register (container) {
9
+ container.register(external_RecordLockingPresenter_js_RecordLockingPresenter).inSingletonScope();
10
+ container.registerDecorator(ContentEntryFormPresenterLockingDecorator);
11
+ container.registerDecorator(SingleEntryPresenterLockingDecorator);
12
+ },
13
+ resolve (container) {
14
+ return {
15
+ presenter: container.resolve(RecordLockingPresenter)
16
+ };
17
+ }
18
+ });
19
+ export { RecordLockingPresenterFeature };
20
+
21
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/entryLocking/feature.js","sources":["../../../src/presentation/entryLocking/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { RecordLockingPresenter as Abstraction } from \"./abstractions.js\";\nimport { RecordLockingPresenter } from \"./RecordLockingPresenter.js\";\nimport { ContentEntryFormPresenterLockingDecorator } from \"./ContentEntryFormPresenterDecorator.js\";\nimport { SingleEntryPresenterLockingDecorator } from \"./SingleEntryPresenterDecorator.js\";\n\nexport const RecordLockingPresenterFeature = createFeature({\n name: \"RecordLocking/EntryLockingPresenter\",\n register(container) {\n container.register(RecordLockingPresenter).inSingletonScope();\n container.registerDecorator(ContentEntryFormPresenterLockingDecorator);\n container.registerDecorator(SingleEntryPresenterLockingDecorator);\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n"],"names":["RecordLockingPresenterFeature","createFeature","container","RecordLockingPresenter","ContentEntryFormPresenterLockingDecorator","SingleEntryPresenterLockingDecorator","Abstraction"],"mappings":";;;;;AAMO,MAAMA,gCAAgCC,cAAc;IACvD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,2DAAwB,gBAAgB;QAC3DD,UAAU,iBAAiB,CAACE;QAC5BF,UAAU,iBAAiB,CAACG;IAChC;IACA,SAAQH,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACI;QACjC;IACJ;AACJ"}
@@ -0,0 +1,24 @@
1
+ import { type IContentEntriesPresenter, type IContentEntriesInitConfig } from "@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js";
2
+ import { ListLockRecordsPresenter } from "./abstractions.js";
3
+ declare class ContentEntriesPresenterWithLocking implements IContentEntriesPresenter {
4
+ private lockRecordsPresenter;
5
+ private original;
6
+ private _disposeReaction;
7
+ constructor(lockRecordsPresenter: ListLockRecordsPresenter.Interface, original: IContentEntriesPresenter);
8
+ get vm(): import("@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js").IContentEntriesViewModel;
9
+ get list(): import("@webiny/app-admin/presentation/listPresenter/abstractions.js").IListPresenter<import("@webiny/app-headless-cms/types.js").CmsContentEntry<import("@webiny/app/types.js").GenericRecord>>;
10
+ get folders(): import("@webiny/app-aco/index.js").IFolderTreePresenter;
11
+ init(config?: IContentEntriesInitConfig): void;
12
+ dispose(): void;
13
+ selectEntry(id: string): void;
14
+ deselectEntry(): void;
15
+ createEntry(): void;
16
+ deleteEntry(id: string): Promise<boolean>;
17
+ publishEntry(id: string): Promise<boolean>;
18
+ unpublishEntry(id: string): Promise<boolean>;
19
+ moveEntry(id: string, folderId: string): Promise<boolean>;
20
+ }
21
+ export declare const ContentEntriesPresenterLockingDecorator: typeof ContentEntriesPresenterWithLocking & {
22
+ __abstraction: import("@webiny/di").Abstraction<IContentEntriesPresenter>;
23
+ };
24
+ export {};
@@ -0,0 +1,67 @@
1
+ import { comparer, reaction } from "mobx";
2
+ import { ContentEntriesPresenter } from "@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js";
3
+ import { ListLockRecordsPresenter } from "./abstractions.js";
4
+ class ContentEntriesPresenterWithLocking {
5
+ constructor(lockRecordsPresenter, original){
6
+ this.lockRecordsPresenter = lockRecordsPresenter;
7
+ this.original = original;
8
+ this._disposeReaction = null;
9
+ }
10
+ get vm() {
11
+ return this.original.vm;
12
+ }
13
+ get list() {
14
+ return this.original.list;
15
+ }
16
+ get folders() {
17
+ return this.original.folders;
18
+ }
19
+ init(config) {
20
+ this.original.init(config);
21
+ this._disposeReaction = reaction(()=>this.original.list.vm.rows.map((r)=>r.id), (entryIds)=>{
22
+ if (0 === entryIds.length) return;
23
+ this.lockRecordsPresenter.fetchForEntries(entryIds, this.original.vm.model.modelId);
24
+ }, {
25
+ fireImmediately: true,
26
+ equals: comparer.structural
27
+ });
28
+ }
29
+ dispose() {
30
+ if (this._disposeReaction) {
31
+ this._disposeReaction();
32
+ this._disposeReaction = null;
33
+ }
34
+ this.lockRecordsPresenter.dispose();
35
+ this.original.dispose();
36
+ }
37
+ selectEntry(id) {
38
+ this.original.selectEntry(id);
39
+ }
40
+ deselectEntry() {
41
+ this.original.deselectEntry();
42
+ }
43
+ createEntry() {
44
+ this.original.createEntry();
45
+ }
46
+ deleteEntry(id) {
47
+ return this.original.deleteEntry(id);
48
+ }
49
+ publishEntry(id) {
50
+ return this.original.publishEntry(id);
51
+ }
52
+ unpublishEntry(id) {
53
+ return this.original.unpublishEntry(id);
54
+ }
55
+ moveEntry(id, folderId) {
56
+ return this.original.moveEntry(id, folderId);
57
+ }
58
+ }
59
+ const ContentEntriesPresenterLockingDecorator = ContentEntriesPresenter.createDecorator({
60
+ decorator: ContentEntriesPresenterWithLocking,
61
+ dependencies: [
62
+ ListLockRecordsPresenter
63
+ ]
64
+ });
65
+ export { ContentEntriesPresenterLockingDecorator };
66
+
67
+ //# sourceMappingURL=ContentEntriesPresenterDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/listLocking/ContentEntriesPresenterDecorator.js","sources":["../../../src/presentation/listLocking/ContentEntriesPresenterDecorator.ts"],"sourcesContent":["import { comparer, reaction } from \"mobx\";\nimport type { IReactionDisposer } from \"mobx\";\nimport {\n ContentEntriesPresenter,\n type IContentEntriesPresenter,\n type IContentEntriesInitConfig\n} from \"@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js\";\nimport { ListLockRecordsPresenter } from \"./abstractions.js\";\n\nclass ContentEntriesPresenterWithLocking implements IContentEntriesPresenter {\n private _disposeReaction: IReactionDisposer | null = null;\n\n constructor(\n private lockRecordsPresenter: ListLockRecordsPresenter.Interface,\n private original: IContentEntriesPresenter\n ) {}\n\n get vm() {\n return this.original.vm;\n }\n\n get list() {\n return this.original.list;\n }\n\n get folders() {\n return this.original.folders;\n }\n\n init(config?: IContentEntriesInitConfig): void {\n this.original.init(config);\n\n this._disposeReaction = reaction(\n () => this.original.list.vm.rows.map(r => r.id),\n entryIds => {\n if (entryIds.length === 0) {\n return;\n }\n this.lockRecordsPresenter.fetchForEntries(entryIds, this.original.vm.model.modelId);\n },\n { fireImmediately: true, equals: comparer.structural }\n );\n }\n\n dispose(): void {\n if (this._disposeReaction) {\n this._disposeReaction();\n this._disposeReaction = null;\n }\n this.lockRecordsPresenter.dispose();\n this.original.dispose();\n }\n\n selectEntry(id: string) {\n this.original.selectEntry(id);\n }\n\n deselectEntry() {\n this.original.deselectEntry();\n }\n\n createEntry() {\n this.original.createEntry();\n }\n\n deleteEntry(id: string) {\n return this.original.deleteEntry(id);\n }\n\n publishEntry(id: string) {\n return this.original.publishEntry(id);\n }\n\n unpublishEntry(id: string) {\n return this.original.unpublishEntry(id);\n }\n\n moveEntry(id: string, folderId: string) {\n return this.original.moveEntry(id, folderId);\n }\n}\n\nexport const ContentEntriesPresenterLockingDecorator = ContentEntriesPresenter.createDecorator({\n decorator: ContentEntriesPresenterWithLocking,\n dependencies: [ListLockRecordsPresenter]\n});\n"],"names":["ContentEntriesPresenterWithLocking","lockRecordsPresenter","original","config","reaction","r","entryIds","comparer","id","folderId","ContentEntriesPresenterLockingDecorator","ContentEntriesPresenter","ListLockRecordsPresenter"],"mappings":";;;AASA,MAAMA;IAGF,YACYC,oBAAwD,EACxDC,QAAkC,CAC5C;aAFUD,oBAAoB,GAApBA;aACAC,QAAQ,GAARA;aAJJ,gBAAgB,GAA6B;IAKlD;IAEH,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE;IAC3B;IAEA,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI;IAC7B;IAEA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO;IAChC;IAEA,KAAKC,MAAkC,EAAQ;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAACA;QAEnB,IAAI,CAAC,gBAAgB,GAAGC,SACpB,IAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAACC,CAAAA,IAAKA,EAAE,EAAE,GAC9CC,CAAAA;YACI,IAAIA,AAAoB,MAApBA,SAAS,MAAM,EACf;YAEJ,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAACA,UAAU,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;QACtF,GACA;YAAE,iBAAiB;YAAM,QAAQC,SAAS,UAAU;QAAC;IAE7D;IAEA,UAAgB;QACZ,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACvB,IAAI,CAAC,gBAAgB;YACrB,IAAI,CAAC,gBAAgB,GAAG;QAC5B;QACA,IAAI,CAAC,oBAAoB,CAAC,OAAO;QACjC,IAAI,CAAC,QAAQ,CAAC,OAAO;IACzB;IAEA,YAAYC,EAAU,EAAE;QACpB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAACA;IAC9B;IAEA,gBAAgB;QACZ,IAAI,CAAC,QAAQ,CAAC,aAAa;IAC/B;IAEA,cAAc;QACV,IAAI,CAAC,QAAQ,CAAC,WAAW;IAC7B;IAEA,YAAYA,EAAU,EAAE;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAACA;IACrC;IAEA,aAAaA,EAAU,EAAE;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,CAACA;IACtC;IAEA,eAAeA,EAAU,EAAE;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAACA;IACxC;IAEA,UAAUA,EAAU,EAAEC,QAAgB,EAAE;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAACD,IAAIC;IACvC;AACJ;AAEO,MAAMC,0CAA0CC,wBAAwB,eAAe,CAAC;IAC3F,WAAWX;IACX,cAAc;QAACY;KAAyB;AAC5C"}
@@ -0,0 +1,17 @@
1
+ import { ListLockRecordsUseCase } from "../../features/listLockRecords/abstractions.js";
2
+ import { type IListLockRecordsPresenter, type IListLockRecordsViewModel } from "./abstractions.js";
3
+ import type { IRecordLockingLockRecord } from "../../types.js";
4
+ declare class ListLockRecordsPresenterImpl implements IListLockRecordsPresenter {
5
+ private listLockRecordsUseCase;
6
+ private _lockMap;
7
+ constructor(listLockRecordsUseCase: ListLockRecordsUseCase.Interface);
8
+ get vm(): IListLockRecordsViewModel;
9
+ fetchForEntries(entryIds: string[], type: string): Promise<void>;
10
+ isLocked(entryId: string): boolean;
11
+ getLockRecord(entryId: string): IRecordLockingLockRecord | undefined;
12
+ dispose(): void;
13
+ }
14
+ export declare const ListLockRecordsPresenter: typeof ListLockRecordsPresenterImpl & {
15
+ __abstraction: import("@webiny/di").Abstraction<IListLockRecordsPresenter>;
16
+ };
17
+ export {};
@@ -0,0 +1,52 @@
1
+ import { computed, makeAutoObservable, observable, runInAction } from "mobx";
2
+ import { ListLockRecordsUseCase } from "../../features/listLockRecords/abstractions.js";
3
+ import { ListLockRecordsPresenter } from "./abstractions.js";
4
+ class ListLockRecordsPresenterImpl {
5
+ constructor(listLockRecordsUseCase){
6
+ this.listLockRecordsUseCase = listLockRecordsUseCase;
7
+ this._lockMap = observable.map();
8
+ makeAutoObservable(this, {
9
+ listLockRecordsUseCase: false,
10
+ vm: computed
11
+ });
12
+ }
13
+ get vm() {
14
+ return {
15
+ lockedCount: this._lockMap.size
16
+ };
17
+ }
18
+ async fetchForEntries(entryIds, type) {
19
+ if (0 === entryIds.length) return;
20
+ try {
21
+ const records = await this.listLockRecordsUseCase.execute({
22
+ where: {
23
+ id_in: entryIds,
24
+ type
25
+ },
26
+ limit: entryIds.length
27
+ });
28
+ runInAction(()=>{
29
+ this._lockMap.clear();
30
+ for (const record of records)this._lockMap.set(record.targetId, record);
31
+ });
32
+ } catch {}
33
+ }
34
+ isLocked(entryId) {
35
+ return this._lockMap.has(entryId);
36
+ }
37
+ getLockRecord(entryId) {
38
+ return this._lockMap.get(entryId);
39
+ }
40
+ dispose() {
41
+ this._lockMap.clear();
42
+ }
43
+ }
44
+ const ListLockRecordsPresenter_ListLockRecordsPresenter = ListLockRecordsPresenter.createImplementation({
45
+ implementation: ListLockRecordsPresenterImpl,
46
+ dependencies: [
47
+ ListLockRecordsUseCase
48
+ ]
49
+ });
50
+ export { ListLockRecordsPresenter_ListLockRecordsPresenter as ListLockRecordsPresenter };
51
+
52
+ //# sourceMappingURL=ListLockRecordsPresenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/listLocking/ListLockRecordsPresenter.js","sources":["../../../src/presentation/listLocking/ListLockRecordsPresenter.ts"],"sourcesContent":["import { computed, makeAutoObservable, observable, runInAction } from \"mobx\";\nimport { ListLockRecordsUseCase } from \"~/features/listLockRecords/abstractions.js\";\nimport {\n ListLockRecordsPresenter as Abstraction,\n type IListLockRecordsPresenter,\n type IListLockRecordsViewModel\n} from \"./abstractions.js\";\nimport type { IRecordLockingLockRecord } from \"~/types.js\";\n\nclass ListLockRecordsPresenterImpl implements IListLockRecordsPresenter {\n private _lockMap = observable.map<string, IRecordLockingLockRecord>();\n\n constructor(private listLockRecordsUseCase: ListLockRecordsUseCase.Interface) {\n makeAutoObservable<ListLockRecordsPresenterImpl, \"listLockRecordsUseCase\">(this, {\n listLockRecordsUseCase: false,\n vm: computed\n });\n }\n\n get vm(): IListLockRecordsViewModel {\n return {\n lockedCount: this._lockMap.size\n };\n }\n\n async fetchForEntries(entryIds: string[], type: string): Promise<void> {\n if (entryIds.length === 0) {\n return;\n }\n\n try {\n const records = await this.listLockRecordsUseCase.execute({\n where: { id_in: entryIds, type },\n limit: entryIds.length\n });\n\n runInAction(() => {\n this._lockMap.clear();\n for (const record of records) {\n this._lockMap.set(record.targetId, record);\n }\n });\n } catch {\n // Silently fail — list still works without lock indicators\n }\n }\n\n isLocked(entryId: string): boolean {\n return this._lockMap.has(entryId);\n }\n\n getLockRecord(entryId: string): IRecordLockingLockRecord | undefined {\n return this._lockMap.get(entryId);\n }\n\n dispose(): void {\n this._lockMap.clear();\n }\n}\n\nexport const ListLockRecordsPresenter = Abstraction.createImplementation({\n implementation: ListLockRecordsPresenterImpl,\n dependencies: [ListLockRecordsUseCase]\n});\n"],"names":["ListLockRecordsPresenterImpl","listLockRecordsUseCase","observable","makeAutoObservable","computed","entryIds","type","records","runInAction","record","entryId","ListLockRecordsPresenter","Abstraction","ListLockRecordsUseCase"],"mappings":";;;AASA,MAAMA;IAGF,YAAoBC,sBAAwD,CAAE;aAA1DA,sBAAsB,GAAtBA;aAFZ,QAAQ,GAAGC,WAAW,GAAG;QAG7BC,mBAA2E,IAAI,EAAE;YAC7E,wBAAwB;YACxB,IAAIC;QACR;IACJ;IAEA,IAAI,KAAgC;QAChC,OAAO;YACH,aAAa,IAAI,CAAC,QAAQ,CAAC,IAAI;QACnC;IACJ;IAEA,MAAM,gBAAgBC,QAAkB,EAAEC,IAAY,EAAiB;QACnE,IAAID,AAAoB,MAApBA,SAAS,MAAM,EACf;QAGJ,IAAI;YACA,MAAME,UAAU,MAAM,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;gBACtD,OAAO;oBAAE,OAAOF;oBAAUC;gBAAK;gBAC/B,OAAOD,SAAS,MAAM;YAC1B;YAEAG,YAAY;gBACR,IAAI,CAAC,QAAQ,CAAC,KAAK;gBACnB,KAAK,MAAMC,UAAUF,QACjB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAACE,OAAO,QAAQ,EAAEA;YAE3C;QACJ,EAAE,OAAM,CAER;IACJ;IAEA,SAASC,OAAe,EAAW;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAACA;IAC7B;IAEA,cAAcA,OAAe,EAAwC;QACjE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAACA;IAC7B;IAEA,UAAgB;QACZ,IAAI,CAAC,QAAQ,CAAC,KAAK;IACvB;AACJ;AAEO,MAAMC,oDAA2BC,yBAAAA,oBAAgC,CAAC;IACrE,gBAAgBZ;IAChB,cAAc;QAACa;KAAuB;AAC1C"}
@@ -0,0 +1,16 @@
1
+ import type { IRecordLockingLockRecord } from "../../types.js";
2
+ export interface IListLockRecordsViewModel {
3
+ lockedCount: number;
4
+ }
5
+ export interface IListLockRecordsPresenter {
6
+ readonly vm: IListLockRecordsViewModel;
7
+ fetchForEntries(entryIds: string[], type: string): Promise<void>;
8
+ isLocked(entryId: string): boolean;
9
+ getLockRecord(entryId: string): IRecordLockingLockRecord | undefined;
10
+ dispose(): void;
11
+ }
12
+ export declare const ListLockRecordsPresenter: import("@webiny/di").Abstraction<IListLockRecordsPresenter>;
13
+ export declare namespace ListLockRecordsPresenter {
14
+ type Interface = IListLockRecordsPresenter;
15
+ type ViewModel = IListLockRecordsViewModel;
16
+ }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/admin";
2
+ const ListLockRecordsPresenter = createAbstraction("ListLockRecordsPresenter");
3
+ export { ListLockRecordsPresenter };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/listLocking/abstractions.js","sources":["../../../src/presentation/listLocking/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { IRecordLockingLockRecord } from \"~/types.js\";\n\nexport interface IListLockRecordsViewModel {\n lockedCount: number;\n}\n\nexport interface IListLockRecordsPresenter {\n readonly vm: IListLockRecordsViewModel;\n fetchForEntries(entryIds: string[], type: string): Promise<void>;\n isLocked(entryId: string): boolean;\n getLockRecord(entryId: string): IRecordLockingLockRecord | undefined;\n dispose(): void;\n}\n\nexport const ListLockRecordsPresenter = createAbstraction<IListLockRecordsPresenter>(\n \"ListLockRecordsPresenter\"\n);\n\nexport namespace ListLockRecordsPresenter {\n export type Interface = IListLockRecordsPresenter;\n export type ViewModel = IListLockRecordsViewModel;\n}\n"],"names":["ListLockRecordsPresenter","createAbstraction"],"mappings":";AAeO,MAAMA,2BAA2BC,kBACpC"}
@@ -0,0 +1,3 @@
1
+ export declare const ListLockRecordsSync: (() => null) & {
2
+ displayName: string;
3
+ };
@@ -0,0 +1,26 @@
1
+ import react, { useEffect } from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { useContainer } from "@webiny/app";
4
+ import { useContentEntriesPresenter } from "@webiny/app-headless-cms/presentation/contentEntries/list/useContentEntriesPresenter.js";
5
+ import { ListLockRecordsPresenter } from "../abstractions.js";
6
+ const ListLockRecordsSync = observer(()=>{
7
+ const container = useContainer();
8
+ const presenter = react.useMemo(()=>container.resolve(ListLockRecordsPresenter), [
9
+ container
10
+ ]);
11
+ const entriesPresenter = useContentEntriesPresenter();
12
+ const rows = entriesPresenter.list.vm.rows;
13
+ const modelId = entriesPresenter.vm.model.modelId;
14
+ useEffect(()=>{
15
+ if (0 === rows.length) return;
16
+ const entryIds = rows.map((row)=>row.id);
17
+ presenter.fetchForEntries(entryIds, modelId);
18
+ }, [
19
+ rows,
20
+ modelId
21
+ ]);
22
+ return null;
23
+ });
24
+ export { ListLockRecordsSync };
25
+
26
+ //# sourceMappingURL=ListLockRecordsSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/listLocking/components/ListLockRecordsSync.js","sources":["../../../../src/presentation/listLocking/components/ListLockRecordsSync.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useContainer } from \"@webiny/app\";\nimport { useContentEntriesPresenter } from \"@webiny/app-headless-cms/presentation/contentEntries/list/useContentEntriesPresenter.js\";\nimport { ListLockRecordsPresenter } from \"../abstractions.js\";\n\nexport const ListLockRecordsSync = observer(() => {\n const container = useContainer();\n const presenter = React.useMemo(() => container.resolve(ListLockRecordsPresenter), [container]);\n const entriesPresenter = useContentEntriesPresenter();\n\n const rows = entriesPresenter.list.vm.rows;\n const modelId = entriesPresenter.vm.model.modelId;\n\n useEffect(() => {\n if (rows.length === 0) {\n return;\n }\n\n const entryIds = rows.map(row => row.id);\n presenter.fetchForEntries(entryIds, modelId);\n }, [rows, modelId]);\n\n return null;\n});\n"],"names":["ListLockRecordsSync","observer","container","useContainer","presenter","React","ListLockRecordsPresenter","entriesPresenter","useContentEntriesPresenter","rows","modelId","useEffect","entryIds","row"],"mappings":";;;;;AAMO,MAAMA,sBAAsBC,SAAS;IACxC,MAAMC,YAAYC;IAClB,MAAMC,YAAYC,MAAAA,OAAa,CAAC,IAAMH,UAAU,OAAO,CAACI,2BAA2B;QAACJ;KAAU;IAC9F,MAAMK,mBAAmBC;IAEzB,MAAMC,OAAOF,iBAAiB,IAAI,CAAC,EAAE,CAAC,IAAI;IAC1C,MAAMG,UAAUH,iBAAiB,EAAE,CAAC,KAAK,CAAC,OAAO;IAEjDI,UAAU;QACN,IAAIF,AAAgB,MAAhBA,KAAK,MAAM,EACX;QAGJ,MAAMG,WAAWH,KAAK,GAAG,CAACI,CAAAA,MAAOA,IAAI,EAAE;QACvCT,UAAU,eAAe,CAACQ,UAAUF;IACxC,GAAG;QAACD;QAAMC;KAAQ;IAElB,OAAO;AACX"}
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare const RecordLockingCellActionsDecorator: (props: unknown) => React.JSX.Element;
@@ -0,0 +1,39 @@
1
+ import react from "react";
2
+ import { observer } from "mobx-react-lite";
3
+ import { useContainer } from "@webiny/app";
4
+ import { ReactComponent } from "@webiny/icons/lock.svg";
5
+ import { Icon, Tooltip } from "@webiny/admin-ui";
6
+ import { ContentEntryListConfig, useModel } from "@webiny/app-headless-cms";
7
+ import { ListLockRecordsPresenter } from "../abstractions.js";
8
+ const { Browser: Browser } = ContentEntryListConfig;
9
+ const ActionsCell = observer(({ children })=>{
10
+ const { model } = useModel();
11
+ const container = useContainer();
12
+ const presenter = react.useMemo(()=>container.resolve(ListLockRecordsPresenter), [
13
+ container
14
+ ]);
15
+ const { useTableRow, isFolderRow } = Browser.Table.Column;
16
+ const { row } = useTableRow();
17
+ if (isFolderRow(row)) return /*#__PURE__*/ react.createElement(react.Fragment, null, children);
18
+ const lockRecord = presenter.getLockRecord(row.id);
19
+ if (!lockRecord) return /*#__PURE__*/ react.createElement(react.Fragment, null, children);
20
+ return /*#__PURE__*/ react.createElement(Tooltip, {
21
+ side: "left",
22
+ content: `This ${model.name} is currently locked by ${lockRecord.lockedBy.displayName}.`,
23
+ trigger: /*#__PURE__*/ react.createElement(Icon, {
24
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
25
+ label: "Locked entry",
26
+ color: "neutral-light"
27
+ })
28
+ });
29
+ });
30
+ const RecordLockingCellActionsDecorator = Browser.Table.Column.createDecorator((Original)=>function(props) {
31
+ if ("actions" === props.name && props.cell) return /*#__PURE__*/ react.createElement(Original, {
32
+ ...props,
33
+ cell: /*#__PURE__*/ react.createElement(ActionsCell, null, props.cell)
34
+ });
35
+ return /*#__PURE__*/ react.createElement(Original, props);
36
+ });
37
+ export { RecordLockingCellActionsDecorator };
38
+
39
+ //# sourceMappingURL=LockIndicatorCell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/listLocking/components/LockIndicatorCell.js","sources":["../../../../src/presentation/listLocking/components/LockIndicatorCell.tsx"],"sourcesContent":["import React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useContainer } from \"@webiny/app\";\nimport { ReactComponent as LockedIcon } from \"@webiny/icons/lock.svg\";\nimport { Icon, Tooltip } from \"@webiny/admin-ui\";\nimport { useModel, ContentEntryListConfig } from \"@webiny/app-headless-cms\";\nimport { ListLockRecordsPresenter } from \"../abstractions.js\";\n\nconst { Browser } = ContentEntryListConfig;\n\nconst ActionsCell = observer(({ children }: { children: React.ReactNode }) => {\n const { model } = useModel();\n const container = useContainer();\n const presenter = React.useMemo(() => container.resolve(ListLockRecordsPresenter), [container]);\n const { useTableRow, isFolderRow } = Browser.Table.Column;\n const { row } = useTableRow();\n\n if (isFolderRow(row)) {\n return <>{children}</>;\n }\n\n const lockRecord = presenter.getLockRecord(row.id);\n\n if (!lockRecord) {\n return <>{children}</>;\n }\n\n return (\n <Tooltip\n side={\"left\"}\n content={`This ${model.name} is currently locked by ${lockRecord.lockedBy.displayName}.`}\n trigger={<Icon icon={<LockedIcon />} label={\"Locked entry\"} color={\"neutral-light\"} />}\n />\n );\n});\n\nexport const RecordLockingCellActionsDecorator = Browser.Table.Column.createDecorator(Original => {\n return function RecordLockingCellActions(props) {\n if (props.name === \"actions\" && props.cell) {\n return <Original {...props} cell={<ActionsCell>{props.cell}</ActionsCell>} />;\n }\n\n return <Original {...props} />;\n };\n});\n"],"names":["Browser","ContentEntryListConfig","ActionsCell","observer","children","model","useModel","container","useContainer","presenter","React","ListLockRecordsPresenter","useTableRow","isFolderRow","row","lockRecord","Tooltip","Icon","LockedIcon","RecordLockingCellActionsDecorator","Original","props"],"mappings":";;;;;;;AAQA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAEpB,MAAMC,cAAcC,SAAS,CAAC,EAAEC,QAAQ,EAAiC;IACrE,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAClB,MAAMC,YAAYC;IAClB,MAAMC,YAAYC,MAAAA,OAAa,CAAC,IAAMH,UAAU,OAAO,CAACI,2BAA2B;QAACJ;KAAU;IAC9F,MAAM,EAAEK,WAAW,EAAEC,WAAW,EAAE,GAAGb,QAAQ,KAAK,CAAC,MAAM;IACzD,MAAM,EAAEc,GAAG,EAAE,GAAGF;IAEhB,IAAIC,YAAYC,MACZ,OAAO,WAAP,GAAO,0CAAGV;IAGd,MAAMW,aAAaN,UAAU,aAAa,CAACK,IAAI,EAAE;IAEjD,IAAI,CAACC,YACD,OAAO,WAAP,GAAO,0CAAGX;IAGd,OAAO,WAAP,GACI,oBAACY,SAAOA;QACJ,MAAM;QACN,SAAS,CAAC,KAAK,EAAEX,MAAM,IAAI,CAAC,wBAAwB,EAAEU,WAAW,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;QACxF,uBAAS,oBAACE,MAAIA;YAAC,oBAAM,oBAACC,gBAAUA;YAAK,OAAO;YAAgB,OAAO;;;AAG/E;AAEO,MAAMC,oCAAoCnB,QAAQ,KAAK,CAAC,MAAM,CAAC,eAAe,CAACoB,CAAAA,WAC3E,SAAkCC,KAAK;QAC1C,IAAIA,AAAe,cAAfA,MAAM,IAAI,IAAkBA,MAAM,IAAI,EACtC,OAAO,WAAP,GAAO,oBAACD,UAAAA;YAAU,GAAGC,KAAK;YAAE,oBAAM,oBAACnB,aAAWA,MAAEmB,MAAM,IAAI;;QAG9D,OAAO,WAAP,GAAO,oBAACD,UAAaC;IACzB"}
@@ -0,0 +1,3 @@
1
+ export declare const ListLockRecordsPresenterFeature: import("@webiny/feature/admin").FeatureDefinition<{
2
+ presenter: import("./abstractions.js").IListLockRecordsPresenter;
3
+ }, []>;
@@ -0,0 +1,19 @@
1
+ import { createFeature } from "@webiny/feature/admin";
2
+ import { ListLockRecordsPresenter } from "./abstractions.js";
3
+ import { ListLockRecordsPresenter as external_ListLockRecordsPresenter_js_ListLockRecordsPresenter } from "./ListLockRecordsPresenter.js";
4
+ import { ContentEntriesPresenterLockingDecorator } from "./ContentEntriesPresenterDecorator.js";
5
+ const ListLockRecordsPresenterFeature = createFeature({
6
+ name: "RecordLocking/ListLockRecordsPresenter",
7
+ register (container) {
8
+ container.register(external_ListLockRecordsPresenter_js_ListLockRecordsPresenter).inSingletonScope();
9
+ container.registerDecorator(ContentEntriesPresenterLockingDecorator);
10
+ },
11
+ resolve (container) {
12
+ return {
13
+ presenter: container.resolve(ListLockRecordsPresenter)
14
+ };
15
+ }
16
+ });
17
+ export { ListLockRecordsPresenterFeature };
18
+
19
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation/listLocking/feature.js","sources":["../../../src/presentation/listLocking/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { ListLockRecordsPresenter as Abstraction } from \"./abstractions.js\";\nimport { ListLockRecordsPresenter } from \"./ListLockRecordsPresenter.js\";\nimport { ContentEntriesPresenterLockingDecorator } from \"./ContentEntriesPresenterDecorator.js\";\n\nexport const ListLockRecordsPresenterFeature = createFeature({\n name: \"RecordLocking/ListLockRecordsPresenter\",\n register(container) {\n container.register(ListLockRecordsPresenter).inSingletonScope();\n container.registerDecorator(ContentEntriesPresenterLockingDecorator);\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n"],"names":["ListLockRecordsPresenterFeature","createFeature","container","ListLockRecordsPresenter","ContentEntriesPresenterLockingDecorator","Abstraction"],"mappings":";;;;AAKO,MAAMA,kCAAkCC,cAAc;IACzD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,+DAA0B,gBAAgB;QAC7DD,UAAU,iBAAiB,CAACE;IAChC;IACA,SAAQF,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACG;QACjC;IACJ;AACJ"}
package/types.d.ts CHANGED
@@ -1,67 +1,10 @@
1
- import type { CmsContentEntry } from "@webiny/app-headless-cms/types.js";
2
1
  import type { GenericRecord } from "@webiny/app/types.js";
3
- import type { IRecordLockingUnlockEntryResult } from "./domain/abstractions/IRecordLockingUnlockEntry.js";
4
- import type { IRecordLockingUpdateEntryLockResult } from "./domain/abstractions/IRecordLocking.js";
5
2
  import { Identity } from "@webiny/app-admin/domain/Identity.js";
6
3
  export interface IRecordLockingIdentity {
7
4
  id: string;
8
5
  displayName: string;
9
6
  type: string;
10
7
  }
11
- export interface IRecordLockingRecordLocked {
12
- lockedBy: IRecordLockingIdentity;
13
- lockedOn: string;
14
- expiresOn: string;
15
- actions: IRecordLockingLockRecordAction[];
16
- }
17
- export interface IRecordLockingCmsEntryValuesAction {
18
- type: string;
19
- message: string;
20
- createdBy: Identity;
21
- createdOn: string;
22
- }
23
- export interface IRecordLockingCmsEntryValues {
24
- lockedBy: Identity;
25
- lockedOn: string;
26
- updatedOn: string;
27
- expiresOn: string;
28
- targetId: string;
29
- type: string;
30
- actions: IRecordLockingCmsEntryValuesAction;
31
- }
32
- export interface IPossiblyRecordLockingRecord extends CmsContentEntry<IRecordLockingCmsEntryValues> {
33
- $selectable?: boolean;
34
- $type?: "RECORD";
35
- $lockingType?: string;
36
- $locked?: IRecordLockingRecordLocked | null;
37
- }
38
- export interface IRecordLockingRecord extends IPossiblyRecordLockingRecord {
39
- $lockingType: string;
40
- }
41
- export type IIsRecordLockedParams = Pick<IRecordLockingRecord, "id" | "$lockingType">;
42
- export type IUpdateEntryLockParams = Pick<IRecordLockingRecord, "id" | "$lockingType">;
43
- export type IUnlockEntryParams = Pick<IRecordLockingRecord, "id" | "$lockingType">;
44
- export type IFetchLockRecordParams = Pick<IRecordLockingRecord, "id" | "$lockingType">;
45
- export type IFetchLockedEntryLockRecordParams = Pick<IRecordLockingRecord, "id" | "$lockingType">;
46
- export interface IFetchLockRecordResult {
47
- data: IRecordLockingLockRecord | null;
48
- error: IRecordLockingError | null;
49
- }
50
- export interface IRecordLockingContext<T extends IPossiblyRecordLockingRecord = IPossiblyRecordLockingRecord> {
51
- readonly loading: boolean;
52
- readonly records: IPossiblyRecordLockingRecord[];
53
- readonly error?: IRecordLockingError | null;
54
- setRecords(folderId: string, type: string, records: T[]): Promise<void>;
55
- updateEntryLock(params: IUpdateEntryLockParams): Promise<IRecordLockingUpdateEntryLockResult>;
56
- isRecordLocked(params?: IIsRecordLockedParams): boolean;
57
- getLockRecordEntry(id: string): IRecordLockingRecord | undefined;
58
- fetchLockRecord(params: IFetchLockRecordParams): Promise<IFetchLockRecordResult>;
59
- fetchLockedEntryLockRecord(params: IFetchLockedEntryLockRecordParams): Promise<IRecordLockingLockRecord | null>;
60
- unlockEntry(params: IUnlockEntryParams): Promise<IRecordLockingUnlockEntryResult>;
61
- removeEntryLock(params: IUnlockEntryParams): void;
62
- unlockEntryForce(params: IUnlockEntryParams): Promise<IRecordLockingUnlockEntryResult>;
63
- isLockExpired(input: Date | string): boolean;
64
- }
65
8
  export interface IRecordLockingLockRecordAction {
66
9
  type: string;
67
10
  message: string;
@@ -71,17 +14,13 @@ export interface IRecordLockingLockRecordAction {
71
14
  export interface IRecordLockingLockRecord {
72
15
  id: string;
73
16
  lockedOn: string;
17
+ updatedOn: string;
74
18
  expiresOn: string;
75
19
  lockedBy: IRecordLockingIdentity;
76
20
  targetId: string;
77
21
  type: string;
78
22
  actions: IRecordLockingLockRecordAction[];
79
23
  }
80
- export interface IRecordLockingMeta {
81
- totalCount: number;
82
- cursor: string | null;
83
- hasMoreItems: boolean;
84
- }
85
24
  export interface IRecordLockingError<T = GenericRecord> {
86
25
  message: string;
87
26
  code: string;
@@ -1,2 +0,0 @@
1
- import React from "react";
2
- export declare const HeadlessCmsActionsAcoCell: () => React.JSX.Element;
@@ -1,38 +0,0 @@
1
- import react from "react";
2
- import { ContentEntryListConfig, useModel } from "@webiny/app-headless-cms";
3
- import { ReactComponent } from "@webiny/icons/lock.svg";
4
- import { useRecordLocking } from "../hooks/index.js";
5
- import { UseContentEntriesListHookDecorator } from "./decorators/UseContentEntriesListHookDecorator.js";
6
- import { UseSaveEntryDecorator } from "./decorators/UseSaveEntryDecorator.js";
7
- import { UseRecordsDecorator } from "./decorators/UseRecordsDecorator.js";
8
- import { Icon, Tooltip } from "@webiny/admin-ui";
9
- const { Browser: Browser } = ContentEntryListConfig;
10
- const ActionsCell = ({ children })=>{
11
- const { model } = useModel();
12
- const { getLockRecordEntry, isRecordLocked } = useRecordLocking();
13
- const { useTableRow, isFolderRow } = Browser.Table.Column;
14
- const { row } = useTableRow();
15
- if (isFolderRow(row)) return /*#__PURE__*/ react.createElement(react.Fragment, null, children);
16
- const entry = getLockRecordEntry(row.id);
17
- if (!isRecordLocked(entry) || !entry?.$locked) return /*#__PURE__*/ react.createElement(react.Fragment, null, children);
18
- return /*#__PURE__*/ react.createElement(Tooltip, {
19
- side: "left",
20
- content: `This ${model.name} is currently locked by ${entry.$locked.lockedBy.displayName}.`,
21
- trigger: /*#__PURE__*/ react.createElement(Icon, {
22
- icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
23
- label: "Locked entry",
24
- color: "neutral-light"
25
- })
26
- });
27
- };
28
- const HeadlessCmsActionsAcoCell_RecordLockingCellActions = Browser.Table.Column.createDecorator((Original)=>function(props) {
29
- if ("actions" === props.name && props.cell) return /*#__PURE__*/ react.createElement(Original, {
30
- ...props,
31
- cell: /*#__PURE__*/ react.createElement(ActionsCell, null, props.cell)
32
- });
33
- return /*#__PURE__*/ react.createElement(Original, props);
34
- });
35
- const HeadlessCmsActionsAcoCell = ()=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(UseContentEntriesListHookDecorator, null), /*#__PURE__*/ react.createElement(UseSaveEntryDecorator, null), /*#__PURE__*/ react.createElement(HeadlessCmsActionsAcoCell_RecordLockingCellActions, null), /*#__PURE__*/ react.createElement(UseRecordsDecorator, null));
36
- export { HeadlessCmsActionsAcoCell };
37
-
38
- //# sourceMappingURL=HeadlessCmsActionsAcoCell.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"components/HeadlessCmsActionsAcoCell.js","sources":["../../src/components/HeadlessCmsActionsAcoCell.tsx"],"sourcesContent":["import React from \"react\";\nimport { ContentEntryListConfig, useModel } from \"@webiny/app-headless-cms\";\nimport { ReactComponent as LockedIcon } from \"@webiny/icons/lock.svg\";\nimport { useRecordLocking } from \"~/hooks/index.js\";\nimport { UseContentEntriesListHookDecorator } from \"./decorators/UseContentEntriesListHookDecorator.js\";\nimport { UseSaveEntryDecorator } from \"~/components/decorators/UseSaveEntryDecorator.js\";\nimport { UseRecordsDecorator } from \"./decorators/UseRecordsDecorator.js\";\nimport { Icon, Tooltip } from \"@webiny/admin-ui\";\n\nconst { Browser } = ContentEntryListConfig;\n\ninterface ActionsCellProps {\n children: React.ReactNode;\n}\n\nconst ActionsCell = ({ children }: ActionsCellProps) => {\n const { model } = useModel();\n const { getLockRecordEntry, isRecordLocked } = useRecordLocking();\n\n const { useTableRow, isFolderRow } = Browser.Table.Column;\n const { row } = useTableRow();\n\n if (isFolderRow(row)) {\n return <>{children}</>;\n }\n\n const entry = getLockRecordEntry(row.id);\n\n if (!isRecordLocked(entry) || !entry?.$locked) {\n return <>{children}</>;\n }\n return (\n <Tooltip\n side={\"left\"}\n content={`This ${model.name} is currently locked by ${entry.$locked.lockedBy.displayName}.`}\n trigger={<Icon icon={<LockedIcon />} label={\"Locked entry\"} color={\"neutral-light\"} />}\n />\n );\n};\n\nconst RecordLockingCellActions = Browser.Table.Column.createDecorator(Original => {\n return function RecordLockingCellActions(props) {\n if (props.name === \"actions\" && props.cell) {\n return <Original {...props} cell={<ActionsCell>{props.cell}</ActionsCell>} />;\n }\n\n return <Original {...props} />;\n };\n});\n\nexport const HeadlessCmsActionsAcoCell = () => {\n return (\n <>\n <UseContentEntriesListHookDecorator />\n <UseSaveEntryDecorator />\n <RecordLockingCellActions />\n <UseRecordsDecorator />\n </>\n );\n};\n"],"names":["Browser","ContentEntryListConfig","ActionsCell","children","model","useModel","getLockRecordEntry","isRecordLocked","useRecordLocking","useTableRow","isFolderRow","row","entry","Tooltip","Icon","LockedIcon","RecordLockingCellActions","Original","props","HeadlessCmsActionsAcoCell","UseContentEntriesListHookDecorator","UseSaveEntryDecorator","UseRecordsDecorator"],"mappings":";;;;;;;;AASA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAMpB,MAAMC,cAAc,CAAC,EAAEC,QAAQ,EAAoB;IAC/C,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAClB,MAAM,EAAEC,kBAAkB,EAAEC,cAAc,EAAE,GAAGC;IAE/C,MAAM,EAAEC,WAAW,EAAEC,WAAW,EAAE,GAAGV,QAAQ,KAAK,CAAC,MAAM;IACzD,MAAM,EAAEW,GAAG,EAAE,GAAGF;IAEhB,IAAIC,YAAYC,MACZ,OAAO,WAAP,GAAO,0CAAGR;IAGd,MAAMS,QAAQN,mBAAmBK,IAAI,EAAE;IAEvC,IAAI,CAACJ,eAAeK,UAAU,CAACA,OAAO,SAClC,OAAO,WAAP,GAAO,0CAAGT;IAEd,OAAO,WAAP,GACI,oBAACU,SAAOA;QACJ,MAAM;QACN,SAAS,CAAC,KAAK,EAAET,MAAM,IAAI,CAAC,wBAAwB,EAAEQ,MAAM,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;QAC3F,uBAAS,oBAACE,MAAIA;YAAC,oBAAM,oBAACC,gBAAUA;YAAK,OAAO;YAAgB,OAAO;;;AAG/E;AAEA,MAAMC,qDAA2BhB,QAAQ,KAAK,CAAC,MAAM,CAAC,eAAe,CAACiB,CAAAA,WAC3D,SAAkCC,KAAK;QAC1C,IAAIA,AAAe,cAAfA,MAAM,IAAI,IAAkBA,MAAM,IAAI,EACtC,OAAO,WAAP,GAAO,oBAACD,UAAAA;YAAU,GAAGC,KAAK;YAAE,oBAAM,oBAAChB,aAAWA,MAAEgB,MAAM,IAAI;;QAG9D,OAAO,WAAP,GAAO,oBAACD,UAAaC;IACzB;AAGG,MAAMC,4BAA4B,IAC9B,WAAP,GACI,wDACI,oBAACC,oCAAkCA,OAAAA,WAAAA,GACnC,oBAACC,uBAAqBA,OAAAA,WAAAA,GACtB,oBAACL,oDAAwBA,OAAAA,WAAAA,GACzB,oBAACM,qBAAmBA"}
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- import type { CmsContentEntry, CmsModel } from "@webiny/app-headless-cms/types.js";
3
- export interface IContentEntryGuardProps {
4
- loading: boolean;
5
- entry: CmsContentEntry;
6
- model: CmsModel;
7
- children: React.ReactElement;
8
- }
9
- export declare const ContentEntryGuard: (props: IContentEntryGuardProps) => React.JSX.Element;