(core) Improving experience when editing group-by column.

Summary:
Improving experience when editing group-by column:
- Disable column rename
- Allow changing most widget properties:
 - Color/Background
 - Number format
 - Date/DateTime format (but not the timezone)
 - All toggle options (for toggle column)
- Remove Edit button on Choice Edit
- Changing the underlying column should reset all those options back to the original column.

Test Plan: nbrowser

Reviewers: alexmojaki

Reviewed By: alexmojaki

Subscribers: alexmojaki

Differential Revision: https://phab.getgrist.com/D3216
This commit is contained in:
Jarosław Sadziński
2022-01-18 12:48:57 +01:00
parent 9c57b565b2
commit d2077bc486
10 changed files with 196 additions and 15 deletions

View File

@@ -918,7 +918,12 @@ GridView.prototype.buildDom = function() {
kd.style('borderLeftWidth', v.borderWidthPx),
kd.foreach(v.viewFields(), field => {
var isEditingLabel = ko.pureComputed({
read: () => this.gristDoc.isReadonlyKo() || self.isPreview ? false : editIndex() === field._index(),
read: () => {
const goodIndex = () => editIndex() === field._index();
const isReadonly = () => this.gristDoc.isReadonlyKo() || self.isPreview;
const isSummary = () => Boolean(field.column().disableEditData());
return goodIndex() && !isReadonly() && !isSummary();
},
write: val => editIndex(val ? field._index() : -1)
}).extend({ rateLimit: 0 });
let filterTriggerCtl;

View File

@@ -18,6 +18,7 @@ export interface ACSelectItem extends ACItem {
export function buildACSelect(
owner: IDisposableOwner,
options: {
disabled?: Observable<boolean>,
acIndex: ACIndex<ACSelectItem>,
valueObs: Observable<string>,
save: (value: string, item: ACSelectItem|undefined) => Promise<void>|void
@@ -55,6 +56,9 @@ export function buildACSelect(
const onMouseDown = (ev: MouseEvent) => {
ev.preventDefault(); // Don't let it affect focus, since we focus/blur manually.
if (options.disabled?.get()) {
return;
}
if (!isOpen()) { textInput.focus(); }
openOrCommit();
};
@@ -73,6 +77,7 @@ export function buildACSelect(
dom.prop('value', valueObs),
dom.on('focus', (ev, elem) => elem.select()),
dom.on('blur', commitOrRevert),
dom.prop("disabled", (use) => options.disabled ? use(options.disabled) : false),
dom.onKeyDown({
Escape: revert,
Enter: openOrCommit,

View File

@@ -58,7 +58,8 @@ export function buildNameConfig(owner: MultiHolder, origColumn: ColumnRec, curso
cssColTieConnectors(),
cssToggleButton(icon('FieldReference'),
cssToggleButton.cls('-selected', (use) => !use(untieColId)),
dom.on('click', () => untieColId.saveOnly(!untieColId.peek())),
dom.on('click', () => !origColumn.disableModify.peek() && untieColId.saveOnly(!untieColId.peek())),
cssToggleButton.cls("-disabled", origColumn.disableModify),
testId('field-derive-id')
),
)
@@ -391,6 +392,10 @@ const cssToggleButton = styled(cssIconButton, `
&-selected:hover {
--icon-color: ${colors.darkGrey};
}
&-disabled, &-disabled:hover {
--icon-color: ${colors.light};
background-color: var(--grist-color-medium-grey-opaque);
}
`);
const cssColLabelBlock = styled('div', `

View File

@@ -91,7 +91,8 @@ export class ChoiceListEntry extends Disposable {
constructor(
private _values: Observable<string[]>,
private _choiceOptionsByName: Observable<ChoiceOptionsByName>,
private _onSave: (values: string[], choiceOptions: ChoiceOptionsByName, renames: Record<string, string>) => void
private _onSave: (values: string[], choiceOptions: ChoiceOptionsByName, renames: Record<string, string>) => void,
private _disabled: Observable<boolean>
) {
super();
@@ -177,12 +178,15 @@ export class ChoiceListEntry extends Disposable {
)
),
dom.on('click', () => this._startEditing()),
cssListBoxInactive.cls("-disabled", this._disabled),
testId('choice-list-entry')
),
cssButtonRow(
primaryButton('Edit',
dom.on('click', () => this._startEditing()),
testId('choice-list-entry-edit')
dom.maybe(use => !use(this._disabled), () =>
cssButtonRow(
primaryButton('Edit',
dom.on('click', () => this._startEditing()),
testId('choice-list-entry-edit')
)
)
)
);
@@ -191,7 +195,9 @@ export class ChoiceListEntry extends Disposable {
}
private _startEditing(): void {
this._isEditing.set(true);
if (!this._disabled.get()) {
this._isEditing.set(true);
}
}
private _save(): void {
@@ -369,6 +375,9 @@ const cssListBoxInactive = styled(cssListBox, `
&:hover {
border: 1px solid ${colors.hover};
}
&-disabled {
cursor: default;
}
`);
const cssListRow = styled('div', `

View File

@@ -5,7 +5,7 @@ import {KoSaveableObservable} from 'app/client/models/modelUtil';
import {cssLabel, cssRow} from 'app/client/ui/RightPanel';
import {testId} from 'app/client/ui2018/cssVars';
import {NTextBox} from 'app/client/widgets/NTextBox';
import {Computed, dom, styled} from 'grainjs';
import {Computed, dom, fromKo, styled} from 'grainjs';
import {choiceToken, DEFAULT_FILL_COLOR, DEFAULT_TEXT_COLOR} from 'app/client/widgets/ChoiceToken';
export interface IChoiceOptions {
@@ -73,7 +73,8 @@ export class ChoiceTextBox extends NTextBox {
ChoiceListEntry,
this._choiceValues,
this._choiceOptionsByName,
this.save.bind(this)
this.save.bind(this),
fromKo(this.field.column().disableEditData)
)
)
];

View File

@@ -66,7 +66,10 @@ DateTimeTextBox.prototype.buildConfigDom = function(isTransformConfig) {
var self = this;
return dom('div',
cssLabel("Timezone"),
cssRow(gdom.create(buildTZAutocomplete, moment, fromKo(this._timezone), this._setTimezone)),
cssRow(
gdom.create(buildTZAutocomplete, moment, fromKo(this._timezone), this._setTimezone,
{ disabled : fromKo(this.field.column().disableEditData)}),
),
self.buildDateConfigDom(),
cssLabel("Time Format"),
cssRow(dom(select(fromKo(self.standardTimeFormat), self.timeFormatOptions), dom.testId("Widget_timeFormat"))),

View File

@@ -47,7 +47,8 @@ export function buildTZAutocomplete(
owner: IDisposableOwner,
moment: MomentTimezone,
valueObs: Observable<string>,
save: (value: string) => Promise<void>|void
save: (value: string) => Promise<void>|void,
options?: { disabled?: Observable<boolean> }
) {
// Set a large maxResults, since it's sometimes nice to see all supported timezones (there are
// fewer than 1000 in practice).
@@ -69,7 +70,7 @@ export function buildTZAutocomplete(
}
};
return buildACSelect(owner,
{acIndex, valueObs, save: saveTZ},
{...options, acIndex, valueObs, save: saveTZ},
testId("tz-autocomplete")
);
}