gristlabs_grist-core/app/client/models/entities/TableRec.ts
Dmitry S 51ff72c15e (core) Faster builds all around.
Summary:
Building:
- Builds no longer wait for tsc for either client, server, or test targets. All use esbuild which is very fast.
- Build still runs tsc, but only to report errors. This may be turned off with `SKIP_TSC=1` env var.
- Grist-core continues to build using tsc.
- Esbuild requires ES6 module semantics. Typescript's esModuleInterop is turned
  on, so that tsc accepts and enforces correct usage.
- Client-side code is watched and bundled by webpack as before (using esbuild-loader)

Code changes:
- Imports must now follow ES6 semantics: `import * as X from ...` produces a
  module object; to import functions or class instances, use `import X from ...`.
- Everything is now built with isolatedModules flag. Some exports were updated for it.

Packages:
- Upgraded browserify dependency, and related packages (used for the distribution-building step).
- Building the distribution now uses esbuild's minification. babel-minify is no longer used.

Test Plan: Should have no behavior changes, existing tests should pass, and docker image should build too.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Subscribers: alexmojaki

Differential Revision: https://phab.getgrist.com/D3506
2022-07-04 10:42:40 -04:00

118 lines
4.5 KiB
TypeScript

import {KoArray} from 'app/client/lib/koArray';
import {DocModel, IRowModel, recordSet, refRecord, ViewSectionRec} from 'app/client/models/DocModel';
import {ColumnRec, ValidationRec, ViewRec} from 'app/client/models/DocModel';
import * as modelUtil from 'app/client/models/modelUtil';
import {MANUALSORT} from 'app/common/gristTypes';
import * as ko from 'knockout';
import randomcolor from 'randomcolor';
// Represents a user-defined table.
export interface TableRec extends IRowModel<"_grist_Tables"> {
columns: ko.Computed<KoArray<ColumnRec>>;
validations: ko.Computed<KoArray<ValidationRec>>;
primaryView: ko.Computed<ViewRec>;
rawViewSection: ko.Computed<ViewSectionRec>;
summarySource: ko.Computed<TableRec>;
// A Set object of colRefs for all summarySourceCols of table.
summarySourceColRefs: ko.Computed<Set<number>>;
// tableId for normal tables, or tableId of the source table for summary tables.
primaryTableId: ko.Computed<string>;
// The list of grouped by columns.
groupByColumns: ko.Computed<ColumnRec[]>;
// Grouping description.
groupDesc: ko.PureComputed<string>;
// Name of the data table - title of the rawViewSection
// for summary table it is name of primary table.
tableName: modelUtil.KoSaveableObservable<string>;
// Table name with a default value (which is tableId).
tableNameDef: modelUtil.KoSaveableObservable<string>;
// If user can select this table in various places.
// Note: Some hidden tables can still be visible on RawData view.
isHidden: ko.Computed<boolean>;
tableColor: string;
disableAddRemoveRows: ko.Computed<boolean>;
supportsManualSort: ko.Computed<boolean>;
}
export function createTableRec(this: TableRec, docModel: DocModel): void {
this.columns = recordSet(this, docModel.columns, 'parentId', {sortBy: 'parentPos'});
this.validations = recordSet(this, docModel.validations, 'tableRef');
this.primaryView = refRecord(docModel.views, this.primaryViewId);
this.rawViewSection = refRecord(docModel.viewSections, this.rawViewSectionRef);
this.summarySource = refRecord(docModel.tables, this.summarySourceTable);
this.isHidden = this.autoDispose(
// This is repeated logic from isHiddenTable.
ko.pureComputed(() => !!this.summarySourceTable() || this.tableId()?.startsWith("GristHidden"))
);
// A Set object of colRefs for all summarySourceCols of this table.
this.summarySourceColRefs = this.autoDispose(ko.pureComputed(() => new Set(
this.columns().all().map(c => c.summarySourceCol()).filter(colRef => colRef))));
// tableId for normal tables, or tableId of the source table for summary tables.
this.primaryTableId = ko.pureComputed(() =>
this.summarySourceTable() ? this.summarySource().tableId() : this.tableId());
this.groupByColumns = ko.pureComputed(() => this.columns().all().filter(c => c.summarySourceCol()));
this.groupDesc = ko.pureComputed(() => {
if (!this.summarySourceTable()) {
return '';
}
const groupBy = this.groupByColumns();
return `[${groupBy.length ? 'by ' + groupBy.map(c => c.label()).join(", ") : "Totals"}]`;
});
// TODO: We should save this value and let users change it.
this.tableColor = randomcolor({
luminosity: 'light',
seed: typeof this.id() === 'number' ? 5 * this.id() : this.id()
});
this.disableAddRemoveRows = ko.pureComputed(() => Boolean(this.summarySourceTable()));
this.supportsManualSort = ko.pureComputed(() => this.columns().all().some(c => c.colId() === MANUALSORT));
this.tableName = modelUtil.savingComputed({
read: () => {
if (this.isDisposed()) {
return '';
}
if (this.summarySourceTable()) {
return this.summarySource().rawViewSection().title();
} else {
// Need to be extra careful here, rawViewSection might be disposed.
if (this.rawViewSection().isDisposed()) {
return '';
}
return this.rawViewSection().title();
}
},
write: (setter, val) => {
if (this.summarySourceTable()) {
setter(this.summarySource().rawViewSection().title, val);
} else {
setter(this.rawViewSection().title, val);
}
}
});
this.tableNameDef = modelUtil.fieldWithDefault(
this.tableName,
// TableId will be null/undefined when ACL will restrict access to it.
ko.computed(() => {
// During table removal, we could be disposed.
if (this.isDisposed()) {
return '';
}
const table = this.summarySourceTable() ? this.summarySource() : this;
return table.tableId() || '';
})
);
}