mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) updates from grist-core
This commit is contained in:
commit
fb276bade7
@ -9,8 +9,11 @@ import {icon} from 'app/client/ui2018/icons';
|
||||
import {cssModalTooltip, modalTooltip} from 'app/client/ui2018/modals';
|
||||
import {dom, DomContents, keyframes, observable, styled, svg} from 'grainjs';
|
||||
import {IPopupOptions} from 'popweasel';
|
||||
import {makeT} from 'app/client/lib/localization';
|
||||
import merge = require('lodash/merge');
|
||||
|
||||
const t = makeT('modals');
|
||||
|
||||
/**
|
||||
* This is a file for all custom and pre-configured popups, modals, toasts and tooltips, used
|
||||
* in more then one component.
|
||||
@ -35,19 +38,21 @@ export function buildConfirmDelete(
|
||||
Escape: () => ctl.close(),
|
||||
Enter: () => { onSave(remember.get()); ctl.close(); },
|
||||
}),
|
||||
dom('div', `Are you sure you want to delete ${single ? 'this' : 'these'} record${single ? '' : 's'}?`,
|
||||
dom('div', single ?
|
||||
t(`Are you sure you want to delete this record?`)
|
||||
: t(`Are you sure you want to delete these records?`),
|
||||
dom.style('margin-bottom', '10px'),
|
||||
),
|
||||
dom('div',
|
||||
labeledSquareCheckbox(remember, "Don't ask again.", testId('confirm-remember')),
|
||||
labeledSquareCheckbox(remember, t("Don't ask again."), testId('confirm-remember')),
|
||||
dom.style('margin-bottom', '10px'),
|
||||
),
|
||||
cssButtons(
|
||||
primaryButton('Delete', testId('confirm-save'), dom.on('click', () => {
|
||||
primaryButton(t('Delete'), testId('confirm-save'), dom.on('click', () => {
|
||||
onSave(remember.get());
|
||||
ctl.close();
|
||||
})),
|
||||
basicButton('Cancel', testId('confirm-cancel'), dom.on('click', () => ctl.close()))
|
||||
basicButton(t('Cancel'), testId('confirm-cancel'), dom.on('click', () => ctl.close()))
|
||||
)
|
||||
), {}
|
||||
);
|
||||
@ -81,9 +86,9 @@ export function showDeprecatedWarning(
|
||||
dom.style('justify-content', 'space-between'),
|
||||
dom.style('align-items', 'center'),
|
||||
dom('div',
|
||||
labeledSquareCheckbox(remember, "Don't show again.", testId('confirm-remember')),
|
||||
labeledSquareCheckbox(remember, t("Don't show again."), testId('confirm-remember')),
|
||||
),
|
||||
basicButton('Dismiss', testId('confirm-save'),
|
||||
basicButton(t('Dismiss'), testId('confirm-save'),
|
||||
dom.on('click', () => { ctl.close(); onClose(remember.get()); })
|
||||
)
|
||||
),
|
||||
@ -105,7 +110,7 @@ export function showDeprecatedWarning(
|
||||
export function reportUndo(
|
||||
doc: GristDoc,
|
||||
messageLabel: string,
|
||||
buttonLabel = 'Undo to restore'
|
||||
buttonLabel = t('Undo to restore')
|
||||
) {
|
||||
// First create a notification with a button to undo the delete.
|
||||
let notification = reportSuccess(messageLabel, {
|
||||
@ -179,12 +184,12 @@ export function showBehavioralPrompt(
|
||||
dom.style('align-items', 'center'),
|
||||
dom('div',
|
||||
cssSkipTipsCheckbox(dontShowTips,
|
||||
cssSkipTipsCheckboxLabel("Don't show tips"),
|
||||
cssSkipTipsCheckboxLabel(t("Don't show tips")),
|
||||
testId('behavioral-prompt-dont-show-tips')
|
||||
),
|
||||
dom.style('visibility', hideDontShowTips ? 'hidden' : ''),
|
||||
),
|
||||
cssDismissPromptButton('Got it', testId('behavioral-prompt-dismiss'),
|
||||
cssDismissPromptButton(t('Got it'), testId('behavioral-prompt-dismiss'),
|
||||
dom.on('click', () => { onClose(dontShowTips.get()); ctl.close(); })
|
||||
),
|
||||
),
|
||||
|
@ -526,11 +526,19 @@ export class Client {
|
||||
}
|
||||
}
|
||||
|
||||
private async _onMessage(message: string): Promise<void> {
|
||||
try {
|
||||
await this._onMessageImpl(message);
|
||||
} catch (err) {
|
||||
this._log.warn(null, 'onMessage error received for message "%s": %s', shortDesc(message), err.stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from a client. All requests from a client get a response, at least to
|
||||
* indicate success or failure.
|
||||
*/
|
||||
private async _onMessage(message: string): Promise<void> {
|
||||
private async _onMessageImpl(message: string): Promise<void> {
|
||||
const request = JSON.parse(message);
|
||||
if (request.beat) {
|
||||
// this is a heart beat, to keep the websocket alive. No need to reply.
|
||||
|
@ -433,7 +433,19 @@
|
||||
"Created by": "Created by",
|
||||
"Detect duplicates in...": "Detect duplicates in...",
|
||||
"Last updated at": "Last updated at",
|
||||
"Last updated by": "Last updated by"
|
||||
"Last updated by": "Last updated by",
|
||||
"Any": "Any",
|
||||
"Numeric": "Numeric",
|
||||
"Text": "Text",
|
||||
"Integer": "Integer",
|
||||
"Toggle": "Toggle",
|
||||
"Date": "Date",
|
||||
"DateTime": "DateTime",
|
||||
"Choice": "Choice",
|
||||
"Choice List": "Choice List",
|
||||
"Reference": "Reference",
|
||||
"Reference List": "Reference List",
|
||||
"Attachment": "Attachment"
|
||||
},
|
||||
"GristDoc": {
|
||||
"Added new linked section to view {{viewName}}": "Added new linked section to view {{viewName}}",
|
||||
@ -622,7 +634,23 @@
|
||||
"Widget": "Widget",
|
||||
"You do not have edit access to this document": "You do not have edit access to this document",
|
||||
"Add referenced columns": "Add referenced columns",
|
||||
"Reset form": "Reset form"
|
||||
"Reset form": "Reset form",
|
||||
"Configuration": "Configuration",
|
||||
"Default field value": "Default field value",
|
||||
"Display button": "Display button",
|
||||
"Enter text": "Enter text",
|
||||
"Field rules": "Field rules",
|
||||
"Field title": "Field title",
|
||||
"Hidden field": "Hidden field",
|
||||
"Layout": "Layout",
|
||||
"Redirect automatically after submission": "Redirect automatically after submission",
|
||||
"Redirection": "Redirection",
|
||||
"Required field": "Required field",
|
||||
"Submission": "Submission",
|
||||
"Submit another response": "Submit another response",
|
||||
"Submit button label": "Submit button label",
|
||||
"Success text": "Success text",
|
||||
"Table column name": "Table column name"
|
||||
},
|
||||
"RowContextMenu": {
|
||||
"Copy anchor link": "Copy anchor link",
|
||||
@ -761,7 +789,8 @@
|
||||
"Show raw data": "Show raw data",
|
||||
"Widget options": "Widget options",
|
||||
"Add to page": "Add to page",
|
||||
"Collapse widget": "Collapse widget"
|
||||
"Collapse widget": "Collapse widget",
|
||||
"Create a form": "Create a form"
|
||||
},
|
||||
"ViewSectionMenu": {
|
||||
"(customized)": "(customized)",
|
||||
@ -863,7 +892,16 @@
|
||||
"modals": {
|
||||
"Cancel": "Cancel",
|
||||
"Ok": "OK",
|
||||
"Save": "Save"
|
||||
"Save": "Save",
|
||||
"Are you sure you want to delete these records?": "Are you sure you want to delete these records?",
|
||||
"Are you sure you want to delete this record?": "Are you sure you want to delete this record?",
|
||||
"Delete": "Delete",
|
||||
"Dismiss": "Dismiss",
|
||||
"Don't ask again.": "Don't ask again.",
|
||||
"Don't show again.": "Don't show again.",
|
||||
"Don't show tips": "Don't show tips",
|
||||
"Undo to restore": "Undo to restore",
|
||||
"Got it": "Got it"
|
||||
},
|
||||
"pages": {
|
||||
"Duplicate Page": "Duplicate Page",
|
||||
@ -1266,5 +1304,28 @@
|
||||
"Publish your form?": "Publish your form?",
|
||||
"Unpublish": "Unpublish",
|
||||
"Unpublish your form?": "Unpublish your form?"
|
||||
},
|
||||
"Editor": {
|
||||
"Delete": "Delete"
|
||||
},
|
||||
"Menu": {
|
||||
"Building blocks": "Building blocks",
|
||||
"Columns": "Columns",
|
||||
"Copy": "Copy",
|
||||
"Cut": "Cut",
|
||||
"Insert question above": "Insert question above",
|
||||
"Insert question below": "Insert question below",
|
||||
"Paragraph": "Paragraph",
|
||||
"Paste": "Paste",
|
||||
"Separator": "Separator",
|
||||
"Unmapped fields": "Unmapped fields"
|
||||
},
|
||||
"UnmappedFieldsConfig": {
|
||||
"Clear": "Clear",
|
||||
"Map fields": "Map fields",
|
||||
"Mapped": "Mapped",
|
||||
"Select All": "Select All",
|
||||
"Unmap fields": "Unmap fields",
|
||||
"Unmapped": "Unmapped"
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,24 @@ describe('Comm', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should only log warning for malformed JSON data', async function () {
|
||||
const logMessages = await testUtils.captureLog('warn', async () => {
|
||||
ws.send('foobar');
|
||||
}, {waitForFirstLog: true});
|
||||
testUtils.assertMatchArray(logMessages, [
|
||||
/^warn: Client.* Unexpected token.*/
|
||||
]);
|
||||
});
|
||||
|
||||
it('should log warning when null value is passed', async function () {
|
||||
const logMessages = await testUtils.captureLog('warn', async () => {
|
||||
ws.send('null');
|
||||
}, {waitForFirstLog: true});
|
||||
testUtils.assertMatchArray(logMessages, [
|
||||
/^warn: Client.*Cannot read properties of null*/
|
||||
]);
|
||||
});
|
||||
|
||||
it("should support app-level events correctly", async function() {
|
||||
comm!.broadcastMessage('fooType' as any, 'hello');
|
||||
comm!.broadcastMessage('barType' as any, 'world');
|
||||
|
@ -126,25 +126,32 @@ export function setTmpLogLevel(level: string, optCaptureFunc?: (level: string, m
|
||||
*/
|
||||
export async function captureLog(
|
||||
minLevel: string, callback: (messages: string[]) => void|Promise<void>,
|
||||
options: {timestamp: boolean} = {timestamp: false}
|
||||
options: {timestamp?: boolean, waitForFirstLog?: boolean} = {timestamp: false, waitForFirstLog: false}
|
||||
): Promise<string[]> {
|
||||
const messages: string[] = [];
|
||||
const prevLogLevel = log.transports.file.level;
|
||||
const name = _.uniqueId('CaptureLog');
|
||||
|
||||
function capture(level: string, msg: string, meta: any) {
|
||||
if ((log as any).levels[level] <= (log as any).levels[minLevel]) { // winston types are off?
|
||||
const timePrefix = options.timestamp ? new Date().toISOString() + ' ' : '';
|
||||
messages.push(`${timePrefix}${level}: ${msg}${meta ? ' ' + serialize(meta) : ''}`);
|
||||
const captureFirstLogPromise = new Promise((resolve) => {
|
||||
function capture(level: string, msg: string, meta: any) {
|
||||
if ((log as any).levels[level] <= (log as any).levels[minLevel]) { // winston types are off?
|
||||
const timePrefix = options.timestamp ? new Date().toISOString() + ' ' : '';
|
||||
messages.push(`${timePrefix}${level}: ${msg}${meta ? ' ' + serialize(meta) : ''}`);
|
||||
resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!process.env.VERBOSE) {
|
||||
log.transports.file.level = -1 as any; // Suppress all log output.
|
||||
}
|
||||
log.add(CaptureTransport as any, { captureFunc: capture, name, level: minLevel}); // types are off.
|
||||
if (!process.env.VERBOSE) {
|
||||
log.transports.file.level = -1 as any; // Suppress all log output.
|
||||
}
|
||||
log.add(CaptureTransport as any, { captureFunc: capture, name, level: minLevel}); // types are off.
|
||||
});
|
||||
|
||||
try {
|
||||
await callback(messages);
|
||||
if (options.waitForFirstLog) {
|
||||
await captureFirstLogPromise;
|
||||
}
|
||||
} finally {
|
||||
log.remove(name);
|
||||
log.transports.file.level = prevLogLevel;
|
||||
|
Loading…
Reference in New Issue
Block a user