@webiny/app-record-locking 0.0.0-unstable.e6f0dc8ca7 → 0.0.0-unstable.eb81deee7e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RecordLockingModule.d.ts +2 -0
- package/RecordLockingModule.js +74 -0
- package/RecordLockingModule.js.map +1 -0
- package/SecurityPermissions.js +15 -0
- package/SecurityPermissions.js.map +1 -0
- package/features/acquireLock/AcquireLockGateway.d.ts +12 -0
- package/features/acquireLock/AcquireLockGateway.js +43 -0
- package/features/acquireLock/AcquireLockGateway.js.map +1 -0
- package/features/acquireLock/AcquireLockUseCase.d.ts +10 -0
- package/features/acquireLock/AcquireLockUseCase.js +18 -0
- package/features/acquireLock/AcquireLockUseCase.js.map +1 -0
- package/features/acquireLock/abstractions.d.ts +19 -0
- package/features/acquireLock/abstractions.js +6 -0
- package/features/acquireLock/abstractions.js.map +1 -0
- package/features/acquireLock/feature.d.ts +3 -0
- package/features/acquireLock/feature.js +19 -0
- package/features/acquireLock/feature.js.map +1 -0
- package/features/checkLockStatus/CheckLockStatusGateway.d.ts +12 -0
- package/features/checkLockStatus/CheckLockStatusGateway.js +43 -0
- package/features/checkLockStatus/CheckLockStatusGateway.js.map +1 -0
- package/features/checkLockStatus/CheckLockStatusUseCase.d.ts +10 -0
- package/features/checkLockStatus/CheckLockStatusUseCase.js +18 -0
- package/features/checkLockStatus/CheckLockStatusUseCase.js.map +1 -0
- package/features/checkLockStatus/abstractions.d.ts +19 -0
- package/features/checkLockStatus/abstractions.js +6 -0
- package/features/checkLockStatus/abstractions.js.map +1 -0
- package/features/checkLockStatus/feature.d.ts +3 -0
- package/features/checkLockStatus/feature.js +19 -0
- package/features/checkLockStatus/feature.js.map +1 -0
- package/features/feature.d.ts +1 -0
- package/features/feature.js +19 -0
- package/features/feature.js.map +1 -0
- package/features/forceUnlock/ForceUnlockGateway.d.ts +12 -0
- package/features/forceUnlock/ForceUnlockGateway.js +44 -0
- package/features/forceUnlock/ForceUnlockGateway.js.map +1 -0
- package/features/forceUnlock/ForceUnlockUseCase.d.ts +10 -0
- package/features/forceUnlock/ForceUnlockUseCase.js +18 -0
- package/features/forceUnlock/ForceUnlockUseCase.js.map +1 -0
- package/features/forceUnlock/abstractions.d.ts +19 -0
- package/features/forceUnlock/abstractions.js +6 -0
- package/features/forceUnlock/abstractions.js.map +1 -0
- package/features/forceUnlock/feature.d.ts +3 -0
- package/features/forceUnlock/feature.js +19 -0
- package/features/forceUnlock/feature.js.map +1 -0
- package/{domain/graphql/fields.js → features/graphqlFields.js} +4 -3
- package/features/graphqlFields.js.map +1 -0
- package/features/listLockRecords/ListLockRecordsGateway.d.ts +12 -0
- package/features/listLockRecords/ListLockRecordsGateway.js +48 -0
- package/features/listLockRecords/ListLockRecordsGateway.js.map +1 -0
- package/features/listLockRecords/ListLockRecordsUseCase.d.ts +10 -0
- package/features/listLockRecords/ListLockRecordsUseCase.js +18 -0
- package/features/listLockRecords/ListLockRecordsUseCase.js.map +1 -0
- package/features/listLockRecords/abstractions.d.ts +22 -0
- package/features/listLockRecords/abstractions.js +6 -0
- package/features/listLockRecords/abstractions.js.map +1 -0
- package/features/listLockRecords/feature.d.ts +3 -0
- package/features/listLockRecords/feature.js +19 -0
- package/features/listLockRecords/feature.js.map +1 -0
- package/features/permissions/abstractions.d.ts +1 -1
- package/features/permissions/abstractions.js +3 -2
- package/features/permissions/abstractions.js.map +1 -1
- package/features/permissions/feature.js +3 -2
- package/features/permissions/feature.js.map +1 -1
- package/features/releaseLock/ReleaseLockGateway.d.ts +12 -0
- package/features/releaseLock/ReleaseLockGateway.js +44 -0
- package/features/releaseLock/ReleaseLockGateway.js.map +1 -0
- package/features/releaseLock/ReleaseLockUseCase.d.ts +10 -0
- package/features/releaseLock/ReleaseLockUseCase.js +18 -0
- package/features/releaseLock/ReleaseLockUseCase.js.map +1 -0
- package/features/releaseLock/abstractions.d.ts +19 -0
- package/features/releaseLock/abstractions.js +6 -0
- package/features/releaseLock/abstractions.js.map +1 -0
- package/features/releaseLock/feature.d.ts +3 -0
- package/features/releaseLock/feature.js +19 -0
- package/features/releaseLock/feature.js.map +1 -0
- package/index.d.ts +0 -5
- package/index.js +20 -27
- package/index.js.map +1 -1
- package/package.json +18 -20
- package/permissions/permissionsSchema.js +10 -0
- package/permissions/permissionsSchema.js.map +1 -0
- package/presentation/entryLocking/ContentEntryFormPresenterDecorator.d.ts +23 -0
- package/presentation/entryLocking/ContentEntryFormPresenterDecorator.js +64 -0
- package/presentation/entryLocking/ContentEntryFormPresenterDecorator.js.map +1 -0
- package/presentation/entryLocking/RecordLockingPresenter.d.ts +32 -0
- package/presentation/entryLocking/RecordLockingPresenter.js +164 -0
- package/presentation/entryLocking/RecordLockingPresenter.js.map +1 -0
- package/presentation/entryLocking/SingleEntryContentDecorator.d.ts +2 -0
- package/presentation/entryLocking/SingleEntryContentDecorator.js +72 -0
- package/presentation/entryLocking/SingleEntryContentDecorator.js.map +1 -0
- package/presentation/entryLocking/SingleEntryPresenterDecorator.d.ts +15 -0
- package/presentation/entryLocking/SingleEntryPresenterDecorator.js +40 -0
- package/presentation/entryLocking/SingleEntryPresenterDecorator.js.map +1 -0
- package/presentation/entryLocking/abstractions.d.ts +26 -0
- package/presentation/entryLocking/abstractions.js +5 -0
- package/presentation/entryLocking/abstractions.js.map +1 -0
- package/presentation/entryLocking/components/ForceUnlockButton.d.ts +11 -0
- package/presentation/entryLocking/components/ForceUnlockButton.js +37 -0
- package/presentation/entryLocking/components/ForceUnlockButton.js.map +1 -0
- package/presentation/entryLocking/components/LockedEntryOverlay.d.ts +10 -0
- package/presentation/entryLocking/components/LockedEntryOverlay.js +52 -0
- package/presentation/entryLocking/components/LockedEntryOverlay.js.map +1 -0
- package/presentation/entryLocking/components/RecordLockingGuard.d.ts +12 -0
- package/presentation/entryLocking/components/RecordLockingGuard.js +74 -0
- package/presentation/entryLocking/components/RecordLockingGuard.js.map +1 -0
- package/presentation/entryLocking/feature.d.ts +3 -0
- package/presentation/entryLocking/feature.js +21 -0
- package/presentation/entryLocking/feature.js.map +1 -0
- package/presentation/listLocking/ContentEntriesPresenterDecorator.d.ts +25 -0
- package/presentation/listLocking/ContentEntriesPresenterDecorator.js +70 -0
- package/presentation/listLocking/ContentEntriesPresenterDecorator.js.map +1 -0
- package/presentation/listLocking/ListLockRecordsPresenter.d.ts +17 -0
- package/presentation/listLocking/ListLockRecordsPresenter.js +52 -0
- package/presentation/listLocking/ListLockRecordsPresenter.js.map +1 -0
- package/presentation/listLocking/abstractions.d.ts +16 -0
- package/presentation/listLocking/abstractions.js +5 -0
- package/presentation/listLocking/abstractions.js.map +1 -0
- package/presentation/listLocking/components/ListLockRecordsSync.d.ts +4 -0
- package/presentation/listLocking/components/ListLockRecordsSync.js +26 -0
- package/presentation/listLocking/components/ListLockRecordsSync.js.map +1 -0
- package/presentation/listLocking/components/LockIndicatorCell.d.ts +2 -0
- package/presentation/listLocking/components/LockIndicatorCell.js +39 -0
- package/presentation/listLocking/components/LockIndicatorCell.js.map +1 -0
- package/presentation/listLocking/feature.d.ts +3 -0
- package/presentation/listLocking/feature.js +19 -0
- package/presentation/listLocking/feature.js.map +1 -0
- package/types.d.ts +1 -62
- package/types.js +0 -3
- package/components/HeadlessCmsActionsAcoCell.d.ts +0 -2
- package/components/HeadlessCmsActionsAcoCell.js +0 -60
- package/components/HeadlessCmsActionsAcoCell.js.map +0 -1
- package/components/HeadlessCmsContentEntry/ContentEntryGuard.d.ts +0 -9
- package/components/HeadlessCmsContentEntry/ContentEntryGuard.js +0 -42
- package/components/HeadlessCmsContentEntry/ContentEntryGuard.js.map +0 -1
- package/components/HeadlessCmsContentEntry/ContentEntryLocker.d.ts +0 -18
- package/components/HeadlessCmsContentEntry/ContentEntryLocker.js +0 -99
- package/components/HeadlessCmsContentEntry/ContentEntryLocker.js.map +0 -1
- package/components/HeadlessCmsContentEntry/HeadlessCmsContentEntry.d.ts +0 -2
- package/components/HeadlessCmsContentEntry/HeadlessCmsContentEntry.js +0 -68
- package/components/HeadlessCmsContentEntry/HeadlessCmsContentEntry.js.map +0 -1
- package/components/HeadlessCmsContentEntry/index.d.ts +0 -1
- package/components/HeadlessCmsContentEntry/index.js +0 -3
- package/components/HeadlessCmsContentEntry/index.js.map +0 -1
- package/components/LockedRecord/LockedRecord.d.ts +0 -6
- package/components/LockedRecord/LockedRecord.js +0 -66
- package/components/LockedRecord/LockedRecord.js.map +0 -1
- package/components/LockedRecord/LockedRecordForceUnlock.d.ts +0 -9
- package/components/LockedRecord/LockedRecordForceUnlock.js +0 -71
- package/components/LockedRecord/LockedRecordForceUnlock.js.map +0 -1
- package/components/LockedRecord/index.d.ts +0 -1
- package/components/LockedRecord/index.js +0 -3
- package/components/LockedRecord/index.js.map +0 -1
- package/components/RecordLockingProvider.d.ts +0 -7
- package/components/RecordLockingProvider.js +0 -125
- package/components/RecordLockingProvider.js.map +0 -1
- package/components/SecurityPermissions.js +0 -18
- package/components/SecurityPermissions.js.map +0 -1
- package/components/decorators/UseContentEntriesListHookDecorator.d.ts +0 -1
- package/components/decorators/UseContentEntriesListHookDecorator.js +0 -23
- package/components/decorators/UseContentEntriesListHookDecorator.js.map +0 -1
- package/components/decorators/UseRecordsDecorator.d.ts +0 -8
- package/components/decorators/UseRecordsDecorator.js +0 -25
- package/components/decorators/UseRecordsDecorator.js.map +0 -1
- package/components/decorators/UseSaveEntryDecorator.d.ts +0 -1
- package/components/decorators/UseSaveEntryDecorator.js +0 -55
- package/components/decorators/UseSaveEntryDecorator.js.map +0 -1
- package/domain/RecordLocking.d.ts +0 -28
- package/domain/RecordLocking.js +0 -321
- package/domain/RecordLocking.js.map +0 -1
- package/domain/RecordLockingClient.d.ts +0 -12
- package/domain/RecordLockingClient.js +0 -19
- package/domain/RecordLockingClient.js.map +0 -1
- package/domain/RecordLockingGetLockRecord.d.ts +0 -11
- package/domain/RecordLockingGetLockRecord.js +0 -21
- package/domain/RecordLockingGetLockRecord.js.map +0 -1
- package/domain/RecordLockingGetLockedEntryLockRecord.d.ts +0 -11
- package/domain/RecordLockingGetLockedEntryLockRecord.js +0 -19
- package/domain/RecordLockingGetLockedEntryLockRecord.js.map +0 -1
- package/domain/RecordLockingIsEntryLocked.d.ts +0 -11
- package/domain/RecordLockingIsEntryLocked.js +0 -19
- package/domain/RecordLockingIsEntryLocked.js.map +0 -1
- package/domain/RecordLockingListLockRecords.d.ts +0 -12
- package/domain/RecordLockingListLockRecords.js +0 -31
- package/domain/RecordLockingListLockRecords.js.map +0 -1
- package/domain/RecordLockingLockEntry.d.ts +0 -11
- package/domain/RecordLockingLockEntry.js +0 -13
- package/domain/RecordLockingLockEntry.js.map +0 -1
- package/domain/RecordLockingUnlockEntry.d.ts +0 -11
- package/domain/RecordLockingUnlockEntry.js +0 -19
- package/domain/RecordLockingUnlockEntry.js.map +0 -1
- package/domain/RecordLockingUpdateEntryLock.d.ts +0 -11
- package/domain/RecordLockingUpdateEntryLock.js +0 -19
- package/domain/RecordLockingUpdateEntryLock.js.map +0 -1
- package/domain/abstractions/IRecordLocking.d.ts +0 -25
- package/domain/abstractions/IRecordLocking.js +0 -3
- package/domain/abstractions/IRecordLocking.js.map +0 -1
- package/domain/abstractions/IRecordLockingClient.d.ts +0 -6
- package/domain/abstractions/IRecordLockingClient.js +0 -3
- package/domain/abstractions/IRecordLockingClient.js.map +0 -1
- package/domain/abstractions/IRecordLockingGetLockRecord.d.ts +0 -12
- package/domain/abstractions/IRecordLockingGetLockRecord.js +0 -3
- package/domain/abstractions/IRecordLockingGetLockRecord.js.map +0 -1
- package/domain/abstractions/IRecordLockingGetLockedEntryLockRecord.d.ts +0 -12
- package/domain/abstractions/IRecordLockingGetLockedEntryLockRecord.js +0 -3
- package/domain/abstractions/IRecordLockingGetLockedEntryLockRecord.js.map +0 -1
- package/domain/abstractions/IRecordLockingIsEntryLocked.d.ts +0 -8
- package/domain/abstractions/IRecordLockingIsEntryLocked.js +0 -3
- package/domain/abstractions/IRecordLockingIsEntryLocked.js.map +0 -1
- package/domain/abstractions/IRecordLockingListLockRecords.d.ts +0 -19
- package/domain/abstractions/IRecordLockingListLockRecords.js +0 -3
- package/domain/abstractions/IRecordLockingListLockRecords.js.map +0 -1
- package/domain/abstractions/IRecordLockingLockEntry.d.ts +0 -12
- package/domain/abstractions/IRecordLockingLockEntry.js +0 -3
- package/domain/abstractions/IRecordLockingLockEntry.js.map +0 -1
- package/domain/abstractions/IRecordLockingUnlockEntry.d.ts +0 -13
- package/domain/abstractions/IRecordLockingUnlockEntry.js +0 -3
- package/domain/abstractions/IRecordLockingUnlockEntry.js.map +0 -1
- package/domain/abstractions/IRecordLockingUpdateEntryLock.d.ts +0 -12
- package/domain/abstractions/IRecordLockingUpdateEntryLock.js +0 -3
- package/domain/abstractions/IRecordLockingUpdateEntryLock.js.map +0 -1
- package/domain/graphql/fields.js.map +0 -1
- package/domain/graphql/getLockRecord.d.ts +0 -12
- package/domain/graphql/getLockRecord.js +0 -18
- package/domain/graphql/getLockRecord.js.map +0 -1
- package/domain/graphql/getLockedEntryLockRecord.d.ts +0 -12
- package/domain/graphql/getLockedEntryLockRecord.js +0 -18
- package/domain/graphql/getLockedEntryLockRecord.js.map +0 -1
- package/domain/graphql/isEntryLocked.d.ts +0 -12
- package/domain/graphql/isEntryLocked.js +0 -16
- package/domain/graphql/isEntryLocked.js.map +0 -1
- package/domain/graphql/listLockRecords.d.ts +0 -17
- package/domain/graphql/listLockRecords.js +0 -26
- package/domain/graphql/listLockRecords.js.map +0 -1
- package/domain/graphql/lockEntry.d.ts +0 -12
- package/domain/graphql/lockEntry.js +0 -20
- package/domain/graphql/lockEntry.js.map +0 -1
- package/domain/graphql/unlockEntry.d.ts +0 -12
- package/domain/graphql/unlockEntry.js +0 -18
- package/domain/graphql/unlockEntry.js.map +0 -1
- package/domain/graphql/updateEntryLock.d.ts +0 -12
- package/domain/graphql/updateEntryLock.js +0 -18
- package/domain/graphql/updateEntryLock.js.map +0 -1
- package/domain/permissionsSchema.js +0 -9
- package/domain/permissionsSchema.js.map +0 -1
- package/domain/utils/createRecordLockingClient.d.ts +0 -3
- package/domain/utils/createRecordLockingClient.js +0 -12
- package/domain/utils/createRecordLockingClient.js.map +0 -1
- package/domain/utils/createRecordLockingError.d.ts +0 -6
- package/domain/utils/createRecordLockingError.js +0 -16
- package/domain/utils/createRecordLockingError.js.map +0 -1
- package/hooks/index.d.ts +0 -2
- package/hooks/index.js +0 -4
- package/hooks/index.js.map +0 -1
- package/hooks/usePermission.d.ts +0 -3
- package/hooks/usePermission.js +0 -20
- package/hooks/usePermission.js.map +0 -1
- package/hooks/useRecordLocking.d.ts +0 -2
- package/hooks/useRecordLocking.js +0 -12
- package/hooks/useRecordLocking.js.map +0 -1
- package/types.js.map +0 -1
- package/utils/createCacheKey.d.ts +0 -3
- package/utils/createCacheKey.js +0 -15
- package/utils/createCacheKey.js.map +0 -1
- /package/{components/SecurityPermissions.d.ts → SecurityPermissions.d.ts} +0 -0
- /package/{domain/graphql/fields.d.ts → features/graphqlFields.d.ts} +0 -0
- /package/{domain → permissions}/permissionsSchema.d.ts +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import react from "react";
|
|
2
|
+
import { ReactComponent } from "@webiny/icons/lock.svg";
|
|
3
|
+
import { Grid, Heading, Icon, Text } from "@webiny/admin-ui";
|
|
4
|
+
import { ForceUnlockButton } from "./ForceUnlockButton.js";
|
|
5
|
+
const LockedEntryOverlay = ({ vm, entryTitle, onForceUnlock, onNavigateBack })=>{
|
|
6
|
+
const title = entryTitle ? `Record (${entryTitle}) is locked!` : "Record is locked!";
|
|
7
|
+
if (!vm.lockRecord?.lockedBy) return /*#__PURE__*/ react.createElement(Wrapper, null, /*#__PURE__*/ react.createElement(Heading, {
|
|
8
|
+
level: 4,
|
|
9
|
+
className: "mb-sm"
|
|
10
|
+
}, title), /*#__PURE__*/ react.createElement(Text, null, "This record is locked, but the system cannot find the user that created the record lock. A force-unlock is required to regain editing capabilities for this record."), /*#__PURE__*/ react.createElement(ForceUnlockButton, {
|
|
11
|
+
canForceUnlock: vm.canForceUnlock,
|
|
12
|
+
lockedBy: null,
|
|
13
|
+
entryTitle: entryTitle,
|
|
14
|
+
onForceUnlock: onForceUnlock,
|
|
15
|
+
onNavigateBack: onNavigateBack
|
|
16
|
+
}));
|
|
17
|
+
return /*#__PURE__*/ react.createElement(Wrapper, null, /*#__PURE__*/ react.createElement(Heading, {
|
|
18
|
+
level: 4,
|
|
19
|
+
className: "mb-sm"
|
|
20
|
+
}, title), /*#__PURE__*/ react.createElement(Text, null, "It is locked because ", /*#__PURE__*/ react.createElement("strong", null, vm.lockedByUserName), " is currently editing this record. You can either contact the user and ask them to unlock the record, or you can wait for the lock to expire."), /*#__PURE__*/ react.createElement(ForceUnlockButton, {
|
|
21
|
+
canForceUnlock: vm.canForceUnlock,
|
|
22
|
+
lockedBy: vm.lockRecord.lockedBy,
|
|
23
|
+
entryTitle: entryTitle,
|
|
24
|
+
onForceUnlock: onForceUnlock,
|
|
25
|
+
onNavigateBack: onNavigateBack
|
|
26
|
+
}));
|
|
27
|
+
};
|
|
28
|
+
const Wrapper = ({ children })=>/*#__PURE__*/ react.createElement("div", {
|
|
29
|
+
className: "w-5/12 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50"
|
|
30
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
31
|
+
className: "flex p-lg border-sm border-neutral-dimmed-darker rounded-3xl bg-neutral-base"
|
|
32
|
+
}, /*#__PURE__*/ react.createElement(Grid, null, /*#__PURE__*/ react.createElement(Grid.Column, {
|
|
33
|
+
span: 3
|
|
34
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
35
|
+
className: "h-full flex items-center justify-center bg-neutral-dimmed rounded-md p-lg"
|
|
36
|
+
}, /*#__PURE__*/ react.createElement(Icon, {
|
|
37
|
+
style: {
|
|
38
|
+
width: "64px",
|
|
39
|
+
height: "64px"
|
|
40
|
+
},
|
|
41
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
|
|
42
|
+
label: "Locked Record",
|
|
43
|
+
color: "accent",
|
|
44
|
+
size: "lg"
|
|
45
|
+
}))), /*#__PURE__*/ react.createElement(Grid.Column, {
|
|
46
|
+
span: 9
|
|
47
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
48
|
+
className: "flex flex-col justify-center"
|
|
49
|
+
}, children)))));
|
|
50
|
+
export { LockedEntryOverlay };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=LockedEntryOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/entryLocking/components/LockedEntryOverlay.js","sources":["../../../../src/presentation/entryLocking/components/LockedEntryOverlay.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as LockIcon } from \"@webiny/icons/lock.svg\";\nimport { Grid, Heading, Icon, Text } from \"@webiny/admin-ui\";\nimport { ForceUnlockButton } from \"./ForceUnlockButton.js\";\nimport type { IRecordLockingViewModel } from \"../abstractions.js\";\n\ninterface LockedEntryOverlayProps {\n vm: IRecordLockingViewModel;\n entryTitle?: string;\n onForceUnlock: () => Promise<boolean>;\n onNavigateBack: () => void;\n}\n\nexport const LockedEntryOverlay = ({\n vm,\n entryTitle,\n onForceUnlock,\n onNavigateBack\n}: LockedEntryOverlayProps) => {\n const title = entryTitle ? `Record (${entryTitle}) is locked!` : \"Record is locked!\";\n\n if (!vm.lockRecord?.lockedBy) {\n return (\n <Wrapper>\n <Heading level={4} className={\"mb-sm\"}>\n {title}\n </Heading>\n <Text>\n This record is locked, but the system cannot find the user that created the\n record lock. A force-unlock is required to regain editing capabilities for this\n record.\n </Text>\n <ForceUnlockButton\n canForceUnlock={vm.canForceUnlock}\n lockedBy={null}\n entryTitle={entryTitle}\n onForceUnlock={onForceUnlock}\n onNavigateBack={onNavigateBack}\n />\n </Wrapper>\n );\n }\n\n return (\n <Wrapper>\n <Heading level={4} className={\"mb-sm\"}>\n {title}\n </Heading>\n <Text>\n It is locked because <strong>{vm.lockedByUserName}</strong> is currently editing\n this record. You can either contact the user and ask them to unlock the record, or\n you can wait for the lock to expire.\n </Text>\n <ForceUnlockButton\n canForceUnlock={vm.canForceUnlock}\n lockedBy={vm.lockRecord.lockedBy}\n entryTitle={entryTitle}\n onForceUnlock={onForceUnlock}\n onNavigateBack={onNavigateBack}\n />\n </Wrapper>\n );\n};\n\nconst Wrapper = ({ children }: { children: React.ReactNode }) => {\n return (\n <div className=\"w-5/12 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50\">\n <div\n className={\n \"flex p-lg border-sm border-neutral-dimmed-darker rounded-3xl bg-neutral-base\"\n }\n >\n <Grid>\n <Grid.Column span={3}>\n <div className=\"h-full flex items-center justify-center bg-neutral-dimmed rounded-md p-lg\">\n <Icon\n style={{ width: \"64px\", height: \"64px\" }}\n icon={<LockIcon />}\n label={\"Locked Record\"}\n color={\"accent\"}\n size={\"lg\"}\n />\n </div>\n </Grid.Column>\n <Grid.Column span={9}>\n <div className={\"flex flex-col justify-center\"}>{children}</div>\n </Grid.Column>\n </Grid>\n </div>\n </div>\n );\n};\n"],"names":["LockedEntryOverlay","vm","entryTitle","onForceUnlock","onNavigateBack","title","Wrapper","Heading","Text","ForceUnlockButton","children","Grid","Icon","LockIcon"],"mappings":";;;;AAaO,MAAMA,qBAAqB,CAAC,EAC/BC,EAAE,EACFC,UAAU,EACVC,aAAa,EACbC,cAAc,EACQ;IACtB,MAAMC,QAAQH,aAAa,CAAC,QAAQ,EAAEA,WAAW,YAAY,CAAC,GAAG;IAEjE,IAAI,CAACD,GAAG,UAAU,EAAE,UAChB,OAAO,WAAP,GACI,oBAACK,SAAOA,MAAAA,WAAAA,GACJ,oBAACC,SAAOA;QAAC,OAAO;QAAG,WAAW;OACzBF,QAAAA,WAAAA,GAEL,oBAACG,MAAIA,MAAC,sLAKN,oBAACC,mBAAiBA;QACd,gBAAgBR,GAAG,cAAc;QACjC,UAAU;QACV,YAAYC;QACZ,eAAeC;QACf,gBAAgBC;;IAMhC,OAAO,WAAP,GACI,oBAACE,SAAOA,MAAAA,WAAAA,GACJ,oBAACC,SAAOA;QAAC,OAAO;QAAG,WAAW;OACzBF,QAAAA,WAAAA,GAEL,oBAACG,MAAIA,MAAC,uCACmB,oBAAC,gBAAQP,GAAG,gBAAgB,GAAU,gKAI/D,oBAACQ,mBAAiBA;QACd,gBAAgBR,GAAG,cAAc;QACjC,UAAUA,GAAG,UAAU,CAAC,QAAQ;QAChC,YAAYC;QACZ,eAAeC;QACf,gBAAgBC;;AAIhC;AAEA,MAAME,UAAU,CAAC,EAAEI,QAAQ,EAAiC,GACjD,WAAP,GACI,oBAAC;QAAI,WAAU;qBACX,oBAAC;QACG,WACI;qBAGJ,oBAACC,MAAIA,MAAAA,WAAAA,GACD,oBAACA,KAAK,MAAM;QAAC,MAAM;qBACf,oBAAC;QAAI,WAAU;qBACX,oBAACC,MAAIA;QACD,OAAO;YAAE,OAAO;YAAQ,QAAQ;QAAO;QACvC,oBAAM,oBAACC,gBAAQA;QACf,OAAO;QACP,OAAO;QACP,MAAM;wBAIlB,oBAACF,KAAK,MAAM;QAAC,MAAM;qBACf,oBAAC;QAAI,WAAW;OAAiCD"}
|
|
@@ -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) & React.NamedExoticComponent<RecordLockingGuardProps> & {
|
|
10
|
+
readonly type: ({ entryId, modelId, entryTitle, onNavigateBack, children }: RecordLockingGuardProps) => React.JSX.Element;
|
|
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,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,25 @@
|
|
|
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
|
+
duplicateEntry(entry: Parameters<IContentEntriesPresenter["duplicateEntry"]>[0]): Promise<false | import("@webiny/app-headless-cms/presentation/contentEntries/list/abstractions.js").IDuplicateEntryResult>;
|
|
21
|
+
}
|
|
22
|
+
export declare const ContentEntriesPresenterLockingDecorator: typeof ContentEntriesPresenterWithLocking & {
|
|
23
|
+
__abstraction: import("@webiny/di").Abstraction<IContentEntriesPresenter>;
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { compareStructural, 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: compareStructural
|
|
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
|
+
duplicateEntry(entry) {
|
|
59
|
+
return this.original.duplicateEntry(entry);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const ContentEntriesPresenterLockingDecorator = ContentEntriesPresenter.createDecorator({
|
|
63
|
+
decorator: ContentEntriesPresenterWithLocking,
|
|
64
|
+
dependencies: [
|
|
65
|
+
ListLockRecordsPresenter
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
export { ContentEntriesPresenterLockingDecorator };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=ContentEntriesPresenterDecorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/listLocking/ContentEntriesPresenterDecorator.js","sources":["../../../src/presentation/listLocking/ContentEntriesPresenterDecorator.ts"],"sourcesContent":["import { compareStructural, 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: compareStructural }\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 duplicateEntry(entry: Parameters<IContentEntriesPresenter[\"duplicateEntry\"]>[0]) {\n return this.original.duplicateEntry(entry);\n }\n}\n\nexport const ContentEntriesPresenterLockingDecorator = ContentEntriesPresenter.createDecorator({\n decorator: ContentEntriesPresenterWithLocking,\n dependencies: [ListLockRecordsPresenter]\n});\n"],"names":["ContentEntriesPresenterWithLocking","lockRecordsPresenter","original","config","reaction","r","entryIds","compareStructural","id","folderId","entry","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;QAAkB;IAE3D;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;IAEA,eAAeC,KAAgE,EAAE;QAC7E,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAACA;IACxC;AACJ;AAEO,MAAMC,0CAA0CC,wBAAwB,eAAe,CAAC;IAC3F,WAAWZ;IACX,cAAc;QAACa;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 @@
|
|
|
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,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,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,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"}
|