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
572995f19a
@ -218,6 +218,20 @@ export class App extends DisposableWithEvents {
|
||||
this._mostRecentDocPageModel = pageModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not called anywhere, it is here just to introduce
|
||||
* a special translation key. The purpose of this key is to let translators
|
||||
* control whether a translation is ready to be offered to the user.
|
||||
*
|
||||
* If the key has not been translated for a language, and the language
|
||||
* is not the default language, then the language should not be offered
|
||||
* or used (unless some flag is set). TODO: implement this once key
|
||||
* is available in weblate and good translations have been updated.
|
||||
*/
|
||||
public checkSpecialTranslationKey() {
|
||||
return t('Translators: please translate this only when your language is ready to be offered to users');
|
||||
}
|
||||
|
||||
// Get the user profile for testing purposes
|
||||
public async testGetProfile(): Promise<any> {
|
||||
const resp = await fetchFromHome('/api/profile/user', {credentials: 'include'});
|
||||
|
@ -79,7 +79,7 @@ export function makeViewLayoutMenu(viewSection: ViewSectionRec, isReadonly: bool
|
||||
menuItemLink({ href: gristDoc.getCsvLink(), target: '_blank', download: ''},
|
||||
t("Download as CSV"), testId('download-section')),
|
||||
menuItemLink({ href: gristDoc.getXlsxActiveViewLink(), target: '_blank', download: ''},
|
||||
t("Download as XLSX"), testId('download-section')),
|
||||
t("Download as XLSX"), testId('download-section')),
|
||||
dom.maybe((use) => ['detail', 'single'].includes(use(viewSection.parentKey)), () =>
|
||||
menuItemCmd(allCommands.editLayout, t("Edit Card Layout"),
|
||||
dom.cls('disabled', isReadonly))),
|
||||
|
@ -370,7 +370,7 @@ export interface UserAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for the download CSV and XLSX endpoint (/download/csv & /download/csv).
|
||||
* Parameters for the download CSV and XLSX endpoint (/download/table-schema & /download/csv & /download/csv).
|
||||
*/
|
||||
export interface DownloadDocParams {
|
||||
tableId: string;
|
||||
@ -418,6 +418,7 @@ export interface DocAPI {
|
||||
getDownloadUrl(template?: boolean): string;
|
||||
getDownloadXlsxUrl(params?: DownloadDocParams): string;
|
||||
getDownloadCsvUrl(params: DownloadDocParams): string;
|
||||
getDownloadTableSchemaUrl(params: DownloadDocParams): string;
|
||||
/**
|
||||
* Exports current document to the Google Drive as a spreadsheet file. To invoke this method, first
|
||||
* acquire "code" via Google Auth Endpoint (see ShareMenu.ts for an example).
|
||||
@ -920,6 +921,11 @@ export class DocAPIImpl extends BaseAPI implements DocAPI {
|
||||
return this._url + '/download/csv?' + encodeQueryParams({...params});
|
||||
}
|
||||
|
||||
public getDownloadTableSchemaUrl(params: DownloadDocParams) {
|
||||
// We spread `params` to work around TypeScript being overly cautious.
|
||||
return this._url + '/download/table-schema?' + encodeQueryParams({...params});
|
||||
}
|
||||
|
||||
public async sendToDrive(code: string, title: string): Promise<{url: string}> {
|
||||
const url = new URL(`${this._url}/send-to-drive`);
|
||||
url.searchParams.append('title', title);
|
||||
|
11
app/common/WidgetOptions.ts
Normal file
11
app/common/WidgetOptions.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import {NumberFormatOptions} from 'app/common/NumberFormat';
|
||||
|
||||
export interface WidgetOptions extends NumberFormatOptions {
|
||||
textColor?: 'string';
|
||||
fillColor?: 'string';
|
||||
alignment?: 'left' | 'center' | 'right';
|
||||
dateFormat?: string;
|
||||
timeFormat?: string;
|
||||
widget?: 'HyperLink';
|
||||
choices?: Array<string>;
|
||||
}
|
@ -36,6 +36,7 @@ import {IDocWorkerMap} from "app/server/lib/DocWorkerMap";
|
||||
import {DownloadOptions, parseExportParameters} from "app/server/lib/Export";
|
||||
import {downloadCSV} from "app/server/lib/ExportCSV";
|
||||
import {downloadXLSX} from "app/server/lib/ExportXLSX";
|
||||
import {collectTableSchemaInFrictionlessFormat} from "app/server/lib/ExportTableSchema";
|
||||
import {expressWrap} from 'app/server/lib/expressWrap';
|
||||
import {filterDocumentInPlace} from "app/server/lib/filterUtils";
|
||||
import {googleAuthTokenMiddleware} from "app/server/lib/GoogleAuth";
|
||||
@ -871,6 +872,26 @@ export class DocWorkerApi {
|
||||
res.json(result);
|
||||
}));
|
||||
|
||||
this._app.get('/api/docs/:docId/download/table-schema', canView, withDoc(async (activeDoc, req, res) => {
|
||||
const doc = await this._dbManager.getDoc(req);
|
||||
const options = this._getDownloadOptions(req, doc.name);
|
||||
const tableSchema = await collectTableSchemaInFrictionlessFormat(activeDoc, req, options);
|
||||
const apiPath = await this._grist.getResourceUrl(doc, 'api');
|
||||
const query = new URLSearchParams(req.query as {[key: string]: string});
|
||||
const tableSchemaPath = `${apiPath}/download/csv?${query.toString()}`;
|
||||
res.send({
|
||||
format: "csv",
|
||||
mediatype: "text/csv",
|
||||
encoding: "utf-8",
|
||||
path: tableSchemaPath,
|
||||
dialect: {
|
||||
delimiter: ",",
|
||||
doubleQuote: true,
|
||||
},
|
||||
...tableSchema,
|
||||
});
|
||||
}));
|
||||
|
||||
this._app.get('/api/docs/:docId/download/csv', canView, withDoc(async (activeDoc, req, res) => {
|
||||
// Query DB for doc metadata to get the doc title.
|
||||
const {name: docTitle} = await this._dbManager.getDoc(req);
|
||||
|
@ -204,7 +204,8 @@ export async function exportTable(
|
||||
label: tc.label,
|
||||
type: displayCol.type,
|
||||
widgetOptions,
|
||||
parentPos: tc.parentPos
|
||||
parentPos: tc.parentPos,
|
||||
description: displayCol.description,
|
||||
};
|
||||
}).filter(tc => tc !== emptyCol);
|
||||
|
||||
@ -279,6 +280,7 @@ export async function exportSection(
|
||||
label: col.label,
|
||||
type: col.type,
|
||||
parentPos: col.parentPos,
|
||||
description: col.description,
|
||||
widgetOptions: Object.assign(colWidgetOptions, fieldWidgetOptions),
|
||||
};
|
||||
};
|
||||
|
151
app/server/lib/ExportTableSchema.ts
Normal file
151
app/server/lib/ExportTableSchema.ts
Normal file
@ -0,0 +1,151 @@
|
||||
import * as express from 'express';
|
||||
import {ApiError} from 'app/common/ApiError';
|
||||
import {WidgetOptions} from 'app/common/WidgetOptions';
|
||||
import {ActiveDoc} from 'app/server/lib/ActiveDoc';
|
||||
import {DownloadOptions, exportTable} from 'app/server/lib/Export';
|
||||
|
||||
interface ExportColumn {
|
||||
id: number;
|
||||
colId: string;
|
||||
label: string;
|
||||
type: string;
|
||||
widgetOptions: WidgetOptions;
|
||||
description?: string;
|
||||
parentPos: number;
|
||||
}
|
||||
|
||||
interface FrictionlessFormat {
|
||||
name: string;
|
||||
title: string;
|
||||
schema: {
|
||||
fields: {
|
||||
name: string;
|
||||
type: string;
|
||||
description?: string;
|
||||
format?: string;
|
||||
bareNumber?: boolean;
|
||||
groupChar?: string;
|
||||
decimalChar?: string;
|
||||
gristFormat?: string;
|
||||
constraint?: {};
|
||||
trueValue?: string[];
|
||||
falseValue?: string[];
|
||||
}[]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a table schema for frictionless interoperability
|
||||
*
|
||||
* See https://specs.frictionlessdata.io/table-schema/#page-frontmatter-title for spec
|
||||
* @param {Object} activeDoc - the activeDoc that the table being converted belongs to.
|
||||
* @param {Object} options - options to get the table ID
|
||||
* @return {Promise<FrictionlessFormat>} Promise for the resulting schema.
|
||||
*/
|
||||
export async function collectTableSchemaInFrictionlessFormat(
|
||||
activeDoc: ActiveDoc,
|
||||
req: express.Request,
|
||||
options: DownloadOptions
|
||||
): Promise<FrictionlessFormat> {
|
||||
const {tableId} = options;
|
||||
if (!activeDoc.docData) {
|
||||
throw new Error('No docData in active document');
|
||||
}
|
||||
|
||||
// Look up the table to make a CSV from.
|
||||
const settings = activeDoc.docData.docSettings();
|
||||
const tables = activeDoc.docData.getMetaTable('_grist_Tables');
|
||||
const tableRef = tables.findRow('tableId', tableId);
|
||||
|
||||
if (tableRef === 0) {
|
||||
throw new ApiError(`Table ${tableId} not found.`, 404);
|
||||
}
|
||||
|
||||
const data = await exportTable(activeDoc, tableRef, req);
|
||||
const tableSchema = columnsToTableSchema(tableId, data, settings.locale);
|
||||
return tableSchema;
|
||||
}
|
||||
|
||||
function columnsToTableSchema(
|
||||
tableId: string,
|
||||
{tableName, columns}: {tableName: string, columns: ExportColumn[]},
|
||||
locale: string,
|
||||
): FrictionlessFormat {
|
||||
return {
|
||||
name: tableId.toLowerCase().replace(/_/g, '-'),
|
||||
title: tableName,
|
||||
schema: {
|
||||
fields: columns.map(col => ({
|
||||
name: col.label,
|
||||
...(col.description ? {description: col.description} : {}),
|
||||
...buildTypeField(col, locale),
|
||||
})),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function buildTypeField(col: ExportColumn, locale: string) {
|
||||
const type = col.type.split(':', 1)[0];
|
||||
switch (type) {
|
||||
case 'Text':
|
||||
return {
|
||||
type: 'string',
|
||||
format: col.widgetOptions.widget === 'HyperLink' ? 'uri' : 'default',
|
||||
};
|
||||
case 'Numeric':
|
||||
return {
|
||||
type: 'number',
|
||||
bareNumber: col.widgetOptions?.numMode === 'decimal',
|
||||
...getNumberSeparators(locale),
|
||||
};
|
||||
case 'Integer':
|
||||
return {
|
||||
type: 'integer',
|
||||
bareNumber: col.widgetOptions?.numMode === 'decimal',
|
||||
groupChar: getNumberSeparators(locale).groupChar,
|
||||
};
|
||||
case 'Date':
|
||||
return {
|
||||
type: 'date',
|
||||
format: 'any',
|
||||
gristFormat: col.widgetOptions?.dateFormat || 'YYYY-MM-DD',
|
||||
};
|
||||
case 'DateTime':
|
||||
return {
|
||||
type: 'datetime',
|
||||
format: 'any',
|
||||
gristFormat: `${col.widgetOptions?.dateFormat} ${col.widgetOptions?.timeFormat}`,
|
||||
};
|
||||
case 'Bool':
|
||||
return {
|
||||
type: 'boolean',
|
||||
trueValue: ['TRUE'],
|
||||
falseValue: ['FALSE'],
|
||||
};
|
||||
case 'Choice':
|
||||
return {
|
||||
type: 'string',
|
||||
constraints: {enum: col.widgetOptions?.choices},
|
||||
};
|
||||
case 'ChoiceList':
|
||||
return {
|
||||
type: 'array',
|
||||
constraints: {enum: col.widgetOptions?.choices},
|
||||
};
|
||||
case 'Reference':
|
||||
return {type: 'string'};
|
||||
case 'ReferenceList':
|
||||
return {type: 'array'};
|
||||
default:
|
||||
return {type: 'string'};
|
||||
}
|
||||
}
|
||||
|
||||
function getNumberSeparators(locale: string) {
|
||||
const numberWithGroupAndDecimalSeparator = 1000.1;
|
||||
const parts = Intl.NumberFormat(locale).formatToParts(numberWithGroupAndDecimalSeparator);
|
||||
return {
|
||||
groupChar: parts.find(obj => obj.type === 'group')?.value,
|
||||
decimalChar: parts.find(obj => obj.type === 'decimal')?.value,
|
||||
};
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
"ACUserManager": {
|
||||
"Enter email address": "E-Mail Adresse eingeben",
|
||||
"Invite new member": "Neues Mitglied einladen",
|
||||
"We'll email an invite to {{email}}": "Wir schicken eine Einladung zu {{email}}"
|
||||
"We'll email an invite to {{email}}": "Eine Einladung wird per E-Mail an {{email}} gesendet"
|
||||
},
|
||||
"AccessRules": {
|
||||
"Add Column Rule": "Spaltenregel hinzufügen",
|
||||
@ -95,7 +95,8 @@
|
||||
"App": {
|
||||
"Description": "Beschreibung",
|
||||
"Key": "Schlüssel",
|
||||
"Memory Error": "Speicherfehler"
|
||||
"Memory Error": "Speicherfehler",
|
||||
"Translators: please translate this only when your language is ready to be offered to users": "Übersetzer: Bitte übersetzen Sie dies erst, wenn Ihre Sprache bereit ist, Benutzern angeboten zu werden"
|
||||
},
|
||||
"AppHeader": {
|
||||
"Home Page": "Startseite",
|
||||
@ -279,10 +280,10 @@
|
||||
"Time Zone:": "Zeitzone:",
|
||||
"API": "API",
|
||||
"Document ID copied to clipboard": "Dokument-ID in die Zwischenablage kopiert",
|
||||
"Ok": "Ok"
|
||||
"Ok": "OK"
|
||||
},
|
||||
"DocumentUsage": {
|
||||
"Attachments Size": "Anhänge Größe",
|
||||
"Attachments Size": "Größe der Anhänge",
|
||||
"Contact the site owner to upgrade the plan to raise limits.": "Wenden Sie sich an den Eigentümer der Seite, um den Plan zu aktualisieren und die Grenzwerte zu erhöhen.",
|
||||
"Data Size": "Daten Größe",
|
||||
"Document limits {{- link}}.": "Dokumentgrenzwerte {{- link}}.",
|
||||
@ -572,7 +573,7 @@
|
||||
"Save": "Speichern",
|
||||
"Select Widget": "Widget auswählen",
|
||||
"Series": "Serie",
|
||||
"Sort & Filter": "Sortieren & Filtern",
|
||||
"Sort & Filter": "Sortieren und Filtern",
|
||||
"TRANSFORM": "UMWANDELN",
|
||||
"Theme": "Thema",
|
||||
"WIDGET TITLE": "WIDGET-TITEL",
|
||||
@ -687,7 +688,7 @@
|
||||
"No Default Access": "Kein Standardzugriff",
|
||||
"None": "Keine",
|
||||
"Owner": "Eigentümer",
|
||||
"View & Edit": "Anzeigen & Bearbeiten",
|
||||
"View & Edit": "Anzeigen und Bearbeiten",
|
||||
"View Only": "Nur anzeigen",
|
||||
"Viewer": "Betrachter"
|
||||
},
|
||||
@ -825,7 +826,7 @@
|
||||
},
|
||||
"modals": {
|
||||
"Cancel": "Abbrechen",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Save": "Speichern"
|
||||
},
|
||||
"pages": {
|
||||
@ -943,7 +944,7 @@
|
||||
"Row ID": "Zeilen-ID"
|
||||
},
|
||||
"HyperLinkEditor": {
|
||||
"[link label] url": "[Linklabel]-URL"
|
||||
"[link label] url": "[Linkbezeichnung] URL"
|
||||
},
|
||||
"welcomeTour": {
|
||||
"Add New": "Neu hinzufügen",
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"ACUserManager": {
|
||||
"Enter email address": "Enter email address",
|
||||
"Enter email address": "Enter e-mail address",
|
||||
"Invite new member": "Invite new member",
|
||||
"We'll email an invite to {{email}}": "We'll email an invite to {{email}}"
|
||||
"We'll email an invite to {{email}}": "An invite will be e-mailed to {{email}}"
|
||||
},
|
||||
"AccessRules": {
|
||||
"Add Column Rule": "Add Column Rule",
|
||||
@ -48,7 +48,7 @@
|
||||
"Allow signing in to this account with Google": "Allow signing in to this account with Google",
|
||||
"Change Password": "Change Password",
|
||||
"Edit": "Edit",
|
||||
"Email": "Email",
|
||||
"Email": "E-mail",
|
||||
"Login Method": "Login Method",
|
||||
"Name": "Name",
|
||||
"Names only allow letters, numbers and certain special characters": "Names only allow letters, numbers and certain special characters",
|
||||
@ -99,7 +99,8 @@
|
||||
"App": {
|
||||
"Description": "Description",
|
||||
"Key": "Key",
|
||||
"Memory Error": "Memory Error"
|
||||
"Memory Error": "Memory Error",
|
||||
"Translators: please translate this only when your language is ready to be offered to users": "Translators: please translate this only when your language is ready to be offered to users"
|
||||
},
|
||||
"AppHeader": {
|
||||
"Home Page": "Home Page",
|
||||
@ -137,7 +138,7 @@
|
||||
"Each Y series is followed by two series, for top and bottom error bars.": "Each Y series is followed by two series, for top and bottom error bars.",
|
||||
"Pick a column": "Pick a column",
|
||||
"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"
|
||||
},
|
||||
"CodeEditorPanel": {
|
||||
"Access denied": "Access denied",
|
||||
@ -218,7 +219,7 @@
|
||||
"Document will be permanently deleted.": "Document will be permanently deleted.",
|
||||
"Documents stay in Trash for 30 days, after which they get deleted permanently.": "Documents stay in Trash for 30 days, after which they get deleted permanently.",
|
||||
"Edited {{at}}": "Edited {{at}}",
|
||||
"Examples & Templates": "Examples & Templates",
|
||||
"Examples & Templates": "Examples and Templates",
|
||||
"Examples and Templates": "Examples and Templates",
|
||||
"Featured": "Featured",
|
||||
"Manage Users": "Manage Users",
|
||||
@ -271,10 +272,10 @@
|
||||
"Time Zone:": "Time Zone:",
|
||||
"API": "API",
|
||||
"Document ID copied to clipboard": "Document ID copied to clipboard",
|
||||
"Ok": "Ok"
|
||||
"Ok": "OK"
|
||||
},
|
||||
"DocumentUsage": {
|
||||
"Attachments Size": "Attachments Size",
|
||||
"Attachments Size": "Size of Attachments",
|
||||
"Contact the site owner to upgrade the plan to raise limits.": "Contact the site owner to upgrade the plan to raise limits.",
|
||||
"Data Size": "Data Size",
|
||||
"For higher limits, ": "For higher limits, ",
|
||||
@ -300,7 +301,7 @@
|
||||
"Check out our related tutorial to learn how to create summary tables and charts, and to link charts dynamically.": "Check out our related tutorial to learn how to create summary tables and charts, and to link charts dynamically.",
|
||||
"Investment Research": "Investment Research",
|
||||
"Lightweight CRM": "Lightweight CRM",
|
||||
"Tutorial: Analyze & Visualize": "Tutorial: Analyze & Visualize",
|
||||
"Tutorial: Analyze & Visualize": "Tutorial: Analyze and Visualize",
|
||||
"Tutorial: Create a CRM": "Tutorial: Create a CRM",
|
||||
"Tutorial: Manage Business Data": "Tutorial: Manage Business Data",
|
||||
"Welcome to the Afterschool Program template": "Welcome to the Afterschool Program template",
|
||||
@ -365,7 +366,7 @@
|
||||
"Hide {{count}} columns_one": "Hide column",
|
||||
"Hide {{count}} columns_other": "Hide {{count}} columns",
|
||||
"Insert column to the {{to}}": "Insert column to the {{to}}",
|
||||
"More sort options ...": "More sort options…",
|
||||
"More sort options ...": "More sorting options…",
|
||||
"Rename column": "Rename column",
|
||||
"Reset {{count}} columns_one": "Reset column",
|
||||
"Reset {{count}} columns_other": "Reset {{count}} columns",
|
||||
@ -413,7 +414,7 @@
|
||||
"Create Workspace": "Create Workspace",
|
||||
"Delete": "Delete",
|
||||
"Delete {{workspace}} and all included documents?": "Delete {{workspace}} and all included documents?",
|
||||
"Examples & Templates": "Examples & Templates",
|
||||
"Examples & Templates": "Examples and Templates",
|
||||
"Import Document": "Import Document",
|
||||
"Manage Users": "Manage Users",
|
||||
"Rename": "Rename",
|
||||
@ -533,7 +534,7 @@
|
||||
"Select Widget": "Select Widget",
|
||||
"Series_one": "Series",
|
||||
"Series_other": "Series",
|
||||
"Sort & Filter": "Sort & Filter",
|
||||
"Sort & Filter": "Sort and Filter",
|
||||
"TRANSFORM": "TRANSFORM",
|
||||
"Theme": "Theme",
|
||||
"WIDGET TITLE": "WIDGET TITLE",
|
||||
@ -636,7 +637,7 @@
|
||||
"No Default Access": "No Default Access",
|
||||
"None": "None",
|
||||
"Owner": "Owner",
|
||||
"View & Edit": "View & Edit",
|
||||
"View & Edit": "View and Edit",
|
||||
"View Only": "View Only",
|
||||
"Viewer": "Viewer"
|
||||
},
|
||||
@ -660,7 +661,7 @@
|
||||
"Unmark On-Demand": "Unmark On-Demand"
|
||||
},
|
||||
"ViewLayoutMenu": {
|
||||
"Advanced Sort & Filter": "Advanced Sort & Filter",
|
||||
"Advanced Sort & Filter": "Advanced Sorting and Filtering",
|
||||
"Copy anchor link": "Copy anchor link",
|
||||
"Data selection": "Data selection",
|
||||
"Delete record": "Delete record",
|
||||
@ -698,9 +699,9 @@
|
||||
},
|
||||
"WelcomeQuestions": {
|
||||
"Education": "Education",
|
||||
"Finance & Accounting": "Finance & Accounting",
|
||||
"HR & Management": "HR & Management",
|
||||
"IT & Technology": "IT & Technology",
|
||||
"Finance & Accounting": "Finance and Accounting",
|
||||
"HR & Management": "HR and Management",
|
||||
"IT & Technology": "IT and Technology",
|
||||
"Marketing": "Marketing",
|
||||
"Media Production": "Media Production",
|
||||
"Other": "Other",
|
||||
@ -743,7 +744,7 @@
|
||||
"Sign in to access this organization's documents.": "Sign in to access this organization's documents.",
|
||||
"Signed out{{suffix}}": "Signed out{{suffix}}",
|
||||
"Something went wrong": "Something went wrong",
|
||||
"The requested page could not be found.{{separator}}Please check the URL and try again.": "The requested page could not be found.{{separator}}Please check the URL and try again.",
|
||||
"The requested page could not be found.{{separator}}Please check the URL and try again.": "Could not find the requested page.{{separator}}Please check the URL and try again.",
|
||||
"There was an error: {{message}}": "There was an error: {{message}}",
|
||||
"There was an unknown error.": "There was an unknown error.",
|
||||
"You are now signed out.": "You are now signed out.",
|
||||
@ -769,7 +770,7 @@
|
||||
},
|
||||
"modals": {
|
||||
"Cancel": "Cancel",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Save": "Save"
|
||||
},
|
||||
"pages": {
|
||||
@ -878,7 +879,7 @@
|
||||
"editingFormula is required": "editingFormula is required"
|
||||
},
|
||||
"HyperLinkEditor": {
|
||||
"[link label] url": "[link label] url"
|
||||
"[link label] url": "[link label] URL"
|
||||
},
|
||||
"NumericTextBox": {
|
||||
"Currency": "Currency",
|
||||
|
@ -44,7 +44,7 @@
|
||||
"Allow signing in to this account with Google": "Permitir iniciar sesión en esta cuenta con Google",
|
||||
"Change Password": "Cambiar contraseña",
|
||||
"Edit": "Editar",
|
||||
"Email": "E-mail",
|
||||
"Email": "Correo electrónico",
|
||||
"Login Method": "Método de inicio de sesión",
|
||||
"Name": "Nombre",
|
||||
"Names only allow letters, numbers and certain special characters": "Los nombres solo permiten letras, números y ciertos caracteres especiales",
|
||||
@ -84,7 +84,8 @@
|
||||
"App": {
|
||||
"Description": "Descripción",
|
||||
"Key": "Clave",
|
||||
"Memory Error": "Error de memoria"
|
||||
"Memory Error": "Error de memoria",
|
||||
"Translators: please translate this only when your language is ready to be offered to users": "Traductores: por favor, traduzcan esto sólo cuando su idioma esté listo para ser ofrecido a los usuarios"
|
||||
},
|
||||
"AppHeader": {
|
||||
"Home Page": "Portada",
|
||||
@ -226,7 +227,7 @@
|
||||
"Save and Reload": "Guardar y recargar",
|
||||
"This document's ID (for API use):": "ID de este documento (para uso de API):",
|
||||
"Time Zone:": "Zona horaria:",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Document ID copied to clipboard": "ID de documento copiado al portapapeles",
|
||||
"API": "API"
|
||||
},
|
||||
@ -612,7 +613,7 @@
|
||||
"WelcomeQuestions": {
|
||||
"Education": "Educación",
|
||||
"Finance & Accounting": "Finanzas y Contabilidad",
|
||||
"HR & Management": "Recursos humanos y gestión",
|
||||
"HR & Management": "RRHH y Gestión",
|
||||
"IT & Technology": "TI y Tecnología",
|
||||
"Marketing": "Publicidad",
|
||||
"Media Production": "Producción audiovisual",
|
||||
@ -682,7 +683,7 @@
|
||||
"ACUserManager": {
|
||||
"Enter email address": "Introduzca la dirección de correo electrónico",
|
||||
"Invite new member": "Invitar nuevo miembro",
|
||||
"We'll email an invite to {{email}}": "Enviaremos una invitación a {{email}}"
|
||||
"We'll email an invite to {{email}}": "Se enviará una invitación por correo electrónico a {{email}}"
|
||||
},
|
||||
"ViewAsDropdown": {
|
||||
"View As": "Ver como",
|
||||
@ -795,7 +796,7 @@
|
||||
"No Default Access": "Sin acceso predeterminado",
|
||||
"None": "Ninguno",
|
||||
"Owner": "Propietario",
|
||||
"View & Edit": "Ver y Editar",
|
||||
"View & Edit": "Ver y editar",
|
||||
"View Only": "Ver sólo",
|
||||
"Viewer": "Espectador"
|
||||
},
|
||||
@ -830,7 +831,7 @@
|
||||
},
|
||||
"modals": {
|
||||
"Cancel": "Cancelar",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Save": "Guardar"
|
||||
},
|
||||
"pages": {
|
||||
@ -940,7 +941,7 @@
|
||||
"convert to card view, select data, and more.": "convertir a la vista de la tarjeta, seleccionar datos y más."
|
||||
},
|
||||
"HyperLinkEditor": {
|
||||
"[link label] url": "[etiqueta de enlace] url"
|
||||
"[link label] url": "[etiqueta de enlace] URL"
|
||||
},
|
||||
"NumericTextBox": {
|
||||
"Currency": "Moneda",
|
||||
|
@ -352,7 +352,8 @@
|
||||
"App": {
|
||||
"Memory Error": "Errore di memoria",
|
||||
"Key": "Chiave",
|
||||
"Description": "Descrizione"
|
||||
"Description": "Descrizione",
|
||||
"Translators: please translate this only when your language is ready to be offered to users": "Traduttori: per favore tradurre questo solo quando la tua lingua è pronta per gli utenti"
|
||||
},
|
||||
"AppModel": {
|
||||
"This team site is suspended. Documents can be read, but not modified.": "Il sito del team è sospeso. Si possono leggere i documenti, ma non modificarli."
|
||||
@ -386,7 +387,7 @@
|
||||
"Allow signing in to this account with Google": "Permetti di accedere a questo account con Google",
|
||||
"Change Password": "Cambia password",
|
||||
"Edit": "Modifica",
|
||||
"Email": "Email",
|
||||
"Email": "E-mail",
|
||||
"Login Method": "Metodo di accesso",
|
||||
"Name": "Nome",
|
||||
"Names only allow letters, numbers and certain special characters": "Per il nome puoi usare solo lettere, numeri e alcuni caratteri speciali",
|
||||
@ -434,9 +435,9 @@
|
||||
"When adding table rules, automatically add a rule to grant OWNER full access.": "Quando si mettono regole per la tabella, inserire sempre una che dà pieno accesso a OWNER."
|
||||
},
|
||||
"ACUserManager": {
|
||||
"Enter email address": "Inserisci indirizzo email",
|
||||
"Enter email address": "Inserisci indirizzo e-mail",
|
||||
"Invite new member": "Invita un nuovo membro",
|
||||
"We'll email an invite to {{email}}": "Spediremo un invito a {{email}}"
|
||||
"We'll email an invite to {{email}}": "Un invito sarà inviato a {{email}}"
|
||||
},
|
||||
"ViewAsDropdown": {
|
||||
"View As": "Vedi come",
|
||||
@ -598,7 +599,7 @@
|
||||
"Time Zone:": "Zona oraria:",
|
||||
"API": "API",
|
||||
"Document ID copied to clipboard": "ID del documento copiato",
|
||||
"Ok": "Ok"
|
||||
"Ok": "OK"
|
||||
},
|
||||
"DocumentUsage": {
|
||||
"Data Size": "Dimensione dei dati",
|
||||
@ -816,7 +817,9 @@
|
||||
"Open configuration": "Apri configurazione",
|
||||
"Print widget": "Widget di stampa",
|
||||
"Show raw data": "Mostra dati grezzi",
|
||||
"Widget options": "Opzioni widget"
|
||||
"Widget options": "Opzioni widget",
|
||||
"Add to page": "Aggiungi a pagina",
|
||||
"Collapse widget": "Compatta widget"
|
||||
},
|
||||
"ViewSectionMenu": {
|
||||
"(customized)": "(personalizzato)",
|
||||
@ -957,5 +960,8 @@
|
||||
"Access Rules": "Regole di accesso",
|
||||
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Le regole di accesso ti danno il potere di creare regole sofisticate per decidere chi può vedere o modificare il tuo documento, e quali parti.",
|
||||
"Reference columns are the key to {{relational}} data in Grist.": "Le colonne con riferimenti sono il motore {{relational}} dei dati in Grist."
|
||||
},
|
||||
"DescriptionConfig": {
|
||||
"DESCRIPTION": "DESCRIZIONE"
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -823,5 +823,144 @@
|
||||
},
|
||||
"ChoiceTextBox": {
|
||||
"CHOICES": "WYBORY"
|
||||
},
|
||||
"FormulaEditor": {
|
||||
"Error in the cell": "Błąd w komórce",
|
||||
"editingFormula is required": "edycja Formuły jest wymagana",
|
||||
"Column or field is required": "Kolumna lub pole jest wymagane",
|
||||
"Errors in {{numErrors}} of {{numCells}} cells": "Błędy w {{numErrors}} komórek {{numCells}}",
|
||||
"Errors in all {{numErrors}} cells": "Błędy we wszystkich komórkach {{numErrors}}"
|
||||
},
|
||||
"FieldEditor": {
|
||||
"Unable to finish saving edited cell": "Nie można zakończyć zapisywania edytowanej komórki",
|
||||
"It should be impossible to save a plain data value into a formula column": "Zapisanie zwykłej wartości danych w kolumnie formuły powinno być niemożliwe"
|
||||
},
|
||||
"HyperLinkEditor": {
|
||||
"[link label] url": "[etykieta linku] url"
|
||||
},
|
||||
"NumericTextBox": {
|
||||
"Decimals": "Miejsc dziesiętnych",
|
||||
"Default currency ({{defaultCurrency}})": "Waluta domyślna ({{defaultCurrency}})",
|
||||
"Number Format": "Format liczb",
|
||||
"Currency": "Waluta:"
|
||||
},
|
||||
"ConditionalStyle": {
|
||||
"Add another rule": "Dodaj kolejną regułę",
|
||||
"Add conditional style": "Dodaj styl warunkowy",
|
||||
"Error in style rule": "Błąd w regule stylu",
|
||||
"Row Style": "Styl wiersza",
|
||||
"Rule must return True or False": "Reguła musi zwracać wartość Prawda lub Fałsz"
|
||||
},
|
||||
"CurrencyPicker": {
|
||||
"Invalid currency": "Nieprawidłowa waluta"
|
||||
},
|
||||
"DiscussionEditor": {
|
||||
"Only current page": "Tylko bieżąca strona",
|
||||
"Remove": "Usuń",
|
||||
"Resolve": "Rozwiązać",
|
||||
"Save": "Zapisać",
|
||||
"Showing last {{nb}} comments": "Wyświetlanie ostatnich {{nb}} komentarzy",
|
||||
"Started discussion": "Rozpoczęto dyskusję",
|
||||
"Write a comment": "Napisz komentarz",
|
||||
"Only my threads": "Tylko moje wątki",
|
||||
"Open": "Otwórz",
|
||||
"Reply to a comment": "Odpowiedz na komentarz",
|
||||
"Show resolved comments": "Pokaż rozwiązane komentarze",
|
||||
"Cancel": "Anulować",
|
||||
"Comment": "Komentarz",
|
||||
"Edit": "Edytuj",
|
||||
"Marked as resolved": "Oznaczone jako rozwiązane",
|
||||
"Reply": "Odpowiedź"
|
||||
},
|
||||
"EditorTooltip": {
|
||||
"Convert column to formula": "Konwertuj kolumnę na formułę"
|
||||
},
|
||||
"FieldBuilder": {
|
||||
"Apply Formula to Data": "Zastosuj formułę do danych",
|
||||
"CELL FORMAT": "FORMAT KOMÓRKI",
|
||||
"DATA FROM TABLE": "DANE Z TABELI",
|
||||
"Mixed format": "Format mieszany",
|
||||
"Mixed types": "Rodzaje mieszane",
|
||||
"Save field settings for {{colId}} as common": "Zapisz ustawienia pola dla {{colId}} jako typowe",
|
||||
"Use separate field settings for {{colId}}": "Użyj oddzielnych ustawień pól dla {{colId}}",
|
||||
"Revert field settings for {{colId}} to common": "Przywróć ustawienia pola dla {{colId}} do wspólnych",
|
||||
"Changing multiple column types": "Zmienianie wielu typów kolumn"
|
||||
},
|
||||
"Reference": {
|
||||
"CELL FORMAT": "FORMAT KOMÓRKI",
|
||||
"Row ID": "Identyfikator wiersza",
|
||||
"SHOW COLUMN": "POKAŻ KOLUMNĘ"
|
||||
},
|
||||
"welcomeTour": {
|
||||
"Add New": "Dodaj nowy",
|
||||
"Building up": "Budowanie",
|
||||
"Flying higher": "Latanie wyżej",
|
||||
"Help Center": "Centrum pomocy",
|
||||
"Make it relational! Use the {{ref}} type to link tables. ": "Spraw, aby był relacyjny! Użyj typu {{ref}}, aby połączyć tabele. ",
|
||||
"Reference": "Odnośnik",
|
||||
"Set formatting options, formulas, or column types, such as dates, choices, or attachments. ": "Ustaw opcje formatowania, formuły lub typy kolumn, takie jak daty, wybory lub załączniki. ",
|
||||
"Sharing": "Udostępnianie",
|
||||
"Start with {{equal}} to enter a formula.": "Zacznij od {{equal}}, aby wprowadzić formułę.",
|
||||
"convert to card view, select data, and more.": "Konwertuj na widok karty, wybierz Dane i nie tylko.",
|
||||
"creator panel": "Panel tworzenia",
|
||||
"template library": "Biblioteka szablonów",
|
||||
"Configuring your document": "Konfigurowanie dokumentu",
|
||||
"Customizing columns": "Dostosowywanie kolumn",
|
||||
"Double-click or hit {{enter}} on a cell to edit it. ": "Kliknij dwukrotnie lub naciśnij {{enter}} na komórkę, aby ją edytować. ",
|
||||
"Enter": "Wejść",
|
||||
"Editing Data": "Edycja danych",
|
||||
"Welcome to Grist!": "Witamy w Grist!",
|
||||
"Use {{helpCenter}} for documentation or questions.": "Użyj {{helpCenter}} do dokumentacji lub pytań.",
|
||||
"Browse our {{templateLibrary}} to discover what's possible and get inspired.": "Przeglądaj nasze {{templateLibrary}}, aby odkryć, co jest możliwe i zainspirować się.",
|
||||
"Toggle the {{creatorPanel}} to format columns, ": "Przełącz {{creatorPanel}}, aby sformatować kolumny, ",
|
||||
"Share": "Udostępnij",
|
||||
"Use the Share button ({{share}}) to share the document or export data.": "Użyj przycisku Udostępnij ({{share}}), aby udostępnić dokument lub wyeksportować dane.",
|
||||
"Use {{addNew}} to add widgets, pages, or import more data. ": "Użyj {{addNew}}, aby dodać widżety, strony lub zaimportować więcej danych. "
|
||||
},
|
||||
"GristTooltips": {
|
||||
"Click on “Open row styles” to apply conditional formatting to rows.": "Kliknij na \"Otwórz style wierszy\", aby zastosować formatowanie warunkowe do wierszy.",
|
||||
"Click the Add New button to create new documents or workspaces, or import data.": "Kliknij przycisk Dodaj nowy, aby utworzyć nowe dokumenty lub obszary robocze albo zaimportować dane.",
|
||||
"Learn more.": "Dowiedz się więcej.",
|
||||
"Link your new widget to an existing widget on this page.": "Połącz swój nowy widget z istniejącym widgetem na tej stronie.",
|
||||
"Nested Filtering": "Filtrowanie zagnieżdżone",
|
||||
"Pinned filters are displayed as buttons above the widget.": "Przypięte filtry są wyświetlane jako przyciski nad widżetem.",
|
||||
"Pinning Filters": "Przypinanie filtrów",
|
||||
"Raw Data page": "Strona z danymi surowymi",
|
||||
"Reference Columns": "Kolumny referencyjne",
|
||||
"Select the table containing the data to show.": "Wybierz tabelę zawierającą dane do wyświetlenia.",
|
||||
"Select the table to link to.": "Wybierz tabelę, do której chcesz utworzyć łącze.",
|
||||
"Selecting Data": "Wybieranie danych",
|
||||
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "Strona Dane surowe zawiera listę wszystkich tabel danych w dokumencie, w tym tabel podsumowania i tabel nieuwzględnionych w układach stron.",
|
||||
"The total size of all data in this document, excluding attachments.": "Całkowity rozmiar wszystkich danych w tym dokumencie, z wyłączeniem załączników.",
|
||||
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Wypróbuj zmiany w kopii, a następnie zdecyduj, czy zastąpić oryginał zmianami.",
|
||||
"Unpin to hide the the button while keeping the filter.": "Odepnij, aby ukryć przycisk, zachowując filtr.",
|
||||
"You can filter by more than one column.": "Możesz filtrować według więcej niż jednej kolumny.",
|
||||
"entire": "cały",
|
||||
"Editing Card Layout": "Edytuj układ karty",
|
||||
"Formulas that trigger in certain cases, and store the calculated value as data.": "Formuły, które wyzwalają się w określonych przypadkach i przechowują obliczoną wartość jako dane.",
|
||||
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Przydatne do przechowywania znacznika czasu lub autora nowego rekordu, czyszczenia danych i nie tylko.",
|
||||
"Apply conditional formatting to cells in this column when formula conditions are met.": "Zastosuj formatowanie warunkowe do komórek w tej kolumnie, gdy spełnione są warunki formuły.",
|
||||
"Apply conditional formatting to rows based on formulas.": "Zastosuj formatowanie warunkowe do wierszy na podstawie formuł.",
|
||||
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "Komórki w kolumnie odwołania zawsze identyfikują rekord {{entire}} w tej tabeli, ale można wybrać kolumnę z tego rekordu do wyświetlenia.",
|
||||
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Kliknięcie {{EyeHideIcon}} w każdej komórce powoduje ukrycie pola w tym widoku bez jego usuwania.",
|
||||
"Only those rows will appear which match all of the filters.": "Pojawią się tylko te wiersze, które pasują do wszystkich filtrów.",
|
||||
"Linking Widgets": "Połączenie widżetów",
|
||||
"Rearrange the fields in your card by dragging and resizing cells.": "Zmień kolejność pól na karcie, przeciągając komórki i zmieniając ich rozmiar.",
|
||||
"Reference columns are the key to {{relational}} data in Grist.": "Kolumny referencyjne są kluczem do {{relational}} danych w Grist.",
|
||||
"They allow for one record to point (or refer) to another.": "Pozwalają one na to, aby jeden rekord wskazywał (lub odnosił się) do innego.",
|
||||
"This is the secret to Grist's dynamic and productive layouts.": "To jest sekret dynamicznych i produktywnych układów Grist.",
|
||||
"Updates every 5 minutes.": "Aktualizacje co 5 minut.",
|
||||
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Użyj ikony Σ, aby utworzyć tabele podsumowujące (lub przestawne) dla sum lub sum częściowych.",
|
||||
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Użyj ikony \\u{1D6BA}, aby utworzyć tabele podsumowujące (przestawne) dla sum lub sum częściowych.",
|
||||
"relational": "relacyjny",
|
||||
"Access Rules": "Zasady dostępu",
|
||||
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Reguły dostępu umożliwiają tworzenie reguł szczegółowych w celu określenia, kto może wyświetlać lub edytować poszczególne części dokumentu.",
|
||||
"Add New": "Dodaj nowy"
|
||||
},
|
||||
"DescriptionConfig": {
|
||||
"DESCRIPTION": "OPIS"
|
||||
},
|
||||
"LanguageMenu": {
|
||||
"Language": "Język"
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"ACUserManager": {
|
||||
"Enter email address": "Digite seu email",
|
||||
"Enter email address": "Digite o endereço de e-mail",
|
||||
"Invite new member": "Convidar novo membro",
|
||||
"We'll email an invite to {{email}}": "Enviaremos um convite por e-mail para {{email}}"
|
||||
"We'll email an invite to {{email}}": "Um convite será enviado por e-mail para {{email}}"
|
||||
},
|
||||
"AccessRules": {
|
||||
"Add Column Rule": "Adicionar Regra de Coluna",
|
||||
@ -95,7 +95,8 @@
|
||||
"App": {
|
||||
"Description": "Descrição",
|
||||
"Key": "Chave",
|
||||
"Memory Error": "Erro de Memória"
|
||||
"Memory Error": "Erro de Memória",
|
||||
"Translators: please translate this only when your language is ready to be offered to users": "Tradutores: por favor, traduzam isso apenas quando seu idioma estiver pronto para ser oferecido aos usuários"
|
||||
},
|
||||
"AppHeader": {
|
||||
"Home Page": "Página inicial",
|
||||
@ -277,7 +278,7 @@
|
||||
"Save and Reload": "Salvar e Recarregar",
|
||||
"This document's ID (for API use):": "O ID deste documento (para uso em API):",
|
||||
"Time Zone:": "Fuso horário:",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Document ID copied to clipboard": "ID do documento copiado para a área de transferência",
|
||||
"API": "API"
|
||||
},
|
||||
@ -712,7 +713,7 @@
|
||||
"Unmark table On-Demand?": "Desmarcar a tabela Sob-Demanda?"
|
||||
},
|
||||
"ViewLayoutMenu": {
|
||||
"Advanced Sort & Filter": "Classificação e Filtros Avançados",
|
||||
"Advanced Sort & Filter": "Classificação e filtragem avançadas",
|
||||
"Copy anchor link": "Copiar o link de ancoragem",
|
||||
"Data selection": "Seleção de dados",
|
||||
"Delete record": "Excluir registro",
|
||||
@ -825,7 +826,7 @@
|
||||
},
|
||||
"modals": {
|
||||
"Cancel": "Cancelar",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Save": "Salvar"
|
||||
},
|
||||
"pages": {
|
||||
@ -940,7 +941,7 @@
|
||||
"Error in the cell": "Erro na célula"
|
||||
},
|
||||
"HyperLinkEditor": {
|
||||
"[link label] url": "[rótulo do link] url"
|
||||
"[link label] url": "[rótulo do link] URL"
|
||||
},
|
||||
"NumericTextBox": {
|
||||
"Currency": "Moeda",
|
||||
|
@ -39,7 +39,7 @@
|
||||
"ACUserManager": {
|
||||
"Enter email address": "Введите адрес электронной почты",
|
||||
"Invite new member": "Пригласить нового участника",
|
||||
"We'll email an invite to {{email}}": "Мы вышлем приглашение на {{email}}"
|
||||
"We'll email an invite to {{email}}": "Приглашение будет отправлено на электронную почту {{email}}"
|
||||
},
|
||||
"AccountPage": {
|
||||
"API": "API",
|
||||
@ -50,7 +50,7 @@
|
||||
"Account settings": "Настройки аккаунта",
|
||||
"Edit": "Редактировать",
|
||||
"Name": "Имя",
|
||||
"Email": "Email",
|
||||
"Email": "E-mail",
|
||||
"Login Method": "Способ входа в систему",
|
||||
"Names only allow letters, numbers and certain special characters": "В именах допускаются только буквы, цифры и определенные специальные символы",
|
||||
"Save": "Сохранить",
|
||||
@ -62,7 +62,8 @@
|
||||
"App": {
|
||||
"Memory Error": "Ошибка памяти",
|
||||
"Description": "Описание",
|
||||
"Key": "Ключ"
|
||||
"Key": "Ключ",
|
||||
"Translators: please translate this only when your language is ready to be offered to users": "Переводчики: пожалуйста, переведите это только тогда, когда ваш язык будет готов для использования пользователями"
|
||||
},
|
||||
"ColorSelect": {
|
||||
"Apply": "Применить",
|
||||
@ -338,7 +339,7 @@
|
||||
"Edited {{at}}": "Отредактировано {{at}}",
|
||||
"Document will be permanently deleted.": "Документ будет удален навсегда.",
|
||||
"Documents stay in Trash for 30 days, after which they get deleted permanently.": "Документы остаются в Корзине в течение 30 дней, после чего удаляются навсегда.",
|
||||
"Examples & Templates": "Примеры & Шаблоны",
|
||||
"Examples & Templates": "Примеры и Шаблоны",
|
||||
"Featured": "Рекомендуемые",
|
||||
"Manage Users": "Управление пользователями",
|
||||
"Move": "Переместить",
|
||||
@ -369,7 +370,7 @@
|
||||
"DocumentSettings": {
|
||||
"Document Settings": "Настройки документа",
|
||||
"Currency:": "Валюта:",
|
||||
"Ok": "Ok",
|
||||
"Ok": "OK",
|
||||
"Locale:": "Регион:",
|
||||
"Save and Reload": "Сохранить и Перезагрузить",
|
||||
"Save": "Сохранить",
|
||||
@ -394,7 +395,7 @@
|
||||
},
|
||||
"DocumentUsage": {
|
||||
"Data Size": "Размер данных",
|
||||
"Attachments Size": "Размер вложений",
|
||||
"Attachments Size": "Размер Вложений",
|
||||
"For higher limits, ": "Для более высоких пределов, ",
|
||||
"Rows": "Строки",
|
||||
"Contact the site owner to upgrade the plan to raise limits.": "Свяжитесь с владельцем сайта для обновления тарифа и увеличения лимитов.",
|
||||
@ -417,7 +418,7 @@
|
||||
"Investment Research": "Инвестиционные исследования",
|
||||
"Check out our related tutorial for how to link data, and create high-productivity layouts.": "Ознакомьтесь с нашим соответствующим учебником, чтобы узнать, как связывать данные и создавать высокопроизводительные макеты.",
|
||||
"Lightweight CRM": "Легкая CRM",
|
||||
"Tutorial: Analyze & Visualize": "Учебник: Анализ и визуализация",
|
||||
"Tutorial: Analyze & Visualize": "Учебник: Анализ и Визуализация",
|
||||
"Check out our related tutorial to learn how to create summary tables and charts, and to link charts dynamically.": "Ознакомьтесь с нашим соответствующим учебником, чтобы узнать, как создавать сводные таблицы и графики, а также динамически связывать графики.",
|
||||
"Tutorial: Create a CRM": "Учебник: Создание CRM",
|
||||
"Tutorial: Manage Business Data": "Учебник: Управление бизнес-данными",
|
||||
@ -469,7 +470,7 @@
|
||||
"Access Details": "Детали доступа",
|
||||
"Create Empty Document": "Создать пустой документ",
|
||||
"Delete": "Удалить",
|
||||
"Examples & Templates": "Примеры & Шаблоны",
|
||||
"Examples & Templates": "Примеры и Шаблоны",
|
||||
"Rename": "Переименовать",
|
||||
"Delete {{workspace}} and all included documents?": "Удалить {{workspace}} и все прилагаемые документы?",
|
||||
"Trash": "Корзина",
|
||||
@ -590,7 +591,7 @@
|
||||
"Save": "Сохранить",
|
||||
"Select Widget": "Выберите виджет",
|
||||
"Series_one": "Ряд",
|
||||
"Sort & Filter": "Сортировка & Фильтрация",
|
||||
"Sort & Filter": "Сортировка и Фильтрация",
|
||||
"TRANSFORM": "ПРЕОБРАЗОВАНИЕ",
|
||||
"WIDGET TITLE": "ЗАГОЛОВОК ВИДЖЕТА",
|
||||
"You do not have edit access to this document": "У вас нет прав на редактирование этого документа",
|
||||
@ -648,7 +649,7 @@
|
||||
"UserManagerModel": {
|
||||
"In Full": "Полный",
|
||||
"None": "Без доступа",
|
||||
"View & Edit": "Просмотр & Редактирование",
|
||||
"View & Edit": "Просмотр и Редактирование",
|
||||
"Viewer": "Наблюдатель",
|
||||
"Owner": "Владелец",
|
||||
"No Default Access": "Нет доступа по умолчанию",
|
||||
@ -671,7 +672,7 @@
|
||||
"Compact": "Компактная"
|
||||
},
|
||||
"ViewLayoutMenu": {
|
||||
"Advanced Sort & Filter": "Расширенная Сортировка & Фильтр",
|
||||
"Advanced Sort & Filter": "Расширенная Сортировка и Фильтрация",
|
||||
"Delete record": "Удалить запись",
|
||||
"Delete widget": "Удалить виджет",
|
||||
"Download as XLSX": "Скачать как XLSX",
|
||||
@ -682,7 +683,9 @@
|
||||
"Open configuration": "Открыть конфигурацию",
|
||||
"Print widget": "Печать виджета",
|
||||
"Data selection": "Выбор данных",
|
||||
"Widget options": "Параметры виджета"
|
||||
"Widget options": "Параметры виджета",
|
||||
"Add to page": "Добавить на страницу",
|
||||
"Collapse widget": "Свернуть виджет"
|
||||
},
|
||||
"FieldEditor": {
|
||||
"It should be impossible to save a plain data value into a formula column": "Должно быть невозможно сохранить значение простых данных в столбце формулы",
|
||||
@ -957,5 +960,8 @@
|
||||
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Правила доступа дают вам возможность создавать детальные правила, определяющие, кто может просматривать или редактировать части вашего документа.",
|
||||
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Используйте 𝚺 значок для создания сводных таблиц для итогов или промежуточных итогов.",
|
||||
"relational": "реляционный"
|
||||
},
|
||||
"DescriptionConfig": {
|
||||
"DESCRIPTION": "ОПИСАНИЕ"
|
||||
}
|
||||
}
|
||||
|
@ -2138,6 +2138,62 @@ function testDocApi() {
|
||||
assert.deepEqual(resp.data, { error: 'tableId parameter should be a string: undefined' });
|
||||
});
|
||||
|
||||
it("GET /docs/{did}/download/table-schema serves table-schema-encoded document", async function() {
|
||||
const resp = await axios.get(`${serverUrl}/api/docs/${docIds.TestDoc}/download/table-schema?tableId=Foo`, chimpy);
|
||||
assert.equal(resp.status, 200);
|
||||
const expected = {
|
||||
format: "csv",
|
||||
mediatype: "text/csv",
|
||||
encoding: "utf-8",
|
||||
dialect: {
|
||||
delimiter: ",",
|
||||
doubleQuote: true,
|
||||
},
|
||||
name: 'foo',
|
||||
title: 'Foo',
|
||||
schema: {
|
||||
fields: [{
|
||||
name: 'A',
|
||||
type: 'string',
|
||||
format: 'default',
|
||||
}, {
|
||||
name: 'B',
|
||||
type: 'string',
|
||||
format: 'default',
|
||||
}]
|
||||
}
|
||||
};
|
||||
assert.deepInclude(resp.data, expected);
|
||||
|
||||
const resp2 = await axios.get(resp.data.path, chimpy);
|
||||
assert.equal(resp2.status, 200);
|
||||
assert.equal(resp2.data, 'A,B\nSanta,1\nBob,11\nAlice,2\nFelix,22\n');
|
||||
});
|
||||
|
||||
it("GET /docs/{did}/download/table-schema respects permissions", async function() {
|
||||
// kiwi has no access to TestDoc
|
||||
const resp = await axios.get(`${serverUrl}/api/docs/${docIds.TestDoc}/download/table-schema?tableId=Table1`, kiwi);
|
||||
assert.equal(resp.status, 403);
|
||||
assert.deepEqual(resp.data, {"error":"No view access"});
|
||||
});
|
||||
|
||||
it("GET /docs/{did}/download/table-schema returns 404 if tableId is invalid", async function() {
|
||||
const resp = await axios.get(
|
||||
`${serverUrl}/api/docs/${docIds.TestDoc}/download/table-schema?tableId=MissingTableId`,
|
||||
chimpy,
|
||||
);
|
||||
assert.equal(resp.status, 404);
|
||||
assert.deepEqual(resp.data, { error: 'Table MissingTableId not found.' });
|
||||
});
|
||||
|
||||
it("GET /docs/{did}/download/table-schema returns 400 if tableId is missing", async function() {
|
||||
const resp = await axios.get(
|
||||
`${serverUrl}/api/docs/${docIds.TestDoc}/download/table-schema`, chimpy);
|
||||
assert.equal(resp.status, 400);
|
||||
assert.deepEqual(resp.data, { error: 'tableId parameter should be a string: undefined' });
|
||||
});
|
||||
|
||||
|
||||
it("GET /docs/{did}/download/xlsx serves XLSX-encoded document", async function() {
|
||||
const resp = await axios.get(`${serverUrl}/api/docs/${docIds.Timesheets}/download/xlsx?tableId=Table1`, chimpy);
|
||||
assert.equal(resp.status, 200);
|
||||
|
Loading…
Reference in New Issue
Block a user