mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Renaming filters for choice columns
Summary: Updating filters when user renames labels in a choice/choice list column. When there are unsaved filters they are reverted to orginal values (only for the affected column). Test Plan: new tests Reviewers: alexmojaki Reviewed By: alexmojaki Differential Revision: https://phab.getgrist.com/D3230
This commit is contained in:
parent
f74002fe32
commit
a685707d50
@ -1,3 +1,4 @@
|
||||
import json
|
||||
import types
|
||||
import logger
|
||||
import useractions
|
||||
@ -860,6 +861,38 @@ class TestUserActions(test_engine.EngineTestCase):
|
||||
[12, [[]]],
|
||||
])
|
||||
|
||||
# Test filters rename
|
||||
|
||||
# Create new view section
|
||||
self.apply_user_action(["CreateViewSection", 1, 0, "record", None])
|
||||
|
||||
# Filter it by first column
|
||||
self.apply_user_action(['BulkAddRecord', '_grist_Filters', [None], {
|
||||
"viewSectionRef": [1],
|
||||
"colRef": [1],
|
||||
"filter": [json.dumps({"included": ["b", "c"]})]
|
||||
}])
|
||||
|
||||
# Add the same filter for second column (to make sure it is not renamed)
|
||||
self.apply_user_action(['BulkAddRecord', '_grist_Filters', [None], {
|
||||
"viewSectionRef": [1],
|
||||
"colRef": [2],
|
||||
"filter": [json.dumps({"included": ["b", "c"]})]
|
||||
}])
|
||||
|
||||
# Rename choices
|
||||
renames = {"b": "z", "c": "b"}
|
||||
self.apply_user_action(
|
||||
["RenameChoices", "ChoiceTable", "ChoiceColumn", renames])
|
||||
|
||||
# Test filters
|
||||
self.assertTableData('_grist_Filters', data=[
|
||||
["id", "colRef", "filter", "setAutoRemove", "viewSectionRef"],
|
||||
[1, 1, json.dumps({"included": ["z", "b"]}), None, 1],
|
||||
[2, 2, json.dumps({"included": ["b", "c"]}), None, 1]
|
||||
])
|
||||
|
||||
|
||||
def test_reference_lookup(self):
|
||||
sample = testutil.parse_test_sample({
|
||||
"SCHEMA": [
|
||||
|
@ -1291,13 +1291,35 @@ class UserActions(object):
|
||||
table = self._engine.tables[table_id]
|
||||
col = table.get_column(col_id)
|
||||
|
||||
if col.is_formula():
|
||||
# We don't set the values of formula columns, they should just recalculate themselves
|
||||
return None
|
||||
# We don't set the values of formula columns, they should just recalculate themselves
|
||||
if not col.is_formula():
|
||||
row_ids, values = col.rename_choices(renames)
|
||||
values = [encode_object(v) for v in values]
|
||||
self.BulkUpdateRecord(table_id, row_ids, {col_id: values})
|
||||
|
||||
row_ids, values = col.rename_choices(renames)
|
||||
values = [encode_object(v) for v in values]
|
||||
return self.BulkUpdateRecord(table_id, row_ids, {col_id: values})
|
||||
# Helper to rename only string values
|
||||
def rename(value):
|
||||
return renames.get(value, value) if isinstance(value, six.string_types) else value
|
||||
|
||||
# Rename filters
|
||||
filters = self._engine.tables['_grist_Filters']
|
||||
colRef = self._docmodel.get_column_rec(table_id, col_id).id
|
||||
col_filters = filters.filter_records(colRef=colRef)
|
||||
row_ids = []
|
||||
values = []
|
||||
for rec in col_filters:
|
||||
if not rec.filter:
|
||||
continue
|
||||
col_filter = json.loads(rec.filter)
|
||||
new_filter = {
|
||||
include_exclude: [rename(value) for value in values]
|
||||
for include_exclude, values in col_filter.items()
|
||||
}
|
||||
if col_filter != new_filter:
|
||||
row_ids.append(rec.id)
|
||||
values.append(json.dumps(new_filter))
|
||||
if row_ids:
|
||||
self.BulkUpdateRecord('_grist_Filters', row_ids, {"filter": values})
|
||||
|
||||
#----------------------------------------
|
||||
# User actions on tables.
|
||||
|
@ -892,28 +892,33 @@ export async function undo(optCount: number = 1, optTimeout?: number) {
|
||||
|
||||
/**
|
||||
* Returns a function to undo all user actions from a particular point in time.
|
||||
* Optionally accepts a function which should return the same result before and after the test.
|
||||
*/
|
||||
export async function begin() {
|
||||
export async function begin(invariant: () => any = () => true) {
|
||||
const undoStackPointer = () => driver.executeScript<number>(`
|
||||
return window.gristDocPageModel.gristDoc.get()._undoStack._pointer;
|
||||
`);
|
||||
const start = await undoStackPointer();
|
||||
return async () => undo(await undoStackPointer() - start);
|
||||
const previous = await invariant();
|
||||
return async () => {
|
||||
await undo(await undoStackPointer() - start);
|
||||
assert.deepEqual(await invariant(), previous);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates a transaction on the GristDoc. Use with cautions, as there is no guarantee it will undo correctly
|
||||
* in a case of failure.
|
||||
*
|
||||
* Optionally accepts a function which should return the same result before and after the test.
|
||||
* Example:
|
||||
*
|
||||
* it('should ...', revertChanges(async function() {
|
||||
* ...
|
||||
* }));
|
||||
*/
|
||||
export function revertChanges(test: () => Promise<void>) {
|
||||
export function revertChanges(test: () => Promise<void>, invariant: () => any = () => false) {
|
||||
return async function() {
|
||||
const revert = await begin();
|
||||
const revert = await begin(invariant);
|
||||
try {
|
||||
await test();
|
||||
} finally {
|
||||
@ -1953,6 +1958,24 @@ export async function scrollActiveView(x: number, y: number) {
|
||||
await driver.sleep(10); // wait a bit for the scroll to happen (this is async operation in Grist).
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a column in a Grid using the filter menu.
|
||||
*/
|
||||
export async function filterBy(col: IColHeader|string, save: boolean, values: (string|RegExp)[]) {
|
||||
await openColumnMenu(col, 'Filter');
|
||||
// Select none at start
|
||||
await driver.findContent('.test-filter-menu-bulk-action', /None/).click();
|
||||
for(const value of values) {
|
||||
await driver.findContent('.test-filter-menu-list label', value).click();
|
||||
}
|
||||
// Save filters
|
||||
await driver.find('.test-filter-menu-apply-btn').click();
|
||||
if (save) {
|
||||
await driver.find('.test-section-menu-small-btn-save').click();
|
||||
}
|
||||
await waitForServer();
|
||||
}
|
||||
|
||||
} // end of namespace gristUtils
|
||||
|
||||
stackWrapOwnMethods(gristUtils);
|
||||
|
Loading…
Reference in New Issue
Block a user