mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add dropdown conditions
Summary: Dropdown conditions let you specify a predicate formula that's used to filter choices and references in their respective autocomplete dropdown menus. Test Plan: Python and browser tests (WIP). Reviewers: jarek, paulfitz Reviewed By: jarek Subscribers: dsagal, paulfitz Differential Revision: https://phab.getgrist.com/D4235
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
import ace, {Ace} from 'ace-builds';
|
||||
import {setupAceEditorCompletions} from 'app/client/components/AceEditorCompletions';
|
||||
import {theme} from 'app/client/ui2018/cssVars';
|
||||
import {gristThemeObs} from 'app/client/ui2018/theme';
|
||||
import {Theme} from 'app/common/ThemePrefs';
|
||||
import {getGristConfig} from 'app/common/urlUtils';
|
||||
import {Computed, dom, DomArg, Listener, Observable, styled} from 'grainjs';
|
||||
import {dom, DomArg, Observable, styled} from 'grainjs';
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
export interface ACLFormulaOptions {
|
||||
gristTheme: Computed<Theme>;
|
||||
initialValue: string;
|
||||
readOnly: boolean;
|
||||
placeholder: DomArg;
|
||||
@@ -22,19 +21,15 @@ export function aclFormulaEditor(options: ACLFormulaOptions) {
|
||||
const editor: Ace.Editor = ace.edit(editorElem);
|
||||
|
||||
// Set various editor options.
|
||||
function setAceTheme(gristTheme: Theme) {
|
||||
const {enableCustomCss} = getGristConfig();
|
||||
const gristAppearance = gristTheme.appearance;
|
||||
const aceTheme = gristAppearance === 'dark' && !enableCustomCss ? 'dracula' : 'chrome';
|
||||
function setAceTheme(newTheme: Theme) {
|
||||
const {appearance} = newTheme;
|
||||
const aceTheme = appearance === 'dark' ? 'dracula' : 'chrome';
|
||||
editor.setTheme(`ace/theme/${aceTheme}`);
|
||||
}
|
||||
setAceTheme(options.gristTheme.get());
|
||||
let themeListener: Listener | undefined;
|
||||
if (!getGristConfig().enableCustomCss) {
|
||||
themeListener = options.gristTheme.addListener((gristTheme) => {
|
||||
setAceTheme(gristTheme);
|
||||
});
|
||||
}
|
||||
setAceTheme(gristThemeObs().get());
|
||||
const themeListener = gristThemeObs().addListener((newTheme) => {
|
||||
setAceTheme(newTheme);
|
||||
});
|
||||
// ACE editor resizes automatically when maxLines is set.
|
||||
editor.setOptions({enableLiveAutocompletion: true, maxLines: 10});
|
||||
editor.renderer.setShowGutter(false); // Default line numbers to hidden
|
||||
|
||||
@@ -36,14 +36,13 @@ import {ACLRuleCollection, isSchemaEditResource, SPECIAL_RULES_TABLE_ID} from 'a
|
||||
import {AclRuleProblem, AclTableDescription, getTableTitle} from 'app/common/ActiveDocAPI';
|
||||
import {BulkColValues, getColValues, RowRecord, UserAction} from 'app/common/DocActions';
|
||||
import {
|
||||
FormulaProperties,
|
||||
getFormulaProperties,
|
||||
RulePart,
|
||||
RuleSet,
|
||||
UserAttributeRule
|
||||
} from 'app/common/GranularAccessClause';
|
||||
import {isHiddenCol} from 'app/common/gristTypes';
|
||||
import {isNonNullish, unwrap} from 'app/common/gutil';
|
||||
import {getPredicateFormulaProperties, PredicateFormulaProperties} from 'app/common/PredicateFormula';
|
||||
import {SchemaTypes} from 'app/common/schema';
|
||||
import {MetaRowRecord} from 'app/common/TableData';
|
||||
import {
|
||||
@@ -496,7 +495,7 @@ export class AccessRules extends Disposable {
|
||||
removeItem(this._userAttrRules, userAttr);
|
||||
}
|
||||
|
||||
public async checkAclFormula(text: string): Promise<FormulaProperties> {
|
||||
public async checkAclFormula(text: string): Promise<PredicateFormulaProperties> {
|
||||
if (text) {
|
||||
return this.gristDoc.docComm.checkAclFormula(text);
|
||||
}
|
||||
@@ -1465,7 +1464,6 @@ class ObsUserAttributeRule extends Disposable {
|
||||
cssColumnGroup(
|
||||
cssCell1(
|
||||
aclFormulaEditor({
|
||||
gristTheme: this._accessRules.gristDoc.currentTheme,
|
||||
initialValue: this._charId.get(),
|
||||
readOnly: false,
|
||||
setValue: (text) => this._setUserAttr(text),
|
||||
@@ -1598,7 +1596,8 @@ class ObsRulePart extends Disposable {
|
||||
// If the formula failed validation, the error message to show. Blank if valid.
|
||||
private _formulaError = Observable.create(this, '');
|
||||
|
||||
private _formulaProperties = Observable.create<FormulaProperties>(this, getAclFormulaProperties(this._rulePart));
|
||||
private _formulaProperties = Observable.create<PredicateFormulaProperties>(this,
|
||||
getAclFormulaProperties(this._rulePart));
|
||||
|
||||
// Error message if any validation failed.
|
||||
private _error: Computed<string>;
|
||||
@@ -1618,7 +1617,7 @@ class ObsRulePart extends Disposable {
|
||||
|
||||
this._error = Computed.create(this, (use) => {
|
||||
return use(this._formulaError) ||
|
||||
this._warnInvalidColIds(use(this._formulaProperties).usedColIds) ||
|
||||
this._warnInvalidColIds(use(this._formulaProperties).recColIds) ||
|
||||
( !this._ruleSet.isLastCondition(use, this) &&
|
||||
use(this._aclFormula) === '' &&
|
||||
permissionSetToText(use(this._permissions)) !== '' ?
|
||||
@@ -1690,7 +1689,6 @@ class ObsRulePart extends Disposable {
|
||||
cssCell2(
|
||||
wide ? cssCell4.cls('') : null,
|
||||
aclFormulaEditor({
|
||||
gristTheme: this._ruleSet.accessRules.gristDoc.currentTheme,
|
||||
initialValue: this._aclFormula.get(),
|
||||
readOnly: this.isBuiltIn(),
|
||||
setValue: (value) => this._setAclFormula(value),
|
||||
@@ -1913,9 +1911,9 @@ function getChangedStatus(value: boolean): RuleStatus {
|
||||
return value ? RuleStatus.ChangedValid : RuleStatus.Unchanged;
|
||||
}
|
||||
|
||||
function getAclFormulaProperties(part?: RulePart): FormulaProperties {
|
||||
function getAclFormulaProperties(part?: RulePart): PredicateFormulaProperties {
|
||||
const aclFormulaParsed = part?.origRecord?.aclFormulaParsed;
|
||||
return aclFormulaParsed ? getFormulaProperties(JSON.parse(String(aclFormulaParsed))) : {};
|
||||
return aclFormulaParsed ? getPredicateFormulaProperties(JSON.parse(String(aclFormulaParsed))) : {};
|
||||
}
|
||||
|
||||
// Return a rule set if it applies to one of the specified columns.
|
||||
|
||||
Reference in New Issue
Block a user