From 5b2165b260b2c99c60beb5805ae28cb1f33e0283 Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Fri, 10 Jan 2025 17:06:14 +0300 Subject: [PATCH 01/14] added Title Ru in Properties Modal and dashboard list column --- .../src/dashboard/actions/dashboardLayout.js | 5 ++- .../src/dashboard/actions/dashboardState.js | 7 +++- .../src/dashboard/actions/hydrate.js | 1 + .../DashboardBuilder/DashboardBuilder.tsx | 33 +++++++++++++++ .../components/Header/Header.test.tsx | 1 + .../HeaderActionsDropdown.test.tsx | 1 + .../Header/HeaderActionsDropdown/index.jsx | 3 ++ .../src/dashboard/components/Header/index.jsx | 11 ++++- .../src/dashboard/components/Header/types.ts | 10 ++++- .../components/PropertiesModal/index.tsx | 36 +++++++++++++--- .../dashboard/containers/DashboardHeader.jsx | 4 ++ .../src/dashboard/reducers/dashboardLayout.js | 1 + superset-frontend/src/dashboard/types.ts | 6 ++- .../dashboard/util/permissionUtils.test.ts | 1 + .../src/explore/components/SaveModal.tsx | 42 ++++++++++++++++--- .../src/pages/DashboardList/index.tsx | 24 ++++++++++- superset-frontend/src/preamble.ts | 2 +- superset-frontend/src/types/Dashboard.ts | 5 ++- 18 files changed, 172 insertions(+), 21 deletions(-) diff --git a/superset-frontend/src/dashboard/actions/dashboardLayout.js b/superset-frontend/src/dashboard/actions/dashboardLayout.js index 8d4b3fa56c944..226bb4796b03d 100644 --- a/superset-frontend/src/dashboard/actions/dashboardLayout.js +++ b/superset-frontend/src/dashboard/actions/dashboardLayout.js @@ -93,10 +93,13 @@ export function updateDashboardTitle(text) { export const DASHBOARD_TITLE_CHANGED = 'DASHBOARD_TITLE_CHANGED'; // call this one when it's not an undo-able action -export function dashboardTitleChanged(text) { +// export function dashboardTitleChanged(text) { +// DODO changed 44120742 +export function dashboardTitleChanged(text, textRU) { return { type: DASHBOARD_TITLE_CHANGED, text, + textRU, // DODO added 44120742 }; } diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js b/superset-frontend/src/dashboard/actions/dashboardState.js index 6f46ffe60e1de..04a37507165df 100644 --- a/superset-frontend/src/dashboard/actions/dashboardState.js +++ b/superset-frontend/src/dashboard/actions/dashboardState.js @@ -286,6 +286,7 @@ export function saveDashboardRequest(data, id, saveType) { certification_details, css, dashboard_title, + dashboard_title_RU, // DODO added 44120742 owners, roles, slug, @@ -304,7 +305,9 @@ export function saveDashboardRequest(data, id, saveType) { certification_details: certified_by && certification_details ? certification_details : '', css: css || '', - dashboard_title: dashboard_title || t('[ untitled dashboard ]'), + // dashboard_title: dashboard_title || t('[ untitled dashboard ]'), + dashboard_title: dashboard_title || '[ untitled dashboard ]', // DODO changed 44120742 + dashboard_title_RU: dashboard_title_RU || '[ безымянный дашборд ]', // DODO added 44120742 owners: ensureIsArray(owners).map(o => (hasId(o) ? o.id : o)), roles: !isFeatureEnabled(FeatureFlag.DashboardRbac) ? undefined @@ -445,6 +448,7 @@ export function saveDashboardRequest(data, id, saveType) { certification_details: cleanedData.certification_details, css: cleanedData.css, dashboard_title: cleanedData.dashboard_title, + dashboard_title_RU: cleanedData.dashboard_title_RU, // DODO added 44120742 slug: cleanedData.slug, owners: cleanedData.owners, roles: cleanedData.roles, @@ -519,6 +523,7 @@ export function saveDashboardRequest(data, id, saveType) { cleanedData.metadata.filter_scopes = serializedFilterScopes; const copyPayload = { dashboard_title: cleanedData.dashboard_title, + dashboard_title_RU: cleanedData.dashboard_title_RU, // DODO added 44120742 css: cleanedData.css, duplicate_slices: cleanedData.duplicate_slices, json_metadata: JSON.stringify(cleanedData.metadata), diff --git a/superset-frontend/src/dashboard/actions/hydrate.js b/superset-frontend/src/dashboard/actions/hydrate.js index 8dd36a8063231..4c73aedf07b35 100644 --- a/superset-frontend/src/dashboard/actions/hydrate.js +++ b/superset-frontend/src/dashboard/actions/hydrate.js @@ -192,6 +192,7 @@ export const hydrateDashboard = type: DASHBOARD_HEADER_TYPE, meta: { text: dashboard.dashboard_title, + textRU: dashboard.dashboard_title_RU, // DODO added 44120742 }, }; diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx index 03d993288f4ff..e8658d8996be1 100644 --- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx +++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx @@ -32,6 +32,7 @@ import { } from '@superset-ui/core'; import { Global } from '@emotion/react'; import { useDispatch, useSelector } from 'react-redux'; +import { bootstrapData } from 'src/preamble'; import ErrorBoundary from 'src/components/ErrorBoundary'; import BuilderComponentPane from 'src/dashboard/components/BuilderComponentPane'; import DashboardHeader from 'src/dashboard/containers/DashboardHeader'; @@ -84,6 +85,36 @@ import DashboardWrapper from './DashboardWrapper'; type DashboardBuilderProps = {}; +// DODO added start 44120742 +const getPageLanguage = () => { + if (!document) { + return null; + } + const select = document.querySelector( + '#changeLanguage select', + ) as HTMLSelectElement; + const selectedLanguage = select ? select.value : null; + return selectedLanguage; +}; + +const getLocaleForSuperset = () => { + const dodoisLanguage = getPageLanguage(); + if (dodoisLanguage) { + if (dodoisLanguage === 'ru-RU') return 'ru'; + return 'en'; + } + return 'en'; +}; + +let locale = 'en'; + +if (process.env.type === undefined) { + locale = bootstrapData?.common?.locale || 'en'; +} else { + locale = getLocaleForSuperset(); +} +// DODO added stop 44120742 + // @z-index-above-dashboard-charts + 1 = 11 const FiltersPanel = styled.div<{ width: number; hidden: boolean }>` grid-column: 1; @@ -555,6 +586,7 @@ const DashboardBuilder: FC = () => { renderTabContent={false} renderHoverMenu={false} onChangeTab={handleChangeTab} + userLanguage={locale} // DODO added 44120742 /> )} @@ -623,6 +655,7 @@ const DashboardBuilder: FC = () => { )} + {/* @ts-ignore */} ({ }, reports: {}, dashboardTitle: 'Dashboard Title', + dashboardTitleRU: 'Dashboard Title', charts: {}, layout: {}, expandedSlices: {}, diff --git a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx index 3a0d25d600695..44031d9b570f8 100644 --- a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx +++ b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx @@ -46,6 +46,7 @@ const createProps = (): HeaderDropdownProps => ({ }, }, dashboardTitle: 'Title', + dashboardTitleRU: 'Title', editMode: false, expandedSlices: {}, forceRefreshAllCharts: jest.fn(), diff --git a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx index 50cdb67813568..505b96a7da21d 100644 --- a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx @@ -43,6 +43,7 @@ const propTypes = { dashboardInfo: PropTypes.object.isRequired, dashboardId: PropTypes.number, dashboardTitle: PropTypes.string, + dashboardTitleRU: PropTypes.string, dataMask: PropTypes.object.isRequired, customCss: PropTypes.string, colorNamespace: PropTypes.string, @@ -156,6 +157,7 @@ export class HeaderActionsDropdown extends PureComponent { render() { const { dashboardTitle, + dashboardTitleRU, // DODO added 44120742 dashboardId, dashboardInfo, refreshFrequency, @@ -248,6 +250,7 @@ export class HeaderActionsDropdown extends PureComponent { addDangerToast={this.props.addDangerToast} dashboardId={dashboardId} dashboardTitle={dashboardTitle} + dashboardTitleRU={dashboardTitleRU} // DODO added 44120742 dashboardInfo={dashboardInfo} saveType={SAVE_TYPE_NEWDASHBOARD} layout={layout} diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index b0caea3ceb773..0901b1382b6dc 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -109,6 +109,9 @@ const propTypes = { setRefreshFrequency: PropTypes.func.isRequired, dashboardInfoChanged: PropTypes.func.isRequired, dashboardTitleChanged: PropTypes.func.isRequired, + + // Dodo extended + dashboardTitleRU: PropTypes.string, // DODO added 44120742 }; const defaultProps = { @@ -357,6 +360,7 @@ class Header extends PureComponent { overwriteDashboard() { const { dashboardTitle, + dashboardTitleRU, // DODO added 44120742 layout: positions, colorScheme, colorNamespace, @@ -383,6 +387,7 @@ class Header extends PureComponent { certification_details: dashboardInfo.certification_details, css: customCss, dashboard_title: dashboardTitle, + dashboard_title_RU: dashboardTitleRU, // DODO added 44120742 last_modified_time: lastModifiedTime, owners: dashboardInfo.owners, roles: dashboardInfo.roles, @@ -456,6 +461,7 @@ class Header extends PureComponent { render() { const { dashboardTitle, + dashboardTitleRU, // DODO added 44120742 layout, expandedSlices, customCss, @@ -509,7 +515,8 @@ class Header extends PureComponent { roles: updates.roles, }); setUnsavedChanges(true); - dashboardTitleChanged(updates.title); + // dashboardTitleChanged(updates.title); + dashboardTitleChanged(updates.title, updates.titleRU); // DODO changed 44120742 }; const NavExtension = extensionsRegistry.get('dashboard.nav.right'); @@ -671,6 +678,7 @@ class Header extends PureComponent { addDangerToast={this.props.addDangerToast} dashboardId={dashboardInfo.id} dashboardTitle={dashboardTitle} + dashboardTitleRU={dashboardTitleRU} // DODO added 44120742 dashboardInfo={dashboardInfo} dataMask={dataMask} layout={layout} @@ -711,6 +719,7 @@ class Header extends PureComponent { dashboardId={dashboardInfo.id} dashboardInfo={dashboardInfo} dashboardTitle={dashboardTitle} + dashboardTitleRU={dashboardTitleRU} // DODO added 44120742 show={this.state.showingPropertiesModal} onHide={this.hidePropertiesModal} colorScheme={this.props.colorScheme} diff --git a/superset-frontend/src/dashboard/components/Header/types.ts b/superset-frontend/src/dashboard/components/Header/types.ts index f3a35586a2040..6e3c822bb0c48 100644 --- a/superset-frontend/src/dashboard/components/Header/types.ts +++ b/superset-frontend/src/dashboard/components/Header/types.ts @@ -29,7 +29,10 @@ interface DashboardInfo { common?: { conf: Record }; } -export interface HeaderDropdownProps { +interface HeaderDropdownPropsDodoExtended { + dashboardTitleRU: string; // DODO added 44120742 +} +export interface HeaderDropdownProps extends HeaderDropdownPropsDodoExtended { addSuccessToast: () => void; addDangerToast: () => void; customCss: string; @@ -63,7 +66,10 @@ export interface HeaderDropdownProps { logEvent: () => void; } -export interface HeaderProps { +interface HeaderPropsDodoExtended { + dashboardTitleRU: string; // DODO added 44120742 +} +export interface HeaderProps extends HeaderPropsDodoExtended { addSuccessToast: () => void; addDangerToast: () => void; addWarningToast: () => void; diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx index 998e8540dcef3..44cae3d1ab04a 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx @@ -67,6 +67,10 @@ const StyledJsonEditor = styled(JsonEditor)` border: 1px solid ${({ theme }) => theme.colors.secondary.light2}; `; +type PropertiesModalPropsDodoExtended = { + dashboardTitleRU?: string; // DODO added 44120742 +}; + type PropertiesModalProps = { dashboardId: number; dashboardTitle?: string; @@ -78,7 +82,7 @@ type PropertiesModalProps = { addSuccessToast: (message: string) => void; addDangerToast: (message: string) => void; onlyApply?: boolean; -}; +} & PropertiesModalPropsDodoExtended; type Roles = { id: number; name: string }[]; type Owners = { @@ -87,6 +91,10 @@ type Owners = { first_name?: string; last_name?: string; }[]; + +type DashboardInfoDodoExtended = { + titleRU: string; // DODO added 44120742 +}; type DashboardInfo = { id: number; title: string; @@ -95,7 +103,7 @@ type DashboardInfo = { certificationDetails: string; isManagedExternally: boolean; metadata: Record; -}; +} & DashboardInfoDodoExtended; const PropertiesModal = ({ addSuccessToast, @@ -180,6 +188,7 @@ const PropertiesModal = ({ const { id, dashboard_title, + dashboard_title_RU, // DODO added 44120742 slug, certified_by, certification_details, @@ -191,6 +200,7 @@ const PropertiesModal = ({ const dashboardInfo = { id, title: dashboard_title, + titleRU: dashboard_title_RU || '[ Безымянный Дашборд ]', // DODO added 44120742 slug: slug || '', certifiedBy: certified_by || '', certificationDetails: certification_details || '', @@ -318,8 +328,9 @@ const PropertiesModal = ({ }; const onFinish = () => { - const { title, slug, certifiedBy, certificationDetails } = - form.getFieldsValue(); + // const { title, slug, certifiedBy, certificationDetails } = + const { title, titleRU, slug, certifiedBy, certificationDetails } = + form.getFieldsValue(); // DODO changed 44120742 let currentJsonMetadata = jsonMetadata; // validate currentJsonMetadata @@ -392,6 +403,7 @@ const PropertiesModal = ({ const onSubmitProps = { id: dashboardId, title, + titleRU, // DODO added 44120742 slug, jsonMetadata: currentJsonMetadata, owners, @@ -411,6 +423,7 @@ const PropertiesModal = ({ headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dashboard_title: title, + dashboard_title_RU: titleRU, // DODO added 44120742 slug: slug || null, json_metadata: currentJsonMetadata || null, owners: (owners || []).map(o => o.id), @@ -644,7 +657,9 @@ const PropertiesModal = ({ - + {/* */} + {/* DODO changed 44120742 */} + + {/* DODO added start 44120742 */} + + + + + + {/* DODO added stop 44120742 */} diff --git a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx index cc05916dccdee..f9c7aa2b5b450 100644 --- a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx +++ b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx @@ -75,6 +75,10 @@ function mapStateToProps({ dashboardTitle: ( (undoableLayout.present[DASHBOARD_HEADER_ID] || {}).meta || {} ).text, + // DODO added 44120742 + dashboardTitleRU: ( + (undoableLayout.present[DASHBOARD_HEADER_ID] || {}).meta || {} + ).textRU, expandedSlices: dashboardState.expandedSlices, refreshFrequency: dashboardState.refreshFrequency, shouldPersistRefreshFrequency: diff --git a/superset-frontend/src/dashboard/reducers/dashboardLayout.js b/superset-frontend/src/dashboard/reducers/dashboardLayout.js index 6ba297be9147e..436e4337d1301 100644 --- a/superset-frontend/src/dashboard/reducers/dashboardLayout.js +++ b/superset-frontend/src/dashboard/reducers/dashboardLayout.js @@ -300,6 +300,7 @@ const actionHandlers = { meta: { ...state[DASHBOARD_HEADER_ID].meta, text: action.text, + textRU: action.textRU, // DODO added 44120742 }, }, }; diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts index ad78449781c48..159ec60968ae0 100644 --- a/superset-frontend/src/dashboard/types.ts +++ b/superset-frontend/src/dashboard/types.ts @@ -178,6 +178,10 @@ type ComponentTypesKeys = keyof typeof componentTypes; export type ComponentType = (typeof componentTypes)[ComponentTypesKeys]; /** State of dashboardLayout item in redux */ +type LayoutItemDodoExtended = { + sliceNameRU?: string; // DODO added 44120742 + sliceNameOverrideRU?: string; // DODO added 44120742 +}; export type LayoutItem = { children: string[]; parents: string[]; @@ -194,7 +198,7 @@ export type LayoutItem = { uuid: string; width: number; }; -}; +} & LayoutItemDodoExtended; type ActiveFilter = { scope: number[]; diff --git a/superset-frontend/src/dashboard/util/permissionUtils.test.ts b/superset-frontend/src/dashboard/util/permissionUtils.test.ts index 32687509bdc68..1025b5c052df0 100644 --- a/superset-frontend/src/dashboard/util/permissionUtils.test.ts +++ b/superset-frontend/src/dashboard/util/permissionUtils.test.ts @@ -85,6 +85,7 @@ const undefinedUser: UndefinedUser = {}; const dashboard: Dashboard = { id: 1, dashboard_title: 'Test Dash', + dashboard_title_RU: 'Test Dash', url: 'https://dashboard.example.com/1', thumbnail_url: 'https://dashboard.example.com/1/thumbnail.png', published: true, diff --git a/superset-frontend/src/explore/components/SaveModal.tsx b/superset-frontend/src/explore/components/SaveModal.tsx index 8c216056a123e..862ed8eb9ebb3 100644 --- a/superset-frontend/src/explore/components/SaveModal.tsx +++ b/superset-frontend/src/explore/components/SaveModal.tsx @@ -62,13 +62,16 @@ interface SaveModalProps extends RouteComponentProps { dispatch: Dispatch; } +type DashboardDodoExtended = { + labelRU: string; // DODO added 44120742 +}; type SaveModalState = { newSliceName?: string; datasetName: string; action: SaveActionType; isLoading: boolean; saveStatus?: string | null; - dashboard?: { label: string; value: string | number }; + dashboard?: { label: string; value: string | number } & DashboardDodoExtended; }; export const StyledModal = styled(Modal)` @@ -128,7 +131,11 @@ class SaveModal extends Component { const result = (await this.loadDashboard(dashboardId)) as Dashboard; if (canUserEditDashboard(result, this.props.user)) { this.setState({ - dashboard: { label: result.dashboard_title, value: result.id }, + dashboard: { + label: result.dashboard_title, + labelRU: result.dashboard_title_RU, // DODO added 44120742 + value: result.id, + }, }); } } catch (error) { @@ -148,7 +155,12 @@ class SaveModal extends Component { this.setState({ newSliceName: event.target.value }); } - onDashboardChange(dashboard: { label: string; value: string | number }) { + onDashboardChange( + dashboard: { + label: string; + value: string | number; + } & DashboardDodoExtended, // DODO added 44120742 + ) { this.setState({ dashboard }); } @@ -175,11 +187,14 @@ class SaveModal extends Component { this.setState({ isLoading: true }); // Create or retrieve dashboard + type DashboardGetResponseDodoExtended = { + dashboard_title_RU: string; // DODO added 44120742 + }; type DashboardGetResponse = { id: number; url: string; dashboard_title: string; - }; + } & DashboardGetResponseDodoExtended; try { if (this.props.datasource?.type === DatasourceType.Query) { @@ -244,6 +259,7 @@ class SaveModal extends Component { dashboard ? { title: dashboard.dashboard_title, + titleRU: dashboard.dashboard_title_RU, // DODO added 44120742 new: this.isNewDashboard(), } : null, @@ -255,6 +271,7 @@ class SaveModal extends Component { dashboard ? { title: dashboard.dashboard_title, + titleRU: dashboard.dashboard_title_RU, // DODO added 44120742 new: this.isNewDashboard(), } : null, @@ -296,13 +313,21 @@ class SaveModal extends Component { loadDashboards = async (search: string, page: number, pageSize: number) => { const queryParams = rison.encode({ - columns: ['id', 'dashboard_title'], + // columns: ['id', 'dashboard_title'], + columns: ['id', 'dashboard_title', 'dashboard_title_RU'], // DODO changed 44120742 filters: [ { col: 'dashboard_title', opr: 'ct', value: search, }, + // DODO added start 44120742 + { + col: 'dashboard_title_RU', + opr: 'ct', + value: search, + }, + // DODO added stop 44120742 { col: 'owners', opr: 'rel_m_m', @@ -320,9 +345,14 @@ class SaveModal extends Component { const { result, count } = json; return { data: result.map( - (dashboard: { id: number; dashboard_title: string }) => ({ + (dashboard: { + id: number; + dashboard_title: string; + dashboard_title_RU: string; // DODO added 44120742 + }) => ({ value: dashboard.id, label: dashboard.dashboard_title, + labelRU: dashboard.dashboard_title_RU, // DODO added 44120742 }), ), totalCount: count, diff --git a/superset-frontend/src/pages/DashboardList/index.tsx b/superset-frontend/src/pages/DashboardList/index.tsx index 361168f4188e3..5da00ff80ac87 100644 --- a/superset-frontend/src/pages/DashboardList/index.tsx +++ b/superset-frontend/src/pages/DashboardList/index.tsx @@ -93,7 +93,10 @@ interface DashboardListProps { }; } -export interface Dashboard { +interface DashboardDodoExtended { + dashboard_title_RU: string; // DODO added 44120742 +} +export interface Dashboard extends DashboardDodoExtended { changed_by_name: string; changed_on_delta_humanized: string; changed_by: string; @@ -114,6 +117,7 @@ const Actions = styled.div` const DASHBOARD_COLUMNS_TO_FETCH = [ 'id', 'dashboard_title', + 'dashboard_title_RU', // DODO added 44120742 'published', 'url', 'slug', @@ -229,6 +233,7 @@ function DashboardList(props: DashboardListProps) { changed_by_name, changed_by, dashboard_title = '', + dashboard_title_RU = '', // DODO added 44120742 slug = '', json_metadata = '', changed_on_delta_humanized, @@ -243,6 +248,7 @@ function DashboardList(props: DashboardListProps) { changed_by_name, changed_by, dashboard_title, + dashboard_title_RU, // DODO added 44120742 slug, json_metadata, changed_on_delta_humanized, @@ -335,9 +341,23 @@ function DashboardList(props: DashboardListProps) { {dashboardTitle} ), - Header: t('Name'), + // Header: t('Name'), + Header: `${t('Name')} EN`, // DODO changed 44120742 accessor: 'dashboard_title', }, + // DODO added start 44120742 + { + Cell: ({ + row: { + original: { url, dashboard_title_RU: dashboardTitleRU }, + }, + }: any) => ( + {dashboardTitleRU ? `${dashboardTitleRU}` : '-'} + ), + Header: `${t('Name')} RU`, + accessor: 'dashboard_title_RU', + }, + // DODO added stop 44120742 { Cell: ({ row: { diff --git a/superset-frontend/src/preamble.ts b/superset-frontend/src/preamble.ts index c43afc76f88e5..269568c3c1782 100644 --- a/superset-frontend/src/preamble.ts +++ b/superset-frontend/src/preamble.ts @@ -39,7 +39,7 @@ if (process.env.WEBPACK_MODE === 'development') { } // eslint-disable-next-line import/no-mutable-exports -const bootstrapData = getBootstrapData(); +export const bootstrapData = getBootstrapData(); // Configure translation if (typeof window !== 'undefined') { diff --git a/superset-frontend/src/types/Dashboard.ts b/superset-frontend/src/types/Dashboard.ts index faecc0bc4acf7..2bb8d49907daa 100644 --- a/superset-frontend/src/types/Dashboard.ts +++ b/superset-frontend/src/types/Dashboard.ts @@ -19,7 +19,10 @@ import Owner from './Owner'; import Role from './Role'; -export interface Dashboard { +interface DashboardDodoExtended { + dashboard_title_RU: string; // DODO added 44120742 +} +export interface Dashboard extends DashboardDodoExtended { id: number; slug?: string | null; url: string; From 80d66a041957430a3e35490537c778fb502aafce Mon Sep 17 00:00:00 2001 From: Artem Aslamov Date: Mon, 13 Jan 2025 12:52:00 +0700 Subject: [PATCH 02/14] add migrations --- ...7_f3afaf1f11f0_add_unique_name_desc_rls.py | 2 +- ...dd1_required_fields_for_multilingualism.py | 65 +++++++++++++++++++ .../2023-10-05_09-35_049632555b84_.py | 52 +++++++++++++++ .../2023-11-17_11-36_a18f4c261e8b_.py | 50 ++++++++++++++ .../2023-11-17_13-24_687e66be3a9d_.py | 38 +++++++++++ 5 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 superset/migrations/versions/2023-09-26_18-54_168cfd974dd1_required_fields_for_multilingualism.py create mode 100644 superset/migrations/versions/2023-10-05_09-35_049632555b84_.py create mode 100644 superset/migrations/versions/2023-11-17_11-36_a18f4c261e8b_.py create mode 100644 superset/migrations/versions/2023-11-17_13-24_687e66be3a9d_.py diff --git a/superset/migrations/versions/2022-06-19_16-17_f3afaf1f11f0_add_unique_name_desc_rls.py b/superset/migrations/versions/2022-06-19_16-17_f3afaf1f11f0_add_unique_name_desc_rls.py index 34f5522ebdd79..da786b9a489c2 100644 --- a/superset/migrations/versions/2022-06-19_16-17_f3afaf1f11f0_add_unique_name_desc_rls.py +++ b/superset/migrations/versions/2022-06-19_16-17_f3afaf1f11f0_add_unique_name_desc_rls.py @@ -24,7 +24,7 @@ # revision identifiers, used by Alembic. revision = "f3afaf1f11f0" -down_revision = "e09b4ae78457" +down_revision = "687e66be3a9d" import sqlalchemy as sa # noqa: E402 from alembic import op # noqa: E402 diff --git a/superset/migrations/versions/2023-09-26_18-54_168cfd974dd1_required_fields_for_multilingualism.py b/superset/migrations/versions/2023-09-26_18-54_168cfd974dd1_required_fields_for_multilingualism.py new file mode 100644 index 0000000000000..2d4019f401804 --- /dev/null +++ b/superset/migrations/versions/2023-09-26_18-54_168cfd974dd1_required_fields_for_multilingualism.py @@ -0,0 +1,65 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""required fields for multilingualism + +Revision ID: 168cfd974dd1 +Revises: e09b4ae78457 +Create Date: 2023-09-26 18:54:13.683355 + +""" + +# revision identifiers, used by Alembic. +revision = '168cfd974dd1' +down_revision = 'e09b4ae78457' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('dashboards', sa.Column('selected_lang', sa.Text(), nullable=True)) + op.add_column('dashboards', sa.Column('dashboard_title_second_lang', sa.Text(), nullable=True)) + + op.add_column('slices', sa.Column('extra_lang', sa.Text(), nullable=True)) + op.add_column('slices', sa.Column('slice_name_second_lang', sa.Text(), nullable=True)) + op.add_column('slices', sa.Column('primary_lang', sa.Text(), nullable=True)) + + op.add_column('sql_metrics', sa.Column('verbose_name_2nd_lang', sa.Text(), nullable=True)) + op.add_column('sql_metrics', sa.Column('description_2nd_lang', sa.Text(), nullable=True)) + + op.add_column('table_columns', sa.Column('verbose_name_2nd_lang', sa.Text(), nullable=True)) + op.add_column('table_columns', sa.Column('description_2nd_lang', sa.Text(), nullable=True)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('table_columns', 'description_2nd_lang') + op.drop_column('table_columns', 'verbose_name_2nd_lang') + + op.drop_column('sql_metrics', 'description_2nd_lang') + op.drop_column('sql_metrics', 'verbose_name_2nd_lang') + + op.drop_column('slices', 'primary_lang') + op.drop_column('slices', 'slice_name_second_lang') + op.drop_column('slices', 'extra_lang') + + op.drop_column('dashboards', 'dashboard_title_second_lang') + op.drop_column('dashboards', 'selected_lang') + # ### end Alembic commands ### diff --git a/superset/migrations/versions/2023-10-05_09-35_049632555b84_.py b/superset/migrations/versions/2023-10-05_09-35_049632555b84_.py new file mode 100644 index 0000000000000..34f87c2d798f0 --- /dev/null +++ b/superset/migrations/versions/2023-10-05_09-35_049632555b84_.py @@ -0,0 +1,52 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""empty message + +Revision ID: 049632555b84 +Revises: 4b85906e5b91 +Create Date: 2023-10-05 09:35:35.005365 + +""" + +# revision identifiers, used by Alembic. +revision = '049632555b84' +down_revision = '168cfd974dd1' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('dashboards', sa.Column('dashboard_title_RU', sa.Text(), nullable=True)) + op.add_column('slices', sa.Column('slice_name_RU', sa.Text(), nullable=True)) + op.add_column('sql_metrics', sa.Column('verbose_name_RU', sa.Text(), nullable=True)) + op.add_column('sql_metrics', sa.Column('description_RU', sa.Text(), nullable=True)) + op.add_column('table_columns', sa.Column('verbose_name_RU', sa.Text(), nullable=True)) + op.add_column('table_columns', sa.Column('description_RU', sa.Text(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('table_columns', 'description_RU') + op.drop_column('table_columns', 'verbose_name_RU') + op.drop_column('sql_metrics', 'description_RU') + op.drop_column('sql_metrics', 'verbose_name_RU') + op.drop_column('slices', 'slice_name_RU') + op.drop_column('dashboards', 'dashboard_title_RU') + # ### end Alembic commands ### diff --git a/superset/migrations/versions/2023-11-17_11-36_a18f4c261e8b_.py b/superset/migrations/versions/2023-11-17_11-36_a18f4c261e8b_.py new file mode 100644 index 0000000000000..67f566e5d231d --- /dev/null +++ b/superset/migrations/versions/2023-11-17_11-36_a18f4c261e8b_.py @@ -0,0 +1,50 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""empty message + +Revision ID: a18f4c261e8b +Revises: 049632555b84 +Create Date: 2023-11-17 11:36:09.634360 + +""" + +# revision identifiers, used by Alembic. +revision = 'a18f4c261e8b' +down_revision = '049632555b84' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('sql_metrics', sa.Column('verbose_name_EN', sa.Text(), nullable=True)) + op.add_column('sql_metrics', sa.Column('description_EN', sa.Text(), nullable=True)) + + op.add_column('table_columns', sa.Column('verbose_name_EN', sa.Text(), nullable=True)) + op.add_column('table_columns', sa.Column('description_EN', sa.Text(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('table_columns', 'description_EN') + op.drop_column('table_columns', 'verbose_name_EN') + + op.drop_column('sql_metrics', 'description_EN') + op.drop_column('sql_metrics', 'verbose_name_EN') + # ### end Alembic commands ### diff --git a/superset/migrations/versions/2023-11-17_13-24_687e66be3a9d_.py b/superset/migrations/versions/2023-11-17_13-24_687e66be3a9d_.py new file mode 100644 index 0000000000000..c2669ced41924 --- /dev/null +++ b/superset/migrations/versions/2023-11-17_13-24_687e66be3a9d_.py @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""empty message + +Revision ID: 687e66be3a9d +Revises: a18f4c261e8b +Create Date: 2023-11-17 13:24:09.629107 + +""" + +# revision identifiers, used by Alembic. +revision = '687e66be3a9d' +down_revision = 'a18f4c261e8b' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + pass + + +def downgrade(): + pass From 71ab0c5d332d2475ea2433774bacfd6a8ce42e4e Mon Sep 17 00:00:00 2001 From: Artem Aslamov Date: Mon, 13 Jan 2025 12:52:56 +0700 Subject: [PATCH 03/14] add fields "dashboard_title_RU" in dashboard modal window --- superset/dashboards/schemas.py | 9 +++++++++ superset/models/dashboard.py | 1 + 2 files changed, 10 insertions(+) diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py index c3c655e7e89c3..730cc68413999 100644 --- a/superset/dashboards/schemas.py +++ b/superset/dashboards/schemas.py @@ -45,6 +45,7 @@ }, } dashboard_title_description = "A title for the dashboard." +dashboard_title_ru_description = "A title RU for the dashboard." slug_description = "Unique identifying part for the web address of the dashboard." owners_description = ( "Owner are users ids allowed to delete or change this dashboard. " @@ -212,6 +213,9 @@ class DashboardGetResponseSchema(Schema): dashboard_title = fields.String( metadata={"description": dashboard_title_description} ) + dashboard_title_RU = fields.String( + metadata={"description": dashboard_title_ru_description} + ) thumbnail_url = fields.String() published = fields.Boolean() css = fields.String(metadata={"description": css_description}) @@ -383,6 +387,11 @@ class DashboardPutSchema(BaseDashboardSchema): allow_none=True, validate=Length(0, 500), ) + dashboard_title_RU = fields.String( + metadata={"description": dashboard_title_ru_description}, + allow_none=True, + validate=Length(0, 500), + ) slug = fields.String( metadata={"description": slug_description}, allow_none=True, diff --git a/superset/models/dashboard.py b/superset/models/dashboard.py index 28d8aacc7bed9..e80db25c2e21c 100644 --- a/superset/models/dashboard.py +++ b/superset/models/dashboard.py @@ -133,6 +133,7 @@ class Dashboard(AuditMixinNullable, ImportExportMixin, Model): __tablename__ = "dashboards" id = Column(Integer, primary_key=True) dashboard_title = Column(String(500)) + dashboard_title_RU = Column(String(500)) position_json = Column(utils.MediumText()) description = Column(Text) css = Column(utils.MediumText()) From 2c14dc6efa0642be701b6e3444a4924bd1a6c702 Mon Sep 17 00:00:00 2001 From: Artem Aslamov Date: Mon, 13 Jan 2025 13:00:27 +0700 Subject: [PATCH 04/14] add fields "dashboard_title_RU" list dashboards --- superset/dashboards/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index 8b459fa945a0e..2b3069714e137 100644 --- a/superset/dashboards/api.py +++ b/superset/dashboards/api.py @@ -209,6 +209,7 @@ def ensure_screenshots_enabled(self) -> Optional[Response]: "created_by.id", "created_by.last_name", "dashboard_title", + "dashboard_title_RU", "owners.id", "owners.first_name", "owners.last_name", From f3066ed6b89aa36e6ed0ff1c96d47b589bd6530e Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:04:10 +0300 Subject: [PATCH 05/14] feat(dashboard page): document title is set according to locale --- .../dashboard/containers/DashboardPage.tsx | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/superset-frontend/src/dashboard/containers/DashboardPage.tsx b/superset-frontend/src/dashboard/containers/DashboardPage.tsx index e8c9283462069..65aabbafb9f49 100644 --- a/superset-frontend/src/dashboard/containers/DashboardPage.tsx +++ b/superset-frontend/src/dashboard/containers/DashboardPage.tsx @@ -21,6 +21,7 @@ import { Global } from '@emotion/react'; import { useHistory } from 'react-router-dom'; import { t, useTheme } from '@superset-ui/core'; import { useDispatch, useSelector } from 'react-redux'; +import { bootstrapData } from 'src/preamble'; // DODO added 44120742 import { useToasts } from 'src/components/MessageToasts/withToasts'; import Loading from 'src/components/Loading'; import { @@ -55,6 +56,8 @@ import SyncDashboardState, { getDashboardContextLocalStorage, } from '../components/SyncDashboardState'; +const locale = bootstrapData?.common?.locale || 'en'; // DODO added 44120742 + export const DashboardPageIdContext = createContext(''); const DashboardBuilder = lazy( @@ -67,6 +70,7 @@ const DashboardBuilder = lazy( ); const originalDocumentTitle = document.title; +const fallBackPageTitle = 'Superset dashboard'; // DODO added 44120742 type PageProps = { idOrSlug: string; @@ -95,7 +99,8 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { const error = dashboardApiError || chartsApiError; const readyToRender = Boolean(dashboard && charts); - const { dashboard_title, css, id = 0 } = dashboard || {}; + // const { dashboard_title, css, id = 0 } = dashboard || {}; + const { dashboard_title, dashboard_title_RU, css, id = 0 } = dashboard || {}; // DODO changed 44120742 useEffect(() => { // mark tab id as redundant when user closes browser tab - a new id will be @@ -163,14 +168,30 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [readyToRender]); + // useEffect(() => { + // if (dashboard_title) { + // document.title = dashboard_title; + // } + // return () => { + // document.title = originalDocumentTitle; + // }; + // }, [dashboard_title]); + + // DODO changed 44120742 useEffect(() => { - if (dashboard_title) { - document.title = dashboard_title; - } + const localisedTitle = + locale === 'ru' ? dashboard_title_RU : dashboard_title; + + document.title = + localisedTitle || + dashboard_title || + dashboard_title_RU || + fallBackPageTitle; + return () => { document.title = originalDocumentTitle; }; - }, [dashboard_title]); + }, [dashboard_title, dashboard_title_RU]); useEffect(() => { if (typeof css === 'string') { From 3e25f4895641f7406ba222db769b6d5751da1a69 Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:23:35 +0300 Subject: [PATCH 06/14] dashboard api is adapted for locale --- .../src/connection/callApi/callApi.ts | 34 ++++++++++++++++--- .../dashboard/containers/DashboardPage.tsx | 9 +++-- .../src/hooks/apiResources/dashboards.ts | 28 ++++++++++++--- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts b/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts index c682e5b7300df..3aa4a27d0d0d5 100644 --- a/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts +++ b/superset-frontend/packages/superset-ui-core/src/connection/callApi/callApi.ts @@ -40,13 +40,39 @@ function tryParsePayload(payload: Payload) { /** * Try appending search params to an URL if needed. */ +// function getFullUrl(partialUrl: string, params: CallApi['searchParams']) { +// if (params) { +// const url = new URL(partialUrl, window.location.href); +// const search = +// params instanceof URLSearchParams ? params : new URLSearchParams(params); +// // will completely override any existing search params +// url.search = search.toString(); +// return url.href; +// } +// return partialUrl; +// } +// DODO changed 44120742 function getFullUrl(partialUrl: string, params: CallApi['searchParams']) { if (params) { + const splitPartial = partialUrl.split('?language='); + let languageAddition = ''; + if (splitPartial && splitPartial.length > 1) { + languageAddition = splitPartial[1]; + } + const url = new URL(partialUrl, window.location.href); - const search = - params instanceof URLSearchParams ? params : new URLSearchParams(params); - // will completely override any existing search params - url.search = search.toString(); + + if (languageAddition) { + url.searchParams.set('language', languageAddition); + } else { + const search = + params instanceof URLSearchParams + ? params + : new URLSearchParams(params); + + // will completely override any existing search params + url.search = search.toString(); + } return url.href; } return partialUrl; diff --git a/superset-frontend/src/dashboard/containers/DashboardPage.tsx b/superset-frontend/src/dashboard/containers/DashboardPage.tsx index 65aabbafb9f49..8bc2abfd286fb 100644 --- a/superset-frontend/src/dashboard/containers/DashboardPage.tsx +++ b/superset-frontend/src/dashboard/containers/DashboardPage.tsx @@ -88,13 +88,16 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { const { addDangerToast } = useToasts(); const { result: dashboard, error: dashboardApiError } = useDashboard(idOrSlug); - const { result: charts, error: chartsApiError } = - useDashboardCharts(idOrSlug); + const { result: charts, error: chartsApiError } = useDashboardCharts( + idOrSlug, + locale, // DODO added 44120742 + ); const { result: datasets, error: datasetsApiError, status, - } = useDashboardDatasets(idOrSlug); + // } = useDashboardDatasets(idOrSlug); + } = useDashboardDatasets(idOrSlug, locale); // DODO changed 44120742 const isDashboardHydrated = useRef(false); const error = dashboardApiError || chartsApiError; diff --git a/superset-frontend/src/hooks/apiResources/dashboards.ts b/superset-frontend/src/hooks/apiResources/dashboards.ts index 61896ba1309dc..ecfe9224e9a26 100644 --- a/superset-frontend/src/hooks/apiResources/dashboards.ts +++ b/superset-frontend/src/hooks/apiResources/dashboards.ts @@ -36,14 +36,34 @@ export const useDashboard = (idOrSlug: string | number) => ); // gets the chart definitions for a dashboard -export const useDashboardCharts = (idOrSlug: string | number) => - useApiV1Resource(`/api/v1/dashboard/${idOrSlug}/charts`); +// export const useDashboardCharts = (idOrSlug: string | number) => +// useApiV1Resource(`/api/v1/dashboard/${idOrSlug}/charts`); +// DODO changed 44120742 +export const useDashboardCharts = ( + idOrSlug: string | number, + language?: string, +) => + useApiV1Resource( + !language + ? `/api/v1/dashboard/${idOrSlug}/charts` + : `/api/v1/dashboard/${idOrSlug}/charts?language=${language}`, + ); // gets the datasets for a dashboard // important: this endpoint only returns the fields in the dataset // that are necessary for rendering the given dashboard -export const useDashboardDatasets = (idOrSlug: string | number) => - useApiV1Resource(`/api/v1/dashboard/${idOrSlug}/datasets`); +// export const useDashboardDatasets = (idOrSlug: string | number) => +// useApiV1Resource(`/api/v1/dashboard/${idOrSlug}/datasets`); +// DODO changed 44120742 +export const useDashboardDatasets = ( + idOrSlug: string | number, + language?: string, +) => + useApiV1Resource( + !language + ? `/api/v1/dashboard/${idOrSlug}/datasets` + : `/api/v1/dashboard/${idOrSlug}/datasets?language=${language}`, + ); export const useEmbeddedDashboard = (idOrSlug: string | number) => useApiV1Resource(`/api/v1/dashboard/${idOrSlug}/embedded`); From 2f30131dfe5403cc22df08fe5fad8f93505d37f4 Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:46:37 +0300 Subject: [PATCH 07/14] chart translations on dashboard --- .../components/SliceHeader/index.tsx | 145 ++++++++++++++++-- .../components/gridComponents/Chart.jsx | 9 ++ .../components/gridComponents/ChartHolder.tsx | 26 +++- .../ScopingModal/ChartsScopingListPanel.tsx | 5 + .../components/nativeFilters/selectors.ts | 10 +- .../src/dashboard/containers/Chart.jsx | 4 + superset-frontend/src/dashboard/types.ts | 6 +- 7 files changed, 186 insertions(+), 19 deletions(-) diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx index 0ffa82756c9a4..576afca3db805 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx @@ -33,20 +33,27 @@ import { DashboardPageIdContext } from 'src/dashboard/containers/DashboardPage'; const extensionsRegistry = getExtensionsRegistry(); -type SliceHeaderProps = SliceHeaderControlsProps & { - innerRef?: string; - updateSliceName?: (arg0: string) => void; - editMode?: boolean; - annotationQuery?: object; - annotationError?: object; - sliceName?: string; - filters: object; - handleToggleFullSize: () => void; - formData: object; - width: number; - height: number; +type SliceHeaderPropsDodoExtended = { + updateSliceNameRU?: (arg0: string) => void; // DODO added 44120742 + sliceNameRU?: string; // DODO added 44120742 + locale: string; // DODO added 44120742 }; +type SliceHeaderProps = SliceHeaderControlsProps & + SliceHeaderPropsDodoExtended & { + innerRef?: string; + updateSliceName?: (arg0: string) => void; + editMode?: boolean; + annotationQuery?: object; + annotationError?: object; + sliceName?: string; + filters: object; + handleToggleFullSize: () => void; + formData: object; + width: number; + height: number; + }; + const annotationsLoading = t('Annotation layers are still loading.'); const annotationsError = t('One ore more annotation layers failed loading.'); const CrossFilterIcon = styled(Icons.ApartmentOutlined)` @@ -122,10 +129,35 @@ const ChartHeaderStyles = styled.div` `} `; +// DODO added start 44120742 +const TitleWrapper = styled.div` + display: flex; + align-items: flex-start; + justify-content: flex-start; + flex-direction: row; + margin-bottom: 8px; + min-height: 31px; + span { + margin-left: 12px; + &:first-child { + margin-left: 0; + } + } +`; +const TitleLabel = styled.span` + display: inline-block; + padding: 0; +`; +const StyledFlag = styled.i` + margin-top: 2px; +`; +// DODO added stop 44120742 + const SliceHeader: FC = ({ innerRef = null, forceRefresh = () => ({}), updateSliceName = () => ({}), + updateSliceNameRU = () => ({}), // DODO added 44120742 toggleExpandSlice = () => ({}), logExploreChart = () => ({}), logEvent, @@ -139,6 +171,7 @@ const SliceHeader: FC = ({ isCached = [], isExpanded = false, sliceName = '', + sliceNameRU = '', // DODO added 44120742 supersetCanExplore = false, supersetCanShare = false, supersetCanCSV = false, @@ -156,6 +189,7 @@ const SliceHeader: FC = ({ formData, width, height, + locale, // DODO added 44120742 }) => { const SliceHeaderExtension = extensionsRegistry.get('dashboard.slice.header'); const uiConfig = useUiConfig(); @@ -192,7 +226,7 @@ const SliceHeader: FC = ({ return (
- + {/* = ({ showTooltip={false} url={canExplore ? exploreUrl : undefined} /> - + */} + {/* DODO changed start 44120742 */} + {editMode && ( + <> + + +
+ +
+
+ + + +
+ + +
+ +
+
+ + + +
+ + )} + {!editMode && locale !== 'ru' && ( + + + + )} + {!editMode && locale === 'ru' && ( + + + + )} + {/* DODO changed stop 44120742 */} {!!Object.values(annotationQuery).length && ( {/* diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.tsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.tsx index d31e240e4f70d..0a9eba6f3fe8f 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.tsx +++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.tsx @@ -233,6 +233,22 @@ const ChartHolder: React.FC = ({ [component, updateComponents], ); + // DODO added 44120742 + const handleUpdateSliceNameRU = useCallback( + (nextName: string) => { + updateComponents({ + [component.id]: { + ...component, + meta: { + ...component.meta, + sliceNameOverrideRU: nextName, + }, + }, + }); + }, + [component, updateComponents], + ); + const handleToggleFullSize = useCallback(() => { setFullSizeChartId(isFullSize ? null : chartId); }, [chartId, isFullSize, setFullSizeChartId]); @@ -308,9 +324,17 @@ const ChartHolder: React.FC = ({ sliceName={ component.meta.sliceNameOverride || component.meta.sliceName || - '' + '--' // DODO changed 44120742 + } + // DODO added 44120742 + sliceNameRU={ + component.meta.sliceNameOverrideRU || + component.meta.sliceNameRU || + component.meta.sliceName || + '--' } updateSliceName={handleUpdateSliceName} + updateSliceNameRU={handleUpdateSliceNameRU} // DODO added 44120742 isComponentVisible={isComponentVisible} handleToggleFullSize={handleToggleFullSize} isFullSize={isFullSize} diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/ScopingModal/ChartsScopingListPanel.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/ScopingModal/ChartsScopingListPanel.tsx index 119763a22ef3e..e4c8eb3978708 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/ScopingModal/ChartsScopingListPanel.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/ScopingModal/ChartsScopingListPanel.tsx @@ -123,6 +123,11 @@ export const ChartsScopingListPanel = ({ chartLayoutItem?.meta.sliceNameOverride || chartLayoutItem?.meta.sliceName || '', + // DODO added 44120742 + labelRU: + chartLayoutItem?.meta.sliceNameOverrideRU || + chartLayoutItem?.meta.sliceNameRU || + '', }; }); }, [chartConfigs, layout]); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/selectors.ts b/superset-frontend/src/dashboard/components/nativeFilters/selectors.ts index 36f0fd1925dd9..50df0168b0161 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/selectors.ts +++ b/superset-frontend/src/dashboard/components/nativeFilters/selectors.ts @@ -157,13 +157,17 @@ const getRejectedColumns = (chart: any): Set => ), ); +type IndicatorDodoExtended = { + nameRU?: string; // DODO added 44120742 +}; + export type Indicator = { column?: QueryFormColumn; name: string; value?: any; status?: IndicatorStatus; path?: string[]; -}; +} & IndicatorDodoExtended; export type CrossFilterIndicator = Indicator & { emitterId: number }; @@ -188,6 +192,10 @@ export const getCrossFilterIndicator = ( dashboardLayoutItem?.meta?.sliceNameOverride || dashboardLayoutItem?.meta?.sliceName || '', + nameRU: + dashboardLayoutItem?.meta?.sliceNameOverrideRU || + dashboardLayoutItem?.meta?.sliceNameRU || + '', path: [ ...(dashboardLayoutItem?.parents ?? []), dashboardLayoutItem?.id || '', diff --git a/superset-frontend/src/dashboard/containers/Chart.jsx b/superset-frontend/src/dashboard/containers/Chart.jsx index 9f00bd0bf7096..f905ee6a72524 100644 --- a/superset-frontend/src/dashboard/containers/Chart.jsx +++ b/superset-frontend/src/dashboard/containers/Chart.jsx @@ -18,6 +18,7 @@ */ import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; +import { bootstrapData } from 'src/preamble'; // DODO added 44120742 import { toggleExpandSlice, setFocusedFilterField, @@ -40,6 +41,8 @@ import Chart from 'src/dashboard/components/gridComponents/Chart'; import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants'; import { enforceSharedLabelsColorsArray } from 'src/utils/colorScheme'; +const locale = bootstrapData?.common?.locale || 'en'; // DODO added 44120742 + const EMPTY_OBJECT = {}; function mapStateToProps( @@ -112,6 +115,7 @@ function mapStateToProps( setControlValue, datasetsStatus, emitCrossFilters: !!dashboardInfo.crossFiltersEnabled, + locale, // DODO added 44120742 }; } diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts index 159ec60968ae0..eee79ed97c698 100644 --- a/superset-frontend/src/dashboard/types.ts +++ b/superset-frontend/src/dashboard/types.ts @@ -178,7 +178,7 @@ type ComponentTypesKeys = keyof typeof componentTypes; export type ComponentType = (typeof componentTypes)[ComponentTypesKeys]; /** State of dashboardLayout item in redux */ -type LayoutItemDodoExtended = { +type MetaDodoExtended = { sliceNameRU?: string; // DODO added 44120742 sliceNameOverrideRU?: string; // DODO added 44120742 }; @@ -197,8 +197,8 @@ export type LayoutItem = { text?: string; uuid: string; width: number; - }; -} & LayoutItemDodoExtended; + } & MetaDodoExtended; +}; type ActiveFilter = { scope: number[]; From 6035c4936f392e0dbf18a4a0df3cf8819893b732 Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:59:23 +0300 Subject: [PATCH 08/14] Dashboard tabs translation --- .../Common/LanguageIndicator.tsx | 19 ++++ .../Common/LanguageIndicatorWrapper.tsx | 29 ++++++ .../src/DodoExtensions/Common/StyledFlag.tsx | 25 ++++++ .../DodoExtensions/Common/StyledPencil.tsx | 12 +++ .../src/DodoExtensions/Common/TitleLabel.tsx | 8 ++ .../DodoExtensions/Common/TitleWrapper.tsx | 19 ++++ .../src/DodoExtensions/Common/index.ts | 15 ++++ .../DashboardBuilder/DashboardBuilder.tsx | 2 +- .../src/dashboard/components/Header/index.jsx | 24 ++--- .../components/gridComponents/Tab.jsx | 89 ++++++++++++++++--- .../components/gridComponents/Tabs.jsx | 2 + .../containers/DashboardComponent.jsx | 8 +- 12 files changed, 228 insertions(+), 24 deletions(-) create mode 100644 superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx create mode 100644 superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx create mode 100644 superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx create mode 100644 superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx create mode 100644 superset-frontend/src/DodoExtensions/Common/TitleLabel.tsx create mode 100644 superset-frontend/src/DodoExtensions/Common/TitleWrapper.tsx create mode 100644 superset-frontend/src/DodoExtensions/Common/index.ts diff --git a/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx b/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx new file mode 100644 index 0000000000000..0d9f1d120c206 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { StyledPencil } from './StyledPencil'; +import { StyledFlag } from './StyledFlag'; +import { TitleLabel } from './TitleLabel'; + +const LanguageIndicator = ({ + language = 'gb', + canEdit, +}: { + language: 'gb' | 'ru'; + canEdit: boolean; +}) => ( + + + {canEdit && } + +); + +export { LanguageIndicator }; diff --git a/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx b/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx new file mode 100644 index 0000000000000..d1c3139195606 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx @@ -0,0 +1,29 @@ +import { styled } from '@superset-ui/core'; + +// eslint-disable-next-line theme-colors/no-literal-colors +const LanguageIndicatorWrapper = styled.div` + display: flex; + align-items: flex-start; + justify-content: flex-start; + flex-direction: row; + margin-bottom: 8px; + min-height: 32px; + + span { + margin-left: 12px; + + &:first-child { + margin-left: 0; + } + } + &:hover { + .editable-title { + border-bottom: 1px solid ${({ theme }) => theme.colors.primary.base}; + } + .editable-title--editing { + border-bottom: 0; + } + } +`; + +export { LanguageIndicatorWrapper }; diff --git a/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx b/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx new file mode 100644 index 0000000000000..61d82a615c9d1 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx @@ -0,0 +1,25 @@ +// DODO added +import { styled } from '@superset-ui/core'; +import React, { FC } from 'react'; + +const Flag = styled.i<{ $pressToTheBottom: boolean }>` + margin-top: ${props => props.$pressToTheBottom ?? '2px'}; +`; + +type Props = { + language: string; + style?: Record; + pressToTheBottom?: boolean; +}; + +const StyledFlag: FC = ({ + language = 'gb', + style = {}, + pressToTheBottom = true, +}) => ( +
+ +
+); + +export { StyledFlag }; diff --git a/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx b/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx new file mode 100644 index 0000000000000..ed94170244531 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx @@ -0,0 +1,12 @@ +import { styled } from '@superset-ui/core'; +import React from 'react'; + +const Pencil = styled.i` + margin-left: 6px; + margin-top: 6px; + font-size: 12px; +`; + +const StyledPencil = () => ; + +export { StyledPencil }; diff --git a/superset-frontend/src/DodoExtensions/Common/TitleLabel.tsx b/superset-frontend/src/DodoExtensions/Common/TitleLabel.tsx new file mode 100644 index 0000000000000..9f3d3f1bcbc17 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/TitleLabel.tsx @@ -0,0 +1,8 @@ +import { styled } from '@superset-ui/core'; + +const TitleLabel = styled.span` + display: flex; + padding: 2px 0; +`; + +export { TitleLabel }; diff --git a/superset-frontend/src/DodoExtensions/Common/TitleWrapper.tsx b/superset-frontend/src/DodoExtensions/Common/TitleWrapper.tsx new file mode 100644 index 0000000000000..c25d3991796a4 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/TitleWrapper.tsx @@ -0,0 +1,19 @@ +import { styled } from '@superset-ui/core'; + +const TitleWrapper = styled.div` + display: flex; + align-items: flex-start; + justify-content: flex-start; + flex-direction: row; + margin-bottom: 8px; + + span { + margin-left: 12px; + + &:first-child { + margin-left: 0; + } + } +`; + +export { TitleWrapper }; diff --git a/superset-frontend/src/DodoExtensions/Common/index.ts b/superset-frontend/src/DodoExtensions/Common/index.ts new file mode 100644 index 0000000000000..f2bcfc4526030 --- /dev/null +++ b/superset-frontend/src/DodoExtensions/Common/index.ts @@ -0,0 +1,15 @@ +import { TitleWrapper } from 'src/DodoExtensions/Common/TitleWrapper'; +import { TitleLabel } from 'src/DodoExtensions/Common/TitleLabel'; +import { StyledFlag } from 'src/DodoExtensions/Common/StyledFlag'; +import { StyledPencil } from 'src/DodoExtensions/Common/StyledPencil'; +import { LanguageIndicator } from 'src/DodoExtensions/Common/LanguageIndicator'; +import { LanguageIndicatorWrapper } from 'src/DodoExtensions/Common/LanguageIndicatorWrapper'; + +export { + TitleWrapper, + TitleLabel, + StyledFlag, + StyledPencil, + LanguageIndicator, + LanguageIndicatorWrapper, +}; diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx index e8658d8996be1..258ce2b535743 100644 --- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx +++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx @@ -586,7 +586,7 @@ const DashboardBuilder: FC = () => { renderTabContent={false} renderHoverMenu={false} onChangeTab={handleChangeTab} - userLanguage={locale} // DODO added 44120742 + locale={locale} // DODO added 44120742 /> )} diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index 0901b1382b6dc..b999a354f10a5 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -29,6 +29,7 @@ import { getExtensionsRegistry, } from '@superset-ui/core'; import { Global } from '@emotion/react'; +import { bootstrapData } from 'src/preamble'; import { LOG_ACTIONS_PERIODIC_RENDER_DASHBOARD, LOG_ACTIONS_FORCE_REFRESH_DASHBOARD, @@ -46,11 +47,7 @@ import UndoRedoKeyListeners from 'src/dashboard/components/UndoRedoKeyListeners' import PropertiesModal from 'src/dashboard/components/PropertiesModal'; import { chartPropShape } from 'src/dashboard/util/propShapes'; import getOwnerName from 'src/utils/getOwnerName'; -import { - UNDO_LIMIT, - SAVE_TYPE_OVERWRITE, - DASHBOARD_POSITION_DATA_LIMIT, -} from 'src/dashboard/util/constants'; +import * as constants from 'src/dashboard/util/constants'; import setPeriodicRunner, { stopPeriodicRender, } from 'src/dashboard/util/setPeriodicRunner'; @@ -59,6 +56,8 @@ import MetadataBar, { MetadataType } from 'src/components/MetadataBar'; import DashboardEmbedModal from '../EmbeddedModal'; import OverwriteConfirm from '../OverwriteConfirm'; +const locale = bootstrapData?.common?.locale || 'en'; + const extensionsRegistry = getExtensionsRegistry(); const propTypes = { @@ -217,14 +216,14 @@ class Header extends PureComponent { UNSAFE_componentWillReceiveProps(nextProps) { if ( - UNDO_LIMIT - nextProps.undoLength <= 0 && + constants.UNDO_LIMIT - nextProps.undoLength <= 0 && !this.state.didNotifyMaxUndoHistoryToast ) { this.setState(() => ({ didNotifyMaxUndoHistoryToast: true })); this.props.maxUndoHistoryToast(); } if ( - nextProps.undoLength > UNDO_LIMIT && + nextProps.undoLength > constants.UNDO_LIMIT && !this.props.maxUndoHistoryExceeded ) { this.props.setMaxUndoHistoryExceeded(); @@ -405,7 +404,7 @@ class Header extends PureComponent { const positionJSONLength = safeStringify(positions).length; const limit = dashboardInfo.common.conf.SUPERSET_DASHBOARD_POSITION_DATA_LIMIT || - DASHBOARD_POSITION_DATA_LIMIT; + constants.DASHBOARD_POSITION_DATA_LIMIT; if (positionJSONLength >= limit) { this.props.addDangerToast( t( @@ -417,7 +416,7 @@ class Header extends PureComponent { this.props.addWarningToast('Your dashboard is near the size limit.'); } - this.props.onSave(data, dashboardInfo.id, SAVE_TYPE_OVERWRITE); + this.props.onSave(data, dashboardInfo.id, constants.SAVE_TYPE_OVERWRITE); } } @@ -530,7 +529,12 @@ class Header extends PureComponent { > - + {/* DODO changed 44120742 */} + {editMode && ( + + + + this.handleChangeText(nextTabText, 'text') + } + showTooltip={false} + editing={editMode && isFocused} + /> + + )} + {/* DODO added 44120742 */} + {editMode && ( + + + + this.handleChangeText(nextTabText, 'textRU') + } + showTooltip={false} + editing={editMode && isFocused} + /> + + )} + {!editMode && ( + + this.handleChangeText(nextTabText, 'text') + } + showTooltip={false} + editing={editMode && isFocused} + /> + )} {!editMode && ( } > diff --git a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx index bf92c5dcecaeb..c2cb3b754179c 100644 --- a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx +++ b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx @@ -20,6 +20,7 @@ import { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; +import { bootstrapData } from 'src/preamble'; // DODO added 44120742 import { logEvent } from 'src/logger/actions'; import { addDangerToast } from 'src/components/MessageToasts/actions'; import { componentLookup } from 'src/dashboard/components/gridComponents'; @@ -39,6 +40,8 @@ import { setFullSizeChartId, } from 'src/dashboard/actions/dashboardState'; +const locale = bootstrapData?.common?.locale || 'en'; // DODO added 44120742 + const propTypes = { id: PropTypes.string, parentId: PropTypes.string, @@ -58,6 +61,9 @@ const propTypes = { directPathLastUpdated: PropTypes.number, dashboardId: PropTypes.number.isRequired, isComponentVisible: PropTypes.bool, + + // DODO extended + locale: PropTypes.string, // DODO added 44120742 }; const defaultProps = { @@ -121,7 +127,7 @@ class DashboardComponent extends PureComponent { render() { const { component } = this.props; const Component = component ? componentLookup[component.type] : null; - return Component ? : null; + return Component ? : null; } } From 71a62b71f892f13b93aea95a381d5be56d55cc5f Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:00:27 +0300 Subject: [PATCH 09/14] refactor: slice header styles --- .../components/SliceHeader/index.tsx | 30 ++++--------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx index 576afca3db805..2437a2d7b3994 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx @@ -30,6 +30,12 @@ import Icons from 'src/components/Icons'; import { RootState } from 'src/dashboard/types'; import { getSliceHeaderTooltip } from 'src/dashboard/util/getSliceHeaderTooltip'; import { DashboardPageIdContext } from 'src/dashboard/containers/DashboardPage'; +// DODO added 44120742 +import { + StyledFlag, + TitleLabel, + TitleWrapper, +} from 'src/DodoExtensions/Common'; const extensionsRegistry = getExtensionsRegistry(); @@ -129,30 +135,6 @@ const ChartHeaderStyles = styled.div` `} `; -// DODO added start 44120742 -const TitleWrapper = styled.div` - display: flex; - align-items: flex-start; - justify-content: flex-start; - flex-direction: row; - margin-bottom: 8px; - min-height: 31px; - span { - margin-left: 12px; - &:first-child { - margin-left: 0; - } - } -`; -const TitleLabel = styled.span` - display: inline-block; - padding: 0; -`; -const StyledFlag = styled.i` - margin-top: 2px; -`; -// DODO added stop 44120742 - const SliceHeader: FC = ({ innerRef = null, forceRefresh = () => ({}), From cbf0ba061d0748adaf5c18267968dd04139b8e55 Mon Sep 17 00:00:00 2001 From: Artem Aslamov Date: Wed, 15 Jan 2025 13:27:20 +0700 Subject: [PATCH 10/14] add filter for dash by id and dashboard_title_RU --- superset/dashboards/filters.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/superset/dashboards/filters.py b/superset/dashboards/filters.py index 9a4c496b20b31..2a21658c9ed81 100644 --- a/superset/dashboards/filters.py +++ b/superset/dashboards/filters.py @@ -48,6 +48,8 @@ def apply(self, query: Query, value: Any) -> Query: or_( Dashboard.dashboard_title.ilike(ilike_value), Dashboard.slug.ilike(ilike_value), + Dashboard.dashboard_title_RU.ilike(ilike_value), + Dashboard.id(ilike_value), ) ) From 4d392f1c90163411a2958564716b98cc5651034d Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:22:20 +0300 Subject: [PATCH 11/14] refactor --- .../src/DodoExtensions/Common/LanguageIndicator.tsx | 1 - superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx | 2 +- superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx | 1 - .../src/dashboard/components/SliceHeader/index.tsx | 4 ++-- .../src/dashboard/components/gridComponents/Tab.jsx | 3 --- .../src/dashboard/components/gridComponents/Tabs.jsx | 4 ++-- 6 files changed, 5 insertions(+), 10 deletions(-) diff --git a/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx b/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx index 0d9f1d120c206..61ebc10f8eea2 100644 --- a/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx +++ b/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { StyledPencil } from './StyledPencil'; import { StyledFlag } from './StyledFlag'; import { TitleLabel } from './TitleLabel'; diff --git a/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx b/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx index 61d82a615c9d1..099acc504d910 100644 --- a/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx +++ b/superset-frontend/src/DodoExtensions/Common/StyledFlag.tsx @@ -1,6 +1,6 @@ // DODO added import { styled } from '@superset-ui/core'; -import React, { FC } from 'react'; +import { FC } from 'react'; const Flag = styled.i<{ $pressToTheBottom: boolean }>` margin-top: ${props => props.$pressToTheBottom ?? '2px'}; diff --git a/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx b/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx index ed94170244531..652c4e8c79d9c 100644 --- a/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx +++ b/superset-frontend/src/DodoExtensions/Common/StyledPencil.tsx @@ -1,5 +1,4 @@ import { styled } from '@superset-ui/core'; -import React from 'react'; const Pencil = styled.i` margin-left: 6px; diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx index 2437a2d7b3994..cbbc42a2d4bdc 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx @@ -228,7 +228,7 @@ const SliceHeader: FC = ({
- +
@@ -249,7 +249,7 @@ const SliceHeader: FC = ({
- +
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx index 0ebce13059610..c2ebd0348e849 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx @@ -36,9 +36,6 @@ import { TAB_TYPE } from 'src/dashboard/util/componentTypes'; import { LanguageIndicator, LanguageIndicatorWrapper, - StyledFlag, - TitleLabel, - TitleWrapper, } from 'src/DodoExtensions/Common'; export const RENDER_TAB = 'RENDER_TAB'; diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx index ee97883ef66b9..ef8764f8d9f3a 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx @@ -327,7 +327,7 @@ export class Tabs extends PureComponent { isComponentVisible: isCurrentTabVisible, editMode, nativeFilters, - locale, + locale, // DODO added 44120742 } = this.props; const { children: tabIds } = tabsComponent; @@ -389,7 +389,7 @@ export class Tabs extends PureComponent { isHighlighted={ activeKey !== tabId && tabsToHighlight?.includes(tabId) } - locale={locale} + locale={locale} // DODO added 44120742 /> } > From c33c8d20fa85ce02804bda7013b5ef1a9e0aa76e Mon Sep 17 00:00:00 2001 From: Artem Aslamov Date: Wed, 15 Jan 2025 20:35:22 +0700 Subject: [PATCH 12/14] add translate to datasets --- superset/connectors/sqla/models.py | 16 ++++++++++++++++ superset/datasets/api.py | 8 ++++++++ superset/datasets/schemas.py | 8 ++++++++ 3 files changed, 32 insertions(+) diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index fb7409adba589..7fc97dccdbaba 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -834,6 +834,10 @@ class TableColumn(AuditMixinNullable, ImportExportMixin, CertificationMixin, Mod expression = Column(utils.MediumText()) python_date_format = Column(String(255)) extra = Column(Text) + description_EN = Column(utils.MediumText(), nullable=True) + description_RU = Column(utils.MediumText(), nullable=True) + verbose_name_RU = Column(String(1024), nullable=True) + verbose_name_EN = Column(String(1024), nullable=True, default=None) table: Mapped[SqlaTable] = relationship( "SqlaTable", @@ -1022,6 +1026,10 @@ def data(self) -> dict[str, Any]: "type_generic", "verbose_name", "warning_markdown", + "description_EN", + "description_RU", + "verbose_name_RU", + "verbose_name_EN", ) return {s: getattr(self, s) for s in attrs if hasattr(self, s)} @@ -1044,6 +1052,10 @@ class SqlMetric(AuditMixinNullable, ImportExportMixin, CertificationMixin, Model table_id = Column(Integer, ForeignKey("tables.id", ondelete="CASCADE")) expression = Column(utils.MediumText(), nullable=False) extra = Column(Text) + description_EN = Column(utils.MediumText(), nullable=True) + description_RU = Column(utils.MediumText(), nullable=True) + verbose_name_RU = Column(String(1024), nullable=True) + verbose_name_EN = Column(String(1024), nullable=True, default=None) table: Mapped[SqlaTable] = relationship( "SqlaTable", @@ -1119,6 +1131,10 @@ def data(self) -> dict[str, Any]: "warning_markdown", "warning_text", "verbose_name", + "description_EN", + "description_RU", + "verbose_name_RU", + "verbose_name_EN", ) return {s: getattr(self, s) for s in attrs} diff --git a/superset/datasets/api.py b/superset/datasets/api.py index f8f6bdc0b9604..c7e34d5135188 100644 --- a/superset/datasets/api.py +++ b/superset/datasets/api.py @@ -161,6 +161,8 @@ class DatasetRestApi(BaseSupersetModelRestApi): "columns.column_name", "columns.created_on", "columns.description", + "columns.description_RU", + "columns.description_EN", "columns.expression", "columns.filterable", "columns.groupby", @@ -172,17 +174,23 @@ class DatasetRestApi(BaseSupersetModelRestApi): "columns.type", "columns.uuid", "columns.verbose_name", + "columns.verbose_name_RU", + "columns.verbose_name_EN", "metrics.changed_on", "metrics.created_on", "metrics.d3format", "metrics.currency", "metrics.description", + "metrics.description_RU", + "metrics.description_EN", "metrics.expression", "metrics.extra", "metrics.id", "metrics.metric_name", "metrics.metric_type", "metrics.verbose_name", + "metrics.verbose_name_RU", + "metrics.verbose_name_EN", "metrics.warning_text", "datasource_type", "url", diff --git a/superset/datasets/schemas.py b/superset/datasets/schemas.py index 5b899d8402f23..0aaa5ecc311d7 100644 --- a/superset/datasets/schemas.py +++ b/superset/datasets/schemas.py @@ -62,7 +62,11 @@ class DatasetColumnsPutSchema(Schema): validate=Length(1, 255), ) verbose_name = fields.String(allow_none=True, metadata={Length: (1, 1024)}) + verbose_name_RU = fields.String(allow_none=True, metadata={Length: (1, 1024)}) + verbose_name_EN = fields.String(allow_none=True, metadata={Length: (1, 1024)}) description = fields.String(allow_none=True) + description_RU = fields.String(allow_none=True) + description_EN = fields.String(allow_none=True) expression = fields.String(allow_none=True) extra = fields.String(allow_none=True) filterable = fields.Boolean() @@ -79,12 +83,16 @@ class DatasetMetricsPutSchema(Schema): id = fields.Integer() expression = fields.String(required=True) description = fields.String(allow_none=True) + description_RU = fields.String(allow_none=True) + description_EN = fields.String(allow_none=True) extra = fields.String(allow_none=True) metric_name = fields.String(required=True, validate=Length(1, 255)) metric_type = fields.String(allow_none=True, validate=Length(1, 32)) d3format = fields.String(allow_none=True, validate=Length(1, 128)) currency = fields.String(allow_none=True, required=False, validate=Length(1, 128)) verbose_name = fields.String(allow_none=True, metadata={Length: (1, 1024)}) + verbose_name_RU = fields.String(allow_none=True, metadata={Length: (1, 1024)}) + verbose_name_EN = fields.String(allow_none=True, metadata={Length: (1, 1024)}) warning_text = fields.String(allow_none=True) uuid = fields.UUID(allow_none=True) From 0ee3284c1d90ca9d71ebf2517bdc102e7f7b3d7c Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:09:10 +0300 Subject: [PATCH 13/14] refactor(translations): Name is changed to Title --- .../src/dashboard/components/PropertiesModal/index.tsx | 4 ++-- superset-frontend/src/pages/DashboardList/index.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx index 44cae3d1ab04a..209f082ff6b6c 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx @@ -659,7 +659,7 @@ const PropertiesModal = ({ {/* */} {/* DODO changed 44120742 */} - + {/* DODO added start 44120742 */} - + ), // Header: t('Name'), - Header: `${t('Name')} EN`, // DODO changed 44120742 + Header: t('Title'), // DODO changed 44120742 accessor: 'dashboard_title', }, // DODO added start 44120742 @@ -354,7 +354,7 @@ function DashboardList(props: DashboardListProps) { }: any) => ( {dashboardTitleRU ? `${dashboardTitleRU}` : '-'} ), - Header: `${t('Name')} RU`, + Header: t('Title (Rus)'), accessor: 'dashboard_title_RU', }, // DODO added stop 44120742 From c6f5bb9c70970e8020b4a7a3e8ff609fea230476 Mon Sep 17 00:00:00 2001 From: etokiryau <123979827+etokiryau@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:49:42 +0300 Subject: [PATCH 14/14] refactor(styles): dashboards tabs for 4.1 --- .../Common/LanguageIndicator.tsx | 2 +- .../Common/LanguageIndicatorWrapper.tsx | 19 +++++++++++-------- .../src/components/EditableTitle/index.tsx | 3 --- .../components/gridComponents/Tab.jsx | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx b/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx index 61ebc10f8eea2..ce86e2187be5c 100644 --- a/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx +++ b/superset-frontend/src/DodoExtensions/Common/LanguageIndicator.tsx @@ -7,7 +7,7 @@ const LanguageIndicator = ({ canEdit, }: { language: 'gb' | 'ru'; - canEdit: boolean; + canEdit?: boolean; }) => ( diff --git a/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx b/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx index d1c3139195606..139e7b7093506 100644 --- a/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx +++ b/superset-frontend/src/DodoExtensions/Common/LanguageIndicatorWrapper.tsx @@ -6,22 +6,25 @@ const LanguageIndicatorWrapper = styled.div` align-items: flex-start; justify-content: flex-start; flex-direction: row; - margin-bottom: 8px; - min-height: 32px; + margin-bottom: 4px; + min-height: 26px; + font-size: ${({ theme }) => theme.typography.sizes.s}px; + color: ${({ theme }) => theme.colors.grayscale.dark1}; span { - margin-left: 12px; - - &:first-child { - margin-left: 0; + &:nth-child(n + 1) { + margin-left: 12px; } } + .editable-title--editing { + color: ${({ theme }) => theme.colors.primary.base}; + } &:hover { .editable-title { - border-bottom: 1px solid ${({ theme }) => theme.colors.primary.base}; + color: ${({ theme }) => theme.colors.grayscale.base}; } .editable-title--editing { - border-bottom: 0; + color: ${({ theme }) => theme.colors.primary.base}; } } `; diff --git a/superset-frontend/src/components/EditableTitle/index.tsx b/superset-frontend/src/components/EditableTitle/index.tsx index fc01fb9f63b99..582c2b3eff68c 100644 --- a/superset-frontend/src/components/EditableTitle/index.tsx +++ b/superset-frontend/src/components/EditableTitle/index.tsx @@ -226,9 +226,6 @@ export default function EditableTitle({ css={(theme: SupersetTheme) => css` color: ${theme.colors.grayscale.dark1}; text-decoration: none; - :hover { - text-decoration: underline; - } display: inline-block; `} > diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx index c2ebd0348e849..6538077b67759 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx @@ -310,7 +310,7 @@ class Tab extends PureComponent { {/* DODO changed 44120742 */} {editMode && ( - + - +