mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Updating flow and UI for shortcut warnings
Summary: - Popup looks different (better shadow, order and alignment) - Warnings need to be dismissed by checking "Don't show again" button, pressing Esc/Enter or clicking away just hides the popup, but it will be opened once again. - Dismissing one warning popup (about zoom keys), dismisses them all Test Plan: Updated Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3683
This commit is contained in:
parent
64710b60f3
commit
fb16c3de56
@ -63,28 +63,46 @@ export class DeprecatedCommands extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleCommand(c: Command) {
|
private _handleCommand(c: Command) {
|
||||||
const seenWarnings = this._gristDoc.docPageModel.appModel.deprecatedWarnings;
|
|
||||||
if (!this._hasSeenWarning(c.name)) {
|
if (!this._hasSeenWarning(c.name)) {
|
||||||
markAsSeen(seenWarnings, c.name);
|
this._showWarning(c);
|
||||||
this._showWarning(c.desc);
|
|
||||||
return false; // Stop processing.
|
return false; // Stop processing.
|
||||||
} else {
|
} else {
|
||||||
return true; // Continue processing.
|
return true; // Continue processing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showWarning(desc: string) {
|
private _showWarning(c: Command) {
|
||||||
// Try to figure out where to show the message. If we have active view, we can try
|
// Try to figure out where to show the message. If we have active view, we can try
|
||||||
// to find the selected cell and show the message there. Otherwise, we show it in the
|
// to find the selected cell and show the message there. Otherwise, we show it in the
|
||||||
// bottom right corner as a warning.
|
// bottom right corner as a warning.
|
||||||
const selectedCell = this._gristDoc.currentView.get()?.viewPane.querySelector(".selected_cursor");
|
const selectedCell = this._gristDoc.currentView.get()?.viewPane.querySelector(".selected_cursor");
|
||||||
|
const seenWarnings = this._gristDoc.docPageModel.appModel.deprecatedWarnings;
|
||||||
|
function onClose(checked: boolean) {
|
||||||
|
if (checked) {
|
||||||
|
// For deprecated zoom commands we have the same messages, so mark them as seen.
|
||||||
|
const zoomCommands: DeprecationWarning[] = [
|
||||||
|
'deprecatedDeleteRecords',
|
||||||
|
'deprecatedInsertRecordAfter',
|
||||||
|
'deprecatedInsertRowBefore',
|
||||||
|
];
|
||||||
|
if (zoomCommands.includes(c.name as any)) {
|
||||||
|
zoomCommands.forEach((name) => markAsSeen(seenWarnings, name));
|
||||||
|
} else {
|
||||||
|
markAsSeen(seenWarnings, c.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!selectedCell) {
|
if (!selectedCell) {
|
||||||
reportMessage(() => dom('div', this._createMessage(desc)), {
|
reportMessage(() => dom('div', this._createMessage(c.desc)), {
|
||||||
level: 'info',
|
level: 'info',
|
||||||
key: 'deprecated-command',
|
key: 'deprecated-command',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
showDeprecatedWarning(selectedCell, this._createMessage(desc));
|
showDeprecatedWarning(
|
||||||
|
selectedCell,
|
||||||
|
this._createMessage(c.desc),
|
||||||
|
onClose
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +121,7 @@ export class DeprecatedCommands extends Disposable {
|
|||||||
if (part[0] === '{') {
|
if (part[0] === '{') {
|
||||||
const otherCommand = commands.allCommands[part.slice(1, -1)];
|
const otherCommand = commands.allCommands[part.slice(1, -1)];
|
||||||
if (otherCommand) {
|
if (otherCommand) {
|
||||||
elements.push(otherCommand.getKeysDom());
|
elements.push(otherCommand.getKeysDom(() => dom('span', 'or')));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
elements.push(cssTallerText(part));
|
elements.push(cssTallerText(part));
|
||||||
|
@ -159,9 +159,10 @@ Command.prototype.getDesc = function() {
|
|||||||
/**
|
/**
|
||||||
* Returns DOM for the keyboard shortcuts, wrapped in cute boxes that look like keyboard keys.
|
* Returns DOM for the keyboard shortcuts, wrapped in cute boxes that look like keyboard keys.
|
||||||
*/
|
*/
|
||||||
Command.prototype.getKeysDom = function() {
|
Command.prototype.getKeysDom = function(separator) {
|
||||||
return dom('span.shortcut_keys',
|
return dom('span.shortcut_keys',
|
||||||
this.humanKeys.map(key => dom('span.shortcut_key_image', key))
|
separator ? this.humanKeys.map((key, i) => [i ? separator() : null, dom('span.shortcut_key_image', key)])
|
||||||
|
: this.humanKeys.map(key => dom('span.shortcut_key_image', key))
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,16 +35,16 @@ export function buildConfirmDelete(
|
|||||||
dom('div', `Are you sure you want to delete ${single ? 'this' : 'these'} record${single ? '' : 's'}?`,
|
dom('div', `Are you sure you want to delete ${single ? 'this' : 'these'} record${single ? '' : 's'}?`,
|
||||||
dom.style('margin-bottom', '10px'),
|
dom.style('margin-bottom', '10px'),
|
||||||
),
|
),
|
||||||
|
dom('div',
|
||||||
|
labeledSquareCheckbox(remember, "Don't ask again.", testId('confirm-remember')),
|
||||||
|
dom.style('margin-bottom', '10px'),
|
||||||
|
),
|
||||||
cssButtons(
|
cssButtons(
|
||||||
dom.style('margin-bottom', '12px'),
|
|
||||||
primaryButton('Delete', testId('confirm-save'), dom.on('click', () => {
|
primaryButton('Delete', testId('confirm-save'), dom.on('click', () => {
|
||||||
onSave(remember.get());
|
onSave(remember.get());
|
||||||
ctl.close();
|
ctl.close();
|
||||||
})),
|
})),
|
||||||
basicButton('Cancel', testId('confirm-cancel'), dom.on('click', () => ctl.close()))
|
basicButton('Cancel', testId('confirm-cancel'), dom.on('click', () => ctl.close()))
|
||||||
),
|
|
||||||
dom('div',
|
|
||||||
labeledSquareCheckbox(remember, "Don't ask again.", testId('confirm-remember')),
|
|
||||||
)
|
)
|
||||||
), {}
|
), {}
|
||||||
);
|
);
|
||||||
@ -60,21 +60,29 @@ export function buildConfirmDelete(
|
|||||||
|
|
||||||
export function showDeprecatedWarning(
|
export function showDeprecatedWarning(
|
||||||
refElement: Element,
|
refElement: Element,
|
||||||
content: DomContents
|
content: DomContents,
|
||||||
|
onClose: (checked: boolean) => void,
|
||||||
) {
|
) {
|
||||||
|
const remember = observable(false);
|
||||||
const tooltip = modalTooltip(refElement, (ctl) =>
|
const tooltip = modalTooltip(refElement, (ctl) =>
|
||||||
cssWideContainer(
|
cssWideContainer(
|
||||||
testId('popup-warning-deprecated'),
|
testId('popup-warning-deprecated'),
|
||||||
elem => { FocusLayer.create(ctl, {defaultFocusElem: elem, pauseMousetrap: true}); },
|
elem => { FocusLayer.create(ctl, {defaultFocusElem: elem, pauseMousetrap: true}); },
|
||||||
dom.onKeyDown({
|
dom.onKeyDown({
|
||||||
Escape: () => ctl.close(),
|
Escape: () => { ctl.close(); onClose(remember.get()); },
|
||||||
Enter: () => ctl.close(),
|
Enter: () => { ctl.close(); onClose(remember.get()); },
|
||||||
}),
|
}),
|
||||||
content,
|
content,
|
||||||
cssButtons(
|
cssButtons(
|
||||||
dom.style('margin-top', '12px'),
|
dom.style('margin-top', '12px'),
|
||||||
dom.style('justify-content', 'right'),
|
dom.style('justify-content', 'space-between'),
|
||||||
basicButton('Close', testId('confirm-cancel'), dom.on('click', () => ctl.close()))
|
dom.style('align-items', 'center'),
|
||||||
|
dom('div',
|
||||||
|
labeledSquareCheckbox(remember, "Don't show again.", testId('confirm-remember')),
|
||||||
|
),
|
||||||
|
basicButton('Dismiss', testId('confirm-save'),
|
||||||
|
dom.on('click', () => { ctl.close(); onClose(remember.get()); })
|
||||||
|
)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -133,7 +141,7 @@ const cssButtons = styled('div', `
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
const cssContainer = styled(cssTheme, `
|
const cssContainer = styled(cssTheme, `
|
||||||
max-width: 210px;
|
max-width: 270px;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const cssWideContainer = styled(cssTheme, `
|
const cssWideContainer = styled(cssTheme, `
|
||||||
|
@ -9,6 +9,7 @@ import {waitGrainObs} from 'app/common/gutil';
|
|||||||
import {IOpenController, IPopupDomCreator, IPopupOptions, PopupControl, popupOpen} from 'popweasel';
|
import {IOpenController, IPopupDomCreator, IPopupOptions, PopupControl, popupOpen} from 'popweasel';
|
||||||
import {Computed, Disposable, dom, DomContents, DomElementArg, input, keyframes,
|
import {Computed, Disposable, dom, DomContents, DomElementArg, input, keyframes,
|
||||||
MultiHolder, Observable, styled} from 'grainjs';
|
MultiHolder, Observable, styled} from 'grainjs';
|
||||||
|
import {cssMenuElem} from 'app/client/ui2018/menus';
|
||||||
|
|
||||||
// IModalControl is passed into the function creating the body of the modal.
|
// IModalControl is passed into the function creating the body of the modal.
|
||||||
export interface IModalControl {
|
export interface IModalControl {
|
||||||
@ -492,11 +493,10 @@ export function modalTooltip(
|
|||||||
|
|
||||||
/* CSS styled components */
|
/* CSS styled components */
|
||||||
|
|
||||||
const cssModalTooltip = styled('div', `
|
const cssModalTooltip = styled(cssMenuElem, `
|
||||||
padding: 16px;
|
padding: 16px 24px;
|
||||||
background: ${theme.modalBg};
|
background: ${theme.modalBg};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0 2px 18px 0 ${theme.modalInnerShadow}, 0 0 1px 0 ${theme.modalOuterShadow};
|
|
||||||
outline: none;
|
outline: none;
|
||||||
& > div {
|
& > div {
|
||||||
outline: none;
|
outline: none;
|
||||||
|
Loading…
Reference in New Issue
Block a user