diff --git a/app/common/schema.ts b/app/common/schema.ts index 1db1e3cf..fcb05e7c 100644 --- a/app/common/schema.ts +++ b/app/common/schema.ts @@ -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": { diff --git a/app/server/lib/initialDocSql.ts b/app/server/lib/initialDocSql.ts index 9ba79a5f..d735ef01 100644 --- a/app/server/lib/initialDocSql.ts +++ b/app/server/lib/initialDocSql.ts @@ -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); diff --git a/sandbox/grist/import_actions.py b/sandbox/grist/import_actions.py index 2c69cfd5..4f14e8ac 100644 --- a/sandbox/grist/import_actions.py +++ b/sandbox/grist/import_actions.py @@ -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 diff --git a/sandbox/grist/migrations.py b/sandbox/grist/migrations.py index daff4f80..99cd20cc 100644 --- a/sandbox/grist/migrations.py +++ b/sandbox/grist/migrations.py @@ -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) diff --git a/sandbox/grist/schema.py b/sandbox/grist/schema.py index 19ec4fc4..2995a374 100644 --- a/sandbox/grist/schema.py +++ b/sandbox/grist/schema.py @@ -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. diff --git a/sandbox/grist/test_column_actions.py b/sandbox/grist/test_column_actions.py index ea9d86be..af26f855 100644 --- a/sandbox/grist/test_column_actions.py +++ b/sandbox/grist/test_column_actions.py @@ -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=[ diff --git a/sandbox/grist/test_display_cols.py b/sandbox/grist/test_display_cols.py index 92ebf522..59a5ff3b 100644 --- a/sandbox/grist/test_display_cols.py +++ b/sandbox/grist/test_display_cols.py @@ -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], diff --git a/sandbox/grist/test_docmodel.py b/sandbox/grist/test_docmodel.py index 1f3d1a53..57170103 100644 --- a/sandbox/grist/test_docmodel.py +++ b/sandbox/grist/test_docmodel.py @@ -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): diff --git a/sandbox/grist/test_engine.py b/sandbox/grist/test_engine.py index 763da686..79a721df 100644 --- a/sandbox/grist/test_engine.py +++ b/sandbox/grist/test_engine.py @@ -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) diff --git a/sandbox/grist/test_import_actions.py b/sandbox/grist/test_import_actions.py index 9766e72f..ca39086c 100644 --- a/sandbox/grist/test_import_actions.py +++ b/sandbox/grist/test_import_actions.py @@ -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 ]) diff --git a/sandbox/grist/test_summary2.py b/sandbox/grist/test_summary2.py index adca7a1d..3e6fdadd 100644 --- a/sandbox/grist/test_summary2.py +++ b/sandbox/grist/test_summary2.py @@ -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], diff --git a/sandbox/grist/test_table_actions.py b/sandbox/grist/test_table_actions.py index 0659cd43..d37ad96b 100644 --- a/sandbox/grist/test_table_actions.py +++ b/sandbox/grist/test_table_actions.py @@ -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), ]), ]), ]) diff --git a/sandbox/grist/test_useractions.py b/sandbox/grist/test_useractions.py index 818d90a0..5401af0e 100644 --- a/sandbox/grist/test_useractions.py +++ b/sandbox/grist/test_useractions.py @@ -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), ]), ]), ]) diff --git a/sandbox/grist/testscript.json b/sandbox/grist/testscript.json index a70f6fec..1a6190d8 100644 --- a/sandbox/grist/testscript.json +++ b/sandbox/grist/testscript.json @@ -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"}], diff --git a/sandbox/grist/useractions.py b/sandbox/grist/useractions.py index 8891f0e1..3f7fc75e 100644 --- a/sandbox/grist/useractions.py +++ b/sandbox/grist/useractions.py @@ -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): """ diff --git a/test/fixtures/docs/Hello.grist b/test/fixtures/docs/Hello.grist index a9bbd840..23dbb9a9 100644 Binary files a/test/fixtures/docs/Hello.grist and b/test/fixtures/docs/Hello.grist differ