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) {
|
||||
const seenWarnings = this._gristDoc.docPageModel.appModel.deprecatedWarnings;
|
||||
if (!this._hasSeenWarning(c.name)) {
|
||||
markAsSeen(seenWarnings, c.name);
|
||||
this._showWarning(c.desc);
|
||||
this._showWarning(c);
|
||||
return false; // Stop processing.
|
||||
} else {
|
||||
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
|
||||
// to find the selected cell and show the message there. Otherwise, we show it in the
|
||||
// bottom right corner as a warning.
|
||||
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) {
|
||||
reportMessage(() => dom('div', this._createMessage(desc)), {
|
||||
reportMessage(() => dom('div', this._createMessage(c.desc)), {
|
||||
level: 'info',
|
||||
key: 'deprecated-command',
|
||||
});
|
||||
} 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] === '{') {
|
||||
const otherCommand = commands.allCommands[part.slice(1, -1)];
|
||||
if (otherCommand) {
|
||||
elements.push(otherCommand.getKeysDom());
|
||||
elements.push(otherCommand.getKeysDom(() => dom('span', 'or')));
|
||||
}
|
||||
} else {
|
||||
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.
|
||||
*/
|
||||
Command.prototype.getKeysDom = function() {
|
||||
Command.prototype.getKeysDom = function(separator) {
|
||||
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.style('margin-bottom', '10px'),
|
||||
),
|
||||
dom('div',
|
||||
labeledSquareCheckbox(remember, "Don't ask again.", testId('confirm-remember')),
|
||||
dom.style('margin-bottom', '10px'),
|
||||
),
|
||||
cssButtons(
|
||||
dom.style('margin-bottom', '12px'),
|
||||
primaryButton('Delete', testId('confirm-save'), dom.on('click', () => {
|
||||
onSave(remember.get());
|
||||
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(
|
||||
refElement: Element,
|
||||
content: DomContents
|
||||
content: DomContents,
|
||||
onClose: (checked: boolean) => void,
|
||||
) {
|
||||
const remember = observable(false);
|
||||
const tooltip = modalTooltip(refElement, (ctl) =>
|
||||
cssWideContainer(
|
||||
testId('popup-warning-deprecated'),
|
||||
elem => { FocusLayer.create(ctl, {defaultFocusElem: elem, pauseMousetrap: true}); },
|
||||
dom.onKeyDown({
|
||||
Escape: () => ctl.close(),
|
||||
Enter: () => ctl.close(),
|
||||
Escape: () => { ctl.close(); onClose(remember.get()); },
|
||||
Enter: () => { ctl.close(); onClose(remember.get()); },
|
||||
}),
|
||||
content,
|
||||
cssButtons(
|
||||
dom.style('margin-top', '12px'),
|
||||
dom.style('justify-content', 'right'),
|
||||
basicButton('Close', testId('confirm-cancel'), dom.on('click', () => ctl.close()))
|
||||
dom.style('justify-content', 'space-between'),
|
||||
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, `
|
||||
max-width: 210px;
|
||||
max-width: 270px;
|
||||
`);
|
||||
|
||||
const cssWideContainer = styled(cssTheme, `
|
||||
|
@ -9,6 +9,7 @@ import {waitGrainObs} from 'app/common/gutil';
|
||||
import {IOpenController, IPopupDomCreator, IPopupOptions, PopupControl, popupOpen} from 'popweasel';
|
||||
import {Computed, Disposable, dom, DomContents, DomElementArg, input, keyframes,
|
||||
MultiHolder, Observable, styled} from 'grainjs';
|
||||
import {cssMenuElem} from 'app/client/ui2018/menus';
|
||||
|
||||
// IModalControl is passed into the function creating the body of the modal.
|
||||
export interface IModalControl {
|
||||
@ -492,11 +493,10 @@ export function modalTooltip(
|
||||
|
||||
/* CSS styled components */
|
||||
|
||||
const cssModalTooltip = styled('div', `
|
||||
padding: 16px;
|
||||
const cssModalTooltip = styled(cssMenuElem, `
|
||||
padding: 16px 24px;
|
||||
background: ${theme.modalBg};
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 2px 18px 0 ${theme.modalInnerShadow}, 0 0 1px 0 ${theme.modalOuterShadow};
|
||||
outline: none;
|
||||
& > div {
|
||||
outline: none;
|
||||
|
Loading…
Reference in New Issue
Block a user