(core) Create an extra raw data widget when creating a table

Summary: This is the first step towards raw data views, merely adding metadata without any UI. Every 'normal' table now has a widget referenced by `rawViewSectionRef`. It has no parent view/page and cannot actually be viewed for now. The widget is created during the AddTable user action, and the migration creates a widget for existing tables.

Test Plan: Many tests had to be updated, especially tests that listed all view sections and/or fields.

Reviewers: jarek, dsagal

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3232
pull/126/head
Alex Hall 2 years ago
parent fd957577d3
commit fa9e6eee88

@ -4,7 +4,7 @@ import { GristObjCode } from "app/plugin/GristData";
// tslint:disable:object-literal-key-quotes
export const SCHEMA_VERSION = 25;
export const SCHEMA_VERSION = 26;
export const schema = {
@ -22,6 +22,7 @@ export const schema = {
primaryViewId : "Ref:_grist_Views",
summarySourceTable : "Ref:_grist_Tables",
onDemand : "Bool",
rawViewSectionRef : "Ref:_grist_Views_section",
},
"_grist_Tables_column": {
@ -209,6 +210,7 @@ export interface SchemaTypes {
primaryViewId: number;
summarySourceTable: number;
onDemand: boolean;
rawViewSectionRef: number;
};
"_grist_Tables_column": {

@ -6,8 +6,8 @@ export const GRIST_DOC_SQL = `
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "_grist_DocInfo" (id INTEGER PRIMARY KEY, "docId" TEXT DEFAULT '', "peers" TEXT DEFAULT '', "basketId" TEXT DEFAULT '', "schemaVersion" INTEGER DEFAULT 0, "timezone" TEXT DEFAULT '', "documentSettings" TEXT DEFAULT '');
INSERT INTO _grist_DocInfo VALUES(1,'','','',25,'UTC','{"locale": "en-US"}');
CREATE TABLE IF NOT EXISTS "_grist_Tables" (id INTEGER PRIMARY KEY, "tableId" TEXT DEFAULT '', "primaryViewId" INTEGER DEFAULT 0, "summarySourceTable" INTEGER DEFAULT 0, "onDemand" BOOLEAN DEFAULT 0);
INSERT INTO _grist_DocInfo VALUES(1,'','','',26,'UTC','{"locale": "en-US"}');
CREATE TABLE IF NOT EXISTS "_grist_Tables" (id INTEGER PRIMARY KEY, "tableId" TEXT DEFAULT '', "primaryViewId" INTEGER DEFAULT 0, "summarySourceTable" INTEGER DEFAULT 0, "onDemand" BOOLEAN DEFAULT 0, "rawViewSectionRef" INTEGER DEFAULT 0);
CREATE TABLE IF NOT EXISTS "_grist_Tables_column" (id INTEGER PRIMARY KEY, "parentId" INTEGER DEFAULT 0, "parentPos" NUMERIC DEFAULT 1e999, "colId" TEXT DEFAULT '', "type" TEXT DEFAULT '', "widgetOptions" TEXT DEFAULT '', "isFormula" BOOLEAN DEFAULT 0, "formula" TEXT DEFAULT '', "label" TEXT DEFAULT '', "untieColIdFromLabel" BOOLEAN DEFAULT 0, "summarySourceCol" INTEGER DEFAULT 0, "displayCol" INTEGER DEFAULT 0, "visibleCol" INTEGER DEFAULT 0, "recalcWhen" INTEGER DEFAULT 0, "recalcDeps" TEXT DEFAULT NULL);
CREATE TABLE IF NOT EXISTS "_grist_Imports" (id INTEGER PRIMARY KEY, "tableRef" INTEGER DEFAULT 0, "origFileName" TEXT DEFAULT '', "parseFormula" TEXT DEFAULT '', "delimiter" TEXT DEFAULT '', "doublequote" BOOLEAN DEFAULT 0, "escapechar" TEXT DEFAULT '', "quotechar" TEXT DEFAULT '', "skipinitialspace" BOOLEAN DEFAULT 0, "encoding" TEXT DEFAULT '', "hasHeaders" BOOLEAN DEFAULT 0);
CREATE TABLE IF NOT EXISTS "_grist_External_database" (id INTEGER PRIMARY KEY, "host" TEXT DEFAULT '', "port" INTEGER DEFAULT 0, "username" TEXT DEFAULT '', "dialect" TEXT DEFAULT '', "database" TEXT DEFAULT '', "storage" TEXT DEFAULT '');
@ -41,9 +41,9 @@ export const GRIST_DOC_WITH_TABLE1_SQL = `
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "_grist_DocInfo" (id INTEGER PRIMARY KEY, "docId" TEXT DEFAULT '', "peers" TEXT DEFAULT '', "basketId" TEXT DEFAULT '', "schemaVersion" INTEGER DEFAULT 0, "timezone" TEXT DEFAULT '', "documentSettings" TEXT DEFAULT '');
INSERT INTO _grist_DocInfo VALUES(1,'','','',25,'UTC','{"locale": "en-US"}');
CREATE TABLE IF NOT EXISTS "_grist_Tables" (id INTEGER PRIMARY KEY, "tableId" TEXT DEFAULT '', "primaryViewId" INTEGER DEFAULT 0, "summarySourceTable" INTEGER DEFAULT 0, "onDemand" BOOLEAN DEFAULT 0);
INSERT INTO _grist_Tables VALUES(1,'Table1',1,0,0);
INSERT INTO _grist_DocInfo VALUES(1,'','','',26,'UTC','{"locale": "en-US"}');
CREATE TABLE IF NOT EXISTS "_grist_Tables" (id INTEGER PRIMARY KEY, "tableId" TEXT DEFAULT '', "primaryViewId" INTEGER DEFAULT 0, "summarySourceTable" INTEGER DEFAULT 0, "onDemand" BOOLEAN DEFAULT 0, "rawViewSectionRef" INTEGER DEFAULT 0);
INSERT INTO _grist_Tables VALUES(1,'Table1',1,0,0,2);
CREATE TABLE IF NOT EXISTS "_grist_Tables_column" (id INTEGER PRIMARY KEY, "parentId" INTEGER DEFAULT 0, "parentPos" NUMERIC DEFAULT 1e999, "colId" TEXT DEFAULT '', "type" TEXT DEFAULT '', "widgetOptions" TEXT DEFAULT '', "isFormula" BOOLEAN DEFAULT 0, "formula" TEXT DEFAULT '', "label" TEXT DEFAULT '', "untieColIdFromLabel" BOOLEAN DEFAULT 0, "summarySourceCol" INTEGER DEFAULT 0, "displayCol" INTEGER DEFAULT 0, "visibleCol" INTEGER DEFAULT 0, "recalcWhen" INTEGER DEFAULT 0, "recalcDeps" TEXT DEFAULT NULL);
INSERT INTO _grist_Tables_column VALUES(1,1,1,'manualSort','ManualSortPos','',0,'','manualSort',0,0,0,0,0,NULL);
INSERT INTO _grist_Tables_column VALUES(2,1,2,'A','Any','',1,'','A',0,0,0,0,0,NULL);
@ -62,10 +62,14 @@ CREATE TABLE IF NOT EXISTS "_grist_Views" (id INTEGER PRIMARY KEY, "name" TEXT D
INSERT INTO _grist_Views VALUES(1,'Table1','raw_data','');
CREATE TABLE IF NOT EXISTS "_grist_Views_section" (id INTEGER PRIMARY KEY, "tableRef" INTEGER DEFAULT 0, "parentId" INTEGER DEFAULT 0, "parentKey" TEXT DEFAULT '', "title" TEXT DEFAULT '', "defaultWidth" INTEGER DEFAULT 0, "borderWidth" INTEGER DEFAULT 0, "theme" TEXT DEFAULT '', "options" TEXT DEFAULT '', "chartType" TEXT DEFAULT '', "layoutSpec" TEXT DEFAULT '', "filterSpec" TEXT DEFAULT '', "sortColRefs" TEXT DEFAULT '', "linkSrcSectionRef" INTEGER DEFAULT 0, "linkSrcColRef" INTEGER DEFAULT 0, "linkTargetColRef" INTEGER DEFAULT 0, "embedId" TEXT DEFAULT '');
INSERT INTO _grist_Views_section VALUES(1,1,1,'record','',100,1,'','','','','','[]',0,0,0,'');
INSERT INTO _grist_Views_section VALUES(2,1,0,'record','',100,1,'','','','','','',0,0,0,'');
CREATE TABLE IF NOT EXISTS "_grist_Views_section_field" (id INTEGER PRIMARY KEY, "parentId" INTEGER DEFAULT 0, "parentPos" NUMERIC DEFAULT 1e999, "colRef" INTEGER DEFAULT 0, "width" INTEGER DEFAULT 0, "widgetOptions" TEXT DEFAULT '', "displayCol" INTEGER DEFAULT 0, "visibleCol" INTEGER DEFAULT 0, "filter" TEXT DEFAULT '');
INSERT INTO _grist_Views_section_field VALUES(1,1,1,2,0,'',0,0,'');
INSERT INTO _grist_Views_section_field VALUES(2,1,2,3,0,'',0,0,'');
INSERT INTO _grist_Views_section_field VALUES(3,1,3,4,0,'',0,0,'');
INSERT INTO _grist_Views_section_field VALUES(4,2,4,2,0,'',0,0,'');
INSERT INTO _grist_Views_section_field VALUES(5,2,5,3,0,'',0,0,'');
INSERT INTO _grist_Views_section_field VALUES(6,2,6,4,0,'',0,0,'');
CREATE TABLE IF NOT EXISTS "_grist_Validations" (id INTEGER PRIMARY KEY, "formula" TEXT DEFAULT '', "name" TEXT DEFAULT '', "tableRef" INTEGER DEFAULT 0);
CREATE TABLE IF NOT EXISTS "_grist_REPL_Hist" (id INTEGER PRIMARY KEY, "code" TEXT DEFAULT '', "outputText" TEXT DEFAULT '', "errorText" TEXT DEFAULT '');
CREATE TABLE IF NOT EXISTS "_grist_Attachments" (id INTEGER PRIMARY KEY, "fileIdent" TEXT DEFAULT '', "fileName" TEXT DEFAULT '', "fileType" TEXT DEFAULT '', "fileSize" INTEGER DEFAULT 0, "imageHeight" INTEGER DEFAULT 0, "imageWidth" INTEGER DEFAULT 0, "timeUploaded" DATETIME DEFAULT NULL);

@ -193,13 +193,11 @@ class ImportActions(object):
# ======== Cleanup old sections/columns
# Transform sections are created without a parent View, so we delete all such sections here.
old_sections = [s for s in src_table_rec.viewSections if not s.parentId]
self._docmodel.remove(old_sections)
# Transform columns are those that start with a special prefix.
old_cols = [c for c in src_table_rec.columns
if c.colId.startswith(_import_transform_col_prefix)]
old_sections = {field.parentId for c in old_cols for field in c.viewFields}
self._docmodel.remove(old_sections)
self._docmodel.remove(old_cols)
#======== Prepare/normalize transform_rule, Create new formula columns

@ -10,6 +10,8 @@ import schema
import summary
import table_data_set
import logger
from column import is_visible_column
log = logger.Logger(__name__, logger.INFO)
# PHILOSOPHY OF MIGRATIONS.
@ -840,3 +842,59 @@ def migration25(tdset):
doc_actions.append(actions.BulkAddRecord('_grist_Filters', [None] * num_filters, col_info))
return tdset.apply_doc_actions(doc_actions)
@migration(schema_version=26)
def migration26(tdset):
"""
Add rawViewSectionRef column to _grist_Tables
and new raw view sections for each 'normal' table.
"""
doc_actions = [add_column('_grist_Tables', 'rawViewSectionRef', 'Ref:_grist_Views_section')]
tables = list(actions.transpose_bulk_action(tdset.all_tables["_grist_Tables"]))
columns = list(actions.transpose_bulk_action(tdset.all_tables["_grist_Tables_column"]))
views = {view.id: view
for view in actions.transpose_bulk_action(tdset.all_tables["_grist_Views"])}
new_view_section_id = next_id(tdset, "_grist_Views_section")
for table in sorted(tables, key=lambda t: t.tableId):
old_view = views.get(table.primaryViewId)
if not (table.primaryViewId and old_view):
continue
table_columns = [
col for col in columns
if table.id == col.parentId and is_visible_column(col.colId)
]
table_columns.sort(key=lambda c: c.parentPos)
fields = {
"parentId": [new_view_section_id] * len(table_columns),
"colRef": [col.id for col in table_columns],
"parentPos": [col.parentPos for col in table_columns],
}
field_ids = [None] * len(table_columns)
doc_actions += [
actions.AddRecord(
"_grist_Views_section", new_view_section_id, {
"tableRef": table.id,
"parentId": 0,
"parentKey": "record",
"title": old_view.name,
"defaultWidth": 100,
"borderWidth": 1,
}),
actions.UpdateRecord(
"_grist_Tables", table.id, {
"rawViewSectionRef": new_view_section_id,
}),
actions.BulkAddRecord(
"_grist_Views_section_field", field_ids, fields
),
]
new_view_section_id += 1
return tdset.apply_doc_actions(doc_actions)

@ -15,7 +15,7 @@ import six
import actions
SCHEMA_VERSION = 25
SCHEMA_VERSION = 26
def make_column(col_id, col_type, formula='', isFormula=False):
return {
@ -55,7 +55,9 @@ def schema_create_actions():
# A table may be marked as "onDemand", which will keep its data out of the data engine, and
# only available to the frontend when requested.
make_column("onDemand", "Bool")
make_column("onDemand", "Bool"),
make_column("rawViewSectionRef", "Ref:_grist_Views_section"),
]),
# All columns in all user tables.

@ -222,15 +222,15 @@ class TestColumnActions(test_engine.EngineTestCase):
Field(2, colRef=12),
Field(3, colRef=13),
]),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=15),
Field(8, colRef=16),
Field(9, colRef=17),
Section(4, parentKey="record", tableRef=2, fields=[
Field(10, colRef=15),
Field(11, colRef=16),
Field(12, colRef=17),
]),
Section(4, parentKey="record", tableRef=3, fields=[
Field(10, colRef=18),
Field(11, colRef=20),
Field(12, colRef=21),
Section(5, parentKey="record", tableRef=3, fields=[
Field(13, colRef=18),
Field(14, colRef=20),
Field(15, colRef=21),
]),
]),
View(2, sections=[
@ -310,14 +310,14 @@ class TestColumnActions(test_engine.EngineTestCase):
Field(2, colRef=12),
Field(3, colRef=13),
]),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=15),
Field(9, colRef=17),
Section(4, parentKey="record", tableRef=2, fields=[
Field(10, colRef=15),
Field(12, colRef=17),
]),
Section(4, parentKey="record", tableRef=3, fields=[
Field(10, colRef=18),
Field(11, colRef=20),
Field(12, colRef=21),
Section(5, parentKey="record", tableRef=3, fields=[
Field(13, colRef=18),
Field(14, colRef=20),
Field(15, colRef=21),
]),
]),
View(2, sections=[
@ -367,13 +367,13 @@ class TestColumnActions(test_engine.EngineTestCase):
Section(1, parentKey="record", tableRef=1, fields=[
Field(3, colRef=13),
]),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=15),
Field(9, colRef=17),
Section(4, parentKey="record", tableRef=2, fields=[
Field(10, colRef=15),
Field(12, colRef=17),
]),
Section(4, parentKey="record", tableRef=4, fields=[
Field(11, colRef=22),
Field(12, colRef=23),
Section(5, parentKey="record", tableRef=4, fields=[
Field(14, colRef=22),
Field(15, colRef=23),
]),
]),
View(2, sections=[

@ -52,6 +52,7 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 0],
[2, 25, 0],
])
self.assertTableData("Favorites", cols="subset", data=[
["id", "favorite"],
@ -67,7 +68,8 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 0],
[2, 25, 0]
[2, 25, 0],
[3, 25, 0],
])
# Set display formula for 'favorite' column.
@ -84,7 +86,7 @@ class TestUserActions(test_engine.EngineTestCase):
# A single "gristHelper_Display2" column should be added with the requested formula, since both
# require the same formula. The fields' colRefs should be set to the new column.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 1, None, '$favorite.network'])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 2, None, '$favorite.network'])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 3, None, '$favorite.network'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
@ -94,13 +96,14 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 27]
[2, 25, 0],
[3, 25, 27],
])
# Change display formula for a field.
# Since the field is changing to use a formula not yet held by a display column,
# a new display column should be added with the desired formula.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 2, None, '$favorite.viewers'])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 3, None, '$favorite.viewers'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
@ -111,13 +114,14 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 28]
[2, 25, 0],
[3, 25, 28],
])
# Remove a field.
# This should also remove the display column used by that field, since it is not used
# by any other fields.
self.apply_user_action(['RemoveRecord', '_grist_Views_section_field', 2])
self.apply_user_action(['RemoveRecord', '_grist_Views_section_field', 3])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
@ -126,7 +130,8 @@ class TestUserActions(test_engine.EngineTestCase):
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27]
[1, 25, 27],
[2, 25, 0],
])
# Add a new column with a formula.
@ -140,7 +145,7 @@ class TestUserActions(test_engine.EngineTestCase):
'parentId': 2,
'colRef': 25
}])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 4, None, '$favorite.viewers'])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 6, None, '$favorite.viewers'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
@ -152,16 +157,18 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 28, 0], # fav_viewers field
[2, 25, 0],
[3, 28, 0], # fav_viewers field
[4, 25, 29] # re-added field w/ display col
[4, 28, 0], # fav_viewers field
[5, 28, 0], # fav_viewers field
[6, 25, 29] # re-added field w/ display col
])
# Change the display formula for a field to be the same as the other field, then remove
# the field.
# The display column should not be removed since it is still in use.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 4, None, '$favorite.network'])
self.apply_user_action(['RemoveRecord', '_grist_Views_section_field', 4])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 6, None, '$favorite.network'])
self.apply_user_action(['RemoveRecord', '_grist_Views_section_field', 6])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
@ -172,8 +179,10 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 28, 0],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Clear field display formula, then set it again.
@ -189,8 +198,10 @@ class TestUserActions(test_engine.EngineTestCase):
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 0],
[2, 28, 0],
[3, 28, 0]
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Setting the display formula should add another display column.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 1, None, '$favorite.viewers'])
@ -203,9 +214,11 @@ class TestUserActions(test_engine.EngineTestCase):
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 28, 0],
[3, 28, 0]
[1, 25, 29],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Change column display formula.
@ -220,9 +233,11 @@ class TestUserActions(test_engine.EngineTestCase):
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 28, 0],
[3, 28, 0]
[1, 25, 29],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Remove column.
@ -234,8 +249,9 @@ class TestUserActions(test_engine.EngineTestCase):
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[2, 28, 0],
[3, 28, 0]
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
@ -337,7 +353,8 @@ class TestUserActions(test_engine.EngineTestCase):
]
self.assertTables(expected_tables1)
self.assertTableData("People", cols="subset", data=expected_data1)
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef", "displayCol"],
[1, 1, 25, 0],
[2, 1, 26, 28],
@ -354,7 +371,8 @@ class TestUserActions(test_engine.EngineTestCase):
Column(25, "name", "Text", False, "", 0),
]),
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef", "displayCol"],
[1, 1, 25, 0],
])
@ -363,7 +381,7 @@ class TestUserActions(test_engine.EngineTestCase):
# pylint:disable=line-too-long
self.assertOutActions(out_actions, {
"stored": [
["RemoveRecord", "_grist_Views_section_field", 2],
["BulkRemoveRecord", "_grist_Views_section_field", [2, 4]],
["BulkRemoveRecord", "_grist_Tables_column", [26, 27]],
["RemoveColumn", "People", "favorite"],
["RemoveColumn", "People", "gristHelper_Display"],
@ -374,7 +392,7 @@ class TestUserActions(test_engine.EngineTestCase):
"undo": [
["BulkUpdateRecord", "People", [1, 2, 3], {"gristHelper_Display2": ["Netflix", "HBO", "NBC"]}],
["BulkUpdateRecord", "People", [1, 2, 3], {"gristHelper_Display": ["Narcos", "Game of Thrones", "Today"]}],
["AddRecord", "_grist_Views_section_field", 2, {"colRef": 26, "displayCol": 28, "parentId": 1, "parentPos": 2.0}],
["BulkAddRecord", "_grist_Views_section_field", [2, 4], {"colRef": [26, 26], "displayCol": [28, 0], "parentId": [1, 2], "parentPos": [2.0, 4.0]}],
["BulkAddRecord", "_grist_Tables_column", [26, 27], {"colId": ["favorite", "gristHelper_Display"], "displayCol": [27, 0], "formula": ["", "$favorite.show"], "isFormula": [False, True], "label": ["favorite", "gristHelper_Display"], "parentId": [2, 2], "parentPos": [6.0, 7.0], "type": ["Ref:Television", "Any"], "widgetOptions": ["\"{\"alignment\":\"center\",\"visibleCol\":\"show\"}\"", ""]}],
["BulkUpdateRecord", "People", [1, 2, 3], {"favorite": [12, 11, 13]}],
["AddColumn", "People", "favorite", {"formula": "", "isFormula": False, "type": "Ref:Television"}],
@ -390,7 +408,8 @@ class TestUserActions(test_engine.EngineTestCase):
out_actions = self.apply_user_action(['ApplyUndoActions', undo_actions])
self.assertTables(expected_tables1)
self.assertTableData("People", cols="subset", data=expected_data1)
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef", "displayCol"],
[1, 1, 25, 0],
[2, 1, 26, 28],
@ -528,7 +547,8 @@ class TestUserActions(test_engine.EngineTestCase):
[28, "gristHelper_Display", 2, 0, "$favorite.show"],
[29, "gristHelper_Display2", 2, 0, "$favorite.network"]
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 26, 0],
@ -593,7 +613,8 @@ class TestUserActions(test_engine.EngineTestCase):
[28, "gristHelper_Display", 2, 0, "$favorite.show"],
[29, "gristHelper_Display2", 2, 0, "$favorite.network"]
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 26, 0],

@ -140,9 +140,11 @@ class TestDocModel(test_engine.EngineTestCase):
])
self.assertPartialData('_grist_Views_section', ["id", "parentId", "tableRef"], [
[1, 1, 4],
[2, 2, 5],
[3, 1, 4],
[4, 1, 5],
[2, 0, 4],
[3, 2, 5],
[4, 0, 5],
[5, 1, 4],
[6, 1, 5],
])
self.assertPartialData('_grist_Views_section_field', ["id", "parentId", "parentPos"], [
[1, 1, 1.0],
@ -153,18 +155,22 @@ class TestDocModel(test_engine.EngineTestCase):
[6, 3, 6.0],
[7, 4, 7.0],
[8, 4, 8.0],
[9, 5, 9.0],
[10, 5, 10.0],
[11, 6, 11.0],
[12, 6, 12.0],
])
table = self.engine.docmodel.tables.lookupOne(tableId='Test2')
self.assertRecordSet(table.viewSections, [1,3])
self.assertRecordSet(list(table.viewSections)[0].fields, [1,2])
self.assertRecordSet(list(table.viewSections)[1].fields, [5,6])
self.assertRecordSet(table.viewSections, [1, 2, 5])
self.assertRecordSet(list(table.viewSections)[0].fields, [1, 2])
self.assertRecordSet(list(table.viewSections)[2].fields, [9, 10])
view = self.engine.docmodel.views.lookupOne(id=1)
self.assertRecordSet(view.viewSections, [1,3,4])
self.assertRecordSet(view.viewSections, [1, 5, 6])
self.engine.docmodel.remove(f for vs in table.viewSections for f in vs.fields)
self.engine.docmodel.remove(table.viewSections)
self.assertRecordSet(view.viewSections, [4])
self.assertRecordSet(view.viewSections, [6])
def test_modifications(self):

@ -280,11 +280,15 @@ class EngineTestCase(unittest.TestCase):
"""
self.assertPartialData('_grist_Views', ["id"],
[[view.id] for view in list_of_views])
self.assertPartialData('_grist_Views_section', ["id", "parentId", "parentKey", "tableRef"],
sorted((sec.id, view.id, sec.parentKey, sec.tableRef)
for view in list_of_views
for sec in view.sections))
self.assertTableData('_grist_Views_section',
rows=lambda r: r.parentId,
cols="subset",
data=[["id", "parentId", "parentKey", "tableRef"]] + sorted(
(sec.id, view.id, sec.parentKey, sec.tableRef)
for view in list_of_views
for sec in view.sections))
self.assertTableData('_grist_Views_section_field', sort=(lambda r: r.parentPos),
rows=lambda r: r.parentId.parentId,
cols="subset",
data=[["id", "parentId", "colRef"]] + sorted(
((field.id, sec.id, field.colRef)

@ -53,8 +53,11 @@ class TestImportActions(test_engine.EngineTestCase):
# Verify created sections
self.assertPartialData("_grist_Views_section", ["id", "tableRef", 'fields'], [
[1, 1, [1, 2, 3]], # section for "Source" table
[2, 2, [4, 5]], # section for "Destination1" table
[3, 3, [6]] # section for "Destination2" table
[2, 1, [4, 5, 6]], # section for "Source" table
[3, 2, [7, 8]], # section for "Destination1" table
[4, 2, [9, 10]], # section for "Destination1" table
[5, 3, [11]], # section for "Destination2" table
[6, 3, [12]], # section for "Destination2" table
])
def test_transform(self):
@ -85,9 +88,12 @@ class TestImportActions(test_engine.EngineTestCase):
self.assertPartialData("_grist_Views_section", ["id", "tableRef", 'fields'], [
[1, 1, [1, 2, 3]],
[2, 2, [4, 5]],
[3, 3, [6]],
[4, 1, [7, 8]] # new section for transform preview
[2, 1, [4, 5, 6]],
[3, 2, [7, 8]],
[4, 2, [9, 10]],
[5, 3, [11]],
[6, 3, [12]],
[7, 1, [13, 14]], # new section for transform preview
])
# Apply useraction again to verify that old columns and sections are removing
@ -112,9 +118,12 @@ class TestImportActions(test_engine.EngineTestCase):
])
self.assertPartialData("_grist_Views_section", ["id", "tableRef", 'fields'], [
[1, 1, [1, 2, 3]],
[2, 2, [4, 5]],
[3, 3, [6]],
[4, 1, [7]] # new section for transform preview
[2, 1, [4, 5, 6]],
[3, 2, [7, 8]],
[4, 2, [9, 10]],
[5, 3, [11]],
[6, 3, [12]],
[7, 1, [13]], # new section for transform preview
])
@ -126,8 +135,8 @@ class TestImportActions(test_engine.EngineTestCase):
out_actions = self.apply_user_action(['GenImporterView', 'Source', 'Destination1', None])
self.assertPartialOutActions(out_actions, {
"stored": [
["BulkRemoveRecord", "_grist_Views_section_field", [7, 8, 9]],
["RemoveRecord", "_grist_Views_section", 4],
["BulkRemoveRecord", "_grist_Views_section_field", [13, 14, 15]],
["RemoveRecord", "_grist_Views_section", 7],
["BulkRemoveRecord", "_grist_Tables_column", [10, 11, 12]],
["RemoveColumn", "Source", "gristHelper_Import_Name"],
["RemoveColumn", "Source", "gristHelper_Import_City"],
@ -136,8 +145,8 @@ class TestImportActions(test_engine.EngineTestCase):
["AddRecord", "_grist_Tables_column", 10, {"colId": "gristHelper_Import_Name", "formula": "$Name", "isFormula": True, "label": "Name", "parentId": 1, "parentPos": 10.0, "type": "Text", "widgetOptions": ""}],
["AddColumn", "Source", "gristHelper_Import_City", {"formula": "$City", "isFormula": True, "type": "Text"}],
["AddRecord", "_grist_Tables_column", 11, {"colId": "gristHelper_Import_City", "formula": "$City", "isFormula": True, "label": "City", "parentId": 1, "parentPos": 11.0, "type": "Text", "widgetOptions": ""}],
["AddRecord", "_grist_Views_section", 4, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "sortColRefs": "[]", "tableRef": 1}],
["BulkAddRecord", "_grist_Views_section_field", [7, 8], {"colRef": [10, 11], "parentId": [4, 4], "parentPos": [7.0, 8.0]}],
["AddRecord", "_grist_Views_section", 7, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "sortColRefs": "[]", "tableRef": 1}],
["BulkAddRecord", "_grist_Views_section_field", [13, 14], {"colRef": [10, 11], "parentId": [7, 7], "parentPos": [13.0, 14.0]}],
# The actions to populate the removed and re-added columns should be there.
["BulkUpdateRecord", "Source", [1, 2], {"gristHelper_Import_City": ["New York", "Boston"]}],
["BulkUpdateRecord", "Source", [1, 2], {"gristHelper_Import_Name": ["John", "Alison"]}],
@ -173,7 +182,10 @@ class TestImportActions(test_engine.EngineTestCase):
])
self.assertPartialData("_grist_Views_section", ["id", "tableRef", 'fields'], [
[1, 1, [1, 2, 3]],
[2, 2, [4, 5]],
[3, 3, [6]],
[4, 1, [7, 8, 9]], # new section for transform preview
[2, 1, [4, 5, 6]],
[3, 2, [7, 8]],
[4, 2, [9, 10]],
[5, 3, [11]],
[6, 3, [12]],
[7, 1, [13, 14, 15]], # new section for transform preview
])

@ -927,13 +927,14 @@ class TestSummary2(test_engine.EngineTestCase):
]),
])
# We should now have two sections for table 2 (the one with two group-by fields).
self.assertTableData('_grist_Views_section', cols="subset", data=[
self.assertTableData('_grist_Views_section', cols="subset", rows=lambda r: r.parentId, data=[
["id", "parentId", "tableRef"],
[1, 1, 4],
[2, 2, 3],
[3, 3, 4],
])
self.assertTableData('_grist_Views_section_field', cols="subset", data=[
self.assertTableData(
'_grist_Views_section_field', cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef"],
[1, 1, 24],
[2, 1, 25],

@ -88,27 +88,27 @@ class TestTableActions(test_engine.EngineTestCase):
]),
]),
View(2, sections=[
Section(2, parentKey="record", tableRef=2, fields=[
Field(4, colRef=6),
Field(5, colRef=7),
Field(6, colRef=8),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=6),
Field(8, colRef=7),
Field(9, colRef=8),
]),
]),
View(3, sections=[
Section(3, parentKey="record", tableRef=1, fields=[
Field(7, colRef=2),
Field(8, colRef=3),
Field(9, colRef=4),
Section(5, parentKey="record", tableRef=1, fields=[
Field(13, colRef=2),
Field(14, colRef=3),
Field(15, colRef=4),
]),
Section(4, parentKey="record", tableRef=3, fields=[
Field(10, colRef=9),
Field(11, colRef=11),
Field(12, colRef=12),
Section(6, parentKey="record", tableRef=3, fields=[
Field(16, colRef=9),
Field(17, colRef=11),
Field(18, colRef=12),
]),
Section(5, parentKey="record", tableRef=2, fields=[
Field(13, colRef=6),
Field(14, colRef=7),
Field(15, colRef=8),
Section(7, parentKey="record", tableRef=2, fields=[
Field(19, colRef=6),
Field(20, colRef=7),
Field(21, colRef=8),
]),
]),
])
@ -294,15 +294,15 @@ class TestTableActions(test_engine.EngineTestCase):
])
self.assertViews([
View(2, sections=[
Section(2, parentKey="record", tableRef=2, fields=[
Field(4, colRef=6),
Field(6, colRef=8),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=6),
Field(9, colRef=8),
]),
]),
View(3, sections=[
Section(5, parentKey="record", tableRef=2, fields=[
Field(13, colRef=6),
Field(15, colRef=8),
Section(7, parentKey="record", tableRef=2, fields=[
Field(19, colRef=6),
Field(21, colRef=8),
]),
]),
])

@ -54,7 +54,8 @@ class TestUserActions(test_engine.EngineTestCase):
[23, "city", 2, 3.0, ""],
])
self.assertPartialData("_grist_Views_section_field", ["id", "colRef", "widgetOptions"], [
[1, 23, ""]
[1, 23, ""],
[2, 23, ""],
])
self.assertPartialData("Schools", ["id", "city"], [
[1, "New York" ],
@ -75,8 +76,11 @@ class TestUserActions(test_engine.EngineTestCase):
'grist_Transform', 'formula': 'return $city', 'label': 'grist_Transform',
'type': 'Text'
}],
["AddRecord", "_grist_Views_section_field", 2, {
"colRef": 24, "parentId": 1, "parentPos": 2.0
["AddRecord", "_grist_Views_section_field", 3, {
"colRef": 24, "parentId": 1, "parentPos": 3.0
}],
["AddRecord", "_grist_Views_section_field", 4, {
"colRef": 24, "parentId": 2, "parentPos": 4.0
}],
["BulkUpdateRecord", "Schools", [1, 2, 3],
{"grist_Transform": ["New York", "Colombia", "New York"]}],
@ -120,7 +124,7 @@ class TestUserActions(test_engine.EngineTestCase):
out_actions = self.remove_column('Schools', 'grist_Transform')
self.assertPartialOutActions(out_actions, { "stored": [
['RemoveRecord', '_grist_Views_section_field', 2],
["BulkRemoveRecord", "_grist_Views_section_field", [3, 4]],
['RemoveRecord', '_grist_Tables_column', 24],
['RemoveColumn', 'Schools', 'grist_Transform'],
]})
@ -210,10 +214,10 @@ class TestUserActions(test_engine.EngineTestCase):
])
])
new_view = View(2, sections=[
Section(2, parentKey="record", tableRef=2, fields=[
Field(4, colRef=23),
Field(5, colRef=24),
Field(6, colRef=25),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=23),
Field(8, colRef=24),
Field(9, colRef=25),
])
])
self.assertTables([self.starting_table, new_table])
@ -228,18 +232,18 @@ class TestUserActions(test_engine.EngineTestCase):
Column(29, "C", "Any", isFormula=True, formula="", summarySourceCol=0),
])
primary_view2 = View(3, sections=[
Section(3, parentKey="record", tableRef=3, fields=[
Field(7, colRef=27),
Field(8, colRef=28),
Field(9, colRef=29),
])
])
new_view.sections.append(
Section(4, parentKey="record", tableRef=3, fields=[
Field(10, colRef=27),
Field(11, colRef=28),
Field(12, colRef=29),
])
])
new_view.sections.append(
Section(6, parentKey="record", tableRef=3, fields=[
Field(16, colRef=27),
Field(17, colRef=28),
Field(18, colRef=29),
])
)
# Check that we have a new table, only the primary view as new view; and a new section.
self.assertTables([self.starting_table, new_table, new_table2])
@ -269,15 +273,15 @@ class TestUserActions(test_engine.EngineTestCase):
])
# The primary view of the new table.
primary_view3 = View(4, sections=[
Section(5, parentKey="record", tableRef=4, fields=[
Field(13, colRef=31),
Field(14, colRef=32),
Field(15, colRef=33),
Section(7, parentKey="record", tableRef=4, fields=[
Field(19, colRef=31),
Field(20, colRef=32),
Field(21, colRef=33),
])
])
# And a new view section for the summary.
new_view.sections.append(Section(6, parentKey="record", tableRef=5, fields=[
Field(16, colRef=35)
new_view.sections.append(Section(9, parentKey="record", tableRef=5, fields=[
Field(25, colRef=35)
]))
self.assertTables([self.starting_table, new_table, new_table2, new_table3, summary_table])
self.assertViews([primary_view, new_view, primary_view2, primary_view3])
@ -332,33 +336,33 @@ class TestUserActions(test_engine.EngineTestCase):
]),
]),
View(2, sections=[
Section(2, parentKey="detail", tableRef=1, fields=[
Field(4, colRef=2),
Field(5, colRef=3),
Field(6, colRef=4),
Section(3, parentKey="detail", tableRef=1, fields=[
Field(7, colRef=2),
Field(8, colRef=3),
Field(9, colRef=4),
]),
Section(3, parentKey="record", tableRef=2, fields=[
Field(7, colRef=5),
Field(8, colRef=7),
Field(9, colRef=8),
Section(4, parentKey="record", tableRef=2, fields=[
Field(10, colRef=5),
Field(11, colRef=7),
Field(12, colRef=8),
]),
Section(6, parentKey='record', tableRef=3, fields=[
Field(15, colRef=10),
Field(16, colRef=11),
Field(17, colRef=12),
Section(8, parentKey='record', tableRef=3, fields=[
Field(21, colRef=10),
Field(22, colRef=11),
Field(23, colRef=12),
]),
]),
View(3, sections=[
Section(4, parentKey="chart", tableRef=1, fields=[
Field(10, colRef=2),
Field(11, colRef=3),
Section(5, parentKey="chart", tableRef=1, fields=[
Field(13, colRef=2),
Field(14, colRef=3),
]),
]),
View(4, sections=[
Section(5, parentKey='record', tableRef=3, fields=[
Field(12, colRef=10),
Field(13, colRef=11),
Field(14, colRef=12),
Section(6, parentKey='record', tableRef=3, fields=[
Field(15, colRef=10),
Field(16, colRef=11),
Field(17, colRef=12),
]),
]),
])
@ -411,10 +415,10 @@ class TestUserActions(test_engine.EngineTestCase):
]),
]),
View(4, sections=[
Section(5, parentKey='record', tableRef=3, fields=[
Field(12, colRef=10),
Field(13, colRef=11),
Field(14, colRef=12),
Section(6, parentKey='record', tableRef=3, fields=[
Field(15, colRef=10),
Field(16, colRef=11),
Field(17, colRef=12),
]),
]),
])
@ -474,7 +478,7 @@ class TestUserActions(test_engine.EngineTestCase):
self.init_views_sample()
# Remove a couple of sections. Ensure their fields get removed.
self.apply_user_action(['BulkRemoveRecord', '_grist_Views_section', [3,6]])
self.apply_user_action(['BulkRemoveRecord', '_grist_Views_section', [4, 8]])
self.assertViews([
View(1, sections=[
@ -485,23 +489,23 @@ class TestUserActions(test_engine.EngineTestCase):
]),
]),
View(2, sections=[
Section(2, parentKey="detail", tableRef=1, fields=[
Field(4, colRef=2),
Field(5, colRef=3),
Field(6, colRef=4),
Section(3, parentKey="detail", tableRef=1, fields=[
Field(7, colRef=2),
Field(8, colRef=3),
Field(9, colRef=4),
]),
]),
View(3, sections=[
Section(4, parentKey="chart", tableRef=1, fields=[
Field(10, colRef=2),
Field(11, colRef=3),
Section(5, parentKey="chart", tableRef=1, fields=[
Field(13, colRef=2),
Field(14, colRef=3),
]),
]),
View(4, sections=[
Section(5, parentKey='record', tableRef=3, fields=[
Field(12, colRef=10),
Field(13, colRef=11),
Field(14, colRef=12),
Section(6, parentKey='record', tableRef=3, fields=[
Field(15, colRef=10),
Field(16, colRef=11),
Field(17, colRef=12),
]),
]),
])

@ -914,7 +914,11 @@
"parentId": 1, "parentKey": "record", "sortColRefs": "[]", "title": "" }],
["AddRecord", "_grist_Views_section_field", 1,
{"parentId": 1, "colRef": 34, "parentPos": 1.0}],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1}],
// Raw data widget
["AddRecord", "_grist_Views_section", 2, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "tableRef": 4}],
["AddRecord", "_grist_Views_section_field", 2, {"colRef": 34, "parentId": 2, "parentPos": 2.0}],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1, "rawViewSectionRef": 2}],
// Actions generated from AddColumn.
["AddColumn", "Bar", "world",
@ -923,9 +927,10 @@
{"colId": "world", "parentPos": 13.0,
"formula": "rec.hello.upper()", "parentId": 4, "type": "Text",
"isFormula": true, "label": "world", "widgetOptions": ""}],
["AddRecord", "_grist_Views_section_field", 2, {"colRef": 35, "parentId": 1, "parentPos": 2.0}]
["AddRecord", "_grist_Views_section_field", 3, {"colRef": 35, "parentId": 1, "parentPos": 3.0}],
["AddRecord", "_grist_Views_section_field", 4, {"colRef": 35, "parentId": 2, "parentPos": 4.0}]
],
"direct": [true, true,
"direct": [true, true, true, true, true,
true, true, true, true, true, true, true,
true, true, true],
"undo": [
@ -937,10 +942,13 @@
["RemoveRecord", "_grist_Pages", 1],
["RemoveRecord", "_grist_Views_section", 1],
["RemoveRecord", "_grist_Views_section_field", 1],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0}],
["RemoveRecord", "_grist_Views_section", 2],
["RemoveRecord", "_grist_Views_section_field", 2],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0, "rawViewSectionRef": 0}],
["RemoveColumn", "Bar", "world"],
["RemoveRecord", "_grist_Tables_column", 35],
["RemoveRecord", "_grist_Views_section_field", 2]
["RemoveRecord", "_grist_Views_section_field", 3],
["RemoveRecord", "_grist_Views_section_field", 4]
],
"retValue": [
{
@ -1249,13 +1257,16 @@
"parentId": 1, "parentKey": "record", "sortColRefs": "[]", "title": ""}],
["BulkAddRecord", "_grist_Views_section_field", [1,2],
{"parentId": [1,1], "colRef": [31,32], "parentPos": [1.0,2.0]}],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1}],
["RemoveRecord", "_grist_Views_section_field", 1],
["AddRecord", "_grist_Views_section", 2, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "tableRef": 4}],
["BulkAddRecord", "_grist_Views_section_field", [3, 4], {"colRef": [31, 32], "parentId": [2, 2], "parentPos": [3.0, 4.0]}],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1, "rawViewSectionRef": 2}],
["BulkRemoveRecord", "_grist_Views_section_field", [1, 3]],
["RemoveRecord", "_grist_Tables_column", 31],
["RemoveColumn", "ViewTest", "hello"]
],
"direct": [true, true, true, true, true, true, true, true, true,
true, true,
true, true, true],
"undo": [
["RemoveTable", "ViewTest"],
@ -1266,9 +1277,10 @@
["RemoveRecord", "_grist_Pages", 1],
["RemoveRecord", "_grist_Views_section", 1],
["BulkRemoveRecord", "_grist_Views_section_field", [1,2]],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0}],
["AddRecord", "_grist_Views_section_field", 1,
{"parentId": 1, "colRef": 31, "parentPos": 1.0}],
["RemoveRecord", "_grist_Views_section", 2],
["BulkRemoveRecord", "_grist_Views_section_field", [3, 4]],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0, "rawViewSectionRef": 0}],
["BulkAddRecord", "_grist_Views_section_field", [1, 3], {"colRef": [31, 31], "parentId": [1, 2], "parentPos": [1.0, 3.0]}],
["AddRecord", "_grist_Tables_column", 31,
{"colId": "hello", "parentPos": 9.0,
"parentId": 4, "type": "Text"
@ -2188,8 +2200,8 @@
["AddRecord", "_grist_Views_section", 1,
{"tableRef": 4, "defaultWidth": 100, "borderWidth": 1,
"parentId": 1, "parentKey": "record", "sortColRefs": "[]", "title": ""}],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1}],
["AddRecord", "_grist_Views_section", 2, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "tableRef": 4}],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1, "rawViewSectionRef": 2}],
["AddTable", "Bar", [
{"id": "manualSort", "formula": "", "isFormula": false, "type": "ManualSortPos"},
{"isFormula": false, "formula": "", "type": "Text", "id": "hello"},
@ -2213,18 +2225,21 @@
{"type": "raw_data", "name": "Bar"}],
["AddRecord", "_grist_TabBar", 2, {"tabPos": 2.0, "viewRef": 2}],
["AddRecord", "_grist_Pages", 2, {"pagePos": 2.0, "viewRef": 2, "indentation": 0}],
["AddRecord", "_grist_Views_section", 2,
["AddRecord", "_grist_Views_section", 3,
{"tableRef": 5, "defaultWidth": 100, "borderWidth": 1,
"parentId": 2, "parentKey": "record", "sortColRefs": "[]", "title": ""}],
["BulkAddRecord", "_grist_Views_section_field", [1,2,3],
{"parentId": [2,2,2], "colRef": [32,33,34], "parentPos": [1.0,2.0,3.0]}],
["UpdateRecord", "_grist_Tables", 5, {"primaryViewId": 2}],
{"parentId": [3,3,3], "colRef": [32,33,34], "parentPos": [1.0,2.0,3.0]}],
["AddRecord", "_grist_Views_section", 4, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "tableRef": 5}],
["BulkAddRecord", "_grist_Views_section_field", [4, 5, 6], {"colRef": [32, 33, 34], "parentId": [4, 4, 4], "parentPos": [4.0, 5.0, 6.0]}],
["UpdateRecord", "_grist_Tables", 5, {"primaryViewId": 2, "rawViewSectionRef": 4}],
["AddRecord", "Bar", 1, {"foo": 0, "hello": "a", "manualSort": 1.0}],
["AddRecord", "Bar", 2, {"foo": 1, "hello": "b", "manualSort": 2.0}],
["AddRecord", "Bar", 3, {"foo": 1, "hello": "c", "manualSort": 3.0}],
["BulkUpdateRecord", "Bar", [1, 2, 3], {"world": ["A", "B", "C"]}]
],
"direct": [true, true, true, true, true, true, true, true,
true, true, true,
true, true, true, true, true, true, true, true, true,
true, true, true, false],
"undo": [
@ -2235,16 +2250,19 @@
["RemoveRecord", "_grist_TabBar", 1],
["RemoveRecord", "_grist_Pages", 1],
["RemoveRecord", "_grist_Views_section", 1],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0}],
["RemoveRecord", "_grist_Views_section", 2],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0, "rawViewSectionRef": 0}],
["RemoveTable", "Bar"],
["RemoveRecord", "_grist_Tables", 5],
["BulkRemoveRecord", "_grist_Tables_column", [31,32,33,34]],
["RemoveRecord", "_grist_Views", 2],
["RemoveRecord", "_grist_TabBar", 2],
["RemoveRecord", "_grist_Pages", 2],
["RemoveRecord", "_grist_Views_section", 2],
["RemoveRecord", "_grist_Views_section", 3],
["BulkRemoveRecord", "_grist_Views_section_field", [1,2,3]],
["UpdateRecord", "_grist_Tables", 5, {"primaryViewId": 0}],
["RemoveRecord", "_grist_Views_section", 4],
["BulkRemoveRecord", "_grist_Views_section_field", [4, 5, 6]],
["UpdateRecord", "_grist_Tables", 5, {"primaryViewId": 0, "rawViewSectionRef": 0}],
["RemoveRecord", "Bar", 1],
["RemoveRecord", "Bar", 2],
["RemoveRecord", "Bar", 3]
@ -2265,7 +2283,7 @@
"id": 5,
"columns": ["hello", "world", "foo"],
"views": [
{ "sections": [ 2 ], "id": 2 }
{ "sections": [ 3 ], "id": 2 }
]
},
// AddRecord retValues
@ -2315,10 +2333,12 @@
["AddRecord", "_grist_Views_section", 1,
{"tableRef": 4, "defaultWidth": 100, "borderWidth": 1,
"parentId": 1, "parentKey": "record", "sortColRefs": "[]", "title": ""}],
// Raw data widget
["AddRecord", "_grist_Views_section", 2, {"borderWidth": 1, "defaultWidth": 100, "parentKey": "record", "tableRef": 4}],
// As part of adding a table, we also set the primaryViewId.
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1}]
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 1, "rawViewSectionRef": 2}]
],
"direct": [true, true, true, true, true, true, true, true],
"direct": [true, true, true, true, true, true, true, true, true],
"undo": [
["RemoveTable", "Foo"],
["RemoveRecord", "_grist_Tables", 4],
@ -2327,7 +2347,8 @@
["RemoveRecord", "_grist_TabBar", 1],
["RemoveRecord", "_grist_Pages", 1],
["RemoveRecord", "_grist_Views_section", 1],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0}]
["RemoveRecord", "_grist_Views_section", 2],
["UpdateRecord", "_grist_Tables", 4, {"primaryViewId": 0, "rawViewSectionRef": 0}]
]
}
}],
@ -2340,7 +2361,8 @@
"USER_ACTION": ["RemoveTable", "Foo"],
"ACTIONS": {
"stored": [
["RemoveRecord", "_grist_Views_section", 1],
["BulkRemoveRecord", "_grist_Views_section", [1, 2]],
["UpdateRecord", "_grist_Tables", 4, {"rawViewSectionRef": 0}],
["RemoveRecord", "_grist_TabBar", 1],
["RemoveRecord", "_grist_Pages", 1],
["RemoveRecord", "_grist_Views", 1],
@ -2349,11 +2371,12 @@
["RemoveRecord", "_grist_Tables", 4],
["RemoveTable", "Foo"]
],
"direct": [true, true, true, true, true, true, true, true],
"direct": [true, true, true, true, true, true, true, true, true],
"undo": [
["AddRecord", "_grist_Views_section", 1,
{"tableRef": 4, "defaultWidth": 100, "borderWidth": 1,
"parentId": 1, "parentKey": "record", "sortColRefs": "[]"}],
["BulkAddRecord", "_grist_Views_section", [1, 2],
{"borderWidth": [1, 1], "defaultWidth": [100, 100], "parentId": [1, 0],
"parentKey": ["record", "record"], "sortColRefs": ["[]", ""], "tableRef": [4, 4]}],
["UpdateRecord", "_grist_Tables", 4, {"rawViewSectionRef": 2}],
["AddRecord", "_grist_TabBar", 1, {"tabPos": 1.0, "viewRef": 1}],
["AddRecord", "_grist_Pages", 1, {"pagePos": 1.0, "viewRef": 1}],
["AddRecord", "_grist_Views", 1, {"name": "Foo", "type": "raw_data"}],

@ -635,11 +635,15 @@ class UserActions(object):
if 'name' in col_values:
rename_table_recs = []
rename_names = []
rename_section_recs = []
for i, rec, values in self._bulk_action_iter(table_id, row_ids, col_values):
if rec.primaryViewTable:
rename_table_recs.append(rec.primaryViewTable)
table = rec.primaryViewTable
if table:
rename_table_recs.append(table)
rename_section_recs.append(table.rawViewSectionRef)
rename_names.append(values['name'])
self._docmodel.update(rename_table_recs, tableId=rename_names)
self._docmodel.update(rename_section_recs, title=rename_names)
self.doBulkUpdateRecord(table_id, row_ids, col_values)
@ -1343,12 +1347,25 @@ class UserActions(object):
# Add a manualSort column.
columns.insert(0, column.MANUAL_SORT_COL_INFO.copy())
# First the tables is created without a primary view assigned as no view for it exists.
result = self.doAddTable(table_id, columns)
# Then its Primary View is created.
primary_view = self.doAddView(result["table_id"], 'raw_data', result["table_id"])
self.UpdateRecord('_grist_Tables', result["id"], {'primaryViewId': primary_view["id"]})
result["views"] = [primary_view]
raw_view_section = self._create_plain_view_section(
result["id"],
result["table_id"],
self._docmodel.view_sections,
"record",
)
self.UpdateRecord('_grist_Tables', result["id"], {
'primaryViewId': primary_view["id"],
'rawViewSectionRef': raw_view_section.id,
})
return result
def doAddTable(self, table_id, columns, summarySourceTableRef=0):
@ -1434,17 +1451,26 @@ class UserActions(object):
if groupby_colrefs is not None:
section = self._summary.create_new_summary_section(table, groupby_cols, view, section_type)
else:
section = self._docmodel.add(view.viewSections, tableRef=table.id, parentKey=section_type,
borderWidth=1, defaultWidth=100)[0]
# TODO: We should address the automatic selection of fields for charts in a better way.
self._RebuildViewFields(table.tableId, section.id,
limit=(2 if section_type == 'chart' else None))
section = self._create_plain_view_section(
table.id,
table.tableId,
view.viewSections,
section_type,
)
return {
'tableRef': table_ref,
'viewRef': view_ref,
'sectionRef': section.id
}
def _create_plain_view_section(self, tableRef, tableId, view_sections, section_type):
section = self._docmodel.add(view_sections, tableRef=tableRef, parentKey=section_type,
borderWidth=1, defaultWidth=100)[0]
# TODO: We should address the automatic selection of fields for charts in a better way.
self._RebuildViewFields(tableId, section.id,
limit=(2 if section_type == 'chart' else None))
return section
@useraction
def UpdateSummaryViewSection(self, section_ref, groupby_colrefs):
"""

Binary file not shown.
Loading…
Cancel
Save