Skip to content

Commit 837fedf

Browse files
committed
feat(FR-1731): implement mutation functionality for the project table
1 parent 58312c4 commit 837fedf

File tree

136 files changed

+2689
-479
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+2689
-479
lines changed

packages/backend.ai-ui/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
"@types/relay-test-utils": "^19.0.0",
162162
"@vitejs/plugin-react": "^4.7.0",
163163
"babel-plugin-react-compiler": "^1.0.0",
164+
"babel-jest": "^30.2.0",
164165
"eslint": "^8.57.1",
165166
"eslint-plugin-import": "^2.31.0",
166167
"eslint-plugin-react": "^7.37.4",
@@ -195,7 +196,8 @@
195196
"jsx": "react-jsx"
196197
}
197198
}
198-
]
199+
],
200+
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
199201
},
200202
"setupFilesAfterEnv": [
201203
"./setupTests.ts"

packages/backend.ai-ui/setupTests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
// allows you to do things like:
33
// expect(element).toHaveTextContent(/react/i)
44
// learn more: https://github.com/testing-library/jest-dom
5+
import './src/__test__/matchMedia.mock';
56
import '@testing-library/jest-dom';
File renamed without changes.

react/src/components/AllowedHostNamesSelect.tsx renamed to packages/backend.ai-ui/src/components/BAIAllowedHostNamesSelect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useAllowedHostNames } from '../hooks/backendai';
1+
import { useAllowedHostNames } from '../hooks';
22
import { Select, SelectProps } from 'antd';
33
import _ from 'lodash';
44
import React from 'react';

react/src/components/DynamicUnitInputNumber.stories.tsx renamed to packages/backend.ai-ui/src/components/BAIDynamicUnitInputNumber.stories.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Button.stories.ts|tsx
22
import DynamicUnitInputNumber, {
3-
DynamicUnitInputNumberProps,
4-
} from './DynamicUnitInputNumber';
5-
import type { Meta, StoryObj } from '@storybook/react';
3+
BAIDynamicUnitInputNumberProps,
4+
} from './BAIDynamicUnitInputNumber';
5+
import type { Meta, StoryObj } from '@storybook/react-vite';
66
import { Form } from 'antd';
77

88
const meta: Meta<typeof DynamicUnitInputNumber> = {
9-
title: 'Input/DynamicUnitInputNumber',
9+
title: 'Components/Input/DynamicUnitInputNumber',
1010
component: DynamicUnitInputNumber,
1111
parameters: {
1212
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
@@ -21,7 +21,7 @@ type Story = StoryObj<typeof DynamicUnitInputNumber>;
2121
const renderWithFormItem = ({
2222
value,
2323
...args
24-
}: DynamicUnitInputNumberProps) => {
24+
}: BAIDynamicUnitInputNumberProps) => {
2525
return (
2626
<Form
2727
initialValues={{

react/src/components/DynamicUnitInputNumber.tsx renamed to packages/backend.ai-ui/src/components/BAIDynamicUnitInputNumber.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { convertToBinaryUnit, parseValueWithUnit, SizeUnit } from '../helper';
2-
import useControllableState_deprecated from '../hooks/useControllableState';
3-
import { usePrevious } from 'ahooks';
2+
import { useControllableValue, usePrevious } from 'ahooks';
43
import { InputNumber, InputNumberProps, Select, Typography } from 'antd';
54
import _ from 'lodash';
65
import React, { RefObject, useEffect, useRef } from 'react';
76

8-
export interface DynamicUnitInputNumberProps
7+
export interface BAIDynamicUnitInputNumberProps
98
extends Omit<
109
InputNumberProps,
1110
'step' | 'max' | 'min' | 'value' | 'onChange'
@@ -21,7 +20,7 @@ export interface DynamicUnitInputNumberProps
2120
ref?: RefObject<HTMLInputElement | null>;
2221
}
2322

24-
const DynamicUnitInputNumber: React.FC<DynamicUnitInputNumberProps> = ({
23+
const BAIDynamicUnitInputNumber: React.FC<BAIDynamicUnitInputNumberProps> = ({
2524
dynamicSteps = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512],
2625
units = ['m', 'g', 't', 'p'],
2726
disableAutoUnit = false,
@@ -30,11 +29,12 @@ const DynamicUnitInputNumber: React.FC<DynamicUnitInputNumberProps> = ({
3029
roundStep,
3130
...inputNumberProps
3231
}) => {
33-
const [value, setValue] = useControllableState_deprecated<
34-
string | null | undefined
35-
>(inputNumberProps, {
36-
defaultValue: '0g',
37-
});
32+
const [value, setValue] = useControllableValue<string | null | undefined>(
33+
inputNumberProps,
34+
{
35+
defaultValue: '0g',
36+
},
37+
);
3838
const [numValue, _unitFromValue] =
3939
value === null || value === undefined
4040
? [null, null]
@@ -221,4 +221,4 @@ const DynamicUnitInputNumber: React.FC<DynamicUnitInputNumberProps> = ({
221221
);
222222
};
223223

224-
export default DynamicUnitInputNumber;
224+
export default BAIDynamicUnitInputNumber;

react/src/components/DynamicUnitInputNumberWithSlider.stories.tsx renamed to packages/backend.ai-ui/src/components/BAIDynamicUnitInputNumberWithSlider.stories.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
// Button.stories.ts|tsx
2-
import DynamicUnitInputNumberWithSlider, {
3-
DynamicUnitInputNumberWithSliderProps,
4-
} from './DynamicUnitInputNumberWithSlider';
5-
import type { Meta, StoryObj } from '@storybook/react';
1+
import {
2+
BAIDynamicUnitInputNumberWithSlider,
3+
BAIDynamicUnitInputNumberWithSliderProps,
4+
} from '.';
5+
import type { Meta, StoryObj } from '@storybook/react-vite';
66
import { Form } from 'antd';
77

8-
const meta: Meta<typeof DynamicUnitInputNumberWithSlider> = {
9-
title: 'Input/DynamicUnitInputNumberWithSlider',
10-
component: DynamicUnitInputNumberWithSlider,
8+
const meta: Meta<typeof BAIDynamicUnitInputNumberWithSlider> = {
9+
title: 'Components/Input/DynamicUnitInputNumberWithSlider',
10+
component: BAIDynamicUnitInputNumberWithSlider,
1111
parameters: {
1212
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
1313
layout: 'centered',
@@ -16,20 +16,20 @@ const meta: Meta<typeof DynamicUnitInputNumberWithSlider> = {
1616

1717
export default meta;
1818

19-
type Story = StoryObj<typeof DynamicUnitInputNumberWithSlider>;
19+
type Story = StoryObj<typeof BAIDynamicUnitInputNumberWithSlider>;
2020

2121
const renderWithFormItem = ({
2222
value,
2323
...args
24-
}: DynamicUnitInputNumberWithSliderProps) => {
24+
}: BAIDynamicUnitInputNumberWithSliderProps) => {
2525
return (
2626
<Form
2727
initialValues={{
2828
mem: value,
2929
}}
3030
>
3131
<Form.Item name="mem">
32-
<DynamicUnitInputNumberWithSlider {...args} />
32+
<BAIDynamicUnitInputNumberWithSlider {...args} />
3333
</Form.Item>
3434
</Form>
3535
);

react/src/components/DynamicUnitInputNumberWithSlider.tsx renamed to packages/backend.ai-ui/src/components/BAIDynamicUnitInputNumberWithSlider.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,24 @@ import {
44
toFixedFloorWithoutTrailingZeros,
55
} from '../helper';
66
import { useUpdatableState } from '../hooks';
7-
import useControllableState_deprecated from '../hooks/useControllableState';
8-
import DynamicUnitInputNumber, {
9-
DynamicUnitInputNumberProps,
10-
} from './DynamicUnitInputNumber';
7+
import { BAIDynamicUnitInputNumberProps } from './BAIDynamicUnitInputNumber';
8+
import BAIFlex from './BAIFlex';
9+
import { useControllableValue } from 'ahooks';
1110
import { Slider, theme } from 'antd';
1211
import { SliderMarks } from 'antd/es/slider';
13-
import { BAIFlex } from 'backend.ai-ui';
1412
import _ from 'lodash';
1513
import React, { useEffect, useMemo } from 'react';
1614

17-
export interface DynamicUnitInputNumberWithSliderProps
18-
extends DynamicUnitInputNumberProps {
15+
export interface BAIDynamicUnitInputNumberWithSliderProps
16+
extends BAIDynamicUnitInputNumberProps {
1917
extraMarks?: SliderMarks;
2018
hideSlider?: boolean;
2119
warn?: string;
2220
step?: number;
2321
inputMinWidth?: number;
2422
}
2523
const DynamicUnitInputNumberWithSlider: React.FC<
26-
DynamicUnitInputNumberWithSliderProps
24+
BAIDynamicUnitInputNumberWithSliderProps
2725
> = ({
2826
min = '0m',
2927
max = '32g',
@@ -34,11 +32,12 @@ const DynamicUnitInputNumberWithSlider: React.FC<
3432
step = 0.05,
3533
...otherProps
3634
}) => {
37-
const [value, setValue] = useControllableState_deprecated<
38-
string | undefined | null
39-
>(otherProps, {
40-
defaultValue: '0g',
41-
});
35+
const [value, setValue] = useControllableValue<string | undefined | null>(
36+
otherProps,
37+
{
38+
defaultValue: '0g',
39+
},
40+
);
4241
const { token } = theme.useToken();
4342
const minGiB = useMemo(() => convertToBinaryUnit(min, 'g', 2), [min]);
4443
const maxGiB = useMemo(() => convertToBinaryUnit(max, 'g', 2), [max]);
@@ -79,7 +78,7 @@ const DynamicUnitInputNumberWithSlider: React.FC<
7978
direction="column"
8079
align="stretch"
8180
>
82-
<DynamicUnitInputNumber
81+
<DynamicUnitInputNumberWithSlider
8382
{...otherProps}
8483
key={key}
8584
min={min}

react/src/components/ResourceGroupSelect.tsx renamed to packages/backend.ai-ui/src/components/BAIProjectResourceGroupSelect.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { useBaiSignedRequestWithPromise } from '../helper';
2-
import { useUpdatableState } from '../hooks';
3-
import { useSuspenseTanQuery } from '../hooks/reactQueryAlias';
4-
import useControllableState_deprecated from '../hooks/useControllableState';
1+
import { useSuspenseTanQuery } from '../helper/reactQueryAlias';
2+
import { useBAISignedRequestWithPromise, useUpdatableState } from '../hooks';
53
import BAISelect, { BAISelectProps } from './BAISelect';
6-
import TextHighlighter from './TextHighlighter';
4+
import BAITextHighlighter from './BAITextHighlighter';
5+
import { useControllableValue } from 'ahooks';
76
import { SelectProps } from 'antd';
87
import _ from 'lodash';
98
import React, { useEffect, useState, useTransition } from 'react';
@@ -21,13 +20,15 @@ interface VolumeInfo {
2120
sftp_scaling_groups?: string[];
2221
}
2322

24-
interface ResourceGroupSelectProps extends BAISelectProps {
23+
interface BAIProjectResourceGroupSelectProps extends BAISelectProps {
2524
projectName: string;
2625
autoSelectDefault?: boolean;
2726
filter?: (projectName: string) => boolean;
2827
}
2928

30-
const ResourceGroupSelect: React.FC<ResourceGroupSelectProps> = ({
29+
const BAIProjectResourceGroupSelect: React.FC<
30+
BAIProjectResourceGroupSelectProps
31+
> = ({
3132
projectName,
3233
autoSelectDefault,
3334
filter,
@@ -36,16 +37,16 @@ const ResourceGroupSelect: React.FC<ResourceGroupSelectProps> = ({
3637
loading,
3738
...selectProps
3839
}) => {
39-
const baiRequestWithPromise = useBaiSignedRequestWithPromise();
40+
const baiRequestWithPromise = useBAISignedRequestWithPromise();
4041
const [fetchKey] = useUpdatableState('first');
4142
const [controllableSearchValue, setControllableSearchValue] =
42-
useControllableState_deprecated<string>({
43+
useControllableValue<string>({
4344
value: searchValue,
4445
onChange: onSearch,
4546
});
4647

4748
const [controllableValue, setControllableValueDoNotUseWithoutTransition] =
48-
useControllableState_deprecated(selectProps);
49+
useControllableValue(selectProps);
4950
const [isPendingChangeTransition, startChangeTransition] = useTransition();
5051

5152
const [optimisticValue, setOptimisticValue] = useState();
@@ -169,9 +170,9 @@ const ResourceGroupSelect: React.FC<ResourceGroupSelectProps> = ({
169170
})}
170171
optionRender={(option) => {
171172
return (
172-
<TextHighlighter keyword={controllableSearchValue}>
173+
<BAITextHighlighter keyword={controllableSearchValue}>
173174
{option.data.value?.toString()}
174-
</TextHighlighter>
175+
</BAITextHighlighter>
175176
);
176177
}}
177178
{...selectProps}
@@ -181,4 +182,4 @@ const ResourceGroupSelect: React.FC<ResourceGroupSelectProps> = ({
181182
);
182183
};
183184

184-
export default ResourceGroupSelect;
185+
export default BAIProjectResourceGroupSelect;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { theme } from 'antd';
2+
import _ from 'lodash';
3+
import React from 'react';
4+
5+
interface BAITextHighlighterProps {
6+
children?: string | null;
7+
keyword?: string;
8+
style?: React.CSSProperties;
9+
}
10+
11+
const BAITextHighlighter: React.FC<BAITextHighlighterProps> = ({
12+
children,
13+
keyword,
14+
style,
15+
}) => {
16+
if (!children) return null;
17+
18+
if (_.isEmpty(keyword)) {
19+
return <span>{children}</span>;
20+
} else {
21+
const { token } = theme.useToken() || '#F1A239';
22+
const parts = children.split(
23+
new RegExp(`(${_.escapeRegExp(keyword)})`, 'gi'),
24+
);
25+
26+
return (
27+
<span>
28+
{parts.map((part, i) =>
29+
part.toLowerCase() === keyword?.toLowerCase() ? (
30+
<span
31+
key={i}
32+
style={{ backgroundColor: token.colorWarningHover, ...style }}
33+
>
34+
{part}
35+
</span>
36+
) : (
37+
part
38+
),
39+
)}
40+
</span>
41+
);
42+
}
43+
};
44+
45+
export default React.memo(BAITextHighlighter);

0 commit comments

Comments
 (0)