@campxdev/react-blueprint 1.1.5 → 1.1.7
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/.prettierrc +8 -0
- package/package.json +4 -1
- package/src/App.tsx +26 -10
- package/src/components/Assets/Icons/IconComponents/AcademicIcon.tsx +41 -0
- package/src/components/Assets/Icons/IconComponents/AccordionArrow.tsx +23 -0
- package/src/components/Assets/Icons/IconComponents/DeleteIcon.tsx +58 -0
- package/src/components/Assets/Icons/IconComponents/EditIcon.tsx +43 -0
- package/src/components/Assets/Icons/IconComponents/NoteIcon.tsx +41 -0
- package/src/components/Assets/Icons/IconComponents/RedirectIcon.tsx +36 -0
- package/src/components/Assets/Icons/IconComponents/ViewIcon.tsx +34 -0
- package/src/components/Assets/Icons/Icons.tsx +68 -55
- package/src/components/Charts/BarChart/BarChart.tsx +33 -9
- package/src/components/Charts/LineChart/LineChart.tsx +10 -4
- package/src/components/Charts/PieChart/PieChart.tsx +3 -2
- package/src/components/Charts/TreeMap/TreeMap.tsx +1 -0
- package/src/components/Charts/export.ts +4 -0
- package/src/components/Charts/types/types.ts +12 -2
- package/src/components/DataDisplay/Accordion/Accordion.tsx +42 -46
- package/src/components/DataDisplay/AccordionGroup/AccordionGroup.tsx +30 -0
- package/src/components/DataDisplay/Avatar/Avatar.tsx +18 -29
- package/src/components/DataDisplay/Card/Card.tsx +29 -8
- package/src/components/DataDisplay/Chips/Chips.tsx +91 -0
- package/src/components/DataDisplay/DataTable/DataTable.tsx +14 -6
- package/src/components/DataDisplay/export.ts +6 -5
- package/src/components/DataDisplay/styles.tsx +2 -3
- package/src/components/Feedback/Snackbar/Snackbar.tsx +6 -5
- package/src/components/Input/DatePicker/DatePicker.tsx +58 -0
- package/src/components/Input/FormActions/FormActions.tsx +49 -0
- package/src/components/Input/FormControlWrapper/FormControlWrapper.tsx +70 -0
- package/src/components/Input/IconButtons/IconButtons/DeleteButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons/EditButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons/RedirectButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons/ViewButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons.tsx +11 -0
- package/src/components/Input/LabelWrapper/LabelWrapper.tsx +1 -1
- package/src/components/Input/SingleSelect/SingleSelect.tsx +43 -54
- package/src/components/Input/{Chips/Chips.tsx → Tags/Tags.tsx} +14 -14
- package/src/components/Input/TimePicker/TimePicker.tsx +39 -0
- package/src/components/Input/export.ts +13 -8
- package/src/components/Layout/PageContent/PageContent.tsx +16 -0
- package/src/components/Layout/PageHeader/PageHeader.tsx +46 -0
- package/src/components/Navigation/DropDownMenu/DropDownButton.tsx +5 -5
- package/src/components/Navigation/Sidebar/Components.tsx +97 -0
- package/src/components/Navigation/Sidebar/MenuItem.tsx +76 -104
- package/src/components/Navigation/Sidebar/Sidebar.tsx +150 -55
- package/src/components/Navigation/Sidebar/SubMenuItem.tsx +34 -0
- package/src/components/Navigation/Sidebar/interfaces.ts +35 -12
- package/src/components/Navigation/Sidebar/styles.tsx +2 -2
- package/src/components/Navigation/exports.ts +2 -0
- package/src/components/export.ts +1 -1
- package/src/stories/DataDisplay/AccordionGroup.stories.tsx +131 -0
- package/src/stories/DataDisplay/Chips.stories.tsx +77 -0
- package/src/stories/Input/DatePicker.stories.tsx +138 -0
- package/src/stories/Input/IconButtons.stories.tsx +30 -0
- package/src/stories/Input/{Chips.stories.tsx → Tags.stories.tsx} +17 -17
- package/src/stories/Input/TimePicker.stories.tsx +123 -0
- package/src/themes/commonTheme.ts +171 -155
- package/src/components/DataDisplay/Accordion/utils/StandardImageList.tsx +0 -70
- package/src/components/Navigation/Sidebar/DropdownItem.tsx +0 -34
- package/src/stories/DataDisplay/Accordion.stories.tsx +0 -62
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Stack,
|
|
7
7
|
useTheme,
|
|
8
8
|
} from "@mui/material";
|
|
9
|
+
import { capitalize } from "lodash";
|
|
9
10
|
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
10
11
|
import { Icons } from "../../export";
|
|
11
12
|
|
|
@@ -50,13 +51,13 @@ export const Snackbar = ({ ...props }: SnackbarProps) => {
|
|
|
50
51
|
const getIcon = (variant: Severity) => {
|
|
51
52
|
switch (variant) {
|
|
52
53
|
case "success":
|
|
53
|
-
return <Icons.SuccessFilledIcon />;
|
|
54
|
+
return <Icons.SuccessFilledIcon size={20} />;
|
|
54
55
|
case "error":
|
|
55
|
-
return <Icons.AlertFilledIcon />;
|
|
56
|
+
return <Icons.AlertFilledIcon size={20} />;
|
|
56
57
|
case "info":
|
|
57
|
-
return <Icons.InfoFilledIcon />;
|
|
58
|
+
return <Icons.InfoFilledIcon size={20} />;
|
|
58
59
|
case "warning":
|
|
59
|
-
return <Icons.WarningFilledIcon />;
|
|
60
|
+
return <Icons.WarningFilledIcon size={20} />;
|
|
60
61
|
}
|
|
61
62
|
};
|
|
62
63
|
|
|
@@ -93,7 +94,7 @@ export const Snackbar = ({ ...props }: SnackbarProps) => {
|
|
|
93
94
|
<Box sx={{ marginTop: "2px" }}>{getIcon(props.severity)}</Box>
|
|
94
95
|
<Stack direction={"column"}>
|
|
95
96
|
<Typography variant="subtitle2">
|
|
96
|
-
{props.severity
|
|
97
|
+
{capitalize(props.severity)}
|
|
97
98
|
</Typography>
|
|
98
99
|
<Typography variant="body2">{props.message}</Typography>
|
|
99
100
|
</Stack>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { StackProps } from '@mui/material';
|
|
2
|
+
import { PickersShortcutsItem, PickerValidDate } from '@mui/x-date-pickers';
|
|
3
|
+
import { DatePicker as MuiDatePicker, DatePickerProps as MuiDatePickerProps } from '@mui/x-date-pickers/DatePicker';
|
|
4
|
+
import { format as DateFnsFormat } from 'date-fns';
|
|
5
|
+
import { Icons } from '../../Assets/Icons/Icons';
|
|
6
|
+
import { LabelWrapper } from '../LabelWrapper/LabelWrapper';
|
|
7
|
+
|
|
8
|
+
type DatePickerProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false> = {
|
|
9
|
+
format?: 'yyyy' | 'MMMM yyyy' | 'dd MMMM yyyy' | 'dd/MM/yyyy';
|
|
10
|
+
views?: ('year' | 'month' | 'day')[];
|
|
11
|
+
helperText?: string;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
shortcutsItems?: PickersShortcutsItem<any>[];
|
|
14
|
+
required?: boolean;
|
|
15
|
+
containerProps?: StackProps;
|
|
16
|
+
openPickerIcon?: React.ElementType;
|
|
17
|
+
} & MuiDatePickerProps<TDate, TEnableAccessibleFieldDOMStructure>;
|
|
18
|
+
|
|
19
|
+
export const DatePicker = <TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false>({
|
|
20
|
+
label,
|
|
21
|
+
name,
|
|
22
|
+
value,
|
|
23
|
+
required = false,
|
|
24
|
+
format = 'dd/MM/yyyy',
|
|
25
|
+
views = ['year', 'month', 'day'],
|
|
26
|
+
helperText,
|
|
27
|
+
placeholder = '',
|
|
28
|
+
shortcutsItems = [],
|
|
29
|
+
openPickerIcon: Icon = Icons.NoteIcon,
|
|
30
|
+
containerProps,
|
|
31
|
+
...rest
|
|
32
|
+
}: DatePickerProps<TDate, TEnableAccessibleFieldDOMStructure>) => {
|
|
33
|
+
return (
|
|
34
|
+
<LabelWrapper label={label} required={required} name={name} containerProps={containerProps}>
|
|
35
|
+
<MuiDatePicker
|
|
36
|
+
format={format}
|
|
37
|
+
views={views}
|
|
38
|
+
defaultValue={value}
|
|
39
|
+
slotProps={{
|
|
40
|
+
textField: {
|
|
41
|
+
helperText,
|
|
42
|
+
placeholder,
|
|
43
|
+
},
|
|
44
|
+
shortcuts: {
|
|
45
|
+
items: shortcutsItems,
|
|
46
|
+
},
|
|
47
|
+
}}
|
|
48
|
+
slots={{
|
|
49
|
+
openPickerIcon: Icon,
|
|
50
|
+
}}
|
|
51
|
+
dayOfWeekFormatter={(day: any) => {
|
|
52
|
+
return `${DateFnsFormat(day, 'EEEE').slice(0, 2)}.`;
|
|
53
|
+
}}
|
|
54
|
+
{...rest}
|
|
55
|
+
/>
|
|
56
|
+
</LabelWrapper>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ButtonProps, Stack, StackProps, useTheme } from '@mui/material';
|
|
2
|
+
import { Button } from '../export';
|
|
3
|
+
|
|
4
|
+
export interface ButtonConfig {
|
|
5
|
+
title: string;
|
|
6
|
+
onClick?: () => void;
|
|
7
|
+
show?: boolean;
|
|
8
|
+
variant?: ButtonProps['variant'];
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface FormActionsProps {
|
|
13
|
+
submitButtonProps?: ButtonConfig;
|
|
14
|
+
cancelButtonProps?: ButtonConfig;
|
|
15
|
+
stackProps?: StackProps;
|
|
16
|
+
showTopBorder?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function FormActions({ submitButtonProps, cancelButtonProps, stackProps, showTopBorder = false }: FormActionsProps) {
|
|
20
|
+
const theme = useTheme();
|
|
21
|
+
const defaultSubmitProps: ButtonConfig = {
|
|
22
|
+
title: 'Submit',
|
|
23
|
+
show: true,
|
|
24
|
+
variant: 'contained',
|
|
25
|
+
...submitButtonProps,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const defaultCancelProps: ButtonConfig = {
|
|
29
|
+
title: 'Cancel',
|
|
30
|
+
show: true,
|
|
31
|
+
variant: 'text',
|
|
32
|
+
...cancelButtonProps,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Stack
|
|
37
|
+
direction="row"
|
|
38
|
+
padding={2}
|
|
39
|
+
gap={2.5}
|
|
40
|
+
borderTop={showTopBorder ? `1px solid ${theme.palette.border.primary}` : 'none'}
|
|
41
|
+
{...stackProps}
|
|
42
|
+
>
|
|
43
|
+
{defaultSubmitProps.show && <Button {...defaultSubmitProps}>{defaultSubmitProps.title}</Button>}
|
|
44
|
+
{defaultCancelProps.show && <Button {...defaultCancelProps}>{defaultCancelProps.title}</Button>}
|
|
45
|
+
</Stack>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default FormActions;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { TextFieldProps } from '@mui/material/TextField';
|
|
2
|
+
import React, { ReactElement, ReactNode, isValidElement } from 'react';
|
|
3
|
+
import { Control, Controller } from 'react-hook-form';
|
|
4
|
+
import FormActions, { FormActionsProps } from '../FormActions/FormActions';
|
|
5
|
+
|
|
6
|
+
interface FormControlWrapperProps {
|
|
7
|
+
control: Control<any>;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
formActionProps?: FormActionsProps;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type FormElementProps = {
|
|
13
|
+
checked?: boolean;
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
} & TextFieldProps;
|
|
16
|
+
|
|
17
|
+
type ControlledElementProps = {
|
|
18
|
+
name: string;
|
|
19
|
+
error?: boolean;
|
|
20
|
+
helperText?: ReactNode;
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
[key: string]: any;
|
|
23
|
+
} & TextFieldProps;
|
|
24
|
+
|
|
25
|
+
export function FormControlWrapper({ control, children, formActionProps }: FormControlWrapperProps) {
|
|
26
|
+
const wrapWithController = (element: ReactElement<any>): ReactElement<any> => {
|
|
27
|
+
if (!isValidElement(element)) return element;
|
|
28
|
+
|
|
29
|
+
const { name, children: childElements, ...restProps } = element.props as ControlledElementProps;
|
|
30
|
+
|
|
31
|
+
if (name) {
|
|
32
|
+
return (
|
|
33
|
+
<Controller
|
|
34
|
+
name={name}
|
|
35
|
+
control={control}
|
|
36
|
+
render={({ field, fieldState: { error } }) => {
|
|
37
|
+
const additionalProps =
|
|
38
|
+
element.type === 'input' && restProps.type === 'checkbox' ? { checked: field.value } : { value: field.value };
|
|
39
|
+
return React.cloneElement(element, {
|
|
40
|
+
...restProps,
|
|
41
|
+
...field,
|
|
42
|
+
...additionalProps,
|
|
43
|
+
error: !!error,
|
|
44
|
+
helperText: error ? error.message : null,
|
|
45
|
+
children: childElements,
|
|
46
|
+
} as FormElementProps);
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (childElements) {
|
|
53
|
+
const wrappedChildren: ReactNode = React.Children.map(childElements as any, wrapWithController);
|
|
54
|
+
return React.cloneElement(element, {
|
|
55
|
+
...restProps,
|
|
56
|
+
children: wrappedChildren,
|
|
57
|
+
} as FormElementProps);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return element;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<>
|
|
65
|
+
{React.Children.map(children as any, wrapWithController) || null}
|
|
66
|
+
|
|
67
|
+
{formActionProps && <FormActions {...formActionProps} showTopBorder />}
|
|
68
|
+
</>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ButtonProps, IconButton } from "@mui/material";
|
|
2
|
+
import { Icons } from "../../../export";
|
|
3
|
+
|
|
4
|
+
export function RedirectButton({ disabled, ...props }: ButtonProps) {
|
|
5
|
+
return (
|
|
6
|
+
<IconButton {...props}>
|
|
7
|
+
<Icons.RedirectIcon />
|
|
8
|
+
</IconButton>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DeleteButton } from './IconButtons/DeleteButton';
|
|
2
|
+
import { EditButton } from './IconButtons/EditButton';
|
|
3
|
+
import { RedirectButton } from './IconButtons/RedirectButton';
|
|
4
|
+
import { ViewButton } from './IconButtons/ViewButton';
|
|
5
|
+
|
|
6
|
+
export const IconButtons = {
|
|
7
|
+
DeleteButton,
|
|
8
|
+
EditButton,
|
|
9
|
+
ViewButton,
|
|
10
|
+
RedirectButton,
|
|
11
|
+
};
|
|
@@ -16,7 +16,7 @@ export const LabelWrapper = ({
|
|
|
16
16
|
}) => {
|
|
17
17
|
const theme = useTheme();
|
|
18
18
|
return (
|
|
19
|
-
<Stack margin="
|
|
19
|
+
<Stack margin={" 8px 12px"} {...containerProps}>
|
|
20
20
|
{typeof label === "string" ? (
|
|
21
21
|
<Typography htmlFor={name} component="label" variant="label1">
|
|
22
22
|
{label}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
12
|
-
import { Spinner } from "../../Feedback/Spinner/Spinner";
|
|
13
|
-
import { TextField } from "../TextField/TextField";
|
|
14
|
-
import { FetchingOptionsLoader } from "../components/FetchingOptionsLoader";
|
|
15
|
-
import { OptionContainer } from "../styles";
|
|
1
|
+
import { axios as campxAxios } from '@campxdev/campx-web-utils';
|
|
2
|
+
import { BaseSelectProps, Box, Autocomplete as MuiAutocomplete, Paper, PaperProps } from '@mui/material';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import _ from 'lodash';
|
|
5
|
+
import { useEffect, useReducer } from 'react';
|
|
6
|
+
import { Typography } from '../../DataDisplay/Typography/Typography';
|
|
7
|
+
import { Spinner } from '../../Feedback/Spinner/Spinner';
|
|
8
|
+
import { TextField } from '../TextField/TextField';
|
|
9
|
+
import { FetchingOptionsLoader } from '../components/FetchingOptionsLoader';
|
|
10
|
+
import { OptionContainer } from '../styles';
|
|
16
11
|
|
|
17
12
|
function sleep(duration: number): Promise<void> {
|
|
18
13
|
return new Promise<void>((resolve) => {
|
|
@@ -28,9 +23,13 @@ export type SingleSelectProps = {
|
|
|
28
23
|
useCampxAxios: boolean;
|
|
29
24
|
required?: boolean;
|
|
30
25
|
label?: string;
|
|
26
|
+
name?: string;
|
|
31
27
|
value?: any;
|
|
32
28
|
getValue?: (option: any) => any;
|
|
33
|
-
|
|
29
|
+
onChange: (value: any) => void;
|
|
30
|
+
error?: any;
|
|
31
|
+
helperText?: string;
|
|
32
|
+
} & BaseSelectProps;
|
|
34
33
|
|
|
35
34
|
const CustomPaper = (props: PaperProps) => (
|
|
36
35
|
<Paper {...props}>
|
|
@@ -40,24 +39,18 @@ const CustomPaper = (props: PaperProps) => (
|
|
|
40
39
|
);
|
|
41
40
|
|
|
42
41
|
enum SingleSelectActionsTypes {
|
|
43
|
-
OPEN =
|
|
44
|
-
CLOSE =
|
|
45
|
-
LOAD_INTERNAL_OPTIONS_START =
|
|
46
|
-
LOAD_INTERNAL_OPTIONS_END =
|
|
47
|
-
LOAD_INITIAL_INTERNAL_OPTIONS_START =
|
|
48
|
-
LOAD_INITIAL_INTERNAL_OPTIONS_END =
|
|
49
|
-
SET_NETWORK_ERROR =
|
|
50
|
-
SET_INTERNAL_OPTIONS =
|
|
51
|
-
APPEND_INTERNAL_OPTIONS =
|
|
52
|
-
CHANGE_HAS_MORE_FLAG =
|
|
42
|
+
OPEN = 'open',
|
|
43
|
+
CLOSE = 'close',
|
|
44
|
+
LOAD_INTERNAL_OPTIONS_START = 'load_internal_options_start',
|
|
45
|
+
LOAD_INTERNAL_OPTIONS_END = 'load_internal_options_end',
|
|
46
|
+
LOAD_INITIAL_INTERNAL_OPTIONS_START = 'load_initial_internal_options_start',
|
|
47
|
+
LOAD_INITIAL_INTERNAL_OPTIONS_END = 'load_initial_internal_options_end',
|
|
48
|
+
SET_NETWORK_ERROR = 'set_network_error',
|
|
49
|
+
SET_INTERNAL_OPTIONS = 'set_internal_options',
|
|
50
|
+
APPEND_INTERNAL_OPTIONS = 'append_internal_options',
|
|
51
|
+
CHANGE_HAS_MORE_FLAG = 'change_has_more_flag',
|
|
53
52
|
}
|
|
54
|
-
const singleSelectReducer = (
|
|
55
|
-
state: any,
|
|
56
|
-
{
|
|
57
|
-
actionType,
|
|
58
|
-
stateChanges,
|
|
59
|
-
}: { actionType: SingleSelectActionsTypes; stateChanges?: any }
|
|
60
|
-
) => {
|
|
53
|
+
const singleSelectReducer = (state: any, { actionType, stateChanges }: { actionType: SingleSelectActionsTypes; stateChanges?: any }) => {
|
|
61
54
|
switch (actionType) {
|
|
62
55
|
case SingleSelectActionsTypes.OPEN: {
|
|
63
56
|
return { ...state, open: true };
|
|
@@ -118,8 +111,13 @@ export const SingleSelect = ({
|
|
|
118
111
|
useCampxAxios = true,
|
|
119
112
|
required = false,
|
|
120
113
|
label,
|
|
114
|
+
name,
|
|
121
115
|
getValue,
|
|
122
116
|
value,
|
|
117
|
+
onChange,
|
|
118
|
+
error,
|
|
119
|
+
helperText,
|
|
120
|
+
...restProps
|
|
123
121
|
}: SingleSelectProps) => {
|
|
124
122
|
const generateOptionsMap = (options: any[]) => {
|
|
125
123
|
return _.keyBy(options ?? [], getValue ? getValue : (o) => o.value);
|
|
@@ -135,15 +133,7 @@ export const SingleSelect = ({
|
|
|
135
133
|
offset: 0,
|
|
136
134
|
hasMore: true,
|
|
137
135
|
});
|
|
138
|
-
const {
|
|
139
|
-
open,
|
|
140
|
-
loadingInternalOptions,
|
|
141
|
-
loadingInitialInternalOptions,
|
|
142
|
-
internalOptions,
|
|
143
|
-
limit,
|
|
144
|
-
offset,
|
|
145
|
-
hasMore,
|
|
146
|
-
} = state;
|
|
136
|
+
const { open, loadingInternalOptions, loadingInitialInternalOptions, internalOptions, limit, offset, hasMore } = state;
|
|
147
137
|
|
|
148
138
|
const internalAxios = useCampxAxios ? campxAxios : axios;
|
|
149
139
|
|
|
@@ -188,17 +178,12 @@ export const SingleSelect = ({
|
|
|
188
178
|
|
|
189
179
|
const handleScroll = async (event: any) => {
|
|
190
180
|
const listboxNode = event.currentTarget;
|
|
191
|
-
if (
|
|
192
|
-
listboxNode.scrollTop + listboxNode.clientHeight >=
|
|
193
|
-
listboxNode.scrollHeight - 1 &&
|
|
194
|
-
hasMore &&
|
|
195
|
-
optionsApiEndPoint
|
|
196
|
-
) {
|
|
181
|
+
if (listboxNode.scrollTop + listboxNode.clientHeight >= listboxNode.scrollHeight - 1 && hasMore && optionsApiEndPoint) {
|
|
197
182
|
dispatch({
|
|
198
183
|
actionType: SingleSelectActionsTypes.LOAD_INTERNAL_OPTIONS_START,
|
|
199
184
|
});
|
|
200
185
|
const newOptions = await internalAxios
|
|
201
|
-
.get(optionsApiEndPoint ??
|
|
186
|
+
.get(optionsApiEndPoint ?? '', {
|
|
202
187
|
params: {
|
|
203
188
|
limit: limit,
|
|
204
189
|
offset: offset + 10,
|
|
@@ -226,7 +211,7 @@ export const SingleSelect = ({
|
|
|
226
211
|
actionType: SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_START,
|
|
227
212
|
});
|
|
228
213
|
try {
|
|
229
|
-
const res = await internalAxios.get(optionsApiEndPoint ??
|
|
214
|
+
const res = await internalAxios.get(optionsApiEndPoint ?? '', {
|
|
230
215
|
params: { limit, offset, selectedValue: value },
|
|
231
216
|
});
|
|
232
217
|
dispatch({
|
|
@@ -249,32 +234,36 @@ export const SingleSelect = ({
|
|
|
249
234
|
if (value && optionsApiEndPoint) {
|
|
250
235
|
fetchInitialOptions().finally(() => {
|
|
251
236
|
dispatch({
|
|
252
|
-
actionType:
|
|
253
|
-
SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_END,
|
|
237
|
+
actionType: SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_END,
|
|
254
238
|
});
|
|
255
239
|
});
|
|
256
240
|
}
|
|
257
241
|
}, []);
|
|
258
242
|
|
|
259
243
|
if (loadingInitialInternalOptions) {
|
|
260
|
-
console.log("Rendered Loading");
|
|
261
244
|
return (
|
|
262
245
|
<TextField
|
|
263
246
|
label={label}
|
|
247
|
+
name={name}
|
|
264
248
|
required={required}
|
|
265
249
|
InputProps={{
|
|
266
250
|
endAdornment: <Spinner />,
|
|
267
251
|
}}
|
|
252
|
+
error={error}
|
|
253
|
+
helperText={helperText}
|
|
268
254
|
/>
|
|
269
255
|
);
|
|
270
256
|
}
|
|
271
257
|
return (
|
|
272
258
|
<MuiAutocomplete
|
|
259
|
+
onChange={(e, value) => {
|
|
260
|
+
onChange(getValue ? getValue(value) : value?.value);
|
|
261
|
+
}}
|
|
273
262
|
open={open}
|
|
274
263
|
autoFocus={true}
|
|
275
264
|
value={state.internalOptionsMap[value]}
|
|
276
265
|
renderInput={(params) => (
|
|
277
|
-
<TextField {...params} label={label} required={required} />
|
|
266
|
+
<TextField {...params} label={label} required={required} name={name} error={error} helperText={helperText} />
|
|
278
267
|
)}
|
|
279
268
|
PaperComponent={CustomPaper}
|
|
280
269
|
renderOption={(props, option: any) => {
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { Chip, styled } from
|
|
2
|
-
import { Typography } from
|
|
3
|
-
import { Icons } from
|
|
1
|
+
import { Chip, styled } from '@mui/material';
|
|
2
|
+
import { Typography } from '../../DataDisplay/Typography/Typography';
|
|
3
|
+
import { Icons } from '../../export';
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
display:
|
|
7
|
-
justifyContent:
|
|
8
|
-
flexWrap:
|
|
9
|
-
listStyle:
|
|
5
|
+
const TagList = styled('ul')(({ theme }) => ({
|
|
6
|
+
display: 'flex',
|
|
7
|
+
justifyContent: 'center',
|
|
8
|
+
flexWrap: 'wrap',
|
|
9
|
+
listStyle: 'none',
|
|
10
10
|
}));
|
|
11
11
|
|
|
12
|
-
export type
|
|
13
|
-
|
|
12
|
+
export type TagsProps = {
|
|
13
|
+
tags: { label: string; value: any }[];
|
|
14
14
|
onClick?: (clickedChip: any) => void;
|
|
15
15
|
onDelete?: (deletedChip: any) => void;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export const
|
|
18
|
+
export const Tags = ({ tags, onClick, onDelete }: TagsProps) => {
|
|
19
19
|
return (
|
|
20
|
-
<
|
|
21
|
-
{
|
|
20
|
+
<TagList>
|
|
21
|
+
{tags.map(({ label, value }) => (
|
|
22
22
|
<Chip
|
|
23
23
|
label={<Typography variant="body2">{label}</Typography>}
|
|
24
24
|
onClick={
|
|
@@ -38,6 +38,6 @@ export const Chips = ({ chips, onClick, onDelete }: ChipsProps) => {
|
|
|
38
38
|
deleteIcon={<Icons.CrossIcon />}
|
|
39
39
|
/>
|
|
40
40
|
))}
|
|
41
|
-
</
|
|
41
|
+
</TagList>
|
|
42
42
|
);
|
|
43
43
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { PickerValidDate } from '@mui/x-date-pickers';
|
|
2
|
+
import { TimePicker as MuiTimePicker, TimePickerProps as MuiTimePickerProps } from '@mui/x-date-pickers/TimePicker';
|
|
3
|
+
import { LabelWrapper } from '../LabelWrapper/LabelWrapper';
|
|
4
|
+
|
|
5
|
+
type TimePickerProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false> = {
|
|
6
|
+
format?: 'hh:mm a' | 'HH:mm' | 'HH:mm:ss a' | 'HH:mm:ss';
|
|
7
|
+
views?: ('hours' | 'minutes' | 'seconds')[];
|
|
8
|
+
helperText?: string;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
required?: boolean;
|
|
11
|
+
containerProps?: any;
|
|
12
|
+
} & MuiTimePickerProps<TDate, TEnableAccessibleFieldDOMStructure>;
|
|
13
|
+
|
|
14
|
+
export const TimePicker = <TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false>({
|
|
15
|
+
label,
|
|
16
|
+
name,
|
|
17
|
+
value,
|
|
18
|
+
format = 'hh:mm a',
|
|
19
|
+
views = ['hours', 'minutes'],
|
|
20
|
+
helperText,
|
|
21
|
+
placeholder = '',
|
|
22
|
+
required = false,
|
|
23
|
+
containerProps,
|
|
24
|
+
...rest
|
|
25
|
+
}: TimePickerProps<TDate, TEnableAccessibleFieldDOMStructure>) => {
|
|
26
|
+
return (
|
|
27
|
+
<LabelWrapper label={label} required={required} name={name} containerProps={containerProps}>
|
|
28
|
+
<MuiTimePicker
|
|
29
|
+
defaultValue={value}
|
|
30
|
+
format={format}
|
|
31
|
+
views={views}
|
|
32
|
+
slotProps={{
|
|
33
|
+
textField: { placeholder, helperText },
|
|
34
|
+
}}
|
|
35
|
+
{...rest}
|
|
36
|
+
/>
|
|
37
|
+
</LabelWrapper>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
1
|
+
export * from './Button/Button';
|
|
2
|
+
export * from './DatePicker/DatePicker';
|
|
3
|
+
export * from './FormActions/FormActions';
|
|
4
|
+
export * from './FormControlWrapper/FormControlWrapper';
|
|
5
|
+
export * from './IconButtons/IconButtons';
|
|
6
|
+
export * from './MultiCheckBox/MultiCheckBox';
|
|
7
|
+
export * from './PasswordField/PasswordField';
|
|
8
|
+
export * from './SearchBar/SearchBar';
|
|
9
|
+
export * from './SingleCheckBox/SIngleCheckBox';
|
|
10
|
+
export * from './SingleSelect/SingleSelect';
|
|
11
|
+
export * from './Switch/Switch';
|
|
12
|
+
export * from './TextField/TextField';
|
|
13
|
+
export * from './TimePicker/TimePicker';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Box, BoxProps, styled } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
const StyledPageContent = styled(Box)(({ theme }) => ({
|
|
4
|
+
padding: '1rem',
|
|
5
|
+
flex: 1,
|
|
6
|
+
display: 'flex',
|
|
7
|
+
flexDirection: 'column',
|
|
8
|
+
borderRadius: '10px',
|
|
9
|
+
overflowY: 'auto',
|
|
10
|
+
backgroundColor: theme.palette.surface.paperBackground,
|
|
11
|
+
height: '100%',
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
export function PageContent(props: BoxProps) {
|
|
15
|
+
return <StyledPageContent {...props}>{props.children}</StyledPageContent>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Box, styled, Typography } from '@mui/material';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { Breadcrumbs } from '../../Navigation/Breadcrumbs/Breadcrumbs';
|
|
4
|
+
|
|
5
|
+
interface BreadCrumbsLink {
|
|
6
|
+
name: string | ReactNode;
|
|
7
|
+
to: string;
|
|
8
|
+
}
|
|
9
|
+
interface PageHeaderProps {
|
|
10
|
+
title?: string | ReactNode;
|
|
11
|
+
actions?: ReactNode;
|
|
12
|
+
links?: BreadCrumbsLink[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const StyledBox = styled(Box)(({ theme }) => ({
|
|
16
|
+
minHeight: '40px',
|
|
17
|
+
display: 'flex',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
justifyContent: 'space-between',
|
|
20
|
+
margin: '0',
|
|
21
|
+
flexWrap: 'wrap',
|
|
22
|
+
'& .actions': {
|
|
23
|
+
display: 'flex',
|
|
24
|
+
gap: '1rem',
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
marginLeft: 'auto',
|
|
27
|
+
'& .MuiButton-root': {
|
|
28
|
+
height: '40px',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
export default function PageHeader({ title, actions, links }: PageHeaderProps) {
|
|
34
|
+
return (
|
|
35
|
+
<StyledBox>
|
|
36
|
+
<>
|
|
37
|
+
{links && links.length > 0 ? (
|
|
38
|
+
<Breadcrumbs links={links} />
|
|
39
|
+
) : (
|
|
40
|
+
<>{typeof title === 'string' ? <Typography variant="subtitle2">{title}</Typography> : title}</>
|
|
41
|
+
)}
|
|
42
|
+
</>
|
|
43
|
+
<Box className="actions">{actions}</Box>
|
|
44
|
+
</StyledBox>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { KeyboardArrowDown } from
|
|
2
|
-
import { Button, ButtonProps } from
|
|
1
|
+
import { KeyboardArrowDown } from '@mui/icons-material'
|
|
2
|
+
import { Button, ButtonProps } from '../../Input/Button/Button'
|
|
3
3
|
|
|
4
4
|
export const DropDownButton = (props: ButtonProps) => {
|
|
5
5
|
return (
|
|
6
|
-
<Button
|
|
7
|
-
)
|
|
8
|
-
}
|
|
6
|
+
<Button variant="outlined" endIcon={<KeyboardArrowDown />} {...props} />
|
|
7
|
+
)
|
|
8
|
+
}
|