mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Checks that an ACL formula can be parsed, and prevent saving unparsable ACL rules.
Summary: - Fix error-handling in bundleActions(), and wait for the full bundle to complete. (The omissions here were making it impossibly to react to errors from inside bundleActions()) - Catch problematic rules early enough to undo them, by trying out ruleCollection.update() on updated rules before the updates are applied. - Added checkAclFormula() call to DocComm that checks parsing and compiling formula, and reports errors. - In UI, prevent saving if any aclFormulas are invalid, or while waiting for the to get checked. - Also fixed some lint errors Test Plan: Added a test case of error reporting in ACL formulas. Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2689
This commit is contained in:
@@ -83,7 +83,7 @@ export class DocData extends BaseDocData {
|
||||
this._bundlesPending++;
|
||||
|
||||
// Promise to allow waiting for the result of prepare() callback before it's even called.
|
||||
let prepareResolve!: (value: T) => void;
|
||||
let prepareResolve!: (value: T|Promise<T>) => void;
|
||||
const preparePromise = new Promise<T>(resolve => { prepareResolve = resolve; });
|
||||
|
||||
// Manually-triggered promise for when finalize() should be called. It's triggered by user,
|
||||
@@ -100,8 +100,7 @@ export class DocData extends BaseDocData {
|
||||
this._nextDesc = options.description;
|
||||
this._lastActionNum = null;
|
||||
this._triggerBundleFinalize = triggerFinalize;
|
||||
const value = await options.prepare();
|
||||
prepareResolve(value);
|
||||
await prepareResolve(options.prepare());
|
||||
this._shouldIncludeInBundle = options.shouldIncludeInBundle;
|
||||
|
||||
await triggerFinalizePromise;
|
||||
@@ -123,8 +122,8 @@ export class DocData extends BaseDocData {
|
||||
}
|
||||
};
|
||||
|
||||
this._lastBundlePromise = doBundleActions();
|
||||
return {preparePromise, triggerFinalize};
|
||||
const completionPromise = this._lastBundlePromise = doBundleActions();
|
||||
return {preparePromise, triggerFinalize, completionPromise};
|
||||
}
|
||||
|
||||
// Execute a callback that may send multiple actions, and bundle those actions together. The
|
||||
@@ -146,6 +145,7 @@ export class DocData extends BaseDocData {
|
||||
return await bundlingInfo.preparePromise;
|
||||
} finally {
|
||||
bundlingInfo.triggerFinalize();
|
||||
await bundlingInfo.completionPromise;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ export interface BundlingOptions<T = unknown> {
|
||||
|
||||
/**
|
||||
* Result of startBundlingActions(), to allow waiting for prepare() to complete, and to trigger
|
||||
* finalize() manually.
|
||||
* finalize() manually, and to wait for the full bundle to complete.
|
||||
*/
|
||||
export interface BundlingInfo<T = unknown> {
|
||||
// Promise for when the prepare() has completed. Note that sometimes it's delayed until the
|
||||
@@ -270,4 +270,7 @@ export interface BundlingInfo<T = unknown> {
|
||||
|
||||
// Ask DocData to call the finalize callback immediately.
|
||||
triggerFinalize: () => void;
|
||||
|
||||
// Promise for when the bundle has been finalized.
|
||||
completionPromise: Promise<void>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user