From d384cdc42fdebac6a3ef69ca4298b03e9a509356 Mon Sep 17 00:00:00 2001 From: Valerii Sidorenko Date: Mon, 26 Feb 2024 10:25:35 +0000 Subject: [PATCH 1/2] feat: show diffierent page titles on different pages --- package-lock.json | 28 +++++ package.json | 1 + src/containers/App/App.tsx | 2 + src/containers/App/Providers.tsx | 25 +++-- src/containers/Cluster/Cluster.tsx | 16 ++- src/containers/Clusters/Clusters.tsx | 10 +- src/containers/Clusters/i18n/en.json | 4 +- src/containers/Clusters/i18n/index.ts | 7 +- src/containers/Clusters/i18n/ru.json | 4 +- src/containers/Node/Node.tsx | 21 ++-- src/containers/Node/NodePages.ts | 5 +- src/containers/Node/i18n/index.ts | 7 +- src/containers/Tablet/Tablet.tsx | 102 ++++++++++-------- src/containers/Tablet/i18n/index.ts | 7 +- .../TabletsFilters/TabletsFilters.js | 31 ++++-- src/containers/TabletsFilters/i18n/en.json | 3 + src/containers/TabletsFilters/i18n/index.ts | 8 ++ src/containers/TabletsFilters/i18n/ru.json | 3 + .../Tenant/Diagnostics/Diagnostics.tsx | 23 ++-- src/containers/Tenant/Query/Query.tsx | 14 ++- .../Tenant/Query/QueryTabs/QueryTabs.tsx | 2 +- src/containers/Tenant/Tenant.tsx | 7 ++ src/containers/Tenant/i18n/en.json | 2 + src/containers/Tenant/i18n/index.ts | 7 +- src/containers/Tenant/i18n/ru.json | 2 + src/utils/i18n/i18n.ts | 12 ++- 26 files changed, 245 insertions(+), 108 deletions(-) create mode 100644 src/containers/TabletsFilters/i18n/en.json create mode 100644 src/containers/TabletsFilters/i18n/index.ts create mode 100644 src/containers/TabletsFilters/i18n/ru.json diff --git a/package-lock.json b/package-lock.json index ec0de06d05..1d6bf59df7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "path-to-regexp": "^3.0.0", "qs": "^6.11.0", "react-error-boundary": "^4.0.12", + "react-helmet-async": "2.0.4", "react-json-inspector": "^7.1.1", "react-list": "^0.8.11", "react-monaco-editor": "^0.47.0", @@ -12711,6 +12712,14 @@ "node": ">=12" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -20083,6 +20092,20 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, + "node_modules/react-helmet-async": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz", + "integrity": "sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ==", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -22446,6 +22469,11 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 19351df2f3..ffac37bec9 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "qs": "^6.11.0", "react-error-boundary": "^4.0.12", "react-json-inspector": "^7.1.1", + "react-helmet-async": "2.0.4", "react-list": "^0.8.11", "react-monaco-editor": "^0.47.0", "react-redux": "^7.2.6", diff --git a/src/containers/App/App.tsx b/src/containers/App/App.tsx index 1c54bb0929..ac071ab23f 100644 --- a/src/containers/App/App.tsx +++ b/src/containers/App/App.tsx @@ -1,5 +1,6 @@ import React from 'react'; import {connect} from 'react-redux'; +import {Helmet} from 'react-helmet-async'; import ContentWrapper, {Content} from './Content'; import ReduxTooltip from '../ReduxTooltip/ReduxTooltip'; @@ -30,6 +31,7 @@ export interface AppProps { function App({store, history, singleClusterMode, children, userSettings = settings}: AppProps) { return ( + diff --git a/src/containers/App/Providers.tsx b/src/containers/App/Providers.tsx index 022493dcb2..a62ec64d74 100644 --- a/src/containers/App/Providers.tsx +++ b/src/containers/App/Providers.tsx @@ -4,6 +4,7 @@ import {Router} from 'react-router'; import {QueryParamProvider} from 'use-query-params'; import {ReactRouter5Adapter} from 'use-query-params/adapters/react-router-5'; import {ThemeProvider} from '@gravity-ui/uikit'; +import {HelmetProvider} from 'react-helmet-async'; import {ComponentsProvider} from '../../components/ComponentsProvider/ComponentsProvider'; import {componentsRegistry as defaultComponentsRegistry} from '../../components/ComponentsProvider/componentsRegistry'; @@ -28,17 +29,19 @@ export function Providers({ children, }: ProvidersProps) { return ( - - - - - - {children} - - - - - + + + + + + + {children} + + + + + + ); } diff --git a/src/containers/Cluster/Cluster.tsx b/src/containers/Cluster/Cluster.tsx index c225fb8ec1..d85f68586b 100644 --- a/src/containers/Cluster/Cluster.tsx +++ b/src/containers/Cluster/Cluster.tsx @@ -1,6 +1,7 @@ import {useEffect, useMemo, useRef} from 'react'; import {Redirect, Switch, Route, useLocation, useRouteMatch} from 'react-router'; import {useDispatch} from 'react-redux'; +import {Helmet} from 'react-helmet-async'; import cn from 'bem-cn-lite'; import qs from 'qs'; @@ -52,7 +53,7 @@ function Cluster({ const dispatch = useDispatch(); - const activeTab = useClusterTab(); + const activeTabId = useClusterTab(); const location = useLocation(); const queryParams = qs.parse(location.search, { @@ -117,14 +118,23 @@ function Cluster({ ); }; + const clusterTitle = cluster?.Name ?? clusterName ?? CLUSTER_DEFAULT_TITLE; + const activeTab = useMemo(() => clusterTabs.find(({id}) => id === activeTabId), [activeTabId]); + return (
+ + {activeTab ? {activeTab.title} : null} +
{getClusterTitle()}
{ const path = getClusterPath(id as ClusterTab, queryParams); @@ -197,7 +207,7 @@ function Cluster({ > - +
diff --git a/src/containers/Clusters/Clusters.tsx b/src/containers/Clusters/Clusters.tsx index 67987a13d6..0b312841c5 100644 --- a/src/containers/Clusters/Clusters.tsx +++ b/src/containers/Clusters/Clusters.tsx @@ -1,11 +1,12 @@ import {useCallback, useMemo} from 'react'; import {useDispatch} from 'react-redux'; +import {Helmet} from 'react-helmet-async'; import DataTable from '@gravity-ui/react-data-table'; - import {TableColumnSetup, Select} from '@gravity-ui/uikit'; import {Search} from '../../components/Search'; +import {Loader} from '../../components/Loader'; import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants'; import {useAutofetcher} from '../../utils/hooks'; @@ -35,10 +36,9 @@ import {ClustersStatistics} from './ClustersStatistics'; import {CLUSTERS_COLUMNS} from './columns'; import {useSelectedColumns} from './useSelectedColumns'; import {b} from './shared'; +import i18n from './i18n'; import './Clusters.scss'; -import {Loader} from '../../components/Loader'; -import i18n from './i18n'; export function Clusters() { const dispatch = useDispatch(); @@ -103,6 +103,10 @@ export function Clusters() { return (
+ + {i18n('page_title')} + +
diff --git a/src/containers/Clusters/i18n/en.json b/src/containers/Clusters/i18n/en.json index b800983964..db7438356d 100644 --- a/src/containers/Clusters/i18n/en.json +++ b/src/containers/Clusters/i18n/en.json @@ -13,5 +13,7 @@ "statistics_load": "Load", "statistics_storage": "Storage", - "tooltip_no-cluster-data": "No cluster data" + "tooltip_no-cluster-data": "No cluster data", + + "page_title": "Clusters" } diff --git a/src/containers/Clusters/i18n/index.ts b/src/containers/Clusters/i18n/index.ts index b1d4a0861e..ce7771fcad 100644 --- a/src/containers/Clusters/i18n/index.ts +++ b/src/containers/Clusters/i18n/index.ts @@ -1,11 +1,8 @@ -import {Lang, i18n} from '../../../utils/i18n'; +import {registerKeysets} from '../../../utils/i18n'; import en from './en.json'; import ru from './ru.json'; const COMPONENT = 'ydb-clusters-page'; -i18n.registerKeyset(Lang.En, COMPONENT, en); -i18n.registerKeyset(Lang.Ru, COMPONENT, ru); - -export default i18n.keyset(COMPONENT); +export default registerKeysets(COMPONENT, {ru, en}); diff --git a/src/containers/Clusters/i18n/ru.json b/src/containers/Clusters/i18n/ru.json index b65b081f09..f420ffde20 100644 --- a/src/containers/Clusters/i18n/ru.json +++ b/src/containers/Clusters/i18n/ru.json @@ -13,5 +13,7 @@ "statistics_load": "Нагрузка", "statistics_storage": "Хранилище", - "tooltip_no-cluster-data": "Нет данных кластера" + "tooltip_no-cluster-data": "Нет данных кластера", + + "page_title": "Кластеры" } diff --git a/src/containers/Node/Node.tsx b/src/containers/Node/Node.tsx index 0f7f986450..25a2480ff4 100644 --- a/src/containers/Node/Node.tsx +++ b/src/containers/Node/Node.tsx @@ -2,6 +2,7 @@ import {useEffect, useMemo, useRef} from 'react'; import {useLocation, useRouteMatch} from 'react-router'; import cn from 'bem-cn-lite'; import {useDispatch} from 'react-redux'; +import {Helmet} from 'react-helmet-async'; import {Tabs} from '@gravity-ui/uikit'; import {Link} from 'react-router-dom'; @@ -52,10 +53,6 @@ function Node(props: NodeProps) { const {activeTabVerified, nodeTabs} = useMemo(() => { const hasStorage = node?.Roles?.find((el) => el === STORAGE_ROLE); - let actualActiveTab = activeTab; - if (!hasStorage && activeTab === STORAGE) { - actualActiveTab = OVERVIEW; - } const nodePages = hasStorage ? NODE_PAGES : NODE_PAGES.filter((el) => el.id !== STORAGE); const actualNodeTabs = nodePages.map((page) => { @@ -65,6 +62,11 @@ function Node(props: NodeProps) { }; }); + let actualActiveTab = actualNodeTabs.find(({id}) => id === activeTab); + if (!actualActiveTab) { + actualActiveTab = actualNodeTabs[0]; + } + return {activeTabVerified: actualActiveTab, nodeTabs: actualNodeTabs}; }, [activeTab, node]); @@ -97,7 +99,7 @@ function Node(props: NodeProps) { ( { - switch (activeTab) { + switch (activeTabVerified.id) { case STORAGE: { return (
@@ -145,6 +147,13 @@ function Node(props: NodeProps) { if (node) { return (
+ + {activeTabVerified.title} + + { nodeId: queryNodeId, tenantName: queryTenantName, type: queryTabletType, + clusterName: queryClusterName, } = parseQuery(location); const nodeId = tablet.NodeId?.toString() || queryNodeId?.toString(); const tenantName = tenantPath || queryTenantName?.toString(); @@ -98,57 +100,69 @@ export const Tablet = () => { ); }; - if (loading && id !== tabletId && isFirstDataFetchRef.current) { - return ; - } + const renderView = () => { + if (loading && id !== tabletId && isFirstDataFetchRef.current) { + return ; + } - if (error) { - return ; - } + if (error) { + return ; + } - if (!tablet || !Object.keys(tablet).length) { - return ( -
- -
- ); - } + if (!tablet || !Object.keys(tablet).length) { + return ( +
+ +
+ ); + } - const {TabletId, Overall, Leader} = tablet; + const {TabletId, Overall, Leader} = tablet; - const externalLinks = [ - { - name: `${DEVELOPER_UI_TITLE} - tablet`, - path: `/tablets?TabletID=${TabletId}`, - }, - ]; + const externalLinks = [ + { + name: `${DEVELOPER_UI_TITLE} - tablet`, + path: `/tablets?TabletID=${TabletId}`, + }, + ]; - return ( -
-
-
-
    {externalLinks.map(renderExternalLinks)}
-
- {i18n('tablet.header')} - - - - - {Leader && } - {loading && } + return ( +
+
+
+
    {externalLinks.map(renderExternalLinks)}
+
+ {i18n('tablet.header')} + + + + + {Leader && } + {loading && } +
+ + +
+
+
- - -
-
-
-
+ ); + }; + return ( + <> + + {`${id} - ${ + tenantName || queryClusterName || i18n('tablet.header') + }`} + + {renderView()} + ); }; diff --git a/src/containers/Tablet/i18n/index.ts b/src/containers/Tablet/i18n/index.ts index 9ff2cdf682..966a41f5ad 100644 --- a/src/containers/Tablet/i18n/index.ts +++ b/src/containers/Tablet/i18n/index.ts @@ -1,11 +1,8 @@ -import {i18n, Lang} from '../../../utils/i18n'; +import {registerKeysets} from '../../../utils/i18n'; import en from './en.json'; import ru from './ru.json'; const COMPONENT = 'ydb-tablet-page'; -i18n.registerKeyset(Lang.En, COMPONENT, en); -i18n.registerKeyset(Lang.Ru, COMPONENT, ru); - -export default i18n.keyset(COMPONENT); +export default registerKeysets(COMPONENT, {en, ru}); diff --git a/src/containers/TabletsFilters/TabletsFilters.js b/src/containers/TabletsFilters/TabletsFilters.js index 2da325fcef..804a22736c 100644 --- a/src/containers/TabletsFilters/TabletsFilters.js +++ b/src/containers/TabletsFilters/TabletsFilters.js @@ -2,8 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import cn from 'bem-cn-lite'; -import qs from 'qs'; import _ from 'lodash'; +import {Helmet} from 'react-helmet-async'; import {Loader, Select} from '@gravity-ui/uikit'; import ReactList from 'react-list'; @@ -21,6 +21,9 @@ import { getFilteredTablets, getTablets, } from '../../store/reducers/tabletsFilters'; +import {parseQuery} from '../../routes'; +import {CLUSTER_DEFAULT_TITLE} from '../../utils/constants'; +import i18n from './i18n'; import './TabletsFilters.scss'; @@ -69,6 +72,7 @@ export class TabletsFilters extends React.Component { state = { nodeFilter: [], tenantPath: '', + clusterName: '', }; reloadDescriptor = -1; @@ -76,10 +80,8 @@ export class TabletsFilters extends React.Component { componentDidMount() { const {setStateFilter, setTypeFilter, setHeaderBreadcrumbs} = this.props; - const queryParams = qs.parse(this.props.location.search, { - ignoreQueryPrefix: true, - }); - const {nodeIds, type, path, state} = queryParams; + const queryParams = parseQuery(this.props.location); + const {nodeIds, type, path, state, clusterName} = queryParams; const nodes = TabletsFilters.parseNodes(nodeIds); if (state) { @@ -91,7 +93,7 @@ export class TabletsFilters extends React.Component { setTypeFilter([type]); } - this.setState({nodeFilter: nodes, tenantPath: path}, () => { + this.setState({nodeFilter: nodes, tenantPath: path, clusterName}, () => { this.makeRequest(); }); @@ -216,7 +218,7 @@ export class TabletsFilters extends React.Component { ); }; - render() { + renderView = () => { const {loading, wasLoaded, error} = this.props; if (loading && !wasLoaded) { @@ -230,6 +232,21 @@ export class TabletsFilters extends React.Component { } else { return this.renderContent(); } + }; + + render() { + const {tenantPath, clusterName} = this.state; + + return ( + <> + + {`${tenantPath || clusterName || CLUSTER_DEFAULT_TITLE} - ${i18n( + 'page.title', + )}`} + + {this.renderView()} + + ); } } diff --git a/src/containers/TabletsFilters/i18n/en.json b/src/containers/TabletsFilters/i18n/en.json new file mode 100644 index 0000000000..1ad4d87da5 --- /dev/null +++ b/src/containers/TabletsFilters/i18n/en.json @@ -0,0 +1,3 @@ +{ + "page.title": "Tablets" +} diff --git a/src/containers/TabletsFilters/i18n/index.ts b/src/containers/TabletsFilters/i18n/index.ts new file mode 100644 index 0000000000..d5f896e36c --- /dev/null +++ b/src/containers/TabletsFilters/i18n/index.ts @@ -0,0 +1,8 @@ +import {registerKeysets} from '../../../utils/i18n'; + +import en from './en.json'; +import ru from './ru.json'; + +const COMPONENT = 'ydb-tablets-filters-page'; + +export default registerKeysets(COMPONENT, {en, ru}); diff --git a/src/containers/TabletsFilters/i18n/ru.json b/src/containers/TabletsFilters/i18n/ru.json new file mode 100644 index 0000000000..36691b1267 --- /dev/null +++ b/src/containers/TabletsFilters/i18n/ru.json @@ -0,0 +1,3 @@ +{ + "page.title": "Таблетки" +} diff --git a/src/containers/Tenant/Diagnostics/Diagnostics.tsx b/src/containers/Tenant/Diagnostics/Diagnostics.tsx index 0c5bb12637..e454d0c72b 100644 --- a/src/containers/Tenant/Diagnostics/Diagnostics.tsx +++ b/src/containers/Tenant/Diagnostics/Diagnostics.tsx @@ -4,6 +4,7 @@ import cn from 'bem-cn-lite'; import {Link} from 'react-router-dom'; import {useDispatch, useSelector} from 'react-redux'; import {useLocation} from 'react-router'; +import {Helmet} from 'react-helmet-async'; import {Switch, Tabs} from '@gravity-ui/uikit'; @@ -80,13 +81,14 @@ function Diagnostics(props: DiagnosticsProps) { }; const activeTab = useMemo(() => { if (wasLoaded) { - if (pages.find((el) => el.id === diagnosticsTab)) { - return diagnosticsTab; - } else { - const newPage = pages[0].id; - forwardToDiagnosticTab(newPage); - return newPage; + let page = pages.find((el) => el.id === diagnosticsTab); + if (!page) { + page = pages[0]; } + if (page && page.id !== diagnosticsTab) { + forwardToDiagnosticTab(page.id); + } + return page; } return undefined; }, [pages, diagnosticsTab, wasLoaded]); @@ -104,7 +106,7 @@ function Diagnostics(props: DiagnosticsProps) { const tenantNameString = tenantName as string; - switch (diagnosticsTab) { + switch (activeTab?.id) { case TENANT_DIAGNOSTICS_TABS_IDS.overview: { return ( { const path = createHref(routes.tenant, undefined, { ...queryParams, @@ -202,6 +204,11 @@ function Diagnostics(props: DiagnosticsProps) { return (
+ {activeTab ? ( + + {activeTab.title} + + ) : null} {renderTabs()}
{renderTabContent()}
diff --git a/src/containers/Tenant/Query/Query.tsx b/src/containers/Tenant/Query/Query.tsx index fcc9bd0270..79420bd5ee 100644 --- a/src/containers/Tenant/Query/Query.tsx +++ b/src/containers/Tenant/Query/Query.tsx @@ -1,4 +1,6 @@ +import React from 'react'; import {useDispatch} from 'react-redux'; +import {Helmet} from 'react-helmet-async'; import block from 'bem-cn-lite'; import type {EPathType} from '../../../types/api/schema'; @@ -8,7 +10,7 @@ import {TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants'; import {useSetting, useTypedSelector} from '../../../utils/hooks'; import {SAVED_QUERIES_KEY} from '../../../utils/constants'; -import {QueryTabs} from './QueryTabs/QueryTabs'; +import {QueryTabs, queryEditorTabs} from './QueryTabs/QueryTabs'; import {SavedQueries} from './SavedQueries/SavedQueries'; import QueriesHistory from './QueriesHistory/QueriesHistory'; import QueryEditor from './QueryEditor/QueryEditor'; @@ -41,6 +43,11 @@ export const Query = (props: QueryProps) => { dispatch(changeUserInput(value)); }; + const activeTab = React.useMemo( + () => queryEditorTabs.find(({id}) => id === queryTab), + [queryTab], + ); + const renderContent = () => { switch (queryTab) { case TENANT_QUERY_TABS_ID.newQuery: { @@ -66,6 +73,11 @@ export const Query = (props: QueryProps) => { return (
+ {activeTab ? ( + + {activeTab.title} + + ) : null}
{renderContent()}
diff --git a/src/containers/Tenant/Query/QueryTabs/QueryTabs.tsx b/src/containers/Tenant/Query/QueryTabs/QueryTabs.tsx index cb971482fa..0e6a7eb991 100644 --- a/src/containers/Tenant/Query/QueryTabs/QueryTabs.tsx +++ b/src/containers/Tenant/Query/QueryTabs/QueryTabs.tsx @@ -24,7 +24,7 @@ const saved = { title: i18n('tabs.saved'), }; -const queryEditorTabs = [newQuery, history, saved]; +export const queryEditorTabs = [newQuery, history, saved]; interface QueryEditorTabsProps { className?: string; diff --git a/src/containers/Tenant/Tenant.tsx b/src/containers/Tenant/Tenant.tsx index 71f5bcd609..57b4e1192c 100644 --- a/src/containers/Tenant/Tenant.tsx +++ b/src/containers/Tenant/Tenant.tsx @@ -3,6 +3,7 @@ import {useDispatch, useSelector} from 'react-redux'; import cn from 'bem-cn-lite'; import {useLocation} from 'react-router'; import qs from 'qs'; +import {Helmet} from 'react-helmet-async'; import type {TEvDescribeSchemeResult} from '../../types/api/schema'; import type {AdditionalTenantsProps, AdditionalNodesProps} from '../../types/additionalProps'; @@ -22,6 +23,7 @@ import { PaneVisibilityActionTypes, paneVisibilityToggleReducerCreator, } from './utils/paneVisibilityToggleHelpers'; +import i18n from './i18n'; import './Tenant.scss'; @@ -104,8 +106,13 @@ function Tenant(props: TenantProps) { const showBlockingError = schemaStatus === 403; + const title = currentSchemaPath || tenantName || i18n('page.title'); return (
+ {showBlockingError ? ( ) : ( diff --git a/src/containers/Tenant/i18n/en.json b/src/containers/Tenant/i18n/en.json index d9ae34cd69..49271f3c8f 100644 --- a/src/containers/Tenant/i18n/en.json +++ b/src/containers/Tenant/i18n/en.json @@ -1,4 +1,6 @@ { + "page.title": "Database", + "acl.owner": "Owner", "acl.empty": "No Acl data", diff --git a/src/containers/Tenant/i18n/index.ts b/src/containers/Tenant/i18n/index.ts index a463e4e24a..a8c2d5a6f0 100644 --- a/src/containers/Tenant/i18n/index.ts +++ b/src/containers/Tenant/i18n/index.ts @@ -1,11 +1,8 @@ -import {i18n, Lang} from '../../../utils/i18n'; +import {registerKeysets} from '../../../utils/i18n'; import en from './en.json'; import ru from './ru.json'; const COMPONENT = 'ydb-tenant'; -i18n.registerKeyset(Lang.En, COMPONENT, en); -i18n.registerKeyset(Lang.Ru, COMPONENT, ru); - -export default i18n.keyset(COMPONENT); +export default registerKeysets(COMPONENT, {en, ru}); diff --git a/src/containers/Tenant/i18n/ru.json b/src/containers/Tenant/i18n/ru.json index 7a4b59814a..366ea2a7fb 100644 --- a/src/containers/Tenant/i18n/ru.json +++ b/src/containers/Tenant/i18n/ru.json @@ -1,4 +1,6 @@ { + "page.title": "База данных", + "acl.owner": "Владелец", "acl.empty": "Нет данных об Acl", diff --git a/src/utils/i18n/i18n.ts b/src/utils/i18n/i18n.ts index f0c2f19a11..644eb6ff52 100644 --- a/src/utils/i18n/i18n.ts +++ b/src/utils/i18n/i18n.ts @@ -1,4 +1,4 @@ -import {I18N} from '@gravity-ui/i18n'; +import {I18N, KeysData} from '@gravity-ui/i18n'; import {configure as configureUiKit} from '@gravity-ui/uikit'; import {configure as configureUiKitComponents} from '@gravity-ui/components'; import {configure as configureUiKitNavigation} from '@gravity-ui/navigation'; @@ -26,4 +26,14 @@ configureUiKit({lang: currentLang}); configureUiKitComponents({lang: currentLang}); configureUiKitNavigation({lang: currentLang}); +export function registerKeysets(id: string, data: Record) { + type Keys = Extract; + + for (const lang of Object.keys(data)) { + i18n.registerKeyset(lang, id, data[lang]); + } + + return i18n.keyset(id); +} + export {i18n, Lang, currentLang, defaultLang}; From 1dd77be2a773e46190e78b30127b509691fde23d Mon Sep 17 00:00:00 2001 From: Valerii Sidorenko Date: Wed, 28 Feb 2024 13:25:06 +0000 Subject: [PATCH 2/2] fix: adjust page titles --- src/containers/App/App.tsx | 2 +- src/containers/Cluster/Cluster.tsx | 4 ++-- src/containers/Node/Node.tsx | 4 ++-- src/containers/Tablet/Tablet.tsx | 6 +++--- src/containers/TabletsFilters/TabletsFilters.js | 6 +++--- src/containers/Tenant/Tenant.tsx | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/containers/App/App.tsx b/src/containers/App/App.tsx index ac071ab23f..51b87aa0d9 100644 --- a/src/containers/App/App.tsx +++ b/src/containers/App/App.tsx @@ -31,7 +31,7 @@ export interface AppProps { function App({store, history, singleClusterMode, children, userSettings = settings}: AppProps) { return ( - + diff --git a/src/containers/Cluster/Cluster.tsx b/src/containers/Cluster/Cluster.tsx index d85f68586b..dfd7255b1e 100644 --- a/src/containers/Cluster/Cluster.tsx +++ b/src/containers/Cluster/Cluster.tsx @@ -124,8 +124,8 @@ function Cluster({ return (
{activeTab ? {activeTab.title} : null} diff --git a/src/containers/Node/Node.tsx b/src/containers/Node/Node.tsx index 25a2480ff4..003dda62fb 100644 --- a/src/containers/Node/Node.tsx +++ b/src/containers/Node/Node.tsx @@ -148,8 +148,8 @@ function Node(props: NodeProps) { return (
{activeTabVerified.title} diff --git a/src/containers/Tablet/Tablet.tsx b/src/containers/Tablet/Tablet.tsx index 87f712083b..dddc07d954 100644 --- a/src/containers/Tablet/Tablet.tsx +++ b/src/containers/Tablet/Tablet.tsx @@ -10,7 +10,7 @@ import {getTablet, getTabletDescribe, clearTabletData} from '../../store/reducer import {setHeaderBreadcrumbs} from '../../store/reducers/header/header'; import {useAutofetcher, useTypedSelector} from '../../utils/hooks'; -import {DEVELOPER_UI_TITLE} from '../../utils/constants'; +import {CLUSTER_DEFAULT_TITLE, DEVELOPER_UI_TITLE} from '../../utils/constants'; import {parseQuery} from '../../routes'; import type {EType} from '../../types/api/tablet'; @@ -158,8 +158,8 @@ export const Tablet = () => { return ( <> - {`${id} - ${ - tenantName || queryClusterName || i18n('tablet.header') + <title>{`${id} — ${i18n('tablet.header')} — ${ + tenantName || queryClusterName || CLUSTER_DEFAULT_TITLE }`} {renderView()} diff --git a/src/containers/TabletsFilters/TabletsFilters.js b/src/containers/TabletsFilters/TabletsFilters.js index 804a22736c..47d1c72b6b 100644 --- a/src/containers/TabletsFilters/TabletsFilters.js +++ b/src/containers/TabletsFilters/TabletsFilters.js @@ -240,9 +240,9 @@ export class TabletsFilters extends React.Component { return ( <> - {`${tenantPath || clusterName || CLUSTER_DEFAULT_TITLE} - ${i18n( - 'page.title', - )}`} + {`${i18n('page.title')} — ${ + tenantPath || clusterName || CLUSTER_DEFAULT_TITLE + }`} {this.renderView()} diff --git a/src/containers/Tenant/Tenant.tsx b/src/containers/Tenant/Tenant.tsx index 57b4e1192c..969941a4ba 100644 --- a/src/containers/Tenant/Tenant.tsx +++ b/src/containers/Tenant/Tenant.tsx @@ -110,8 +110,8 @@ function Tenant(props: TenantProps) { return (
{showBlockingError ? (