mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
trad: make the widgets and the Welcome Tour translatable
trad: make the widgets and the Welcome Tour translatable feat(translation): create automatisation for synchronize key in other locals than en trad: add french translations fix(trad): remove all useless code fix(trad): convert tab to space indentation fix(trad): add line to english trads
This commit is contained in:
parent
6804283603
commit
4befca1c92
@ -1,3 +1,4 @@
|
|||||||
|
import { makeT } from 'app/client/lib/localization';
|
||||||
import * as commands from 'app/client/components/commands';
|
import * as commands from 'app/client/components/commands';
|
||||||
import { urlState } from 'app/client/models/gristUrlState';
|
import { urlState } from 'app/client/models/gristUrlState';
|
||||||
import { IOnBoardingMsg, startOnBoarding } from "app/client/ui/OnBoardingPopups";
|
import { IOnBoardingMsg, startOnBoarding } from "app/client/ui/OnBoardingPopups";
|
||||||
@ -6,25 +7,26 @@ import { icon } from "app/client/ui2018/icons";
|
|||||||
import { cssLink } from "app/client/ui2018/links";
|
import { cssLink } from "app/client/ui2018/links";
|
||||||
import { dom, styled } from "grainjs";
|
import { dom, styled } from "grainjs";
|
||||||
|
|
||||||
|
const t = makeT('WelcomeTour');
|
||||||
|
|
||||||
export const welcomeTour: IOnBoardingMsg[] = [
|
export const welcomeTour: IOnBoardingMsg[] = [
|
||||||
{
|
{
|
||||||
title: 'Editing Data',
|
title: t('Editing Data'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p',
|
dom('p',
|
||||||
'Double-click or hit ', Key(KeyContent('Enter')), ' on a cell to edit it. ',
|
t('Double-click or hit {{enter}} on a cell to edit it. ', {enter: Key(KeyContent(t('Enter')))}),
|
||||||
'Start with ', Key(KeyStrong('=')), ' to enter a formula.'
|
t('Start with {{equal}} to enter a formula.', { equal: Key(KeyStrong('=')) }))
|
||||||
)
|
|
||||||
],
|
],
|
||||||
selector: '.field_clip',
|
selector: '.field_clip',
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '.tour-creator-panel',
|
selector: '.tour-creator-panel',
|
||||||
title: 'Configuring your document',
|
title: t('Configuring your document'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p',
|
dom('p',
|
||||||
'Toggle the ', dom('em', 'creator panel'), ' to format columns, ',
|
t('Toggle the {{creatorPanel}} to format columns, ', {creatorPanel: dom('em', t('creator panel'))}),
|
||||||
'convert to card view, select data, and more.'
|
t('convert to card view, select data, and more.')
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
placement: 'left',
|
placement: 'left',
|
||||||
@ -32,50 +34,52 @@ export const welcomeTour: IOnBoardingMsg[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '.tour-type-selector',
|
selector: '.tour-type-selector',
|
||||||
title: 'Customizing columns',
|
title: t('Customizing columns'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p',
|
dom('p',
|
||||||
'Set formatting options, formulas, or column types, such as dates, choices, or attachments. '),
|
t('Set formatting options, formulas, or column types, such as dates, choices, or attachments. ')),
|
||||||
dom('p',
|
dom('p',
|
||||||
'Make it relational! Use the ', Key('Reference'), ' type to link tables. '
|
t('Make it relational! Use the {{ref}} type to link tables. ', {ref: Key(t('Reference'))}),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
placement: 'right',
|
placement: 'right',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '.tour-add-new',
|
selector: '.tour-add-new',
|
||||||
title: 'Building up',
|
title: t('Building up'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p', 'Use ', Key('Add New'), ' to add widgets, pages, or import more data. ')
|
dom('p', t('Use {{addNew}} to add widgets, pages, or import more data. ', {addNew: Key(t('Add New'))}))
|
||||||
],
|
],
|
||||||
placement: 'right',
|
placement: 'right',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '.tour-share-icon',
|
selector: '.tour-share-icon',
|
||||||
title: 'Sharing',
|
title: t('Sharing'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p', 'Use the Share button (', TopBarButtonIcon('Share'), ') to share the document or export data.')
|
dom('p', t('Use the Share button ({{share}}) to share the document or export data.',
|
||||||
|
{share:TopBarButtonIcon(t('Share'))}))
|
||||||
],
|
],
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
cropPadding: true,
|
cropPadding: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '.tour-help-center',
|
selector: '.tour-help-center',
|
||||||
title: 'Flying higher',
|
title: t('Flying higher'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p', 'Use ', Key(GreyIcon('Help'), 'Help Center'), ' for documentation or questions.'),
|
dom('p', t('Use {{helpCenter}} for documentation or questions.', {helpCenter: Key(GreyIcon('Help'), t('Help Center'))})),
|
||||||
],
|
],
|
||||||
placement: 'right',
|
placement: 'right',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '.tour-welcome',
|
selector: '.tour-welcome',
|
||||||
title: 'Welcome to Grist!',
|
title: t('Welcome to Grist!'),
|
||||||
body: () => [
|
body: () => [
|
||||||
dom('p', 'Browse our ',
|
dom('p', t("Browse our {{templateLibrary}} to discover what's possible and get inspired.",
|
||||||
cssLink({target: '_blank', href: urlState().makeUrl({homePage: "templates"})},
|
{
|
||||||
'template library', cssInlineIcon('FieldLink')),
|
templateLibrary: cssLink({ target: '_blank', href: urlState().makeUrl({ homePage: "templates" }) },
|
||||||
"to discover what's possible and get inspired."
|
t('template library'), cssInlineIcon('FieldLink'))
|
||||||
),
|
}
|
||||||
|
)),
|
||||||
],
|
],
|
||||||
showHasModal: true,
|
showHasModal: true,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { makeT } from 'app/client/lib/localization';
|
||||||
import {allCommands} from 'app/client/components/commands';
|
import {allCommands} from 'app/client/components/commands';
|
||||||
import {GristDoc} from 'app/client/components/GristDoc';
|
import {GristDoc} from 'app/client/components/GristDoc';
|
||||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||||
@ -7,6 +8,8 @@ import {theme, vars} from 'app/client/ui2018/cssVars';
|
|||||||
import {ConditionalStyle} from 'app/client/widgets/ConditionalStyle';
|
import {ConditionalStyle} from 'app/client/widgets/ConditionalStyle';
|
||||||
import {Computed, Disposable, dom, DomContents, fromKo, styled} from 'grainjs';
|
import {Computed, Disposable, dom, DomContents, fromKo, styled} from 'grainjs';
|
||||||
|
|
||||||
|
const t = makeT('CellStyle');
|
||||||
|
|
||||||
export class CellStyle extends Disposable {
|
export class CellStyle extends Disposable {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -20,8 +23,8 @@ export class CellStyle extends Disposable {
|
|||||||
public buildDom(): DomContents {
|
public buildDom(): DomContents {
|
||||||
return [
|
return [
|
||||||
cssLine(
|
cssLine(
|
||||||
cssLabel('CELL STYLE'),
|
cssLabel(t('CELL STYLE')),
|
||||||
cssButton('Open row styles', dom.on('click', allCommands.viewTabOpen.run)),
|
cssButton(t('Open row styles'), dom.on('click', allCommands.viewTabOpen.run)),
|
||||||
),
|
),
|
||||||
cssRow(
|
cssRow(
|
||||||
dom.domComputedOwned(fromKo(this._field.config.style), (holder, options) => {
|
dom.domComputedOwned(fromKo(this._field.config.style), (holder, options) => {
|
||||||
@ -58,12 +61,12 @@ export class CellStyle extends Disposable {
|
|||||||
}, {
|
}, {
|
||||||
onSave: () => options.save(),
|
onSave: () => options.save(),
|
||||||
onRevert: () => options.revert(),
|
onRevert: () => options.revert(),
|
||||||
placeholder: use => use(hasMixedStyle) ? 'Mixed style' : 'Default cell style'
|
placeholder: use => use(hasMixedStyle) ? t('Mixed style') : t('Default cell style')
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
dom.create(ConditionalStyle, "Cell Style", this._field, this._gristDoc, fromKo(this._field.config.multiselect))
|
dom.create(ConditionalStyle, t("Cell Style"), this._field, this._gristDoc, fromKo(this._field.config.multiselect))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||||
import {KoSaveableObservable} from 'app/client/models/modelUtil';
|
import {KoSaveableObservable} from 'app/client/models/modelUtil';
|
||||||
@ -13,6 +14,8 @@ export type IChoiceOptions = Style
|
|||||||
export type ChoiceOptions = Record<string, IChoiceOptions | undefined>;
|
export type ChoiceOptions = Record<string, IChoiceOptions | undefined>;
|
||||||
export type ChoiceOptionsByName = Map<string, IChoiceOptions | undefined>;
|
export type ChoiceOptionsByName = Map<string, IChoiceOptions | undefined>;
|
||||||
|
|
||||||
|
const t = makeT('ChoiceTextBox');
|
||||||
|
|
||||||
export function getRenderFillColor(choiceOptions?: IChoiceOptions) {
|
export function getRenderFillColor(choiceOptions?: IChoiceOptions) {
|
||||||
return choiceOptions?.fillColor ?? DEFAULT_FILL_COLOR;
|
return choiceOptions?.fillColor ?? DEFAULT_FILL_COLOR;
|
||||||
}
|
}
|
||||||
@ -78,7 +81,7 @@ export class ChoiceTextBox extends NTextBox {
|
|||||||
);
|
);
|
||||||
return [
|
return [
|
||||||
super.buildConfigDom(),
|
super.buildConfigDom(),
|
||||||
cssLabel('CHOICES'),
|
cssLabel(t('CHOICES')),
|
||||||
cssRow(
|
cssRow(
|
||||||
dom.autoDispose(disabled),
|
dom.autoDispose(disabled),
|
||||||
dom.autoDispose(mixed),
|
dom.autoDispose(mixed),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {GristDoc} from 'app/client/components/GristDoc';
|
import {GristDoc} from 'app/client/components/GristDoc';
|
||||||
import {ColumnRec} from 'app/client/models/DocModel';
|
import {ColumnRec} from 'app/client/models/DocModel';
|
||||||
import {KoSaveableObservable} from 'app/client/models/modelUtil';
|
import {KoSaveableObservable} from 'app/client/models/modelUtil';
|
||||||
@ -18,6 +19,7 @@ import {Computed, Disposable, dom, DomContents, makeTestId, Observable, styled}
|
|||||||
import debounce = require('lodash/debounce');
|
import debounce = require('lodash/debounce');
|
||||||
|
|
||||||
const testId = makeTestId('test-widget-style-');
|
const testId = makeTestId('test-widget-style-');
|
||||||
|
const t = makeT('ConditionalStyle');
|
||||||
|
|
||||||
export class ConditionalStyle extends Disposable {
|
export class ConditionalStyle extends Disposable {
|
||||||
// Holds data from currently selected record (holds data only when this field has conditional styles).
|
// Holds data from currently selected record (holds data only when this field has conditional styles).
|
||||||
@ -71,12 +73,12 @@ export class ConditionalStyle extends Disposable {
|
|||||||
{ style: 'margin-top: 16px' },
|
{ style: 'margin-top: 16px' },
|
||||||
withInfoTooltip(
|
withInfoTooltip(
|
||||||
textButton(
|
textButton(
|
||||||
'Add conditional style',
|
t('Add conditional style'),
|
||||||
testId('add-conditional-style'),
|
testId('add-conditional-style'),
|
||||||
dom.on('click', () => this._ruleOwner.addEmptyRule()),
|
dom.on('click', () => this._ruleOwner.addEmptyRule()),
|
||||||
dom.prop('disabled', this._disabled),
|
dom.prop('disabled', this._disabled),
|
||||||
),
|
),
|
||||||
(this._label === 'Row Style'
|
(this._label === t('Row Style')
|
||||||
? GristTooltips.addRowConditionalStyle()
|
? GristTooltips.addRowConditionalStyle()
|
||||||
: GristTooltips.addColumnConditionalStyle()
|
: GristTooltips.addColumnConditionalStyle()
|
||||||
),
|
),
|
||||||
@ -113,8 +115,8 @@ export class ConditionalStyle extends Disposable {
|
|||||||
const errorMessage = Computed.create(owner, use => {
|
const errorMessage = Computed.create(owner, use => {
|
||||||
const value = use(currentValue);
|
const value = use(currentValue);
|
||||||
return (!use(hasError) ? '' :
|
return (!use(hasError) ? '' :
|
||||||
isRaisedException(value) ? 'Error in style rule' :
|
isRaisedException(value) ? t('Error in style rule') :
|
||||||
'Rule must return True or False');
|
t('Rule must return True or False'));
|
||||||
});
|
});
|
||||||
return dom('div',
|
return dom('div',
|
||||||
testId(`conditional-rule-${ruleIndex}`),
|
testId(`conditional-rule-${ruleIndex}`),
|
||||||
@ -153,7 +155,7 @@ export class ConditionalStyle extends Disposable {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
cssRow(
|
cssRow(
|
||||||
textButton('Add another rule',
|
textButton(t('Add another rule'),
|
||||||
dom.on('click', () => this._ruleOwner.addEmptyRule()),
|
dom.on('click', () => this._ruleOwner.addEmptyRule()),
|
||||||
testId('add-another-rule'),
|
testId('add-another-rule'),
|
||||||
dom.prop('disabled', use => this._disabled && use(this._disabled))
|
dom.prop('disabled', use => this._disabled && use(this._disabled))
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import { makeT } from 'app/client/lib/localization';
|
||||||
import {ACSelectItem, buildACSelect} from "app/client/lib/ACSelect";
|
import {ACSelectItem, buildACSelect} from "app/client/lib/ACSelect";
|
||||||
import {Computed, IDisposableOwner, Observable} from "grainjs";
|
import {Computed, IDisposableOwner, Observable} from "grainjs";
|
||||||
import {ACIndexImpl} from "app/client/lib/ACIndex";
|
import {ACIndexImpl} from "app/client/lib/ACIndex";
|
||||||
import {testId} from 'app/client/ui2018/cssVars';
|
import {testId} from 'app/client/ui2018/cssVars';
|
||||||
import {currencies} from 'app/common/Locales';
|
import {currencies} from 'app/common/Locales';
|
||||||
|
|
||||||
|
const t = makeT('CurrencyPicker');
|
||||||
|
|
||||||
interface CurrencyPickerOptions {
|
interface CurrencyPickerOptions {
|
||||||
// The label to use in the select menu for the default option.
|
// The label to use in the select menu for the default option.
|
||||||
defaultCurrencyLabel: string;
|
defaultCurrencyLabel: string;
|
||||||
@ -40,7 +43,7 @@ export function buildCurrencyPicker(
|
|||||||
save(_, item: ACSelectItem | undefined) {
|
save(_, item: ACSelectItem | undefined) {
|
||||||
// Save only if we have found a match
|
// Save only if we have found a match
|
||||||
if (!item) {
|
if (!item) {
|
||||||
throw new Error("Invalid currency");
|
throw new Error(t("Invalid currency"));
|
||||||
}
|
}
|
||||||
// For default value, return undefined to use default currency for document.
|
// For default value, return undefined to use default currency for document.
|
||||||
onSave(item.value === defaultCurrencyLabel ? undefined : item.value);
|
onSave(item.value === defaultCurrencyLabel ? undefined : item.value);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {GristDoc} from 'app/client/components/GristDoc';
|
import {GristDoc} from 'app/client/components/GristDoc';
|
||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {FocusLayer} from 'app/client/lib/FocusLayer';
|
import {FocusLayer} from 'app/client/lib/FocusLayer';
|
||||||
import {createObsArray} from 'app/client/lib/koArrayWrap';
|
import {createObsArray} from 'app/client/lib/koArrayWrap';
|
||||||
import {localStorageBoolObs} from 'app/client/lib/localStorageObs';
|
import {localStorageBoolObs} from 'app/client/lib/localStorageObs';
|
||||||
@ -35,6 +36,7 @@ import maxSize from 'popper-max-size-modifier';
|
|||||||
import flatMap = require('lodash/flatMap');
|
import flatMap = require('lodash/flatMap');
|
||||||
|
|
||||||
const testId = makeTestId('test-discussion-');
|
const testId = makeTestId('test-discussion-');
|
||||||
|
const t = makeT('DiscussionEditor');
|
||||||
const COMMENTS_LIMIT = 200;
|
const COMMENTS_LIMIT = 200;
|
||||||
|
|
||||||
interface DiscussionPopupProps {
|
interface DiscussionPopupProps {
|
||||||
@ -68,7 +70,7 @@ export class CellWithComments extends Disposable implements ICellView {
|
|||||||
|
|
||||||
public async reply(comment: CellRec, text: string): Promise<void> {
|
public async reply(comment: CellRec, text: string): Promise<void> {
|
||||||
const author = commentAuthor(this.gristDoc);
|
const author = commentAuthor(this.gristDoc);
|
||||||
await this.gristDoc.docData.bundleActions("Reply to a comment", () => Promise.all([
|
await this.gristDoc.docData.bundleActions(t("Reply to a comment"), () => Promise.all([
|
||||||
this.gristDoc.docModel.cells.sendTableAction([
|
this.gristDoc.docModel.cells.sendTableAction([
|
||||||
"AddRecord",
|
"AddRecord",
|
||||||
null,
|
null,
|
||||||
@ -150,7 +152,7 @@ export class EmptyCell extends CellWithComments implements ICellView {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
await props.gristDoc.docData.sendActions([addComment], 'Started discussion');
|
await props.gristDoc.docData.sendActions([addComment], t('Started discussion'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,9 +223,9 @@ class EmptyCellView extends Disposable {
|
|||||||
text: this._newText,
|
text: this._newText,
|
||||||
onSave: () => this.props.onSave(this._newText.get()),
|
onSave: () => this.props.onSave(this._newText.get()),
|
||||||
onCancel: () => this.props.closeClicked?.(),
|
onCancel: () => this.props.closeClicked?.(),
|
||||||
editorArgs: [{placeholder: 'Write a comment'}],
|
editorArgs: [{placeholder: t('Write a comment')}],
|
||||||
mainButton: 'Comment',
|
mainButton: t('Comment'),
|
||||||
buttons: ['Cancel'],
|
buttons: [t('Cancel')],
|
||||||
args: [testId('editor-start')]
|
args: [testId('editor-start')]
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -274,7 +276,7 @@ class CellWithCommentsView extends Disposable implements IDomComponent {
|
|||||||
|
|
||||||
public buildDom() {
|
public buildDom() {
|
||||||
return cssTopic(
|
return cssTopic(
|
||||||
dom.maybe(this._truncated, () => cssTruncate(`Showing last ${COMMENTS_LIMIT} comments`)),
|
dom.maybe(this._truncated, () => cssTruncate(t("Showing last {{nb}} comments", {nb: COMMENTS_LIMIT}))),
|
||||||
cssTopic.cls('-panel', this.props.panel),
|
cssTopic.cls('-panel', this.props.panel),
|
||||||
domOnCustom(CommentView.EDIT, (s: CommentView) => this._onEditComment(s)),
|
domOnCustom(CommentView.EDIT, (s: CommentView) => this._onEditComment(s)),
|
||||||
domOnCustom(CommentView.CANCEL, (s: CommentView) => this._onCancelEdit()),
|
domOnCustom(CommentView.CANCEL, (s: CommentView) => this._onCancelEdit()),
|
||||||
@ -358,7 +360,7 @@ class CellWithCommentsView extends Disposable implements IDomComponent {
|
|||||||
onSave: () => this._save(),
|
onSave: () => this._save(),
|
||||||
onCancel: () => this.props.closeClicked?.(),
|
onCancel: () => this.props.closeClicked?.(),
|
||||||
mainButton: 'Send',
|
mainButton: 'Send',
|
||||||
editorArgs: [{placeholder: 'Comment'}],
|
editorArgs: [{placeholder: t('Comment')}],
|
||||||
args: [testId('editor-add')]
|
args: [testId('editor-add')]
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -464,8 +466,8 @@ class CommentView extends Disposable {
|
|||||||
const text = Observable.create(owner, comment.text.peek() ?? '');
|
const text = Observable.create(owner, comment.text.peek() ?? '');
|
||||||
return dom.create(CommentEntry, {
|
return dom.create(CommentEntry, {
|
||||||
text,
|
text,
|
||||||
mainButton: 'Save',
|
mainButton: t('Save'),
|
||||||
buttons: ['Cancel'],
|
buttons: [t('Cancel')],
|
||||||
onSave: async () => {
|
onSave: async () => {
|
||||||
const value = text.get();
|
const value = text.get();
|
||||||
text.set("");
|
text.set("");
|
||||||
@ -503,7 +505,7 @@ class CommentView extends Disposable {
|
|||||||
dom.maybe(use => !use(this.isEditing) && !this.props.isReply && !use(comment.resolved),
|
dom.maybe(use => !use(this.isEditing) && !this.props.isReply && !use(comment.resolved),
|
||||||
() => dom.domComputed(use => {
|
() => dom.domComputed(use => {
|
||||||
if (!use(this.replying)) {
|
if (!use(this.replying)) {
|
||||||
return cssReplyButton(icon('Message'), 'Reply',
|
return cssReplyButton(icon('Message'), t('Reply'),
|
||||||
testId('comment-reply-button'),
|
testId('comment-reply-button'),
|
||||||
dom.on('click', withStop(() => this.replying.set(true))),
|
dom.on('click', withStop(() => this.replying.set(true))),
|
||||||
dom.style('margin-left', use2 => use2(this._hasReplies) ? '16px' : '0px'),
|
dom.style('margin-left', use2 => use2(this._hasReplies) ? '16px' : '0px'),
|
||||||
@ -513,8 +515,8 @@ class CommentView extends Disposable {
|
|||||||
return dom.create(CommentEntry, {
|
return dom.create(CommentEntry, {
|
||||||
text,
|
text,
|
||||||
args: [dom.style('margin-top', '8px'), testId('editor-reply')],
|
args: [dom.style('margin-top', '8px'), testId('editor-reply')],
|
||||||
mainButton: 'Reply',
|
mainButton: t('Reply'),
|
||||||
buttons: ['Cancel'],
|
buttons: [t('Cancel')],
|
||||||
onSave: async () => {
|
onSave: async () => {
|
||||||
const value = text.get();
|
const value = text.get();
|
||||||
this.replying.set(false);
|
this.replying.set(false);
|
||||||
@ -522,7 +524,7 @@ class CommentView extends Disposable {
|
|||||||
},
|
},
|
||||||
onCancel: () => this.replying.set(false),
|
onCancel: () => this.replying.set(false),
|
||||||
onClick: (button) => {
|
onClick: (button) => {
|
||||||
if (button === 'Cancel') {
|
if (button === t('Cancel')) {
|
||||||
this.replying.set(false);
|
this.replying.set(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -538,7 +540,7 @@ class CommentView extends Disposable {
|
|||||||
testId('comment-resolved'),
|
testId('comment-resolved'),
|
||||||
icon('FieldChoice'),
|
icon('FieldChoice'),
|
||||||
cssResolvedText(dom.text(
|
cssResolvedText(dom.text(
|
||||||
`Marked as resolved`
|
t(`Marked as resolved`)
|
||||||
)));
|
)));
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@ -554,23 +556,23 @@ class CommentView extends Disposable {
|
|||||||
!canResolve ? null :
|
!canResolve ? null :
|
||||||
menuItem(
|
menuItem(
|
||||||
() => this.props.topic.resolve(this.props.comment),
|
() => this.props.topic.resolve(this.props.comment),
|
||||||
'Resolve'
|
t('Resolve')
|
||||||
),
|
),
|
||||||
!comment.resolved() ? null :
|
!comment.resolved() ? null :
|
||||||
menuItem(
|
menuItem(
|
||||||
() => this.props.topic.open(comment),
|
() => this.props.topic.open(comment),
|
||||||
'Open'
|
t('Open')
|
||||||
),
|
),
|
||||||
menuItem(
|
menuItem(
|
||||||
() => this.props.topic.remove(comment),
|
() => this.props.topic.remove(comment),
|
||||||
'Remove',
|
t('Remove'),
|
||||||
dom.cls('disabled', use => {
|
dom.cls('disabled', use => {
|
||||||
return currentUser !== use(comment.userRef);
|
return currentUser !== use(comment.userRef);
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
menuItem(
|
menuItem(
|
||||||
() => this._edit(),
|
() => this._edit(),
|
||||||
'Edit',
|
t('Edit'),
|
||||||
dom.cls('disabled', use => {
|
dom.cls('disabled', use => {
|
||||||
return currentUser !== use(comment.userRef);
|
return currentUser !== use(comment.userRef);
|
||||||
})
|
})
|
||||||
@ -605,7 +607,7 @@ class CommentEntry extends Disposable {
|
|||||||
public buildDom() {
|
public buildDom() {
|
||||||
const text = this.props.text;
|
const text = this.props.text;
|
||||||
const clickBuilder = (button: string) => dom.on('click', () => {
|
const clickBuilder = (button: string) => dom.on('click', () => {
|
||||||
if (button === "Cancel") {
|
if (button === t("Cancel")) {
|
||||||
this.props.onCancel?.();
|
this.props.onCancel?.();
|
||||||
} else {
|
} else {
|
||||||
this.props.onClick?.(button);
|
this.props.onClick?.(button);
|
||||||
@ -699,9 +701,9 @@ export class DiscussionPanel extends Disposable implements IDomComponent {
|
|||||||
const tables = Computed.create(owner, use => {
|
const tables = Computed.create(owner, use => {
|
||||||
// Filter out those tables that are not available by ACL.
|
// Filter out those tables that are not available by ACL.
|
||||||
if (use(this._currentPageKo)) {
|
if (use(this._currentPageKo)) {
|
||||||
return [...new Set(use(viewSections).map(vs => use(vs.table)).filter(t => use(t.tableId)))];
|
return [...new Set(use(viewSections).map(vs => use(vs.table)).filter(tb => use(tb.tableId)))];
|
||||||
} else {
|
} else {
|
||||||
return use(this._grist.docModel.visibleTables.getObservable()).filter(t => use(t.tableId));
|
return use(this._grist.docModel.visibleTables.getObservable()).filter(tb => use(tb.tableId));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -774,8 +776,8 @@ export class DiscussionPanel extends Disposable implements IDomComponent {
|
|||||||
;
|
;
|
||||||
});
|
});
|
||||||
const allDiscussions = Computed.create(owner, use => {
|
const allDiscussions = Computed.create(owner, use => {
|
||||||
const list = flatMap(flatMap(use(tables).map(t => {
|
const list = flatMap(flatMap(use(tables).map(tb => {
|
||||||
const columns = use(use(t.columns).getObservable());
|
const columns = use(use(tb.columns).getObservable());
|
||||||
const dList = columns.map(col => use(use(col.cells).getObservable())
|
const dList = columns.map(col => use(use(col.cells).getObservable())
|
||||||
.filter(c => use(c.root) && use(c.type) === CellInfoType.COMMENT));
|
.filter(c => use(c.root) && use(c.type) === CellInfoType.COMMENT));
|
||||||
return dList;
|
return dList;
|
||||||
@ -818,9 +820,9 @@ export class DiscussionPanel extends Disposable implements IDomComponent {
|
|||||||
testId('panel-menu'),
|
testId('panel-menu'),
|
||||||
menu(() => {
|
menu(() => {
|
||||||
return [cssDropdownMenu(
|
return [cssDropdownMenu(
|
||||||
labeledSquareCheckbox(this._onlyMine, "Only my threads", testId('my-threads')),
|
labeledSquareCheckbox(this._onlyMine, t("Only my threads"), testId('my-threads')),
|
||||||
labeledSquareCheckbox(this._currentPage, "Only current page", testId('only-page')),
|
labeledSquareCheckbox(this._currentPage, t("Only current page"), testId('only-page')),
|
||||||
labeledSquareCheckbox(this._resolved, "Show resolved comments", testId('show-resolved')),
|
labeledSquareCheckbox(this._resolved, t("Show resolved comments"), testId('show-resolved')),
|
||||||
)];
|
)];
|
||||||
}, {placement: 'bottom-start'}),
|
}, {placement: 'bottom-start'}),
|
||||||
dom.on('click', stopPropagation)
|
dom.on('click', stopPropagation)
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {ITooltipControl, showTooltip, tooltipCloseButton} from 'app/client/ui/tooltips';
|
import {ITooltipControl, showTooltip, tooltipCloseButton} from 'app/client/ui/tooltips';
|
||||||
import {colors, testId} from 'app/client/ui2018/cssVars';
|
import {colors, testId} from 'app/client/ui2018/cssVars';
|
||||||
import {icon} from 'app/client/ui2018/icons';
|
import {icon} from 'app/client/ui2018/icons';
|
||||||
import {cssLink} from 'app/client/ui2018/links';
|
import {cssLink} from 'app/client/ui2018/links';
|
||||||
import {dom, styled} from 'grainjs';
|
import {dom, styled} from 'grainjs';
|
||||||
|
|
||||||
|
const t = makeT('DiscussionEditor');
|
||||||
|
|
||||||
export function showTooltipToCreateFormula(editorDom: HTMLElement, convert: () => void) {
|
export function showTooltipToCreateFormula(editorDom: HTMLElement, convert: () => void) {
|
||||||
function buildTooltip(ctl: ITooltipControl) {
|
function buildTooltip(ctl: ITooltipControl) {
|
||||||
return cssConvertTooltip(icon('Convert'),
|
return cssConvertTooltip(icon('Convert'),
|
||||||
cssLink('Convert column to formula',
|
cssLink(t('Convert column to formula'),
|
||||||
dom.on('mousedown', (ev) => { ev.preventDefault(); convert(); }),
|
dom.on('mousedown', (ev) => { ev.preventDefault(); convert(); }),
|
||||||
testId('editor-tooltip-convert'),
|
testId('editor-tooltip-convert'),
|
||||||
),
|
),
|
||||||
|
@ -9,6 +9,7 @@ import { KoArray } from 'app/client/lib/koArray';
|
|||||||
import * as kd from 'app/client/lib/koDom';
|
import * as kd from 'app/client/lib/koDom';
|
||||||
import * as kf from 'app/client/lib/koForm';
|
import * as kf from 'app/client/lib/koForm';
|
||||||
import * as koUtil from 'app/client/lib/koUtil';
|
import * as koUtil from 'app/client/lib/koUtil';
|
||||||
|
import { makeT } from 'app/client/lib/localization';
|
||||||
import { reportError } from 'app/client/models/AppModel';
|
import { reportError } from 'app/client/models/AppModel';
|
||||||
import { DataRowModel } from 'app/client/models/DataRowModel';
|
import { DataRowModel } from 'app/client/models/DataRowModel';
|
||||||
import { ColumnRec, DocModel, ViewFieldRec } from 'app/client/models/DocModel';
|
import { ColumnRec, DocModel, ViewFieldRec } from 'app/client/models/DocModel';
|
||||||
@ -38,7 +39,7 @@ import * as ko from 'knockout';
|
|||||||
import * as _ from 'underscore';
|
import * as _ from 'underscore';
|
||||||
|
|
||||||
const testId = makeTestId('test-fbuilder-');
|
const testId = makeTestId('test-fbuilder-');
|
||||||
|
const t = makeT('FieldBuilder');
|
||||||
|
|
||||||
|
|
||||||
// Creates a FieldBuilder object for each field in viewFields
|
// Creates a FieldBuilder object for each field in viewFields
|
||||||
@ -228,7 +229,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
defaultWidget.onWrite((value) => this.field.config.widget(value));
|
defaultWidget.onWrite((value) => this.field.config.widget(value));
|
||||||
const disabled = Computed.create(null, use => !use(this.field.config.sameWidgets));
|
const disabled = Computed.create(null, use => !use(this.field.config.sameWidgets));
|
||||||
return [
|
return [
|
||||||
cssLabel('CELL FORMAT'),
|
cssLabel(t('CELL FORMAT')),
|
||||||
cssRow(
|
cssRow(
|
||||||
grainjsDom.autoDispose(defaultWidget),
|
grainjsDom.autoDispose(defaultWidget),
|
||||||
widgetOptions.length <= 2 ?
|
widgetOptions.length <= 2 ?
|
||||||
@ -242,7 +243,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
widgetOptions,
|
widgetOptions,
|
||||||
{
|
{
|
||||||
disabled,
|
disabled,
|
||||||
defaultLabel: 'Mixed format'
|
defaultLabel: t('Mixed format')
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
testId('widget-select')
|
testId('widget-select')
|
||||||
@ -286,7 +287,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
// If we are waiting for a server response
|
// If we are waiting for a server response
|
||||||
use(this.isCallPending),
|
use(this.isCallPending),
|
||||||
menuCssClass: cssTypeSelectMenu.className,
|
menuCssClass: cssTypeSelectMenu.className,
|
||||||
defaultLabel: 'Mixed types',
|
defaultLabel: t('Mixed types'),
|
||||||
renderOptionArgs: (op) => {
|
renderOptionArgs: (op) => {
|
||||||
if (['Ref', 'RefList'].includes(selectType.get())) {
|
if (['Ref', 'RefList'].includes(selectType.get())) {
|
||||||
// Don't show tip if a reference column type is already selected.
|
// Don't show tip if a reference column type is already selected.
|
||||||
@ -340,7 +341,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
// If we selected multiple empty/formula columns, make the change for all of them.
|
// If we selected multiple empty/formula columns, make the change for all of them.
|
||||||
if (this.field.viewSection.peek().selectedFields.peek().length > 1 &&
|
if (this.field.viewSection.peek().selectedFields.peek().length > 1 &&
|
||||||
['formula', 'empty'].indexOf(this.field.viewSection.peek().columnsBehavior.peek())) {
|
['formula', 'empty'].indexOf(this.field.viewSection.peek().columnsBehavior.peek())) {
|
||||||
return this.gristDoc.docData.bundleActions("Changing multiple column types", () =>
|
return this.gristDoc.docData.bundleActions(t("Changing multiple column types"), () =>
|
||||||
Promise.all(this.field.viewSection.peek().selectedFields.peek().map(f =>
|
Promise.all(this.field.viewSection.peek().selectedFields.peek().map(f =>
|
||||||
f.column.peek().type.setAndSave(calculatedType)
|
f.column.peek().type.setAndSave(calculatedType)
|
||||||
))).catch(reportError);
|
))).catch(reportError);
|
||||||
@ -369,7 +370,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
return use(this.origColumn.disableModifyBase) || use(this.field.config.multiselect);
|
return use(this.origColumn.disableModifyBase) || use(this.field.config.multiselect);
|
||||||
});
|
});
|
||||||
return [
|
return [
|
||||||
cssLabel('DATA FROM TABLE',
|
cssLabel(t('DATA FROM TABLE'),
|
||||||
!this._showRefConfigPopup.peek() ? null : this.gristDoc.behavioralPromptsManager.attachTip(
|
!this._showRefConfigPopup.peek() ? null : this.gristDoc.behavioralPromptsManager.attachTip(
|
||||||
'referenceColumnsConfig',
|
'referenceColumnsConfig',
|
||||||
{
|
{
|
||||||
@ -417,7 +418,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
kf.row(
|
kf.row(
|
||||||
15, kf.label('Apply Formula to Data'),
|
15, kf.label(t('Apply Formula to Data')),
|
||||||
3, kf.buttonGroup(
|
3, kf.buttonGroup(
|
||||||
kf.checkButton(transformButton,
|
kf.checkButton(transformButton,
|
||||||
dom('span.glyphicon.glyphicon-flash'),
|
dom('span.glyphicon.glyphicon-flash'),
|
||||||
@ -498,7 +499,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
|
|
||||||
public fieldSettingsUseSeparate() {
|
public fieldSettingsUseSeparate() {
|
||||||
return this.gristDoc.docData.bundleActions(
|
return this.gristDoc.docData.bundleActions(
|
||||||
`Use separate field settings for ${this.origColumn.colId()}`, () => {
|
t("Use separate field settings for {{colId}}", { colId: this.origColumn.colId() }), () => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
setSaveValue(this.field.widgetOptions, this.field.column().widgetOptions()),
|
setSaveValue(this.field.widgetOptions, this.field.column().widgetOptions()),
|
||||||
setSaveValue(this.field.visibleCol, this.field.column().visibleCol()),
|
setSaveValue(this.field.visibleCol, this.field.column().visibleCol()),
|
||||||
@ -510,7 +511,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
|
|
||||||
public fieldSettingsSaveAsCommon() {
|
public fieldSettingsSaveAsCommon() {
|
||||||
return this.gristDoc.docData.bundleActions(
|
return this.gristDoc.docData.bundleActions(
|
||||||
`Save field settings for ${this.origColumn.colId()} as common`, () => {
|
t("Save field settings for {{colId}} as common", { colId: this.origColumn.colId() }), () => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
setSaveValue(this.field.column().widgetOptions, this.field.widgetOptions()),
|
setSaveValue(this.field.column().widgetOptions, this.field.widgetOptions()),
|
||||||
setSaveValue(this.field.column().visibleCol, this.field.visibleCol()),
|
setSaveValue(this.field.column().visibleCol, this.field.visibleCol()),
|
||||||
@ -525,7 +526,7 @@ export class FieldBuilder extends Disposable {
|
|||||||
|
|
||||||
public fieldSettingsRevertToCommon() {
|
public fieldSettingsRevertToCommon() {
|
||||||
return this.gristDoc.docData.bundleActions(
|
return this.gristDoc.docData.bundleActions(
|
||||||
`Revert field settings for ${this.origColumn.colId()} to common`, () => {
|
t("Revert field settings for {{colId}} to common", { colId: this.origColumn.colId() }), () => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
setSaveValue(this.field.widgetOptions, ''),
|
setSaveValue(this.field.widgetOptions, ''),
|
||||||
setSaveValue(this.field.visibleCol, 0),
|
setSaveValue(this.field.visibleCol, 0),
|
||||||
|
@ -2,6 +2,7 @@ import * as commands from 'app/client/components/commands';
|
|||||||
import {Cursor} from 'app/client/components/Cursor';
|
import {Cursor} from 'app/client/components/Cursor';
|
||||||
import {GristDoc} from 'app/client/components/GristDoc';
|
import {GristDoc} from 'app/client/components/GristDoc';
|
||||||
import {UnsavedChange} from 'app/client/components/UnsavedChanges';
|
import {UnsavedChange} from 'app/client/components/UnsavedChanges';
|
||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||||
import {reportError} from 'app/client/models/errors';
|
import {reportError} from 'app/client/models/errors';
|
||||||
@ -17,6 +18,8 @@ import {CellPosition} from "app/client/components/CellPosition";
|
|||||||
|
|
||||||
type IEditorConstructor = typeof NewBaseEditor;
|
type IEditorConstructor = typeof NewBaseEditor;
|
||||||
|
|
||||||
|
const t = makeT('FieldEditor');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the typed-in value should change the cell without opening the cell editor, and if so,
|
* Check if the typed-in value should change the cell without opening the cell editor, and if so,
|
||||||
* saves and returns true. E.g. on typing space, CheckBoxEditor toggles the cell without opening.
|
* saves and returns true. E.g. on typing space, CheckBoxEditor toggles the cell without opening.
|
||||||
@ -320,7 +323,7 @@ export class FieldEditor extends Disposable {
|
|||||||
await editor.prepForSave();
|
await editor.prepForSave();
|
||||||
if (this.isDisposed()) {
|
if (this.isDisposed()) {
|
||||||
// We shouldn't normally get disposed here, but if we do, avoid confusing JS errors.
|
// We shouldn't normally get disposed here, but if we do, avoid confusing JS errors.
|
||||||
console.warn("Unable to finish saving edited cell"); // tslint:disable-line:no-console
|
console.warn(t("Unable to finish saving edited cell")); // tslint:disable-line:no-console
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +352,7 @@ export class FieldEditor extends Disposable {
|
|||||||
const value = editor.getCellValue();
|
const value = editor.getCellValue();
|
||||||
if (col.isRealFormula()) {
|
if (col.isRealFormula()) {
|
||||||
// tslint:disable-next-line:no-console
|
// tslint:disable-next-line:no-console
|
||||||
console.warn("It should be impossible to save a plain data value into a formula column");
|
console.warn(t("It should be impossible to save a plain data value into a formula column"));
|
||||||
} else {
|
} else {
|
||||||
// This could still be an isFormula column if it's empty (isEmpty is true), but we don't
|
// This could still be an isFormula column if it's empty (isEmpty is true), but we don't
|
||||||
// need to toggle isFormula in that case, since the data engine takes care of that.
|
// need to toggle isFormula in that case, since the data engine takes care of that.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as AceEditor from 'app/client/components/AceEditor';
|
import * as AceEditor from 'app/client/components/AceEditor';
|
||||||
import {createGroup} from 'app/client/components/commands';
|
import {createGroup} from 'app/client/components/commands';
|
||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||||
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
|
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
|
||||||
@ -20,6 +21,7 @@ import debounce = require('lodash/debounce');
|
|||||||
|
|
||||||
// How wide to expand the FormulaEditor when an error is shown in it.
|
// How wide to expand the FormulaEditor when an error is shown in it.
|
||||||
const minFormulaErrorWidth = 400;
|
const minFormulaErrorWidth = 400;
|
||||||
|
const t = makeT('FormulaEditor');
|
||||||
|
|
||||||
export interface IFormulaEditorOptions extends Options {
|
export interface IFormulaEditorOptions extends Options {
|
||||||
cssClass?: string;
|
cssClass?: string;
|
||||||
@ -293,7 +295,7 @@ export function openFormulaEditor(options: {
|
|||||||
const column = options.column ?? options.field?.column();
|
const column = options.column ?? options.field?.column();
|
||||||
|
|
||||||
if (!column) {
|
if (!column) {
|
||||||
throw new Error('Column or field is required');
|
throw new Error(t('Column or field is required'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsyncOnce ensures it's called once even if triggered multiple times.
|
// AsyncOnce ensures it's called once even if triggered multiple times.
|
||||||
@ -338,7 +340,7 @@ export function openFormulaEditor(options: {
|
|||||||
const editingFormula = options.editingFormula ?? options?.field?.editingFormula;
|
const editingFormula = options.editingFormula ?? options?.field?.editingFormula;
|
||||||
|
|
||||||
if (!editingFormula) {
|
if (!editingFormula) {
|
||||||
throw new Error('editingFormula is required');
|
throw new Error(t('editingFormula is required'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// When formula is empty enter formula-editing mode (highlight formula icons; click on a column inserts its ID).
|
// When formula is empty enter formula-editing mode (highlight formula icons; click on a column inserts its ID).
|
||||||
@ -393,9 +395,9 @@ export function createFormulaErrorObs(owner: MultiHolder, gristDoc: GristDoc, or
|
|||||||
const numErrors = tableData.countErrors(colId) || 0;
|
const numErrors = tableData.countErrors(colId) || 0;
|
||||||
errorMessage.set(
|
errorMessage.set(
|
||||||
(numErrors === 0) ? '' :
|
(numErrors === 0) ? '' :
|
||||||
(numCells === 1) ? `Error in the cell` :
|
(numCells === 1) ? t(`Error in the cell`) :
|
||||||
(numErrors === numCells) ? `Errors in all ${numErrors} cells` :
|
(numErrors === numCells) ? t(`Errors in all {{numErrors}} cells`, {numErrors}) :
|
||||||
`Errors in ${numErrors} of ${numCells} cells`
|
t(`Errors in {{numErrors}} of {{numCells}} cells`, {numErrors, numCells})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
errorMessage.set('');
|
errorMessage.set('');
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {FieldOptions} from 'app/client/widgets/NewBaseEditor';
|
import {FieldOptions} from 'app/client/widgets/NewBaseEditor';
|
||||||
import {NTextEditor} from 'app/client/widgets/NTextEditor';
|
import {NTextEditor} from 'app/client/widgets/NTextEditor';
|
||||||
|
|
||||||
|
const t = makeT('HyperLinkEditor');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HyperLinkEditor - Is the same NTextEditor but with some placeholder text to help explain
|
* HyperLinkEditor - Is the same NTextEditor but with some placeholder text to help explain
|
||||||
* to the user how links should be formatted.
|
* to the user how links should be formatted.
|
||||||
@ -8,6 +11,6 @@ import {NTextEditor} from 'app/client/widgets/NTextEditor';
|
|||||||
export class HyperLinkEditor extends NTextEditor {
|
export class HyperLinkEditor extends NTextEditor {
|
||||||
constructor(options: FieldOptions) {
|
constructor(options: FieldOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
this.textInput.setAttribute('placeholder', '[link label] url');
|
this.textInput.setAttribute('placeholder', t('[link label] url'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* See app/common/NumberFormat for description of options we support.
|
* See app/common/NumberFormat for description of options we support.
|
||||||
*/
|
*/
|
||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||||
import {reportError} from 'app/client/models/errors';
|
import {reportError} from 'app/client/models/errors';
|
||||||
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
|
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
|
||||||
@ -16,6 +17,7 @@ import {BindableValue, Computed, dom, DomContents, DomElementArg,
|
|||||||
import * as LocaleCurrency from 'locale-currency';
|
import * as LocaleCurrency from 'locale-currency';
|
||||||
|
|
||||||
|
|
||||||
|
const t = makeT('NumericTextBox');
|
||||||
const modeOptions: Array<ISelectorOption<NumMode>> = [
|
const modeOptions: Array<ISelectorOption<NumMode>> = [
|
||||||
{value: 'currency', label: '$'},
|
{value: 'currency', label: '$'},
|
||||||
{value: 'decimal', label: ','},
|
{value: 'decimal', label: ','},
|
||||||
@ -85,23 +87,23 @@ export class NumericTextBox extends NTextBox {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
super.buildConfigDom(),
|
super.buildConfigDom(),
|
||||||
cssLabel('Number Format'),
|
cssLabel(t('Number Format')),
|
||||||
cssRow(
|
cssRow(
|
||||||
dom.autoDispose(holder),
|
dom.autoDispose(holder),
|
||||||
makeButtonSelect(numMode, modeOptions, setMode, disabledStyle, cssModeSelect.cls(''), testId('numeric-mode')),
|
makeButtonSelect(numMode, modeOptions, setMode, disabledStyle, cssModeSelect.cls(''), testId('numeric-mode')),
|
||||||
makeButtonSelect(numSign, signOptions, setSign, disabledStyle, cssSignSelect.cls(''), testId('numeric-sign')),
|
makeButtonSelect(numSign, signOptions, setSign, disabledStyle, cssSignSelect.cls(''), testId('numeric-sign')),
|
||||||
),
|
),
|
||||||
dom.maybe((use) => use(numMode) === 'currency', () => [
|
dom.maybe((use) => use(numMode) === 'currency', () => [
|
||||||
cssLabel('Currency'),
|
cssLabel(t('Currency')),
|
||||||
cssRow(
|
cssRow(
|
||||||
dom.domComputed(docCurrency, (defaultCurrency) =>
|
dom.domComputed(docCurrency, (defaultCurrency) =>
|
||||||
buildCurrencyPicker(holder, currency, setCurrency,
|
buildCurrencyPicker(holder, currency, setCurrency,
|
||||||
{defaultCurrencyLabel: `Default currency (${defaultCurrency})`, disabled})
|
{defaultCurrencyLabel: t(`Default currency ({{defaultCurrency}})`, {defaultCurrency}), disabled})
|
||||||
),
|
),
|
||||||
testId("numeric-currency")
|
testId("numeric-currency")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
cssLabel('Decimals'),
|
cssLabel(t('Decimals')),
|
||||||
cssRow(
|
cssRow(
|
||||||
decimals('min', minDecimals, defaultMin, setMinDecimals, disabled, testId('numeric-min-decimals')),
|
decimals('min', minDecimals, defaultMin, setMinDecimals, disabled, testId('numeric-min-decimals')),
|
||||||
decimals('max', maxDecimals, defaultMax, setMaxDecimals, disabled, testId('numeric-max-decimals')),
|
decimals('max', maxDecimals, defaultMax, setMaxDecimals, disabled, testId('numeric-max-decimals')),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {makeT} from 'app/client/lib/localization';
|
||||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||||
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
|
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
|
||||||
@ -8,6 +9,9 @@ import {NTextBox} from 'app/client/widgets/NTextBox';
|
|||||||
import {isFullReferencingType, isVersions} from 'app/common/gristTypes';
|
import {isFullReferencingType, isVersions} from 'app/common/gristTypes';
|
||||||
import {Computed, dom, styled} from 'grainjs';
|
import {Computed, dom, styled} from 'grainjs';
|
||||||
|
|
||||||
|
|
||||||
|
const t = makeT('Reference');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference - The widget for displaying references to another table's records.
|
* Reference - The widget for displaying references to another table's records.
|
||||||
*/
|
*/
|
||||||
@ -33,14 +37,14 @@ export class Reference extends NTextBox {
|
|||||||
icon: 'FieldColumn',
|
icon: 'FieldColumn',
|
||||||
disabled: isFullReferencingType(use(col.type)) || use(col.isTransforming)
|
disabled: isFullReferencingType(use(col.type)) || use(col.isTransforming)
|
||||||
}))
|
}))
|
||||||
.concat([{label: 'Row ID', value: 0, icon: 'FieldColumn'}]);
|
.concat([{label: t('Row ID'), value: 0, icon: 'FieldColumn'}]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildConfigDom() {
|
public buildConfigDom() {
|
||||||
return [
|
return [
|
||||||
this.buildTransformConfigDom(),
|
this.buildTransformConfigDom(),
|
||||||
cssLabel('CELL FORMAT'),
|
cssLabel(t('CELL FORMAT')),
|
||||||
super.buildConfigDom()
|
super.buildConfigDom()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -48,7 +52,7 @@ export class Reference extends NTextBox {
|
|||||||
public buildTransformConfigDom() {
|
public buildTransformConfigDom() {
|
||||||
const disabled = Computed.create(null, use => use(this.field.config.multiselect));
|
const disabled = Computed.create(null, use => use(this.field.config.multiselect));
|
||||||
return [
|
return [
|
||||||
cssLabel('SHOW COLUMN'),
|
cssLabel(t('SHOW COLUMN')),
|
||||||
cssRow(
|
cssRow(
|
||||||
dom.autoDispose(disabled),
|
dom.autoDispose(disabled),
|
||||||
select(this._visibleColRef, this._validCols, {
|
select(this._visibleColRef, this._validCols, {
|
||||||
|
@ -36,6 +36,7 @@ export function mergeOptions(options: any, type: string) {
|
|||||||
// The names of widgets are used, instead of the actual classes needed, in order to limit
|
// The names of widgets are used, instead of the actual classes needed, in order to limit
|
||||||
// the spread of dependencies. See ./UserTypeImpl for actual classes.
|
// the spread of dependencies. See ./UserTypeImpl for actual classes.
|
||||||
export const typeDefs: any = {
|
export const typeDefs: any = {
|
||||||
|
// TODO : translate labels (can not use classic makeT function)
|
||||||
Any: {
|
Any: {
|
||||||
label: 'Any',
|
label: 'Any',
|
||||||
icon: 'FieldAny',
|
icon: 'FieldAny',
|
||||||
|
@ -666,7 +666,7 @@
|
|||||||
"Current field ": "Aktuelles Feld ",
|
"Current field ": "Aktuelles Feld ",
|
||||||
"OK": "OK"
|
"OK": "OK"
|
||||||
},
|
},
|
||||||
"TypeTransformation": {
|
"TypeTransform": {
|
||||||
"Apply": "Anwenden",
|
"Apply": "Anwenden",
|
||||||
"Cancel": "Abbrechen",
|
"Cancel": "Abbrechen",
|
||||||
"Preview": "Vorschau",
|
"Preview": "Vorschau",
|
||||||
|
@ -27,17 +27,21 @@
|
|||||||
"Permission to view Access Rules": "Permission to view Access Rules",
|
"Permission to view Access Rules": "Permission to view Access Rules",
|
||||||
"Permissions": "Permissions",
|
"Permissions": "Permissions",
|
||||||
"Remove column {{- colId }} from {{- tableId }} rules": "Remove column {{- colId }} from {{- tableId }} rules",
|
"Remove column {{- colId }} from {{- tableId }} rules": "Remove column {{- colId }} from {{- tableId }} rules",
|
||||||
"Remove {{- tableId }} rules": "Remove {{- tableId }} rules",
|
|
||||||
"Remove {{- name }} user attribute": "Remove {{- name }} user attribute",
|
"Remove {{- name }} user attribute": "Remove {{- name }} user attribute",
|
||||||
|
"Remove {{- tableId }} rules": "Remove {{- tableId }} rules",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Rules for table ": "Rules for table ",
|
"Rules for table ": "Rules for table ",
|
||||||
"Save": "Save",
|
"Save": "Save",
|
||||||
"Saved": "Saved",
|
"Saved": "Saved",
|
||||||
|
"Seed rules": "Seed rules",
|
||||||
"Special Rules": "Special Rules",
|
"Special Rules": "Special Rules",
|
||||||
"Type a message...": "Type a message…",
|
"Type a message...": "Type a message…",
|
||||||
"User Attributes": "User Attributes",
|
"User Attributes": "User Attributes",
|
||||||
"View As": "View As",
|
"View As": "View As",
|
||||||
|
<<<<<<< HEAD
|
||||||
"Seed rules": "Seed rules",
|
"Seed rules": "Seed rules",
|
||||||
|
=======
|
||||||
|
>>>>>>> trad: make the widgets and the Welcome Tour translatable
|
||||||
"When adding table rules, automatically add a rule to grant OWNER full access.": "When adding table rules, automatically add a rule to grant OWNER full access."
|
"When adding table rules, automatically add a rule to grant OWNER full access.": "When adding table rules, automatically add a rule to grant OWNER full access."
|
||||||
},
|
},
|
||||||
"AccountPage": {
|
"AccountPage": {
|
||||||
@ -70,11 +74,6 @@
|
|||||||
"Switch Accounts": "Switch Accounts",
|
"Switch Accounts": "Switch Accounts",
|
||||||
"Toggle Mobile Mode": "Toggle Mobile Mode"
|
"Toggle Mobile Mode": "Toggle Mobile Mode"
|
||||||
},
|
},
|
||||||
"ViewAsDropdown": {
|
|
||||||
"View As": "View As",
|
|
||||||
"Users from table": "Users from table",
|
|
||||||
"Example Users": "Example Users"
|
|
||||||
},
|
|
||||||
"ActionLog": {
|
"ActionLog": {
|
||||||
"Action Log failed to load": "Action Log failed to load",
|
"Action Log failed to load": "Action Log failed to load",
|
||||||
"Column {{colId}} was subsequently removed in action #{{action.actionNum}}": "Column {{colId}} was subsequently removed in action #{{action.actionNum}}",
|
"Column {{colId}} was subsequently removed in action #{{action.actionNum}}": "Column {{colId}} was subsequently removed in action #{{action.actionNum}}",
|
||||||
@ -129,6 +128,13 @@
|
|||||||
"Reset {{count}} entire columns_one": "Reset entire column",
|
"Reset {{count}} entire columns_one": "Reset entire column",
|
||||||
"Reset {{count}} entire columns_other": "Reset {{count}} entire columns"
|
"Reset {{count}} entire columns_other": "Reset {{count}} entire columns"
|
||||||
},
|
},
|
||||||
|
"CellStyle": {
|
||||||
|
"CELL STYLE": "CELL STYLE",
|
||||||
|
"Cell Style": "Cell Style",
|
||||||
|
"Default cell style": "Default cell style",
|
||||||
|
"Mixed style": "Mixed style",
|
||||||
|
"Open row styles": "Open row styles"
|
||||||
|
},
|
||||||
"ChartView": {
|
"ChartView": {
|
||||||
"Create separate series for each value of the selected column.": "Create separate series for each value of the selected column.",
|
"Create separate series for each value of the selected column.": "Create separate series for each value of the selected column.",
|
||||||
"Each Y series is followed by a series for the length of error bars.": "Each Y series is followed by a series for the length of error bars.",
|
"Each Y series is followed by a series for the length of error bars.": "Each Y series is followed by a series for the length of error bars.",
|
||||||
@ -137,6 +143,9 @@
|
|||||||
"Toggle chart aggregation": "Toggle chart aggregation",
|
"Toggle chart aggregation": "Toggle chart aggregation",
|
||||||
"selected new group data columns": "selected new group data columns"
|
"selected new group data columns": "selected new group data columns"
|
||||||
},
|
},
|
||||||
|
"ChoiceTextBox": {
|
||||||
|
"CHOICES": "CHOICES"
|
||||||
|
},
|
||||||
"CodeEditorPanel": {
|
"CodeEditorPanel": {
|
||||||
"Access denied": "Access denied",
|
"Access denied": "Access denied",
|
||||||
"Code View is available only when you have full document access.": "Code View is available only when you have full document access."
|
"Code View is available only when you have full document access.": "Code View is available only when you have full document access."
|
||||||
@ -150,20 +159,30 @@
|
|||||||
"All": "All",
|
"All": "All",
|
||||||
"All Except": "All Except",
|
"All Except": "All Except",
|
||||||
"All Shown": "All Shown",
|
"All Shown": "All Shown",
|
||||||
|
"End": "End",
|
||||||
"Filter by Range": "Filter by Range",
|
"Filter by Range": "Filter by Range",
|
||||||
"Future Values": "Future Values",
|
"Future Values": "Future Values",
|
||||||
|
"Max": "Max",
|
||||||
|
"Min": "Min",
|
||||||
"No matching values": "No matching values",
|
"No matching values": "No matching values",
|
||||||
"None": "None",
|
"None": "None",
|
||||||
"Min": "Min",
|
|
||||||
"Max": "Max",
|
|
||||||
"Start": "Start",
|
|
||||||
"End": "End",
|
|
||||||
"Other Matching": "Other Matching",
|
"Other Matching": "Other Matching",
|
||||||
"Other Non-Matching": "Other Non-Matching",
|
"Other Non-Matching": "Other Non-Matching",
|
||||||
"Other Values": "Other Values",
|
"Other Values": "Other Values",
|
||||||
"Others": "Others",
|
"Others": "Others",
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
"Search values": "Search values"
|
"Search values": "Search values",
|
||||||
|
"Start": "Start"
|
||||||
|
},
|
||||||
|
"ConditionalStyle": {
|
||||||
|
"Add another rule": "Add another rule",
|
||||||
|
"Add conditional style": "Add conditional style",
|
||||||
|
"Error in style rule": "Error in style rule",
|
||||||
|
"Row Style": "Row Style",
|
||||||
|
"Rule must return True or False": "Rule must return True or False"
|
||||||
|
},
|
||||||
|
"CurrencyPicker": {
|
||||||
|
"Invalid currency": "Invalid currency"
|
||||||
},
|
},
|
||||||
"CustomSectionConfig": {
|
"CustomSectionConfig": {
|
||||||
" (optional)": " (optional)",
|
" (optional)": " (optional)",
|
||||||
@ -191,6 +210,24 @@
|
|||||||
"Table ID copied to clipboard": "Table ID copied to clipboard",
|
"Table ID copied to clipboard": "Table ID copied to clipboard",
|
||||||
"You do not have edit access to this document": "You do not have edit access to this document"
|
"You do not have edit access to this document": "You do not have edit access to this document"
|
||||||
},
|
},
|
||||||
|
"DiscussionEditor": {
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Comment": "Comment",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Marked as resolved": "Marked as resolved",
|
||||||
|
"Only current page": "Only current page",
|
||||||
|
"Only my threads": "Only my threads",
|
||||||
|
"Open": "Open",
|
||||||
|
"Remove": "Remove",
|
||||||
|
"Reply": "Reply",
|
||||||
|
"Reply to a comment": "Reply to a comment",
|
||||||
|
"Resolve": "Resolve",
|
||||||
|
"Save": "Save",
|
||||||
|
"Show resolved comments": "Show resolved comments",
|
||||||
|
"Showing last {{nb}} comments": "Showing last {{nb}} comments",
|
||||||
|
"Started discussion": "Started discussion",
|
||||||
|
"Write a comment": "Write a comment"
|
||||||
|
},
|
||||||
"DocHistory": {
|
"DocHistory": {
|
||||||
"Activity": "Activity",
|
"Activity": "Activity",
|
||||||
"Beta": "Beta",
|
"Beta": "Beta",
|
||||||
@ -291,6 +328,9 @@
|
|||||||
"Name for new table": "Name for new table",
|
"Name for new table": "Name for new table",
|
||||||
"Only the document default access rules will apply to the copy.": "Only the document default access rules will apply to the copy."
|
"Only the document default access rules will apply to the copy.": "Only the document default access rules will apply to the copy."
|
||||||
},
|
},
|
||||||
|
"EditorTooltip": {
|
||||||
|
"Convert column to formula": "Convert column to formula"
|
||||||
|
},
|
||||||
"ExampleInfo": {
|
"ExampleInfo": {
|
||||||
"Afterschool Program": "Afterschool Program",
|
"Afterschool Program": "Afterschool Program",
|
||||||
"Check out our related tutorial for how to link data, and create high-productivity layouts.": "Check out our related tutorial for how to link data, and create high-productivity layouts.",
|
"Check out our related tutorial for how to link data, and create high-productivity layouts.": "Check out our related tutorial for how to link data, and create high-productivity layouts.",
|
||||||
@ -305,6 +345,17 @@
|
|||||||
"Welcome to the Investment Research template": "Welcome to the Investment Research template",
|
"Welcome to the Investment Research template": "Welcome to the Investment Research template",
|
||||||
"Welcome to the Lightweight CRM template": "Welcome to the Lightweight CRM template"
|
"Welcome to the Lightweight CRM template": "Welcome to the Lightweight CRM template"
|
||||||
},
|
},
|
||||||
|
"FieldBuilder": {
|
||||||
|
"Apply Formula to Data": "Apply Formula to Data",
|
||||||
|
"CELL FORMAT": "CELL FORMAT",
|
||||||
|
"Changing multiple column types": "Changing multiple column types",
|
||||||
|
"DATA FROM TABLE": "DATA FROM TABLE",
|
||||||
|
"Mixed format": "Mixed format",
|
||||||
|
"Mixed types": "Mixed types",
|
||||||
|
"Revert field settings for {{colId}} to common": "Revert field settings for {{colId}} to common",
|
||||||
|
"Save field settings for {{colId}} as common": "Save field settings for {{colId}} as common",
|
||||||
|
"Use separate field settings for {{colId}}": "Use separate field settings for {{colId}}"
|
||||||
|
},
|
||||||
"FieldConfig": {
|
"FieldConfig": {
|
||||||
"COLUMN BEHAVIOR": "COLUMN BEHAVIOR",
|
"COLUMN BEHAVIOR": "COLUMN BEHAVIOR",
|
||||||
"COLUMN LABEL AND ID": "COLUMN LABEL AND ID",
|
"COLUMN LABEL AND ID": "COLUMN LABEL AND ID",
|
||||||
@ -326,6 +377,10 @@
|
|||||||
"Set trigger formula": "Set trigger formula",
|
"Set trigger formula": "Set trigger formula",
|
||||||
"TRIGGER FORMULA": "TRIGGER FORMULA"
|
"TRIGGER FORMULA": "TRIGGER FORMULA"
|
||||||
},
|
},
|
||||||
|
"FieldEditor": {
|
||||||
|
"It should be impossible to save a plain data value into a formula column": "It should be impossible to save a plain data value into a formula column",
|
||||||
|
"Unable to finish saving edited cell": "Unable to finish saving edited cell"
|
||||||
|
},
|
||||||
"FieldMenus": {
|
"FieldMenus": {
|
||||||
"Revert to common settings": "Revert to common settings",
|
"Revert to common settings": "Revert to common settings",
|
||||||
"Save as common settings": "Save as common settings",
|
"Save as common settings": "Save as common settings",
|
||||||
@ -340,6 +395,13 @@
|
|||||||
"SearchColumns": "Search columns",
|
"SearchColumns": "Search columns",
|
||||||
"Search Columns": "Search Columns"
|
"Search Columns": "Search Columns"
|
||||||
},
|
},
|
||||||
|
"FormulaEditor": {
|
||||||
|
"Column or field is required": "Column or field is required",
|
||||||
|
"Error in the cell": "Error in the cell",
|
||||||
|
"Errors in all {{numErrors}} cells": "Errors in all {{numErrors}} cells",
|
||||||
|
"Errors in {{numErrors}} of {{numCells}} cells": "Errors in {{numErrors}} of {{numCells}} cells",
|
||||||
|
"editingFormula is required": "editingFormula is required"
|
||||||
|
},
|
||||||
"GridOptions": {
|
"GridOptions": {
|
||||||
"Grid Options": "Grid Options",
|
"Grid Options": "Grid Options",
|
||||||
"Horizontal Gridlines": "Horizontal Gridlines",
|
"Horizontal Gridlines": "Horizontal Gridlines",
|
||||||
@ -417,6 +479,9 @@
|
|||||||
"Workspace will be moved to Trash.": "Workspace will be moved to Trash.",
|
"Workspace will be moved to Trash.": "Workspace will be moved to Trash.",
|
||||||
"Workspaces": "Workspaces"
|
"Workspaces": "Workspaces"
|
||||||
},
|
},
|
||||||
|
"HyperLinkEditor": {
|
||||||
|
"[link label] url": "[link label] url"
|
||||||
|
},
|
||||||
"Importer": {
|
"Importer": {
|
||||||
"Merge rows that match these fields:": "Merge rows that match these fields:",
|
"Merge rows that match these fields:": "Merge rows that match these fields:",
|
||||||
"Select fields to match on": "Select fields to match on",
|
"Select fields to match on": "Select fields to match on",
|
||||||
@ -437,8 +502,8 @@
|
|||||||
"No destination workspace": "No destination workspace",
|
"No destination workspace": "No destination workspace",
|
||||||
"Organization": "Organization",
|
"Organization": "Organization",
|
||||||
"Original Has Modifications": "Original Has Modifications",
|
"Original Has Modifications": "Original Has Modifications",
|
||||||
"Original Looks Unrelated": "Original Looks Unrelated",
|
|
||||||
"Original Looks Identical": "Original Looks Identical",
|
"Original Looks Identical": "Original Looks Identical",
|
||||||
|
"Original Looks Unrelated": "Original Looks Unrelated",
|
||||||
"Overwrite": "Overwrite",
|
"Overwrite": "Overwrite",
|
||||||
"Replacing the original requires editing rights on the original document.": "Replacing the original requires editing rights on the original document.",
|
"Replacing the original requires editing rights on the original document.": "Replacing the original requires editing rights on the original document.",
|
||||||
"Sign up": "Sign up",
|
"Sign up": "Sign up",
|
||||||
@ -461,6 +526,12 @@
|
|||||||
"Report a problem": "Report a problem",
|
"Report a problem": "Report a problem",
|
||||||
"Upgrade Plan": "Upgrade Plan"
|
"Upgrade Plan": "Upgrade Plan"
|
||||||
},
|
},
|
||||||
|
"NumericTextBox": {
|
||||||
|
"Currency": "Currency",
|
||||||
|
"Decimals": "Decimals",
|
||||||
|
"Default currency ({{defaultCurrency}})": "Default currency ({{defaultCurrency}})",
|
||||||
|
"Number Format": "Number Format"
|
||||||
|
},
|
||||||
"OnBoardingPopups": {
|
"OnBoardingPopups": {
|
||||||
"Finish": "Finish",
|
"Finish": "Finish",
|
||||||
"Next": "Next"
|
"Next": "Next"
|
||||||
@ -496,15 +567,20 @@
|
|||||||
},
|
},
|
||||||
"RecordLayoutEditor": {
|
"RecordLayoutEditor": {
|
||||||
"Add Field": "Add Field",
|
"Add Field": "Add Field",
|
||||||
|
"Cancel": "Cancel",
|
||||||
"Create New Field": "Create New Field",
|
"Create New Field": "Create New Field",
|
||||||
"Show field {{- label}}": "Show field {{- label}}",
|
|
||||||
"Save Layout": "Save Layout",
|
"Save Layout": "Save Layout",
|
||||||
"Cancel": "Cancel"
|
"Show field {{- label}}": "Show field {{- label}}"
|
||||||
},
|
},
|
||||||
"RefSelect": {
|
"RefSelect": {
|
||||||
"Add Column": "Add Column",
|
"Add Column": "Add Column",
|
||||||
"No columns to add": "No columns to add"
|
"No columns to add": "No columns to add"
|
||||||
},
|
},
|
||||||
|
"Reference": {
|
||||||
|
"CELL FORMAT": "CELL FORMAT",
|
||||||
|
"Row ID": "Row ID",
|
||||||
|
"SHOW COLUMN": "SHOW COLUMN"
|
||||||
|
},
|
||||||
"RightPanel": {
|
"RightPanel": {
|
||||||
"CHART TYPE": "CHART TYPE",
|
"CHART TYPE": "CHART TYPE",
|
||||||
"COLUMN TYPE": "COLUMN TYPE",
|
"COLUMN TYPE": "COLUMN TYPE",
|
||||||
@ -577,9 +653,9 @@
|
|||||||
"Add Column": "Add Column",
|
"Add Column": "Add Column",
|
||||||
"Empty values last": "Empty values last",
|
"Empty values last": "Empty values last",
|
||||||
"Natural sort": "Natural sort",
|
"Natural sort": "Natural sort",
|
||||||
|
"Search Columns": "Search columns",
|
||||||
"Update Data": "Update Data",
|
"Update Data": "Update Data",
|
||||||
"Use choice position": "Use choice position",
|
"Use choice position": "Use choice position"
|
||||||
"Search Columns": "Search columns"
|
|
||||||
},
|
},
|
||||||
"SortFilterConfig": {
|
"SortFilterConfig": {
|
||||||
"Filter": "FILTER",
|
"Filter": "FILTER",
|
||||||
@ -618,13 +694,6 @@
|
|||||||
"Current field ": "Current field ",
|
"Current field ": "Current field ",
|
||||||
"OK": "OK"
|
"OK": "OK"
|
||||||
},
|
},
|
||||||
"TypeTransformation": {
|
|
||||||
"Apply": "Apply",
|
|
||||||
"Cancel": "Cancel",
|
|
||||||
"Preview": "Preview",
|
|
||||||
"Revise": "Revise",
|
|
||||||
"Update formula (Shift+Enter)": "Update formula (Shift+Enter)"
|
|
||||||
},
|
|
||||||
"UserManagerModel": {
|
"UserManagerModel": {
|
||||||
"Editor": "Editor",
|
"Editor": "Editor",
|
||||||
"In Full": "In Full",
|
"In Full": "In Full",
|
||||||
@ -642,6 +711,11 @@
|
|||||||
"ViewAsBanner": {
|
"ViewAsBanner": {
|
||||||
"UnknownUser": "Unknown User"
|
"UnknownUser": "Unknown User"
|
||||||
},
|
},
|
||||||
|
"ViewAsDropdown": {
|
||||||
|
"Example Users": "Example Users",
|
||||||
|
"Users from table": "Users from table",
|
||||||
|
"View As": "View As"
|
||||||
|
},
|
||||||
"ViewConfigTab": {
|
"ViewConfigTab": {
|
||||||
"Advanced settings": "Advanced settings",
|
"Advanced settings": "Advanced settings",
|
||||||
"Big tables may be marked as \"on-demand\" to avoid loading them into the data engine.": "Big tables may be marked as \"on-demand\" to avoid loading them into the data engine.",
|
"Big tables may be marked as \"on-demand\" to avoid loading them into the data engine.": "Big tables may be marked as \"on-demand\" to avoid loading them into the data engine.",
|
||||||
@ -779,5 +853,31 @@
|
|||||||
"Preview": "Preview",
|
"Preview": "Preview",
|
||||||
"Revise": "Revise",
|
"Revise": "Revise",
|
||||||
"Update formula (Shift+Enter)": "Update formula (Shift+Enter)"
|
"Update formula (Shift+Enter)": "Update formula (Shift+Enter)"
|
||||||
|
},
|
||||||
|
"welcomeTour": {
|
||||||
|
"Add New": "Add New",
|
||||||
|
"Browse our {{templateLibrary}} to discover what's possible and get inspired.": "Browse our {{templateLibrary}} to discover what's possible and get inspired.",
|
||||||
|
"Building up": "Building up",
|
||||||
|
"Configuring your document": "Configuring your document",
|
||||||
|
"Customizing columns": "Customizing columns",
|
||||||
|
"Double-click or hit {{enter}} on a cell to edit it. ": "Double-click or hit {{enter}} on a cell to edit it. ",
|
||||||
|
"Editing Data": "Editing Data",
|
||||||
|
"Enter": "Enter",
|
||||||
|
"Flying higher": "Flying higher",
|
||||||
|
"Help Center": "Help Center",
|
||||||
|
"Make it relational! Use the {{ref}} type to link tables. ": "Make it relational! Use the {{ref}} type to link tables. ",
|
||||||
|
"Reference": "Reference",
|
||||||
|
"Set formatting options, formulas, or column types, such as dates, choices, or attachments. ": "Set formatting options, formulas, or column types, such as dates, choices, or attachments. ",
|
||||||
|
"Share": "Share",
|
||||||
|
"Sharing": "Sharing",
|
||||||
|
"Start with {{equal}} to enter a formula.": "Start with {{equal}} to enter a formula.",
|
||||||
|
"Toggle the {{creatorPanel}} to format columns, ": "Toggle the {{creatorPanel}} to format columns, ",
|
||||||
|
"Use the Share button ({{share}}) to share the document or export data.": "Use the Share button ({{share}}) to share the document or export data.",
|
||||||
|
"Use {{addNew}} to add widgets, pages, or import more data. ": "Use {{addNew}} to add widgets, pages, or import more data. ",
|
||||||
|
"Use {{helpCenter}} for documentation or questions.": "Use {{helpCenter}} for documentation or questions.",
|
||||||
|
"Welcome to Grist!": "Welcome to Grist!",
|
||||||
|
"convert to card view, select data, and more.": "convert to card view, select data, and more.",
|
||||||
|
"creator panel": "creator panel",
|
||||||
|
"template library": "template library"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,7 +768,7 @@
|
|||||||
"SelectionSummary": {
|
"SelectionSummary": {
|
||||||
"Copied to clipboard": "Copiado al portapapeles"
|
"Copied to clipboard": "Copiado al portapapeles"
|
||||||
},
|
},
|
||||||
"TypeTransformation": {
|
"TypeTransform": {
|
||||||
"Apply": "Aplicar",
|
"Apply": "Aplicar",
|
||||||
"Cancel": "Cancelar",
|
"Cancel": "Cancelar",
|
||||||
"Preview": "Vista previa",
|
"Preview": "Vista previa",
|
||||||
|
@ -610,7 +610,7 @@
|
|||||||
"Cancel": "Annuler",
|
"Cancel": "Annuler",
|
||||||
"Close": "Fermer"
|
"Close": "Fermer"
|
||||||
},
|
},
|
||||||
"TypeTransformation": {
|
"TypeTransform": {
|
||||||
"Apply": "Appliquer",
|
"Apply": "Appliquer",
|
||||||
"Cancel": "Annuler",
|
"Cancel": "Annuler",
|
||||||
"Preview": "Aperçu",
|
"Preview": "Aperçu",
|
||||||
|
@ -666,7 +666,7 @@
|
|||||||
"Current field ": "Campo atual ",
|
"Current field ": "Campo atual ",
|
||||||
"OK": "OK"
|
"OK": "OK"
|
||||||
},
|
},
|
||||||
"TypeTransformation": {
|
"TypeTransform": {
|
||||||
"Apply": "Aplicar",
|
"Apply": "Aplicar",
|
||||||
"Cancel": "Cancelar",
|
"Cancel": "Cancelar",
|
||||||
"Preview": "Pré-visualização",
|
"Preview": "Pré-visualização",
|
||||||
|
Loading…
Reference in New Issue
Block a user