mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Support user variable in dropdown conditions
Summary: Dropdown conditions can now reference a `user` variable, similar to the one available in Access Rules. Test Plan: Browser test. Reviewers: jarek, paulfitz Reviewed By: jarek, paulfitz Differential Revision: https://phab.getgrist.com/D4255
This commit is contained in:
@@ -21,7 +21,7 @@ dispose.makeDisposable(AbstractWidget);
|
||||
/**
|
||||
* Builds the DOM showing configuration buttons and fields in the sidebar.
|
||||
*/
|
||||
AbstractWidget.prototype.buildConfigDom = function() {
|
||||
AbstractWidget.prototype.buildConfigDom = function(_gristDoc) {
|
||||
throw new Error("Not Implemented");
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ AbstractWidget.prototype.buildConfigDom = function() {
|
||||
* Builds the transform prompt config DOM in the few cases where it is necessary.
|
||||
* Child classes need not override this function if they do not require transform config options.
|
||||
*/
|
||||
AbstractWidget.prototype.buildTransformConfigDom = function() {
|
||||
AbstractWidget.prototype.buildTransformConfigDom = function(_gristDoc) {
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ ChoiceEditor.prototype.buildDropdownConditionFilter = function() {
|
||||
|
||||
return buildDropdownConditionFilter({
|
||||
dropdownConditionCompiled: dropdownConditionCompiled.result,
|
||||
docData: this.options.gristDoc.docData,
|
||||
gristDoc: this.options.gristDoc,
|
||||
tableId: this.options.field.tableId(),
|
||||
rowId: this.options.rowId,
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {createGroup} from 'app/client/components/commands';
|
||||
import {GristDoc} from 'app/client/components/GristDoc';
|
||||
import {ACIndexImpl, ACItem, ACResults,
|
||||
buildHighlightedDom, HighlightFunc, normalizeText} from 'app/client/lib/ACIndex';
|
||||
import {IAutocompleteOptions} from 'app/client/lib/autocomplete';
|
||||
import {makeT} from 'app/client/lib/localization';
|
||||
import {IToken, TokenField, tokenFieldStyles} from 'app/client/lib/TokenField';
|
||||
import {DocData} from 'app/client/models/DocData';
|
||||
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
|
||||
import {menuCssClass} from 'app/client/ui2018/menus';
|
||||
import {createMobileButtons, getButtonMargins} from 'app/client/widgets/EditorButtons';
|
||||
@@ -12,7 +12,8 @@ import {EditorPlacement} from 'app/client/widgets/EditorPlacement';
|
||||
import {FieldOptions, NewBaseEditor} from 'app/client/widgets/NewBaseEditor';
|
||||
import {csvEncodeRow} from 'app/common/csvFormat';
|
||||
import {CellValue} from "app/common/DocActions";
|
||||
import {CompiledPredicateFormula, EmptyRecordView} from 'app/common/PredicateFormula';
|
||||
import {CompiledPredicateFormula} from 'app/common/PredicateFormula';
|
||||
import {EmptyRecordView} from 'app/common/RecordView';
|
||||
import {decodeObject, encodeObject} from 'app/plugin/objtypes';
|
||||
import {ChoiceOptions, getRenderFillColor, getRenderTextColor} from 'app/client/widgets/ChoiceTextBox';
|
||||
import {choiceToken, cssChoiceACItem, cssChoiceToken} from 'app/client/widgets/ChoiceToken';
|
||||
@@ -246,7 +247,7 @@ export class ChoiceListEditor extends NewBaseEditor {
|
||||
|
||||
return buildDropdownConditionFilter({
|
||||
dropdownConditionCompiled: dropdownConditionCompiled.result,
|
||||
docData: this.options.gristDoc.docData,
|
||||
gristDoc: this.options.gristDoc,
|
||||
tableId: this.options.field.tableId(),
|
||||
rowId: this.options.rowId,
|
||||
});
|
||||
@@ -311,7 +312,7 @@ export class ChoiceListEditor extends NewBaseEditor {
|
||||
|
||||
export interface GetACFilterFuncParams {
|
||||
dropdownConditionCompiled: CompiledPredicateFormula;
|
||||
docData: DocData;
|
||||
gristDoc: GristDoc;
|
||||
tableId: string;
|
||||
rowId: number;
|
||||
}
|
||||
@@ -319,12 +320,13 @@ export interface GetACFilterFuncParams {
|
||||
export function buildDropdownConditionFilter(
|
||||
params: GetACFilterFuncParams
|
||||
): (item: ChoiceItem) => boolean {
|
||||
const {dropdownConditionCompiled, docData, tableId, rowId} = params;
|
||||
const table = docData.getTable(tableId);
|
||||
const {dropdownConditionCompiled, gristDoc, tableId, rowId} = params;
|
||||
const table = gristDoc.docData.getTable(tableId);
|
||||
if (!table) { throw new Error(`Table ${tableId} not found`); }
|
||||
|
||||
const user = gristDoc.docPageModel.user.get() ?? undefined;
|
||||
const rec = table.getRecord(rowId) || new EmptyRecordView();
|
||||
return (item: ChoiceItem) => dropdownConditionCompiled({rec, choice: item.label});
|
||||
return (item: ChoiceItem) => dropdownConditionCompiled({user, rec, choice: item.label});
|
||||
}
|
||||
|
||||
const cssCellEditor = styled('div', `
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
FormSelectConfig,
|
||||
} from 'app/client/components/Forms/FormConfig';
|
||||
import {DropdownConditionConfig} from 'app/client/components/DropdownConditionConfig';
|
||||
import {GristDoc} from 'app/client/components/GristDoc';
|
||||
import {makeT} from 'app/client/lib/localization';
|
||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||
@@ -79,17 +80,17 @@ export class ChoiceTextBox extends NTextBox {
|
||||
);
|
||||
}
|
||||
|
||||
public buildConfigDom() {
|
||||
public buildConfigDom(gristDoc: GristDoc) {
|
||||
return [
|
||||
super.buildConfigDom(),
|
||||
super.buildConfigDom(gristDoc),
|
||||
this.buildChoicesConfigDom(),
|
||||
dom.create(DropdownConditionConfig, this.field),
|
||||
dom.create(DropdownConditionConfig, this.field, gristDoc),
|
||||
];
|
||||
}
|
||||
|
||||
public buildTransformConfigDom() {
|
||||
public buildTransformConfigDom(gristDoc: GristDoc) {
|
||||
return [
|
||||
super.buildConfigDom(),
|
||||
super.buildConfigDom(gristDoc),
|
||||
this.buildChoicesConfigDom(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ _.extend(DateTimeTextBox.prototype, DateTextBox.prototype);
|
||||
* Builds the config dom for the DateTime TextBox. If isTransformConfig is true,
|
||||
* builds only the necessary dom for the transform config menu.
|
||||
*/
|
||||
DateTimeTextBox.prototype.buildConfigDom = function(isTransformConfig) {
|
||||
DateTimeTextBox.prototype.buildConfigDom = function(_gristDoc, isTransformConfig) {
|
||||
const disabled = ko.pureComputed(() => {
|
||||
return this.field.config.options.disabled('timeFormat')() || this.field.column().disableEditData();
|
||||
});
|
||||
@@ -92,8 +92,8 @@ DateTimeTextBox.prototype.buildConfigDom = function(isTransformConfig) {
|
||||
);
|
||||
};
|
||||
|
||||
DateTimeTextBox.prototype.buildTransformConfigDom = function() {
|
||||
return this.buildConfigDom(true);
|
||||
DateTimeTextBox.prototype.buildTransformConfigDom = function(gristDoc) {
|
||||
return this.buildConfigDom(gristDoc, true);
|
||||
};
|
||||
|
||||
// clean up old koform styles
|
||||
|
||||
@@ -499,7 +499,7 @@ export class FieldBuilder extends Disposable {
|
||||
// the dom created by the widgetImpl to get out of sync.
|
||||
return dom('div',
|
||||
kd.maybe(() => !this._isTransformingType() && this.widgetImpl(), (widget: NewAbstractWidget) =>
|
||||
dom('div', widget.buildConfigDom())
|
||||
dom('div', widget.buildConfigDom(this.gristDoc))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FormFieldRulesConfig } from 'app/client/components/Forms/FormConfig';
|
||||
import { GristDoc } from 'app/client/components/GristDoc';
|
||||
import { fromKoSave } from 'app/client/lib/fromKoSave';
|
||||
import { makeT } from 'app/client/lib/localization';
|
||||
import { DataRowModel } from 'app/client/models/DataRowModel';
|
||||
@@ -32,7 +33,7 @@ export class NTextBox extends NewAbstractWidget {
|
||||
}));
|
||||
}
|
||||
|
||||
public buildConfigDom(): DomContents {
|
||||
public buildConfigDom(_gristDoc: GristDoc): DomContents {
|
||||
const toggle = () => {
|
||||
const newValue = !this.field.config.wrap.peek();
|
||||
this.field.config.wrap.setAndSave(newValue).catch(reportError);
|
||||
|
||||
@@ -60,7 +60,7 @@ export abstract class NewAbstractWidget extends Disposable {
|
||||
/**
|
||||
* Builds the DOM showing configuration buttons and fields in the sidebar.
|
||||
*/
|
||||
public buildConfigDom(): DomContents {
|
||||
public buildConfigDom(_gristDoc: GristDoc): DomContents {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export abstract class NewAbstractWidget extends Disposable {
|
||||
* Builds the transform prompt config DOM in the few cases where it is necessary.
|
||||
* Child classes need not override this function if they do not require transform config options.
|
||||
*/
|
||||
public buildTransformConfigDom(): DomContents {
|
||||
public buildTransformConfigDom(_gristDoc: GristDoc): DomContents {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* See app/common/NumberFormat for description of options we support.
|
||||
*/
|
||||
import {FormFieldRulesConfig} from 'app/client/components/Forms/FormConfig';
|
||||
import {GristDoc} from 'app/client/components/GristDoc';
|
||||
import {fromKoSave} from 'app/client/lib/fromKoSave';
|
||||
import {makeT} from 'app/client/lib/localization';
|
||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||
@@ -39,7 +40,7 @@ export class NumericTextBox extends NTextBox {
|
||||
super(field);
|
||||
}
|
||||
|
||||
public buildConfigDom(): DomContents {
|
||||
public buildConfigDom(gristDoc: GristDoc): DomContents {
|
||||
// Holder for all computeds created here. It gets disposed with the returned DOM element.
|
||||
const holder = new MultiHolder();
|
||||
|
||||
@@ -89,7 +90,7 @@ export class NumericTextBox extends NTextBox {
|
||||
const disabledStyle = cssButtonSelect.cls('-disabled', disabled);
|
||||
|
||||
return [
|
||||
super.buildConfigDom(),
|
||||
super.buildConfigDom(gristDoc),
|
||||
cssLabel(t('Number Format')),
|
||||
cssRow(
|
||||
dom.autoDispose(holder),
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
FormSelectConfig
|
||||
} from 'app/client/components/Forms/FormConfig';
|
||||
import {DropdownConditionConfig} from 'app/client/components/DropdownConditionConfig';
|
||||
import {GristDoc} from 'app/client/components/GristDoc';
|
||||
import {makeT} from 'app/client/lib/localization';
|
||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||
import {TableRec} from 'app/client/models/DocModel';
|
||||
@@ -53,12 +54,12 @@ export class Reference extends NTextBox {
|
||||
});
|
||||
}
|
||||
|
||||
public buildConfigDom() {
|
||||
public buildConfigDom(gristDoc: GristDoc) {
|
||||
return [
|
||||
this.buildTransformConfigDom(),
|
||||
dom.create(DropdownConditionConfig, this.field),
|
||||
dom.create(DropdownConditionConfig, this.field, gristDoc),
|
||||
cssLabel(t('CELL FORMAT')),
|
||||
super.buildConfigDom(),
|
||||
super.buildConfigDom(gristDoc),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ export class ReferenceEditor extends NTextEditor {
|
||||
constructor(options: FieldOptions) {
|
||||
super(options);
|
||||
|
||||
const docData = options.gristDoc.docData;
|
||||
this._utils = new ReferenceUtils(options.field, docData);
|
||||
const gristDoc = options.gristDoc;
|
||||
this._utils = new ReferenceUtils(options.field, gristDoc);
|
||||
|
||||
const vcol = this._utils.visibleColModel;
|
||||
this._enableAddNew = (
|
||||
@@ -47,7 +47,7 @@ export class ReferenceEditor extends NTextEditor {
|
||||
|
||||
// The referenced table has probably already been fetched (because there must already be a
|
||||
// Reference widget instantiated), but it's better to avoid this assumption.
|
||||
docData.fetchTable(this._utils.refTableId).then(() => {
|
||||
gristDoc.docData.fetchTable(this._utils.refTableId).then(() => {
|
||||
if (this.isDisposed()) { return; }
|
||||
if (needReload && this.textInput.value === '') {
|
||||
this.textInput.value = undef(options.state, options.editValue, this._idToText());
|
||||
|
||||
@@ -55,8 +55,8 @@ export class ReferenceListEditor extends NewBaseEditor {
|
||||
constructor(protected options: FieldOptions) {
|
||||
super(options);
|
||||
|
||||
const docData = options.gristDoc.docData;
|
||||
this._utils = new ReferenceUtils(options.field, docData);
|
||||
const gristDoc = options.gristDoc;
|
||||
this._utils = new ReferenceUtils(options.field, gristDoc);
|
||||
|
||||
const vcol = this._utils.visibleColModel;
|
||||
this._enableAddNew = (
|
||||
@@ -130,7 +130,7 @@ export class ReferenceListEditor extends NewBaseEditor {
|
||||
|
||||
// The referenced table has probably already been fetched (because there must already be a
|
||||
// Reference widget instantiated), but it's better to avoid this assumption.
|
||||
docData.fetchTable(this._utils.refTableId).then(() => {
|
||||
gristDoc.docData.fetchTable(this._utils.refTableId).then(() => {
|
||||
if (this.isDisposed()) { return; }
|
||||
if (needReload) {
|
||||
this._tokenField.setTokens(
|
||||
|
||||
Reference in New Issue
Block a user