@webiny/app-record-locking 0.0.0-unstable.e53eceafb5 → 0.0.0-unstable.eb196ccd2f
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/components/LockedRecord/LockedRecord.js +2 -2
- package/components/LockedRecord/LockedRecord.js.map +1 -1
- package/components/RecordLockingProvider.js +13 -3
- package/components/RecordLockingProvider.js.map +1 -1
- package/components/decorators/UseContentEntriesListHookDecorator.js.map +1 -1
- package/package.json +17 -17
- package/types.d.ts +2 -4
- package/types.js.map +1 -1
|
@@ -52,14 +52,14 @@ export const LockedRecord = ({
|
|
|
52
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
53
|
id: lockRecordEntry.id,
|
|
54
54
|
type: record.$lockingType,
|
|
55
|
-
title: record.meta.title
|
|
55
|
+
title: record.data.meta.title
|
|
56
56
|
}));
|
|
57
57
|
}
|
|
58
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
59
|
id: lockRecordEntry.id,
|
|
60
60
|
type: record.$lockingType,
|
|
61
61
|
lockedBy: lockRecordEntry.lockedBy,
|
|
62
|
-
title: record.meta.title
|
|
62
|
+
title: record.data.meta.title
|
|
63
63
|
}));
|
|
64
64
|
};
|
|
65
65
|
|
|
@@ -1 +1 @@
|
|
|
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\";\nimport { useContentEntry } from \"@webiny/app-headless-cms\";\nimport { LockedRecordForceUnlock } from \"./LockedRecordForceUnlock\";\nimport type { IRecordLockingLockRecord } from \"~/types\";\n\ninterface IWrapperProps {\n children: React.ReactNode;\n}\n\nconst Wrapper = ({ children }: IWrapperProps) => {\n return (\n <>\n <div className=\"wby-w-5/12 wby-absolute wby-top-1/2 wby-left-1/2 wby--translate-x-1/2 wby--translate-y-1/2 wby-z-50\">\n <div\n className={\n \"wby-flex wby-p-lg wby-border-sm wby-border-neutral-dimmed-darker wby-rounded-3xl wby-bg-neutral-base\"\n }\n >\n <Grid>\n <Grid.Column span={3}>\n <div className=\"wby-h-full wby-flex wby-items-center wby-justify-center wby-bg-neutral-dimmed wby-rounded-md wby-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={\"wby-flex wby-flex-col wby-justify-center\"}>\n {children}\n </div>\n </Grid.Column>\n </Grid>\n </div>\n </div>\n {/*<div className=\"wby-absolute wby-inset-0 wby-bg-neutral-dark/50 wby-z-45\"></div>*/}\n </>\n );\n};\n\nconst Title = () => {\n const { entry } = useContentEntry();\n return (\n <Heading level={4} className={\"wby-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":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,cAAc,IAAIC,QAAQ,QAAQ,wBAAwB;AACnE,SAASC,IAAI,EAAEC,OAAO,EAAEC,IAAI,EAAEC,IAAI,QAAQ,kBAAkB;AAC5D,SAASC,gBAAgB;AACzB,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,uBAAuB;AAOhC,MAAMC,OAAO,GAAGA,CAAC;EAAEC;AAAwB,CAAC,KAAK;EAC7C,oBACIX,KAAA,CAAAY,aAAA,CAAAZ,KAAA,CAAAa,QAAA,qBACIb,KAAA,CAAAY,aAAA;IAAKE,SAAS,EAAC;EAAqG,gBAChHd,KAAA,CAAAY,aAAA;IACIE,SAAS,EACL;EACH,gBAEDd,KAAA,CAAAY,aAAA,CAACT,IAAI,qBACDH,KAAA,CAAAY,aAAA,CAACT,IAAI,CAACY,MAAM;IAACC,IAAI,EAAE;EAAE,gBACjBhB,KAAA,CAAAY,aAAA;IAAKE,SAAS,EAAC;EAAuG,gBAClHd,KAAA,CAAAY,aAAA,CAACP,IAAI;IACDY,KAAK,EAAE;MACHC,KAAK,EAAE,MAAM;MACbC,MAAM,EAAE;IACZ,CAAE;IACFC,IAAI,eAAEpB,KAAA,CAAAY,aAAA,CAACV,QAAQ,MAAE,CAAE;IACnBmB,KAAK,EAAE,eAAgB;IACvBC,KAAK,EAAE,QAAS;IAChBC,IAAI,EAAE;EAAK,CACd,CACA,CACI,CAAC,eACdvB,KAAA,CAAAY,aAAA,CAACT,IAAI,CAACY,MAAM;IAACC,IAAI,EAAE;EAAE,gBACjBhB,KAAA,CAAAY,aAAA;IAAKE,SAAS,EAAE;EAA2C,GACtDH,QACA,CACI,CACX,CACL,CACJ,CAEP,CAAC;AAEX,CAAC;AAED,MAAMa,KAAK,GAAGA,CAAA,KAAM;EAChB,MAAM;IAAEC;EAAM,CAAC,GAAGjB,eAAe,CAAC,CAAC;EACnC,oBACIR,KAAA,CAAAY,aAAA,CAACR,OAAO;IAACsB,KAAK,EAAE,CAAE;IAACZ,SAAS,EAAE;EAAY,GAAC,UAC/B,EAACW,KAAK,CAACE,IAAI,CAACC,KAAK,EAAC,cACrB,CAAC;AAElB,CAAC;AAMD,OAAO,MAAMC,YAAY,GAAGA,CAAC;EAAEC,MAAM,EAAEC;AAAoC,CAAC,KAAK;EAC7E,MAAM;IAAEC;EAAmB,CAAC,GAAGzB,gBAAgB,CAAC,CAAC;EAEjD,MAAMuB,MAAM,GAAGE,kBAAkB,CAACD,eAAe,CAACE,EAAE,CAAC;EAErD,IAAI,CAACH,MAAM,EAAE;IACT,oBACI9B,KAAA,CAAAY,aAAA,CAACF,OAAO,qBACJV,KAAA,CAAAY,aAAA,CAACN,IAAI,QAAC,8DAAkE,CACnE,CAAC;EAElB,CAAC,MAAM,IAAI,CAACyB,eAAe,EAAEG,QAAQ,EAAE;IACnC,oBACIlC,KAAA,CAAAY,aAAA,CAACF,OAAO,qBACJV,KAAA,CAAAY,aAAA,CAACY,KAAK,MAAE,CAAC,eACTxB,KAAA,CAAAY,aAAA,CAACN,IAAI,QAAC,qKAIA,CAAC,eACPN,KAAA,CAAAY,aAAA,CAACH,uBAAuB;MACpBwB,EAAE,EAAEF,eAAe,CAACE,EAAG;MACvBE,IAAI,EAAEL,MAAM,CAACM,YAAa;MAC1BR,KAAK,EAAEE,MAAM,
|
|
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","data","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\";\nimport { useContentEntry } from \"@webiny/app-headless-cms\";\nimport { LockedRecordForceUnlock } from \"./LockedRecordForceUnlock\";\nimport type { IRecordLockingLockRecord } from \"~/types\";\n\ninterface IWrapperProps {\n children: React.ReactNode;\n}\n\nconst Wrapper = ({ children }: IWrapperProps) => {\n return (\n <>\n <div className=\"wby-w-5/12 wby-absolute wby-top-1/2 wby-left-1/2 wby--translate-x-1/2 wby--translate-y-1/2 wby-z-50\">\n <div\n className={\n \"wby-flex wby-p-lg wby-border-sm wby-border-neutral-dimmed-darker wby-rounded-3xl wby-bg-neutral-base\"\n }\n >\n <Grid>\n <Grid.Column span={3}>\n <div className=\"wby-h-full wby-flex wby-items-center wby-justify-center wby-bg-neutral-dimmed wby-rounded-md wby-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={\"wby-flex wby-flex-col wby-justify-center\"}>\n {children}\n </div>\n </Grid.Column>\n </Grid>\n </div>\n </div>\n {/*<div className=\"wby-absolute wby-inset-0 wby-bg-neutral-dark/50 wby-z-45\"></div>*/}\n </>\n );\n};\n\nconst Title = () => {\n const { entry } = useContentEntry();\n return (\n <Heading level={4} className={\"wby-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.data.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.data.meta.title}\n />\n </Wrapper>\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -7,10 +7,20 @@ const isSameArray = (existingRecords, newRecords) => {
|
|
|
7
7
|
if (existingRecords.length !== newRecords.length) {
|
|
8
8
|
return false;
|
|
9
9
|
}
|
|
10
|
-
return existingRecords.every(record => {
|
|
11
|
-
|
|
10
|
+
return existingRecords.every((record, index) => {
|
|
11
|
+
const newRecord = newRecords[index];
|
|
12
|
+
if (!newRecord) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return newRecord.id === record.id && newRecord.savedOn === record.savedOn;
|
|
12
16
|
});
|
|
13
17
|
};
|
|
18
|
+
const getData = records => {
|
|
19
|
+
return records.map(record => ({
|
|
20
|
+
id: record.id,
|
|
21
|
+
savedOn: record.savedOn
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
14
24
|
export const RecordLockingProvider = props => {
|
|
15
25
|
const client = useApolloClient();
|
|
16
26
|
const [loading, setLoading] = useState(false);
|
|
@@ -23,7 +33,7 @@ export const RecordLockingProvider = props => {
|
|
|
23
33
|
const [error, setError] = useStateIfMounted(null);
|
|
24
34
|
const [records, setRecords] = useStateIfMounted([]);
|
|
25
35
|
const setRecordsIfNeeded = useCallback(newRecords => {
|
|
26
|
-
const sameArray = isSameArray(records, newRecords);
|
|
36
|
+
const sameArray = isSameArray(getData(records), getData(newRecords));
|
|
27
37
|
if (sameArray) {
|
|
28
38
|
return;
|
|
29
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useMemo","useState","useApolloClient","createRecordLocking","useStateIfMounted","RecordLockingContext","createContext","isSameArray","existingRecords","newRecords","length","every","record","
|
|
1
|
+
{"version":3,"names":["React","useCallback","useMemo","useState","useApolloClient","createRecordLocking","useStateIfMounted","RecordLockingContext","createContext","isSameArray","existingRecords","newRecords","length","every","record","index","newRecord","id","savedOn","getData","records","map","RecordLockingProvider","props","client","loading","setLoading","recordLocking","error","setError","setRecords","setRecordsIfNeeded","sameArray","value","updateEntryLock","params","result","target","data","message","code","prev","item","entryId","$locked","unlockEntry","unlockEntryForce","isLockExpired","input","isRecordLocked","getLockRecordEntry","removeEntryLock","fetchLockRecord","ex","fetchLockedEntryLockRecord","folderId","type","createElement","Provider","Object","assign"],"sources":["RecordLockingProvider.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from \"react\";\nimport { useApolloClient } from \"@apollo/react-hooks\";\nimport { createRecordLocking } from \"~/domain/RecordLocking\";\nimport type {\n IFetchLockedEntryLockRecordParams,\n IFetchLockRecordParams,\n IPossiblyRecordLockingRecord,\n IRecordLockingContext,\n IRecordLockingError,\n IUnlockEntryParams,\n IUpdateEntryLockParams\n} from \"~/types\";\nimport { useStateIfMounted } from \"@webiny/app-admin\";\n\nexport interface IRecordLockingProviderProps {\n children: React.ReactNode;\n}\n\nexport const RecordLockingContext = React.createContext({} as unknown as IRecordLockingContext);\n\nconst isSameArray = (\n existingRecords: Pick<IPossiblyRecordLockingRecord[\"data\"], \"id\" | \"savedOn\">[],\n newRecords: Pick<IPossiblyRecordLockingRecord[\"data\"], \"id\" | \"savedOn\">[]\n): boolean => {\n if (existingRecords.length !== newRecords.length) {\n return false;\n }\n return existingRecords.every((record, index) => {\n const newRecord = newRecords[index];\n if (!newRecord) {\n return false;\n }\n\n return newRecord.id === record.id && newRecord.savedOn === record.savedOn;\n });\n};\n\nconst getData = (records: IPossiblyRecordLockingRecord[]) => {\n return records.map(record => ({\n id: record.id,\n savedOn: record.savedOn\n }));\n};\n\nexport const RecordLockingProvider = (props: IRecordLockingProviderProps) => {\n const client = useApolloClient();\n\n const [loading, setLoading] = useState(false);\n\n const recordLocking = useMemo(() => {\n return createRecordLocking({\n client,\n setLoading\n });\n }, []);\n\n const [error, setError] = useStateIfMounted<IRecordLockingError | null>(null);\n\n const [records, setRecords] = useStateIfMounted<IPossiblyRecordLockingRecord[]>([]);\n\n const setRecordsIfNeeded = useCallback(\n (newRecords: IPossiblyRecordLockingRecord[]) => {\n const sameArray = isSameArray(getData(records), getData(newRecords));\n if (sameArray) {\n return;\n }\n setRecords(newRecords);\n },\n [records]\n );\n\n const value: IRecordLockingContext = {\n async updateEntryLock(params: IUpdateEntryLockParams) {\n const result = await recordLocking.updateEntryLock(params);\n if (result.error) {\n setError(result.error);\n return result;\n }\n const target = result.data;\n if (!target?.id) {\n const error = {\n message: \"No data returned from server.\",\n code: \"NO_DATA\"\n };\n setError(error);\n return {\n error,\n data: null\n };\n }\n\n setRecords(prev => {\n return prev.map(item => {\n if (item.entryId === target.id) {\n return {\n ...item,\n $locked: result.data\n };\n }\n return item;\n });\n });\n return result;\n },\n async unlockEntry(params: IUnlockEntryParams) {\n return await recordLocking.unlockEntry(params);\n },\n async unlockEntryForce(params: IUnlockEntryParams) {\n return await recordLocking.unlockEntry(params, true);\n },\n isLockExpired(input: Date | string): boolean {\n return recordLocking.isLockExpired(input);\n },\n isRecordLocked(record) {\n if (!record) {\n return false;\n }\n return recordLocking.isRecordLocked(record);\n },\n getLockRecordEntry(id: string) {\n return recordLocking.getLockRecordEntry(id);\n },\n removeEntryLock(params: IUnlockEntryParams) {\n return recordLocking.removeEntryLock(params);\n },\n async fetchLockRecord(params: IFetchLockRecordParams) {\n try {\n return await recordLocking.fetchLockRecord(params);\n } catch (ex) {\n return {\n data: null,\n error: ex\n };\n }\n },\n async fetchLockedEntryLockRecord(params: IFetchLockedEntryLockRecordParams) {\n return recordLocking.fetchLockedEntryLockRecord(params);\n },\n async setRecords(folderId, type, newRecords) {\n setRecordsIfNeeded(newRecords);\n\n const result = await recordLocking.setRecords(folderId, type, newRecords);\n if (!result) {\n return;\n }\n setRecords(result);\n },\n error,\n records,\n loading\n };\n\n return <RecordLockingContext.Provider {...props} value={value} />;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","ContentEntryListConfig","useRecordLocking","UseContentEntriesListHookDecorator","ContentEntries","useContentEntriesList","createDecorator","originalHook","RecordLockingUseContentEntriesList","value","recordLocking","records","setRecords","folderId","modelId"],"sources":["UseContentEntriesListHookDecorator.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { ContentEntryListConfig } from \"@webiny/app-headless-cms\";\nimport { useRecordLocking } from \"~/hooks\";\n\nexport const UseContentEntriesListHookDecorator =\n ContentEntryListConfig.ContentEntries.useContentEntriesList.createDecorator(originalHook => {\n return function RecordLockingUseContentEntriesList() {\n const value = originalHook();\n const recordLocking = useRecordLocking();\n\n useEffect(() => {\n if (!value.records) {\n return;\n }\n
|
|
1
|
+
{"version":3,"names":["useEffect","ContentEntryListConfig","useRecordLocking","UseContentEntriesListHookDecorator","ContentEntries","useContentEntriesList","createDecorator","originalHook","RecordLockingUseContentEntriesList","value","recordLocking","records","setRecords","folderId","modelId"],"sources":["UseContentEntriesListHookDecorator.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { ContentEntryListConfig } from \"@webiny/app-headless-cms\";\nimport { useRecordLocking } from \"~/hooks\";\n\nexport const UseContentEntriesListHookDecorator =\n ContentEntryListConfig.ContentEntries.useContentEntriesList.createDecorator(originalHook => {\n return function RecordLockingUseContentEntriesList() {\n const value = originalHook();\n const recordLocking = useRecordLocking();\n\n useEffect(() => {\n if (!value.records) {\n return;\n }\n recordLocking.setRecords(value.folderId, value.modelId, value.records);\n }, [value.folderId, value.modelId, value.records, recordLocking]);\n\n return {\n ...value,\n records: recordLocking.records\n };\n };\n });\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SAASC,sBAAsB,QAAQ,0BAA0B;AACjE,SAASC,gBAAgB;AAEzB,OAAO,MAAMC,kCAAkC,GAC3CF,sBAAsB,CAACG,cAAc,CAACC,qBAAqB,CAACC,eAAe,CAACC,YAAY,IAAI;EACxF,OAAO,SAASC,kCAAkCA,CAAA,EAAG;IACjD,MAAMC,KAAK,GAAGF,YAAY,CAAC,CAAC;IAC5B,MAAMG,aAAa,GAAGR,gBAAgB,CAAC,CAAC;IAExCF,SAAS,CAAC,MAAM;MACZ,IAAI,CAACS,KAAK,CAACE,OAAO,EAAE;QAChB;MACJ;MACAD,aAAa,CAACE,UAAU,CAACH,KAAK,CAACI,QAAQ,EAAEJ,KAAK,CAACK,OAAO,EAAEL,KAAK,CAACE,OAAO,CAAC;IAC1E,CAAC,EAAE,CAACF,KAAK,CAACI,QAAQ,EAAEJ,KAAK,CAACK,OAAO,EAAEL,KAAK,CAACE,OAAO,EAAED,aAAa,CAAC,CAAC;IAEjE,OAAO;MACH,GAAGD,KAAK;MACRE,OAAO,EAAED,aAAa,CAACC;IAC3B,CAAC;EACL,CAAC;AACL,CAAC,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/app-record-locking",
|
|
3
|
-
"version": "0.0.0-unstable.
|
|
3
|
+
"version": "0.0.0-unstable.eb196ccd2f",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,20 +14,20 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@apollo/react-hooks": "3.1.5",
|
|
17
|
-
"@webiny/admin-ui": "0.0.0-unstable.
|
|
18
|
-
"@webiny/app": "0.0.0-unstable.
|
|
19
|
-
"@webiny/app-aco": "0.0.0-unstable.
|
|
20
|
-
"@webiny/app-admin": "0.0.0-unstable.
|
|
21
|
-
"@webiny/app-headless-cms": "0.0.0-unstable.
|
|
22
|
-
"@webiny/app-security": "0.0.0-unstable.
|
|
23
|
-
"@webiny/app-wcp": "0.0.0-unstable.
|
|
24
|
-
"@webiny/app-websockets": "0.0.0-unstable.
|
|
25
|
-
"@webiny/error": "0.0.0-unstable.
|
|
26
|
-
"@webiny/form": "0.0.0-unstable.
|
|
27
|
-
"@webiny/icons": "0.0.0-unstable.
|
|
28
|
-
"@webiny/plugins": "0.0.0-unstable.
|
|
29
|
-
"@webiny/react-router": "0.0.0-unstable.
|
|
30
|
-
"@webiny/utils": "0.0.0-unstable.
|
|
17
|
+
"@webiny/admin-ui": "0.0.0-unstable.eb196ccd2f",
|
|
18
|
+
"@webiny/app": "0.0.0-unstable.eb196ccd2f",
|
|
19
|
+
"@webiny/app-aco": "0.0.0-unstable.eb196ccd2f",
|
|
20
|
+
"@webiny/app-admin": "0.0.0-unstable.eb196ccd2f",
|
|
21
|
+
"@webiny/app-headless-cms": "0.0.0-unstable.eb196ccd2f",
|
|
22
|
+
"@webiny/app-security": "0.0.0-unstable.eb196ccd2f",
|
|
23
|
+
"@webiny/app-wcp": "0.0.0-unstable.eb196ccd2f",
|
|
24
|
+
"@webiny/app-websockets": "0.0.0-unstable.eb196ccd2f",
|
|
25
|
+
"@webiny/error": "0.0.0-unstable.eb196ccd2f",
|
|
26
|
+
"@webiny/form": "0.0.0-unstable.eb196ccd2f",
|
|
27
|
+
"@webiny/icons": "0.0.0-unstable.eb196ccd2f",
|
|
28
|
+
"@webiny/plugins": "0.0.0-unstable.eb196ccd2f",
|
|
29
|
+
"@webiny/react-router": "0.0.0-unstable.eb196ccd2f",
|
|
30
|
+
"@webiny/utils": "0.0.0-unstable.eb196ccd2f",
|
|
31
31
|
"apollo-client": "2.6.10",
|
|
32
32
|
"apollo-link": "1.2.14",
|
|
33
33
|
"crypto-hash": "3.0.0",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"react-dom": "18.2.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@webiny/project-utils": "0.0.0-unstable.
|
|
39
|
+
"@webiny/project-utils": "0.0.0-unstable.eb196ccd2f",
|
|
40
40
|
"rimraf": "6.0.1",
|
|
41
41
|
"typescript": "5.3.3"
|
|
42
42
|
},
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"build": "node ../cli/bin.js run build",
|
|
49
49
|
"watch": "node ../cli/bin.js run watch"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "eb196ccd2f32296e10f7add6dd7220d4e3abece4"
|
|
52
52
|
}
|
package/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CmsContentEntry } from "@webiny/app-headless-cms/types";
|
|
2
2
|
import type { GenericRecord } from "@webiny/app/types";
|
|
3
3
|
import type { IRecordLockingUnlockEntryResult } from "./domain/abstractions/IRecordLockingUnlockEntry";
|
|
4
4
|
import type { SecurityPermission } from "@webiny/app-security/types";
|
|
@@ -14,13 +14,11 @@ export interface IRecordLockingRecordLocked {
|
|
|
14
14
|
expiresOn: string;
|
|
15
15
|
actions: IRecordLockingLockRecordAction[];
|
|
16
16
|
}
|
|
17
|
-
export interface IPossiblyRecordLockingRecord extends
|
|
17
|
+
export interface IPossiblyRecordLockingRecord extends CmsContentEntry {
|
|
18
18
|
$lockingType?: string;
|
|
19
|
-
entryId: string;
|
|
20
19
|
$locked?: IRecordLockingRecordLocked | null;
|
|
21
20
|
}
|
|
22
21
|
export interface IRecordLockingRecord extends IPossiblyRecordLockingRecord {
|
|
23
|
-
entryId: string;
|
|
24
22
|
$lockingType: string;
|
|
25
23
|
}
|
|
26
24
|
export type IIsRecordLockedParams = Pick<IRecordLockingRecord, "id" | "$lockingType">;
|
package/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { CmsContentEntry } from \"@webiny/app-headless-cms/types\";\nimport type { GenericRecord } from \"@webiny/app/types\";\nimport type { IRecordLockingUnlockEntryResult } from \"~/domain/abstractions/IRecordLockingUnlockEntry\";\nimport type { SecurityPermission } from \"@webiny/app-security/types\";\nimport type { IRecordLockingUpdateEntryLockResult } from \"~/domain/abstractions/IRecordLocking.js\";\n\nexport interface IRecordLockingIdentity {\n id: string;\n displayName: string;\n type: string;\n}\n\nexport interface IRecordLockingRecordLocked {\n lockedBy: IRecordLockingIdentity;\n lockedOn: string;\n expiresOn: string;\n actions: IRecordLockingLockRecordAction[];\n}\n\nexport interface IPossiblyRecordLockingRecord extends CmsContentEntry {\n $lockingType?: string;\n $locked?: IRecordLockingRecordLocked | null;\n}\n\nexport interface IRecordLockingRecord extends IPossiblyRecordLockingRecord {\n $lockingType: string;\n}\n\nexport type IIsRecordLockedParams = Pick<IRecordLockingRecord, \"id\" | \"$lockingType\">;\n\nexport type IUpdateEntryLockParams = Pick<IRecordLockingRecord, \"id\" | \"$lockingType\">;\n\nexport type IUnlockEntryParams = Pick<IRecordLockingRecord, \"id\" | \"$lockingType\">;\n\nexport type IFetchLockRecordParams = Pick<IRecordLockingRecord, \"id\" | \"$lockingType\">;\n\nexport type IFetchLockedEntryLockRecordParams = Pick<IRecordLockingRecord, \"id\" | \"$lockingType\">;\n\nexport interface IFetchLockRecordResult {\n data: IRecordLockingLockRecord | null;\n error: IRecordLockingError | null;\n}\n\nexport interface IRecordLockingContext<\n T extends IPossiblyRecordLockingRecord = IPossiblyRecordLockingRecord\n> {\n readonly loading: boolean;\n readonly records: IPossiblyRecordLockingRecord[];\n readonly error?: IRecordLockingError | null;\n setRecords(folderId: string, type: string, records: T[]): Promise<void>;\n updateEntryLock(params: IUpdateEntryLockParams): Promise<IRecordLockingUpdateEntryLockResult>;\n isRecordLocked(params?: IIsRecordLockedParams): boolean;\n getLockRecordEntry(id: string): IRecordLockingRecord | undefined;\n fetchLockRecord(params: IFetchLockRecordParams): Promise<IFetchLockRecordResult>;\n fetchLockedEntryLockRecord(\n params: IFetchLockedEntryLockRecordParams\n ): Promise<IRecordLockingLockRecord | null>;\n unlockEntry(params: IUnlockEntryParams): Promise<IRecordLockingUnlockEntryResult>;\n removeEntryLock(params: IUnlockEntryParams): void;\n unlockEntryForce(params: IUnlockEntryParams): Promise<IRecordLockingUnlockEntryResult>;\n isLockExpired(input: Date | string): boolean;\n}\n\nexport interface IRecordLockingLockRecordAction {\n type: string;\n message: string;\n createdBy: IRecordLockingIdentity;\n createdOn: string;\n}\n\nexport interface IRecordLockingLockRecord {\n id: string;\n lockedOn: string;\n expiresOn: string;\n lockedBy: IRecordLockingIdentity;\n targetId: string;\n type: string;\n actions: IRecordLockingLockRecordAction[];\n}\n\nexport interface IRecordLockingMeta {\n totalCount: number;\n cursor: string | null;\n hasMoreItems: boolean;\n}\n\nexport interface IRecordLockingError<T = GenericRecord> {\n message: string;\n code: string;\n data?: T;\n}\n\nexport interface RecordLockingSecurityPermission extends SecurityPermission {\n canForceUnlock?: string;\n}\n"],"mappings":"","ignoreList":[]}
|