@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
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;
|
package/types.js
CHANGED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { ContentEntryListConfig, useModel } from "@webiny/app-headless-cms";
|
|
3
|
-
import { ReactComponent as LockedIcon } 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 {
|
|
10
|
-
Browser
|
|
11
|
-
} = ContentEntryListConfig;
|
|
12
|
-
const ActionsCell = ({
|
|
13
|
-
children
|
|
14
|
-
}) => {
|
|
15
|
-
const {
|
|
16
|
-
model
|
|
17
|
-
} = useModel();
|
|
18
|
-
const {
|
|
19
|
-
getLockRecordEntry,
|
|
20
|
-
isRecordLocked
|
|
21
|
-
} = useRecordLocking();
|
|
22
|
-
const {
|
|
23
|
-
useTableRow,
|
|
24
|
-
isFolderRow
|
|
25
|
-
} = Browser.Table.Column;
|
|
26
|
-
const {
|
|
27
|
-
row
|
|
28
|
-
} = useTableRow();
|
|
29
|
-
if (isFolderRow(row)) {
|
|
30
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
31
|
-
}
|
|
32
|
-
const entry = getLockRecordEntry(row.id);
|
|
33
|
-
if (!isRecordLocked(entry) || !entry?.$locked) {
|
|
34
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
35
|
-
}
|
|
36
|
-
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
37
|
-
side: "left",
|
|
38
|
-
content: `This ${model.name} is currently locked by ${entry.$locked.lockedBy.displayName}.`,
|
|
39
|
-
trigger: /*#__PURE__*/React.createElement(Icon, {
|
|
40
|
-
icon: /*#__PURE__*/React.createElement(LockedIcon, null),
|
|
41
|
-
label: "Locked entry",
|
|
42
|
-
color: "neutral-light"
|
|
43
|
-
})
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
const RecordLockingCellActions = Browser.Table.Column.createDecorator(Original => {
|
|
47
|
-
return function RecordLockingCellActions(props) {
|
|
48
|
-
if (props.name === "actions" && props.cell) {
|
|
49
|
-
return /*#__PURE__*/React.createElement(Original, Object.assign({}, props, {
|
|
50
|
-
cell: /*#__PURE__*/React.createElement(ActionsCell, null, props.cell)
|
|
51
|
-
}));
|
|
52
|
-
}
|
|
53
|
-
return /*#__PURE__*/React.createElement(Original, props);
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
export const HeadlessCmsActionsAcoCell = () => {
|
|
57
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(UseContentEntriesListHookDecorator, null), /*#__PURE__*/React.createElement(UseSaveEntryDecorator, null), /*#__PURE__*/React.createElement(RecordLockingCellActions, null), /*#__PURE__*/React.createElement(UseRecordsDecorator, null));
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
//# sourceMappingURL=HeadlessCmsActionsAcoCell.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","ContentEntryListConfig","useModel","ReactComponent","LockedIcon","useRecordLocking","UseContentEntriesListHookDecorator","UseSaveEntryDecorator","UseRecordsDecorator","Icon","Tooltip","Browser","ActionsCell","children","model","getLockRecordEntry","isRecordLocked","useTableRow","isFolderRow","Table","Column","row","createElement","Fragment","entry","id","$locked","side","content","name","lockedBy","displayName","trigger","icon","label","color","RecordLockingCellActions","createDecorator","Original","props","cell","Object","assign","HeadlessCmsActionsAcoCell"],"sources":["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"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,sBAAsB,EAAEC,QAAQ,QAAQ,0BAA0B;AAC3E,SAASC,cAAc,IAAIC,UAAU,QAAQ,wBAAwB;AACrE,SAASC,gBAAgB;AACzB,SAASC,kCAAkC;AAC3C,SAASC,qBAAqB;AAC9B,SAASC,mBAAmB;AAC5B,SAASC,IAAI,EAAEC,OAAO,QAAQ,kBAAkB;AAEhD,MAAM;EAAEC;AAAQ,CAAC,GAAGV,sBAAsB;AAM1C,MAAMW,WAAW,GAAGA,CAAC;EAAEC;AAA2B,CAAC,KAAK;EACpD,MAAM;IAAEC;EAAM,CAAC,GAAGZ,QAAQ,CAAC,CAAC;EAC5B,MAAM;IAAEa,kBAAkB;IAAEC;EAAe,CAAC,GAAGX,gBAAgB,CAAC,CAAC;EAEjE,MAAM;IAAEY,WAAW;IAAEC;EAAY,CAAC,GAAGP,OAAO,CAACQ,KAAK,CAACC,MAAM;EACzD,MAAM;IAAEC;EAAI,CAAC,GAAGJ,WAAW,CAAC,CAAC;EAE7B,IAAIC,WAAW,CAACG,GAAG,CAAC,EAAE;IAClB,oBAAOrB,KAAA,CAAAsB,aAAA,CAAAtB,KAAA,CAAAuB,QAAA,QAAGV,QAAW,CAAC;EAC1B;EAEA,MAAMW,KAAK,GAAGT,kBAAkB,CAACM,GAAG,CAACI,EAAE,CAAC;EAExC,IAAI,CAACT,cAAc,CAACQ,KAAK,CAAC,IAAI,CAACA,KAAK,EAAEE,OAAO,EAAE;IAC3C,oBAAO1B,KAAA,CAAAsB,aAAA,CAAAtB,KAAA,CAAAuB,QAAA,QAAGV,QAAW,CAAC;EAC1B;EACA,oBACIb,KAAA,CAAAsB,aAAA,CAACZ,OAAO;IACJiB,IAAI,EAAE,MAAO;IACbC,OAAO,EAAE,QAAQd,KAAK,CAACe,IAAI,2BAA2BL,KAAK,CAACE,OAAO,CAACI,QAAQ,CAACC,WAAW,GAAI;IAC5FC,OAAO,eAAEhC,KAAA,CAAAsB,aAAA,CAACb,IAAI;MAACwB,IAAI,eAAEjC,KAAA,CAAAsB,aAAA,CAAClB,UAAU,MAAE,CAAE;MAAC8B,KAAK,EAAE,cAAe;MAACC,KAAK,EAAE;IAAgB,CAAE;EAAE,CAC1F,CAAC;AAEV,CAAC;AAED,MAAMC,wBAAwB,GAAGzB,OAAO,CAACQ,KAAK,CAACC,MAAM,CAACiB,eAAe,CAACC,QAAQ,IAAI;EAC9E,OAAO,SAASF,wBAAwBA,CAACG,KAAK,EAAE;IAC5C,IAAIA,KAAK,CAACV,IAAI,KAAK,SAAS,IAAIU,KAAK,CAACC,IAAI,EAAE;MACxC,oBAAOxC,KAAA,CAAAsB,aAAA,CAACgB,QAAQ,EAAAG,MAAA,CAAAC,MAAA,KAAKH,KAAK;QAAEC,IAAI,eAAExC,KAAA,CAAAsB,aAAA,CAACV,WAAW,QAAE2B,KAAK,CAACC,IAAkB;MAAE,EAAE,CAAC;IACjF;IAEA,oBAAOxC,KAAA,CAAAsB,aAAA,CAACgB,QAAQ,EAAKC,KAAQ,CAAC;EAClC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,MAAMI,yBAAyB,GAAGA,CAAA,KAAM;EAC3C,oBACI3C,KAAA,CAAAsB,aAAA,CAAAtB,KAAA,CAAAuB,QAAA,qBACIvB,KAAA,CAAAsB,aAAA,CAAChB,kCAAkC,MAAE,CAAC,eACtCN,KAAA,CAAAsB,aAAA,CAACf,qBAAqB,MAAE,CAAC,eACzBP,KAAA,CAAAsB,aAAA,CAACc,wBAAwB,MAAE,CAAC,eAC5BpC,KAAA,CAAAsB,aAAA,CAACd,mBAAmB,MAAE,CACxB,CAAC;AAEX,CAAC","ignoreList":[]}
|
|
@@ -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;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
-
import { useRecordLocking } from "../../hooks/index.js";
|
|
3
|
-
import { LockedRecord } from "../LockedRecord/index.js";
|
|
4
|
-
import { OverlayLoader } from "@webiny/admin-ui";
|
|
5
|
-
export const ContentEntryGuard = props => {
|
|
6
|
-
const {
|
|
7
|
-
loading,
|
|
8
|
-
entry,
|
|
9
|
-
model,
|
|
10
|
-
children
|
|
11
|
-
} = props;
|
|
12
|
-
const {
|
|
13
|
-
fetchLockedEntryLockRecord
|
|
14
|
-
} = useRecordLocking();
|
|
15
|
-
const [locked, setLocked] = useState(undefined);
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (!entry.id || loading || locked !== undefined) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
(async () => {
|
|
21
|
-
const result = await fetchLockedEntryLockRecord({
|
|
22
|
-
id: entry.id,
|
|
23
|
-
$lockingType: model.modelId
|
|
24
|
-
});
|
|
25
|
-
setLocked(result);
|
|
26
|
-
})();
|
|
27
|
-
}, [entry.id, loading]);
|
|
28
|
-
if (locked === undefined) {
|
|
29
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
30
|
-
className: "h-screen w-screen fixed top-0 left-0 z-20"
|
|
31
|
-
}, /*#__PURE__*/React.createElement(OverlayLoader, {
|
|
32
|
-
text: "Checking record status..."
|
|
33
|
-
}));
|
|
34
|
-
} else if (locked) {
|
|
35
|
-
return /*#__PURE__*/React.createElement(LockedRecord, {
|
|
36
|
-
record: locked
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return children;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
//# sourceMappingURL=ContentEntryGuard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","useEffect","useState","useRecordLocking","LockedRecord","OverlayLoader","ContentEntryGuard","props","loading","entry","model","children","fetchLockedEntryLockRecord","locked","setLocked","undefined","id","result","$lockingType","modelId","createElement","className","text","record"],"sources":["ContentEntryGuard.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { useRecordLocking } from \"~/hooks/index.js\";\nimport { LockedRecord } from \"../LockedRecord/index.js\";\nimport type { IRecordLockingLockRecord } from \"~/types.js\";\nimport type { CmsContentEntry, CmsModel } from \"@webiny/app-headless-cms/types.js\";\nimport { OverlayLoader } from \"@webiny/admin-ui\";\n\nexport interface IContentEntryGuardProps {\n loading: boolean;\n entry: CmsContentEntry;\n model: CmsModel;\n children: React.ReactElement;\n}\n\nexport const ContentEntryGuard = (props: IContentEntryGuardProps) => {\n const { loading, entry, model, children } = props;\n const { fetchLockedEntryLockRecord } = useRecordLocking();\n\n const [locked, setLocked] = useState<IRecordLockingLockRecord | null | undefined>(undefined);\n\n useEffect(() => {\n if (!entry.id || loading || locked !== undefined) {\n return;\n }\n (async () => {\n const result = await fetchLockedEntryLockRecord({\n id: entry.id,\n $lockingType: model.modelId\n });\n setLocked(result);\n })();\n }, [entry.id, loading]);\n\n if (locked === undefined) {\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 } else if (locked) {\n return <LockedRecord record={locked} />;\n }\n\n return children;\n};\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAClD,SAASC,gBAAgB;AACzB,SAASC,YAAY;AAGrB,SAASC,aAAa,QAAQ,kBAAkB;AAShD,OAAO,MAAMC,iBAAiB,GAAIC,KAA8B,IAAK;EACjE,MAAM;IAAEC,OAAO;IAAEC,KAAK;IAAEC,KAAK;IAAEC;EAAS,CAAC,GAAGJ,KAAK;EACjD,MAAM;IAAEK;EAA2B,CAAC,GAAGT,gBAAgB,CAAC,CAAC;EAEzD,MAAM,CAACU,MAAM,EAAEC,SAAS,CAAC,GAAGZ,QAAQ,CAA8Ca,SAAS,CAAC;EAE5Fd,SAAS,CAAC,MAAM;IACZ,IAAI,CAACQ,KAAK,CAACO,EAAE,IAAIR,OAAO,IAAIK,MAAM,KAAKE,SAAS,EAAE;MAC9C;IACJ;IACA,CAAC,YAAY;MACT,MAAME,MAAM,GAAG,MAAML,0BAA0B,CAAC;QAC5CI,EAAE,EAAEP,KAAK,CAACO,EAAE;QACZE,YAAY,EAAER,KAAK,CAACS;MACxB,CAAC,CAAC;MACFL,SAAS,CAACG,MAAM,CAAC;IACrB,CAAC,EAAE,CAAC;EACR,CAAC,EAAE,CAACR,KAAK,CAACO,EAAE,EAAER,OAAO,CAAC,CAAC;EAEvB,IAAIK,MAAM,KAAKE,SAAS,EAAE;IACtB,oBACIf,KAAA,CAAAoB,aAAA;MAAKC,SAAS,EAAE;IAA4C,gBACxDrB,KAAA,CAAAoB,aAAA,CAACf,aAAa;MAACiB,IAAI,EAAE;IAA4B,CAAE,CAClD,CAAC;EAEd,CAAC,MAAM,IAAIT,MAAM,EAAE;IACf,oBAAOb,KAAA,CAAAoB,aAAA,CAAChB,YAAY;MAACmB,MAAM,EAAEV;IAAO,CAAE,CAAC;EAC3C;EAEA,OAAOF,QAAQ;AACnB,CAAC","ignoreList":[]}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { IRecordLockingIdentity, IRecordLockingLockRecord } from "../../types.js";
|
|
3
|
-
import type { IncomingGenericData } from "@webiny/app-websockets";
|
|
4
|
-
import type { CmsContentEntry, CmsModel } from "@webiny/app-headless-cms/types.js";
|
|
5
|
-
export interface IContentEntryLockerProps {
|
|
6
|
-
entry: CmsContentEntry;
|
|
7
|
-
model: CmsModel;
|
|
8
|
-
onEntryUnlocked: () => void;
|
|
9
|
-
onDisablePrompt: () => void;
|
|
10
|
-
children: React.ReactElement;
|
|
11
|
-
}
|
|
12
|
-
export interface IKickOutWebsocketsMessage extends IncomingGenericData {
|
|
13
|
-
data: {
|
|
14
|
-
record: IRecordLockingLockRecord;
|
|
15
|
-
user: IRecordLockingIdentity;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export declare const ContentEntryLocker: ({ onEntryUnlocked, onDisablePrompt, entry, model, children }: IContentEntryLockerProps) => React.JSX.Element;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useRef } from "react";
|
|
2
|
-
import { useRecordLocking } from "../../hooks/index.js";
|
|
3
|
-
import { useWebsockets } from "@webiny/app-websockets";
|
|
4
|
-
import { parseIdentifier } from "@webiny/utils";
|
|
5
|
-
import { useDialogs } from "@webiny/app-admin";
|
|
6
|
-
const autoUpdateTimeout = 20;
|
|
7
|
-
export const ContentEntryLocker = ({
|
|
8
|
-
onEntryUnlocked,
|
|
9
|
-
onDisablePrompt,
|
|
10
|
-
entry,
|
|
11
|
-
model,
|
|
12
|
-
children
|
|
13
|
-
}) => {
|
|
14
|
-
const {
|
|
15
|
-
updateEntryLock,
|
|
16
|
-
removeEntryLock
|
|
17
|
-
} = useRecordLocking();
|
|
18
|
-
const websockets = useWebsockets();
|
|
19
|
-
const {
|
|
20
|
-
showDialog
|
|
21
|
-
} = useDialogs();
|
|
22
|
-
const entryLockerTimeout = useRef(null);
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (!entry.id) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
const {
|
|
28
|
-
id: entryId
|
|
29
|
-
} = parseIdentifier(entry.id);
|
|
30
|
-
let onMessageSub = websockets.onMessage(`recordLocking.entry.kickOut.${entryId}`, async incoming => {
|
|
31
|
-
const {
|
|
32
|
-
user
|
|
33
|
-
} = incoming.data;
|
|
34
|
-
onDisablePrompt();
|
|
35
|
-
removeEntryLock({
|
|
36
|
-
id: entryId,
|
|
37
|
-
$lockingType: model.modelId
|
|
38
|
-
});
|
|
39
|
-
showDialog({
|
|
40
|
-
title: "Entry was forcefully unlocked!",
|
|
41
|
-
content: /*#__PURE__*/React.createElement(React.Fragment, null, "The entry you were editing was forcefully unlocked by", " ", /*#__PURE__*/React.createElement("strong", null, user.displayName || "Unknown user"), ". Unfortunately, this means you lost the unsaved changes."),
|
|
42
|
-
acceptLabel: "Ok",
|
|
43
|
-
onClose: undefined,
|
|
44
|
-
cancelLabel: null
|
|
45
|
-
});
|
|
46
|
-
onEntryUnlocked();
|
|
47
|
-
});
|
|
48
|
-
return () => {
|
|
49
|
-
onMessageSub.off();
|
|
50
|
-
/**
|
|
51
|
-
* Lets null subscriptions, just in case it...
|
|
52
|
-
*/
|
|
53
|
-
// @ts-expect-error
|
|
54
|
-
onMessageSub = null;
|
|
55
|
-
};
|
|
56
|
-
}, [entry.id, onEntryUnlocked, model.modelId]);
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
if (!entry.id) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (entryLockerTimeout.current) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const updateLock = async () => {
|
|
65
|
-
const result = await updateEntryLock({
|
|
66
|
-
id: entry.id,
|
|
67
|
-
$lockingType: model.modelId
|
|
68
|
-
});
|
|
69
|
-
if (result.error) {
|
|
70
|
-
showDialog({
|
|
71
|
-
title: "There was an error while updating the entry lock.",
|
|
72
|
-
content: result.error.message,
|
|
73
|
-
acceptLabel: "Ok",
|
|
74
|
-
onClose: undefined,
|
|
75
|
-
cancelLabel: null
|
|
76
|
-
});
|
|
77
|
-
onEntryUnlocked();
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
createTimeout();
|
|
81
|
-
};
|
|
82
|
-
const createTimeout = () => {
|
|
83
|
-
entryLockerTimeout.current = window.setTimeout(() => {
|
|
84
|
-
updateLock();
|
|
85
|
-
}, autoUpdateTimeout * 1000);
|
|
86
|
-
};
|
|
87
|
-
updateLock();
|
|
88
|
-
return () => {
|
|
89
|
-
if (!entryLockerTimeout.current) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
clearTimeout(entryLockerTimeout.current);
|
|
93
|
-
entryLockerTimeout.current = null;
|
|
94
|
-
};
|
|
95
|
-
}, [entry.id, onEntryUnlocked]);
|
|
96
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
//# sourceMappingURL=ContentEntryLocker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","useEffect","useRef","useRecordLocking","useWebsockets","parseIdentifier","useDialogs","autoUpdateTimeout","ContentEntryLocker","onEntryUnlocked","onDisablePrompt","entry","model","children","updateEntryLock","removeEntryLock","websockets","showDialog","entryLockerTimeout","id","entryId","onMessageSub","onMessage","incoming","user","data","$lockingType","modelId","title","content","createElement","Fragment","displayName","acceptLabel","onClose","undefined","cancelLabel","off","current","updateLock","result","error","message","createTimeout","window","setTimeout","clearTimeout"],"sources":["ContentEntryLocker.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useRecordLocking } from \"~/hooks/index.js\";\nimport type { IRecordLockingIdentity, IRecordLockingLockRecord } from \"~/types.js\";\nimport type { IncomingGenericData } from \"@webiny/app-websockets\";\nimport { useWebsockets } from \"@webiny/app-websockets\";\nimport { parseIdentifier } from \"@webiny/utils\";\nimport { useDialogs } from \"@webiny/app-admin\";\nimport type { CmsContentEntry, CmsModel } from \"@webiny/app-headless-cms/types.js\";\n\nconst autoUpdateTimeout = 20;\n\nexport interface IContentEntryLockerProps {\n entry: CmsContentEntry;\n model: CmsModel;\n onEntryUnlocked: () => void;\n onDisablePrompt: () => void;\n children: React.ReactElement;\n}\n\nexport interface IKickOutWebsocketsMessage extends IncomingGenericData {\n data: {\n record: IRecordLockingLockRecord;\n user: IRecordLockingIdentity;\n };\n}\n\nexport const ContentEntryLocker = ({\n onEntryUnlocked,\n onDisablePrompt,\n entry,\n model,\n children\n}: IContentEntryLockerProps) => {\n const { updateEntryLock, removeEntryLock } = useRecordLocking();\n const websockets = useWebsockets();\n const { showDialog } = useDialogs();\n\n const entryLockerTimeout = useRef<number | null>(null);\n\n useEffect(() => {\n if (!entry.id) {\n return;\n }\n const { id: entryId } = parseIdentifier(entry.id);\n\n let onMessageSub = websockets.onMessage<IKickOutWebsocketsMessage>(\n `recordLocking.entry.kickOut.${entryId}`,\n async incoming => {\n const { user } = incoming.data;\n onDisablePrompt();\n removeEntryLock({\n id: entryId,\n $lockingType: model.modelId\n });\n showDialog({\n title: \"Entry was forcefully unlocked!\",\n content: (\n <>\n The entry you were editing was forcefully unlocked by{\" \"}\n <strong>{user.displayName || \"Unknown user\"}</strong>. Unfortunately,\n this means you lost the unsaved changes.\n </>\n ),\n acceptLabel: \"Ok\",\n onClose: undefined,\n cancelLabel: null\n });\n onEntryUnlocked();\n }\n );\n\n return () => {\n onMessageSub.off();\n /**\n * Lets null subscriptions, just in case it...\n */\n // @ts-expect-error\n onMessageSub = null;\n };\n }, [entry.id, onEntryUnlocked, model.modelId]);\n\n useEffect(() => {\n if (!entry.id) {\n return;\n }\n\n if (entryLockerTimeout.current) {\n return;\n }\n\n const updateLock = async () => {\n const result = await updateEntryLock({\n id: entry.id,\n $lockingType: model.modelId\n });\n if (result.error) {\n showDialog({\n title: \"There was an error while updating the entry lock.\",\n content: result.error.message,\n acceptLabel: \"Ok\",\n onClose: undefined,\n cancelLabel: null\n });\n onEntryUnlocked();\n return;\n }\n createTimeout();\n };\n\n const createTimeout = () => {\n entryLockerTimeout.current = window.setTimeout(() => {\n updateLock();\n }, autoUpdateTimeout * 1000);\n };\n\n updateLock();\n return () => {\n if (!entryLockerTimeout.current) {\n return;\n }\n clearTimeout(entryLockerTimeout.current);\n entryLockerTimeout.current = null;\n };\n }, [entry.id, onEntryUnlocked]);\n\n return <>{children}</>;\n};\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,MAAM,QAAQ,OAAO;AAChD,SAASC,gBAAgB;AAGzB,SAASC,aAAa,QAAQ,wBAAwB;AACtD,SAASC,eAAe,QAAQ,eAAe;AAC/C,SAASC,UAAU,QAAQ,mBAAmB;AAG9C,MAAMC,iBAAiB,GAAG,EAAE;AAiB5B,OAAO,MAAMC,kBAAkB,GAAGA,CAAC;EAC/BC,eAAe;EACfC,eAAe;EACfC,KAAK;EACLC,KAAK;EACLC;AACsB,CAAC,KAAK;EAC5B,MAAM;IAAEC,eAAe;IAAEC;EAAgB,CAAC,GAAGZ,gBAAgB,CAAC,CAAC;EAC/D,MAAMa,UAAU,GAAGZ,aAAa,CAAC,CAAC;EAClC,MAAM;IAAEa;EAAW,CAAC,GAAGX,UAAU,CAAC,CAAC;EAEnC,MAAMY,kBAAkB,GAAGhB,MAAM,CAAgB,IAAI,CAAC;EAEtDD,SAAS,CAAC,MAAM;IACZ,IAAI,CAACU,KAAK,CAACQ,EAAE,EAAE;MACX;IACJ;IACA,MAAM;MAAEA,EAAE,EAAEC;IAAQ,CAAC,GAAGf,eAAe,CAACM,KAAK,CAACQ,EAAE,CAAC;IAEjD,IAAIE,YAAY,GAAGL,UAAU,CAACM,SAAS,CACnC,+BAA+BF,OAAO,EAAE,EACxC,MAAMG,QAAQ,IAAI;MACd,MAAM;QAAEC;MAAK,CAAC,GAAGD,QAAQ,CAACE,IAAI;MAC9Bf,eAAe,CAAC,CAAC;MACjBK,eAAe,CAAC;QACZI,EAAE,EAAEC,OAAO;QACXM,YAAY,EAAEd,KAAK,CAACe;MACxB,CAAC,CAAC;MACFV,UAAU,CAAC;QACPW,KAAK,EAAE,gCAAgC;QACvCC,OAAO,eACH7B,KAAA,CAAA8B,aAAA,CAAA9B,KAAA,CAAA+B,QAAA,QAAE,uDACuD,EAAC,GAAG,eACzD/B,KAAA,CAAA8B,aAAA,iBAASN,IAAI,CAACQ,WAAW,IAAI,cAAuB,CAAC,6DAEvD,CACL;QACDC,WAAW,EAAE,IAAI;QACjBC,OAAO,EAAEC,SAAS;QAClBC,WAAW,EAAE;MACjB,CAAC,CAAC;MACF3B,eAAe,CAAC,CAAC;IACrB,CACJ,CAAC;IAED,OAAO,MAAM;MACTY,YAAY,CAACgB,GAAG,CAAC,CAAC;MAClB;AACZ;AACA;MACY;MACAhB,YAAY,GAAG,IAAI;IACvB,CAAC;EACL,CAAC,EAAE,CAACV,KAAK,CAACQ,EAAE,EAAEV,eAAe,EAAEG,KAAK,CAACe,OAAO,CAAC,CAAC;EAE9C1B,SAAS,CAAC,MAAM;IACZ,IAAI,CAACU,KAAK,CAACQ,EAAE,EAAE;MACX;IACJ;IAEA,IAAID,kBAAkB,CAACoB,OAAO,EAAE;MAC5B;IACJ;IAEA,MAAMC,UAAU,GAAG,MAAAA,CAAA,KAAY;MAC3B,MAAMC,MAAM,GAAG,MAAM1B,eAAe,CAAC;QACjCK,EAAE,EAAER,KAAK,CAACQ,EAAE;QACZO,YAAY,EAAEd,KAAK,CAACe;MACxB,CAAC,CAAC;MACF,IAAIa,MAAM,CAACC,KAAK,EAAE;QACdxB,UAAU,CAAC;UACPW,KAAK,EAAE,mDAAmD;UAC1DC,OAAO,EAAEW,MAAM,CAACC,KAAK,CAACC,OAAO;UAC7BT,WAAW,EAAE,IAAI;UACjBC,OAAO,EAAEC,SAAS;UAClBC,WAAW,EAAE;QACjB,CAAC,CAAC;QACF3B,eAAe,CAAC,CAAC;QACjB;MACJ;MACAkC,aAAa,CAAC,CAAC;IACnB,CAAC;IAED,MAAMA,aAAa,GAAGA,CAAA,KAAM;MACxBzB,kBAAkB,CAACoB,OAAO,GAAGM,MAAM,CAACC,UAAU,CAAC,MAAM;QACjDN,UAAU,CAAC,CAAC;MAChB,CAAC,EAAEhC,iBAAiB,GAAG,IAAI,CAAC;IAChC,CAAC;IAEDgC,UAAU,CAAC,CAAC;IACZ,OAAO,MAAM;MACT,IAAI,CAACrB,kBAAkB,CAACoB,OAAO,EAAE;QAC7B;MACJ;MACAQ,YAAY,CAAC5B,kBAAkB,CAACoB,OAAO,CAAC;MACxCpB,kBAAkB,CAACoB,OAAO,GAAG,IAAI;IACrC,CAAC;EACL,CAAC,EAAE,CAAC3B,KAAK,CAACQ,EAAE,EAAEV,eAAe,CAAC,CAAC;EAE/B,oBAAOT,KAAA,CAAA8B,aAAA,CAAA9B,KAAA,CAAA+B,QAAA,QAAGlB,QAAW,CAAC;AAC1B,CAAC","ignoreList":[]}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { useRouter } from "@webiny/app";
|
|
3
|
-
import { ContentEntryEditorConfig, ContentEntryListConfig } from "@webiny/app-headless-cms";
|
|
4
|
-
import { ContentEntryGuard } from "./ContentEntryGuard.js";
|
|
5
|
-
import { ContentEntryLocker } from "./ContentEntryLocker.js";
|
|
6
|
-
const {
|
|
7
|
-
ContentEntry,
|
|
8
|
-
SingletonContentEntry
|
|
9
|
-
} = ContentEntryEditorConfig;
|
|
10
|
-
const ContentEntryDecorator = ContentEntry.createDecorator(Original => {
|
|
11
|
-
return function RecordLockingContentEntry() {
|
|
12
|
-
const router = useRouter();
|
|
13
|
-
const {
|
|
14
|
-
entry,
|
|
15
|
-
contentModel,
|
|
16
|
-
loading
|
|
17
|
-
} = ContentEntry.useContentEntry();
|
|
18
|
-
const {
|
|
19
|
-
navigateTo
|
|
20
|
-
} = ContentEntryListConfig.ContentEntries.useContentEntriesList();
|
|
21
|
-
/**
|
|
22
|
-
* New entry does not have ID yet.
|
|
23
|
-
*/
|
|
24
|
-
if (!entry?.id) {
|
|
25
|
-
return /*#__PURE__*/React.createElement(Original, null);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Continue with existing entry.
|
|
29
|
-
*/
|
|
30
|
-
const props = {
|
|
31
|
-
entry,
|
|
32
|
-
model: contentModel
|
|
33
|
-
};
|
|
34
|
-
return /*#__PURE__*/React.createElement(ContentEntryGuard, Object.assign({}, props, {
|
|
35
|
-
loading: loading
|
|
36
|
-
}), /*#__PURE__*/React.createElement(ContentEntryLocker, Object.assign({}, props, {
|
|
37
|
-
onDisablePrompt: () => router.unblockTransition(),
|
|
38
|
-
onEntryUnlocked: navigateTo
|
|
39
|
-
}), /*#__PURE__*/React.createElement(Original, null)));
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
const SingletonContentEntryDecorator = SingletonContentEntry.createDecorator(Original => {
|
|
43
|
-
return function RecordLockingSingletonContentEntry() {
|
|
44
|
-
const router = useRouter();
|
|
45
|
-
const {
|
|
46
|
-
entry,
|
|
47
|
-
contentModel,
|
|
48
|
-
loading
|
|
49
|
-
} = SingletonContentEntry.useSingletonContentEntry();
|
|
50
|
-
const props = {
|
|
51
|
-
entry,
|
|
52
|
-
model: contentModel
|
|
53
|
-
};
|
|
54
|
-
return /*#__PURE__*/React.createElement(ContentEntryGuard, Object.assign({}, props, {
|
|
55
|
-
loading: loading
|
|
56
|
-
}), /*#__PURE__*/React.createElement(ContentEntryLocker, Object.assign({}, props, {
|
|
57
|
-
onDisablePrompt: () => router.unblockTransition(),
|
|
58
|
-
onEntryUnlocked: () => {
|
|
59
|
-
// There's nowhere to go, since singleton entry doesn't have a list view.
|
|
60
|
-
}
|
|
61
|
-
}), /*#__PURE__*/React.createElement(Original, null)));
|
|
62
|
-
};
|
|
63
|
-
});
|
|
64
|
-
export const HeadlessCmsContentEntry = () => {
|
|
65
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ContentEntryDecorator, null), /*#__PURE__*/React.createElement(SingletonContentEntryDecorator, null));
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
//# sourceMappingURL=HeadlessCmsContentEntry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","useRouter","ContentEntryEditorConfig","ContentEntryListConfig","ContentEntryGuard","ContentEntryLocker","ContentEntry","SingletonContentEntry","ContentEntryDecorator","createDecorator","Original","RecordLockingContentEntry","router","entry","contentModel","loading","useContentEntry","navigateTo","ContentEntries","useContentEntriesList","id","createElement","props","model","Object","assign","onDisablePrompt","unblockTransition","onEntryUnlocked","SingletonContentEntryDecorator","RecordLockingSingletonContentEntry","useSingletonContentEntry","HeadlessCmsContentEntry","Fragment"],"sources":["HeadlessCmsContentEntry.tsx"],"sourcesContent":["import React from \"react\";\nimport { useRouter } from \"@webiny/app\";\nimport { ContentEntryEditorConfig, ContentEntryListConfig } from \"@webiny/app-headless-cms\";\nimport { ContentEntryGuard } from \"./ContentEntryGuard.js\";\nimport { ContentEntryLocker } from \"./ContentEntryLocker.js\";\n\nconst { ContentEntry, SingletonContentEntry } = ContentEntryEditorConfig;\n\nconst ContentEntryDecorator = ContentEntry.createDecorator(Original => {\n return function RecordLockingContentEntry() {\n const router = useRouter();\n const { entry, contentModel, loading } = ContentEntry.useContentEntry();\n const { navigateTo } = ContentEntryListConfig.ContentEntries.useContentEntriesList();\n /**\n * New entry does not have ID yet.\n */\n if (!entry?.id) {\n return <Original />;\n }\n /**\n * Continue with existing entry.\n */\n const props = { entry, model: contentModel };\n\n return (\n <ContentEntryGuard {...props} loading={loading}>\n <ContentEntryLocker\n {...props}\n onDisablePrompt={() => router.unblockTransition()}\n onEntryUnlocked={navigateTo}\n >\n <Original />\n </ContentEntryLocker>\n </ContentEntryGuard>\n );\n };\n});\n\nconst SingletonContentEntryDecorator = SingletonContentEntry.createDecorator(Original => {\n return function RecordLockingSingletonContentEntry() {\n const router = useRouter();\n const { entry, contentModel, loading } = SingletonContentEntry.useSingletonContentEntry();\n\n const props = { entry, model: contentModel };\n\n return (\n <ContentEntryGuard {...props} loading={loading}>\n <ContentEntryLocker\n {...props}\n onDisablePrompt={() => router.unblockTransition()}\n onEntryUnlocked={() => {\n // There's nowhere to go, since singleton entry doesn't have a list view.\n }}\n >\n <Original />\n </ContentEntryLocker>\n </ContentEntryGuard>\n );\n };\n});\n\nexport const HeadlessCmsContentEntry = () => {\n return (\n <>\n <ContentEntryDecorator />\n <SingletonContentEntryDecorator />\n </>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,SAAS,QAAQ,aAAa;AACvC,SAASC,wBAAwB,EAAEC,sBAAsB,QAAQ,0BAA0B;AAC3F,SAASC,iBAAiB;AAC1B,SAASC,kBAAkB;AAE3B,MAAM;EAAEC,YAAY;EAAEC;AAAsB,CAAC,GAAGL,wBAAwB;AAExE,MAAMM,qBAAqB,GAAGF,YAAY,CAACG,eAAe,CAACC,QAAQ,IAAI;EACnE,OAAO,SAASC,yBAAyBA,CAAA,EAAG;IACxC,MAAMC,MAAM,GAAGX,SAAS,CAAC,CAAC;IAC1B,MAAM;MAAEY,KAAK;MAAEC,YAAY;MAAEC;IAAQ,CAAC,GAAGT,YAAY,CAACU,eAAe,CAAC,CAAC;IACvE,MAAM;MAAEC;IAAW,CAAC,GAAGd,sBAAsB,CAACe,cAAc,CAACC,qBAAqB,CAAC,CAAC;IACpF;AACR;AACA;IACQ,IAAI,CAACN,KAAK,EAAEO,EAAE,EAAE;MACZ,oBAAOpB,KAAA,CAAAqB,aAAA,CAACX,QAAQ,MAAE,CAAC;IACvB;IACA;AACR;AACA;IACQ,MAAMY,KAAK,GAAG;MAAET,KAAK;MAAEU,KAAK,EAAET;IAAa,CAAC;IAE5C,oBACId,KAAA,CAAAqB,aAAA,CAACjB,iBAAiB,EAAAoB,MAAA,CAAAC,MAAA,KAAKH,KAAK;MAAEP,OAAO,EAAEA;IAAQ,iBAC3Cf,KAAA,CAAAqB,aAAA,CAAChB,kBAAkB,EAAAmB,MAAA,CAAAC,MAAA,KACXH,KAAK;MACTI,eAAe,EAAEA,CAAA,KAAMd,MAAM,CAACe,iBAAiB,CAAC,CAAE;MAClDC,eAAe,EAAEX;IAAW,iBAE5BjB,KAAA,CAAAqB,aAAA,CAACX,QAAQ,MAAE,CACK,CACL,CAAC;EAE5B,CAAC;AACL,CAAC,CAAC;AAEF,MAAMmB,8BAA8B,GAAGtB,qBAAqB,CAACE,eAAe,CAACC,QAAQ,IAAI;EACrF,OAAO,SAASoB,kCAAkCA,CAAA,EAAG;IACjD,MAAMlB,MAAM,GAAGX,SAAS,CAAC,CAAC;IAC1B,MAAM;MAAEY,KAAK;MAAEC,YAAY;MAAEC;IAAQ,CAAC,GAAGR,qBAAqB,CAACwB,wBAAwB,CAAC,CAAC;IAEzF,MAAMT,KAAK,GAAG;MAAET,KAAK;MAAEU,KAAK,EAAET;IAAa,CAAC;IAE5C,oBACId,KAAA,CAAAqB,aAAA,CAACjB,iBAAiB,EAAAoB,MAAA,CAAAC,MAAA,KAAKH,KAAK;MAAEP,OAAO,EAAEA;IAAQ,iBAC3Cf,KAAA,CAAAqB,aAAA,CAAChB,kBAAkB,EAAAmB,MAAA,CAAAC,MAAA,KACXH,KAAK;MACTI,eAAe,EAAEA,CAAA,KAAMd,MAAM,CAACe,iBAAiB,CAAC,CAAE;MAClDC,eAAe,EAAEA,CAAA,KAAM;QACnB;MAAA;IACF,iBAEF5B,KAAA,CAAAqB,aAAA,CAACX,QAAQ,MAAE,CACK,CACL,CAAC;EAE5B,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,MAAMsB,uBAAuB,GAAGA,CAAA,KAAM;EACzC,oBACIhC,KAAA,CAAAqB,aAAA,CAAArB,KAAA,CAAAiC,QAAA,qBACIjC,KAAA,CAAAqB,aAAA,CAACb,qBAAqB,MAAE,CAAC,eACzBR,KAAA,CAAAqB,aAAA,CAACQ,8BAA8B,MAAE,CACnC,CAAC;AAEX,CAAC","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./HeadlessCmsContentEntry.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./HeadlessCmsContentEntry.js\";\n"],"mappings":"AAAA","ignoreList":[]}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { IRecordLockingLockRecord } from "../../types.js";
|
|
3
|
-
export interface ILockedRecordProps {
|
|
4
|
-
record: IRecordLockingLockRecord;
|
|
5
|
-
}
|
|
6
|
-
export declare const LockedRecord: ({ record: lockRecordEntry }: ILockedRecordProps) => React.JSX.Element;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { ReactComponent as LockIcon } from "@webiny/icons/lock.svg";
|
|
3
|
-
import { Grid, Heading, Icon, Text } from "@webiny/admin-ui";
|
|
4
|
-
import { useRecordLocking } from "../../hooks/index.js";
|
|
5
|
-
import { useContentEntry } from "@webiny/app-headless-cms";
|
|
6
|
-
import { LockedRecordForceUnlock } from "./LockedRecordForceUnlock.js";
|
|
7
|
-
const Wrapper = ({
|
|
8
|
-
children
|
|
9
|
-
}) => {
|
|
10
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
11
|
-
className: "w-5/12 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50"
|
|
12
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
13
|
-
className: "flex p-lg border-sm border-neutral-dimmed-darker rounded-3xl bg-neutral-base"
|
|
14
|
-
}, /*#__PURE__*/React.createElement(Grid, null, /*#__PURE__*/React.createElement(Grid.Column, {
|
|
15
|
-
span: 3
|
|
16
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
17
|
-
className: "h-full flex items-center justify-center bg-neutral-dimmed rounded-md p-lg"
|
|
18
|
-
}, /*#__PURE__*/React.createElement(Icon, {
|
|
19
|
-
style: {
|
|
20
|
-
width: "64px",
|
|
21
|
-
height: "64px"
|
|
22
|
-
},
|
|
23
|
-
icon: /*#__PURE__*/React.createElement(LockIcon, null),
|
|
24
|
-
label: "Locked Record",
|
|
25
|
-
color: "accent",
|
|
26
|
-
size: "lg"
|
|
27
|
-
}))), /*#__PURE__*/React.createElement(Grid.Column, {
|
|
28
|
-
span: 9
|
|
29
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
30
|
-
className: "flex flex-col justify-center"
|
|
31
|
-
}, children))))));
|
|
32
|
-
};
|
|
33
|
-
const Title = () => {
|
|
34
|
-
const {
|
|
35
|
-
entry
|
|
36
|
-
} = useContentEntry();
|
|
37
|
-
return /*#__PURE__*/React.createElement(Heading, {
|
|
38
|
-
level: 4,
|
|
39
|
-
className: "mb-sm"
|
|
40
|
-
}, "Record (", entry.meta.title, ") is locked!");
|
|
41
|
-
};
|
|
42
|
-
export const LockedRecord = ({
|
|
43
|
-
record: lockRecordEntry
|
|
44
|
-
}) => {
|
|
45
|
-
const {
|
|
46
|
-
getLockRecordEntry
|
|
47
|
-
} = useRecordLocking();
|
|
48
|
-
const record = getLockRecordEntry(lockRecordEntry.id);
|
|
49
|
-
if (!record) {
|
|
50
|
-
return /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(Text, null, "Could not find the lock record. Please refresh the Admin UI."));
|
|
51
|
-
} else if (!lockRecordEntry?.lockedBy) {
|
|
52
|
-
return /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(Title, null), /*#__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(LockedRecordForceUnlock, {
|
|
53
|
-
id: lockRecordEntry.id,
|
|
54
|
-
type: record.$lockingType,
|
|
55
|
-
title: record.meta?.title
|
|
56
|
-
}));
|
|
57
|
-
}
|
|
58
|
-
return /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(Title, null), /*#__PURE__*/React.createElement(Text, null, "It is locked because ", /*#__PURE__*/React.createElement("strong", null, lockRecordEntry.lockedBy.displayName), " 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(LockedRecordForceUnlock, {
|
|
59
|
-
id: lockRecordEntry.id,
|
|
60
|
-
type: record.$lockingType,
|
|
61
|
-
lockedBy: lockRecordEntry.lockedBy,
|
|
62
|
-
title: record.meta?.title
|
|
63
|
-
}));
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
//# sourceMappingURL=LockedRecord.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","ReactComponent","LockIcon","Grid","Heading","Icon","Text","useRecordLocking","useContentEntry","LockedRecordForceUnlock","Wrapper","children","createElement","Fragment","className","Column","span","style","width","height","icon","label","color","size","Title","entry","level","meta","title","LockedRecord","record","lockRecordEntry","getLockRecordEntry","id","lockedBy","type","$lockingType","displayName"],"sources":["LockedRecord.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 { useRecordLocking } from \"~/hooks/index.js\";\nimport { useContentEntry } from \"@webiny/app-headless-cms\";\nimport { LockedRecordForceUnlock } from \"./LockedRecordForceUnlock.js\";\nimport type { IRecordLockingLockRecord } from \"~/types.js\";\n\ninterface IWrapperProps {\n children: React.ReactNode;\n}\n\nconst Wrapper = ({ children }: IWrapperProps) => {\n return (\n <>\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={{\n width: \"64px\",\n height: \"64px\"\n }}\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 {/*<div className=\"absolute inset-0 bg-neutral-dark/50 z-45\"></div>*/}\n </>\n );\n};\n\nconst Title = () => {\n const { entry } = useContentEntry();\n return (\n <Heading level={4} className={\"mb-sm\"}>\n Record ({entry.meta.title}) is locked!\n </Heading>\n );\n};\n\nexport interface ILockedRecordProps {\n record: IRecordLockingLockRecord;\n}\n\nexport const LockedRecord = ({ record: lockRecordEntry }: ILockedRecordProps) => {\n const { getLockRecordEntry } = useRecordLocking();\n\n const record = getLockRecordEntry(lockRecordEntry.id);\n\n if (!record) {\n return (\n <Wrapper>\n <Text>Could not find the lock record. Please refresh the Admin UI.</Text>\n </Wrapper>\n );\n } else if (!lockRecordEntry?.lockedBy) {\n return (\n <Wrapper>\n <Title />\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 <LockedRecordForceUnlock\n id={lockRecordEntry.id}\n type={record.$lockingType}\n title={record.meta?.title}\n />\n </Wrapper>\n );\n }\n return (\n <Wrapper>\n <Title />\n <Text>\n It is locked because <strong>{lockRecordEntry.lockedBy.displayName}</strong> is\n currently editing this record. You can either contact the user and ask them to\n unlock the record, or you can wait for the lock to expire.\n </Text>\n <LockedRecordForceUnlock\n id={lockRecordEntry.id}\n type={record.$lockingType}\n lockedBy={lockRecordEntry.lockedBy}\n title={record.meta?.title}\n />\n </Wrapper>\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { IRecordLockingIdentity } from "../../types.js";
|
|
3
|
-
export interface ILockedRecordForceUnlockProps {
|
|
4
|
-
id: string;
|
|
5
|
-
type: string;
|
|
6
|
-
title: string;
|
|
7
|
-
lockedBy?: IRecordLockingIdentity;
|
|
8
|
-
}
|
|
9
|
-
export declare const LockedRecordForceUnlock: (props: ILockedRecordForceUnlockProps) => React.JSX.Element | null;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useState } from "react";
|
|
2
|
-
import { Alert, Button, Text } from "@webiny/admin-ui";
|
|
3
|
-
import { useConfirmationDialog, useSnackbar } from "@webiny/app-admin";
|
|
4
|
-
import { useContentEntriesList } from "@webiny/app-headless-cms";
|
|
5
|
-
import { useRecordLocking, usePermission } from "../../hooks/index.js";
|
|
6
|
-
const ErrorMessage = props => {
|
|
7
|
-
const {
|
|
8
|
-
title,
|
|
9
|
-
lockedBy
|
|
10
|
-
} = props;
|
|
11
|
-
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Alert, {
|
|
12
|
-
type: "warning",
|
|
13
|
-
title: "Warning",
|
|
14
|
-
className: "mb-md"
|
|
15
|
-
}, /*#__PURE__*/React.createElement("strong", null, lockedBy?.displayName || "Unknown user"), " is currently editing this record.", /*#__PURE__*/React.createElement("br", null), " If you force unlock it, they could potentially lose their changes."), /*#__PURE__*/React.createElement(Text, null, "You are about to forcefully unlock the ", /*#__PURE__*/React.createElement("strong", null, title), " entry. Are you sure you want to continue?"));
|
|
16
|
-
};
|
|
17
|
-
export const LockedRecordForceUnlock = props => {
|
|
18
|
-
const {
|
|
19
|
-
unlockEntryForce
|
|
20
|
-
} = useRecordLocking();
|
|
21
|
-
const {
|
|
22
|
-
navigateTo
|
|
23
|
-
} = useContentEntriesList();
|
|
24
|
-
const {
|
|
25
|
-
showConfirmation: showForceUnlockConfirmation
|
|
26
|
-
} = useConfirmationDialog({
|
|
27
|
-
title: "Force unlock the entry",
|
|
28
|
-
message: /*#__PURE__*/React.createElement(ErrorMessage, props)
|
|
29
|
-
});
|
|
30
|
-
const {
|
|
31
|
-
showSnackbar
|
|
32
|
-
} = useSnackbar();
|
|
33
|
-
const [error, setError] = useState();
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (!error?.message) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
console.error(error);
|
|
39
|
-
showSnackbar(error.message);
|
|
40
|
-
}, [error?.message]);
|
|
41
|
-
const onClick = useCallback(() => {
|
|
42
|
-
showForceUnlockConfirmation(async () => {
|
|
43
|
-
const result = await unlockEntryForce({
|
|
44
|
-
id: props.id,
|
|
45
|
-
$lockingType: props.type
|
|
46
|
-
});
|
|
47
|
-
if (!result.error) {
|
|
48
|
-
navigateTo();
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
setError(result.error);
|
|
52
|
-
});
|
|
53
|
-
}, [props.id, navigateTo]);
|
|
54
|
-
const {
|
|
55
|
-
canForceUnlock
|
|
56
|
-
} = usePermission();
|
|
57
|
-
if (!canForceUnlock) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
61
|
-
className: "mt-md"
|
|
62
|
-
}, /*#__PURE__*/React.createElement(Text, {
|
|
63
|
-
as: "div",
|
|
64
|
-
className: "mb-md"
|
|
65
|
-
}, "Because you have a full access to the system, you can force unlock the record."), /*#__PURE__*/React.createElement(Button, {
|
|
66
|
-
onClick: onClick,
|
|
67
|
-
text: "Unlock and go back"
|
|
68
|
-
}));
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
//# sourceMappingURL=LockedRecordForceUnlock.js.map
|