@etsoo/materialui 1.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/.eslintignore +3 -0
- package/.eslintrc.json +38 -0
- package/.gitattributes +2 -0
- package/.github/workflows/main.yml +48 -0
- package/.prettierignore +5 -0
- package/.prettierrc +6 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/__tests__/ComboBox.tsx +30 -0
- package/__tests__/MUGlobalTests.tsx +58 -0
- package/__tests__/NotifierMUTests.tsx +217 -0
- package/__tests__/SelectEx.tsx +26 -0
- package/__tests__/tsconfig.json +19 -0
- package/babel.config.json +11 -0
- package/lib/AuditDisplay.d.ts +33 -0
- package/lib/AuditDisplay.js +52 -0
- package/lib/AutocompleteExtendedProps.d.ts +64 -0
- package/lib/AutocompleteExtendedProps.js +1 -0
- package/lib/BackButton.d.ts +13 -0
- package/lib/BackButton.js +33 -0
- package/lib/BridgeCloseButton.d.ts +23 -0
- package/lib/BridgeCloseButton.js +32 -0
- package/lib/ButtonLink.d.ts +17 -0
- package/lib/ButtonLink.js +19 -0
- package/lib/ComboBox.d.ts +38 -0
- package/lib/ComboBox.js +108 -0
- package/lib/CountdownButton.d.ts +23 -0
- package/lib/CountdownButton.js +81 -0
- package/lib/CustomFabProps.d.ts +27 -0
- package/lib/CustomFabProps.js +1 -0
- package/lib/DataGridEx.d.ts +94 -0
- package/lib/DataGridEx.js +329 -0
- package/lib/DataGridRenderers.d.ts +22 -0
- package/lib/DataGridRenderers.js +99 -0
- package/lib/DialogButton.d.ts +54 -0
- package/lib/DialogButton.js +45 -0
- package/lib/DnDList.d.ts +87 -0
- package/lib/DnDList.js +153 -0
- package/lib/DraggablePaperComponent.d.ts +8 -0
- package/lib/DraggablePaperComponent.js +12 -0
- package/lib/EmailInput.d.ts +11 -0
- package/lib/EmailInput.js +15 -0
- package/lib/FabBox.d.ts +21 -0
- package/lib/FabBox.js +31 -0
- package/lib/FlexBox.d.ts +14 -0
- package/lib/FlexBox.js +18 -0
- package/lib/GridDataFormat.d.ts +10 -0
- package/lib/GridDataFormat.js +43 -0
- package/lib/IconButtonLink.d.ts +17 -0
- package/lib/IconButtonLink.js +16 -0
- package/lib/InputField.d.ts +21 -0
- package/lib/InputField.js +39 -0
- package/lib/ItemList.d.ts +56 -0
- package/lib/ItemList.js +69 -0
- package/lib/ListItemRightIcon.d.ts +4 -0
- package/lib/ListItemRightIcon.js +8 -0
- package/lib/ListMoreDisplay.d.ts +35 -0
- package/lib/ListMoreDisplay.js +99 -0
- package/lib/LoadingButton.d.ts +16 -0
- package/lib/LoadingButton.js +41 -0
- package/lib/MUGlobal.d.ts +102 -0
- package/lib/MUGlobal.js +184 -0
- package/lib/MaskInput.d.ts +34 -0
- package/lib/MaskInput.js +43 -0
- package/lib/MobileListItemRenderer.d.ts +17 -0
- package/lib/MobileListItemRenderer.js +35 -0
- package/lib/MoreFab.d.ts +45 -0
- package/lib/MoreFab.js +95 -0
- package/lib/NotifierMU.d.ts +47 -0
- package/lib/NotifierMU.js +387 -0
- package/lib/NotifierPromptProps.d.ts +22 -0
- package/lib/NotifierPromptProps.js +1 -0
- package/lib/OptionGroup.d.ts +58 -0
- package/lib/OptionGroup.js +81 -0
- package/lib/PList.d.ts +15 -0
- package/lib/PList.js +12 -0
- package/lib/ProgressCount.d.ts +44 -0
- package/lib/ProgressCount.js +79 -0
- package/lib/PullToRefreshUI.d.ts +9 -0
- package/lib/PullToRefreshUI.js +18 -0
- package/lib/RLink.d.ts +14 -0
- package/lib/RLink.js +37 -0
- package/lib/ResponsibleContainer.d.ts +87 -0
- package/lib/ResponsibleContainer.js +156 -0
- package/lib/ScrollTopFab.d.ts +7 -0
- package/lib/ScrollTopFab.js +25 -0
- package/lib/ScrollerListEx.d.ts +81 -0
- package/lib/ScrollerListEx.js +167 -0
- package/lib/SearchBar.d.ts +29 -0
- package/lib/SearchBar.js +260 -0
- package/lib/SearchField.d.ts +21 -0
- package/lib/SearchField.js +39 -0
- package/lib/SearchOptionGroup.d.ts +9 -0
- package/lib/SearchOptionGroup.js +14 -0
- package/lib/SelectBool.d.ts +13 -0
- package/lib/SelectBool.js +22 -0
- package/lib/SelectEx.d.ts +50 -0
- package/lib/SelectEx.js +156 -0
- package/lib/ShowDataComparison.d.ts +20 -0
- package/lib/ShowDataComparison.js +58 -0
- package/lib/Switch.d.ts +29 -0
- package/lib/Switch.js +34 -0
- package/lib/SwitchAnt.d.ts +25 -0
- package/lib/SwitchAnt.js +40 -0
- package/lib/TabBox.d.ts +54 -0
- package/lib/TabBox.js +31 -0
- package/lib/TableEx.d.ts +65 -0
- package/lib/TableEx.js +270 -0
- package/lib/TextFieldEx.d.ts +101 -0
- package/lib/TextFieldEx.js +126 -0
- package/lib/Tiplist.d.ts +18 -0
- package/lib/Tiplist.js +157 -0
- package/lib/TooltipClick.d.ts +15 -0
- package/lib/TooltipClick.js +40 -0
- package/lib/UserAvatar.d.ts +24 -0
- package/lib/UserAvatar.js +25 -0
- package/lib/UserAvatarEditor.d.ts +53 -0
- package/lib/UserAvatarEditor.js +129 -0
- package/lib/app/CommonApp.d.ts +38 -0
- package/lib/app/CommonApp.js +149 -0
- package/lib/app/IServiceAppSettings.d.ts +11 -0
- package/lib/app/IServiceAppSettings.js +1 -0
- package/lib/app/IServicePage.d.ts +6 -0
- package/lib/app/IServicePage.js +1 -0
- package/lib/app/IServiceUser.d.ts +14 -0
- package/lib/app/IServiceUser.js +1 -0
- package/lib/app/ISmartERPUser.d.ts +14 -0
- package/lib/app/ISmartERPUser.js +1 -0
- package/lib/app/Labels.d.ts +65 -0
- package/lib/app/Labels.js +62 -0
- package/lib/app/ReactApp.d.ts +195 -0
- package/lib/app/ReactApp.js +296 -0
- package/lib/app/ServiceApp.d.ts +78 -0
- package/lib/app/ServiceApp.js +244 -0
- package/lib/index.d.ts +74 -0
- package/lib/index.js +74 -0
- package/lib/pages/CommonPage.d.ts +11 -0
- package/lib/pages/CommonPage.js +60 -0
- package/lib/pages/CommonPageProps.d.ts +59 -0
- package/lib/pages/CommonPageProps.js +1 -0
- package/lib/pages/DataGridPage.d.ts +9 -0
- package/lib/pages/DataGridPage.js +79 -0
- package/lib/pages/DataGridPageProps.d.ts +17 -0
- package/lib/pages/DataGridPageProps.js +1 -0
- package/lib/pages/EditPage.d.ts +33 -0
- package/lib/pages/EditPage.js +29 -0
- package/lib/pages/FixedListPage.d.ts +15 -0
- package/lib/pages/FixedListPage.js +70 -0
- package/lib/pages/ListPage.d.ts +9 -0
- package/lib/pages/ListPage.js +50 -0
- package/lib/pages/ListPageProps.d.ts +7 -0
- package/lib/pages/ListPageProps.js +1 -0
- package/lib/pages/ResponsivePage.d.ts +9 -0
- package/lib/pages/ResponsivePage.js +45 -0
- package/lib/pages/ResponsivePageProps.d.ts +39 -0
- package/lib/pages/ResponsivePageProps.js +1 -0
- package/lib/pages/SearchPageProps.d.ts +30 -0
- package/lib/pages/SearchPageProps.js +1 -0
- package/lib/pages/TablePage.d.ts +9 -0
- package/lib/pages/TablePage.js +69 -0
- package/lib/pages/TablePageProps.d.ts +7 -0
- package/lib/pages/TablePageProps.js +1 -0
- package/lib/pages/ViewPage.d.ts +66 -0
- package/lib/pages/ViewPage.js +105 -0
- package/lib/texts/DateText.d.ts +34 -0
- package/lib/texts/DateText.js +25 -0
- package/lib/texts/MoneyText.d.ts +21 -0
- package/lib/texts/MoneyText.js +14 -0
- package/lib/texts/NumberText.d.ts +25 -0
- package/lib/texts/NumberText.js +14 -0
- package/package.json +97 -0
- package/src/AuditDisplay.tsx +114 -0
- package/src/AutocompleteExtendedProps.ts +83 -0
- package/src/BackButton.tsx +55 -0
- package/src/BridgeCloseButton.tsx +69 -0
- package/src/ButtonLink.tsx +32 -0
- package/src/ComboBox.tsx +251 -0
- package/src/CountdownButton.tsx +119 -0
- package/src/CustomFabProps.ts +32 -0
- package/src/DataGridEx.tsx +713 -0
- package/src/DataGridRenderers.tsx +140 -0
- package/src/DialogButton.tsx +163 -0
- package/src/DnDList.tsx +344 -0
- package/src/DraggablePaperComponent.tsx +19 -0
- package/src/EmailInput.tsx +24 -0
- package/src/FabBox.tsx +51 -0
- package/src/FlexBox.tsx +20 -0
- package/src/GridDataFormat.tsx +77 -0
- package/src/IconButtonLink.tsx +29 -0
- package/src/InputField.tsx +82 -0
- package/src/ItemList.tsx +204 -0
- package/src/ListItemRightIcon.tsx +9 -0
- package/src/ListMoreDisplay.tsx +205 -0
- package/src/LoadingButton.tsx +75 -0
- package/src/MUGlobal.ts +220 -0
- package/src/MaskInput.tsx +107 -0
- package/src/MobileListItemRenderer.tsx +79 -0
- package/src/MoreFab.tsx +211 -0
- package/src/NotifierMU.tsx +654 -0
- package/src/NotifierPromptProps.ts +24 -0
- package/src/OptionGroup.tsx +223 -0
- package/src/PList.tsx +27 -0
- package/src/ProgressCount.tsx +166 -0
- package/src/PullToRefreshUI.tsx +21 -0
- package/src/RLink.tsx +64 -0
- package/src/ResponsibleContainer.tsx +394 -0
- package/src/ScrollTopFab.tsx +34 -0
- package/src/ScrollerListEx.tsx +387 -0
- package/src/SearchBar.tsx +396 -0
- package/src/SearchField.tsx +82 -0
- package/src/SearchOptionGroup.tsx +31 -0
- package/src/SelectBool.tsx +33 -0
- package/src/SelectEx.tsx +290 -0
- package/src/ShowDataComparison.tsx +106 -0
- package/src/Switch.tsx +94 -0
- package/src/SwitchAnt.tsx +95 -0
- package/src/TabBox.tsx +118 -0
- package/src/TableEx.tsx +558 -0
- package/src/TextFieldEx.tsx +249 -0
- package/src/Tiplist.tsx +303 -0
- package/src/TooltipClick.tsx +84 -0
- package/src/UserAvatar.tsx +64 -0
- package/src/UserAvatarEditor.tsx +287 -0
- package/src/app/CommonApp.ts +223 -0
- package/src/app/IServiceAppSettings.ts +13 -0
- package/src/app/IServicePage.ts +6 -0
- package/src/app/IServiceUser.ts +17 -0
- package/src/app/ISmartERPUser.ts +16 -0
- package/src/app/Labels.ts +77 -0
- package/src/app/ReactApp.ts +504 -0
- package/src/app/ServiceApp.ts +352 -0
- package/src/index.ts +77 -0
- package/src/pages/CommonPage.tsx +128 -0
- package/src/pages/CommonPageProps.ts +70 -0
- package/src/pages/DataGridPage.tsx +140 -0
- package/src/pages/DataGridPageProps.ts +24 -0
- package/src/pages/EditPage.tsx +114 -0
- package/src/pages/FixedListPage.tsx +141 -0
- package/src/pages/ListPage.tsx +90 -0
- package/src/pages/ListPageProps.ts +12 -0
- package/src/pages/ResponsivePage.tsx +68 -0
- package/src/pages/ResponsivePageProps.ts +57 -0
- package/src/pages/SearchPageProps.ts +39 -0
- package/src/pages/TablePage.tsx +126 -0
- package/src/pages/TablePageProps.ts +12 -0
- package/src/pages/ViewPage.tsx +282 -0
- package/src/texts/DateText.tsx +74 -0
- package/src/texts/MoneyText.tsx +49 -0
- package/src/texts/NumberText.tsx +40 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Utils } from '@etsoo/shared';
|
|
2
|
+
import { Grid, LinearProgress, Stack, Typography } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Labels } from '../app/Labels';
|
|
5
|
+
import { globalApp } from '../app/ReactApp';
|
|
6
|
+
import { GridDataFormat } from '../GridDataFormat';
|
|
7
|
+
import { MUGlobal } from '../MUGlobal';
|
|
8
|
+
import { PullToRefreshUI } from '../PullToRefreshUI';
|
|
9
|
+
import { CommonPage } from './CommonPage';
|
|
10
|
+
function formatItemData(fieldData) {
|
|
11
|
+
if (fieldData == null)
|
|
12
|
+
return undefined;
|
|
13
|
+
if (typeof fieldData === 'string')
|
|
14
|
+
return fieldData;
|
|
15
|
+
if (fieldData instanceof Date)
|
|
16
|
+
return globalApp.formatDate(fieldData, 'd');
|
|
17
|
+
return `${fieldData}`;
|
|
18
|
+
}
|
|
19
|
+
function getItemField(field, data) {
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
// Item data and label
|
|
22
|
+
let itemData, itemLabel, gridProps = {};
|
|
23
|
+
let xs = 6;
|
|
24
|
+
if (Array.isArray(field)) {
|
|
25
|
+
const [fieldData, fieldType, renderProps] = field;
|
|
26
|
+
itemData = GridDataFormat(data[fieldData], fieldType, renderProps);
|
|
27
|
+
itemLabel = (_a = globalApp.get(fieldData)) !== null && _a !== void 0 ? _a : fieldData;
|
|
28
|
+
}
|
|
29
|
+
else if (typeof field === 'object') {
|
|
30
|
+
// Destruct
|
|
31
|
+
const { data: fieldData, dataType, label: fieldLabel, renderProps, singleRow, ...rest } = field;
|
|
32
|
+
gridProps = {
|
|
33
|
+
...rest,
|
|
34
|
+
...(singleRow && { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 })
|
|
35
|
+
};
|
|
36
|
+
if (singleRow === false)
|
|
37
|
+
xs = 12;
|
|
38
|
+
// Field data
|
|
39
|
+
if (typeof fieldData === 'function')
|
|
40
|
+
itemData = fieldData(data);
|
|
41
|
+
else if (dataType == null)
|
|
42
|
+
itemData = formatItemData(data[fieldData]);
|
|
43
|
+
else
|
|
44
|
+
itemData = GridDataFormat(data[fieldData], dataType, renderProps);
|
|
45
|
+
// Field label
|
|
46
|
+
itemLabel =
|
|
47
|
+
typeof fieldLabel === 'function'
|
|
48
|
+
? fieldLabel()
|
|
49
|
+
: (_b = globalApp.get(fieldLabel !== null && fieldLabel !== void 0 ? fieldLabel : (typeof fieldData === 'string' ? fieldData : 'noData'))) !== null && _b !== void 0 ? _b : fieldLabel;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
itemData = formatItemData(data[field]);
|
|
53
|
+
itemLabel = (_c = globalApp.get(field)) !== null && _c !== void 0 ? _c : field;
|
|
54
|
+
}
|
|
55
|
+
return [
|
|
56
|
+
itemData,
|
|
57
|
+
itemLabel,
|
|
58
|
+
{ xs, sm: 6, md: 6, lg: 4, xl: 3, ...gridProps }
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* View page
|
|
63
|
+
* @param props Props
|
|
64
|
+
*/
|
|
65
|
+
export function ViewPage(props) {
|
|
66
|
+
// Destruct
|
|
67
|
+
const { actions, children, fields, loadData, paddings = MUGlobal.pagePaddings, supportRefresh = true, fabColumnDirection = true, supportBack = true, pullToRefresh = true, ...rest } = props;
|
|
68
|
+
// Data
|
|
69
|
+
const [data, setData] = React.useState();
|
|
70
|
+
// Labels
|
|
71
|
+
const labels = Labels.CommonPage;
|
|
72
|
+
// Container
|
|
73
|
+
const pullContainer = '#page-container';
|
|
74
|
+
// Load data
|
|
75
|
+
const refresh = async () => {
|
|
76
|
+
const result = await loadData();
|
|
77
|
+
if (result == null)
|
|
78
|
+
return;
|
|
79
|
+
setData(result);
|
|
80
|
+
};
|
|
81
|
+
return (React.createElement(CommonPage, { paddings: paddings, onRefresh: supportRefresh ? refresh : undefined, onUpdate: supportRefresh ? undefined : refresh, ...rest, scrollContainer: globalThis, fabColumnDirection: fabColumnDirection, supportBack: supportBack }, data == null ? (React.createElement(LinearProgress, null)) : (React.createElement(React.Fragment, null,
|
|
82
|
+
React.createElement(Grid, { container: true, justifyContent: "left", spacing: paddings, className: "ET-ViewPage", sx: {
|
|
83
|
+
'.MuiTypography-subtitle2': {
|
|
84
|
+
fontWeight: 'bold'
|
|
85
|
+
}
|
|
86
|
+
} }, fields.map((field, index) => {
|
|
87
|
+
// Get data
|
|
88
|
+
const [itemData, itemLabel, gridProps] = getItemField(field, data);
|
|
89
|
+
// Some callback function may return '' instead of undefined
|
|
90
|
+
if (itemData == null || itemData === '')
|
|
91
|
+
return undefined;
|
|
92
|
+
// Layout
|
|
93
|
+
return (React.createElement(Grid, { item: true, ...gridProps, key: index },
|
|
94
|
+
React.createElement(Typography, { variant: "caption", component: "div" },
|
|
95
|
+
itemLabel,
|
|
96
|
+
":"),
|
|
97
|
+
React.createElement(Typography, { variant: "subtitle2" }, itemData)));
|
|
98
|
+
})),
|
|
99
|
+
actions != null && (React.createElement(Stack, { className: "ET-ViewPage-Actions", direction: "row", width: "100%", flexWrap: "wrap", justifyContent: "flex-end", paddingTop: paddings, paddingBottom: paddings, gap: paddings }, Utils.getResult(actions, data, refresh))),
|
|
100
|
+
Utils.getResult(children, data, refresh),
|
|
101
|
+
pullToRefresh && (React.createElement(PullToRefreshUI, { mainElement: pullContainer, triggerElement: pullContainer, instructionsPullToRefresh: labels.pullToRefresh, instructionsReleaseToRefresh: labels.releaseToRefresh, instructionsRefreshing: labels.refreshing, onRefresh: refresh, shouldPullToRefresh: () => {
|
|
102
|
+
const container = document.querySelector(pullContainer);
|
|
103
|
+
return !(container === null || container === void 0 ? void 0 : container.scrollTop);
|
|
104
|
+
} }))))));
|
|
105
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { DateUtils } from '@etsoo/shared';
|
|
3
|
+
import { TypographyProps } from '@mui/material';
|
|
4
|
+
/**
|
|
5
|
+
* Date text props
|
|
6
|
+
*/
|
|
7
|
+
export interface DateTextProps extends TypographyProps {
|
|
8
|
+
/**
|
|
9
|
+
* Locale
|
|
10
|
+
*/
|
|
11
|
+
locale?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Near days to show in error color
|
|
14
|
+
*/
|
|
15
|
+
nearDays?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Options
|
|
18
|
+
*/
|
|
19
|
+
options?: DateUtils.FormatOptions;
|
|
20
|
+
/**
|
|
21
|
+
* Time zone
|
|
22
|
+
*/
|
|
23
|
+
timeZone?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Value to display
|
|
26
|
+
*/
|
|
27
|
+
value?: Date | string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Date text
|
|
31
|
+
* @param props Props
|
|
32
|
+
* @returns Component
|
|
33
|
+
*/
|
|
34
|
+
export declare function DateText(props: DateTextProps): JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DateUtils } from '@etsoo/shared';
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Date text
|
|
6
|
+
* @param props Props
|
|
7
|
+
* @returns Component
|
|
8
|
+
*/
|
|
9
|
+
export function DateText(props) {
|
|
10
|
+
// Destruct
|
|
11
|
+
const { nearDays, locale = 'lookup', options, timeZone, value, ...rest } = props;
|
|
12
|
+
// Format date
|
|
13
|
+
const date = DateUtils.parse(value);
|
|
14
|
+
// Formatted value
|
|
15
|
+
const localValue = date == null
|
|
16
|
+
? undefined
|
|
17
|
+
: DateUtils.format(value, locale, options, timeZone);
|
|
18
|
+
if (nearDays != null &&
|
|
19
|
+
date != null &&
|
|
20
|
+
Math.abs(new Date().substract(date).totalDays) <= nearDays) {
|
|
21
|
+
rest.color = (theme) => theme.palette.error.main;
|
|
22
|
+
}
|
|
23
|
+
// Layout
|
|
24
|
+
return (React.createElement(Typography, { component: "span", fontSize: "inherit", ...rest }, localValue));
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { NumberTextProps } from './NumberText';
|
|
3
|
+
/**
|
|
4
|
+
* Money text props
|
|
5
|
+
*/
|
|
6
|
+
export interface MoneyTextProps extends NumberTextProps {
|
|
7
|
+
/**
|
|
8
|
+
* Currency, USD for US dollar
|
|
9
|
+
*/
|
|
10
|
+
currency?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Is integer number
|
|
13
|
+
*/
|
|
14
|
+
isInteger?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Money text
|
|
18
|
+
* @param props Props
|
|
19
|
+
* @returns Component
|
|
20
|
+
*/
|
|
21
|
+
export declare function MoneyText(props: MoneyTextProps): JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NumberUtils } from '@etsoo/shared';
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Money text
|
|
6
|
+
* @param props Props
|
|
7
|
+
* @returns Component
|
|
8
|
+
*/
|
|
9
|
+
export function MoneyText(props) {
|
|
10
|
+
// Destruct
|
|
11
|
+
const { currency, isInteger = false, locale, options = {}, value, ...rest } = props;
|
|
12
|
+
// Layout
|
|
13
|
+
return (React.createElement(Typography, { component: "span", fontSize: "inherit", ...rest }, NumberUtils.formatMoney(value, currency, locale, isInteger, options)));
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { TypographyProps } from '@mui/material';
|
|
3
|
+
/**
|
|
4
|
+
* Number text props
|
|
5
|
+
*/
|
|
6
|
+
export interface NumberTextProps extends TypographyProps {
|
|
7
|
+
/**
|
|
8
|
+
* Locale
|
|
9
|
+
*/
|
|
10
|
+
locale?: string | string[];
|
|
11
|
+
/**
|
|
12
|
+
* Options
|
|
13
|
+
*/
|
|
14
|
+
options?: Intl.NumberFormatOptions;
|
|
15
|
+
/**
|
|
16
|
+
* Value
|
|
17
|
+
*/
|
|
18
|
+
value?: number | bigint;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Number text
|
|
22
|
+
* @param props Props
|
|
23
|
+
* @returns Component
|
|
24
|
+
*/
|
|
25
|
+
export declare function NumberText(props: NumberTextProps): JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NumberUtils } from '@etsoo/shared';
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Number text
|
|
6
|
+
* @param props Props
|
|
7
|
+
* @returns Component
|
|
8
|
+
*/
|
|
9
|
+
export function NumberText(props) {
|
|
10
|
+
// Destruct
|
|
11
|
+
const { locale, options = {}, value, ...rest } = props;
|
|
12
|
+
// Layout
|
|
13
|
+
return (React.createElement(Typography, { component: "span", fontSize: "inherit", ...rest }, NumberUtils.format(value, locale, options)));
|
|
14
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@etsoo/materialui",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "TypeScript Material-UI Implementation",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"format": "prettier --write src/**/*.{ts,tsx}",
|
|
10
|
+
"lint": "eslint --ext .ts,.tsx src/",
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand"
|
|
13
|
+
},
|
|
14
|
+
"jest": {
|
|
15
|
+
"automock": false,
|
|
16
|
+
"testMatch": [
|
|
17
|
+
"<rootDir>/__tests__/**/*.{ts,tsx}"
|
|
18
|
+
],
|
|
19
|
+
"testEnvironment": "jsdom",
|
|
20
|
+
"transform": {
|
|
21
|
+
".+\\.jsx?$": "babel-jest",
|
|
22
|
+
".+\\.tsx?$": "ts-jest"
|
|
23
|
+
},
|
|
24
|
+
"transformIgnorePatterns": [
|
|
25
|
+
"/node_modules/(?!@etsoo/).+\\.js$"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/ETSOO/ReactMU.git"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"React",
|
|
34
|
+
"MaterialUI",
|
|
35
|
+
"TypeScript",
|
|
36
|
+
"ETSOO",
|
|
37
|
+
"SmartERP",
|
|
38
|
+
"司友云平台",
|
|
39
|
+
"青岛亿速思维",
|
|
40
|
+
"上海亿商"
|
|
41
|
+
],
|
|
42
|
+
"author": "ETSOO",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/ETSOO/ReactMU/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/ETSOO/ReactMU#readme",
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@dnd-kit/core": "^6.0.5",
|
|
50
|
+
"@dnd-kit/sortable": "^7.0.1",
|
|
51
|
+
"@emotion/css": "^11.10.0",
|
|
52
|
+
"@emotion/react": "^11.10.0",
|
|
53
|
+
"@emotion/styled": "^11.10.0",
|
|
54
|
+
"@etsoo/appscript": "^1.2.88",
|
|
55
|
+
"@etsoo/notificationbase": "^1.1.7",
|
|
56
|
+
"@etsoo/react": "^1.5.81",
|
|
57
|
+
"@etsoo/shared": "^1.1.51",
|
|
58
|
+
"@mui/icons-material": "^5.10.2",
|
|
59
|
+
"@mui/material": "^5.10.2",
|
|
60
|
+
"@types/pica": "^9.0.1",
|
|
61
|
+
"@types/pulltorefreshjs": "^0.1.5",
|
|
62
|
+
"@types/react": "^18.0.17",
|
|
63
|
+
"@types/react-avatar-editor": "^13.0.0",
|
|
64
|
+
"@types/react-dom": "^18.0.6",
|
|
65
|
+
"@types/react-input-mask": "^3.0.1",
|
|
66
|
+
"@types/react-window": "^1.8.5",
|
|
67
|
+
"pica": "^9.0.1",
|
|
68
|
+
"pulltorefreshjs": "^0.1.22",
|
|
69
|
+
"react": "^18.2.0",
|
|
70
|
+
"react-avatar-editor": "^13.0.0",
|
|
71
|
+
"react-dom": "^18.2.0",
|
|
72
|
+
"react-draggable": "^4.4.5",
|
|
73
|
+
"react-imask": "^6.4.2",
|
|
74
|
+
"react-router-dom": "^6.3.0",
|
|
75
|
+
"react-window": "^1.8.7"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@babel/cli": "^7.18.10",
|
|
79
|
+
"@babel/core": "^7.18.13",
|
|
80
|
+
"@babel/plugin-transform-runtime": "^7.18.10",
|
|
81
|
+
"@babel/preset-env": "^7.18.10",
|
|
82
|
+
"@babel/runtime-corejs3": "^7.18.9",
|
|
83
|
+
"@testing-library/jest-dom": "^5.16.5",
|
|
84
|
+
"@testing-library/react": "^13.3.0",
|
|
85
|
+
"@types/jest": "^28.1.8",
|
|
86
|
+
"@typescript-eslint/eslint-plugin": "^5.35.1",
|
|
87
|
+
"@typescript-eslint/parser": "^5.35.1",
|
|
88
|
+
"eslint": "^8.23.0",
|
|
89
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
90
|
+
"eslint-plugin-import": "^2.26.0",
|
|
91
|
+
"eslint-plugin-react": "^7.31.1",
|
|
92
|
+
"jest": "^28.1.3",
|
|
93
|
+
"jest-environment-jsdom": "^28.1.3",
|
|
94
|
+
"ts-jest": "^28.0.8",
|
|
95
|
+
"typescript": "^4.8.2"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Utils } from '@etsoo/shared';
|
|
2
|
+
import { Button, Divider, Theme, Typography, useTheme } from '@mui/material';
|
|
3
|
+
import React, { CSSProperties } from 'react';
|
|
4
|
+
import { globalApp } from './app/ReactApp';
|
|
5
|
+
import { ListMoreDisplay, ListMoreDisplayProps } from './ListMoreDisplay';
|
|
6
|
+
import { AuditLineUpdateData, ShowDataComparison } from './ShowDataComparison';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Audit line data model
|
|
10
|
+
*/
|
|
11
|
+
export interface AuditLine {
|
|
12
|
+
id: number;
|
|
13
|
+
creation: Date;
|
|
14
|
+
user: string;
|
|
15
|
+
action: string;
|
|
16
|
+
changes?: AuditLineUpdateData;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Audit display props
|
|
21
|
+
*/
|
|
22
|
+
export interface AuditDisplayProps
|
|
23
|
+
extends Omit<ListMoreDisplayProps<AuditLine>, 'children'> {
|
|
24
|
+
/**
|
|
25
|
+
* Get list item style callback
|
|
26
|
+
*/
|
|
27
|
+
getItemStyle?: (index: number, theme: Theme) => CSSProperties;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Item/line renderer
|
|
31
|
+
*/
|
|
32
|
+
itemRenderer?: (data: AuditLine, index: number) => React.ReactNode;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Get label
|
|
36
|
+
const getLabel = (key: string) => {
|
|
37
|
+
return globalApp.get(Utils.formatInitial(key)) ?? key;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Format date
|
|
41
|
+
const formatDate = (date: Date) => {
|
|
42
|
+
if (typeof globalApp === 'undefined') return date.toUTCString();
|
|
43
|
+
return globalApp.formatDate(date, 'ds');
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Audit display
|
|
48
|
+
* @param props Props
|
|
49
|
+
* @returns Component
|
|
50
|
+
*/
|
|
51
|
+
export function AuditDisplay(props: AuditDisplayProps) {
|
|
52
|
+
// Theme
|
|
53
|
+
const theme = useTheme();
|
|
54
|
+
|
|
55
|
+
// Title
|
|
56
|
+
var title = getLabel('dataComparison');
|
|
57
|
+
|
|
58
|
+
// Destruct
|
|
59
|
+
const {
|
|
60
|
+
getItemStyle = (index, theme) => ({
|
|
61
|
+
padding: [theme.spacing(1.5), theme.spacing(1)].join(' '),
|
|
62
|
+
background:
|
|
63
|
+
index % 2 === 0
|
|
64
|
+
? theme.palette.grey[100]
|
|
65
|
+
: theme.palette.grey[50]
|
|
66
|
+
}),
|
|
67
|
+
itemRenderer = (data) => {
|
|
68
|
+
const changes = data.changes;
|
|
69
|
+
return (
|
|
70
|
+
<React.Fragment>
|
|
71
|
+
{changes != null && (
|
|
72
|
+
<Button
|
|
73
|
+
variant="outlined"
|
|
74
|
+
size="small"
|
|
75
|
+
onClick={() => ShowDataComparison(changes, title)}
|
|
76
|
+
sx={{
|
|
77
|
+
marginLeft: theme.spacing(1),
|
|
78
|
+
marginTop: theme.spacing(-0.5),
|
|
79
|
+
float: 'right'
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
{title}
|
|
83
|
+
</Button>
|
|
84
|
+
)}
|
|
85
|
+
<Typography>
|
|
86
|
+
{formatDate(data.creation) +
|
|
87
|
+
', [' +
|
|
88
|
+
getLabel(data.action) +
|
|
89
|
+
'], ' +
|
|
90
|
+
data.user}
|
|
91
|
+
</Typography>
|
|
92
|
+
</React.Fragment>
|
|
93
|
+
);
|
|
94
|
+
},
|
|
95
|
+
headerTitle = (
|
|
96
|
+
<React.Fragment>
|
|
97
|
+
<Typography>{getLabel('audits')}</Typography>
|
|
98
|
+
<Divider />
|
|
99
|
+
</React.Fragment>
|
|
100
|
+
),
|
|
101
|
+
...rest
|
|
102
|
+
} = props;
|
|
103
|
+
|
|
104
|
+
// Layout
|
|
105
|
+
return (
|
|
106
|
+
<ListMoreDisplay<AuditLine> headerTitle={headerTitle} {...rest}>
|
|
107
|
+
{(data, index) => (
|
|
108
|
+
<div key={data.id} style={getItemStyle(index, theme)}>
|
|
109
|
+
{itemRenderer(data, index)}
|
|
110
|
+
</div>
|
|
111
|
+
)}
|
|
112
|
+
</ListMoreDisplay>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { DataTypes } from '@etsoo/shared';
|
|
2
|
+
import { AutocompleteProps } from '@mui/material';
|
|
3
|
+
import { ChangeEventHandler } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Autocomplete extended props
|
|
7
|
+
*/
|
|
8
|
+
export type AutocompleteExtendedProps<
|
|
9
|
+
T extends object,
|
|
10
|
+
D extends DataTypes.Keys<T>
|
|
11
|
+
> = Omit<
|
|
12
|
+
AutocompleteProps<T, undefined, false, false>,
|
|
13
|
+
'renderInput' | 'options'
|
|
14
|
+
> & {
|
|
15
|
+
/**
|
|
16
|
+
* Id field
|
|
17
|
+
*/
|
|
18
|
+
idField?: D;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Id value
|
|
22
|
+
*/
|
|
23
|
+
idValue?: T[D];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Autocomplete for the input
|
|
27
|
+
*/
|
|
28
|
+
inputAutoComplete?: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* If `true`, the label is displayed in an error state.
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
inputError?: boolean;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The helper text content.
|
|
38
|
+
*/
|
|
39
|
+
inputHelperText?: React.ReactNode;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* If `dense` or `normal`, will adjust vertical spacing of this and contained components.
|
|
43
|
+
* @default 'none'
|
|
44
|
+
*/
|
|
45
|
+
inputMargin?: 'dense' | 'normal' | 'none';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Input onChange hanlder
|
|
49
|
+
*/
|
|
50
|
+
inputOnChange?: ChangeEventHandler<HTMLInputElement> | undefined;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* If `true`, the label will indicate that the `input` is required.
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
inputRequired?: boolean;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The variant to use.
|
|
60
|
+
* @default 'outlined'
|
|
61
|
+
*/
|
|
62
|
+
inputVariant?: 'standard' | 'outlined' | 'filled';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Label of the field
|
|
66
|
+
*/
|
|
67
|
+
label: string;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Name of the field
|
|
71
|
+
*/
|
|
72
|
+
name: string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Is the field read only?
|
|
76
|
+
*/
|
|
77
|
+
readOnly?: boolean;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Is search field?
|
|
81
|
+
*/
|
|
82
|
+
search?: boolean;
|
|
83
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { IconButton, IconButtonProps, useTheme } from '@mui/material';
|
|
2
|
+
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useNavigate } from 'react-router-dom';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* BackButton props
|
|
8
|
+
*/
|
|
9
|
+
export interface BackButtonProps extends IconButtonProps {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* BackButton
|
|
13
|
+
* @param props Props
|
|
14
|
+
* @returns Component
|
|
15
|
+
*/
|
|
16
|
+
export function BackButton(props: BackButtonProps) {
|
|
17
|
+
// Destruct
|
|
18
|
+
const { color = 'primary', size = 'small', onClick, ...rest } = props;
|
|
19
|
+
|
|
20
|
+
// Theme
|
|
21
|
+
const theme = useTheme();
|
|
22
|
+
|
|
23
|
+
// Navigate
|
|
24
|
+
const navigate = useNavigate();
|
|
25
|
+
|
|
26
|
+
// Color
|
|
27
|
+
const pColor =
|
|
28
|
+
color != 'inherit' && color != 'default' && color in theme.palette
|
|
29
|
+
? theme.palette[color]
|
|
30
|
+
: theme.palette.primary;
|
|
31
|
+
|
|
32
|
+
// Click handler
|
|
33
|
+
const onClickLocal = async (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
34
|
+
if (onClick) onClick(event);
|
|
35
|
+
|
|
36
|
+
// Navigate
|
|
37
|
+
navigate(-1);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<IconButton
|
|
42
|
+
aria-label="Back"
|
|
43
|
+
color={color}
|
|
44
|
+
size={size}
|
|
45
|
+
onClick={onClickLocal}
|
|
46
|
+
sx={{
|
|
47
|
+
backgroundColor: pColor.contrastText,
|
|
48
|
+
border: `1px solid ${pColor.light}`
|
|
49
|
+
}}
|
|
50
|
+
{...rest}
|
|
51
|
+
>
|
|
52
|
+
<ArrowBackIcon />
|
|
53
|
+
</IconButton>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { BridgeUtils, IBridgeHost } from '@etsoo/appscript';
|
|
2
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
3
|
+
import { Box, BoxProps, IconButton, IconButtonProps } from '@mui/material';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { globalApp } from './app/ReactApp';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Bridge close button props
|
|
9
|
+
*/
|
|
10
|
+
export interface BridgeCloseButtonProps extends IconButtonProps {
|
|
11
|
+
/**
|
|
12
|
+
* Box props
|
|
13
|
+
*/
|
|
14
|
+
boxProps?: BoxProps;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Validate the host
|
|
18
|
+
* @param host Host
|
|
19
|
+
*/
|
|
20
|
+
validate?(host: IBridgeHost): boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Bridge close button
|
|
25
|
+
* @param props Props
|
|
26
|
+
* @returns Component
|
|
27
|
+
*/
|
|
28
|
+
export function BridgeCloseButton(props: BridgeCloseButtonProps) {
|
|
29
|
+
// Destruct
|
|
30
|
+
const {
|
|
31
|
+
boxProps,
|
|
32
|
+
onClick,
|
|
33
|
+
title = typeof globalApp === 'undefined'
|
|
34
|
+
? 'Close'
|
|
35
|
+
: globalApp.get('close'),
|
|
36
|
+
validate,
|
|
37
|
+
...rest
|
|
38
|
+
} = props;
|
|
39
|
+
|
|
40
|
+
// Host
|
|
41
|
+
const host = BridgeUtils.host;
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
host == null ||
|
|
45
|
+
!host.closable() ||
|
|
46
|
+
(validate && validate(host) === false)
|
|
47
|
+
) {
|
|
48
|
+
return <React.Fragment />;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Click handler
|
|
52
|
+
const onClickLocal = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
53
|
+
if (onClick) onClick(event);
|
|
54
|
+
host.exit();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<Box {...boxProps}>
|
|
59
|
+
<IconButton
|
|
60
|
+
aria-label="close"
|
|
61
|
+
onClick={onClickLocal}
|
|
62
|
+
title={title}
|
|
63
|
+
{...rest}
|
|
64
|
+
>
|
|
65
|
+
<CloseIcon />
|
|
66
|
+
</IconButton>
|
|
67
|
+
</Box>
|
|
68
|
+
);
|
|
69
|
+
}
|