Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {Feature} from '../../../../shared';
import {createFeatureConfig} from '../utils';

export default createFeatureConfig({
name: Feature.EnableGlobalSelectors,
state: {
development: true,
production: false,
},
});
26 changes: 23 additions & 3 deletions src/server/components/sdk/dash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ function validateData(data: DashData) {
return true;
};

data.tabs.forEach(({id: tabId, title: tabTitle, items, layout, connections}) => {
data.tabs.forEach(({id: tabId, title: tabTitle, items, layout, connections, globalItems}) => {
const currentItemsIds: Set<string> = new Set();
const currentWidgetTabsIds: Set<string> = new Set();
const currentControlsIds: Set<string> = new Set();
Expand All @@ -165,6 +165,24 @@ function validateData(data: DashData) {
allTabsIds.add(tabId);
}

if (globalItems) {
globalItems.forEach(({id: itemId, type, data}) => {
allItemsIds.add(itemId);
currentItemsIds.add(itemId);

if (type === DashTabItemType.Control || type === DashTabItemType.GroupControl) {
// if it is group control all connections set on its items
if ('group' in data) {
data.group.forEach((widgetItem) => {
currentControlsIds.add(widgetItem.id);
});
} else {
currentControlsIds.add(itemId);
}
}
});
}

items.forEach(({id: itemId, type, data}) => {
if (isIdUniq(itemId)) {
allItemsIds.add(itemId);
Expand All @@ -190,10 +208,12 @@ function validateData(data: DashData) {
}
});

const allItemsLength = items.length + (globalItems?.length ?? 0);

// checking that layout has all the ids from item, i.e. positions are set for all elements
if (
items.length !== layout.length ||
items.length !==
allItemsLength !== layout.length ||
allItemsLength !==
intersection(
Array.from(currentItemsIds),
layout.map(({i}) => i),
Expand Down
2 changes: 2 additions & 0 deletions src/shared/constants/dash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ export const DASH_DATA_REQUIRED_FIELDS: Array<keyof DashData> = [
'tabs',
'settings',
];

export const TABS_SCOPE_ALL = 'all' as const;
6 changes: 6 additions & 0 deletions src/shared/types/dash.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type {ItemDropProps} from '@gravity-ui/dashkit';

import type {TABS_SCOPE_ALL} from '../constants/dash';
import type {Operations} from '../modules';

export type TabsScope = typeof TABS_SCOPE_ALL | string | string[] | undefined;

import type {
ClientChartsConfig,
Dictionary,
Expand Down Expand Up @@ -125,6 +128,7 @@ export interface DashTab {
aliases: DashTabAliases;
connections: DashTabConnection[];
settings?: DashTabSettings;
globalItems?: DashTabItem[];
}

export type DashSettingsGlobalParams = Record<string, string | string[]>;
Expand Down Expand Up @@ -232,6 +236,7 @@ export interface DashTabItemControlData {
width?: string;
defaults?: StringParams;
namespace: string;
tabsScope?: TabsScope;
}

export type DashTabItemControlSingle = DashTabItemControlDataset | DashTabItemControlManual;
Expand Down Expand Up @@ -339,6 +344,7 @@ export interface DashTabItemGroupControlData {
autoHeight: boolean;
buttonApply: boolean;
buttonReset: boolean;
tabsScope?: TabsScope;

updateControlsOnChange?: boolean;

Expand Down
2 changes: 2 additions & 0 deletions src/shared/types/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export enum Feature {

EnableMobileFixedHeader = 'EnableMobileFixedHeader',
EnableCommonChartDashSettings = 'EnableCommonChartDashSettings',
/** Enable a setting in the Selector settings dialog that allows you to make the selector pass-through for all or several tabs */
EnableGlobalSelectors = 'EnableGlobalSelectors',
/** Shows updated settings page */
EnableNewServiceSettings = 'EnableNewServiceSettings',
}
Expand Down
2 changes: 2 additions & 0 deletions src/shared/zod-schemas/dash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const controlSchema = z
namespace: z.literal(DASH_DEFAULT_NAMESPACE),
title: z.string().min(1),
sourceType: z.enum(DashTabItemControlSourceType),
tabsScope: z.union([z.string(), z.array(z.string())]).optional(),
})
.and(
z.discriminatedUnion('sourceType', [
Expand Down Expand Up @@ -147,6 +148,7 @@ const groupControlItemsSchema = z
defaults: z.record(z.any(), z.any()),
placementMode: z.enum(CONTROLS_PLACEMENT_MODE).optional(),
width: z.string().optional(),
tabsScope: z.union([z.string(), z.array(z.string())]).optional(),
})
.and(
z.discriminatedUnion('sourceType', [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,64 @@ import React from 'react';
import {I18n} from 'i18n';
import {useSelector} from 'react-redux';
import {DashTabItemControlSourceType} from 'shared';
import {selectSelectorDialog} from 'ui/store/selectors/controlDialog';
import {selectSelectorDialog, selectSelectorsGroup} from 'ui/store/selectors/controlDialog';

import {ConnectionSettings} from './ConnectionSettings/ConnectionSettings';
import {DatasetSelector} from './DatasetSelector/DatasetSelector';
import {ExternalSelectorSettings} from './ExternalSelectorSettings/ExternalSelectorSettings';
import {DatasetSelectorSettings} from './DatasetSelectorSettings/DatasetSelectorSettings';
import {ParameterNameInput} from './ParameterNameInput/ParameterNameInput';
import {TabsScopeSelect} from './TabsScopeSelect/TabsScopeSelect';

const i18n = I18n.keyset('dash.control-dialog.edit');

export const CommonSettingsSection = ({
export const CommonGroupSettingsSection = ({
navigationPath,
changeNavigationPath,
enableAutoheightDefault,
enableGlobalSelectors,
className,
}: {
navigationPath: string | null;
changeNavigationPath: (newNavigationPath: string) => void;
enableAutoheightDefault?: boolean;
enableGlobalSelectors?: boolean;
className?: string;
}) => {
const {sourceType} = useSelector(selectSelectorDialog);
const {group, tabsScope} = useSelector(selectSelectorsGroup);

const hasMultipleSelectors = group.length > 1;

switch (sourceType) {
case DashTabItemControlSourceType.External:
return (
<ExternalSelectorSettings
rowClassName={className}
changeNavigationPath={changeNavigationPath}
navigationPath={navigationPath}
enableAutoheightDefault={enableAutoheightDefault}
/>
);
case DashTabItemControlSourceType.Manual:
return (
<ParameterNameInput
label={i18n('field_field-name')}
note={i18n('field_field-name-note')}
className={className}
/>
<React.Fragment>
<ParameterNameInput
label={i18n('field_field-name')}
note={i18n('field_field-name-note')}
className={className}
/>
{enableGlobalSelectors && (
<TabsScopeSelect
groupTabsScope={tabsScope}
hasMultipleSelectors={hasMultipleSelectors}
/>
)}
</React.Fragment>
);
case DashTabItemControlSourceType.Connection:
return (
<ConnectionSettings
rowClassName={className}
changeNavigationPath={changeNavigationPath}
navigationPath={navigationPath}
enableGlobalSelectors={enableGlobalSelectors}
/>
);
default:
return (
<DatasetSelector
<DatasetSelectorSettings
rowClassName={className}
navigationPath={navigationPath}
changeNavigationPath={changeNavigationPath}
enableGlobalSelectors={enableGlobalSelectors}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import React from 'react';

import {I18n} from 'i18n';
import {useSelector} from 'react-redux';
import {selectSelectorDialog} from 'ui/store/selectors/controlDialog';
import {selectSelectorDialog, selectSelectorsGroup} from 'ui/store/selectors/controlDialog';

import {ParameterNameInput} from '../ParameterNameInput/ParameterNameInput';
import {TabsScopeSelect} from '../TabsScopeSelect/TabsScopeSelect';

import {ConnectionSelector} from './components/ConnectionSelector/ConnectionSelector';
import {QueryTypeControl} from './components/QueryTypeControl/QueryTypeControl';
Expand All @@ -15,12 +16,15 @@ export const ConnectionSettings = ({
navigationPath,
changeNavigationPath,
rowClassName,
enableGlobalSelectors,
}: {
navigationPath: string | null;
changeNavigationPath: (newNavigationPath: string) => void;
rowClassName?: string;
enableGlobalSelectors?: boolean;
}) => {
const {connectionQueryTypes} = useSelector(selectSelectorDialog);
const {tabsScope, group} = useSelector(selectSelectorsGroup);

return (
<React.Fragment>
Expand All @@ -38,6 +42,12 @@ export const ConnectionSettings = ({
<QueryTypeControl connectionQueryTypes={connectionQueryTypes} />
</React.Fragment>
)}
{enableGlobalSelectors && (
<TabsScopeSelect
groupTabsScope={tabsScope}
hasMultipleSelectors={group.length > 1}
/>
)}
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,32 @@ import {
import logger from 'ui/libs/logger';
import {setLastUsedDatasetId, setSelectorDialogItem} from 'ui/store/actions/controlDialog';
import {ELEMENT_TYPE} from 'ui/store/constants/controlDialog';
import {selectOpenedItemMeta, selectSelectorDialog} from 'ui/store/selectors/controlDialog';
import {
selectOpenedItemMeta,
selectSelectorDialog,
selectSelectorsGroup,
} from 'ui/store/selectors/controlDialog';
import type {SelectorElementType, SetSelectorDialogItemArgs} from 'ui/store/typings/controlDialog';

import {DatasetField} from '../../Switchers/DatasetField/DatasetField';
import {EntrySelector} from '../EntrySelector/EntrySelector';
import {TabsScopeSelect} from '../TabsScopeSelect/TabsScopeSelect';

const i18n = I18n.keyset('dash.control-dialog.edit');

const getDatasetLink = (entryId: string) => `/datasets/${entryId}`;

function DatasetSelector(props: {
function DatasetSelectorSettings(props: {
navigationPath: string | null;
changeNavigationPath: (newNavigationPath: string) => void;
rowClassName?: string;
enableGlobalSelectors?: boolean;
}) {
const dispatch = useDispatch();
const {datasetId, datasetFieldId, isManualTitle, title, fieldType, validation} =
useSelector(selectSelectorDialog);
const {workbookId} = useSelector(selectOpenedItemMeta);
const {tabsScope, group} = useSelector(selectSelectorsGroup);
const [isInvalid, setIsInvalid] = React.useState(false);

const fetchDataset = React.useCallback((entryId: string) => {
Expand All @@ -53,7 +60,7 @@ function DatasetSelector(props: {
})
.catch((isInvalid) => {
setIsInvalid(true);
logger.logError('DatasetSelector: load dataset failed', isInvalid);
logger.logError('DatasetSelectorSettings: load dataset failed', isInvalid);
});
}, []);

Expand Down Expand Up @@ -171,8 +178,14 @@ function DatasetSelector(props: {
/>
</FieldWrapper>
</FormRow>
{props.enableGlobalSelectors && (
<TabsScopeSelect
hasMultipleSelectors={group.length > 1}
groupTabsScope={tabsScope}
></TabsScopeSelect>
)}
</React.Fragment>
);
}

export {DatasetSelector};
export {DatasetSelectorSettings};
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {selectOpenedItemMeta, selectSelectorDialog} from 'ui/store/selectors/con
import {EntryTypeNode} from 'ui/units/dash/modules/constants';

import {EntrySelector} from '../EntrySelector/EntrySelector';
import {TabsScopeSelect} from '../TabsScopeSelect/TabsScopeSelect';

import './ExternalSelectorSettings.scss';

Expand All @@ -32,6 +33,7 @@ const ExternalSelectorSettings: React.FC<{
navigationPath: string | null;
changeNavigationPath: (newNavigationPath: string) => void;
enableAutoheightDefault?: boolean;
enableGlobalSelectors?: boolean;
rowClassName?: string;
}> = (props) => {
const dispatch = useDispatch();
Expand Down Expand Up @@ -121,6 +123,8 @@ const ExternalSelectorSettings: React.FC<{
changeNavigationPath={props.changeNavigationPath}
/>

{props.enableGlobalSelectors && <TabsScopeSelect />}

{!props.enableAutoheightDefault && (
<FormRow
label={i18n('dash.control-dialog.edit', 'field_autoheight')}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.tabs-scope-select {
&__group-hint,
&__tab-hint {
color: var(--g-color-text-secondary);
}
}
Loading
Loading