Skip to content

Commit

Permalink
feat(PoolTreeSuggestControl): now we could select multiply pool trees…
Browse files Browse the repository at this point in the history
… on clique creation/edit [#841]
  • Loading branch information
vrozaev committed Nov 6, 2024
1 parent 62e7dd0 commit 2014215
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ export function PoolSuggestControl(props: Props) {

const [poolNames, setPoolNames] = React.useState<Array<string>>([]);

const loadedPools = useLoadedPools(cluster, poolTrees);
const names = useLoadedPools(cluster, poolTrees);

React.useEffect(
function onPoolLoaded() {
const {names} = loadedPools;
if (!names) {
return;
}
const noRoot = filter_(names, (item) => '<Root>' !== item);
const valueIndex = indexOf_(noRoot, value);
if (value && -1 === valueIndex) {
Expand All @@ -73,7 +75,7 @@ export function PoolSuggestControl(props: Props) {
}
},
// value should not affect the useEffect
[loadedPools, setPoolNames, onChange, calculateValueOnPoolsLoaded /*, value */],
[names && names.join(), setPoolNames, onChange, calculateValueOnPoolsLoaded /*, value */],
);

const getItems = React.useCallback(
Expand Down Expand Up @@ -121,13 +123,19 @@ PoolSuggestControl.isEmpty = (value: Props['value']) => {
return !value;
};

function useLoadedPools(cluster?: string, poolTrees: string[] = []): {names: Array<string>} {
const [poolNames, setPoolNames] = React.useState<Array<string>>([]);
function useLoadedPools(cluster?: string, poolTrees?: string[]): Array<string> | null {
poolTrees = poolTrees || [];

const [poolNames, setPoolNames] = React.useState<Array<string> | null>(null);

const defaultPoolTree = useDefaultPoolTree();

React.useMemo(() => {
const localPoolTrees: string[] = poolTrees.length ? poolTrees : defaultPoolTree ? [defaultPoolTree] : [];
const localPoolTrees: string[] = poolTrees.length
? poolTrees
: defaultPoolTree
? [defaultPoolTree]
: [];

if (!localPoolTrees.length) {
return;
Expand All @@ -150,9 +158,7 @@ function useLoadedPools(cluster?: string, poolTrees: string[] = []): {names: Arr
});
}, [cluster, defaultPoolTree, poolTrees.join()]);

return {
names: poolNames,
};
return poolNames;
}

function fetchPoolNamesByCluster(cluster: string, poolTrees: string[]): Promise<string[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import {Select} from '@gravity-ui/uikit';

import {DialogControlProps} from '../../../../components/Dialog/Dialog.types';
import {getAllPoolTreeNames} from '../../../../store/selectors/global';
import {usePoolTreesLoaded} from '../../../../hooks/global-pool-trees';

type Props = DialogControlProps<string> & {
type Props = DialogControlProps<string[]> & {
disabled?: boolean;
};

export function PoolTreeSuggestControl(props: Props) {
const {value, onChange, disabled, placeholder} = props;
const treeNames = useSelector(getAllPoolTreeNames);

usePoolTreesLoaded();

const items = React.useMemo(() => {
return map_(treeNames, (value) => {
return {value, content: value};
Expand All @@ -24,20 +27,21 @@ export function PoolTreeSuggestControl(props: Props) {
return (
<Select
disabled={disabled}
value={[value]}
value={value}
options={items}
onUpdate={(values) => onChange(values[0])}
onUpdate={onChange}
placeholder={placeholder}
width="max"
filterable={items?.length > 5}
multiple
/>
);
}

PoolTreeSuggestControl.getDefaultValue = () => {
return '';
return [];
};

PoolTreeSuggestControl.isEmpty = (value: Props['value']) => {
return !value;
return !value.length;
};
56 changes: 52 additions & 4 deletions packages/ui/src/ui/components/Dialog/df-dialog-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DialogField} from './Dialog';
import {ControlField, DialogField} from './Dialog';

import format from '../../common/hammer/format';
import {UnipikaSettings} from '../Yson/StructuredYson/StructuredYsonTypes';
Expand All @@ -17,7 +17,8 @@ export type OptionDescription =
min_value?: number;
})
| Option<'yson', JsonAsString>
| Option<'path' | 'pool', string>;
| Option<'path' | 'pool', string>
| Option<'pool_trees', string[]>;

export type JsonAsString = string;

Expand All @@ -31,7 +32,7 @@ export type Option<TypeName extends string, T> = {

export function descriptionToDialogField<T = unknown>(
item: OptionDescription,
{unipikaSettings, allowEdit}: MakeDialogFieldsOptions,
{unipikaSettings, allowEdit, defaultPoolTree}: MakeDialogFieldsOptions,
): DialogField<T> & {initialValue?: unknown; converter: Converter} {
const common = {
name: item.name,
Expand Down Expand Up @@ -115,7 +116,19 @@ export function descriptionToDialogField<T = unknown>(
case 'path':
return {...common, type: 'path', extras};
case 'pool':
return {...common, type: 'pool', extras: {...extras, allowEmpty: true}};
return {
...common,
type: 'pool',
extras: {...extras, allowEmpty: true},
initialValue: item.current_value ?? item.default_value,
};
case 'pool_trees':
return {
...common,
type: 'pool-tree',
extras,
initialValue: item.current_value ?? item.default_value ?? [defaultPoolTree],
};
default:
return {...common, type: 'plain'};
}
Expand Down Expand Up @@ -195,6 +208,7 @@ function makeDialogField<FormValues = any>(
type MakeDialogFieldsOptions = {
allowEdit: boolean;
unipikaSettings: UnipikaSettings;
defaultPoolTree: string;
};

export function makeDialogFieldsFromDescription<
Expand Down Expand Up @@ -253,3 +267,37 @@ export function makeTabbedDialogFieldsFromDescription<
}),
};
}

export function linkPoolWithPoolTree<
FormValues extends Record<string, Record<string, unknown>> = Record<
string,
Record<string, unknown>
>,
>(data: ReturnType<typeof makeTabbedDialogFieldsFromDescription>) {
for (const group of data.fields) {
type FieldType = (typeof data)['fields'][number]['fields'][number];
type FieldPoolType = FieldType & {type: 'pool'};
type FieldPoolTreesType = FieldType & {type: 'pool-tree'};

let pool: undefined | FieldPoolType;
let poolTrees: undefined | FieldPoolTreesType;

group.fields.some((field) => {
if (field.type === 'pool-tree') {
poolTrees = field;
}
if (field.type === 'pool') {
pool = field;
}
return Boolean(pool && poolTrees);
});

if (pool && poolTrees) {
const extras = pool.extras;
(pool as ControlField).extras = (values: FormValues) => ({
...extras,
poolTrees: values[group.name].pool_trees,
});
}
}
}
2 changes: 1 addition & 1 deletion packages/ui/src/ui/hooks/global-pool-trees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {useDispatch} from 'react-redux';
import {loadPoolTreesIfNotLoaded} from '../store/actions/global';
import {loadDefaultPoolTree} from '../utils/poolTrees';

function usePoolTreesLoaded() {
export function usePoolTreesLoaded() {
const dispatch = useDispatch();

React.useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import Icon from '../../../components/Icon/Icon';
import {YTDFDialog} from '../../../components/Dialog';
import Yson from '../../../components/Yson/Yson';
import {UnipikaSettings} from '../../../components/Yson/StructuredYson/StructuredYsonTypes';
import {makeTabbedDialogFieldsFromDescription} from '../../../components/Dialog/df-dialog-utils';
import {
linkPoolWithPoolTree,
makeTabbedDialogFieldsFromDescription,
} from '../../../components/Dialog/df-dialog-utils';

import {useUpdater} from '../../../hooks/use-updater';

Expand All @@ -31,6 +34,7 @@ import {
} from '../../../store/selectors/chyt/speclet';
import {useThunkDispatch} from '../../../store/thunkDispatch';
import {YTError} from '../../../../@types/types';
import {WaitForDefaultPoolTree} from '../../../hooks/global-pool-trees';

import './ChytPageCliqueSpeclet.scss';

Expand Down Expand Up @@ -124,14 +128,19 @@ export function ChytSpecletEditButton({
return (
<React.Fragment>
{!visible || !specletData ? null : (
<ChytSpecletEditDialog
key={dataAlias}
data={specletData}
alias={alias}
unipikaSettings={unipikaSettings}
allowEdit={dataAlias === alias}
onClose={() => setVisible(false)}
/>
<WaitForDefaultPoolTree>
{({defaultPoolTree}) => (
<ChytSpecletEditDialog
key={dataAlias}
data={specletData}
alias={alias}
unipikaSettings={unipikaSettings}
allowEdit={dataAlias === alias}
onClose={() => setVisible(false)}
defaultPoolTree={defaultPoolTree}
/>
)}
</WaitForDefaultPoolTree>
)}
<Button
view={compact ? 'outlined' : undefined}
Expand All @@ -153,21 +162,28 @@ function ChytSpecletEditDialog({
allowEdit,
unipikaSettings,
onClose,
defaultPoolTree,
}: {
allowEdit: boolean;
alias: string;
data: ChytCliqueOptionsState['data'];
unipikaSettings: UnipikaSettings;
onClose: () => void;
defaultPoolTree: string;
}) {
const dispatch = useThunkDispatch();
const [error, setError] = React.useState<YTError | undefined>();

const {fields, initialValues, fieldTypeByName} = React.useMemo(() => {
return makeTabbedDialogFieldsFromDescription(data ?? [], {
const groups = makeTabbedDialogFieldsFromDescription(data ?? [], {
allowEdit,
unipikaSettings,
defaultPoolTree,
});

linkPoolWithPoolTree(groups);

return groups;
}, [data, allowEdit, unipikaSettings]);

return (
Expand Down
9 changes: 3 additions & 6 deletions packages/ui/src/ui/pages/chyt/ChytPageTopRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ function ChytAliasSuggest({
type FormValues = {
alias: string;
instance_count: number;
tree: string;
tree: string[];
pool: string;
runAfterCreation: boolean;
};
Expand Down Expand Up @@ -246,17 +246,14 @@ function CreateChytButton() {
name: 'tree',
type: 'pool-tree',
caption: 'Pool tree',
extras: {
disabled: true,
},
},
{
name: 'pool',
type: 'pool',
caption: 'Pool',
extras: ({tree}: FormValues) => {
return {
poolTrees: [tree],
poolTrees: tree,
placeholder: 'Pool name...',
allowEmpty: true,
};
Expand Down Expand Up @@ -294,7 +291,7 @@ function CreateChytButton() {
]}
initialValues={{
instance_count: 1,
tree: defaultPoolTree,
tree: [defaultPoolTree],
runAfterCreation: true,
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function TableMergeModal() {
} = values;
const chunkSizeBytes = parseBytes(chunkSize);
const data_size_per_job = isNaN(chunkSizeBytes) ? undefined : chunkSizeBytes;
const pool_trees = poolTree ? [poolTree] : undefined;
const pool_trees = poolTree.length ? poolTree : undefined;
await dispatch(
runTableMerge(
pickBy_(
Expand Down Expand Up @@ -114,7 +114,7 @@ export default function TableMergeModal() {
outputPath,
columns: [],
force_transform: true,
poolTree: defaultPoolTree,
poolTree: [defaultPoolTree],
combine_chunks: true,
}}
fields={[
Expand Down Expand Up @@ -194,7 +194,7 @@ export default function TableMergeModal() {
),
extras: ({poolTree}: FormValues) => {
return {
poolTrees: [poolTree],
poolTrees: poolTree,
placeholder: login,
allowEphemeral: true,
};
Expand Down Expand Up @@ -237,7 +237,7 @@ export default function TableMergeModal() {
interface FormValues {
mode: string;
pool: string;
poolTree: string;
poolTree: string[];

paths: Array<string>;
outputPath: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function TableSortModal() {
}),
},
pool ? {pool} : {},
poolTree ? {pool_trees: [poolTree]} : {},
poolTree.length ? {pool_trees: poolTree} : {},
);

await dispatch(runTableSort(spec));
Expand Down Expand Up @@ -125,7 +125,7 @@ export default function TableSortModal() {
paths,
outputPath,
columns: [],
poolTree: defaultPoolTree,
poolTree: [defaultPoolTree],
}}
fields={[
{
Expand Down Expand Up @@ -183,7 +183,7 @@ export default function TableSortModal() {
const {poolTree} = values;
return {
placeholder: login,
poolTrees: [poolTree],
poolTrees: poolTree,
allowEphemeral: true,
};
},
Expand All @@ -200,6 +200,6 @@ interface FormValues {
paths: Array<string>;
outputPath: string;
columns: Array<string>;
poolTree: string;
poolTree: string[];
pool: string;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2014215

Please # to comment.