(core) updates from grist-core

This commit is contained in:
Paul Fitzpatrick
2023-01-04 10:38:22 -05:00
41 changed files with 1079 additions and 101 deletions

View File

@@ -113,7 +113,9 @@ export class AccountPage extends Disposable {
),
css.subHeader(t("Two-factor authentication")),
css.description(
t("Two-factor authentication is an extra layer of security for your Grist account designed to ensure that you're the only person who can access your account, even if someone knows your password.")
t("Two-factor authentication is an extra layer of security for your Grist account " +
"designed to ensure that you're the only person who can access your account, " +
"even if someone knows your password.")
),
dom.create(MFAConfig, user),
),

View File

@@ -78,7 +78,8 @@ export class ApiKey extends Disposable {
dom.maybe((use) => !(use(this._apiKey) || this._anonymous), () => [
basicButton(t("Create"), dom.on('click', () => this._onCreate()), testId('create'),
dom.boolAttr('disabled', this._loading)),
description(t("By generating an API key, you will be able to make API calls for your own account."), testId('description')),
description(t("By generating an API key, you will be able to " +
"make API calls for your own account."), testId('description')),
]),
);
}
@@ -114,7 +115,8 @@ export class ApiKey extends Disposable {
confirmModal(
t("Remove API Key"), t("Remove"),
() => this._onDelete(),
t("You're about to delete an API key. This will cause all future requests using this API key to be rejected. Do you still want to delete?")
t("You're about to delete an API key. This will cause all future requests " +
"using this API key to be rejected. Do you still want to delete?")
);
}
}

View File

@@ -73,7 +73,9 @@ class ColumnPicker extends Disposable {
properValue,
options,
{
defaultLabel: this._column.typeDesc != "any" ? t("Pick a {{columnType}} column", {"columnType": this._column.typeDesc}) : t("Pick a column")
defaultLabel: this._column.typeDesc != "any"
? t("Pick a {{columnType}} column", {"columnType": this._column.typeDesc})
: t("Pick a column")
}
),
testId('mapping-for-' + this._column.name),
@@ -117,7 +119,11 @@ class ColumnListPicker extends Disposable {
col.label.peek(),
)),
wrongTypeCount > 0 ? menuText(
t("{{wrongTypeCount}} non-{{columnType}} columns are not shown", {wrongTypeCount, columnType: this._column.type.toLowerCase(), count: wrongTypeCount}),
t("{{wrongTypeCount}} non-{{columnType}} columns are not shown", {
wrongTypeCount,
columnType: this._column.type.toLowerCase(),
count: wrongTypeCount
}),
testId('map-message-' + this._column.name)
) : null
];
@@ -371,8 +377,12 @@ export class CustomSectionConfig extends Disposable {
}
switch(level) {
case AccessLevel.none: return cssConfirmLine(t("Widget does not require any permissions."));
case AccessLevel.read_table: return cssConfirmLine(t("Widget needs to {{read}} the current table.", {read: dom("b", "read")})); // TODO i18next
case AccessLevel.full: return cssConfirmLine(t("Widget needs {{fullAccess}} to this document.", {fullAccess: dom("b", "full access")})); // TODO i18next
case AccessLevel.read_table:
return cssConfirmLine(t("Widget needs to {{read}} the current table.", {read: dom("b", "read")}));
case AccessLevel.full:
return cssConfirmLine(t("Widget needs {{fullAccess}} to this document.", {
fullAccess: dom("b", "full access")
}));
default: throw new Error(`Unsupported ${level} access level`);
}
}

View File

@@ -21,7 +21,8 @@ export async function startDocTour(docData: DocData, docComm: DocComm, onFinishC
const invalidDocTour: IOnBoardingMsg[] = [{
title: t("No valid document tour"),
body: t("Cannot construct a document tour from the data in this document. Ensure there is a table named GristDocTour with columns Title, Body, Placement, and Location."),
body: t("Cannot construct a document tour from the data in this document. " +
"Ensure there is a table named GristDocTour with columns Title, Body, Placement, and Location."),
selector: 'document',
showHasModal: true,
}];

View File

@@ -58,7 +58,7 @@ export async function showDocSettingsModal(docInfo: DocInfoRec, docPageModel: Do
canChangeEngine ? [
// Small easter egg: you can click on the skull-and-crossbones to
// force a reload of the document.
cssDataRow(t("Engine (experimental {{span}} change at own risk):", {span:
cssDataRow(t("Engine (experimental {{span}} change at own risk):", {span:
dom('span', '☠',
dom.style('cursor', 'pointer'),
dom.on('click', async () => {

View File

@@ -83,10 +83,9 @@ class DuplicateTableModal extends Disposable {
),
cssWarning(
cssWarningIcon('Warning'),
dom('div',
t("Instead of duplicating tables, it's usually better to segment data using linked views. {{link}}", {link: cssLink({href: commonUrls.helpLinkingWidgets, target: '_blank'}, 'Read More.')})
), //TODO: i18next
dom('div', t("Instead of duplicating tables, it's usually better to segment data using linked views. {{link}}",
{link: cssLink({href: commonUrls.helpLinkingWidgets, target: '_blank'}, 'Read More.')}
)),
),
cssField(
cssCheckbox(

View File

@@ -1,4 +1,4 @@
import {makeT} from 'app/client/lib/localization'
import {makeT} from 'app/client/lib/localization';
const t = makeT('ExampleInfo');
@@ -36,7 +36,8 @@ export const buildExamples = (): IExampleInfo[] => [{
tutorialUrl: 'https://support.getgrist.com/investment-research/',
welcomeCard: {
title: t("Welcome to the Investment Research template"),
text: t("Check out our related tutorial to learn how to create summary tables and charts, and to link charts dynamically."),
text: t("Check out our related tutorial to learn how to create " +
"summary tables and charts, and to link charts dynamically."),
tutorialName: t("Tutorial: Analyze & Visualize"),
},
}, {

View File

@@ -41,7 +41,8 @@ export async function replaceTrunkWithFork(user: FullUser|null, doc: Document, a
if (cmp.summary === 'left' || cmp.summary === 'both') {
titleText = t("Original Has Modifications");
buttonText = t("Overwrite");
warningText = `${warningText} ${t("Be careful, the original has changes not in this document. Those changes will be overwritten.")}`;
warningText = `${warningText} ${t("Be careful, the original has changes " +
"not in this document. Those changes will be overwritten.")}`;
} else if (cmp.summary === 'unrelated') {
titleText = t("Original Looks Unrelated");
buttonText = t("Overwrite");

View File

@@ -268,8 +268,8 @@ export class PageWidgetSelect extends Disposable {
}) :
null;
private _isNewTableDisabled = Computed.create(this, this._value.type, (use, t) => !isValidSelection(
'New Table', t, this._options.isNewPage));
private _isNewTableDisabled = Computed.create(this, this._value.type, (use, type) => !isValidSelection(
'New Table', type, this._options.isNewPage));
constructor(
private _value: IWidgetValueObs,
@@ -399,8 +399,8 @@ export class PageWidgetSelect extends Disposable {
this._value.summarize.set(true);
}
private _selectType(t: IWidgetType) {
this._value.type.set(t);
private _selectType(type: IWidgetType) {
this._value.type.set(type);
}
private _selectTable(tid: TableId) {

View File

@@ -100,11 +100,11 @@ function removeView(activeDoc: GristDoc, viewId: number, pageName: string) {
const removePage = () => [['RemoveRecord', '_grist_Views', viewId]];
const removeAll = () => [
...removePage(),
...notVisibleTables.map(t => ['RemoveTable', t.tableId.peek()])
...notVisibleTables.map(tb => ['RemoveTable', tb.tableId.peek()])
];
if (notVisibleTables.length) {
const tableNames = notVisibleTables.map(t => t.tableNameDef.peek());
const tableNames = notVisibleTables.map(tb => tb.tableNameDef.peek());
buildPrompt(tableNames, async (option) => {
// Errors are handled in the dialog.
if (option === 'data') {
@@ -174,7 +174,7 @@ function buildOption(value: Observable<RemoveOption>, id: RemoveOption, content:
function buildWarning(tables: string[]) {
return cssWarning(
dom.forEach(tables, (t) => cssTableName(t, testId('table')))
dom.forEach(tables, (tb) => cssTableName(tb, testId('table')))
);
}

View File

@@ -39,8 +39,8 @@ import {icon} from 'app/client/ui2018/icons';
import {cssLink} from 'app/client/ui2018/links';
import {loadingSpinner} from 'app/client/ui2018/loaders';
import {menu, menuItem, menuText} from 'app/client/ui2018/menus';
import {confirmModal, cssModalBody, cssModalButtons, cssModalTitle, IModalControl,
modal, cssAnimatedModal} from 'app/client/ui2018/modals';
import {confirmModal, cssAnimatedModal, cssModalBody, cssModalButtons, cssModalTitle,
IModalControl, modal} from 'app/client/ui2018/modals';
export interface IUserManagerOptions {
permissionData: Promise<PermissionData>;

View File

@@ -35,7 +35,8 @@ export function createForbiddenPage(appModel: AppModel, message?: string) {
return pagePanelsError(appModel, t("Access denied{{suffix}}", {suffix: ''}), [
dom.domComputed(appModel.currentValidUser, user => user ? [
cssErrorText(message || t("You do not have access to this organization's documents.")),
cssErrorText(t("You are signed in as {{email}}. You can sign in with a different account, or ask an administrator for access.", {email: dom('b', user.email)})), // TODO: i18next
cssErrorText(t("You are signed in as {{email}}. You can sign in with a different " +
"account, or ask an administrator for access.", {email: dom('b', user.email)})),
] : [
// This page is not normally shown because a logged out user with no access will get
// redirected to log in. But it may be seen if a user logs out and returns to a cached
@@ -58,7 +59,7 @@ export function createForbiddenPage(appModel: AppModel, message?: string) {
export function createSignedOutPage(appModel: AppModel) {
document.title = t("Signed out{{suffix}}", {suffix: getPageTitleSuffix(getGristConfig())});
return pagePanelsError(appModel, t("Signed out{{suffix}}", {suffix: ''}), [
return pagePanelsError(appModel, t("Signed out{{suffix}}", {suffix: ''}), [
cssErrorText(t("You are now signed out.")),
cssButtonWrap(bigPrimaryButtonLink(
t("Sign in again"), {href: getLoginUrl()}, testId('error-signin')
@@ -73,7 +74,10 @@ export function createNotFoundPage(appModel: AppModel, message?: string) {
document.title = t("Page not found{{suffix}}", {suffix: getPageTitleSuffix(getGristConfig())});
return pagePanelsError(appModel, t("Page not found{{suffix}}", {suffix: ''}), [
cssErrorText(message || t("The requested page could not be found.{{separator}}Please check the URL and try again.", {separator: dom('br')})), // TODO: i18next
cssErrorText(message ||
t("The requested page could not be found.{{separator}}Please check the URL and try again.", {
separator: dom('br')
})),
cssButtonWrap(bigPrimaryButtonLink(t("Go to main page"), testId('error-primary-btn'),
urlState().setLinkUrl({}))),
cssButtonWrap(bigBasicButtonLink(t("Contact support"), {href: 'https://getgrist.com/contact'})),

View File

@@ -1,5 +1,5 @@
import {theme, vars} from 'app/client/ui2018/cssVars';
import {dom, IDomArgs, DomElementArg, IInputOptions, Observable, styled, subscribe} from 'grainjs';
import {dom, DomElementArg, IDomArgs, IInputOptions, Observable, styled, subscribe} from 'grainjs';
export const cssInput = styled('input', `
font-size: ${vars.mediumFontSize};