(core) updates from grist-core

pull/598/head
Alex Hall 10 months ago
commit 9b87a6f06a

@ -244,7 +244,7 @@ export class SelectionSummary extends Disposable {
} else {
for (const i of rowIndices) {
const value = values[i];
if (value !== null && value !== undefined && value !== '' && !isEmpty?.(value)) {
if (value !== null && value !== undefined && value !== '' && value !== false && !isEmpty?.(value)) {
countNonEmpty++;
}
}

@ -77,6 +77,7 @@ export class UrlState<IUrlState extends object> extends Disposable {
if (samePage) {
await this._stateImpl.delayPushUrl(prevState, newState);
try {
if (options.replace) {
this._window.history.replaceState(null, '', newUrl);
} else {
@ -84,6 +85,15 @@ export class UrlState<IUrlState extends object> extends Disposable {
}
// pushState/replaceState above do not trigger 'popstate' event, so we call loadState() manually.
this.loadState();
} catch (e) {
// If we fail, we may be in a context where Grist doesn't have
// control over history, e.g. an iframe with srcdoc. Go ahead
// and apply the application state change (e.g. switching to a
// different Grist page). The back button won't work, but what
// it should do in an embedded context is full of nuance anyway.
log.debug(`pushUrl failure: ${e}`);
this.state.set(this._stateImpl.decodeUrl(new URL(newUrl)));
}
} else {
this._window._urlStateLoadPage!(newUrl);
}

@ -270,7 +270,7 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
explanation: (
isDocOwner
? t("You can try reloading the document, or using recovery mode. \
Recovery mode opens the document to be fully accessible to owners, and inaccessible to others. \
Recovery mode opens the document to be fully accessible to owners, and inaccessible to others. \
It also disables formulas. [{{error}}]", {error: err.message})
: isDenied
? t('Sorry, access to this document has been denied. [{{error}}]', {error: err.message})

@ -658,7 +658,8 @@ def TASTEME(food):
def TEXT(number, format_type): # pylint: disable=unused-argument
"""
Converts a number into text according to a specified format. It is not yet implemented in
Grist.
Grist. You can use the similar Python functions str() to convert numbers into strings, and
optionally format() to specify the number format.
"""
raise NotImplementedError()

@ -397,7 +397,8 @@
"GristDoc": {
"Added new linked section to view {{viewName}}": "Added new linked section to view {{viewName}}",
"Import from file": "Import from file",
"Saved linked section {{title}} in view {{name}}": "Saved linked section {{title}} in view {{name}}"
"Saved linked section {{title}} in view {{name}}": "Saved linked section {{title}} in view {{name}}",
"go to webhook settings": "go to webhook settings"
},
"HomeIntro": {
"Any documents created in this site will appear here.": "Any documents created in this site will appear here.",

Binary file not shown.

@ -391,6 +391,7 @@ describe('Dates.ntest', function() {
await gu.clickCellRC(0, 1);
await gu.sendKeys([$.ALT, '=']);
await gu.waitForServer();
await gu.waitAppFocus(false);
await gu.sendKeys("Diff", $.ENTER);
await gu.waitForServer();
await gu.sendKeys('=');

@ -4,7 +4,7 @@ import * as gu from 'test/nbrowser/gristUtils';
import {server, setupTestSuite} from 'test/nbrowser/testUtils';
describe('SelectByRefList', function() {
this.timeout(60000);
this.timeout(80000);
setupTestSuite();
addToRepl('gu2', gu);
gu.bigScreen();

@ -130,11 +130,6 @@ describe('SelectionSummary', function () {
count: 2,
sum: null,
});
await selectAndAssert({col: 2, row: 0}, {col: 3, row: 5}, {
dimensions: '62',
count: 11,
sum: null,
});
// Scroll horizontally to the end of the table.
await gu.sendKeys(Key.END);
@ -151,6 +146,15 @@ describe('SelectionSummary', function () {
});
});
it('does not count false values', async function () {
// False values in boolean columns should not be included in count
await selectAndAssert({col: 2, row: 0}, {col: 3, row: 5}, {
dimensions: '62',
count: 9,
sum: null,
});
});
it('uses the show column of reference columns for computations', async function () {
// Column 6 is a Reference column pointing to column 0.
await gu.sendKeys(Key.HOME);

@ -16,7 +16,6 @@ describe('WebhookOverflow', function () {
before(async function () {
oldEnv = new EnvironmentSnapshot();
//host = new URL(server.getHost()).host;
process.env.ALLOWED_WEBHOOK_DOMAINS = '*';
process.env.GRIST_MAX_QUEUE_SIZE = '2';
await server.restart();
@ -50,45 +49,31 @@ describe('WebhookOverflow', function () {
await driver.sendKeys(...keys);
}
it('should show a message when overflown', async function () {
it('should show a message when overflowed', async function () {
await gu.openPage('Table2');
await gu.getCell('A', 1).click();
await gu.enterCell('123');
await gu.getCell('B', 1).click();
await enterCellWithoutWaitingOnServer('124');
const toast = await driver.wait(() => gu.getToasts(), 10000);
await gu.waitToPass(async () => {
const toast = await gu.getToasts();
assert.include(toast, 'New changes are temporarily suspended. Webhooks queue overflowed.' +
' Please check webhooks settings, remove invalid webhooks, and clean the queue.\ngo to webhook settings');
}, 4000);
});
it('message should disappear after clearing queue', async function () {
await openWebhookPageWithoutWaitForServer();
await driver.findContent('button', /Clear Queue/).click();
await gu.waitForServer();
await waitForOverflownMessageToDisappear();
const toast = await driver.wait(() => gu.getToasts());
await gu.waitToPass(async () => {
const toast = await gu.getToasts();
assert.notInclude(toast, 'New changes are temporarily suspended. Webhooks queue overflowed.' +
' Please check webhooks settings, remove invalid webhooks, and clean the queue.\ngo to webhook settings');
}, 12500);
});
});
async function waitForOverflownMessageToDisappear(maxWait = 12500) {
await driver.wait(async () => {
try {
for (;;) {
const toasts = await gu.getToasts();
const filteredToasts = toasts.find(t => t=='New changes are temporarily suspended. Webhooks queue overflowed.' +
' Please check webhooks settings, remove invalid webhooks, and clean the queue.\ngo to webhook settings');
if (!filteredToasts) {
return true;
}
}
} catch (e) {
return false;
}
}, maxWait, 'Overflown message did not disappear');
}
async function openWebhookPageWithoutWaitForServer() {
await openDocumentSettings();
const button = await driver.findContentWait('a', /Manage Webhooks/, 3000);

Loading…
Cancel
Save