@scality/core-ui 0.163.0 → 0.165.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/barchartv2/Barchart.component.d.ts +10 -2
- package/dist/components/barchartv2/Barchart.component.d.ts.map +1 -1
- package/dist/components/barchartv2/Barchart.component.js +20 -11
- package/dist/components/barchartv2/utils.d.ts +10 -3
- package/dist/components/barchartv2/utils.d.ts.map +1 -1
- package/dist/components/barchartv2/utils.js +45 -22
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/next.d.ts +2 -0
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +2 -0
- package/package.json +1 -1
- package/src/lib/components/accordion/Accordion.test.tsx +1 -1
- package/src/lib/components/barchartv2/Barchart.component.test.tsx +41 -18
- package/src/lib/components/barchartv2/Barchart.component.tsx +56 -14
- package/src/lib/components/barchartv2/utils.test.ts +82 -47
- package/src/lib/components/barchartv2/utils.ts +53 -16
- package/src/lib/components/healthselectorv2/HealthSelector.component.test.tsx +7 -7
- package/src/lib/components/infomessage/InfoMessageUtils.test.tsx +0 -1
- package/src/lib/components/inlineinput/InlineInput.test.tsx +10 -7
- package/src/lib/components/inputlist/InputList.test.tsx +1 -2
- package/src/lib/components/linetemporalchart/ChartUtil.test.ts +5 -4
- package/src/lib/components/selectv2/selectv2.test.tsx +8 -4
- package/src/lib/components/tablev2/TableSync.test.tsx +2 -3
- package/src/lib/components/tablev2/TableUtils.test.ts +6 -3
- package/src/lib/components/tablev2/Tablev2.test.tsx +2 -3
- package/src/lib/components/toggle/Toggle.test.tsx +1 -1
- package/src/lib/index.ts +0 -1
- package/src/lib/next.ts +2 -0
- package/stories/BarChart/barchart.stories.tsx +96 -5
- package/tsconfig.json +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
QueryClient,
|
|
4
4
|
QueryClientProvider,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
render,
|
|
12
12
|
screen,
|
|
13
13
|
waitFor,
|
|
14
|
-
waitForElementToBeRemoved,
|
|
15
14
|
within,
|
|
16
15
|
} from '@testing-library/react';
|
|
17
16
|
import userEvent from '@testing-library/user-event';
|
|
@@ -77,9 +76,10 @@ describe('InlineInput', () => {
|
|
|
77
76
|
/// Then press enter to edit the input
|
|
78
77
|
await act(() => userEvent.keyboard('{enter}'));
|
|
79
78
|
/// Then type a new value
|
|
80
|
-
await act(() => userEvent.type(document.activeElement
|
|
79
|
+
await act(() => userEvent.type(document.activeElement!, 'new value'));
|
|
81
80
|
/// Then press enter to confirm the new value
|
|
82
81
|
await act(() => userEvent.keyboard('{enter}'));
|
|
82
|
+
await waitFor(() => screen.findByText('testnew value'));
|
|
83
83
|
expect(screen.queryByRole('textbox')).not.toBeInTheDocument();
|
|
84
84
|
|
|
85
85
|
//V
|
|
@@ -115,13 +115,16 @@ describe('InlineInput', () => {
|
|
|
115
115
|
/// Then press enter to edit the input
|
|
116
116
|
await act(() => userEvent.keyboard('{enter}'));
|
|
117
117
|
/// Then type a new value
|
|
118
|
-
await act(() => userEvent.type(document.activeElement
|
|
118
|
+
await act(() => userEvent.type(document.activeElement!, 'new value'));
|
|
119
119
|
/// Then press enter to confirm the new value
|
|
120
|
+
|
|
120
121
|
await act(() => userEvent.keyboard('{enter}'));
|
|
122
|
+
await waitFor(() => screen.findByRole('dialog', { name: /Confirm/i }));
|
|
121
123
|
/// Expect the confirmation modal to be opened
|
|
122
124
|
expect(selectors.confirmationModal()).toBeInTheDocument()
|
|
123
125
|
/// Click the confirm button
|
|
124
126
|
await act(() => userEvent.click(screen.getByRole('button', { name: /confirm/i })));
|
|
127
|
+
|
|
125
128
|
/// modal should be closed
|
|
126
129
|
expect(screen.queryByRole('dialog', { name: /Confirm/i })).not.toBeInTheDocument();
|
|
127
130
|
|
|
@@ -156,7 +159,7 @@ describe('InlineInput', () => {
|
|
|
156
159
|
/// Then press enter to edit the input
|
|
157
160
|
await act(() => userEvent.keyboard('{enter}'));
|
|
158
161
|
/// Then type a new value
|
|
159
|
-
await act(() => userEvent.type(document.activeElement
|
|
162
|
+
await act(() => userEvent.type(document.activeElement!, 'new value'));
|
|
160
163
|
/// Then press escape to cancel the new value
|
|
161
164
|
await act(() => userEvent.keyboard('{esc}'));
|
|
162
165
|
|
|
@@ -191,7 +194,7 @@ describe('InlineInput', () => {
|
|
|
191
194
|
/// Then press enter to edit the input
|
|
192
195
|
await act(() => userEvent.keyboard('{enter}'));
|
|
193
196
|
/// Then type a new value
|
|
194
|
-
await act(() => userEvent.type(document.activeElement
|
|
197
|
+
await act(() => userEvent.type(document.activeElement!, 'new value'));
|
|
195
198
|
/// Then press enter to confirm the new value
|
|
196
199
|
await act(() => userEvent.keyboard('{enter}'));
|
|
197
200
|
/// Expect the confirmation modal to be opened
|
|
@@ -208,7 +211,7 @@ describe('InlineInput', () => {
|
|
|
208
211
|
//V
|
|
209
212
|
expect(mock).not.toHaveBeenCalled();
|
|
210
213
|
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
211
|
-
expect(screen.getByRole('textbox').value).toBe('testnew value');
|
|
214
|
+
expect((screen.getByRole('textbox') as HTMLInputElement).value).toBe('testnew value');
|
|
212
215
|
});
|
|
213
216
|
});
|
|
214
217
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
|
|
3
2
|
import { InputList, InputListProps } from './InputList.component';
|
|
4
3
|
import { FormSection } from '../form/Form.component';
|
|
@@ -6,7 +5,7 @@ import { FormSection } from '../form/Form.component';
|
|
|
6
5
|
describe('InputList', () => {
|
|
7
6
|
const onChangeMock = jest.fn();
|
|
8
7
|
|
|
9
|
-
const renderInputList = (props: InputListProps<string
|
|
8
|
+
const renderInputList = (props: InputListProps<string>) => {
|
|
10
9
|
render(
|
|
11
10
|
<FormSection>
|
|
12
11
|
<InputList
|
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
getUnitLabel,
|
|
4
4
|
addMissingDataPoint,
|
|
5
5
|
} from './ChartUtil';
|
|
6
|
-
|
|
6
|
+
import { Serie } from './LineTemporalChart.component';
|
|
7
|
+
const series: Serie[] = [
|
|
7
8
|
{
|
|
8
9
|
resource: 'node1',
|
|
9
10
|
data: [
|
|
@@ -11,7 +12,7 @@ const series = [
|
|
|
11
12
|
[1627460952, '18.73333333333335'],
|
|
12
13
|
],
|
|
13
14
|
getTooltipLabel: (metricPrefix, resource) => {
|
|
14
|
-
return resource
|
|
15
|
+
return `${resource}`;
|
|
15
16
|
},
|
|
16
17
|
isLineDashed: false,
|
|
17
18
|
},
|
|
@@ -22,12 +23,12 @@ const series = [
|
|
|
22
23
|
[1627460952, null],
|
|
23
24
|
],
|
|
24
25
|
getTooltipLabel: (metricPrefix, resource) => {
|
|
25
|
-
return resource
|
|
26
|
+
return `${resource}`;
|
|
26
27
|
},
|
|
27
28
|
isLineDashed: false,
|
|
28
29
|
},
|
|
29
30
|
];
|
|
30
|
-
const seriesSymmetrical = [
|
|
31
|
+
const seriesSymmetrical: Serie[] = [
|
|
31
32
|
{
|
|
32
33
|
metricPrefix: 'read',
|
|
33
34
|
resource: 'node1',
|
|
@@ -2,6 +2,7 @@ import { act, screen, render as testingRender, waitFor } from '@testing-library/
|
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
3
|
import React, { useState, useRef } from 'react';
|
|
4
4
|
import { Option, Select, SelectRef } from '../selectv2/Selectv2.component';
|
|
5
|
+
import { GroupTypeBase, OptionTypeBase } from 'react-select';
|
|
5
6
|
|
|
6
7
|
const render = (args) => {
|
|
7
8
|
return testingRender(args);
|
|
@@ -66,7 +67,10 @@ describe('SelectV2', () => {
|
|
|
66
67
|
};
|
|
67
68
|
|
|
68
69
|
it('should throw error if <Option/> is outside <Select/>', () => {
|
|
70
|
+
// mock console.error as this is the only way to silent expected error thrown by the component
|
|
71
|
+
const consoleErrorFn = jest.spyOn(console, 'error').mockImplementation(() => jest.fn());
|
|
69
72
|
expect(() => render(<Option value="Option 1" />)).toThrowError();
|
|
73
|
+
consoleErrorFn.mockRestore();
|
|
70
74
|
});
|
|
71
75
|
|
|
72
76
|
it('should open/close on click', async () => {
|
|
@@ -458,7 +462,7 @@ describe('SelectV2', () => {
|
|
|
458
462
|
describe('Ref API', () => {
|
|
459
463
|
it('should expose focus method via ref', async () => {
|
|
460
464
|
const RefTestComponent = () => {
|
|
461
|
-
const selectRef = useRef<SelectRef
|
|
465
|
+
const selectRef = useRef<SelectRef<OptionTypeBase, boolean, GroupTypeBase<OptionTypeBase>>>(null);
|
|
462
466
|
const [value, setValue] = useState<string>('');
|
|
463
467
|
|
|
464
468
|
return (
|
|
@@ -486,7 +490,7 @@ describe('SelectV2', () => {
|
|
|
486
490
|
|
|
487
491
|
it('should expose openMenu and closeMenu methods via ref', async () => {
|
|
488
492
|
const RefTestComponent = () => {
|
|
489
|
-
const selectRef = useRef<SelectRef
|
|
493
|
+
const selectRef = useRef<SelectRef<OptionTypeBase, boolean, GroupTypeBase<OptionTypeBase>>>(null);
|
|
490
494
|
const [value, setValue] = useState<string>('');
|
|
491
495
|
|
|
492
496
|
return (
|
|
@@ -529,7 +533,7 @@ describe('SelectV2', () => {
|
|
|
529
533
|
|
|
530
534
|
const RefTestComponent = () => {
|
|
531
535
|
const [value, setValue] = useState('');
|
|
532
|
-
const selectRef = useRef<SelectRef
|
|
536
|
+
const selectRef = useRef<SelectRef<OptionTypeBase, boolean, GroupTypeBase<OptionTypeBase>>>(null);
|
|
533
537
|
|
|
534
538
|
return (
|
|
535
539
|
<div>
|
|
@@ -582,7 +586,7 @@ describe('SelectV2', () => {
|
|
|
582
586
|
|
|
583
587
|
it('should expose blur method via ref', async () => {
|
|
584
588
|
const RefTestComponent = () => {
|
|
585
|
-
const selectRef = useRef<SelectRef
|
|
589
|
+
const selectRef = useRef<SelectRef<OptionTypeBase, boolean, GroupTypeBase<OptionTypeBase>>>(null);
|
|
586
590
|
const [value, setValue] = useState<string>('');
|
|
587
591
|
|
|
588
592
|
return (
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { TableSync } from './TableSync';
|
|
4
3
|
|
|
5
4
|
describe('TableSync', () => {
|
|
6
5
|
it('should render correctly', async () => {
|
|
7
6
|
const onSync = jest.fn();
|
|
8
7
|
render(
|
|
9
|
-
<TableSync onSync={onSync} />
|
|
8
|
+
<TableSync onSync={onSync} tooltipOverlay='sync' />
|
|
10
9
|
);
|
|
11
10
|
await waitFor(() => screen.queryAllByRole('img', { hidden: true }));
|
|
12
11
|
|
|
@@ -17,7 +16,7 @@ describe('TableSync', () => {
|
|
|
17
16
|
it('should call onSync when clicked', async () => {
|
|
18
17
|
const onSync = jest.fn();
|
|
19
18
|
render(
|
|
20
|
-
<TableSync onSync={onSync} />
|
|
19
|
+
<TableSync onSync={onSync} tooltipOverlay='sync' />
|
|
21
20
|
);
|
|
22
21
|
await waitFor(() => screen.queryAllByRole('img', { hidden: true }));
|
|
23
22
|
|
|
@@ -9,9 +9,12 @@ it('should return -1 or 1 to sort the status', () => {
|
|
|
9
9
|
expect(result).toEqual(1);
|
|
10
10
|
expect(result2).toEqual(-1);
|
|
11
11
|
});
|
|
12
|
-
it('should return
|
|
13
|
-
const
|
|
14
|
-
const
|
|
12
|
+
it('should return undefined for the unknown status', () => {
|
|
13
|
+
const consoleErrorMockHandle = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
14
|
+
const result = compareHealth('invalidStatus' as any, 'healthy');
|
|
15
|
+
const result2 = compareHealth('none', 'invalidStatus' as any);
|
|
16
|
+
expect(consoleErrorMockHandle).toHaveBeenCalled();
|
|
17
|
+
consoleErrorMockHandle.mockRestore();
|
|
15
18
|
expect(result).toEqual(undefined);
|
|
16
19
|
expect(result2).toEqual(undefined);
|
|
17
20
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Table } from './Tablev2.component';
|
|
2
|
-
import React from 'react';
|
|
1
|
+
import { Table, TableProps } from './Tablev2.component';
|
|
3
2
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
4
3
|
|
|
5
4
|
jest.mock('./TableUtils', () => ({
|
|
@@ -42,7 +41,7 @@ const data = [
|
|
|
42
41
|
health: 'healthy',
|
|
43
42
|
},
|
|
44
43
|
];
|
|
45
|
-
const columns = [
|
|
44
|
+
const columns: TableProps['columns'] = [
|
|
46
45
|
{
|
|
47
46
|
Header: 'First Name',
|
|
48
47
|
accessor: 'firstName',
|
package/src/lib/index.ts
CHANGED
|
@@ -82,4 +82,3 @@ export { InfoMessage } from './components/infomessage/InfoMessage.component';
|
|
|
82
82
|
export { InputList } from './components/inputlist/InputList.component';
|
|
83
83
|
export { InlineInput } from './components/inlineinput/InlineInput';
|
|
84
84
|
export { UnsuccessfulResult } from './components/UnsuccessfulResult.component';
|
|
85
|
-
export { LineTimeSerieChart } from './components/linetimeseriechart/linetimeseriechart.component';
|
package/src/lib/next.ts
CHANGED
|
@@ -22,3 +22,5 @@ export {
|
|
|
22
22
|
BarchartTooltipFn,
|
|
23
23
|
} from './components/barchartv2/Barchart.component';
|
|
24
24
|
export { ChartLegendWrapper } from './components/chartlegend/ChartLegendWrapper';
|
|
25
|
+
export { ChartLegend } from './components/chartlegend/ChartLegend';
|
|
26
|
+
export { LineTimeSerieChart } from './components/linetimeseriechart/linetimeseriechart.component';
|
|
@@ -360,7 +360,7 @@ export const CapacityWithUnitRange: Story = {
|
|
|
360
360
|
|
|
361
361
|
const stackedData: BarchartProps<
|
|
362
362
|
{
|
|
363
|
-
label: 'Success' | 'Failed';
|
|
363
|
+
label: 'Success' | 'Failed' | 'Warning';
|
|
364
364
|
data: [string, number][];
|
|
365
365
|
}[]
|
|
366
366
|
>['bars'] = [
|
|
@@ -375,9 +375,17 @@ const stackedData: BarchartProps<
|
|
|
375
375
|
{
|
|
376
376
|
label: 'Failed',
|
|
377
377
|
data: [
|
|
378
|
-
['category1',
|
|
379
|
-
['category2',
|
|
380
|
-
['category3',
|
|
378
|
+
['category1', 0],
|
|
379
|
+
['category2', 0],
|
|
380
|
+
['category3', 0],
|
|
381
|
+
],
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
label: 'Warning',
|
|
385
|
+
data: [
|
|
386
|
+
['category1', 0],
|
|
387
|
+
['category2', 0],
|
|
388
|
+
['category3', 0],
|
|
381
389
|
],
|
|
382
390
|
},
|
|
383
391
|
];
|
|
@@ -390,6 +398,7 @@ export const Stacked: Story = {
|
|
|
390
398
|
colorSet={{
|
|
391
399
|
Success: theme.statusHealthy,
|
|
392
400
|
Failed: theme.statusCritical,
|
|
401
|
+
Warning: theme.statusWarning,
|
|
393
402
|
}}
|
|
394
403
|
>
|
|
395
404
|
<Stack direction="vertical" gap="r16">
|
|
@@ -736,6 +745,88 @@ export const BarchartsWithSingleLegend: Story = {
|
|
|
736
745
|
);
|
|
737
746
|
},
|
|
738
747
|
};
|
|
748
|
+
|
|
749
|
+
export const ErrorState: Story = {
|
|
750
|
+
render: () => {
|
|
751
|
+
const theme = useTheme() as CoreUITheme;
|
|
752
|
+
return (
|
|
753
|
+
<ChartLegendWrapper
|
|
754
|
+
colorSet={{
|
|
755
|
+
Success: theme.statusHealthy,
|
|
756
|
+
Failed: theme.statusCritical,
|
|
757
|
+
}}
|
|
758
|
+
>
|
|
759
|
+
<Barchart
|
|
760
|
+
type="category"
|
|
761
|
+
bars={[]}
|
|
762
|
+
isError
|
|
763
|
+
title="Error State"
|
|
764
|
+
helpTooltip="This chart data could not be loaded"
|
|
765
|
+
/>
|
|
766
|
+
<ChartLegend shape="rectangle" />
|
|
767
|
+
</ChartLegendWrapper>
|
|
768
|
+
);
|
|
769
|
+
},
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
export const StackedBarSort: Story = {
|
|
773
|
+
render: () => {
|
|
774
|
+
const theme = useTheme() as CoreUITheme;
|
|
775
|
+
const [sort, setSort] = useState<'default' | 'legend'>('default');
|
|
776
|
+
const statusesData = [
|
|
777
|
+
{
|
|
778
|
+
label: 'Success',
|
|
779
|
+
data: [
|
|
780
|
+
['category1', 100],
|
|
781
|
+
['category2', 80],
|
|
782
|
+
['category3', 50],
|
|
783
|
+
],
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
label: 'Warning',
|
|
787
|
+
data: [
|
|
788
|
+
['category1', 10],
|
|
789
|
+
['category2', 20],
|
|
790
|
+
['category3', 30],
|
|
791
|
+
],
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
label: 'Failed',
|
|
795
|
+
data: [
|
|
796
|
+
['category1', 30],
|
|
797
|
+
['category2', 40],
|
|
798
|
+
['category3', 50],
|
|
799
|
+
],
|
|
800
|
+
},
|
|
801
|
+
] as const;
|
|
802
|
+
return (
|
|
803
|
+
<ChartLegendWrapper
|
|
804
|
+
colorSet={{
|
|
805
|
+
Success: theme.statusHealthy,
|
|
806
|
+
Warning: theme.statusWarning,
|
|
807
|
+
Failed: theme.statusCritical,
|
|
808
|
+
}}
|
|
809
|
+
>
|
|
810
|
+
<Barchart
|
|
811
|
+
type="category"
|
|
812
|
+
bars={statusesData}
|
|
813
|
+
stacked
|
|
814
|
+
stackedBarSort={sort}
|
|
815
|
+
title="Stacked Bar Chart"
|
|
816
|
+
helpTooltip="This chart data could not be loaded"
|
|
817
|
+
rightTitle={
|
|
818
|
+
<Button
|
|
819
|
+
label={sort === 'default' ? 'Sort by Legend' : 'Sort by Default'}
|
|
820
|
+
onClick={() => setSort(sort === 'default' ? 'legend' : 'default')}
|
|
821
|
+
/>
|
|
822
|
+
}
|
|
823
|
+
/>
|
|
824
|
+
<ChartLegend shape="rectangle" />
|
|
825
|
+
</ChartLegendWrapper>
|
|
826
|
+
);
|
|
827
|
+
},
|
|
828
|
+
};
|
|
829
|
+
|
|
739
830
|
export const CompleteExample: Story = {
|
|
740
831
|
render: () => {
|
|
741
832
|
const theme = useTheme() as CoreUITheme;
|
|
@@ -809,7 +900,7 @@ export const CompleteExample: Story = {
|
|
|
809
900
|
}}
|
|
810
901
|
/>
|
|
811
902
|
}
|
|
812
|
-
bars={data
|
|
903
|
+
bars={data}
|
|
813
904
|
tooltip={customTooltip}
|
|
814
905
|
isLoading={isLoading}
|
|
815
906
|
height={200}
|