mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Configure more comprehensive eslint rules for Typescript
Summary: - Update rules to be more like we've had with tslint - Switch tsserver plugin to eslint (tsserver makes for a much faster way to lint in editors) - Apply suggested auto-fixes - Fix all lint errors and warnings in core/, app/, test/ Test Plan: Some behavior may change subtly (e.g. added missing awaits), relying on existing tests to catch problems. Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2785
This commit is contained in:
@@ -241,9 +241,9 @@ AceEditor.prototype._getContentHeight = function() {
|
||||
|
||||
|
||||
let _RangeConstructor = null; //singleton, load it lazily
|
||||
AceEditor.makeRange = function(a,b,c,d) {
|
||||
AceEditor.makeRange = function(a, b, c, d) {
|
||||
_RangeConstructor = _RangeConstructor || ace.acequire('ace/range').Range;
|
||||
return new _RangeConstructor(a,b,c,d);
|
||||
return new _RangeConstructor(a, b, c, d);
|
||||
};
|
||||
|
||||
module.exports = AceEditor;
|
||||
|
||||
@@ -262,7 +262,7 @@ export class ActionLog extends dispose.Disposable implements IDomComponent {
|
||||
if (this._loaded || !this._gristDoc) { return; }
|
||||
this._loading(true);
|
||||
// Returned actions are ordered with earliest actions first.
|
||||
const result = await this._gristDoc!.docComm.getActionSummaries();
|
||||
const result = await this._gristDoc.docComm.getActionSummaries();
|
||||
this._loading(false);
|
||||
this._loaded = true;
|
||||
// Add the actions to our action log.
|
||||
|
||||
@@ -15,7 +15,7 @@ import * as ko from 'knockout';
|
||||
import noop = require('lodash/noop');
|
||||
|
||||
// To simplify diff (avoid rearranging methods to satisfy private/public order).
|
||||
// tslint:disable:member-ordering
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
|
||||
type AceEditor = any;
|
||||
|
||||
@@ -130,7 +130,7 @@ export class ColumnTransform extends Disposable {
|
||||
this.transformColumn = this.field.column();
|
||||
this.transformColumn.origColRef(this.origColumn.getRowId());
|
||||
this._setTransforming(true);
|
||||
return await this.postAddTransformColumn();
|
||||
return this.postAddTransformColumn();
|
||||
} finally {
|
||||
this.isCallPending(false);
|
||||
}
|
||||
@@ -167,7 +167,7 @@ export class ColumnTransform extends Disposable {
|
||||
/**
|
||||
* A derived class can override to do some processing after this.transformColumn has been set.
|
||||
*/
|
||||
protected postAddTransformColumn() {
|
||||
protected postAddTransformColumn(): void {
|
||||
// Nothing in base class.
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ export class ColumnTransform extends Disposable {
|
||||
} finally {
|
||||
// Wait until the change completed to set column back, to avoid value flickering.
|
||||
field.colRef(origRef);
|
||||
tableData.sendTableAction(['RemoveColumn', transformColId]);
|
||||
void tableData.sendTableAction(['RemoveColumn', transformColId]);
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,11 +350,11 @@ GridView.prototype.fillSelectionDown = function() {
|
||||
}).filter(colId => colId);
|
||||
|
||||
var colInfo = _.object(colIds, colIds.map(colId => {
|
||||
var val = this.tableModel.tableData.getValue(rowIds[0],colId);
|
||||
var val = this.tableModel.tableData.getValue(rowIds[0], colId);
|
||||
return rowIds.map(() => val);
|
||||
}));
|
||||
|
||||
this.tableModel.sendTableAction(["BulkUpdateRecord",rowIds,colInfo]);
|
||||
this.tableModel.sendTableAction(["BulkUpdateRecord", rowIds, colInfo]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ export class Importer extends Disposable {
|
||||
} else if (item.kind === "url") {
|
||||
uploadResult = await fetchURL(this._docComm, item.url);
|
||||
} else {
|
||||
throw new Error(`Import source of kind ${item!.kind} are not yet supported!`);
|
||||
throw new Error(`Import source of kind ${(item as any).kind} are not yet supported!`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,7 +391,7 @@ export class Importer extends Disposable {
|
||||
}
|
||||
|
||||
function getSourceDescription(sourceInfo: SourceInfo, upload: UploadResult) {
|
||||
const origName = upload!.files[sourceInfo.uploadFileIndex].origName;
|
||||
const origName = upload.files[sourceInfo.uploadFileIndex].origName;
|
||||
return sourceInfo.origTableName ? origName + ' - ' + sourceInfo.origTableName : origName;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ export function makeSearchToolbarGroup(gristDoc: GristDoc) {
|
||||
// Active normally.
|
||||
const commandGroup = createGroup({
|
||||
find: () => { input.focus(); },
|
||||
findNext: () => { searcher.findNext(); }, // tslint:disable-line:no-floating-promises TODO
|
||||
findPrev: () => { searcher.findPrev(); }, // tslint:disable-line:no-floating-promises TODO
|
||||
findNext: () => { searcher.findNext(); }, // eslint-disable-line @typescript-eslint/no-floating-promises
|
||||
findPrev: () => { searcher.findPrev(); }, // eslint-disable-line @typescript-eslint/no-floating-promises
|
||||
}, null, true);
|
||||
|
||||
// Return an array of one item (for a toolbar group of a single item). The item is an array of
|
||||
@@ -49,7 +49,7 @@ export function makeSearchToolbarGroup(gristDoc: GristDoc) {
|
||||
// the searchbox is created so early that the actions like accept/cancel get overridden).
|
||||
dom.on('keydown', (e: KeyboardEvent) => {
|
||||
switch (e.keyCode) {
|
||||
case 13: searcher.findNext(); break; // tslint:disable-line:no-floating-promises TODO
|
||||
case 13: searcher.findNext(); break; // eslint-disable-line @typescript-eslint/no-floating-promises
|
||||
case 27: input.blur(); break;
|
||||
}
|
||||
})
|
||||
|
||||
@@ -264,7 +264,7 @@ CellSelector.prototype.rowCount = function() {
|
||||
return this.rowUpper() - this.rowLower() + 1;
|
||||
};
|
||||
|
||||
CellSelector.prototype.selectArea = function(rowStartIdx,colStartIdx,rowEndIdx,colEndIdx) {
|
||||
CellSelector.prototype.selectArea = function(rowStartIdx, colStartIdx, rowEndIdx, colEndIdx) {
|
||||
this.row.start(rowStartIdx);
|
||||
this.col.start(colStartIdx);
|
||||
this.row.end(rowEndIdx);
|
||||
|
||||
@@ -22,7 +22,7 @@ import isEmpty = require('lodash/isEmpty');
|
||||
import pickBy = require('lodash/pickBy');
|
||||
|
||||
// To simplify diff (avoid rearranging methods to satisfy private/public order).
|
||||
// tslint:disable:member-ordering
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
|
||||
/**
|
||||
* Creates an instance of TypeTransform for a single field. Extends ColumnTransform.
|
||||
|
||||
@@ -58,7 +58,7 @@ function ViewConfigTab(options) {
|
||||
}) || self.viewSectionData.at(0);
|
||||
}));
|
||||
this.isDetail = this.autoDispose(ko.computed(function() {
|
||||
return ['detail','single'].includes(this.viewModel.activeSection().parentKey());
|
||||
return ['detail', 'single'].includes(this.viewModel.activeSection().parentKey());
|
||||
}, this));
|
||||
this.isChart = this.autoDispose(ko.computed(function() {
|
||||
return this.viewModel.activeSection().parentKey() === 'chart';}, this));
|
||||
|
||||
10
app/client/declarations.d.ts
vendored
10
app/client/declarations.d.ts
vendored
@@ -35,7 +35,6 @@ declare module "app/client/components/BaseView" {
|
||||
import {Cursor, CursorPos} from 'app/client/components/Cursor';
|
||||
import {GristDoc} from 'app/client/components/GristDoc';
|
||||
import {Disposable} from 'app/client/lib/dispose';
|
||||
import {KoArray} from "app/client/lib/koArray";
|
||||
import * as BaseRowModel from "app/client/models/BaseRowModel";
|
||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||
import {LazyArrayModel} from "app/client/models/DataTableModel";
|
||||
@@ -72,10 +71,8 @@ declare module "app/client/components/BaseView" {
|
||||
}
|
||||
|
||||
declare module "app/client/components/RefSelect" {
|
||||
import {GristDoc, TabContent} from 'app/client/components/GristDoc';
|
||||
import {Disposable} from 'app/client/lib/dispose';
|
||||
import {ColumnRec} from "app/client/models/DocModel";
|
||||
import {DomArg} from 'grainjs';
|
||||
import {DocModel} from "app/client/models/DocModel";
|
||||
import {FieldBuilder} from "app/client/widgets/FieldBuilder";
|
||||
|
||||
@@ -161,11 +158,11 @@ declare module "app/client/models/BaseRowModel" {
|
||||
class BaseRowModel extends Disposable {
|
||||
public id: ko.Computed<number>;
|
||||
public _index: ko.Observable<number|null>;
|
||||
public getRowId(): number;
|
||||
public updateColValues(colValues: ColValues): Promise<void>;
|
||||
public _table: TableModel;
|
||||
protected _rowId: number | 'new' | null;
|
||||
protected _fields: string[];
|
||||
public getRowId(): number;
|
||||
public updateColValues(colValues: ColValues): Promise<void>;
|
||||
}
|
||||
export = BaseRowModel;
|
||||
}
|
||||
@@ -286,10 +283,9 @@ declare module "app/client/models/DataTableModel" {
|
||||
import * as BaseRowModel from "app/client/models/BaseRowModel";
|
||||
import {DocModel, TableRec} from "app/client/models/DocModel";
|
||||
import {TableQuerySets} from 'app/client/models/QuerySet';
|
||||
import {RowSource, SortedRowSet} from "app/client/models/rowset";
|
||||
import {SortedRowSet} from "app/client/models/rowset";
|
||||
import {TableData} from "app/client/models/TableData";
|
||||
import * as TableModel from "app/client/models/TableModel";
|
||||
import {CellValue} from "app/common/DocActions";
|
||||
|
||||
namespace DataTableModel {
|
||||
interface LazyArrayModel<T> extends KoArray<T | null> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Implements an autocomplete dropdown.
|
||||
*/
|
||||
import {createPopper, Instance as Popper, Modifier, Options as PopperOptions} from '@popperjs/core';
|
||||
import {createPopper, Modifier, Instance as Popper, Options as PopperOptions} from '@popperjs/core';
|
||||
import {ACItem, ACResults, HighlightFunc} from 'app/client/lib/ACIndex';
|
||||
import {reportError} from 'app/client/models/errors';
|
||||
import {Disposable, dom, EventCB, IDisposable} from 'grainjs';
|
||||
|
||||
@@ -174,7 +174,7 @@ export class BillingModelImpl extends Disposable implements BillingModel {
|
||||
await this._billingAPI.updateAddress(newAddr || undefined, newSettings || undefined);
|
||||
}
|
||||
// If there is an org update, re-initialize the org in the client.
|
||||
if (newSettings) { await this._appModel.topAppModel.initialize(); }
|
||||
if (newSettings) { this._appModel.topAppModel.initialize(); }
|
||||
} else {
|
||||
throw new Error('BillingPage _submit error: no task in progress');
|
||||
}
|
||||
|
||||
@@ -27,13 +27,6 @@ const ROW_ID_SKIP = -1;
|
||||
* This should be the only part of the code that knows that.
|
||||
*/
|
||||
export class ExtraRows {
|
||||
readonly leftTableDelta?: TableDelta;
|
||||
readonly rightTableDelta?: TableDelta;
|
||||
readonly rightAddRows: Set<number>;
|
||||
readonly rightRemoveRows: Set<number>;
|
||||
readonly leftAddRows: Set<number>;
|
||||
readonly leftRemoveRows: Set<number>;
|
||||
|
||||
/**
|
||||
* Map back from a possibly synthetic row id to an original strictly-positive row id.
|
||||
*/
|
||||
@@ -44,7 +37,14 @@ export class ExtraRows {
|
||||
return { type: 'local-remove', id: -(rowId + 2) / 2 };
|
||||
}
|
||||
|
||||
public constructor(readonly tableId: string, readonly comparison?: DocStateComparisonDetails) {
|
||||
public readonly leftTableDelta?: TableDelta;
|
||||
public readonly rightTableDelta?: TableDelta;
|
||||
public readonly rightAddRows: Set<number>;
|
||||
public readonly rightRemoveRows: Set<number>;
|
||||
public readonly leftAddRows: Set<number>;
|
||||
public readonly leftRemoveRows: Set<number>;
|
||||
|
||||
public constructor(public readonly tableId: string, public readonly comparison?: DocStateComparisonDetails) {
|
||||
const remoteTableId = getRemoteTableId(tableId, comparison);
|
||||
this.leftTableDelta = this.comparison?.leftChanges?.tableDeltas[tableId];
|
||||
if (remoteTableId) {
|
||||
|
||||
@@ -100,7 +100,7 @@ export class DocData extends BaseDocData {
|
||||
this._nextDesc = options.description;
|
||||
this._lastActionNum = null;
|
||||
this._triggerBundleFinalize = triggerFinalize;
|
||||
await prepareResolve(options.prepare());
|
||||
prepareResolve(options.prepare());
|
||||
this._shouldIncludeInBundle = options.shouldIncludeInBundle;
|
||||
|
||||
await triggerFinalizePromise;
|
||||
@@ -162,7 +162,7 @@ export class DocData extends BaseDocData {
|
||||
public sendActions(actions: UserAction[], optDesc?: string): Promise<any[]> {
|
||||
// Some old code relies on this promise being a bluebird Promise.
|
||||
// TODO Remove bluebird and this cast.
|
||||
return bluebird.Promise.resolve(this._sendActionsImpl(actions, optDesc)) as any;
|
||||
return bluebird.Promise.resolve(this._sendActionsImpl(actions, optDesc)) as unknown as Promise<any[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,7 +94,8 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
public readonly isReadonly = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.isReadonly : false);
|
||||
public readonly isPrefork = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.isPreFork : false);
|
||||
public readonly isFork = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.isFork : false);
|
||||
public readonly isRecoveryMode = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.isRecoveryMode : false);
|
||||
public readonly isRecoveryMode = Computed.create(this, this.currentDoc,
|
||||
(use, doc) => doc ? doc.isRecoveryMode : false);
|
||||
public readonly userOverride = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.userOverride : null);
|
||||
public readonly isBareFork = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.isBareFork : false);
|
||||
public readonly isSample = Computed.create(this, this.currentDoc, (use, doc) => doc ? doc.isSample : false);
|
||||
@@ -133,8 +134,9 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
if (!urlId) {
|
||||
this._openerHolder.clear();
|
||||
} else {
|
||||
FlowRunner.create(this._openerHolder, (flow: AsyncFlow) => this._openDoc(flow, urlId, urlOpenMode,
|
||||
state.params?.compare, linkParameters))
|
||||
FlowRunner.create(this._openerHolder,
|
||||
(flow: AsyncFlow) => this._openDoc(flow, urlId, urlOpenMode, state.params?.compare, linkParameters)
|
||||
)
|
||||
.resultPromise.catch(err => this._onOpenError(err));
|
||||
}
|
||||
}
|
||||
@@ -305,8 +307,10 @@ function addMenu(importSources: ImportSource[], gristDoc: GristDoc, isReadonly:
|
||||
menuIcon("Widget"), "Add Widget to Page", testId('dp-add-widget-to-page'),
|
||||
dom.cls('disabled', isReadonly)
|
||||
),
|
||||
menuItem(() => gristDoc.addEmptyTable().catch(reportError), menuIcon("TypeTable"), "Add Empty Table", testId('dp-empty-table'),
|
||||
dom.cls('disabled', isReadonly)),
|
||||
menuItem(() => gristDoc.addEmptyTable().catch(reportError),
|
||||
menuIcon("TypeTable"), "Add Empty Table", testId('dp-empty-table'),
|
||||
dom.cls('disabled', isReadonly)
|
||||
),
|
||||
menuDivider(),
|
||||
...importSources.map((importSource, i) =>
|
||||
menuItem(importSource.action,
|
||||
|
||||
@@ -314,7 +314,7 @@ function convertQueryToRefs(docModel: DocModel, query: Query): QueryRefs {
|
||||
const tableRec: any = docModel.dataTables[query.tableId].tableMetaRow;
|
||||
|
||||
const colRefsByColId: {[colId: string]: number} = {};
|
||||
for (const col of (tableRec as any).columns.peek().peek()) {
|
||||
for (const col of tableRec.columns.peek().peek()) {
|
||||
colRefsByColId[col.colId.peek()] = col.getRowId();
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export class SearchModelImpl extends Disposable implements SearchModel {
|
||||
|
||||
// Listen to input value changes (debounced) to activate searching.
|
||||
const findFirst = debounce((_value: string) => this._findFirst(_value), 100);
|
||||
this.autoDispose(this.value.addListener(v => { findFirst(v); }));
|
||||
this.autoDispose(this.value.addListener(v => { void findFirst(v); }));
|
||||
}
|
||||
|
||||
public async findNext() {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {DocData} from 'app/client/models/DocData';
|
||||
import {DocAction, ReplaceTableData, TableDataAction, UserAction} from 'app/common/DocActions';
|
||||
import {isRaisedException} from 'app/common/gristTypes';
|
||||
import {countIf} from 'app/common/gutil';
|
||||
import {ColTypeMap, TableData as BaseTableData} from 'app/common/TableData';
|
||||
import {TableData as BaseTableData, ColTypeMap} from 'app/common/TableData';
|
||||
import {BaseFormatter} from 'app/common/ValueFormatter';
|
||||
import {Emitter} from 'grainjs';
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ class BillingPaymentForm extends BillingSubForm {
|
||||
}) {
|
||||
super();
|
||||
const autofill = this._options.autofill;
|
||||
const stripeAPIKey = (G.window as any).gristConfig.stripeAPIKey;
|
||||
const stripeAPIKey = G.window.gristConfig.stripeAPIKey;
|
||||
try {
|
||||
this._stripe = G.Stripe(stripeAPIKey);
|
||||
this._elements = this._stripe.elements();
|
||||
@@ -462,7 +462,7 @@ function checkRequired(propertyName: string) {
|
||||
// if the current observable value is valid.
|
||||
function createValidated(
|
||||
owner: IDisposableOwnerT<any>,
|
||||
checkValidity: (value: string) => void
|
||||
checkValidity: (value: string) => void|Promise<void>,
|
||||
): IValidated<string> {
|
||||
const value = Observable.create(owner, '');
|
||||
const isInvalid = Observable.create<boolean>(owner, false);
|
||||
|
||||
@@ -352,7 +352,7 @@ function getFieldNewPosition(fields: KoArray<ViewFieldRec>, item: IField,
|
||||
return tableUtil.fieldInsertPositions(fields, index, 1)[0];
|
||||
}
|
||||
|
||||
function getItemIndex<T>(collection: KoArray<ViewFieldRec>, item: ViewFieldRec|null): number {
|
||||
function getItemIndex(collection: KoArray<ViewFieldRec>, item: ViewFieldRec|null): number {
|
||||
if (item !== null) {
|
||||
return collection.peek().indexOf(item);
|
||||
}
|
||||
|
||||
@@ -194,8 +194,8 @@ export const cssHideForNarrowScreen = styled('div', `
|
||||
* Attaches the global css properties to the document's root to them available in the page.
|
||||
*/
|
||||
export function attachCssRootVars(productFlavor: ProductFlavor, varsOnly: boolean = false) {
|
||||
dom.update(document.documentElement!, varsOnly ? dom.cls(cssVarsOnly.className) : dom.cls(cssRootVars));
|
||||
document.documentElement!.classList.add(cssRoot.className);
|
||||
dom.update(document.documentElement, varsOnly ? dom.cls(cssVarsOnly.className) : dom.cls(cssRootVars));
|
||||
document.documentElement.classList.add(cssRoot.className);
|
||||
document.body.classList.add(cssBody.className);
|
||||
const theme = getTheme(productFlavor);
|
||||
if (theme.bodyClassName) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { CellValue } from 'app/common/DocActions';
|
||||
import { isVersions } from 'app/common/gristTypes';
|
||||
import { inlineStyle } from 'app/common/gutil';
|
||||
import { BaseFormatter } from 'app/common/ValueFormatter';
|
||||
import { Diff, DIFF_DELETE, DIFF_INSERT, diff_match_patch as DiffMatchPatch, DIFF_EQUAL } from 'diff-match-patch';
|
||||
import { Diff, DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch as DiffMatchPatch } from 'diff-match-patch';
|
||||
import { Computed, dom } from 'grainjs';
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@ import * as gristTypes from 'app/common/gristTypes';
|
||||
import * as gutil from 'app/common/gutil';
|
||||
import { CellValue } from 'app/plugin/GristData';
|
||||
import { delay } from 'bluebird';
|
||||
import { Computed, Disposable, dom as grainjsDom, fromKo, Holder, IDisposable, makeTestId } from 'grainjs';
|
||||
import { Computed, Disposable, fromKo, dom as grainjsDom, Holder, IDisposable, makeTestId } from 'grainjs';
|
||||
import * as ko from 'knockout';
|
||||
import * as _ from 'underscore';
|
||||
|
||||
@@ -77,7 +77,7 @@ export class FieldBuilder extends Disposable {
|
||||
private readonly widgetCons: ko.Computed<{create: (...args: any[]) => NewAbstractWidget}>;
|
||||
private readonly docModel: DocModel;
|
||||
|
||||
public constructor(readonly gristDoc: GristDoc, readonly field: ViewFieldRec,
|
||||
public constructor(public readonly gristDoc: GristDoc, public readonly field: ViewFieldRec,
|
||||
private _cursor: Cursor) {
|
||||
super();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user