From f10a55f25a8c12e2c763fcf6f54ed57cec5069fb Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Tue, 12 Nov 2024 15:14:37 +0300 Subject: [PATCH 1/5] Support exceptions for chart menu --- .../charts-engine/components/storage/types.ts | 3 ++ .../charts-engine/controllers/embeds.ts | 5 ++++ src/server/configs/opensource/common.ts | 2 +- src/shared/schema/us/types/embeds.ts | 3 ++ src/shared/types/charts.ts | 1 + src/shared/types/common.ts | 1 + .../Widgets/Chart/components/Header.tsx | 26 ++++++++++++++++- src/ui/constants/common.ts | 3 ++ .../Menu/Items/DownloadCsv/DownloadCsv.tsx | 7 ++--- .../components/Menu/Items/Export/Export.tsx | 29 +++++++------------ .../components/Menu/Items/Export/types.ts | 1 - .../components/Header/components/Menu/Menu.js | 6 ++++ .../modules/data-provider/charts/index.ts | 2 +- .../modules/data-provider/charts/node.ts | 2 ++ .../modules/data-provider/charts/types.ts | 5 ++-- .../modules/data-provider/charts/wizard.js | 2 ++ .../DatalensChartkit/modules/export/export.js | 19 ++++++++---- 17 files changed, 82 insertions(+), 35 deletions(-) diff --git a/src/server/components/charts-engine/components/storage/types.ts b/src/server/components/charts-engine/components/storage/types.ts index 224e0b6cac..8c5e43c372 100644 --- a/src/server/components/charts-engine/components/storage/types.ts +++ b/src/server/components/charts-engine/components/storage/types.ts @@ -66,6 +66,9 @@ export type EmbeddingInfo = { createdBy: string; createdAt: string; publicParamsMode: boolean; + settings: { + enableExport?: boolean; + }; }; entry: ChartEntryData | DashEntryData; }; diff --git a/src/server/components/charts-engine/controllers/embeds.ts b/src/server/components/charts-engine/controllers/embeds.ts index 1808018231..737fd19024 100644 --- a/src/server/components/charts-engine/controllers/embeds.ts +++ b/src/server/components/charts-engine/controllers/embeds.ts @@ -288,6 +288,11 @@ export const embedsController = (chartsEngine: ChartsEngine) => { req.body.config = entry; req.body.key = entry.key; + req.body.widgetConfig = { + ...req.body.widgetConfig, + enableMenuExport: embeddingInfo.embed.settings?.enableExport === true, + }; + return runnerFound.handler(ctx, { chartsEngine, req, diff --git a/src/server/configs/opensource/common.ts b/src/server/configs/opensource/common.ts index fef3eee459..84a8fee370 100644 --- a/src/server/configs/opensource/common.ts +++ b/src/server/configs/opensource/common.ts @@ -222,5 +222,5 @@ export default { serviceClientId: process.env.SERVICE_CLIENT_ID || '', serviceClientSecret: process.env.SERVICE_CLIENT_SECRET || '', - runEndpoint: '/api/run', + apiPrefix: '/api', }; diff --git a/src/shared/schema/us/types/embeds.ts b/src/shared/schema/us/types/embeds.ts index 6564a70b19..bb86694ef4 100644 --- a/src/shared/schema/us/types/embeds.ts +++ b/src/shared/schema/us/types/embeds.ts @@ -11,6 +11,9 @@ export type Embed = { updatedAt: string; updatedBy: string; publicParamsMode: boolean; + settings: { + enableExport?: boolean; + }; }; export type CreateEmbedArgs = { diff --git a/src/shared/types/charts.ts b/src/shared/types/charts.ts index 45823488ab..8d06874db1 100644 --- a/src/shared/types/charts.ts +++ b/src/shared/types/charts.ts @@ -238,6 +238,7 @@ export type DashWidgetConfig = { enable?: boolean; fields?: string[]; }; + enableMenuExport?: boolean; }; }; diff --git a/src/shared/types/common.ts b/src/shared/types/common.ts index b58205c883..78eaab1b35 100644 --- a/src/shared/types/common.ts +++ b/src/shared/types/common.ts @@ -204,6 +204,7 @@ export type DLGlobalData = { } | boolean; runEndpoint?: string; + apiPrefix?: string; docPathName?: DocPathName; chartkitSettings?: ChartkitGlobalSettings; extraPalettes?: Record; diff --git a/src/ui/components/Widgets/Chart/components/Header.tsx b/src/ui/components/Widgets/Chart/components/Header.tsx index 8dc1b536d6..1cb0fe1a84 100644 --- a/src/ui/components/Widgets/Chart/components/Header.tsx +++ b/src/ui/components/Widgets/Chart/components/Header.tsx @@ -3,6 +3,7 @@ import React from 'react'; import block from 'bem-cn-lite'; import get from 'lodash/get'; import {useSelector} from 'react-redux'; +import {MenuItemsIds} from 'shared'; import type {StringParams} from 'shared'; import {ChartInfoIcon} from 'ui/components/Widgets/Chart/components/ChartInfoIcon'; import type {ChartKitDataProvider} from 'ui/libs/DatalensChartkit/components/ChartKitBase/types'; @@ -93,7 +94,28 @@ export const Header = (props: HeaderProps) => { */ const hideChartComments = Boolean((loadedData?.config as GraphWidget['config'])?.hideComments); - const canBeShownMenu = isMenuAvailable && widgetDataRef; + // exceptions that are shown forcibly under certain conditions + // when menu is not available + const {forceVisibleMenuConfig, hasForceVisibleItems} = React.useMemo(() => { + if (isMenuAvailable) { + return { + forceVisibleMenuConfig: {}, + hasForceVisibleItems: false, + }; + } + + const config = { + [MenuItemsIds.EXPORT]: loadedData?.widgetConfig?.enableMenuExport, + }; + + return { + forceVisibleMenuConfig: config, + hasForceVisibleItems: Object.values(config).some(Boolean), + }; + }, [loadedData?.widgetConfig?.enableMenuExport, isMenuAvailable]); + + const canBeShownMenu = (isMenuAvailable || hasForceVisibleItems) && widgetDataRef; + const configMenu = menuType ? getChartkitMenu({ type: menuType, @@ -149,6 +171,8 @@ export const Header = (props: HeaderProps) => { /* isWidgetMenuDataChanged - need this flag for extra rerender after widget rendered to check visibility of items (it is not used in component directly) */ isWidgetMenuDataChanged={isWidgetMenuDataChanged} chartsDataProvider={dataProvider} + forceVisibleMenuConfig={forceVisibleMenuConfig} + hasForceVisibleItems={hasForceVisibleItems} /> )} diff --git a/src/ui/constants/common.ts b/src/ui/constants/common.ts index a0ffea56a4..2cc651ee79 100644 --- a/src/ui/constants/common.ts +++ b/src/ui/constants/common.ts @@ -231,6 +231,9 @@ export const DL = { get RUN_ENDPOINT() { return window.DL.runEndpoint || '/api/run'; }, + get API_PREFIX() { + return window.DL.apiPrefix || '/api'; + }, get CONNECTOR_ICONS() { return window.DL.connectorIcons || []; }, diff --git a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/DownloadCsv/DownloadCsv.tsx b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/DownloadCsv/DownloadCsv.tsx index d399e12a9a..456e392b05 100644 --- a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/DownloadCsv/DownloadCsv.tsx +++ b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/DownloadCsv/DownloadCsv.tsx @@ -18,7 +18,7 @@ const i18n = I18n.keyset('chartkit.menu.download-csv'); const EXPORT_WARNING_TYPE = 'table'; type DownloadCsvProps = { - onApply: ({chartData, params, path}: ExportChartArgs) => void; + onApply: ({chartData, params}: ExportChartArgs) => void; loading?: boolean; onClose: () => void; chartType: string; @@ -89,7 +89,6 @@ export const DownloadCsv = ({ onClose, chartType, chartData, - path, onExportLoading, }: DownloadCsvProps) => { const [delValue, setDelValue] = React.useState(';'); @@ -106,9 +105,9 @@ export const DownloadCsv = ({ encoding, }; - onApply({chartData, params, path, onExportLoading}); + onApply({chartData, params, onExportLoading}); onClose(); - }, [chartData, delNumber, delValue, encoding, onApply, path]); + }, [chartData, delNumber, delValue, encoding, onApply]); return ( { +const getExportResult = async ({chartData, params}: ExportChartArgs) => { const {widgetDataRef, loadedData, widget} = chartData; const fileName = getFileName(loadedData.key); @@ -42,7 +42,6 @@ const getExportResult = async ({chartData, params, path}: ExportChartArgs) => { const exportResult = (await exportWidget({ widgetDataRef: widgetDataRef?.current, widget: widgetDataRef?.current || widget, - path, data: loadedData.data, widgetType: loadedData.type, options: params, @@ -59,8 +58,8 @@ const getExportResult = async ({chartData, params, path}: ExportChartArgs) => { return exportResult; }; -const copyData = async ({chartData, params, path}: ExportChartArgs) => { - const exportResult = await getExportResult({chartData, path, params}); +const copyData = async ({chartData, params}: ExportChartArgs) => { + const exportResult = await getExportResult({chartData, params}); if (!exportResult) { return; } @@ -71,13 +70,13 @@ const copyData = async ({chartData, params, path}: ExportChartArgs) => { } }; -const downloadData = async ({chartData, params, path, onExportLoading}: ExportChartArgs) => { +const downloadData = async ({chartData, params, onExportLoading}: ExportChartArgs) => { const {loadedData} = chartData; const fileName = getFileName(loadedData.key) + '.'; setLoadingToast(fileName, params?.format || ''); onExportLoading?.(true); - const exportResult = await getExportResult({chartData, path, params}); + const exportResult = await getExportResult({chartData, params}); if (!exportResult) { toaster.remove(fileName); onExportLoading?.(false); @@ -124,18 +123,10 @@ const csvExportAction = ( }; const directExportAction = ( - chartsDataProvider: ChartKitDataProvider, format: ExportFormatsType, onExportLoading?: ExportChartArgs['onExportLoading'], ) => { return async (chartData: ExportActionArgs) => { - const {loadedData, propsData} = chartData; - - const path = chartsDataProvider.getGoAwayLink( - {loadedData, propsData}, - {urlPostfix: '/preview', idPrefix: '/editor/'}, - ); - const params = { format, delValues: null, @@ -144,10 +135,10 @@ const directExportAction = ( }; if (format === EXPORT_FORMATS.XLSX) { - downloadData({chartData, params, path, onExportLoading}); + downloadData({chartData, params, onExportLoading}); return; } - copyData({chartData, params, path}); + copyData({chartData, params}); }; }; @@ -210,7 +201,7 @@ const getSubItems = ({ isVisible: ({loadedData, error}: MenuItemArgs) => Utils.isEnabledFeature(Feature.XlsxChartExportEnabled) && isExportVisible({loadedData, error}), - action: directExportAction(chartsDataProvider, EXPORT_FORMATS.XLSX, onExportLoading), + action: directExportAction(EXPORT_FORMATS.XLSX, onExportLoading), }, { id: MenuItemsIds.EXPORT_CSV, @@ -222,14 +213,14 @@ const getSubItems = ({ id: MenuItemsIds.EXPORT_MARKDOWN, title: i18n('format_markdown'), isVisible: isExportVisible, - action: directExportAction(chartsDataProvider, EXPORT_FORMATS.MARKDOWN), + action: directExportAction(EXPORT_FORMATS.MARKDOWN), }, { id: MenuItemsIds.EXPORT_WIKI, title: i18n('format_wiki'), isVisible: ({loadedData, error}: MenuItemArgs) => Boolean(showWiki) && isExportVisible({loadedData, error}), - action: directExportAction(chartsDataProvider, EXPORT_FORMATS.WIKI), + action: directExportAction(EXPORT_FORMATS.WIKI), }, { id: MenuItemsIds.EXPORT_SCREENSHOT, diff --git a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/types.ts b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/types.ts index 21519cfebf..389a0d1964 100644 --- a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/types.ts +++ b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/types.ts @@ -35,6 +35,5 @@ export type ExportActionArgs = { export type ExportChartArgs = { chartData: ExportActionArgs; params?: ExportParams; - path?: string; onExportLoading?: (isLoading: boolean) => void; }; diff --git a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js index 4707bbca6a..511c4bf68e 100644 --- a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js +++ b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js @@ -53,6 +53,8 @@ export class Menu extends React.PureComponent { * but we need to toggle show/hide comments menu */ hideChartComments: PropTypes.bool, + forceVisibleMenuConfig: PropTypes.object, + hasForceVisibleItems: PropTypes.bool, }; state = { @@ -133,6 +135,10 @@ export class Menu extends React.PureComponent { if (!this.isVisibleItem({isVisible: item.isVisible, data})) { return null; } + const {forceVisibleMenuConfig, hasForceVisibleItems} = this.props; + if (hasForceVisibleItems && !forceVisibleMenuConfig[item.id]) { + return null; + } return {...item, items: visibleSubItems}; }; diff --git a/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts b/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts index 0686f3b1d2..396b453622 100644 --- a/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts +++ b/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts @@ -734,7 +734,7 @@ class ChartsDataProvider implements DataProvider { @@ -394,7 +398,6 @@ function convertDataToWiki({widget, data, widgetType}) { async function exportWidget({ widget, - path, data, widgetType, options, @@ -403,7 +406,6 @@ async function exportWidget({ downloadName, }) { const params = { - chartUrl: path, formSettings: options, lang: settings.lang, // downloadConfig: props.downloadConfig, @@ -413,12 +415,19 @@ async function exportWidget({ const stringifyData = encodeURIComponent(JSON.stringify(params)); + const headers = {}; + + if (isEmbeddedEntry()) { + const getSecureEmbeddingToken = registry.chart.functions.get('getSecureEmbeddingToken'); + headers[DL_EMBED_TOKEN_HEADER] = getSecureEmbeddingToken(); + } + const request = { url: `${chartsDataProvider.endpoint}${API}`, method: 'post', data: {data: stringifyData, exportFilename}, responseType: 'blob', - headers: {}, + headers, }; // append and remove are needed in particular for FireFox @@ -446,7 +455,6 @@ async function exportWidget({ export default async ({ widget, widgetDataRef, - path, data, widgetType, options = getStorageState(), @@ -477,7 +485,6 @@ export default async ({ default: { return exportWidget({ widget: widgetDataRef?.current || widget, - path, data, widgetType, options, From 9f3860620d011950d02626e4fb849b1b3ce0564b Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Wed, 13 Nov 2024 12:42:00 +0300 Subject: [PATCH 2/5] Review fixes --- .../charts-engine/controllers/embeds.ts | 2 +- src/shared/types/charts.ts | 2 +- .../components/Widgets/Chart/ChartWidget.tsx | 3 +-- .../Widgets/Chart/components/Header.tsx | 26 ++----------------- .../components/Menu/Items/Export/Export.tsx | 6 ++++- .../components/Header/components/Menu/Menu.js | 6 ----- .../libs/DatalensChartkit/menu/MenuItems.tsx | 22 ++++++++++++---- .../types/functions/getChartkitMenuByType.ts | 1 + 8 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/server/components/charts-engine/controllers/embeds.ts b/src/server/components/charts-engine/controllers/embeds.ts index 737fd19024..05f7122b9a 100644 --- a/src/server/components/charts-engine/controllers/embeds.ts +++ b/src/server/components/charts-engine/controllers/embeds.ts @@ -290,7 +290,7 @@ export const embedsController = (chartsEngine: ChartsEngine) => { req.body.widgetConfig = { ...req.body.widgetConfig, - enableMenuExport: embeddingInfo.embed.settings?.enableExport === true, + enableExport: embeddingInfo.embed.settings?.enableExport === true, }; return runnerFound.handler(ctx, { diff --git a/src/shared/types/charts.ts b/src/shared/types/charts.ts index 8d06874db1..406e87b8af 100644 --- a/src/shared/types/charts.ts +++ b/src/shared/types/charts.ts @@ -238,7 +238,7 @@ export type DashWidgetConfig = { enable?: boolean; fields?: string[]; }; - enableMenuExport?: boolean; + enableExport?: boolean; }; }; diff --git a/src/ui/components/Widgets/Chart/ChartWidget.tsx b/src/ui/components/Widgets/Chart/ChartWidget.tsx index b7fe3fd6d0..788ff1ffb9 100644 --- a/src/ui/components/Widgets/Chart/ChartWidget.tsx +++ b/src/ui/components/Widgets/Chart/ChartWidget.tsx @@ -15,7 +15,6 @@ import pick from 'lodash/pick'; import {useDispatch, useSelector} from 'react-redux'; import type {StringParams} from 'shared'; import {setWidgetCurrentTab} from 'ui/units/dash/store/actions/dashTyped'; -import {isEmbeddedEntry} from 'ui/utils/embedded'; import type {ChartKit} from '../../../libs/DatalensChartkit/ChartKit/ChartKit'; import {getDataProviderData} from '../../../libs/DatalensChartkit/components/ChartKitBase/helpers'; @@ -69,7 +68,7 @@ export const ChartWidget = (props: ChartWidgetProps) => { state, dataProvider, forwardedRef, - noControls = isEmbeddedEntry(), + noControls, nonBodyScroll, transformLoadedData, splitTooltip, diff --git a/src/ui/components/Widgets/Chart/components/Header.tsx b/src/ui/components/Widgets/Chart/components/Header.tsx index 1cb0fe1a84..c35e271d39 100644 --- a/src/ui/components/Widgets/Chart/components/Header.tsx +++ b/src/ui/components/Widgets/Chart/components/Header.tsx @@ -3,7 +3,6 @@ import React from 'react'; import block from 'bem-cn-lite'; import get from 'lodash/get'; import {useSelector} from 'react-redux'; -import {MenuItemsIds} from 'shared'; import type {StringParams} from 'shared'; import {ChartInfoIcon} from 'ui/components/Widgets/Chart/components/ChartInfoIcon'; import type {ChartKitDataProvider} from 'ui/libs/DatalensChartkit/components/ChartKitBase/types'; @@ -94,27 +93,7 @@ export const Header = (props: HeaderProps) => { */ const hideChartComments = Boolean((loadedData?.config as GraphWidget['config'])?.hideComments); - // exceptions that are shown forcibly under certain conditions - // when menu is not available - const {forceVisibleMenuConfig, hasForceVisibleItems} = React.useMemo(() => { - if (isMenuAvailable) { - return { - forceVisibleMenuConfig: {}, - hasForceVisibleItems: false, - }; - } - - const config = { - [MenuItemsIds.EXPORT]: loadedData?.widgetConfig?.enableMenuExport, - }; - - return { - forceVisibleMenuConfig: config, - hasForceVisibleItems: Object.values(config).some(Boolean), - }; - }, [loadedData?.widgetConfig?.enableMenuExport, isMenuAvailable]); - - const canBeShownMenu = (isMenuAvailable || hasForceVisibleItems) && widgetDataRef; + const canBeShownMenu = isMenuAvailable && widgetDataRef; const configMenu = menuType ? getChartkitMenu({ @@ -127,6 +106,7 @@ export const Header = (props: HeaderProps) => { onFullscreenClick, isEditAvaible, extraOptions: {enableActionParams}, + widgetConfig: loadedData?.widgetConfig, }) : settings.menu; @@ -171,8 +151,6 @@ export const Header = (props: HeaderProps) => { /* isWidgetMenuDataChanged - need this flag for extra rerender after widget rendered to check visibility of items (it is not used in component directly) */ isWidgetMenuDataChanged={isWidgetMenuDataChanged} chartsDataProvider={dataProvider} - forceVisibleMenuConfig={forceVisibleMenuConfig} - hasForceVisibleItems={hasForceVisibleItems} /> )} diff --git a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx index 9180bb61dc..0cf4ae8d21 100644 --- a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx +++ b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx @@ -269,8 +269,12 @@ export const getExportItem = ({ const isExportAllowed = !loadedData?.extra.dataExportForbidden; const isScreenshotVisible = loadedData?.data && showScreenshot; + const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; + return Boolean( - isExportAllowed && (isExportVisible({loadedData, error}) || isScreenshotVisible), + isVisible && + isExportAllowed && + (isExportVisible({loadedData, error}) || isScreenshotVisible), ); }, action: (data: ExportActionArgs) => { diff --git a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js index 511c4bf68e..4707bbca6a 100644 --- a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js +++ b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Menu.js @@ -53,8 +53,6 @@ export class Menu extends React.PureComponent { * but we need to toggle show/hide comments menu */ hideChartComments: PropTypes.bool, - forceVisibleMenuConfig: PropTypes.object, - hasForceVisibleItems: PropTypes.bool, }; state = { @@ -135,10 +133,6 @@ export class Menu extends React.PureComponent { if (!this.isVisibleItem({isVisible: item.isVisible, data})) { return null; } - const {forceVisibleMenuConfig, hasForceVisibleItems} = this.props; - if (hasForceVisibleItems && !forceVisibleMenuConfig[item.id]) { - return null; - } return {...item, items: visibleSubItems}; }; diff --git a/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx b/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx index b79cf495da..7b3caeea56 100644 --- a/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx +++ b/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx @@ -90,8 +90,11 @@ export const getAlertsMenuItem = ({ return false; } + const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; + return ( !isCriticalError && + isVisible && (loadedData.isNewWizard || loadedData.type === CHARTKIT_WIDGET_TYPE.GRAPH) ); }, @@ -137,7 +140,7 @@ export const getNewWindowMenuItem = ({ className={ICONS_MENU_DEFAULT_CLASSNAME} /> ), - isVisible: () => true, + isVisible: () => (customConfig?.isVisible ? customConfig.isVisible() : true), action: customConfig?.action || (({loadedData, propsData, chartsDataProvider: dataProvider}) => { @@ -207,7 +210,9 @@ export const getOpenAsTableMenuItem = ({ loadedData?.data && ([WidgetKind.Graph, WidgetKind.D3] as string[]).includes(loadedData?.type); - return Boolean(!isCriticalError && isExportAllowed && isChart); + const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; + + return Boolean(!isCriticalError && isVisible && isExportAllowed && isChart); }, action: customConfig?.action || @@ -237,7 +242,11 @@ export const getLinkMenuItem = (customConfig?: Partial): MenuIte className={ICONS_MENU_DEFAULT_CLASSNAME} /> ), - isVisible: ({loadedData}: MenuItemArgs) => Boolean(loadedData?.type), + isVisible: ({loadedData}: MenuItemArgs) => { + const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; + + return Boolean(isVisible && loadedData?.type); + }, action: customConfig?.action || function action({loadedData, propsData}) { @@ -278,7 +287,7 @@ export const getEmbeddedMenuItem = (customConfig?: Partial): Men icon: customConfig?.icon || ( ), - isVisible: () => true, + isVisible: () => (customConfig?.isVisible ? customConfig.isVisible() : true), action: customConfig?.action || function action({propsData, loadedData}) { @@ -316,8 +325,11 @@ export const getFullscreenMenuItem = (customConfig: Partial): Me const searchParams = new URLSearchParams(window.location.search); const isFullscreenMode = searchParams.has(FOCUSED_WIDGET_PARAM_NAME); + const isVisible = customConfig.isVisible ? customConfig.isVisible() : true; + return Boolean( - DL.IS_MOBILE && + isVisible && + DL.IS_MOBILE && loadedData && !error && !isWidgetTypeDoNotNeedOverlay(loadedData.type) && diff --git a/src/ui/registry/units/chart/types/functions/getChartkitMenuByType.ts b/src/ui/registry/units/chart/types/functions/getChartkitMenuByType.ts index 1f47e54afd..f801991771 100644 --- a/src/ui/registry/units/chart/types/functions/getChartkitMenuByType.ts +++ b/src/ui/registry/units/chart/types/functions/getChartkitMenuByType.ts @@ -8,6 +8,7 @@ export type GetChartkitMenuByType = GetChartkitMenuItems & { onFullscreenClick?: () => void; isEditAvaible?: boolean; extraOptions?: Record; + widgetConfig?: Record; }; export type GetChartkitMenuItems = { From b393c0bbd905bab5ddec962847ae7fd70ce3e634 Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Wed, 13 Nov 2024 14:25:54 +0300 Subject: [PATCH 3/5] Remove usage of customOptions --- .../components/Menu/Items/Export/Export.tsx | 6 +---- .../libs/DatalensChartkit/menu/MenuItems.tsx | 24 +++++-------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx index 0cf4ae8d21..9180bb61dc 100644 --- a/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx +++ b/src/ui/libs/DatalensChartkit/components/ChartKitBase/components/Header/components/Menu/Items/Export/Export.tsx @@ -269,12 +269,8 @@ export const getExportItem = ({ const isExportAllowed = !loadedData?.extra.dataExportForbidden; const isScreenshotVisible = loadedData?.data && showScreenshot; - const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; - return Boolean( - isVisible && - isExportAllowed && - (isExportVisible({loadedData, error}) || isScreenshotVisible), + isExportAllowed && (isExportVisible({loadedData, error}) || isScreenshotVisible), ); }, action: (data: ExportActionArgs) => { diff --git a/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx b/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx index 7b3caeea56..e83bbb28a0 100644 --- a/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx +++ b/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx @@ -90,11 +90,8 @@ export const getAlertsMenuItem = ({ return false; } - const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; - return ( !isCriticalError && - isVisible && (loadedData.isNewWizard || loadedData.type === CHARTKIT_WIDGET_TYPE.GRAPH) ); }, @@ -140,7 +137,7 @@ export const getNewWindowMenuItem = ({ className={ICONS_MENU_DEFAULT_CLASSNAME} /> ), - isVisible: () => (customConfig?.isVisible ? customConfig.isVisible() : true), + isVisible: () => true, action: customConfig?.action || (({loadedData, propsData, chartsDataProvider: dataProvider}) => { @@ -172,7 +169,7 @@ export const getEditMenuItem = ({ icon: customConfig?.icon || ( ), - isVisible: () => !DL.IS_MOBILE && (customConfig?.isVisible ? customConfig.isVisible() : true), + isVisible: () => !DL.IS_MOBILE, action: customConfig?.action || (({loadedData = {}, propsData, chartsDataProvider: dataProvider}) => { @@ -210,9 +207,7 @@ export const getOpenAsTableMenuItem = ({ loadedData?.data && ([WidgetKind.Graph, WidgetKind.D3] as string[]).includes(loadedData?.type); - const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; - - return Boolean(!isCriticalError && isVisible && isExportAllowed && isChart); + return Boolean(!isCriticalError && isExportAllowed && isChart); }, action: customConfig?.action || @@ -242,11 +237,7 @@ export const getLinkMenuItem = (customConfig?: Partial): MenuIte className={ICONS_MENU_DEFAULT_CLASSNAME} /> ), - isVisible: ({loadedData}: MenuItemArgs) => { - const isVisible = customConfig?.isVisible ? customConfig.isVisible() : true; - - return Boolean(isVisible && loadedData?.type); - }, + isVisible: ({loadedData}: MenuItemArgs) => Boolean(loadedData?.type), action: customConfig?.action || function action({loadedData, propsData}) { @@ -287,7 +278,7 @@ export const getEmbeddedMenuItem = (customConfig?: Partial): Men icon: customConfig?.icon || ( ), - isVisible: () => (customConfig?.isVisible ? customConfig.isVisible() : true), + isVisible: () => true, action: customConfig?.action || function action({propsData, loadedData}) { @@ -325,11 +316,8 @@ export const getFullscreenMenuItem = (customConfig: Partial): Me const searchParams = new URLSearchParams(window.location.search); const isFullscreenMode = searchParams.has(FOCUSED_WIDGET_PARAM_NAME); - const isVisible = customConfig.isVisible ? customConfig.isVisible() : true; - return Boolean( - isVisible && - DL.IS_MOBILE && + DL.IS_MOBILE && loadedData && !error && !isWidgetTypeDoNotNeedOverlay(loadedData.type) && From 4146df703760a12cbef3130ef1d1207913b911ad Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Wed, 13 Nov 2024 14:33:49 +0300 Subject: [PATCH 4/5] Support backward compatibility --- src/ui/constants/common.ts | 4 +++- .../DatalensChartkit/modules/data-provider/charts/index.ts | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ui/constants/common.ts b/src/ui/constants/common.ts index 2cc651ee79..36cc2d8604 100644 --- a/src/ui/constants/common.ts +++ b/src/ui/constants/common.ts @@ -228,11 +228,13 @@ export const DL = { get HIDE_NAVIGATION() { return window.DL.hideNavigation; }, + // TODO: delete get RUN_ENDPOINT() { return window.DL.runEndpoint || '/api/run'; }, + // TODO: add fallback get API_PREFIX() { - return window.DL.apiPrefix || '/api'; + return window.DL.apiPrefix; }, get CONNECTOR_ICONS() { return window.DL.connectorIcons || []; diff --git a/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts b/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts index 396b453622..551a1280d9 100644 --- a/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts +++ b/src/ui/libs/DatalensChartkit/modules/data-provider/charts/index.ts @@ -732,9 +732,12 @@ class ChartsDataProvider implements DataProvider Date: Wed, 13 Nov 2024 15:22:14 +0300 Subject: [PATCH 5/5] Fixes --- src/ui/libs/DatalensChartkit/menu/MenuItems.tsx | 2 +- src/ui/libs/DatalensChartkit/modules/export/export.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx b/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx index e83bbb28a0..b79cf495da 100644 --- a/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx +++ b/src/ui/libs/DatalensChartkit/menu/MenuItems.tsx @@ -169,7 +169,7 @@ export const getEditMenuItem = ({ icon: customConfig?.icon || ( ), - isVisible: () => !DL.IS_MOBILE, + isVisible: () => !DL.IS_MOBILE && (customConfig?.isVisible ? customConfig.isVisible() : true), action: customConfig?.action || (({loadedData = {}, propsData, chartsDataProvider: dataProvider}) => { diff --git a/src/ui/libs/DatalensChartkit/modules/export/export.js b/src/ui/libs/DatalensChartkit/modules/export/export.js index c4370d90aa..5c2546c475 100644 --- a/src/ui/libs/DatalensChartkit/modules/export/export.js +++ b/src/ui/libs/DatalensChartkit/modules/export/export.js @@ -41,7 +41,8 @@ const TABLE_DATE_FORMAT_BY_SCALE = { y: 'YYYY', }; -const API = `${DL.API_PREFIX}/export`; +//TODO: use only api_prefix +const API = DL.API_PREFIX ? `${DL.API_PREFIX}/export` : '/api/export'; function tableHeadToGraphs(head, prefix) { return head.reduce((result, column) => {