(core) Add rules to eslint to better match our coding conventions.

Summary:
We used tslint earlier, and on switching to eslint, some rules were not
transfered. This moves more rules over, for consistent conventions or helpful
warnings.

- Name private members with a leading underscore.
- Prefer interface over a type alias.
- Use consistent spacing around ':' in type annotations.
- Use consistent spacing around braces of code blocks.
- Use semicolons consistently at the ends of statements.
- Use braces around even one-liner blocks, like conditionals and loops.
- Warn about shadowed variables.

Test Plan: Fixed all new warnings. Should be no behavior changes in code.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2831
This commit is contained in:
Dmitry S
2021-05-23 13:43:11 -04:00
parent 0890749d15
commit d1c1416d78
50 changed files with 281 additions and 277 deletions

View File

@@ -105,7 +105,7 @@ export class AttachmentsEditor extends NewBaseEditor {
}),
// Close if clicking into the background. (The default modal's behavior for this isn't
// triggered because our content covers the whole screen.)
dom.on('click', (ev, elem) => { if (ev.target === elem) { ctl.close(); }}),
dom.on('click', (ev, elem) => { if (ev.target === elem) { ctl.close(); } }),
...this._buildDom(ctl)
];
}, {noEscapeKey: true});

View File

@@ -66,30 +66,30 @@ export class FieldBuilder extends Disposable {
public readonly widgetImpl: ko.Computed<NewAbstractWidget>;
public readonly diffImpl: NewAbstractWidget;
private readonly availableTypes: Computed<Array<IOptionFull<string>>>;
private readonly readOnlyPureType: ko.PureComputed<string>;
private readonly isRightType: ko.PureComputed<(value: CellValue, options?: any) => boolean>;
private readonly refTableId: ko.Computed<string | null>;
private readonly isRef: ko.Computed<boolean>;
private readonly _availableTypes: Computed<Array<IOptionFull<string>>>;
private readonly _readOnlyPureType: ko.PureComputed<string>;
private readonly _isRightType: ko.PureComputed<(value: CellValue, options?: any) => boolean>;
private readonly _refTableId: ko.Computed<string | null>;
private readonly _isRef: ko.Computed<boolean>;
private readonly _rowMap: Map<DataRowModel, Element>;
private readonly isTransformingFormula: ko.Computed<boolean>;
private readonly isTransformingType: ko.Computed<boolean>;
private readonly _isTransformingFormula: ko.Computed<boolean>;
private readonly _isTransformingType: ko.Computed<boolean>;
private readonly _fieldEditorHolder: Holder<IDisposable>;
private readonly widgetCons: ko.Computed<{create: (...args: any[]) => NewAbstractWidget}>;
private readonly docModel: DocModel;
private readonly _widgetCons: ko.Computed<{create: (...args: any[]) => NewAbstractWidget}>;
private readonly _docModel: DocModel;
public constructor(public readonly gristDoc: GristDoc, public readonly field: ViewFieldRec,
private _cursor: Cursor) {
super();
this.docModel = gristDoc.docModel;
this._docModel = gristDoc.docModel;
this.origColumn = field.column();
this.options = field.widgetOptionsJson;
this.readOnlyPureType = ko.pureComputed(() => this.field.column().pureType());
this._readOnlyPureType = ko.pureComputed(() => this.field.column().pureType());
// Observable with a list of available types.
this.availableTypes = Computed.create(this, (use) => {
this._availableTypes = Computed.create(this, (use) => {
const isFormula = use(this.origColumn.isFormula);
const types: Array<IOptionFull<string>> = [];
_.each(UserType.typeDefs, (def: any, key: string|number) => {
@@ -108,17 +108,17 @@ export class FieldBuilder extends Disposable {
});
// Observable which evaluates to a *function* that decides if a value is valid.
this.isRightType = ko.pureComputed(function() {
return gristTypes.isRightType(this.readOnlyPureType()) || _.constant(false);
this._isRightType = ko.pureComputed(function() {
return gristTypes.isRightType(this._readOnlyPureType()) || _.constant(false);
}, this);
// Returns a boolean indicating whether the column is type Reference.
this.isRef = this.autoDispose(ko.computed(() => {
this._isRef = this.autoDispose(ko.computed(() => {
return gutil.startsWith(this.field.column().type(), 'Ref:');
}));
// Gives the table ID to which the reference points.
this.refTableId = this.autoDispose(ko.computed({
this._refTableId = this.autoDispose(ko.computed({
read: () => gutil.removePrefix(this.field.column().type(), "Ref:"),
write: val => this._setType(`Ref:${val}`)
}));
@@ -148,11 +148,11 @@ export class FieldBuilder extends Disposable {
this.columnTransform = null;
// Returns a boolean indicating whether a formula transform is in progress.
this.isTransformingFormula = this.autoDispose(ko.computed(() => {
this._isTransformingFormula = this.autoDispose(ko.computed(() => {
return this.field.column().isTransforming() && this.columnTransform instanceof FormulaTransform;
}));
// Returns a boolean indicating whether a type transform is in progress.
this.isTransformingType = this.autoDispose(ko.computed(() => {
this._isTransformingType = this.autoDispose(ko.computed(() => {
return (this.field.column().isTransforming() || this.isCallPending()) &&
(this.columnTransform instanceof TypeTransform);
}));
@@ -165,14 +165,14 @@ export class FieldBuilder extends Disposable {
this._rowMap = new Map();
// Returns the constructor for the widget, and only notifies subscribers on changes.
this.widgetCons = this.autoDispose(koUtil.withKoUtils(ko.computed(function() {
this._widgetCons = this.autoDispose(koUtil.withKoUtils(ko.computed(function() {
return UserTypeImpl.getWidgetConstructor(this.options().widget,
this.readOnlyPureType());
this._readOnlyPureType());
}, this)).onlyNotifyUnequal());
// Computed builder for the widget.
this.widgetImpl = this.autoDispose(koUtil.computedBuilder(() => {
const cons = this.widgetCons();
const cons = this._widgetCons();
// Must subscribe to `colId` so that field.colId is rechecked on transform.
return cons.create.bind(cons, this.field, this.field.colId());
}, this).extend({ deferred: true }));
@@ -180,11 +180,8 @@ export class FieldBuilder extends Disposable {
this.diffImpl = this.autoDispose(DiffBox.create(this.field));
}
// dispose.makeDisposable(FieldBuilder);
public buildSelectWidgetDom() {
return grainjsDom.maybe((use) => !use(this.isTransformingType) && use(this.readOnlyPureType), type => {
return grainjsDom.maybe((use) => !use(this._isTransformingType) && use(this._readOnlyPureType), type => {
const typeWidgets = getTypeDefinition(type).widgets;
const widgetOptions = Object.keys(typeWidgets).map(label => ({
label,
@@ -206,32 +203,32 @@ export class FieldBuilder extends Disposable {
* Build the type change dom.
*/
public buildSelectTypeDom() {
const selectType = Computed.create(null, (use) => use(fromKo(this.readOnlyPureType)));
selectType.onWrite(newType => newType === this.readOnlyPureType.peek() || this._setType(newType));
const selectType = Computed.create(null, (use) => use(fromKo(this._readOnlyPureType)));
selectType.onWrite(newType => newType === this._readOnlyPureType.peek() || this._setType(newType));
const onDispose = () => (this.isDisposed() || selectType.set(this.field.column().pureType()));
return [
cssRow(
grainjsDom.autoDispose(selectType),
select(selectType, this.availableTypes, {
disabled: (use) => use(this.isTransformingFormula) || use(this.origColumn.disableModifyBase) ||
select(selectType, this._availableTypes, {
disabled: (use) => use(this._isTransformingFormula) || use(this.origColumn.disableModifyBase) ||
use(this.isCallPending)
}),
testId('type-select')
),
grainjsDom.maybe((use) => use(this.isRef) && !use(this.isTransformingType), () => this._buildRefTableSelect()),
grainjsDom.maybe(this.isTransformingType, () => {
grainjsDom.maybe((use) => use(this._isRef) && !use(this._isTransformingType), () => this._buildRefTableSelect()),
grainjsDom.maybe(this._isTransformingType, () => {
// Editor dom must be built before preparing transform.
return dom('div.type_transform_prompt',
kf.prompt(
dom('div',
grainjsDom.maybe(this.isRef, () => this._buildRefTableSelect()),
grainjsDom.maybe(this._isRef, () => this._buildRefTableSelect()),
grainjsDom.maybe((use) => use(this.field.column().isTransforming),
() => this.columnTransform!.buildDom())
)
)
),
grainjsDom.onDispose(onDispose)
);
);
})
];
}
@@ -242,7 +239,7 @@ export class FieldBuilder extends Disposable {
// Do not type transform a new/empty column or a formula column. Just make a best guess for
// the full type, and set it.
const column = this.field.column();
column.type.setAndSave(addColTypeSuffix(newType, column, this.docModel)).catch(reportError);
column.type.setAndSave(addColTypeSuffix(newType, column, this._docModel)).catch(reportError);
} else if (!this.columnTransform) {
this.columnTransform = TypeTransform.create(null, this.gristDoc, this);
return this.columnTransform.prepare(newType);
@@ -256,7 +253,7 @@ export class FieldBuilder extends Disposable {
// Builds the reference type table selector. Built when the column is type reference.
public _buildRefTableSelect() {
const allTables = Computed.create(null, (use) =>
use(this.docModel.allTableIds.getObservable()).map(tableId => ({
use(this._docModel.allTableIds.getObservable()).map(tableId => ({
value: tableId,
label: tableId,
icon: 'FieldTable' as const
@@ -266,7 +263,7 @@ export class FieldBuilder extends Disposable {
cssLabel('DATA FROM TABLE'),
cssRow(
dom.autoDispose(allTables),
select(fromKo(this.refTableId), allTables),
select(fromKo(this._refTableId), allTables),
testId('ref-table-select')
)
];
@@ -301,15 +298,15 @@ export class FieldBuilder extends Disposable {
kf.checkButton(transformButton,
dom('span.glyphicon.glyphicon-flash'),
dom.testId("FieldBuilder_editTransform"),
kd.toggleClass('disabled', () => this.isTransformingType() || this.origColumn.isFormula() ||
kd.toggleClass('disabled', () => this._isTransformingType() || this.origColumn.isFormula() ||
this.origColumn.disableModifyBase())
)
)
),
kd.maybe(this.isTransformingFormula, () => {
kd.maybe(this._isTransformingFormula, () => {
return this.columnTransform!.buildDom();
})
);
);
}
/**
@@ -319,7 +316,7 @@ export class FieldBuilder extends Disposable {
// NOTE: adding a grainjsDom .maybe here causes the disposable order of the widgetImpl and
// the dom created by the widgetImpl to get out of sync.
return dom('div',
kd.maybe(() => !this.isTransformingType() && this.widgetImpl(), (widget: NewAbstractWidget) =>
kd.maybe(() => !this._isTransformingType() && this.widgetImpl(), (widget: NewAbstractWidget) =>
dom('div',
widget.buildConfigDom(),
widget.buildColorConfigDom(),
@@ -401,7 +398,7 @@ export class FieldBuilder extends Disposable {
if (this.isDisposed()) { return null; } // Work around JS errors during field removal.
const value = row.cells[this.field.colId()];
const cell = value && value();
if (value && this.isRightType()(cell, this.options) || row._isAddRow.peek()) {
if (value && this._isRightType()(cell, this.options) || row._isAddRow.peek()) {
return this.widgetImpl();
} else if (gristTypes.isVersions(cell)) {
return this.diffImpl;
@@ -462,7 +459,7 @@ export class FieldBuilder extends Disposable {
return;
}
const editorCtor = UserTypeImpl.getEditorConstructor(this.options().widget, this.readOnlyPureType());
const editorCtor = UserTypeImpl.getEditorConstructor(this.options().widget, this._readOnlyPureType());
// constructor may be null for a read-only non-formula field, though not today.
if (!editorCtor) {
// Actually, we only expect buildEditorDom() to be called when isEditorActive() is false (i.e.

View File

@@ -47,10 +47,10 @@ export async function setAndSave(editRow: DataRowModel, field: ViewFieldRec, val
}
}
export type FieldEditorStateEvent = {
position : CellPosition,
currentState : any,
type: string
export interface FieldEditorStateEvent {
position: CellPosition;
currentState: any;
type: string;
}
export class FieldEditor extends Disposable {
@@ -125,7 +125,7 @@ export class FieldEditor extends Disposable {
unmakeFormula: () => this._unmakeFormula(),
};
const state : any = options.state;
const state: any = options.state;
this.rebuildEditor(isFormula, editValue, Number.POSITIVE_INFINITY, state);
@@ -141,7 +141,7 @@ export class FieldEditor extends Disposable {
}
// cursorPos refers to the position of the caret within the editor.
public rebuildEditor(isFormula: boolean, editValue: string|undefined, cursorPos: number, state? : any) {
public rebuildEditor(isFormula: boolean, editValue: string|undefined, cursorPos: number, state?: any) {
const editorCtor: IEditorConstructor = isFormula ? FormulaEditor : this._editorCtor;
const column = this._field.column();
@@ -168,11 +168,11 @@ export class FieldEditor extends Disposable {
// if editor supports live changes, connect it to the change emitter
if (editor.editorState) {
editor.autoDispose(editor.editorState.addListener((currentState) => {
const event : FieldEditorStateEvent = {
position : this.cellPosition(),
const event: FieldEditorStateEvent = {
position: this._cellPosition(),
currentState,
type : this._field.column.peek().pureType.peek()
}
type: this._field.column.peek().pureType.peek()
};
this.changeEmitter.emit(event);
}));
}
@@ -181,7 +181,7 @@ export class FieldEditor extends Disposable {
}
// calculate current cell's absolute position
private cellPosition() {
private _cellPosition() {
const rowId = this._editRow.getRowId();
const colRef = this._field.colRef.peek();
const sectionId = this._field.viewSection.peek().id.peek();
@@ -189,7 +189,7 @@ export class FieldEditor extends Disposable {
rowId,
colRef,
sectionId
}
};
return position;
}
@@ -240,11 +240,11 @@ export class FieldEditor extends Disposable {
// Cancels the edit
private _cancelEdit() {
const event : FieldEditorStateEvent = {
position : this.cellPosition(),
currentState : this._editorHolder.get()?.editorState?.get(),
type : this._field.column.peek().pureType.peek()
}
const event: FieldEditorStateEvent = {
position: this._cellPosition(),
currentState: this._editorHolder.get()?.editorState?.get(),
type: this._field.column.peek().pureType.peek()
};
this.cancelEmitter.emit(event);
this.dispose();
}
@@ -296,11 +296,11 @@ export class FieldEditor extends Disposable {
}
}
const event : FieldEditorStateEvent = {
position : this.cellPosition(),
currentState : this._editorHolder.get()?.editorState?.get(),
type : this._field.column.peek().pureType.peek()
}
const event: FieldEditorStateEvent = {
position: this._cellPosition(),
currentState: this._editorHolder.get()?.editorState?.get(),
type: this._field.column.peek().pureType.peek()
};
this.saveEmitter.emit(event);
const cursor = this._cursor;

View File

@@ -13,7 +13,7 @@ import {dom, Observable} from 'grainjs';
export class NTextEditor extends NewBaseEditor {
// Observable with current editor state (used by drafts or latest edit/position component)
public readonly editorState : Observable<string>;
public readonly editorState: Observable<string>;
protected cellEditorDiv: HTMLElement;
protected textInput: HTMLTextAreaElement;
@@ -29,7 +29,7 @@ export class NTextEditor extends NewBaseEditor {
constructor(options: Options) {
super(options);
const initialValue : string = undef(
const initialValue: string = undef(
options.state as string | undefined,
options.editValue, String(options.cellValue ?? ""));
this.editorState = Observable.create<string>(this, initialValue);
@@ -96,10 +96,10 @@ export class NTextEditor extends NewBaseEditor {
*/
protected onInput() {
// Resize the textbox whenever user types in it.
this.resizeInput()
this.resizeInput();
// notify about current state
this.editorState.set(String(this.getTextValue()))
this.editorState.set(String(this.getTextValue()));
}
/**

View File

@@ -21,7 +21,7 @@ export interface Options {
editValue?: string;
cursorPos: number;
commands: IEditorCommandGroup;
state? : any;
state?: any;
}
/**
@@ -58,7 +58,7 @@ export abstract class NewBaseEditor extends Disposable {
/**
* Current state of the editor. Optional, not all editors will report theirs current state.
*/
public editorState? : Observable<any>;
public editorState?: Observable<any>;
constructor(protected options: Options) {
super();