(core) When a checkbox is clicked on a new record, set default values determined by linking

Summary: Fixes a bug (reported in https://community.getgrist.com/t/bug-toggle-column-in-linking-widget-not-triggering-default-value/1657)

Test Plan: Added a test case that fails without this fix.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3699
This commit is contained in:
Dmitry S
2022-11-10 12:59:24 -05:00
parent 46148aa125
commit 5c67e12aa5
9 changed files with 185 additions and 98 deletions

View File

@@ -54,9 +54,9 @@ export class Cursor extends Disposable {
// Command to be manually triggered on cell selection. Moves the cursor to the selected cell.
// This is overridden by the formula editor to insert "$col" variables when clicking cells.
setCursor(this: Cursor, rowModel: BaseRowModel, colModel: BaseRowModel) {
setCursor(this: Cursor, rowModel: BaseRowModel, fieldModel: BaseRowModel) {
this.rowIndex(rowModel ? rowModel._index() : 0);
this.fieldIndex(colModel ? colModel._index()! : 0);
this.fieldIndex(fieldModel ? fieldModel._index()! : 0);
},
};

View File

@@ -21,7 +21,7 @@ export class DataRowModel extends BaseRowModel {
public _validationFailures: ko.PureComputed<Array<IRowModel<'_grist_Validations'>>>;
public _isAddRow: ko.Observable<boolean>;
private _isRealChange: ko.Observable<boolean>;
public _isRealChange: ko.Observable<boolean>;
public constructor(dataTableModel: DataTableModel, colNames: string[]) {
super(dataTableModel, colNames);

View File

@@ -1,38 +0,0 @@
var dom = require('../lib/dom');
var dispose = require('../lib/dispose');
var _ = require('underscore');
var kd = require('../lib/koDom');
var AbstractWidget = require('./AbstractWidget');
/**
* CheckBox - A bi-state CheckBox widget
*/
function CheckBox(field) {
AbstractWidget.call(this, field, {defaultTextColor: '#606060'});
}
dispose.makeDisposable(CheckBox);
_.extend(CheckBox.prototype, AbstractWidget.prototype);
CheckBox.prototype.buildConfigDom = function() {
return null;
};
CheckBox.prototype.buildDom = function(row) {
var value = row[this.field.colId()];
return dom('div.field_clip',
dom('div.widget_checkbox',
dom.on('click', () => {
if (!this.field.column().isRealFormula()) {
value.setAndSave(!value.peek());
}
}),
dom('div.widget_checkmark',
kd.show(value),
dom('div.checkmark_kick'),
dom('div.checkmark_stem')
)
)
);
};
module.exports = CheckBox;

View File

@@ -1,37 +0,0 @@
var dom = require('../lib/dom');
var dispose = require('../lib/dispose');
var _ = require('underscore');
var kd = require('../lib/koDom');
var AbstractWidget = require('./AbstractWidget');
/**
* Switch - A bi-state Switch widget
*/
function Switch(field) {
AbstractWidget.call(this, field, {defaultTextColor: '#2CB0AF'});
}
dispose.makeDisposable(Switch);
_.extend(Switch.prototype, AbstractWidget.prototype);
Switch.prototype.buildConfigDom = function() {
return null;
};
Switch.prototype.buildDom = function(row) {
var value = row[this.field.colId()];
return dom('div.field_clip',
dom('div.widget_switch',
kd.toggleClass('switch_on', value),
kd.toggleClass('switch_transition', row._isRealChange),
dom('div.switch_slider'),
dom('div.switch_circle'),
dom.on('click', () => {
if (!this.field.column().isRealFormula()) {
value.setAndSave(!value.peek());
}
})
)
);
};
module.exports = Switch;

View File

@@ -0,0 +1,66 @@
import * as commands from 'app/client/components/commands';
import { DataRowModel } from 'app/client/models/DataRowModel';
import { ViewFieldRec } from 'app/client/models/entities/ViewFieldRec';
import { KoSaveableObservable } from 'app/client/models/modelUtil';
import { NewAbstractWidget, Options } from 'app/client/widgets/NewAbstractWidget';
import { dom } from 'grainjs';
/**
* ToggleBase - The base class for toggle widgets, such as a checkbox or a switch.
*/
abstract class ToggleBase extends NewAbstractWidget {
protected _addClickEventHandler(row: DataRowModel) {
return dom.on('click', (event) => {
if (event.shiftKey) {
// Shift-click is for selection, don't also toggle the checkbox during it.
return;
}
if (!this.field.column().isRealFormula()) {
// Move the cursor here, and pretend that spacebar was pressed. This triggers an editing
// flow which is handled by CheckBoxEditor.skipEditor(). This way the edit applies to
// editRow, which handles setting default values based on widget linking.
commands.allCommands.setCursor.run(row, this.field);
commands.allCommands.input.run(' ');
}
});
}
}
export class ToggleCheckBox extends ToggleBase {
constructor(field: ViewFieldRec, _options: Options = {}) {
super(field, {defaultTextColor: '#606060'});
}
public buildDom(row: DataRowModel) {
const value = row.cells[this.field.colId.peek()] as KoSaveableObservable<boolean>;
return dom('div.field_clip',
dom('div.widget_checkbox',
dom('div.widget_checkmark',
dom.show(value),
dom('div.checkmark_kick'),
dom('div.checkmark_stem')
),
this._addClickEventHandler(row),
)
);
}
}
export class ToggleSwitch extends ToggleBase {
constructor(field: ViewFieldRec, _options: Options = {}) {
super(field, {defaultTextColor: '#2CB0AF'});
}
public buildDom(row: DataRowModel) {
const value = row.cells[this.field.colId.peek()] as KoSaveableObservable<boolean>;
return dom('div.field_clip',
dom('div.widget_switch',
dom.cls('switch_on', value),
dom.cls('switch_transition', row._isRealChange),
dom('div.switch_slider'),
dom('div.switch_circle'),
this._addClickEventHandler(row),
)
);
}
}

View File

@@ -1,6 +1,5 @@
import {AttachmentsEditor} from 'app/client/widgets/AttachmentsEditor';
import {AttachmentsWidget} from 'app/client/widgets/AttachmentsWidget';
import CheckBox from 'app/client/widgets/CheckBox';
import CheckBoxEditor from 'app/client/widgets/CheckBoxEditor';
import ChoiceEditor from 'app/client/widgets/ChoiceEditor';
import {ChoiceListCell} from 'app/client/widgets/ChoiceListCell';
@@ -22,7 +21,7 @@ import {ReferenceEditor} from 'app/client/widgets/ReferenceEditor';
import {ReferenceList} from 'app/client/widgets/ReferenceList';
import {ReferenceListEditor} from 'app/client/widgets/ReferenceListEditor';
import {Spinner} from 'app/client/widgets/Spinner';
import Switch from 'app/client/widgets/Switch';
import {ToggleCheckBox, ToggleSwitch} from 'app/client/widgets/Toggle';
import {getWidgetConfiguration} from 'app/client/widgets/UserType';
import {GristType} from 'app/plugin/GristData';
@@ -36,10 +35,10 @@ export const nameToWidget = {
'HyperLinkTextBox': HyperLinkTextBox,
'HyperLinkEditor': HyperLinkEditor,
'Spinner': Spinner,
'CheckBox': CheckBox,
'CheckBox': ToggleCheckBox,
'CheckBoxEditor': CheckBoxEditor,
'Reference': Reference,
'Switch': Switch,
'Switch': ToggleSwitch,
'ReferenceEditor': ReferenceEditor,
'ReferenceList': ReferenceList,
'ReferenceListEditor': ReferenceListEditor,