From 7897917ead1dd14dec393bc7007e7b0ef2561d0f Mon Sep 17 00:00:00 2001 From: vitshev Date: Tue, 3 Sep 2024 15:42:00 +0200 Subject: [PATCH] feat(Query): default ACO [#436] --- packages/ui/README.md | 21 ++++----- .../ui/src/shared/constants/settings-types.ts | 10 ++++- packages/ui/src/shared/yt-types.d.ts | 1 + .../SettingsPanel/settings-description.tsx | 7 +++ .../QueryACOSettingsMenuForm.scss | 12 +++++ .../QueryACOSettingsMenuForm.tsx | 44 +++++++++++++++++++ .../QueryACO/QueryACOSettingsMenu/index.ts | 1 + .../QueryResults/hooks/useCurrentQuery.ts | 6 ++- .../src/ui/pages/query-tracker/module/api.ts | 11 ++--- .../query-tracker/module/query/actions.ts | 24 ++++++---- .../query-tracker/module/query/selectors.ts | 24 +++++++--- .../query-tracker/module/query/utills.ts | 5 +-- .../query-tracker/module/query_aco/actions.ts | 19 +++++++- .../query-tracker/module/query_aco/reducer.ts | 2 + .../module/query_aco/selectors.ts | 28 +++++++++++- 15 files changed, 176 insertions(+), 39 deletions(-) create mode 100644 packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.scss create mode 100644 packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.tsx create mode 100644 packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/index.ts diff --git a/packages/ui/README.md b/packages/ui/README.md index 7a9fc88447..f25a10f834 100644 --- a/packages/ui/README.md +++ b/packages/ui/README.md @@ -81,16 +81,17 @@ It is supposed that a user is developer on a cluster if he has `write` access to Available flags (**default values** are highlighted in bold): -| Flag name | Allowed values | Description | -| :----------------------------------- | :----------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| enable_per_bundle_tablet_accounting | **true**, false | Allows editing of resources of tablets through BundleEditorDialog [YTFRONT-2851](https://nda.ya.ru/t/xnLq-3Dm6fPYPo) | -| enable_per_account_tablet_accounting | **false**, true | Allows editing of resources of tablets through AccountEditorDialog [YTFRONT-2851](https://nda.ya.ru/t/xnLq-3Dm6fPYPo) | -| per_bundle_accounting_help_link | **null**, url as string | Help link for resources of tablets to display from AccountEditorDialog about moving the resources to bundles [YTFRONT-2851](https://nda.ya.ru/t/xnLq-3Dm6fPYPo) | -| enable_maintenance_api_nodes | **null**, boolean | Allows to use `add_maintenance`/`remove_maintenance` commands from `Comopnents/Nodes` page [YTFRONT-3792](https://nda.ya.ru/t/RvueJLzN6fWx3h) | -| enable_maintenance_api_proxies | **null**, boolean | Allows to use `add_maintenance`/`remove_maintenance` commands from `Components/HTTP Proxies` and `Components/RPC Proxies` pages [YTFRONT-3792](https://nda.ya.ru/t/RvueJLzN6fWx3h) | -| chyt_controller_base_url | **null**, url as string | Base url for chyt-controller | -| livy_controller_base_url | **null**, url as string | Base url for spyt-controller | -| job_trace_url_template | **null**, `{title: string; url_template: string; enforce_for_trees?: Array}` | If defined adds `Job trace` item to meta-table on `Job/Details` page for a job with `archive_features/has_trace == true` and for jobs from a tree in `enforce_for_trees`, example: `{title: 'Open im MyProfiling', url_template: 'https://my.profiling.service/{cluster}/{operationId}/{jobId}', enforce_for_trees: ['tree-with-traces'] }` | +| Flag name | Allowed values | Description | +|:---------------------------------------|:-------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| enable_per_bundle_tablet_accounting | **true**, false | Allows editing of resources of tablets through BundleEditorDialog [YTFRONT-2851](https://nda.ya.ru/t/xnLq-3Dm6fPYPo) | +| enable_per_account_tablet_accounting | **false**, true | Allows editing of resources of tablets through AccountEditorDialog [YTFRONT-2851](https://nda.ya.ru/t/xnLq-3Dm6fPYPo) | +| per_bundle_accounting_help_link | **null**, url as string | Help link for resources of tablets to display from AccountEditorDialog about moving the resources to bundles [YTFRONT-2851](https://nda.ya.ru/t/xnLq-3Dm6fPYPo) | +| enable_maintenance_api_nodes | **null**, boolean | Allows to use `add_maintenance`/`remove_maintenance` commands from `Comopnents/Nodes` page [YTFRONT-3792](https://nda.ya.ru/t/RvueJLzN6fWx3h) | +| enable_maintenance_api_proxies | **null**, boolean | Allows to use `add_maintenance`/`remove_maintenance` commands from `Components/HTTP Proxies` and `Components/RPC Proxies` pages [YTFRONT-3792](https://nda.ya.ru/t/RvueJLzN6fWx3h) | +| chyt_controller_base_url | **null**, url as string | Base url for chyt-controller | +| livy_controller_base_url | **null**, url as string | Base url for spyt-controller | +| job_trace_url_template | **null**, `{title: string; url_template: string; enforce_for_trees?: Array}` | If defined adds `Job trace` item to meta-table on `Job/Details` page for a job with `archive_features/has_trace == true` and for jobs from a tree in `enforce_for_trees`, example: `{title: 'Open im MyProfiling', url_template: 'https://my.profiling.service/{cluster}/{operationId}/{jobId}', enforce_for_trees: ['tree-with-traces'] }` | +| query_tracker_default_aco | **null**, `{stage1: string; stage2: string; }` | Sets the default ACO in Query Tracker requests for each stage | ### Configuration diff --git a/packages/ui/src/shared/constants/settings-types.ts b/packages/ui/src/shared/constants/settings-types.ts index 1cfb29379d..bc7d83bad9 100644 --- a/packages/ui/src/shared/constants/settings-types.ts +++ b/packages/ui/src/shared/constants/settings-types.ts @@ -70,6 +70,7 @@ interface AccountsSettings { } type ClusterName = string; +type Stage = string; interface QueryTrackerSettings { 'global::queryTracker::queriesListSidebarVisibilityMode': boolean; @@ -81,7 +82,11 @@ interface ChytSettings { } type QueryTrackerLastSelectedACOsSettings = { - [key in `local::${ClusterName}::queryTracker::lastSelectedACOs`]: string[]; + [key in `qt-stage::${ClusterName}::queryTracker::${Stage}::lastSelectedACOs`]: string[]; +}; + +type QueryTrackerUserDefaultACOSettings = { + [key in `qt-stage::${ClusterName}::queryTracker::${Stage}::defaultACO`]: string; }; interface OtherSettings { @@ -113,7 +118,8 @@ type DescribedSettings = GlobalSettings & AccountsSettings & QueryTrackerSettings & ChytSettings & - QueryTrackerLastSelectedACOsSettings; + QueryTrackerLastSelectedACOsSettings & + QueryTrackerUserDefaultACOSettings; export type Settings = DescribedSettings & OtherSettings; diff --git a/packages/ui/src/shared/yt-types.d.ts b/packages/ui/src/shared/yt-types.d.ts index aff38f9e47..8eabb89c74 100644 --- a/packages/ui/src/shared/yt-types.d.ts +++ b/packages/ui/src/shared/yt-types.d.ts @@ -24,6 +24,7 @@ export interface ClusterUiConfig { enable_maintenance_api_proxies?: boolean; chyt_controller_base_url?: string; livy_controller_base_url?: string; + query_tracker_default_aco?: Record; job_trace_url_template?: { title: string; url_template: string; diff --git a/packages/ui/src/ui/containers/SettingsPanel/settings-description.tsx b/packages/ui/src/ui/containers/SettingsPanel/settings-description.tsx index 6eb50b9c40..48d0f7574d 100644 --- a/packages/ui/src/ui/containers/SettingsPanel/settings-description.tsx +++ b/packages/ui/src/ui/containers/SettingsPanel/settings-description.tsx @@ -53,6 +53,7 @@ import Link from '../../components/Link/Link'; import Button from '../../components/Button/Button'; import {AddTokenForm, VcsList} from '../../pages/query-tracker/Vcs/SettingsMenu'; import {selectIsVcsVisible, selectVcsConfig} from '../../pages/query-tracker/module/vcs/selectors'; +import {QueryACOSettingsMenuForm} from '../../pages/query-tracker/QueryACO/QueryACOSettingsMenu'; export interface SettingsPage { title: string; @@ -511,6 +512,12 @@ function useSettings(cluster: string, isAdmin: boolean): Array { ]), ), + makePage( + 'Query ACO', + undefined, + compact_([makeItem('Default ACO', undefined, )]), + ), + makePage( 'About', infoIcon, diff --git a/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.scss b/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.scss new file mode 100644 index 0000000000..3c85692f30 --- /dev/null +++ b/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.scss @@ -0,0 +1,12 @@ +.query-aco-settings-menu-form { + &__item { + display: flex; + align-items: center; + + margin-bottom: 12px; + + &-header { + margin: 0 8px 0 0; + } + } +} diff --git a/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.tsx b/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.tsx new file mode 100644 index 0000000000..7e43119040 --- /dev/null +++ b/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/QueryACOSettingsMenuForm.tsx @@ -0,0 +1,44 @@ +import React, {FC, useEffect, useMemo} from 'react'; +import {Item, SelectSingle} from '../../../../components/Select/Select'; +import {useDispatch, useSelector} from 'react-redux'; +import cn from 'bem-cn-lite'; +import {getDefaultQueryACO, selectAvailableAco} from '../../module/query_aco/selectors'; +import {getQueryACO, setUserDefaultACO} from '../../module/query_aco/actions'; + +import './QueryACOSettingsMenuForm.scss'; + +const block = cn('query-aco-settings-menu-form'); + +export const QueryACOSettingsMenuForm: FC = () => { + const dispatch = useDispatch(); + const defaultUserACO = useSelector(getDefaultQueryACO); + const ACOList = useSelector(selectAvailableAco); + + useEffect(() => { + dispatch(getQueryACO()); + }, [dispatch]); + + const items = useMemo(() => { + return ACOList.reduce((acc, item) => { + acc.push({value: item, text: item}); + return acc; + }, []); + }, [ACOList]); + + const handleACOChange = (value?: string) => { + if (value) { + dispatch(setUserDefaultACO(value)); + } + }; + + return ( +
+ +
+ ); +}; diff --git a/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/index.ts b/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/index.ts new file mode 100644 index 0000000000..316774505a --- /dev/null +++ b/packages/ui/src/ui/pages/query-tracker/QueryACO/QueryACOSettingsMenu/index.ts @@ -0,0 +1 @@ +export * from './QueryACOSettingsMenuForm'; diff --git a/packages/ui/src/ui/pages/query-tracker/QueryResults/hooks/useCurrentQuery.ts b/packages/ui/src/ui/pages/query-tracker/QueryResults/hooks/useCurrentQuery.ts index a9274a8049..2e70625651 100644 --- a/packages/ui/src/ui/pages/query-tracker/QueryResults/hooks/useCurrentQuery.ts +++ b/packages/ui/src/ui/pages/query-tracker/QueryResults/hooks/useCurrentQuery.ts @@ -3,6 +3,7 @@ import {useDispatch, useSelector} from 'react-redux'; import {QueriesPoolingContext} from '../../hooks/QueriesPooling/context'; import {getCurrentQuery} from '../../module/query/selectors'; +import {getDefaultQueryACO} from '../../module/query_aco/selectors'; import {isQueryProgress} from '../../utils/query'; import {QueryItem} from '../../module/api'; import {prepareQueryPlanIds} from '../../module/query/utills'; @@ -10,6 +11,7 @@ import {UPDATE_QUERY} from '../../../../pages/query-tracker/module/query-tracker export function useCurrentQuery() { const query = useSelector(getCurrentQuery); + const defaultQueryACO = useSelector(getDefaultQueryACO); const pollingContext = useContext(QueriesPoolingContext); const dispatch = useDispatch(); @@ -19,10 +21,10 @@ export function useCurrentQuery() { ([item]: QueryItem[]) => { dispatch({ type: UPDATE_QUERY, - data: prepareQueryPlanIds(item), + data: prepareQueryPlanIds(item, defaultQueryACO), }); }, - [dispatch], + [dispatch, defaultQueryACO], ); useEffect( diff --git a/packages/ui/src/ui/pages/query-tracker/module/api.ts b/packages/ui/src/ui/pages/query-tracker/module/api.ts index 5ebcb3efc9..1177acec07 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/api.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/api.ts @@ -10,8 +10,8 @@ import {getClusterConfigByName, getClusterProxy} from '../../../store/selectors/ import {generateQuerySettings, generateQueryText} from '../utils/query_generate'; import {RootState} from '../../../store/reducers'; import {makeDirectDownloadPath} from '../../../utils/navigation'; -import {DEFAULT_QUERY_ACO, getQueryTrackerRequestOptions} from './query/selectors'; import {QueriesHistoryCursorDirection, UPDATE_QUERIES_LIST} from './query-tracker-contants'; +import {getCurrentStage, getQueryTrackerRequestOptions} from './query/selectors'; import {AnyAction} from 'redux'; import {QueryEngine} from './engines'; import {getLastSelectedACONamespaces, selectIsMultipleAco} from './query_aco/selectors'; @@ -212,7 +212,7 @@ export type QueriesListRequestParams = { export async function generateQueryFromTable( engine: QueryEngine, - {cluster, path}: {cluster: string; path: string}, + {cluster, path, defaultQueryACO}: {cluster: string; path: string; defaultQueryACO: string}, ): Promise { const selectedCluster = getClusterConfigByName(cluster); const node = await ytApiV3.get({ @@ -239,8 +239,8 @@ export async function generateQueryFromTable( }), files: [], annotations: {}, - access_control_object: DEFAULT_QUERY_ACO, - access_control_objects: [DEFAULT_QUERY_ACO], + access_control_object: defaultQueryACO, + access_control_objects: [defaultQueryACO], settings: generateQuerySettings(engine, cluster), }; } @@ -573,9 +573,10 @@ export function addACOToLastSelected( const state = getState(); const cluster = state.global.cluster; const lastSelectedACONamespaces = getLastSelectedACONamespaces(state); + const stage = getCurrentStage(state); await dispatch( - setSettingByKey(`local::${cluster}::queryTracker::lastSelectedACOs`, [ + setSettingByKey(`qt-stage::${cluster}::queryTracker::${stage}::lastSelectedACOs`, [ ...aco, ...lastSelectedACONamespaces.filter((item) => !aco.includes(item)).slice(0, 9), ]), diff --git a/packages/ui/src/ui/pages/query-tracker/module/query/actions.ts b/packages/ui/src/ui/pages/query-tracker/module/query/actions.ts index d0417fb7e0..66b6f239e3 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/query/actions.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/query/actions.ts @@ -15,7 +15,6 @@ import { } from '../api'; import {requestQueriesList} from '../queries_list/actions'; import { - DEFAULT_QUERY_ACO, SHARED_QUERY_ACO, getCurrentQuery, getQueryDraft, @@ -37,8 +36,8 @@ import {wrapApiPromiseByToaster} from '../../../../utils/utils'; import {prepareQueryPlanIds} from './utills'; import {chytApiAction, spytApiAction} from '../../../../utils/strawberryControllerApi'; import guid from '../../../../common/hammer/guid'; -import {selectIsMultipleAco} from '../query_aco/selectors'; import {getSettingQueryTrackerStage} from '../../../../store/selectors/settings-ts'; +import {getDefaultQueryACO, selectIsMultipleAco} from '../query_aco/selectors'; import { REQUEST_QUERY, @@ -128,7 +127,8 @@ export function loadQuery( }); query.files = query.files.map((file) => ({...file, id: guid()})); - const queryItem = prepareQueryPlanIds(query); + const defaultQueryACO = getDefaultQueryACO(state); + const queryItem = prepareQueryPlanIds(query, defaultQueryACO); if (config?.dontReplaceQueryText) { queryItem.query = state.queryTracker.query.draft.query; @@ -168,11 +168,13 @@ export function createQueryFromTablePath( | UpdateQueryAction | SetQueryReadyAction > { - return async (dispatch) => { + return async (dispatch, getState) => { dispatch({type: REQUEST_QUERY}); try { + const state = getState(); + const defaultQueryACO = getDefaultQueryACO(state); const draft = await wrapApiPromiseByToaster( - generateQueryFromTable(engine, {cluster, path}), + generateQueryFromTable(engine, {cluster, path, defaultQueryACO}), { toasterName: 'load_query', skipSuccessToast: true, @@ -208,11 +210,16 @@ export function createEmptyQuery( query?: string, settings?: Record, ): ThunkAction { - return (dispatch) => { + return (dispatch, getState) => { + const state = getState(); + const defaultQueryACO = getDefaultQueryACO(state); + dispatch({ type: SET_QUERY, data: { initialQuery: { + access_control_object: defaultQueryACO, + access_control_objects: [defaultQueryACO], query: query || '', engine, settings: settings || {}, @@ -335,11 +342,12 @@ export const toggleShareQuery = const query = selectQuery(state); if (!query) return; - let aco = query.access_control_objects || [DEFAULT_QUERY_ACO]; + const defaultQueryACO = getDefaultQueryACO(state); + let aco = query.access_control_objects || [defaultQueryACO]; if (aco.includes(SHARED_QUERY_ACO)) { aco = aco.filter((i) => i !== SHARED_QUERY_ACO); - if (!aco.length) aco = [DEFAULT_QUERY_ACO]; + if (!aco.length) aco = [defaultQueryACO]; } else { aco = [...aco, SHARED_QUERY_ACO]; } diff --git a/packages/ui/src/ui/pages/query-tracker/module/query/selectors.ts b/packages/ui/src/ui/pages/query-tracker/module/query/selectors.ts index 0b56b6caf4..f8cede9f47 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/query/selectors.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/query/selectors.ts @@ -11,7 +11,7 @@ import {QTEditorError} from '../types/editor'; import {YTError} from '../../../../types'; import {isYTError} from '../../../../../shared/utils'; import {getQueryResults} from '../query_result/selectors'; -import {selectIsMultipleAco} from '../query_aco/selectors'; +import {getDefaultQueryACO, selectIsMultipleAco} from '../query_aco/selectors'; const QT_STAGE = getQueryTrackerStage(); const getState = (state: RootState) => state.queryTracker.query; @@ -101,18 +101,30 @@ export const getQueryEditorErrors = (state: RootState): QTEditorError[] => { export const getDirtySinceLastSubmit = (state: RootState) => state.queryTracker.query.dirtySinceLastSubmit; -const getAco = (isMultipleAco: boolean, state?: QueryItem | DraftQuery): string[] => { - if (isMultipleAco) return state?.access_control_objects ?? [DEFAULT_QUERY_ACO]; +export const getCurrentStage = (state: RootState) => { + return state.queryTracker?.aco?.data?.query_tracker_stage ?? 'production'; +}; + +const getAco = ( + defaultACO: string, + isMultipleAco: boolean, + state?: QueryItem | DraftQuery, +): string[] => { + if (isMultipleAco) return state?.access_control_objects ?? [defaultACO]; - return state?.access_control_object ? [state?.access_control_object] : [DEFAULT_QUERY_ACO]; + return state?.access_control_object ? [state?.access_control_object] : [defaultACO]; }; export const getCurrentQueryACO = (state: RootState) => { - return getAco(selectIsMultipleAco(state), state.queryTracker.query?.queryItem); + const defaultACO = getDefaultQueryACO(state); + + return getAco(defaultACO, selectIsMultipleAco(state), state.queryTracker.query?.queryItem); }; export const getCurrentDraftQueryACO = (state: RootState) => { - return getAco(selectIsMultipleAco(state), state.queryTracker.query?.draft); + const defaultACO = getDefaultQueryACO(state); + + return getAco(defaultACO, selectIsMultipleAco(state), state.queryTracker.query?.draft); }; export const getProgressYQLStatistics = (state: RootState) => { diff --git a/packages/ui/src/ui/pages/query-tracker/module/query/utills.ts b/packages/ui/src/ui/pages/query-tracker/module/query/utills.ts index cf26d1bdd4..78801be800 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/query/utills.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/query/utills.ts @@ -1,6 +1,5 @@ import omit_ from 'lodash/omit'; import {QueryItem} from '../api'; -import {DEFAULT_QUERY_ACO} from './selectors'; export const cleanupQueryForDraft = (query: QueryItem): QueryItem => { return { @@ -9,7 +8,7 @@ export const cleanupQueryForDraft = (query: QueryItem): QueryItem => { }; }; -export const prepareQueryPlanIds = (query: QueryItem): QueryItem => { +export const prepareQueryPlanIds = (query: QueryItem, defaultQueryACO: string): QueryItem => { const nodes = query.progress?.yql_plan?.Basic.nodes; const links = query.progress?.yql_plan?.Basic.links; const operations = query.progress?.yql_plan?.Detailed?.Operations; @@ -34,7 +33,7 @@ export const prepareQueryPlanIds = (query: QueryItem): QueryItem => { } if (!query.access_control_objects) { - query.access_control_objects = [DEFAULT_QUERY_ACO]; + query.access_control_objects = [defaultQueryACO]; } return query; diff --git a/packages/ui/src/ui/pages/query-tracker/module/query_aco/actions.ts b/packages/ui/src/ui/pages/query-tracker/module/query_aco/actions.ts index 34f7ed15f9..b485d523cd 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/query_aco/actions.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/query_aco/actions.ts @@ -1,11 +1,14 @@ +import {AnyAction} from 'redux'; import {ThunkAction} from 'redux-thunk'; import {Toaster} from '@gravity-ui/uikit'; import type {AxiosError} from 'axios'; import {YTApiId, ytApiV4Id} from '../../../../rum/rum-wrap-api'; -import {getQueryTrackerRequestOptions} from '../query/selectors'; +import {getCurrentStage, getQueryTrackerRequestOptions} from '../query/selectors'; import {QUERY_ACO_LOADING} from './constants'; import {showErrorPopup} from '../../../../utils/utils'; import {QueryACOActions} from './reducer'; +import {RootState} from '../../../../store/reducers'; +import {setSettingByKey} from '../../../../store/actions/settings'; export const getQueryACO = (): ThunkAction, any, any, QueryACOActions> => { return (dispatch, getState) => { @@ -61,3 +64,17 @@ export const getQueryACO = (): ThunkAction, any, any, QueryACOA }); }; }; + +export function setUserDefaultACO( + aco: string, +): ThunkAction, RootState, any, AnyAction> { + return async (dispatch, getState) => { + const state = getState(); + const cluster = state.global.cluster; + const stage = getCurrentStage(state); + + await dispatch( + setSettingByKey(`qt-stage::${cluster}::queryTracker::${stage}::defaultACO`, aco), + ); + }; +} diff --git a/packages/ui/src/ui/pages/query-tracker/module/query_aco/reducer.ts b/packages/ui/src/ui/pages/query-tracker/module/query_aco/reducer.ts index dedcad7879..1d405ae487 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/query_aco/reducer.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/query_aco/reducer.ts @@ -6,6 +6,7 @@ export interface QueryACOState { data: { cluster_name: string; access_control_objects: string[]; + query_tracker_stage: string; supported_features: {access_control: boolean; multiple_aco?: boolean}; }; loading: boolean; @@ -17,6 +18,7 @@ const initialState: QueryACOState = { data: { cluster_name: '', access_control_objects: [], + query_tracker_stage: 'production', supported_features: { access_control: false, }, diff --git a/packages/ui/src/ui/pages/query-tracker/module/query_aco/selectors.ts b/packages/ui/src/ui/pages/query-tracker/module/query_aco/selectors.ts index 8e72ed8db4..e22cbbd926 100644 --- a/packages/ui/src/ui/pages/query-tracker/module/query_aco/selectors.ts +++ b/packages/ui/src/ui/pages/query-tracker/module/query_aco/selectors.ts @@ -3,13 +3,19 @@ import {SelectOption} from '@gravity-ui/uikit/build/esm/components/Select/types' import {RootState} from '../../../../store/reducers'; import {getSettingsData} from '../../../../store/selectors/settings-base'; import {createSelector} from 'reselect'; -import {SHARED_QUERY_ACO} from '../query/selectors'; +import {DEFAULT_QUERY_ACO, SHARED_QUERY_ACO, getCurrentStage} from '../query/selectors'; +import {getClusterUiConfig} from '../../../../store/selectors/global'; +import get_ from 'lodash/get'; const selectAcoState = (state: RootState) => state.queryTracker.aco; export const getLastSelectedACONamespaces = (state: RootState) => { const cluster = state.global.cluster; + const stage = getCurrentStage(state); - return getSettingsData(state)[`local::${cluster}::queryTracker::lastSelectedACOs`] ?? []; + return ( + getSettingsData(state)[`qt-stage::${cluster}::queryTracker::${stage}::lastSelectedACOs`] ?? + [] + ); }; export const getQueryACOOptions = (state: RootState): SelectOption[] => { @@ -42,3 +48,21 @@ export const isSupportedShareQuery = createSelector( return isMultipleAco && aco.includes(SHARED_QUERY_ACO); }, ); + +export const getClusterDefaultQueryACO = (state: RootState) => { + const queryTrackerDefaultACO = getClusterUiConfig(state)?.query_tracker_default_aco; + const stage = getCurrentStage(state); + + return get_(queryTrackerDefaultACO, stage, DEFAULT_QUERY_ACO); +}; + +export const getUserDefaultQueryACO = (state: RootState) => { + const cluster = state.global.cluster; + const stage = getCurrentStage(state); + + return getSettingsData(state)[`qt-stage::${cluster}::queryTracker::${stage}::defaultACO`]; +}; + +export const getDefaultQueryACO = (state: RootState) => { + return getUserDefaultQueryACO(state) ?? getClusterDefaultQueryACO(state); +};