> = [
- { label: 'Aggregations', options: [] },
- { label: 'Macros', options: [] },
+ { label: t('components.select-row.aggregate-options.options.label.aggregations', 'Aggregations'), options: [] },
+ { label: t('components.select-row.aggregate-options.options.label.macros', 'Macros'), options: [] },
];
for (const func of db.functions()) {
// Create groups for macros
@@ -111,7 +112,11 @@ export function SelectRow({ query, onQueryChange, db, columns }: SelectRowProps)
{query.sql?.columns?.map((item, index) => (
-
+
-
+
{queryRowFilter.filter && (
-
+
)}
{queryRowFilter.group && (
-
+
diff --git a/packages/grafana-sql/src/index.ts b/packages/grafana-sql/src/index.ts
index 8b953f68d5a..0de11d1f5d6 100644
--- a/packages/grafana-sql/src/index.ts
+++ b/packages/grafana-sql/src/index.ts
@@ -23,3 +23,4 @@ export { createSelectClause, haveColumns } from './utils/sql.utils';
export { applyQueryDefaults } from './defaults';
export { makeVariable } from './utils/testHelpers';
export { QueryEditorExpressionType } from './expressions';
+export { loadResources } from './loadResources';
diff --git a/packages/grafana-sql/src/loadResources.ts b/packages/grafana-sql/src/loadResources.ts
new file mode 100644
index 00000000000..ab977b8fbb1
--- /dev/null
+++ b/packages/grafana-sql/src/loadResources.ts
@@ -0,0 +1,11 @@
+import { LANGUAGES, ResourceLoader, Resources } from '@grafana/i18n';
+
+const resources = LANGUAGES.reduce Promise<{ default: Resources }>>>((acc, lang) => {
+ acc[lang.code] = async () => await import(`./locales/${lang.code}/grafana-sql.json`);
+ return acc;
+}, {});
+
+export const loadResources: ResourceLoader = async (resolvedLanguage: string) => {
+ const translation = await resources[resolvedLanguage]();
+ return translation.default;
+};
diff --git a/packages/grafana-sql/src/locales/en-US/grafana-sql.json b/packages/grafana-sql/src/locales/en-US/grafana-sql.json
new file mode 100644
index 00000000000..7b6c7c16021
--- /dev/null
+++ b/packages/grafana-sql/src/locales/en-US/grafana-sql.json
@@ -0,0 +1,148 @@
+{
+ "components": {
+ "confirm-modal": {
+ "builder-mode": "Builder mode does not display changes made in code. The query builder will display the last changes you made in builder mode.",
+ "cancel": "Cancel",
+ "clipboard": "Do you want to copy your code to the clipboard?",
+ "copy-code-and-switch": "Copy code and switch",
+ "discard-code-and-switch": "Discard code and switch",
+ "warning": "Warning"
+ },
+ "connection-limits": {
+ "auto-max-idle": "Auto max idle",
+ "content-auto-max-idle": "If enabled, automatically set the number of <1>Maximum idle connections1> to the same value as<3> Max open connections3>. If the number of maximum open connections is not set it will be set to the default ({{defaultMaxIdle}}).",
+ "content-max-idle": "The maximum number of connections in the idle connection pool.If <1>Max open connections1> is greater than 0 but less than the <3>Max idle connections3>, then the <5>Max idle connections5> will be reduced to match the <8>Max open connections8> limit. If set to 0, no idle connections are retained.",
+ "content-max-lifetime": "The maximum amount of time in seconds a connection may be reused. If set to 0, connections are reused forever.",
+ "content-max-open": "The maximum number of open connections to the database. If <1>Max idle connections1> is greater than 0 and the <3>Max open connections3> is less than <5>Max idle connections5>, then<7>Max idle connections7> will be reduced to match the <9>Max open connections9> limit. If set to 0, there is no limit on the number of open connections.",
+ "max-idle": "Max idle",
+ "max-lifetime": "Max lifetime",
+ "max-open": "Max open",
+ "title-connection-limits": "Connection limits"
+ },
+ "dataset-selector": {
+ "aria-label-dataset-selector": "Dataset selector"
+ },
+ "error-boundary": {
+ "fall-back": {
+ "error": "Error"
+ }
+ },
+ "get-custom-operators": {
+ "custom-operators": {
+ "label": {
+ "macros": "Macros"
+ }
+ }
+ },
+ "make-render-column": {
+ "render-column": {
+ "aria-label-group-by": "Group by",
+ "title-remove-group-by-column": "Remove group by column"
+ }
+ },
+ "order-by-row": {
+ "aria-label-order-by": "Order by",
+ "label-limit": "Limit",
+ "label-offset": "Offset",
+ "label-order-by": "Order by"
+ },
+ "preview": {
+ "label-element": {
+ "preview": "Preview",
+ "tooltip-copy-to-clipboard": "Copy to clipboard"
+ }
+ },
+ "query-header": {
+ "content-invalid-query": "Your query is invalid. Check below for details. <1>1>However, you can still run this query.",
+ "label-dataset": "Dataset",
+ "label-filter": "Filter",
+ "label-format": "Format",
+ "label-group": "Group",
+ "label-order": "Order",
+ "label-preview": "Preview",
+ "label-table": "Table",
+ "placeholder-select-format": "Select format",
+ "run-query": "Run query"
+ },
+ "query-toolbox": {
+ "content-hit-ctrlcmdreturn-to-run-query": "Hit CTRL/CMD+Return to run query",
+ "tooltip-collapse": "Collapse editor",
+ "tooltip-expand": "Expand editor",
+ "tooltip-format-query": "Format query"
+ },
+ "query-validator": {
+ "query-will-process": "<0>0> This query will process <2>{{bytes}}2> when run.",
+ "validating-query": "Validating query..."
+ },
+ "raw-editor": {
+ "render-placeholder": {
+ "editing-in-expanded-code-editor": "Editing in expanded code editor"
+ },
+ "title-query-num": "Query {{queryNum}}"
+ },
+ "select-column": {
+ "label-column": "Column"
+ },
+ "select-custom-function-parameters": {
+ "aria-label-parameter": "Parameter {{index}} for column {{columnIndex}}",
+ "render-parameters": {
+ "params": {
+ "title-remove-parameter": "Remove parameter"
+ }
+ },
+ "title-add-parameter": "Add parameter"
+ },
+ "select-row": {
+ "aggregate-options": {
+ "options": {
+ "label": {
+ "aggregations": "Aggregations",
+ "macros": "Macros"
+ }
+ }
+ },
+ "label": {
+ "time": "time",
+ "value": "value"
+ },
+ "label-alias": "Alias",
+ "label-data-operations": "Data operations",
+ "title-add-column": "Add column",
+ "title-remove-column": "Remove column"
+ },
+ "settings": {
+ "aria-label-conjunction": "Conjunction",
+ "aria-label-field": "Field",
+ "aria-label-operator": "Operator",
+ "title-button-filter": "{{ buttonLabel }} filter"
+ },
+ "sql-query-editor-lazy": {
+ "text-loading-editor": "Loading editor"
+ },
+ "table-selector": {
+ "aria-label-table-selector": "Table selector",
+ "placeholder-loading": "Loading tables",
+ "placeholder-select-table": "Select table"
+ },
+ "tlssecrets-config": {
+ "content-tlsssl-client-certificate": "To authenticate with an TLS/SSL client certificate, provide the client certificate here.",
+ "content-tlsssl-client-key": "To authenticate with a client TLS/SSL certificate, provide the key here.",
+ "content-tlsssl-root-certificate": "If the selected TLS/SSL mode requires a server root certificate, provide it here",
+ "tlsssl-client-certificate": "TLS/SSL Client Certificate",
+ "tlsssl-client-key": "TLS/SSL Client Key",
+ "tlsssl-root-certificate": "TLS/SSL Root Certificate"
+ },
+ "visual-editor": {
+ "label-filter-by-column-value": "Filter by column value",
+ "label-group-by-column": "Group by column"
+ },
+ "widgets": {
+ "aria-label-macros-value-selector": "Macros value selector"
+ }
+ },
+ "utils": {
+ "get-columns-width-indices": {
+ "label-selected-columns": "Selected columns"
+ }
+ }
+}
diff --git a/packages/grafana-sql/src/locales/i18next-parser.config.cjs b/packages/grafana-sql/src/locales/i18next-parser.config.cjs
new file mode 100644
index 00000000000..9ab1f779724
--- /dev/null
+++ b/packages/grafana-sql/src/locales/i18next-parser.config.cjs
@@ -0,0 +1,12 @@
+module.exports = {
+ locales: ['en-US'], // Only en-US is updated - Crowdin will PR with other languages
+ sort: true,
+ createOldCatalogs: false,
+ failOnWarnings: true,
+ verbose: false,
+ resetDefaultValueLocale: 'en-US', // Updates extracted values when they change in code
+
+ defaultNamespace: 'grafana-sql',
+ input: ['../**/*.{tsx,ts}'],
+ output: './src/locales/$LOCALE/$NAMESPACE.json',
+};
diff --git a/packages/grafana-sql/src/utils/getColumnsWithIndices.ts b/packages/grafana-sql/src/utils/getColumnsWithIndices.ts
index 6c7dccbff9e..9bc786ca3e9 100644
--- a/packages/grafana-sql/src/utils/getColumnsWithIndices.ts
+++ b/packages/grafana-sql/src/utils/getColumnsWithIndices.ts
@@ -1,4 +1,5 @@
import { SelectableValue } from '@grafana/data';
+import { t } from '@grafana/i18n';
import { SQLQuery } from '../types';
@@ -20,7 +21,7 @@ export function getColumnsWithIndices(query: SQLQuery, fields: SelectableValue[]
return [
{
value: '',
- label: 'Selected columns',
+ label: t('utils.get-columns-width-indices.label-selected-columns', 'Selected columns'),
options,
expanded: true,
},
diff --git a/public/app/plugins/datasource/mssql/module.ts b/public/app/plugins/datasource/mssql/module.ts
index 69e21d12c3d..7cf4eeaafe1 100644
--- a/public/app/plugins/datasource/mssql/module.ts
+++ b/public/app/plugins/datasource/mssql/module.ts
@@ -1,6 +1,6 @@
import { DataSourcePlugin } from '@grafana/data';
import { initPluginTranslations } from '@grafana/i18n';
-import { SQLQuery, SqlQueryEditorLazy } from '@grafana/sql';
+import { SQLQuery, SqlQueryEditorLazy, loadResources as loadSQLResources } from '@grafana/sql';
import { CheatSheet } from './CheatSheet';
import { ConfigurationEditor } from './configuration/ConfigurationEditor';
@@ -8,7 +8,7 @@ import { MssqlDatasource } from './datasource';
import pluginJson from './plugin.json';
import { MssqlOptions } from './types';
-initPluginTranslations(pluginJson.id);
+initPluginTranslations(pluginJson.id, [loadSQLResources]);
export const plugin = new DataSourcePlugin(MssqlDatasource)
.setQueryEditor(SqlQueryEditorLazy)
diff --git a/yarn.lock b/yarn.lock
index 4a332c66657..35bc7915164 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3572,6 +3572,7 @@ __metadata:
"@emotion/css": "npm:11.13.5"
"@grafana/data": "npm:12.1.0-pre"
"@grafana/e2e-selectors": "npm:12.1.0-pre"
+ "@grafana/i18n": "npm:12.1.0-pre"
"@grafana/plugin-ui": "npm:0.10.6"
"@grafana/runtime": "npm:12.1.0-pre"
"@grafana/tsconfig": "npm:^2.0.0"
@@ -3589,6 +3590,7 @@ __metadata:
"@types/react-virtualized-auto-sizer": "npm:1.0.4"
"@types/systemjs": "npm:6.15.1"
"@types/uuid": "npm:10.0.0"
+ i18next-parser: "npm:9.3.0"
immutable: "npm:5.0.3"
jest: "npm:^29.6.4"
lodash: "npm:4.17.21"