(core) Small changes to Access Rules page to clearify behavior of table default rules

Summary:
- Rename "Add Default Rule" to "Add Table-wide Rule", and enable always.
- Rename "All Other" to "All".

Test Plan: Updated test; new behavior (for when menu option is newly enabled) only tested manually.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D4195
This commit is contained in:
Dmitry S 2024-02-21 01:00:48 -05:00
parent 219b1f3f87
commit ca990bbfe6
2 changed files with 24 additions and 6 deletions

View File

@ -11,6 +11,7 @@ import {GristDoc} from 'app/client/components/GristDoc';
import {logTelemetryEvent} from 'app/client/lib/telemetry'; import {logTelemetryEvent} from 'app/client/lib/telemetry';
import {reportError, UserError} from 'app/client/models/errors'; import {reportError, UserError} from 'app/client/models/errors';
import {TableData} from 'app/client/models/TableData'; import {TableData} from 'app/client/models/TableData';
import {withInfoTooltip} from 'app/client/ui/tooltips';
import {shadowScroll} from 'app/client/ui/shadowScroll'; import {shadowScroll} from 'app/client/ui/shadowScroll';
import {bigBasicButton, bigPrimaryButton} from 'app/client/ui2018/buttons'; import {bigBasicButton, bigPrimaryButton} from 'app/client/ui2018/buttons';
import {squareCheckbox} from 'app/client/ui2018/checkbox'; import {squareCheckbox} from 'app/client/ui2018/checkbox';
@ -690,8 +691,7 @@ class TableRules extends Disposable {
cssIconButton(icon('Dots'), {style: 'margin-left: auto'}, cssIconButton(icon('Dots'), {style: 'margin-left: auto'},
menu(() => [ menu(() => [
menuItemAsync(() => this._addColumnRuleSet(), t("Add Column Rule")), menuItemAsync(() => this._addColumnRuleSet(), t("Add Column Rule")),
menuItemAsync(() => this._addDefaultRuleSet(), t("Add Default Rule"), menuItemAsync(() => this._addDefaultRuleSet(), t("Add Table-wide Rule")),
dom.cls('disabled', use => Boolean(use(this._defaultRuleSet)))),
menuItemAsync(() => this._accessRules.removeTableRules(this), t("Delete Table Rules")), menuItemAsync(() => this._accessRules.removeTableRules(this), t("Delete Table Rules")),
]), ]),
testId('rule-table-menu-btn'), testId('rule-table-menu-btn'),
@ -813,9 +813,13 @@ class TableRules extends Disposable {
} }
private _addDefaultRuleSet() { private _addDefaultRuleSet() {
if (!this._defaultRuleSet.get()) { const ruleSet = this._defaultRuleSet.get();
if (!ruleSet) {
DefaultObsRuleSet.create(this._defaultRuleSet, this._accessRules, this, this._haveColumnRules); DefaultObsRuleSet.create(this._defaultRuleSet, this._accessRules, this, this._haveColumnRules);
this.addDefaultRules(this._accessRules.getSeedRules()); this.addDefaultRules(this._accessRules.getSeedRules());
} else {
const part = ruleSet.addRulePart(ruleSet.getDefaultCondition());
setTimeout(() => part.focusEditor?.(), 0);
} }
} }
} }
@ -1034,6 +1038,12 @@ abstract class ObsRuleSet extends Disposable {
return body.length > 0 && body[body.length - 1].hasEmptyCondition(use); return body.length > 0 && body[body.length - 1].hasEmptyCondition(use);
} }
public getDefaultCondition(): ObsRulePart|null {
const body = this._body.get();
const last = body.length > 0 ? body[body.length - 1] : null;
return last?.hasEmptyCondition(unwrap) ? last : null;
}
/** /**
* Which permission bits to allow the user to set. * Which permission bits to allow the user to set.
*/ */
@ -1129,8 +1139,9 @@ class DefaultObsRuleSet extends ObsRuleSet {
return [ return [
cssCenterContent.cls(''), cssCenterContent.cls(''),
cssDefaultLabel( cssDefaultLabel(
dom.text(use => this._haveColumnRules && use(this._haveColumnRules) ? 'All Other' : 'All'), dom.domComputed(use => this._haveColumnRules && use(this._haveColumnRules), (haveColRules) =>
) haveColRules ? withInfoTooltip('All', 'accessRulesTableWide') : 'All')
),
]; ];
} }
} }
@ -1544,6 +1555,8 @@ class ObsRulePart extends Disposable {
// Whether the rule part, and if it's valid or being checked. // Whether the rule part, and if it's valid or being checked.
public ruleStatus: Computed<RuleStatus>; public ruleStatus: Computed<RuleStatus>;
public focusEditor: (() => void)|undefined;
// Formula to show in the formula editor. // Formula to show in the formula editor.
private _aclFormula = Observable.create<string>(this, this._rulePart?.aclFormula || ""); private _aclFormula = Observable.create<string>(this, this._rulePart?.aclFormula || "");
@ -1679,6 +1692,7 @@ class ObsRulePart extends Disposable {
); );
}), }),
getSuggestions: (prefix) => this._completions.get(), getSuggestions: (prefix) => this._completions.get(),
customiseEditor: (editor) => { this.focusEditor = () => editor.focus(); },
}), }),
testId('rule-acl-formula'), testId('rule-acl-formula'),
), ),

View File

@ -50,7 +50,8 @@ export type Tooltip =
| 'addColumnConditionalStyle' | 'addColumnConditionalStyle'
| 'uuid' | 'uuid'
| 'lookups' | 'lookups'
| 'formulaColumn'; | 'formulaColumn'
| 'accessRulesTableWide';
export type TooltipContentFunc = (...domArgs: DomElementArg[]) => DomContents; export type TooltipContentFunc = (...domArgs: DomElementArg[]) => DomContents;
@ -135,6 +136,9 @@ see or edit which parts of your document.')
), ),
...args, ...args,
), ),
accessRulesTableWide: (...args: DomElementArg[]) => cssTooltipContent(
dom('div', t('These rules are applied after all column rules have been processed, if applicable.'))
),
}; };
export interface BehavioralPromptContent { export interface BehavioralPromptContent {