@scality/core-ui 0.153.0 → 0.155.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/buttonv2/Buttonv2.component.js +1 -1
- package/dist/components/emptystate/Emptystate.component.js +3 -3
- package/dist/components/icon/Icon.component.d.ts +1 -0
- package/dist/components/icon/Icon.component.d.ts.map +1 -1
- package/dist/components/icon/Icon.component.js +1 -0
- package/dist/components/inputlist/InputList.component.d.ts +2 -13
- package/dist/components/inputlist/InputList.component.d.ts.map +1 -1
- package/dist/components/inputv2/inputv2.js +7 -7
- package/dist/components/linetemporalchart/MetricTimespanProvider.d.ts +4 -3
- package/dist/components/linetemporalchart/MetricTimespanProvider.d.ts.map +1 -1
- package/dist/components/linetemporalchart/MetricTimespanProvider.js +3 -4
- package/dist/components/tablev2/SearchWithQueryParams.js +3 -3
- package/dist/components/tablev2/TableCommon.d.ts +1 -1
- package/dist/components/tablev2/TableCommon.d.ts.map +1 -1
- package/dist/components/tabsv2/Tabsv2.component.d.ts +2 -3
- package/dist/components/tabsv2/Tabsv2.component.d.ts.map +1 -1
- package/dist/components/tabsv2/Tabsv2.component.js +26 -25
- package/dist/components/toast/ToastProvider.d.ts +1 -1
- package/dist/components/toast/ToastProvider.d.ts.map +1 -1
- package/dist/organisms/attachments/AttachmentConfirmationModal.d.ts +3 -3
- package/dist/organisms/attachments/AttachmentConfirmationModal.d.ts.map +1 -1
- package/dist/organisms/attachments/AttachmentConfirmationModal.js +7 -7
- package/package.json +9 -8
- package/setupTests.js +4 -0
- package/src/lib/components/buttonv2/Buttonv2.component.tsx +3 -3
- package/src/lib/components/emptystate/Emptystate.component.tsx +3 -3
- package/src/lib/components/icon/Icon.component.tsx +1 -0
- package/src/lib/components/inputlist/InputList.component.tsx +1 -1
- package/src/lib/components/inputv2/inputv2.tsx +7 -7
- package/src/lib/components/linetemporalchart/MetricTimespanProvider.tsx +6 -6
- package/src/lib/components/tablev2/SearchWithQueryParams.tsx +3 -3
- package/src/lib/components/tablev2/TableCommon.tsx +3 -1
- package/src/lib/components/tablev2/Tablev2.component.tsx +2 -2
- package/src/lib/components/tabsv2/Tabsv2.component.tsx +64 -56
- package/src/lib/components/toast/ToastProvider.tsx +1 -1
- package/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx +10 -8
|
@@ -25,10 +25,10 @@ export const ButtonStyled = styled.button `
|
|
|
25
25
|
text-decoration: none;
|
|
26
26
|
font-family: 'Lato';
|
|
27
27
|
font-weight: ${fontWeight.base};
|
|
28
|
-
|
|
29
28
|
padding: ${spacing.r4} ${spacing.r8};
|
|
30
29
|
font-size: ${fontSize.base};
|
|
31
30
|
border-radius: ${spacing.r4};
|
|
31
|
+
white-space: nowrap;
|
|
32
32
|
height: ${(props) => (props.size === 'inline' ? spacing.r24 : spacing.r32)};
|
|
33
33
|
${(props) => {
|
|
34
34
|
const brand = props.theme;
|
|
@@ -4,7 +4,7 @@ import { spacing } from '../../spacing';
|
|
|
4
4
|
import { Button } from '../buttonv2/Buttonv2.component';
|
|
5
5
|
import { Icon } from '../icon/Icon.component';
|
|
6
6
|
import { LargeText } from '../text/Text.component';
|
|
7
|
-
import {
|
|
7
|
+
import { useNavigate } from 'react-router';
|
|
8
8
|
const EmptystateContainer = styled.div `
|
|
9
9
|
${(props) => {
|
|
10
10
|
const { theme, backgroundColor } = props;
|
|
@@ -31,9 +31,9 @@ export const ActionWrapper = styled.div `
|
|
|
31
31
|
`;
|
|
32
32
|
function EmptyState(props) {
|
|
33
33
|
const { icon, listedResource, link, resourceToCreate, backgroundColor } = props;
|
|
34
|
-
const
|
|
34
|
+
const navigate = useNavigate();
|
|
35
35
|
return (_jsxs(EmptystateContainer, { className: "sc-emptystate", backgroundColor: backgroundColor, children: [_jsx(EmptyStateRow, { children: _jsx(Icon, { name: icon, color: "infoPrimary", size: "5x", withWrapper: true }) }), _jsx(EmptyStateRow, { children: _jsx(LargeText, { children: `A list of ${listedResource.plural} will appear here.` }) }), _jsx(EmptyStateRow, { children: _jsx(LargeText, { children: !resourceToCreate
|
|
36
36
|
? `There are no ${listedResource.plural} created yet, let's create your first ${listedResource.singular}.`
|
|
37
|
-
: `Before browsing your ${listedResource.plural}, create your first ${resourceToCreate}.` }) }), link && (_jsx(ActionWrapper, { children: _jsx(Button, { label: `Create ${resourceToCreate || listedResource.singular}`, icon: _jsx(Icon, { name: "Create-add" }), type: "button", variant: "primary", onClick: () =>
|
|
37
|
+
: `Before browsing your ${listedResource.plural}, create your first ${resourceToCreate}.` }) }), link && (_jsx(ActionWrapper, { children: _jsx(Button, { label: `Create ${resourceToCreate || listedResource.singular}`, icon: _jsx(Icon, { name: "Create-add" }), type: "button", variant: "primary", onClick: () => navigate(link) }) }))] }));
|
|
38
38
|
}
|
|
39
39
|
export { EmptyState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/icon/Icon.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAE7D,OAAO,EACL,aAAa,EAKd,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,eAAO,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"Icon.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/icon/Icon.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAE7D,OAAO,EACL,aAAa,EAKd,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6HrB,CAAC;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;CAOvB,CAAC;AAaF,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AACzE,MAAM,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC;AAC1C,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAiBF,eAAO,MAAM,WAAW;UAAsB,QAAQ;SAiCrD,CAAC;AAyEF,iBAAS,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,2CAU7C;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -129,6 +129,7 @@ export const iconTable = {
|
|
|
129
129
|
Ring: 'fas faRing',
|
|
130
130
|
Stop: 'fas faStop',
|
|
131
131
|
Play: 'fas faPlay',
|
|
132
|
+
Mail: 'fas faEnvelope',
|
|
132
133
|
};
|
|
133
134
|
export const customIcons = {
|
|
134
135
|
'Remote-user': ({ ariaLabel, color, size }) => (_jsx(RemoteUser, { ariaLabel: ariaLabel, color: color, size: size })),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HTMLProps } from 'react';
|
|
2
2
|
import { RefCallBack } from 'react-hook-form';
|
|
3
3
|
export type InputListProps<T> = Omit<HTMLProps<HTMLInputElement>, 'size'> & {
|
|
4
|
-
ref
|
|
4
|
+
ref?: RefCallBack;
|
|
5
5
|
min?: string | number;
|
|
6
6
|
max?: string | number;
|
|
7
7
|
maxLength?: number;
|
|
@@ -12,16 +12,5 @@ export type InputListProps<T> = Omit<HTMLProps<HTMLInputElement>, 'size'> & {
|
|
|
12
12
|
maxItems?: number;
|
|
13
13
|
value: T[];
|
|
14
14
|
};
|
|
15
|
-
export declare const InputList: import("react").ForwardRefExoticComponent<Omit<
|
|
16
|
-
ref: RefCallBack;
|
|
17
|
-
min?: string | number;
|
|
18
|
-
max?: string | number;
|
|
19
|
-
maxLength?: number;
|
|
20
|
-
minLength?: number;
|
|
21
|
-
pattern?: string;
|
|
22
|
-
required?: boolean;
|
|
23
|
-
disabled?: boolean;
|
|
24
|
-
maxItems?: number;
|
|
25
|
-
value: (string | number | readonly string[] | undefined)[];
|
|
26
|
-
}, "ref"> & import("react").RefAttributes<unknown>>;
|
|
15
|
+
export declare const InputList: import("react").ForwardRefExoticComponent<Omit<InputListProps<string | number | readonly string[] | undefined>, "ref"> & import("react").RefAttributes<unknown>>;
|
|
27
16
|
//# sourceMappingURL=InputList.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputList.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputlist/InputList.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG;IAC1E,GAAG,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"InputList.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputlist/InputList.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG;IAC1E,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,CAAC,EAAE,CAAC;CACZ,CAAC;AAgFF,eAAO,MAAM,SAAS,kKAAgC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
|
-
import styled from 'styled-components';
|
|
3
|
+
import styled, { css } from 'styled-components';
|
|
4
4
|
import { spacing } from '../../spacing';
|
|
5
5
|
import { DESCRIPTION_PREFIX, useFieldContext } from '../form/Form.component';
|
|
6
6
|
import { Icon } from '../icon/Icon.component';
|
|
@@ -57,12 +57,12 @@ const InputContainer = styled.div `
|
|
|
57
57
|
padding: 0 ${spacing.r8} 0 ${spacing.r8};
|
|
58
58
|
background: ${(props) => props.theme.backgroundLevel1};
|
|
59
59
|
border-radius: ${spacing.r4};
|
|
60
|
-
${(props) => props.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
${(props) => props.disabled
|
|
61
|
+
? css `
|
|
62
|
+
opacity: 0.5;
|
|
63
|
+
cursor: not-allowed;
|
|
64
|
+
`
|
|
65
|
+
: ''}
|
|
66
66
|
`;
|
|
67
67
|
const InputBorder = styled.div `
|
|
68
68
|
box-sizing: border-box;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { QueryTimeSpan } from '../constants';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
2
|
+
import { useLocation } from 'react-router';
|
|
3
|
+
export declare const MetricsTimeSpanContext: import("react").Context<QueryTimeSpan | null>;
|
|
4
|
+
export declare const MetricsTimeSpanProvider: ({ children, location, }: {
|
|
5
5
|
children: JSX.Element;
|
|
6
|
+
location?: ReturnType<typeof useLocation>;
|
|
6
7
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export declare const useMetricsTimeSpan: () => QueryTimeSpan;
|
|
8
9
|
//# sourceMappingURL=MetricTimespanProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricTimespanProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/components/linetemporalchart/MetricTimespanProvider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MetricTimespanProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/components/linetemporalchart/MetricTimespanProvider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAuB,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,eAAO,MAAM,sBAAsB,+CAA4C,CAAC;AAChF,eAAO,MAAM,uBAAuB,4BAGjC;IACD,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CAC3C,4CA4BA,CAAC;AACF,eAAO,MAAM,kBAAkB,QAAO,aAUrC,CAAC"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { useLocation } from 'react-router-dom';
|
|
2
|
+
import { createContext, useContext, useEffect, useState } from 'react';
|
|
4
3
|
import { queryTimeSpansCodes } from '../constants';
|
|
5
4
|
export const MetricsTimeSpanContext = createContext(null);
|
|
6
|
-
export const MetricsTimeSpanProvider = ({ children, }) => {
|
|
5
|
+
export const MetricsTimeSpanProvider = ({ children, location, }) => {
|
|
7
6
|
// the default timespan is the last 24h
|
|
8
7
|
const [queryTimeSpanCode, setQueryTimeSpanCode] = useState(queryTimeSpansCodes[1]);
|
|
9
|
-
const urlSearchParams = new URLSearchParams(
|
|
8
|
+
const urlSearchParams = new URLSearchParams(location === null || location === void 0 ? void 0 : location.search);
|
|
10
9
|
const queryTimeSpan = urlSearchParams.get('from');
|
|
11
10
|
// Sync url timespan to local timespan
|
|
12
11
|
useEffect(() => {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { useLocation,
|
|
3
|
+
import { useLocation, useNavigate } from 'react-router';
|
|
4
4
|
import { TableSearch as Search } from './Search';
|
|
5
5
|
export function SearchWithQueryParams(props) {
|
|
6
6
|
const { queryParams = 'search', onChange, ...rest } = props;
|
|
7
7
|
const { search, pathname } = useLocation();
|
|
8
|
-
const
|
|
8
|
+
const navigate = useNavigate();
|
|
9
9
|
const params = new URLSearchParams(search);
|
|
10
10
|
const initialValue = params.get(queryParams) || '';
|
|
11
11
|
const [value, setValue] = useState(initialValue);
|
|
12
12
|
function handleOnChange(value) {
|
|
13
13
|
const { onChange } = props;
|
|
14
14
|
params.set(queryParams, value);
|
|
15
|
-
|
|
15
|
+
navigate(`${pathname}?${params.toString()}`, { replace: true });
|
|
16
16
|
setValue(value);
|
|
17
17
|
if (typeof onChange === 'function') {
|
|
18
18
|
onChange(value);
|
|
@@ -5,7 +5,7 @@ import { TableHeightKeyType, TableLocalType } from './TableUtils';
|
|
|
5
5
|
import { CSSProperties } from 'styled-components';
|
|
6
6
|
type VirtualizedRowsType<DATA_ROW extends Record<string, unknown> = Record<string, unknown>> = {
|
|
7
7
|
rows: Row<DATA_ROW>[];
|
|
8
|
-
RenderRow: ComponentType<ListChildComponentProps<Row<DATA_ROW>[]
|
|
8
|
+
RenderRow: ComponentType<React.PropsWithChildren<ListChildComponentProps<Row<DATA_ROW>[]>>>;
|
|
9
9
|
rowHeight: TableHeightKeyType;
|
|
10
10
|
setHasScrollbar: React.Dispatch<React.SetStateAction<boolean>>;
|
|
11
11
|
hasScrollbar?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableCommon.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tablev2/TableCommon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,SAAS,EAAyB,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,OAAO,EACL,aAAa,EAEb,uBAAuB,EACvB,mBAAmB,EACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,kBAAkB,EAClB,cAAc,EAEf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,KAAK,mBAAmB,CACtB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAChE;IACF,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtB,SAAS,EAAE,aAAa,CAAC,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"TableCommon.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tablev2/TableCommon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,SAAS,EAAyB,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,OAAO,EACL,aAAa,EAEb,uBAAuB,EACvB,mBAAmB,EACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,kBAAkB,EAClB,cAAc,EAEf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,KAAK,mBAAmB,CACtB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAChE;IACF,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtB,SAAS,EAAE,aAAa,CACtB,KAAK,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAClE,CAAC;IACF,SAAS,EAAE,kBAAkB,CAAC;IAC9B,eAAe,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,0HAUvC,mBAAmB,CAAC,QAAQ,CAAC,4CAmC/B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;CAwB7B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,KAAK,cAAc,CACjB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAChE;IACF,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC;IAClD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC;IAC1D,SAAS,EAAE,KAAK,CAAC,mBAAmB,CAClC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,aAAa,KAAK,GAAG,CAAC,OAAO,CACjD,CAAC;CACH,CAAC;AACF,wBAAgB,SAAS,CACvB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,kDAyEzE"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { ReactElement } from 'react';
|
|
2
|
-
import { Tab } from './Tab';
|
|
3
|
-
import { TabProps } from './Tab';
|
|
2
|
+
import { Tab, TabProps } from './Tab';
|
|
4
3
|
type TabsProps = {
|
|
5
4
|
activeTabColor?: string;
|
|
6
5
|
activeTabSeparator?: string;
|
|
@@ -17,5 +16,5 @@ declare function Tabs({ activeTabColor, activeTabSeparator, tabLineColor, inacti
|
|
|
17
16
|
declare namespace Tabs {
|
|
18
17
|
var Tab: typeof import("./Tab").Tab;
|
|
19
18
|
}
|
|
20
|
-
export {
|
|
19
|
+
export { Tab, Tabs };
|
|
21
20
|
//# sourceMappingURL=Tabsv2.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabsv2.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tabsv2/Tabsv2.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"Tabsv2.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tabsv2/Tabsv2.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,YAAY,EAIb,MAAM,OAAO,CAAC;AAsBf,OAAO,EAAS,GAAG,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG7C,KAAK,SAAS,GAAG;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,WAAW,wBAAgC,CAAC;AAMzD,iBAAS,IAAI,CAAC,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,SAAS,2CAuMX;kBAlNQ,IAAI;;;AAsNb,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import React, { createContext, useEffect, useState,
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
2
|
+
import React, { createContext, useCallback, useEffect, useState, } from 'react';
|
|
3
|
+
import { matchPath, Outlet, Route, Routes, useLocation, useNavigate, } from 'react-router';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { ButtonIcon } from '../buttonv2/Buttonv2.component';
|
|
6
|
+
import { BasicText, EmphaseText, SecondaryText } from '../text/Text.component';
|
|
6
7
|
import { ScrollButton } from './ScrollButton';
|
|
8
|
+
import { ScrollableContainer, TabBar, TabContent, TabItem, TabsContainer, TabsScroller, } from './StyledTabs';
|
|
7
9
|
import { Tab } from './Tab';
|
|
8
10
|
import { useScrollingTabs } from './useScrollingTabs';
|
|
9
|
-
import { ButtonIcon } from '../buttonv2/Buttonv2.component';
|
|
10
|
-
import styled from 'styled-components';
|
|
11
11
|
export const TabsContext = createContext(false);
|
|
12
12
|
const TabIcon = styled(ButtonIcon) `
|
|
13
13
|
color: ${(props) => props.theme.textSecondary};
|
|
14
14
|
`;
|
|
15
15
|
function Tabs({ activeTabColor, activeTabSeparator, tabLineColor, inactiveTabColor, tabContentColor, separatorColor, tabHoverColor, children, className, ...rest }) {
|
|
16
16
|
const location = useLocation();
|
|
17
|
-
const
|
|
18
|
-
const
|
|
17
|
+
const navigate = useNavigate();
|
|
18
|
+
const url = location.pathname;
|
|
19
19
|
const [selectedTabIndex, setSelectedTabIndex] = useState(null);
|
|
20
20
|
const queryURL = new URLSearchParams(location.search);
|
|
21
21
|
const filteredTabsChildren = React.Children.toArray(children).filter((child) => React.isValidElement(child) && child.type === Tab);
|
|
@@ -41,22 +41,19 @@ function Tabs({ activeTabColor, activeTabSeparator, tabLineColor, inactiveTabCol
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
const getPushHistoryPath = (path, query) => {
|
|
44
|
+
const sanitizedSegment = path.replace(/^\/+/, '');
|
|
45
|
+
const replaceUrl = location.pathname.replace(/[^/]+$/, sanitizedSegment);
|
|
44
46
|
if (path.startsWith('/')) {
|
|
45
|
-
return `${
|
|
47
|
+
return `${replaceUrl}${serialize(query)}`;
|
|
46
48
|
}
|
|
47
|
-
return `${
|
|
49
|
+
return `${path}${serialize(query)}`;
|
|
48
50
|
};
|
|
49
51
|
useEffect(() => {
|
|
50
52
|
let hasSelectedTab = false;
|
|
51
53
|
filteredTabsChildren.forEach((child, index) => {
|
|
52
|
-
const isSelected = !!matchPath(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
: url + '/' + child.props.path,
|
|
56
|
-
exact: child.props.exact,
|
|
57
|
-
strict: child.props.strict,
|
|
58
|
-
sensitive: child.props.sensitive,
|
|
59
|
-
}) && (child.props.query ? matchQuery(child.props.query) : true);
|
|
54
|
+
const isSelected = !!matchPath((child.props.path.startsWith('/')
|
|
55
|
+
? child.props.path
|
|
56
|
+
: url + '/' + child.props.path) + '*', location.pathname) && (child.props.query ? matchQuery(child.props.query) : true);
|
|
60
57
|
if (isSelected) {
|
|
61
58
|
setSelectedTabIndex(index);
|
|
62
59
|
hasSelectedTab = true;
|
|
@@ -69,20 +66,24 @@ function Tabs({ activeTabColor, activeTabSeparator, tabLineColor, inactiveTabCol
|
|
|
69
66
|
const tabItems = filteredTabsChildren.map((child, index) => {
|
|
70
67
|
const { path, query, label, textBadge, children, icon, ...childRest } = child.props;
|
|
71
68
|
const isSelected = selectedTabIndex === index;
|
|
72
|
-
|
|
69
|
+
const realPath = path.startsWith('/') ? `/${path.split('/').pop()}` : path;
|
|
70
|
+
return (_jsxs(TabItem, { className: `sc-tabs-item ${isSelected ? 'selected' : ''}`, role: "tab", onClick: () => navigate(getPushHistoryPath(realPath, query)), selected: isSelected, tabHoverColor: tabHoverColor, inactiveTabColor: inactiveTabColor, activeTabColor: activeTabColor, activeTabSeparator: activeTabSeparator, tabIndex: isSelected ? 0 : -1, onKeyDown: (event) => {
|
|
73
71
|
if (event.key === ' ' ||
|
|
74
72
|
event.key === 'Enter' ||
|
|
75
73
|
event.key === 'Spacebar') {
|
|
76
74
|
event.preventDefault();
|
|
77
|
-
|
|
75
|
+
navigate(getPushHistoryPath(realPath, query));
|
|
78
76
|
}
|
|
79
77
|
}, ...childRest, children: [icon && _jsx(TabIcon, { label: label, children: icon }), isSelected ? (_jsx(BasicText, { children: label })) : (_jsx(SecondaryText, { children: label })), textBadge && _jsx(EmphaseText, { children: textBadge })] }, index));
|
|
80
78
|
});
|
|
81
|
-
return (_jsx(TabsContext.Provider, { value: true, children: _jsxs(TabsContainer, { style: { containerType: 'size' }, className: ['sc-tabs', className].join(' '), tabLineColor: tabLineColor, separatorColor: separatorColor, ...rest, children: [_jsxs(ScrollableContainer, { children: [displayScroll.start && (_jsx(ScrollButton, { ref: scrollButtonStartRef, direction: "left", onClick: handleStartScrollClick })), _jsx(TabsScroller, { ref: tabsRef, onScroll: handleTabsScroll, children: _jsx(TabBar, { onKeyDown: handleKeyDown, ref: tabsListRef, className: "sc-tabs-bar", role: "tablist", children: tabItems }) }), displayScroll.end && (_jsx(ScrollButton, { ref: scrollButtonEndRef, direction: "right", onClick: handleEndScrollClick }))] }), filteredTabsChildren.map((tab, index) =>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
return (_jsx(TabsContext.Provider, { value: true, children: _jsxs(TabsContainer, { style: { containerType: 'size' }, className: ['sc-tabs', className].join(' '), tabLineColor: tabLineColor, separatorColor: separatorColor, ...rest, children: [_jsxs(ScrollableContainer, { children: [displayScroll.start && (_jsx(ScrollButton, { ref: scrollButtonStartRef, direction: "left", onClick: handleStartScrollClick })), _jsx(TabsScroller, { ref: tabsRef, onScroll: handleTabsScroll, children: _jsx(TabBar, { onKeyDown: handleKeyDown, ref: tabsListRef, className: "sc-tabs-bar", role: "tablist", children: tabItems }) }), displayScroll.end && (_jsx(ScrollButton, { ref: scrollButtonEndRef, direction: "right", onClick: handleEndScrollClick }))] }), _jsx(Routes, { children: filteredTabsChildren.map((tab, index) => {
|
|
80
|
+
const path = tab.props.path.split('/').pop();
|
|
81
|
+
if (tab.props.query && !matchQuery(tab.props.query)) {
|
|
82
|
+
return _jsx(_Fragment, {});
|
|
83
|
+
}
|
|
84
|
+
return (_jsx(Route, { path: tab.props.path.startsWith('/') ? '/' + path : path, element: _jsxs(_Fragment, { children: [_jsx(TabContent, { className: "sc-tabs-item-content", tabContentColor: tabContentColor, withoutPadding: tab.props.withoutPadding, children: tab.props.children }), _jsx(Outlet, {})] }) }, index));
|
|
85
|
+
}) })] }) }));
|
|
85
86
|
}
|
|
86
87
|
Tabs.Tab = Tab;
|
|
87
88
|
// re-export Tab
|
|
88
|
-
export {
|
|
89
|
+
export { Tab, Tabs };
|
|
@@ -8,7 +8,7 @@ export declare const ToastContext: import("react").Context<ToastContextType | un
|
|
|
8
8
|
interface ToastProviderProps {
|
|
9
9
|
children: ReactNode;
|
|
10
10
|
}
|
|
11
|
-
export declare const ToastProvider: React.FC<ToastProviderProps
|
|
11
|
+
export declare const ToastProvider: React.FC<React.PropsWithChildren<ToastProviderProps>>;
|
|
12
12
|
export declare const useToast: () => ToastContextType;
|
|
13
13
|
export {};
|
|
14
14
|
//# sourceMappingURL=ToastProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/components/toast/ToastProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuC,MAAM,OAAO,CAAC;AACvE,OAAO,EAAS,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,YAAY,uDAExB,CAAC;AAEF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB;AACD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"ToastProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/components/toast/ToastProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuC,MAAM,OAAO,CAAC;AACvE,OAAO,EAAS,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,YAAY,uDAExB,CAAC;AAEF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB;AACD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAe/E,CAAC;AAEF,eAAO,MAAM,QAAQ,wBAMpB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
2
|
import { UseMutationOptions } from 'react-query';
|
|
3
|
-
import {
|
|
3
|
+
import { AttachmentAction, AttachmentOperation } from './AttachmentTypes';
|
|
4
4
|
export declare function AttachmentConfirmationModal<ENTITY_TYPE, RESOURCE_TYPE, ENTITY extends Record<string, unknown> = Record<string, unknown>>({ attachmentOperations, getAttachmentMutationOptions, resourceType, resourceName, redirectUrl, EntityIcon, cancelButtonDisabled, onCancel, onExit, }: {
|
|
5
5
|
attachmentOperations: AttachmentOperation<ENTITY_TYPE, ENTITY>[];
|
|
6
6
|
getAttachmentMutationOptions: () => UseMutationOptions<unknown, unknown, {
|
|
@@ -13,9 +13,9 @@ export declare function AttachmentConfirmationModal<ENTITY_TYPE, RESOURCE_TYPE,
|
|
|
13
13
|
resourceName: string;
|
|
14
14
|
resourceType: RESOURCE_TYPE;
|
|
15
15
|
redirectUrl: string;
|
|
16
|
-
EntityIcon: ComponentType<{
|
|
16
|
+
EntityIcon: ComponentType<React.PropsWithChildren<{
|
|
17
17
|
type: ENTITY_TYPE | RESOURCE_TYPE;
|
|
18
|
-
}
|
|
18
|
+
}>>;
|
|
19
19
|
cancelButtonDisabled?: boolean;
|
|
20
20
|
onCancel?: () => void;
|
|
21
21
|
onExit?: (successfullOperations: AttachmentOperation<ENTITY_TYPE, ENTITY>[], failedOperations: AttachmentOperation<ENTITY_TYPE, ENTITY>[]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachmentConfirmationModal.d.ts","sourceRoot":"","sources":["../../../src/lib/organisms/attachments/AttachmentConfirmationModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAY,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AttachmentConfirmationModal.d.ts","sourceRoot":"","sources":["../../../src/lib/organisms/attachments/AttachmentConfirmationModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAY,MAAM,OAAO,CAAC;AAChD,OAAO,EAAe,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAM9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAK1E,wBAAgB,2BAA2B,CACzC,WAAW,EACX,aAAa,EACb,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,EACA,oBAAoB,EACpB,4BAA4B,EAC5B,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,QAAQ,EACR,MAAM,GACP,EAAE;IACD,oBAAoB,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;IACjE,4BAA4B,EAAE,MAAM,kBAAkB,CACpD,OAAO,EACP,OAAO,EACP;QACE,MAAM,EAAE,gBAAgB,CAAC;QACzB,IAAI,EAAE,WAAW,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CACF,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,aAAa,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,aAAa,CACvB,KAAK,CAAC,iBAAiB,CAAC;QAAE,IAAI,EAAE,WAAW,GAAG,aAAa,CAAA;KAAE,CAAC,CAC/D,CAAC;IACF,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,CACP,qBAAqB,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EACjE,gBAAgB,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,KACzD,IAAI,CAAC;CACX,2CA0QA"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { Table } from '../../components/tablev2/Tablev2.component';
|
|
4
|
-
import { Box, Button } from '../../next';
|
|
5
3
|
import { useMutation } from 'react-query';
|
|
6
|
-
import {
|
|
4
|
+
import { useNavigate } from 'react-router';
|
|
7
5
|
import { useTheme } from 'styled-components';
|
|
8
|
-
import { useHistory } from 'react-router';
|
|
9
6
|
import { Icon, LargerText, Modal, SecondaryText, Stack, Wrap } from '../..';
|
|
7
|
+
import { Table } from '../../components/tablev2/Tablev2.component';
|
|
8
|
+
import { Box, Button } from '../../next';
|
|
9
|
+
import { AttachmentAction } from './AttachmentTypes';
|
|
10
10
|
//The entity is the "thing" you want to attach to the resource, sorry about the naming :(
|
|
11
11
|
export function AttachmentConfirmationModal({ attachmentOperations, getAttachmentMutationOptions, resourceType, resourceName, redirectUrl, EntityIcon, cancelButtonDisabled, onCancel, onExit, }) {
|
|
12
|
-
const
|
|
12
|
+
const navigate = useNavigate();
|
|
13
13
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
14
14
|
const handleClose = () => {
|
|
15
15
|
setIsModalOpen(false);
|
|
@@ -73,7 +73,7 @@ export function AttachmentConfirmationModal({ attachmentOperations, getAttachmen
|
|
|
73
73
|
onExit(successfulOperations, failedOperations);
|
|
74
74
|
}
|
|
75
75
|
handleClose();
|
|
76
|
-
|
|
76
|
+
navigate(redirectUrl);
|
|
77
77
|
};
|
|
78
78
|
const modalFooter = () => {
|
|
79
79
|
return (_jsxs(Wrap, { children: [_jsx("p", {}), _jsx(_Fragment, { children: isAttachNotDone ? (_jsxs(Stack, { children: [_jsx(Button, { variant: "outline", onClick: handleClose, label: "Cancel" }), _jsx(Button, { icon: _jsx(Icon, { name: "Arrow-right" }), variant: "primary", onClick: attach, label: "Confirm", disabled: attachmentMutation.isLoading })] })) : (_jsx(Button, { icon: _jsx(Icon, { name: "Arrow-right" }), variant: "primary", onClick: () => {
|
|
@@ -135,7 +135,7 @@ export function AttachmentConfirmationModal({ attachmentOperations, getAttachmen
|
|
|
135
135
|
return (_jsxs(_Fragment, { children: [_jsx(Button, { label: "Cancel", variant: "outline", disabled: cancelButtonDisabled, onClick: () => {
|
|
136
136
|
if (onCancel)
|
|
137
137
|
onCancel();
|
|
138
|
-
|
|
138
|
+
navigate(redirectUrl);
|
|
139
139
|
} }), _jsx(Button, { icon: _jsx(Icon, { name: "Save" }), label: "Save", onClick: () => {
|
|
140
140
|
setAttachmentOperationsStatuses({});
|
|
141
141
|
setIsModalOpen(true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scality/core-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.155.0",
|
|
4
4
|
"description": "Scality common React component library",
|
|
5
5
|
"author": "Scality Engineering",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"@storybook/storybook-deployer": "^2.8.16",
|
|
50
50
|
"@storybook/theming": "^8.3.6",
|
|
51
51
|
"@testing-library/jest-dom": "^5.14.1",
|
|
52
|
-
"@testing-library/react": "^
|
|
52
|
+
"@testing-library/react": "^15.0.7",
|
|
53
53
|
"@testing-library/react-hooks": "^8.0.1",
|
|
54
54
|
"@testing-library/user-event": "^13.5.0",
|
|
55
55
|
"@types/jest": "^27.5.0",
|
|
56
|
-
"@types/react": "^
|
|
57
|
-
"@types/react-dom": "^
|
|
56
|
+
"@types/react": "^18.3.12",
|
|
57
|
+
"@types/react-dom": "^18.3.1",
|
|
58
58
|
"@types/react-router": "^5.1.20",
|
|
59
59
|
"@types/react-router-dom": "^5.3.3",
|
|
60
60
|
"@types/react-table": "^7.7.11",
|
|
@@ -110,16 +110,17 @@
|
|
|
110
110
|
"framer-motion": "^4.1.17",
|
|
111
111
|
"polished": "3.4.1",
|
|
112
112
|
"pretty-bytes": "^5.6.0",
|
|
113
|
-
"react": "^
|
|
113
|
+
"react": "^18.3.1",
|
|
114
114
|
"react-debounce-input": "3.2.2",
|
|
115
|
-
"react-dom": "^
|
|
115
|
+
"react-dom": "^18.3.1",
|
|
116
116
|
"react-dropzone": "^14.2.3",
|
|
117
117
|
"react-hook-form": "^7.49.2",
|
|
118
118
|
"react-query": "^3.34.0",
|
|
119
|
-
"react-router": "
|
|
120
|
-
"react-router-dom": "
|
|
119
|
+
"react-router": "7.0.1",
|
|
120
|
+
"react-router-dom": "7.0.1",
|
|
121
121
|
"react-select": "4.3.1",
|
|
122
122
|
"react-table": "^7.7.0",
|
|
123
|
+
"react-test-renderer": "^18.3.1",
|
|
123
124
|
"react-virtualized": "9.22.3",
|
|
124
125
|
"react-virtualized-auto-sizer": "^1.0.24",
|
|
125
126
|
"react-window": "^1.8.6",
|
package/setupTests.js
CHANGED
|
@@ -40,10 +40,10 @@ export const ButtonStyled = styled.button<Props>`
|
|
|
40
40
|
text-decoration: none;
|
|
41
41
|
font-family: 'Lato';
|
|
42
42
|
font-weight: ${fontWeight.base};
|
|
43
|
-
|
|
44
43
|
padding: ${spacing.r4} ${spacing.r8};
|
|
45
44
|
font-size: ${fontSize.base};
|
|
46
45
|
border-radius: ${spacing.r4};
|
|
46
|
+
white-space: nowrap;
|
|
47
47
|
height: ${(props) => (props.size === 'inline' ? spacing.r24 : spacing.r32)};
|
|
48
48
|
${(props) => {
|
|
49
49
|
const brand = props.theme;
|
|
@@ -198,8 +198,8 @@ export const ButtonLoader = styled(Loader)<{ label; variant }>`
|
|
|
198
198
|
fill: ${props.variant === 'danger'
|
|
199
199
|
? props.theme.statusCritical
|
|
200
200
|
: props.variant === 'outline'
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
? props.theme.textPrimary
|
|
202
|
+
: props.theme.textSecondary};
|
|
203
203
|
}
|
|
204
204
|
`;
|
|
205
205
|
}}
|
|
@@ -4,7 +4,7 @@ import { Button } from '../buttonv2/Buttonv2.component';
|
|
|
4
4
|
import { Icon, IconName } from '../icon/Icon.component';
|
|
5
5
|
import { LargeText } from '../text/Text.component';
|
|
6
6
|
import { CoreUITheme } from '../../style/theme';
|
|
7
|
-
import {
|
|
7
|
+
import { useNavigate } from 'react-router';
|
|
8
8
|
|
|
9
9
|
export type Props = {
|
|
10
10
|
listedResource: {
|
|
@@ -48,7 +48,7 @@ export const ActionWrapper = styled.div`
|
|
|
48
48
|
function EmptyState(props: Props) {
|
|
49
49
|
const { icon, listedResource, link, resourceToCreate, backgroundColor } =
|
|
50
50
|
props;
|
|
51
|
-
const
|
|
51
|
+
const navigate = useNavigate();
|
|
52
52
|
return (
|
|
53
53
|
<EmptystateContainer
|
|
54
54
|
className="sc-emptystate"
|
|
@@ -74,7 +74,7 @@ function EmptyState(props: Props) {
|
|
|
74
74
|
icon={<Icon name="Create-add" />}
|
|
75
75
|
type="button"
|
|
76
76
|
variant="primary"
|
|
77
|
-
onClick={() =>
|
|
77
|
+
onClick={() => navigate(link)}
|
|
78
78
|
/>
|
|
79
79
|
</ActionWrapper>
|
|
80
80
|
)}
|
|
@@ -5,7 +5,7 @@ import { Input } from '../inputv2/inputv2';
|
|
|
5
5
|
import { AddButton, SubButton } from './InputButtons';
|
|
6
6
|
|
|
7
7
|
export type InputListProps<T> = Omit<HTMLProps<HTMLInputElement>, 'size'> & {
|
|
8
|
-
ref
|
|
8
|
+
ref?: RefCallBack;
|
|
9
9
|
min?: string | number;
|
|
10
10
|
max?: string | number;
|
|
11
11
|
maxLength?: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { forwardRef, InputHTMLAttributes } from 'react';
|
|
2
|
-
import styled from 'styled-components';
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
3
|
import { spacing } from '../../spacing';
|
|
4
4
|
import { DESCRIPTION_PREFIX, useFieldContext } from '../form/Form.component';
|
|
5
5
|
import { Icon, IconName } from '../icon/Icon.component';
|
|
@@ -62,12 +62,12 @@ const InputContainer = styled.div<{
|
|
|
62
62
|
background: ${(props) => props.theme.backgroundLevel1};
|
|
63
63
|
border-radius: ${spacing.r4};
|
|
64
64
|
${(props) =>
|
|
65
|
-
props.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
props.disabled
|
|
66
|
+
? css`
|
|
67
|
+
opacity: 0.5;
|
|
68
|
+
cursor: not-allowed;
|
|
69
|
+
`
|
|
70
|
+
: ''}
|
|
71
71
|
`;
|
|
72
72
|
|
|
73
73
|
const InputBorder = styled.div<{
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { useLocation } from 'react-router
|
|
4
|
-
import { QueryTimeSpan } from '../constants';
|
|
5
|
-
import { queryTimeSpansCodes } from '../constants';
|
|
1
|
+
import { createContext, useContext, useEffect, useState } from 'react';
|
|
2
|
+
import { QueryTimeSpan, queryTimeSpansCodes } from '../constants';
|
|
3
|
+
import { useLocation } from 'react-router';
|
|
6
4
|
export const MetricsTimeSpanContext = createContext<QueryTimeSpan | null>(null);
|
|
7
5
|
export const MetricsTimeSpanProvider = ({
|
|
8
6
|
children,
|
|
7
|
+
location,
|
|
9
8
|
}: {
|
|
10
9
|
children: JSX.Element;
|
|
10
|
+
location?: ReturnType<typeof useLocation>;
|
|
11
11
|
}) => {
|
|
12
12
|
// the default timespan is the last 24h
|
|
13
13
|
const [queryTimeSpanCode, setQueryTimeSpanCode] = useState(
|
|
14
14
|
queryTimeSpansCodes[1],
|
|
15
15
|
);
|
|
16
|
-
const urlSearchParams = new URLSearchParams(
|
|
16
|
+
const urlSearchParams = new URLSearchParams(location?.search);
|
|
17
17
|
const queryTimeSpan = urlSearchParams.get('from');
|
|
18
18
|
// Sync url timespan to local timespan
|
|
19
19
|
useEffect(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { useLocation,
|
|
2
|
+
import { useLocation, useNavigate } from 'react-router';
|
|
3
3
|
import { TableSearch as Search, SearchProps } from './Search';
|
|
4
4
|
|
|
5
5
|
export type SearchWithQueryParamsProps = {
|
|
@@ -10,7 +10,7 @@ export type SearchWithQueryParamsProps = {
|
|
|
10
10
|
export function SearchWithQueryParams(props: SearchWithQueryParamsProps) {
|
|
11
11
|
const { queryParams = 'search', onChange, ...rest } = props;
|
|
12
12
|
const { search, pathname } = useLocation();
|
|
13
|
-
const
|
|
13
|
+
const navigate = useNavigate();
|
|
14
14
|
const params = new URLSearchParams(search);
|
|
15
15
|
const initialValue = params.get(queryParams) || '';
|
|
16
16
|
const [value, setValue] = useState(initialValue);
|
|
@@ -18,7 +18,7 @@ export function SearchWithQueryParams(props: SearchWithQueryParamsProps) {
|
|
|
18
18
|
function handleOnChange(value: string) {
|
|
19
19
|
const { onChange } = props;
|
|
20
20
|
params.set(queryParams, value);
|
|
21
|
-
|
|
21
|
+
navigate(`${pathname}?${params.toString()}`, { replace: true });
|
|
22
22
|
setValue(value);
|
|
23
23
|
|
|
24
24
|
if (typeof onChange === 'function') {
|
|
@@ -22,7 +22,9 @@ type VirtualizedRowsType<
|
|
|
22
22
|
DATA_ROW extends Record<string, unknown> = Record<string, unknown>,
|
|
23
23
|
> = {
|
|
24
24
|
rows: Row<DATA_ROW>[];
|
|
25
|
-
RenderRow: ComponentType<
|
|
25
|
+
RenderRow: ComponentType<
|
|
26
|
+
React.PropsWithChildren<ListChildComponentProps<Row<DATA_ROW>[]>>
|
|
27
|
+
>;
|
|
26
28
|
rowHeight: TableHeightKeyType;
|
|
27
29
|
setHasScrollbar: React.Dispatch<React.SetStateAction<boolean>>;
|
|
28
30
|
hasScrollbar?: boolean;
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
createContext,
|
|
3
|
+
ReactElement,
|
|
4
|
+
useCallback,
|
|
3
5
|
useEffect,
|
|
4
6
|
useState,
|
|
5
|
-
useCallback,
|
|
6
|
-
ReactElement,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
matchPath,
|
|
10
|
+
Outlet,
|
|
11
|
+
Route,
|
|
12
|
+
Routes,
|
|
13
|
+
useLocation,
|
|
14
|
+
useNavigate,
|
|
15
|
+
useRoutes,
|
|
16
|
+
} from 'react-router';
|
|
17
|
+
import styled from 'styled-components';
|
|
18
|
+
import { ButtonIcon } from '../buttonv2/Buttonv2.component';
|
|
19
|
+
import { BasicText, EmphaseText, SecondaryText } from '../text/Text.component';
|
|
20
|
+
import { ScrollButton } from './ScrollButton';
|
|
21
|
+
import {
|
|
10
22
|
ScrollableContainer,
|
|
23
|
+
TabBar,
|
|
11
24
|
TabContent,
|
|
12
25
|
TabItem,
|
|
13
26
|
TabsContainer,
|
|
14
27
|
TabsScroller,
|
|
15
28
|
} from './StyledTabs';
|
|
16
|
-
import {
|
|
17
|
-
useHistory,
|
|
18
|
-
useLocation,
|
|
19
|
-
useRouteMatch,
|
|
20
|
-
matchPath,
|
|
21
|
-
Route,
|
|
22
|
-
Switch,
|
|
23
|
-
} from 'react-router-dom';
|
|
24
|
-
import { SecondaryText, BasicText, EmphaseText } from '../text/Text.component';
|
|
25
|
-
import { ScrollButton } from './ScrollButton';
|
|
26
|
-
import { Tab } from './Tab';
|
|
27
|
-
import { TabProps, Query } from './Tab';
|
|
29
|
+
import { Query, Tab, TabProps } from './Tab';
|
|
28
30
|
import { useScrollingTabs } from './useScrollingTabs';
|
|
29
|
-
import { ButtonIcon } from '../buttonv2/Buttonv2.component';
|
|
30
|
-
import styled from 'styled-components';
|
|
31
31
|
|
|
32
32
|
type TabsProps = {
|
|
33
33
|
activeTabColor?: string;
|
|
@@ -59,8 +59,8 @@ function Tabs({
|
|
|
59
59
|
...rest
|
|
60
60
|
}: TabsProps) {
|
|
61
61
|
const location = useLocation();
|
|
62
|
-
const
|
|
63
|
-
const
|
|
62
|
+
const navigate = useNavigate();
|
|
63
|
+
const url = location.pathname;
|
|
64
64
|
const [selectedTabIndex, setSelectedTabIndex] = useState<
|
|
65
65
|
number | null | undefined
|
|
66
66
|
>(null);
|
|
@@ -101,24 +101,26 @@ function Tabs({
|
|
|
101
101
|
};
|
|
102
102
|
|
|
103
103
|
const getPushHistoryPath = (path: string, query?: Query): string => {
|
|
104
|
+
const sanitizedSegment = path.replace(/^\/+/, '');
|
|
105
|
+
const replaceUrl = location.pathname.replace(/[^/]+$/, sanitizedSegment);
|
|
106
|
+
|
|
104
107
|
if (path.startsWith('/')) {
|
|
105
|
-
return `${
|
|
108
|
+
return `${replaceUrl}${serialize(query)}`;
|
|
106
109
|
}
|
|
107
|
-
|
|
110
|
+
|
|
111
|
+
return `${path}${serialize(query)}`;
|
|
108
112
|
};
|
|
109
113
|
|
|
110
114
|
useEffect(() => {
|
|
111
115
|
let hasSelectedTab = false;
|
|
112
116
|
filteredTabsChildren.forEach((child, index) => {
|
|
113
117
|
const isSelected =
|
|
114
|
-
!!matchPath(
|
|
115
|
-
|
|
118
|
+
!!matchPath(
|
|
119
|
+
(child.props.path.startsWith('/')
|
|
116
120
|
? child.props.path
|
|
117
|
-
: url + '/' + child.props.path,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
sensitive: child.props.sensitive,
|
|
121
|
-
}) && (child.props.query ? matchQuery(child.props.query) : true);
|
|
121
|
+
: url + '/' + child.props.path) + '*',
|
|
122
|
+
location.pathname,
|
|
123
|
+
) && (child.props.query ? matchQuery(child.props.query) : true);
|
|
122
124
|
|
|
123
125
|
if (isSelected) {
|
|
124
126
|
setSelectedTabIndex(index);
|
|
@@ -127,6 +129,7 @@ function Tabs({
|
|
|
127
129
|
});
|
|
128
130
|
if (!hasSelectedTab) setSelectedTabIndex(null);
|
|
129
131
|
}, [location.pathname, filteredTabsChildren, matchQuery]);
|
|
132
|
+
|
|
130
133
|
const {
|
|
131
134
|
scrollButtonEndRef,
|
|
132
135
|
scrollButtonStartRef,
|
|
@@ -138,6 +141,7 @@ function Tabs({
|
|
|
138
141
|
handleKeyDown,
|
|
139
142
|
displayScroll,
|
|
140
143
|
} = useScrollingTabs(selectedTabIndex);
|
|
144
|
+
|
|
141
145
|
const tabItems = filteredTabsChildren.map((child, index) => {
|
|
142
146
|
const {
|
|
143
147
|
path,
|
|
@@ -149,12 +153,13 @@ function Tabs({
|
|
|
149
153
|
...childRest
|
|
150
154
|
}: TabProps = child.props;
|
|
151
155
|
const isSelected = selectedTabIndex === index;
|
|
156
|
+
const realPath = path.startsWith('/') ? `/${path.split('/').pop()}` : path;
|
|
152
157
|
return (
|
|
153
158
|
<TabItem
|
|
154
159
|
className={`sc-tabs-item ${isSelected ? 'selected' : ''}`}
|
|
155
160
|
key={index}
|
|
156
161
|
role="tab"
|
|
157
|
-
onClick={() =>
|
|
162
|
+
onClick={() => navigate(getPushHistoryPath(realPath, query))}
|
|
158
163
|
selected={isSelected}
|
|
159
164
|
tabHoverColor={tabHoverColor}
|
|
160
165
|
inactiveTabColor={inactiveTabColor}
|
|
@@ -168,7 +173,7 @@ function Tabs({
|
|
|
168
173
|
event.key === 'Spacebar'
|
|
169
174
|
) {
|
|
170
175
|
event.preventDefault();
|
|
171
|
-
|
|
176
|
+
navigate(getPushHistoryPath(realPath, query));
|
|
172
177
|
}
|
|
173
178
|
}}
|
|
174
179
|
{...childRest}
|
|
@@ -218,33 +223,36 @@ function Tabs({
|
|
|
218
223
|
/>
|
|
219
224
|
)}
|
|
220
225
|
</ScrollableContainer>
|
|
226
|
+
<Routes>
|
|
227
|
+
{filteredTabsChildren.map((tab, index) => {
|
|
228
|
+
const path = tab.props.path.split('/').pop();
|
|
221
229
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
exact={tab.props.exact}
|
|
225
|
-
sensitive={tab.props.sensitive}
|
|
226
|
-
strict={tab.props.strict}
|
|
227
|
-
path={
|
|
228
|
-
tab.props.path.startsWith('/')
|
|
229
|
-
? tab.props.path
|
|
230
|
-
: url + '/' + tab.props.path
|
|
230
|
+
if (tab.props.query && !matchQuery(tab.props.query)) {
|
|
231
|
+
return <></>;
|
|
231
232
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<Route
|
|
236
|
+
key={index}
|
|
237
|
+
path={
|
|
238
|
+
tab.props.path.startsWith('/') ? '/' + path : path
|
|
239
|
+
}
|
|
240
|
+
element={
|
|
241
|
+
<>
|
|
242
|
+
<TabContent
|
|
243
|
+
className="sc-tabs-item-content"
|
|
244
|
+
tabContentColor={tabContentColor}
|
|
245
|
+
withoutPadding={tab.props.withoutPadding}
|
|
246
|
+
>
|
|
247
|
+
{tab.props.children}
|
|
248
|
+
</TabContent>
|
|
249
|
+
<Outlet />
|
|
250
|
+
</>
|
|
251
|
+
}
|
|
252
|
+
/>
|
|
253
|
+
);
|
|
254
|
+
})}
|
|
255
|
+
</Routes>
|
|
248
256
|
</TabsContainer>
|
|
249
257
|
</TabsContext.Provider>
|
|
250
258
|
);
|
|
@@ -252,4 +260,4 @@ function Tabs({
|
|
|
252
260
|
|
|
253
261
|
Tabs.Tab = Tab;
|
|
254
262
|
// re-export Tab
|
|
255
|
-
export {
|
|
263
|
+
export { Tab, Tabs };
|
|
@@ -14,7 +14,7 @@ export const ToastContext = createContext<ToastContextType | undefined>(
|
|
|
14
14
|
interface ToastProviderProps {
|
|
15
15
|
children: ReactNode;
|
|
16
16
|
}
|
|
17
|
-
export const ToastProvider: React.FC<ToastProviderProps
|
|
17
|
+
export const ToastProvider: React.FC<React.PropsWithChildren<ToastProviderProps>> = ({ children }) => {
|
|
18
18
|
const [toastProps, setToastProps] = useState<ToastContextState | null>(null);
|
|
19
19
|
|
|
20
20
|
const showToast = (toastProps: ToastContextState) => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ComponentType, useState } from 'react';
|
|
2
|
-
import { Column, Table } from '../../components/tablev2/Tablev2.component';
|
|
3
|
-
import { Box, Button } from '../../next';
|
|
4
2
|
import { useMutation, UseMutationOptions } from 'react-query';
|
|
5
|
-
import {
|
|
3
|
+
import { useNavigate } from 'react-router';
|
|
6
4
|
import { useTheme } from 'styled-components';
|
|
7
|
-
import { useHistory } from 'react-router';
|
|
8
5
|
import { Icon, LargerText, Modal, SecondaryText, Stack, Wrap } from '../..';
|
|
6
|
+
import { Column, Table } from '../../components/tablev2/Tablev2.component';
|
|
7
|
+
import { Box, Button } from '../../next';
|
|
8
|
+
import { AttachmentAction, AttachmentOperation } from './AttachmentTypes';
|
|
9
9
|
|
|
10
10
|
type AttachmentStatus = 'Waiting for confirmation' | 'Error' | 'Success';
|
|
11
11
|
|
|
@@ -40,7 +40,9 @@ export function AttachmentConfirmationModal<
|
|
|
40
40
|
resourceName: string;
|
|
41
41
|
resourceType: RESOURCE_TYPE;
|
|
42
42
|
redirectUrl: string;
|
|
43
|
-
EntityIcon: ComponentType<
|
|
43
|
+
EntityIcon: ComponentType<
|
|
44
|
+
React.PropsWithChildren<{ type: ENTITY_TYPE | RESOURCE_TYPE }>
|
|
45
|
+
>;
|
|
44
46
|
cancelButtonDisabled?: boolean;
|
|
45
47
|
onCancel?: () => void;
|
|
46
48
|
onExit?: (
|
|
@@ -48,7 +50,7 @@ export function AttachmentConfirmationModal<
|
|
|
48
50
|
failedOperations: AttachmentOperation<ENTITY_TYPE, ENTITY>[],
|
|
49
51
|
) => void;
|
|
50
52
|
}) {
|
|
51
|
-
const
|
|
53
|
+
const navigate = useNavigate();
|
|
52
54
|
|
|
53
55
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
54
56
|
|
|
@@ -133,7 +135,7 @@ export function AttachmentConfirmationModal<
|
|
|
133
135
|
onExit(successfulOperations, failedOperations);
|
|
134
136
|
}
|
|
135
137
|
handleClose();
|
|
136
|
-
|
|
138
|
+
navigate(redirectUrl);
|
|
137
139
|
};
|
|
138
140
|
const modalFooter = () => {
|
|
139
141
|
return (
|
|
@@ -282,7 +284,7 @@ export function AttachmentConfirmationModal<
|
|
|
282
284
|
disabled={cancelButtonDisabled}
|
|
283
285
|
onClick={() => {
|
|
284
286
|
if (onCancel) onCancel();
|
|
285
|
-
|
|
287
|
+
navigate(redirectUrl);
|
|
286
288
|
}}
|
|
287
289
|
/>
|
|
288
290
|
<Button
|