From 16a5bb7666ab2db1ebdbfe3708e071d485c08503 Mon Sep 17 00:00:00 2001 From: Elena Martynova Date: Mon, 13 Nov 2023 19:09:14 +0300 Subject: [PATCH] Add loading dash entries datasets --- src/ui/units/dash/store/actions/dash.js | 11 ++- src/ui/units/dash/store/actions/dashTyped.ts | 75 +++++++++++++++++++ src/ui/units/dash/store/actions/index.ts | 2 + .../dash/store/reducers/dashTypedReducer.ts | 4 + 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/ui/units/dash/store/actions/dash.js b/src/ui/units/dash/store/actions/dash.js index 23b7b362c5..3807e6b1c9 100644 --- a/src/ui/units/dash/store/actions/dash.js +++ b/src/ui/units/dash/store/actions/dash.js @@ -18,7 +18,7 @@ import {collectDashStats} from '../../modules/pushStats'; import * as actionTypes from '../constants/dashActionTypes'; import {getFakeDashEntry} from '../utils'; -import {SET_ERROR_MODE, SET_STATE, toggleTableOfContent} from './dashTyped'; +import {SET_ERROR_MODE, SET_STATE, loadDashDatasets, toggleTableOfContent} from './dashTyped'; import { DOES_NOT_EXIST_ERROR_TEXT, NOT_FOUND_ERROR_TEXT, @@ -291,6 +291,13 @@ export const setEditMode = (successCallback = () => {}, failCallback = () => {}) export const cleanLock = () => ({type: SET_STATE, payload: {lockToken: null}}); +/** + * Loading dash data: dash config from us, dash state from us, and in parallel all datasets schemas, which is used in dash items + * @param location + * @param history + * @param params + * @returns {(function(*): Promise)|*} + */ export const load = ({location, history, params}) => { // eslint-disable-next-line complexity return async function (dispatch) { @@ -451,6 +458,8 @@ export const load = ({location, history, params}) => { if (mode === Mode.Edit) { await dispatch(setEditMode()); } + + dispatch(loadDashDatasets(entry, tabId)); } catch (error) { logger.logError('load dash failed', error); diff --git a/src/ui/units/dash/store/actions/dashTyped.ts b/src/ui/units/dash/store/actions/dashTyped.ts index 679b163e9a..0bb278691a 100644 --- a/src/ui/units/dash/store/actions/dashTyped.ts +++ b/src/ui/units/dash/store/actions/dashTyped.ts @@ -6,17 +6,22 @@ import {PluginTitleProps} from '@gravity-ui/dashkit/build/esm/plugins/Title/Titl import {i18n} from 'i18n'; import {DatalensGlobalState, URL_QUERY, sdk} from 'index'; import isEmpty from 'lodash/isEmpty'; +import uniq from 'lodash/uniq'; import {Dispatch} from 'redux'; import { DATASET_FIELD_TYPES, DashData, DashTabItem, + DashTabItemControlDataset, DashTabItemControlSourceType, + DashTabItemType, Dataset, DatasetFieldType, EntryUpdateMode, Operations, } from 'shared'; +import {GetEntriesDatasetsFieldsItem} from 'shared/schema'; +import {DashState} from 'ui/units/dash/store/reducers/dashTypedReducer'; import {validateParamTitleOnlyUnderscore} from 'units/dash/components/ParamsSettings/helpers'; import {ELEMENT_TYPE} from 'units/dash/containers/Dialogs/Control/constants'; import {addOperationForValue} from 'units/dash/modules/helpers'; @@ -884,3 +889,73 @@ export const setSkipReload = (skipReload: boolean): SetSkipReloadAction => ({ type: SET_SKIP_RELOAD, payload: skipReload, }); +export const SET_DASH_DS_FIELDS = Symbol('dash/SET_DASH_DS_FIELDS'); +export type SetDashDSAction = { + type: typeof SET_DASH_DS_FIELDS; + payload: {datasetsFields: GetEntriesDatasetsFieldsItem[]}; +}; +export const setDashDatasets = (data: SetDashDSAction['payload']): SetDashDSAction => ({ + type: SET_DASH_DS_FIELDS, + payload: data, +}); + +const LOAD_DASH_DATASETS_CONCURRENT_ID = 'dashLoadDatasets'; + +/** + * Do not wait for the answer when call this function: + * this data will be needed later, not immediately after loading dash + * @param entry + * @param tabId + */ +export function loadDashDatasets(entry: Partial, tabId: string) { + return async function (dispatch: DashDispatch, _getState: () => DatalensGlobalState) { + const tabs = entry.data?.tabs || []; + if (!tabs.length) { + return; + } + + const tabIndex = tabs.findIndex((item) => item.id === tabId); + + if (tabIndex === -1) { + return; + } + + const dashTabItems = tabs[tabIndex].items || []; + if (!dashTabItems.length) { + return; + } + let datasetsIds: string[] = []; + let entriesIds: string[] = []; + dashTabItems.forEach((dashItem) => { + if ( + dashItem.type === DashTabItemType.Control && + dashItem.data.sourceType === DashTabItemControlSourceType.Dataset + ) { + const dataSource = dashItem.data.source as DashTabItemControlDataset['source']; + if (dataSource.datasetId) { + datasetsIds.push(dataSource.datasetId); + } + } else if (dashItem.type === DashTabItemType.Widget) { + const chartData = dashItem.data; + const widgetChartIds = chartData.tabs.map((chartTabItem) => chartTabItem.chartId); + entriesIds = entriesIds.concat(widgetChartIds); + } + }); + datasetsIds = uniq(datasetsIds); + entriesIds = uniq(entriesIds); + + if (isEmpty(datasetsIds) && isEmpty(entriesIds)) { + return; + } + + const entriesDatasetsFields = await getSdk().mix.getEntriesDatasetsFields( + { + entriesIds, + datasetsIds, + }, + {concurrentId: LOAD_DASH_DATASETS_CONCURRENT_ID}, + ); + + dispatch(setDashDatasets({datasetsFields: entriesDatasetsFields})); + }; +} diff --git a/src/ui/units/dash/store/actions/index.ts b/src/ui/units/dash/store/actions/index.ts index 7e07053100..9d93cff809 100644 --- a/src/ui/units/dash/store/actions/index.ts +++ b/src/ui/units/dash/store/actions/index.ts @@ -8,6 +8,7 @@ import { ChangeNavigationPathAction, SetAccessDescriptionAction, SetActiveSelectorIndexAction, + SetDashDSAction, SetDashKeyAction, SetDashKitRefAction, SetDashUpdateStatusAction, @@ -59,6 +60,7 @@ export type DashAction = | SetLoadingEditModeAction | EntryContentAction | SetDashUpdateStatusAction + | SetDashDSAction | SetNewRelationsAction | SetDashKeyAction | SetRenameWithoutReloadAction diff --git a/src/ui/units/dash/store/reducers/dashTypedReducer.ts b/src/ui/units/dash/store/reducers/dashTypedReducer.ts index 64e698e8d9..23342ba548 100644 --- a/src/ui/units/dash/store/reducers/dashTypedReducer.ts +++ b/src/ui/units/dash/store/reducers/dashTypedReducer.ts @@ -4,6 +4,7 @@ import {DashKit} from '@gravity-ui/dashkit'; import update from 'immutability-helper'; import {cloneDeep, pick} from 'lodash'; import {DashData, DashEntry, WidgetType} from 'shared'; +import {GetEntriesDatasetsFieldsItem} from 'shared/schema'; import {Mode} from '../../modules/constants'; import {DashUpdateStatus} from '../../typings/dash'; @@ -15,6 +16,7 @@ import { SET_DASH_ACCESS_DESCRIPTION, SET_DASH_DESCRIPTION, SET_DASH_DESC_VIEW_MODE, + SET_DASH_DS_FIELDS, SET_DASH_KEY, SET_DASH_SUPPORT_DESCRIPTION, SET_DASH_UPDATE_STATUS, @@ -72,6 +74,7 @@ export type DashState = { isRenameWithoutReload?: boolean; skipReload?: boolean; openedItemWidgetType?: WidgetType; + datasetsFields: GetEntriesDatasetsFieldsItem[]; }; // eslint-disable-next-line complexity @@ -85,6 +88,7 @@ export function dashTypedReducer( case SET_STATE: case SET_PAGE_TAB: case CHANGE_NAVIGATION_PATH: + case SET_DASH_DS_FIELDS: case SET_DASHKIT_REF: { return {...state, ...action.payload}; }