(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:
George Gevoian
2024-04-26 16:34:16 -04:00
parent 34c85757f1
commit 3112433a58
86 changed files with 4221 additions and 1060 deletions

View File

@@ -378,7 +378,12 @@ class BruteForceACIndexImpl<Item extends ACItem> implements ACIndex<Item> {
public search(searchText: string): ACResults<Item> {
const cleanedSearchText = searchText.trim().toLowerCase();
if (!cleanedSearchText) {
return {items: this._allItems.slice(0, this._maxResults), highlightFunc: highlightNone, selectIndex: -1};
return {
items: this._allItems.slice(0, this._maxResults),
extraItems: [],
highlightFunc: highlightNone,
selectIndex: -1,
};
}
const searchWords = cleanedSearchText.split(/\s+/);
@@ -397,7 +402,7 @@ class BruteForceACIndexImpl<Item extends ACItem> implements ACIndex<Item> {
matches.sort((a, b) => nativeCompare(b[0], a[0]) || nativeCompare(a[1], b[1]));
const items = matches.slice(0, this._maxResults).map((m) => m[2]);
return {items, highlightFunc: highlightNone, selectIndex: -1};
return {items, extraItems: [], highlightFunc: highlightNone, selectIndex: -1};
}
}

View File

@@ -3,13 +3,11 @@ import { Disposable } from 'app/client/lib/dispose';
import { ClientProcess, SafeBrowser } from 'app/client/lib/SafeBrowser';
import { LocalPlugin } from 'app/common/plugin';
import { PluginInstance } from 'app/common/PluginInstance';
import { GristLight } from 'app/common/themes/GristLight';
import { GristAPI, RPC_GRISTAPI_INTERFACE } from 'app/plugin/GristAPI';
import { Storage } from 'app/plugin/StorageAPI';
import { checkers } from 'app/plugin/TypeCheckers';
import { assert } from 'chai';
import { Rpc } from 'grain-rpc';
import { Computed } from 'grainjs';
import { noop } from 'lodash';
import { basename } from 'path';
import * as sinon from 'sinon';
@@ -188,7 +186,6 @@ describe('SafeBrowser', function() {
untrustedContentOrigin: '',
mainPath,
baseLogger: {},
theme: Computed.create(null, () => ({appearance: 'light', colors: GristLight})),
});
cleanup.push(() => safeBrowser.deactivate());
pluginInstance.rpc.registerForwarder(mainPath, safeBrowser);

View File

@@ -1,11 +1,9 @@
import {checkName} from 'app/client/ui/AccountPage';
import {checkName} from 'app/client/lib/nameUtils';
import {assert} from 'chai';
describe("AccountPage", function() {
describe("nameUtils", function() {
describe("isValidName", function() {
it("should detect invalid name", function() {
assert.equal(checkName('santa'), true);
assert.equal(checkName('_santa'), true);
assert.equal(checkName("O'Neil"), true);

View File

@@ -1,8 +1,8 @@
import {getTimeFromNow} from 'app/client/models/HomeModel';
import {getTimeFromNow} from 'app/client/lib/timeUtils';
import {assert} from 'chai';
import moment from 'moment';
describe("HomeModel", function() {
describe("timeUtils", function() {
describe("getTimeFromNow", function() {
it("should give good summary of time that just passed", function() {
const t = moment().subtract(10, 's');
@@ -18,5 +18,5 @@ describe("HomeModel", function() {
const t = moment().add(2, 'minutes');
assert.equal(getTimeFromNow(t.toISOString()), 'in 2 minutes');
});
});
});
});