@dartech/arsenal-ui 0.0.1
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/.babelrc +12 -0
- package/.eslintrc.json +22 -0
- package/README.md +7 -0
- package/index.ts +3 -0
- package/jest.config.js +9 -0
- package/package.json +21 -0
- package/project.json +69 -0
- package/rollup.config.js +135 -0
- package/src/interfaces/common.ts +12 -0
- package/src/interfaces/definition.ts +143 -0
- package/src/interfaces/index.ts +3 -0
- package/src/interfaces/ui.ts +35 -0
- package/src/lib/Alert/Alert.tsx +108 -0
- package/src/lib/Alert/index.ts +1 -0
- package/src/lib/Definition/CreateDefinition/CreateDefinition.tsx +74 -0
- package/src/lib/Definition/CreateDefinition/index.ts +1 -0
- package/src/lib/Definition/DefinitionFiller/DefinitionFiller.tsx +85 -0
- package/src/lib/Definition/DefinitionFiller/WidgetDefinitionFiller.tsx +96 -0
- package/src/lib/Definition/DefinitionFiller/index.ts +2 -0
- package/src/lib/Definition/index.ts +2 -0
- package/src/lib/DemPropertyField/DemPropertyField.tsx +93 -0
- package/src/lib/DemPropertyField/DemPropertyView/DemPropertyView.tsx +44 -0
- package/src/lib/DemPropertyField/DemPropertyView/index.ts +1 -0
- package/src/lib/DemPropertyField/MultipleDemField/MultipleDemField.tsx +293 -0
- package/src/lib/DemPropertyField/MultipleDemField/index.tsx +1 -0
- package/src/lib/DemPropertyField/RestrictedValuesEditor.tsx +63 -0
- package/src/lib/DemPropertyField/SingleDemField/SingleDemField.tsx +156 -0
- package/src/lib/DemPropertyField/SingleDemField/index.ts +1 -0
- package/src/lib/DemPropertyField/index.ts +2 -0
- package/src/lib/DemPropertyField/styles.ts +50 -0
- package/src/lib/DemPropertyField/widgets/DemBooleanWidget.tsx +26 -0
- package/src/lib/DemPropertyField/widgets/DemDateTimeWidget.tsx +34 -0
- package/src/lib/DemPropertyField/widgets/DemDateWidget.tsx +33 -0
- package/src/lib/DemPropertyField/widgets/DemFieldWidget.tsx +67 -0
- package/src/lib/DemPropertyField/widgets/DemFloatWidget.tsx +49 -0
- package/src/lib/DemPropertyField/widgets/DemIntegerWidget.tsx +63 -0
- package/src/lib/DemPropertyField/widgets/DemJsonWidget.tsx +33 -0
- package/src/lib/DemPropertyField/widgets/DemStringWidget.tsx +35 -0
- package/src/lib/DemPropertyField/widgets/DemTimeWidget.tsx +46 -0
- package/src/lib/DemPropertyField/widgets/index.ts +1 -0
- package/src/lib/Forms/BackButton.tsx +45 -0
- package/src/lib/Forms/ControlAceEditor.tsx +103 -0
- package/src/lib/Forms/ControlAutocomplete.tsx +134 -0
- package/src/lib/Forms/ControlCheckbox.tsx +57 -0
- package/src/lib/Forms/ControlDebouncedInput.tsx +69 -0
- package/src/lib/Forms/ControlInput.tsx +102 -0
- package/src/lib/Forms/ControlNumberInput.tsx +144 -0
- package/src/lib/Forms/ControlRadioBtn.tsx +46 -0
- package/src/lib/Forms/ControlSelect.tsx +135 -0
- package/src/lib/Forms/CopyButton.tsx +49 -0
- package/src/lib/Forms/index.ts +10 -0
- package/src/lib/InfoItem/InfoItem.tsx +39 -0
- package/src/lib/InfoItem/index.ts +1 -0
- package/src/lib/InfoItem/styles.ts +17 -0
- package/src/lib/JsonPathPicker/JsonPathPicker.tsx +71 -0
- package/src/lib/JsonPathPicker/PropertyStep.tsx +74 -0
- package/src/lib/JsonPathPicker/index.ts +1 -0
- package/src/lib/JsonView/JsonView.tsx +43 -0
- package/src/lib/JsonView/index.ts +1 -0
- package/src/lib/Loader/Loader.tsx +41 -0
- package/src/lib/Loader/index.ts +1 -0
- package/src/lib/Modals/JsonModalView.tsx +52 -0
- package/src/lib/Modals/index.ts +1 -0
- package/src/lib/Property/PropertyValueField/BooleanValueField.tsx +41 -0
- package/src/lib/Property/PropertyValueField/DateTimeValueField.tsx +59 -0
- package/src/lib/Property/PropertyValueField/DateValueField.tsx +59 -0
- package/src/lib/Property/PropertyValueField/EntityValueField.tsx +33 -0
- package/src/lib/Property/PropertyValueField/JsonValueField.tsx +64 -0
- package/src/lib/Property/PropertyValueField/PropertyValue.tsx +97 -0
- package/src/lib/Property/PropertyValueField/PropertyValueField.tsx +86 -0
- package/src/lib/Property/PropertyValueField/StringValueField.tsx +21 -0
- package/src/lib/Property/PropertyValueField/TimeValueField.tsx +68 -0
- package/src/lib/Property/PropertyValueField/ValueComponent.tsx +63 -0
- package/src/lib/Property/PropertyValueField/index.ts +1 -0
- package/src/lib/Property/PropertyWidget/PropertyWidget.tsx +167 -0
- package/src/lib/Property/PropertyWidget/index.ts +1 -0
- package/src/lib/Property/UpsertProperty/CreatePropertiesList.tsx +131 -0
- package/src/lib/Property/UpsertProperty/CreatePropertyFormFields.tsx +147 -0
- package/src/lib/Property/UpsertProperty/CustomPropertyField.tsx +40 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/BigDecimalPropertyFields.tsx +41 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/DateAdditionalFields.tsx +27 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/EntityAdditionalFields.tsx +133 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/EntityReferencePropertyFields.tsx +46 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/PropertyAdditionalFields.tsx +52 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/StringPropertyFields.tsx +98 -0
- package/src/lib/Property/UpsertProperty/PropertyAdditionalFields/index.ts +1 -0
- package/src/lib/Property/UpsertProperty/index.ts +2 -0
- package/src/lib/Property/UpsertProperty/useCustomFields.ts +22 -0
- package/src/lib/Property/ViewPropertiesList/ViewPropertiesList.tsx +50 -0
- package/src/lib/Property/ViewPropertiesList/index.ts +1 -0
- package/src/lib/Property/ViewProperty/EntityPropertiesShortView.tsx +41 -0
- package/src/lib/Property/ViewProperty/EntityPropertiesView.tsx +48 -0
- package/src/lib/Property/ViewProperty/PropertyDataTable.tsx +139 -0
- package/src/lib/Property/ViewProperty/PropertyItem.tsx +46 -0
- package/src/lib/Property/ViewProperty/ViewProperty.tsx +52 -0
- package/src/lib/Property/ViewProperty/index.ts +1 -0
- package/src/lib/Property/index.ts +4 -0
- package/src/lib/Status/Status.tsx +15 -0
- package/src/lib/Status/index.ts +1 -0
- package/src/lib/Status/styles.ts +14 -0
- package/src/lib/Table/Table.tsx +116 -0
- package/src/lib/Table/TableColumnMenu.tsx +12 -0
- package/src/lib/Table/TablePagination.tsx +42 -0
- package/src/lib/Table/index.ts +1 -0
- package/src/lib/Table/styles.ts +59 -0
- package/src/lib/Table/usePagination.ts +15 -0
- package/src/lib/Table/useTableQueryPagination.ts +49 -0
- package/src/lib/Table/useTableQuerySorting.ts +52 -0
- package/src/lib/Tabs/RouteTabs.tsx +54 -0
- package/src/lib/Tabs/TabPanel.tsx +42 -0
- package/src/lib/Tabs/index.ts +2 -0
- package/src/lib/TemplateContent/ExpressionDecorator.tsx +7 -0
- package/src/lib/TemplateContent/TemplateContentEditor.tsx +144 -0
- package/src/lib/TemplateContent/index.ts +1 -0
- package/src/lib/index.ts +14 -0
- package/src/utils/common.ts +68 -0
- package/src/utils/dem.ts +78 -0
- package/src/utils/hooks.ts +41 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/ui-utils.tsx +71 -0
- package/src/utils/validators.ts +130 -0
- package/tsconfig.json +24 -0
- package/tsconfig.lib.json +22 -0
- package/tsconfig.spec.json +19 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
import Grid from '@material-ui/core/Grid';
|
2
|
+
import Chip from '@material-ui/core/Chip';
|
3
|
+
import Box from '@material-ui/core/Box';
|
4
|
+
import Typography from '@material-ui/core/Typography';
|
5
|
+
import TextField from '@material-ui/core/TextField';
|
6
|
+
import IconButton from '@material-ui/core/IconButton';
|
7
|
+
import AddIcon from '@material-ui/icons/Add';
|
8
|
+
|
9
|
+
import { useFormContext, useWatch } from 'react-hook-form';
|
10
|
+
import { removeArrayItem } from '../../../../utils';
|
11
|
+
import { useCallback, useMemo, useState } from 'react';
|
12
|
+
|
13
|
+
type Props = {
|
14
|
+
propertyFieldName: string;
|
15
|
+
};
|
16
|
+
|
17
|
+
const StringPropertyFields = ({ propertyFieldName }: Props) => {
|
18
|
+
const fieldName = useMemo(() => `${propertyFieldName}.restrictedValues`, [propertyFieldName]);
|
19
|
+
|
20
|
+
const { control, setValue, getValues } = useFormContext();
|
21
|
+
const restrictedValues = useWatch({
|
22
|
+
control,
|
23
|
+
name: fieldName,
|
24
|
+
defaultValue: getValues(`${propertyFieldName}.restrictedValues`) || [],
|
25
|
+
});
|
26
|
+
|
27
|
+
const [inputValue, setInputValue] = useState('');
|
28
|
+
const [error, setError] = useState('');
|
29
|
+
|
30
|
+
const handleDelete = useCallback(
|
31
|
+
(index) => {
|
32
|
+
setValue(fieldName, removeArrayItem(restrictedValues, index));
|
33
|
+
},
|
34
|
+
[restrictedValues, fieldName, setValue]
|
35
|
+
);
|
36
|
+
|
37
|
+
const handleAddValue = () => {
|
38
|
+
if (inputValue) {
|
39
|
+
setValue(fieldName, [...restrictedValues, inputValue]);
|
40
|
+
setInputValue('');
|
41
|
+
}
|
42
|
+
};
|
43
|
+
|
44
|
+
const handleInputChange = (e) => {
|
45
|
+
const { value } = e.target;
|
46
|
+
setInputValue(value);
|
47
|
+
|
48
|
+
if (restrictedValues.includes(value)) {
|
49
|
+
setError('This value already exists');
|
50
|
+
} else {
|
51
|
+
setError('');
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
const handleKeyDown = (e) => {
|
56
|
+
if (e.key === 'Enter') {
|
57
|
+
handleAddValue();
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
return (
|
62
|
+
<>
|
63
|
+
<Grid item>
|
64
|
+
<Typography variant="h6">Restricted Values</Typography>
|
65
|
+
</Grid>
|
66
|
+
<Grid item>
|
67
|
+
<Box display="flex" gridGap={8} flexWrap="wrap">
|
68
|
+
{restrictedValues?.map((value, index) => (
|
69
|
+
<Chip key={index} variant="outlined" label={value} onDelete={() => handleDelete(index)} />
|
70
|
+
))}
|
71
|
+
</Box>
|
72
|
+
</Grid>
|
73
|
+
<Grid item>
|
74
|
+
<TextField
|
75
|
+
fullWidth
|
76
|
+
variant="outlined"
|
77
|
+
size="small"
|
78
|
+
label="Add restricted value"
|
79
|
+
value={inputValue}
|
80
|
+
onChange={handleInputChange}
|
81
|
+
error={!!error}
|
82
|
+
helperText={error}
|
83
|
+
name="restrictedValues"
|
84
|
+
inputProps={{ onKeyDown: handleKeyDown }}
|
85
|
+
InputProps={{
|
86
|
+
endAdornment: (
|
87
|
+
<IconButton size="small" onClick={handleAddValue} disabled={!!error}>
|
88
|
+
<AddIcon />
|
89
|
+
</IconButton>
|
90
|
+
),
|
91
|
+
}}
|
92
|
+
/>
|
93
|
+
</Grid>
|
94
|
+
</>
|
95
|
+
);
|
96
|
+
};
|
97
|
+
|
98
|
+
export default StringPropertyFields;
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './PropertyAdditionalFields';
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { useMemo } from 'react';
|
2
|
+
import { CustomPropertyFieldProps } from '../../../interfaces';
|
3
|
+
|
4
|
+
const useCustomFields = (customPropertyFields: CustomPropertyFieldProps[]) => {
|
5
|
+
const customCheckboxes = useMemo(() => {
|
6
|
+
if (customPropertyFields.length) {
|
7
|
+
return customPropertyFields.filter((field) => field.type === 'checkbox');
|
8
|
+
}
|
9
|
+
return [];
|
10
|
+
}, [customPropertyFields]);
|
11
|
+
|
12
|
+
const customFields = useMemo(() => {
|
13
|
+
if (customPropertyFields.length) {
|
14
|
+
return customPropertyFields.filter((field) => field.type !== 'checkbox');
|
15
|
+
}
|
16
|
+
return [];
|
17
|
+
}, [customPropertyFields]);
|
18
|
+
|
19
|
+
return { customCheckboxes, customFields };
|
20
|
+
};
|
21
|
+
|
22
|
+
export default useCustomFields;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import Box from '@material-ui/core/Box';
|
2
|
+
import Typography from '@material-ui/core/Typography';
|
3
|
+
import { ViewProperty } from '../ViewProperty';
|
4
|
+
|
5
|
+
import { useMemo } from 'react';
|
6
|
+
import { propertiesObjectToArray } from '../../../utils';
|
7
|
+
import {
|
8
|
+
EntityDefinitionPropertyArrayType,
|
9
|
+
EntityDefinitionPropertyObjectType,
|
10
|
+
GPBPropertiesArrayType,
|
11
|
+
GPBPropertiesObjectType,
|
12
|
+
PropertiesArrayType,
|
13
|
+
PropertiesObjectType,
|
14
|
+
} from '../../../interfaces';
|
15
|
+
|
16
|
+
type Props = {
|
17
|
+
properties:
|
18
|
+
| PropertiesObjectType
|
19
|
+
| PropertiesArrayType
|
20
|
+
| GPBPropertiesArrayType
|
21
|
+
| GPBPropertiesObjectType
|
22
|
+
| EntityDefinitionPropertyArrayType
|
23
|
+
| EntityDefinitionPropertyObjectType;
|
24
|
+
expandAll?: boolean;
|
25
|
+
};
|
26
|
+
|
27
|
+
export const ViewPropertiesList = ({ properties, expandAll = true }: Props) => {
|
28
|
+
const propertiesList = useMemo(() => {
|
29
|
+
if (Array.isArray(properties)) {
|
30
|
+
return properties;
|
31
|
+
} else if (properties) {
|
32
|
+
return propertiesObjectToArray(properties);
|
33
|
+
}
|
34
|
+
return [];
|
35
|
+
}, [properties]);
|
36
|
+
|
37
|
+
return (
|
38
|
+
<Box display="flex" flexDirection="column" gridGap={8}>
|
39
|
+
{propertiesList.length ? (
|
40
|
+
propertiesList.map((property) => (
|
41
|
+
<ViewProperty key={property.key} property={property} defaultExpanded={expandAll} />
|
42
|
+
))
|
43
|
+
) : (
|
44
|
+
<Typography>No properties</Typography>
|
45
|
+
)}
|
46
|
+
</Box>
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
export default ViewPropertiesList;
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './ViewPropertiesList';
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import TreeView from '@material-ui/lab/TreeView';
|
2
|
+
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
3
|
+
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
4
|
+
import PropertyItem from './PropertyItem';
|
5
|
+
|
6
|
+
import { PropertiesArrayType, PropertyType } from '../../../interfaces';
|
7
|
+
import { useMemo } from 'react';
|
8
|
+
|
9
|
+
type Props = {
|
10
|
+
properties: PropertiesArrayType;
|
11
|
+
showName?: boolean;
|
12
|
+
showType?: boolean;
|
13
|
+
};
|
14
|
+
|
15
|
+
const EntityPropertiesShortView = ({ properties = [], showName = false, showType = false }: Props) => {
|
16
|
+
const defaultExpanded = useMemo(() => {
|
17
|
+
const findExpandKeys = (props: PropertiesArrayType) => {
|
18
|
+
return props.reduce((acc, property) => {
|
19
|
+
if (property.propertyType === PropertyType.ENTITY) {
|
20
|
+
return [...acc, property.key, ...findExpandKeys(property.properties as PropertiesArrayType)];
|
21
|
+
}
|
22
|
+
return acc;
|
23
|
+
}, []);
|
24
|
+
};
|
25
|
+
return findExpandKeys(properties);
|
26
|
+
}, [properties]);
|
27
|
+
|
28
|
+
return (
|
29
|
+
<TreeView
|
30
|
+
defaultCollapseIcon={<ExpandMoreIcon />}
|
31
|
+
defaultExpandIcon={<ChevronRightIcon />}
|
32
|
+
defaultExpanded={defaultExpanded}
|
33
|
+
>
|
34
|
+
{properties.map((property) => (
|
35
|
+
<PropertyItem key={property.key} property={property} showName={showName} showType={showType} />
|
36
|
+
))}
|
37
|
+
</TreeView>
|
38
|
+
);
|
39
|
+
};
|
40
|
+
|
41
|
+
export default EntityPropertiesShortView;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import Box from '@material-ui/core/Box';
|
2
|
+
import Stepper from '@material-ui/core/Stepper';
|
3
|
+
import Step from '@material-ui/core/Step';
|
4
|
+
import StepLabel from '@material-ui/core/StepLabel';
|
5
|
+
import StepContent from '@material-ui/core/StepContent';
|
6
|
+
import Typography from '@material-ui/core/Typography';
|
7
|
+
import ViewProperty from './ViewProperty';
|
8
|
+
|
9
|
+
import { memo, useMemo } from 'react';
|
10
|
+
import { PropertiesArrayType, PropertyType } from '../../../interfaces';
|
11
|
+
|
12
|
+
type Props = {
|
13
|
+
properties: PropertiesArrayType;
|
14
|
+
parentNames?: string[];
|
15
|
+
};
|
16
|
+
|
17
|
+
const EntityPropertiesView = ({ properties, parentNames = [] }: Props) => {
|
18
|
+
const hasProperties = useMemo(() => {
|
19
|
+
let hasProps = false;
|
20
|
+
properties.every((property) => {
|
21
|
+
if (property.propertyType === PropertyType.ENTITY) {
|
22
|
+
hasProps = true;
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
return true;
|
26
|
+
});
|
27
|
+
return hasProps;
|
28
|
+
}, [properties]);
|
29
|
+
|
30
|
+
return (
|
31
|
+
<Box mt={4}>
|
32
|
+
<Typography variant="h6">Properties</Typography>
|
33
|
+
<Stepper orientation="vertical" style={{ paddingLeft: '4px' }}>
|
34
|
+
{properties.map((property) => (
|
35
|
+
<Step expanded key={property.key}>
|
36
|
+
<StepLabel StepIconProps={{ icon: '', completed: false, active: true }} />
|
37
|
+
<StepContent>
|
38
|
+
<ViewProperty property={property} parentNames={[...parentNames]} defaultExpanded={false} />
|
39
|
+
</StepContent>
|
40
|
+
</Step>
|
41
|
+
))}
|
42
|
+
{hasProperties && <Step />}
|
43
|
+
</Stepper>
|
44
|
+
</Box>
|
45
|
+
);
|
46
|
+
};
|
47
|
+
|
48
|
+
export default memo(EntityPropertiesView);
|
@@ -0,0 +1,139 @@
|
|
1
|
+
import Box from '@material-ui/core/Box';
|
2
|
+
import Table from '@material-ui/core/Table';
|
3
|
+
import TableBody from '@material-ui/core/TableBody';
|
4
|
+
import TableRow from '@material-ui/core/TableRow';
|
5
|
+
import TableCell from '@material-ui/core/TableCell';
|
6
|
+
import Typography from '@material-ui/core/Typography';
|
7
|
+
import Chip from '@material-ui/core/Chip';
|
8
|
+
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
|
9
|
+
|
10
|
+
import { useMemo } from 'react';
|
11
|
+
import { PropertyType, PropertyUnion } from '../../../interfaces';
|
12
|
+
import { JsonView } from '../../JsonView';
|
13
|
+
|
14
|
+
type Props = {
|
15
|
+
property: PropertyUnion;
|
16
|
+
};
|
17
|
+
|
18
|
+
type ValueDisplayProps = {
|
19
|
+
value: unknown;
|
20
|
+
type: PropertyType;
|
21
|
+
};
|
22
|
+
|
23
|
+
const labels = {
|
24
|
+
name: 'Name',
|
25
|
+
key: 'Key',
|
26
|
+
propertyType: 'Property Type',
|
27
|
+
defaultValue: 'Default Value',
|
28
|
+
defaultValues: 'Default Values',
|
29
|
+
sortOrder: 'Sort Order',
|
30
|
+
isRequired: 'Required',
|
31
|
+
isMultiple: 'Multiple',
|
32
|
+
isEnabled: 'Enabled',
|
33
|
+
isViewableInList: 'Is Viewable In List',
|
34
|
+
precisionScale: 'Precision Scale',
|
35
|
+
roundingMode: 'Rounding Mode',
|
36
|
+
format: 'Format',
|
37
|
+
definitionCode: 'Definition Code',
|
38
|
+
definitionVersion: 'Definition Version',
|
39
|
+
labelPropertyCode: 'Label Property Code',
|
40
|
+
valuePropertyCode: 'Value Property Code',
|
41
|
+
restrictedValues: 'Restricted Values',
|
42
|
+
value: 'Value',
|
43
|
+
values: 'Values',
|
44
|
+
uiSettings: 'UI Settings',
|
45
|
+
};
|
46
|
+
|
47
|
+
const ValueDisplay = ({ value, type }: ValueDisplayProps) => {
|
48
|
+
if ((type === PropertyType.JSON || type === PropertyType.ENTITY) && value) {
|
49
|
+
return <JsonView value={value} />;
|
50
|
+
} else {
|
51
|
+
return (
|
52
|
+
<Typography variant="subtitle1" display="inline" style={{ wordBreak: 'break-word' }}>
|
53
|
+
{value === null ? 'null' : value.toString()}
|
54
|
+
</Typography>
|
55
|
+
);
|
56
|
+
}
|
57
|
+
};
|
58
|
+
|
59
|
+
const formatDiplayValue = (value: unknown, key: string, type: PropertyType) => {
|
60
|
+
switch (key) {
|
61
|
+
case 'isRequired':
|
62
|
+
case 'isMultiple':
|
63
|
+
case 'isEnabled':
|
64
|
+
case 'isViewableInList':
|
65
|
+
return value ? <CheckCircleIcon color="primary" fontSize="small" /> : null;
|
66
|
+
case 'restrictedValues':
|
67
|
+
return value ? (
|
68
|
+
<Box display="flex" flexWrap="wrap" gridGap={4}>
|
69
|
+
{(value as string[]).map((restrictedValue) => (
|
70
|
+
<Chip
|
71
|
+
key={restrictedValue}
|
72
|
+
label={restrictedValue}
|
73
|
+
style={{ wordBreak: 'break-word', maxWidth: '500px' }}
|
74
|
+
/>
|
75
|
+
))}
|
76
|
+
</Box>
|
77
|
+
) : null;
|
78
|
+
case 'defaultValue':
|
79
|
+
case 'value':
|
80
|
+
return <ValueDisplay value={value} type={type} />;
|
81
|
+
case 'values':
|
82
|
+
case 'defaultValues':
|
83
|
+
if (type === PropertyType.ENTITY || type === PropertyType.JSON) {
|
84
|
+
return <JsonView value={value} />;
|
85
|
+
} else {
|
86
|
+
return (
|
87
|
+
<div>
|
88
|
+
{(value as unknown[]).map((v, index) => (
|
89
|
+
<div key={index}>
|
90
|
+
<ValueDisplay value={v} type={type} />
|
91
|
+
</div>
|
92
|
+
))}
|
93
|
+
</div>
|
94
|
+
);
|
95
|
+
}
|
96
|
+
case 'uiSettings':
|
97
|
+
return value ? <JsonView value={value} /> : null;
|
98
|
+
default:
|
99
|
+
return (
|
100
|
+
<Typography variant="subtitle1" display="inline" style={{ wordBreak: 'break-word' }}>
|
101
|
+
{value}
|
102
|
+
</Typography>
|
103
|
+
);
|
104
|
+
}
|
105
|
+
};
|
106
|
+
|
107
|
+
const PropertyDataTable = ({ property }: Props) => {
|
108
|
+
const propertyData = useMemo(() => {
|
109
|
+
if (property) {
|
110
|
+
if (property.isMultiple) {
|
111
|
+
delete property.defaultValue;
|
112
|
+
delete property['value'];
|
113
|
+
} else {
|
114
|
+
delete property.defaultValues;
|
115
|
+
delete property['values'];
|
116
|
+
}
|
117
|
+
}
|
118
|
+
return property;
|
119
|
+
}, [property]);
|
120
|
+
|
121
|
+
return (
|
122
|
+
<Table size="small">
|
123
|
+
<TableBody>
|
124
|
+
{Object.keys(labels).map((key) =>
|
125
|
+
key in propertyData ? (
|
126
|
+
<TableRow key={key}>
|
127
|
+
<TableCell width="30%">
|
128
|
+
<Typography>{labels[key]}</Typography>
|
129
|
+
</TableCell>
|
130
|
+
<TableCell>{formatDiplayValue(propertyData[key], key, propertyData.propertyType)}</TableCell>
|
131
|
+
</TableRow>
|
132
|
+
) : null
|
133
|
+
)}
|
134
|
+
</TableBody>
|
135
|
+
</Table>
|
136
|
+
);
|
137
|
+
};
|
138
|
+
|
139
|
+
export default PropertyDataTable;
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import TreeItem from '@material-ui/lab/TreeItem';
|
2
|
+
|
3
|
+
import { useMemo } from 'react';
|
4
|
+
import { PropertiesArrayType, PropertyType, PropertyUnion } from '../../../interfaces';
|
5
|
+
|
6
|
+
type PropertyItemProps = {
|
7
|
+
property: PropertyUnion;
|
8
|
+
showName: boolean;
|
9
|
+
showType: boolean;
|
10
|
+
};
|
11
|
+
|
12
|
+
const PropertyItem = ({ property, showName, showType }: PropertyItemProps) => {
|
13
|
+
const label = useMemo(() => {
|
14
|
+
let labelText = '';
|
15
|
+
|
16
|
+
if (property) {
|
17
|
+
labelText += `<b>${property.key}</b>`;
|
18
|
+
}
|
19
|
+
|
20
|
+
if (showName) {
|
21
|
+
labelText += ` - ${property.name}`;
|
22
|
+
}
|
23
|
+
|
24
|
+
if (showType) {
|
25
|
+
const type =
|
26
|
+
typeof property.propertyType === 'string'
|
27
|
+
? property.propertyType
|
28
|
+
: (property.propertyType as { value: string }).value;
|
29
|
+
labelText += ` - ${type}${property.isMultiple ? '[]' : ''}`;
|
30
|
+
}
|
31
|
+
|
32
|
+
return labelText;
|
33
|
+
}, [property.key, property.name, property.propertyType, property.isMultiple, showName, showType]);
|
34
|
+
|
35
|
+
return (
|
36
|
+
<TreeItem nodeId={property.key} label={<div dangerouslySetInnerHTML={{ __html: label }} />}>
|
37
|
+
{property.propertyType === PropertyType.ENTITY
|
38
|
+
? (property.properties as PropertiesArrayType).map((prop) => (
|
39
|
+
<PropertyItem key={prop.key} property={prop} showName={showName} showType={showType} />
|
40
|
+
))
|
41
|
+
: null}
|
42
|
+
</TreeItem>
|
43
|
+
);
|
44
|
+
};
|
45
|
+
|
46
|
+
export default PropertyItem;
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import Box from '@material-ui/core/Box';
|
2
|
+
import Typography from '@material-ui/core/Typography';
|
3
|
+
import Accordion from '@material-ui/core/Accordion';
|
4
|
+
import AccordionSummary from '@material-ui/core/AccordionSummary';
|
5
|
+
import AccordionDetails from '@material-ui/core/AccordionDetails';
|
6
|
+
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
7
|
+
import PropertyDataTable from './PropertyDataTable';
|
8
|
+
import EntityPropertiesView from './EntityPropertiesView';
|
9
|
+
|
10
|
+
import { useEffect, useState } from 'react';
|
11
|
+
import { propertiesObjectToArray } from '../../../utils';
|
12
|
+
import { PropertiesObjectType, PropertyType, PropertyUnion } from '../../../interfaces';
|
13
|
+
|
14
|
+
type Props = {
|
15
|
+
property: PropertyUnion;
|
16
|
+
parentNames?: string[];
|
17
|
+
defaultExpanded?: boolean;
|
18
|
+
};
|
19
|
+
|
20
|
+
export const ViewProperty = ({ property, parentNames = [], defaultExpanded = true }: Props) => {
|
21
|
+
const [expanded, setExpanded] = useState(true);
|
22
|
+
|
23
|
+
useEffect(() => {
|
24
|
+
setExpanded(defaultExpanded);
|
25
|
+
}, [defaultExpanded]);
|
26
|
+
|
27
|
+
return (
|
28
|
+
<Accordion
|
29
|
+
elevation={3}
|
30
|
+
style={{ backgroundColor: parentNames.length % 2 === 1 ? '#f1f1f1' : '#fff' }}
|
31
|
+
expanded={expanded}
|
32
|
+
onChange={() => setExpanded((prevState) => !prevState)}
|
33
|
+
>
|
34
|
+
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
35
|
+
<Typography style={{ wordBreak: 'break-word', fontWeight: '600' }}>{property.name}</Typography>
|
36
|
+
</AccordionSummary>
|
37
|
+
<AccordionDetails>
|
38
|
+
<Box width="100%">
|
39
|
+
<PropertyDataTable property={property} />
|
40
|
+
{property.propertyType === PropertyType.ENTITY && (
|
41
|
+
<EntityPropertiesView
|
42
|
+
properties={propertiesObjectToArray(property.properties as PropertiesObjectType)}
|
43
|
+
parentNames={[...parentNames, property.name]}
|
44
|
+
/>
|
45
|
+
)}
|
46
|
+
</Box>
|
47
|
+
</AccordionDetails>
|
48
|
+
</Accordion>
|
49
|
+
);
|
50
|
+
};
|
51
|
+
|
52
|
+
export default ViewProperty;
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './ViewProperty';
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import useStyles from './styles';
|
2
|
+
import cn from 'classnames';
|
3
|
+
|
4
|
+
type Props = {
|
5
|
+
text: string;
|
6
|
+
status?: 'default' | 'success';
|
7
|
+
};
|
8
|
+
|
9
|
+
export const Status = ({ text, status = 'default' }: Props) => {
|
10
|
+
const classes = useStyles();
|
11
|
+
|
12
|
+
return <div className={cn(classes.root, { [status]: true })}>{text}</div>;
|
13
|
+
};
|
14
|
+
|
15
|
+
export default Status;
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Status';
|
@@ -0,0 +1,116 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import TablePagination from './TablePagination';
|
3
|
+
import TableColumnMenu from './TableColumnMenu';
|
4
|
+
|
5
|
+
import useTableQueryPagination from './useTableQueryPagination';
|
6
|
+
import useTableQuerySorting from './useTableQuerySorting';
|
7
|
+
import usePagination from './usePagination';
|
8
|
+
import { DataGrid, GridCellParams, GridColumns, GridFeatureMode, GridRowsProp } from '@mui/x-data-grid';
|
9
|
+
import useStyles from './styles';
|
10
|
+
import Box from '@material-ui/core/Box';
|
11
|
+
|
12
|
+
/**
|
13
|
+
* This interface is referencing the [[Table]] component props.
|
14
|
+
* @category Common UI components
|
15
|
+
*/
|
16
|
+
export interface TableProps {
|
17
|
+
/**
|
18
|
+
* Data loading state
|
19
|
+
*/
|
20
|
+
loading?: boolean;
|
21
|
+
/**
|
22
|
+
* Table columns
|
23
|
+
*/
|
24
|
+
columns: GridColumns;
|
25
|
+
/**
|
26
|
+
* Table rows
|
27
|
+
*/
|
28
|
+
rows: GridRowsProp;
|
29
|
+
/**
|
30
|
+
* Rows count to display
|
31
|
+
*/
|
32
|
+
rowCount: number;
|
33
|
+
disableMargin?: boolean;
|
34
|
+
/**
|
35
|
+
* Data display mode.
|
36
|
+
* Values: `client` | `server`;
|
37
|
+
* Default: `server`
|
38
|
+
*/
|
39
|
+
mode?: GridFeatureMode;
|
40
|
+
/**
|
41
|
+
* Page size. Default `10`
|
42
|
+
*/
|
43
|
+
initialPageSize?: number;
|
44
|
+
/**
|
45
|
+
* On cell click handler function
|
46
|
+
* ```typescript
|
47
|
+
* (params: GridCellParams, event: React.MouseEvent) => void;
|
48
|
+
* ```
|
49
|
+
*/
|
50
|
+
onCellClick?: (params: GridCellParams, event: React.MouseEvent) => void;
|
51
|
+
pagination?: boolean;
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Main data display component. MUI DataGrid used
|
56
|
+
* @category Common UI components
|
57
|
+
*/
|
58
|
+
export const Table = ({
|
59
|
+
columns,
|
60
|
+
rows,
|
61
|
+
rowCount,
|
62
|
+
loading,
|
63
|
+
disableMargin,
|
64
|
+
mode = 'server',
|
65
|
+
initialPageSize = 10,
|
66
|
+
pagination = true,
|
67
|
+
onCellClick,
|
68
|
+
}: TableProps) => {
|
69
|
+
const classes = useStyles();
|
70
|
+
|
71
|
+
const { page, size, onPageChange, onSizeChange } = useTableQueryPagination({ mode });
|
72
|
+
const { onColumnHeaderClick, getSortedColumns } = useTableQuerySorting();
|
73
|
+
|
74
|
+
const { pageSize, handlePageSizeChange } = usePagination(initialPageSize);
|
75
|
+
|
76
|
+
const tableProps = {
|
77
|
+
sortingMode: mode,
|
78
|
+
paginationMode: mode,
|
79
|
+
pageSize: mode === 'server' ? size : pagination ? pageSize : rowCount,
|
80
|
+
onPageSizeChange: mode === 'server' ? onSizeChange : handlePageSizeChange,
|
81
|
+
components: {
|
82
|
+
Pagination: TablePagination,
|
83
|
+
},
|
84
|
+
};
|
85
|
+
|
86
|
+
if (mode === 'server') {
|
87
|
+
tableProps['sortModel'] = [];
|
88
|
+
tableProps['onColumnHeaderClick'] = onColumnHeaderClick;
|
89
|
+
tableProps['page'] = page;
|
90
|
+
tableProps['onPageChange'] = onPageChange;
|
91
|
+
tableProps.components['ColumnMenu'] = TableColumnMenu;
|
92
|
+
}
|
93
|
+
|
94
|
+
return (
|
95
|
+
<Box mt={disableMargin ? 0 : 2}>
|
96
|
+
<DataGrid
|
97
|
+
autoHeight
|
98
|
+
hideFooterPagination={!pagination}
|
99
|
+
hideFooter={!pagination}
|
100
|
+
disableSelectionOnClick
|
101
|
+
showColumnRightBorder
|
102
|
+
showCellRightBorder
|
103
|
+
className={classes.root}
|
104
|
+
loading={loading}
|
105
|
+
rows={rows}
|
106
|
+
columns={getSortedColumns(columns)}
|
107
|
+
rowCount={rowCount}
|
108
|
+
rowsPerPageOptions={[10, 20, 50, 100]}
|
109
|
+
onCellClick={onCellClick}
|
110
|
+
{...tableProps}
|
111
|
+
/>
|
112
|
+
</Box>
|
113
|
+
);
|
114
|
+
};
|
115
|
+
|
116
|
+
export default Table;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { GridColumnMenuContainer, GridFilterMenuItem } from '@mui/x-data-grid';
|
3
|
+
|
4
|
+
const TableColumnMenu = ({ hideMenu, currentColumn, onUnsort, ...rest }: any) => {
|
5
|
+
return (
|
6
|
+
<GridColumnMenuContainer hideMenu={hideMenu} currentColumn={currentColumn} {...rest}>
|
7
|
+
<GridFilterMenuItem onClick={hideMenu} column={currentColumn} />
|
8
|
+
</GridColumnMenuContainer>
|
9
|
+
);
|
10
|
+
};
|
11
|
+
|
12
|
+
export default TableColumnMenu;
|