ish-ui 1.0.2

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.
Files changed (126) hide show
  1. package/.eslintrc.json +39 -0
  2. package/.gitattributes +3 -0
  3. package/.github/workflows/release-package.yml +33 -0
  4. package/.prettierrc +5 -0
  5. package/README.md +80 -0
  6. package/assets/fonts/inter/Inter-Italic.var.woff2 +0 -0
  7. package/assets/fonts/inter/Inter-Roman.var.woff2 +0 -0
  8. package/assets/fonts/inter/LICENSE.txt +92 -0
  9. package/assets/fonts/inter/index.d.ts +10 -0
  10. package/assets/fonts/inter/inter.scss +17 -0
  11. package/package.json +108 -0
  12. package/src/actions/FieldProcessing.ts +21 -0
  13. package/src/actions/index.ts +10 -0
  14. package/src/appBar/AppBarHelpMenu.tsx +139 -0
  15. package/src/appBar/index.ts +9 -0
  16. package/src/buttons/AddButton.tsx +30 -0
  17. package/src/buttons/TimetableButton.tsx +19 -0
  18. package/src/buttons/index.ts +10 -0
  19. package/src/colorPicker/ColorPicker.tsx +223 -0
  20. package/src/colorPicker/index.ts +9 -0
  21. package/src/dialog/BrowserWarning.tsx +24 -0
  22. package/src/dialog/confirm/ConfirmBase.tsx +59 -0
  23. package/src/dialog/index.ts +11 -0
  24. package/src/dialog/message/Message.tsx +140 -0
  25. package/src/documents/DocumentIconsChooser.tsx +69 -0
  26. package/src/documents/index.ts +10 -0
  27. package/src/documents/utils/index.tsx +71 -0
  28. package/src/dynamicSizeList/DynamicSizeList.tsx +208 -0
  29. package/src/dynamicSizeList/index.ts +9 -0
  30. package/src/fieldMessage/ErrorMessage.tsx +28 -0
  31. package/src/fieldMessage/WarningMessage.tsx +28 -0
  32. package/src/fieldMessage/index.ts +11 -0
  33. package/src/fieldMessage/styles.ts +21 -0
  34. package/src/fileUploader/FileUploaderDialog.tsx +158 -0
  35. package/src/fileUploader/index.ts +9 -0
  36. package/src/formFields/CheckboxField.tsx +90 -0
  37. package/src/formFields/CodeEditorField.tsx +103 -0
  38. package/src/formFields/ColoredCheckBox.tsx +74 -0
  39. package/src/formFields/DateTimeField.tsx +61 -0
  40. package/src/formFields/EditInPlaceDateTimeField.tsx +285 -0
  41. package/src/formFields/EditInPlaceDurationField.tsx +79 -0
  42. package/src/formFields/EditInPlaceField.tsx +131 -0
  43. package/src/formFields/EditInPlaceFieldBase.tsx +241 -0
  44. package/src/formFields/EditInPlaceFileField.tsx +67 -0
  45. package/src/formFields/EditInPlaceMoneyField.tsx +64 -0
  46. package/src/formFields/EditInPlacePhoneField.tsx +97 -0
  47. package/src/formFields/EditInPlaceSearchSelect.tsx +562 -0
  48. package/src/formFields/FieldAdornments.tsx +70 -0
  49. package/src/formFields/FilePreview.tsx +149 -0
  50. package/src/formFields/FormRadioButtons.tsx +62 -0
  51. package/src/formFields/SelectCustomComponents.tsx +228 -0
  52. package/src/formFields/Switch.tsx +146 -0
  53. package/src/formFields/TextField.tsx +60 -0
  54. package/src/formFields/UneditableBase.tsx +101 -0
  55. package/src/formFields/index.ts +27 -0
  56. package/src/index.ts +26 -0
  57. package/src/layout/InfoPill.tsx +36 -0
  58. package/src/layout/index.ts +10 -0
  59. package/src/layout/resizable/ResizableWrapper.tsx +87 -0
  60. package/src/markdownEditor/HtmlEditor.tsx +44 -0
  61. package/src/markdownEditor/WysiwygEditor.tsx +137 -0
  62. package/src/markdownEditor/index.ts +12 -0
  63. package/src/markdownEditor/style.ts +188 -0
  64. package/src/markdownEditor/utils/index.ts +48 -0
  65. package/src/model/AppBar.ts +20 -0
  66. package/src/model/CommomObjects.ts +8 -0
  67. package/src/model/CommonFunctions.ts +20 -0
  68. package/src/model/Confirm.ts +27 -0
  69. package/src/model/Fields.ts +254 -0
  70. package/src/model/NestedEntity.ts +14 -0
  71. package/src/model/Theme.ts +42 -0
  72. package/src/model/index.ts +16 -0
  73. package/src/styles/GlobalStylesProvider.tsx +520 -0
  74. package/src/styles/StylesProviderCustom.tsx +8 -0
  75. package/src/styles/animateStyles.ts +94 -0
  76. package/src/styles/bootstrap.ts +503 -0
  77. package/src/styles/hooks.ts +44 -0
  78. package/src/styles/index.ts +18 -0
  79. package/src/styles/makeStyles.ts +21 -0
  80. package/src/styles/mixins/common.ts +40 -0
  81. package/src/styles/mixins/keyframes.ts +16 -0
  82. package/src/styles/mixins/prefixer.ts +21 -0
  83. package/src/tagsInput/AddTagMenu.tsx +74 -0
  84. package/src/tagsInput/AddTagMenuItem.tsx +50 -0
  85. package/src/tagsInput/TagInputList.tsx +428 -0
  86. package/src/tagsInput/index.ts +4 -0
  87. package/src/themes/appTheme.ts +324 -0
  88. package/src/themes/index.ts +10 -0
  89. package/src/themes/ishTheme.ts +401 -0
  90. package/src/timetable/datePeriodFilter/DayPeriodIcons.tsx +95 -0
  91. package/src/timetable/datePeriodFilter/index.ts +10 -0
  92. package/src/timetable/index.ts +11 -0
  93. package/src/timetable/miniCalendar/CalendarDay.tsx +109 -0
  94. package/src/timetable/miniCalendar/CalendarHeader.tsx +37 -0
  95. package/src/timetable/miniCalendar/CalendarWeekPanel.tsx +35 -0
  96. package/src/timetable/miniCalendar/WeekDay.tsx +49 -0
  97. package/src/timetable/miniCalendar/index.ts +13 -0
  98. package/src/utils/DOM/Links.ts +17 -0
  99. package/src/utils/DOM/getCaretCoordinates.ts +122 -0
  100. package/src/utils/DOM/getOS.ts +32 -0
  101. package/src/utils/DOM/index.ts +34 -0
  102. package/src/utils/dates/datesNormalizing.ts +4 -0
  103. package/src/utils/dates/format.ts +52 -0
  104. package/src/utils/dates/formatRelative.ts +22 -0
  105. package/src/utils/dates/formatString.ts +233 -0
  106. package/src/utils/dates/formatTimezone.ts +37 -0
  107. package/src/utils/dates/index.ts +15 -0
  108. package/src/utils/dates/timetable.ts +46 -0
  109. package/src/utils/events/index.ts +8 -0
  110. package/src/utils/fields/index.ts +23 -0
  111. package/src/utils/formatting/PhoneMasks.ts +320 -0
  112. package/src/utils/formatting/index.tsx +20 -0
  113. package/src/utils/hooks/index.ts +19 -0
  114. package/src/utils/index.ts +15 -0
  115. package/src/utils/numbers/decimalCalculation.ts +26 -0
  116. package/src/utils/numbers/index.ts +11 -0
  117. package/src/utils/numbers/numbersNormalizing.ts +52 -0
  118. package/src/utils/stubs/index.tsx +12 -0
  119. package/src/utils/tags/index.ts +53 -0
  120. package/tools/webpack/webpack.aliases.js +13 -0
  121. package/tools/webpack/webpack.config.dev.js +29 -0
  122. package/tools/webpack/webpack.config.prod.js +36 -0
  123. package/tools/webpack/webpack.helpers.js +26 -0
  124. package/tools/webpack/webpack.plugins.js +15 -0
  125. package/tools/webpack/webpack.rules.js +51 -0
  126. package/tsconfig.json +24 -0
@@ -0,0 +1,208 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2022.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ // Temporary implementation
10
+ // TODO: Remove component when native DynamicSizeList will be included in react-window v.2
11
+ import React from 'react';
12
+ import { VariableSizeList } from 'react-window';
13
+
14
+ interface Props {
15
+ height: number;
16
+ itemCount: number;
17
+ width: number;
18
+ estimatedItemSize: number;
19
+ children: any;
20
+ listRef?: any;
21
+ }
22
+
23
+ class ItemMeasurer extends React.Component<any, any> {
24
+ _node = null;
25
+
26
+ _resizeObserver = null;
27
+
28
+ componentDidMount() {
29
+ this._measureItem();
30
+
31
+ // @ts-ignore
32
+ if (typeof window.ResizeObserver !== 'undefined') {
33
+ // @ts-ignore
34
+ this._resizeObserver = new window.ResizeObserver(this._onResize);
35
+
36
+ if (this._node !== null) {
37
+ this._resizeObserver.observe(this._node);
38
+ }
39
+ } else {
40
+ //
41
+ }
42
+ }
43
+
44
+ componentWillUnmount() {
45
+ if (this._resizeObserver !== null) {
46
+ this._resizeObserver.disconnect();
47
+ this._resizeObserver = null;
48
+ }
49
+ }
50
+
51
+ render() {
52
+ return React.cloneElement(this.props.item, {
53
+ ref: this._refSetter
54
+ });
55
+ }
56
+
57
+ _measureItem = () => {
58
+ const { handleNewMeasurements, index } = this.props;
59
+
60
+ const node = this._node;
61
+
62
+ if (node) {
63
+ const { height, width } = node.getBoundingClientRect();
64
+ const isVisible = height > 0 || width > 0;
65
+
66
+ if (isVisible) {
67
+ const newSize = Math.ceil(height);
68
+
69
+ handleNewMeasurements(index, newSize);
70
+ }
71
+ }
72
+ };
73
+
74
+ _refSetter = ref => {
75
+ if (this._resizeObserver !== null && this._node !== null) {
76
+ this._resizeObserver.unobserve(this._node);
77
+ }
78
+
79
+ if (ref) {
80
+ this._node = ref;
81
+ } else {
82
+ this._node = null;
83
+ }
84
+
85
+ if (this._resizeObserver !== null && this._node !== null) {
86
+ this._resizeObserver.observe(this._node);
87
+ }
88
+ };
89
+
90
+ _onResize = entries => {
91
+ const _this = this;
92
+ window.requestAnimationFrame(() => {
93
+ if (!Array.isArray(entries) || !entries.length) {
94
+ return;
95
+ }
96
+ _this._measureItem();
97
+ });
98
+ };
99
+ }
100
+
101
+ class DynamicSizeList extends React.Component<Props> {
102
+ listRef = React.createRef<any>();
103
+
104
+ rowSizes = [];
105
+
106
+ componentDidMount() {
107
+ const ref = this.listRef.current;
108
+ if (ref) {
109
+ ref.resetAfterIndex(0, true);
110
+ }
111
+ }
112
+
113
+ attachRefs = node => {
114
+ const { listRef } = this.props;
115
+
116
+ if (node) {
117
+ if (!this.listRef.current) {
118
+ // @ts-ignore
119
+ this.listRef.current = node;
120
+ }
121
+
122
+ if (typeof listRef === 'function') {
123
+ listRef(node);
124
+ }
125
+
126
+ if (typeof listRef === 'object') {
127
+ listRef.current = node;
128
+ }
129
+ }
130
+ };
131
+
132
+ render() {
133
+ const { children,
134
+ ...rest } = this.props;
135
+
136
+ return (
137
+ <VariableSizeList
138
+ {...rest}
139
+ ref={this.attachRefs}
140
+ itemSize={this.getItemSize}
141
+ >
142
+ {this.renderItem}
143
+ </VariableSizeList>
144
+ );
145
+ }
146
+
147
+ scrollToItem(index, align) {
148
+ const ref = this.listRef.current;
149
+
150
+ if (ref) {
151
+ ref.scrollToItem(index, align);
152
+ //
153
+ window.requestAnimationFrame(() => {
154
+ ref.scrollToItem(index, align);
155
+ });
156
+ }
157
+ }
158
+
159
+ renderItem = props => {
160
+ // clear height
161
+ if (props.style.height !== undefined) {
162
+ props.style.height = undefined;
163
+ }
164
+
165
+ return React.createElement<any>(ItemMeasurer, {
166
+ index: props.index,
167
+ // @ts-ignore
168
+ item: React.createElement(this.props.children, props),
169
+ handleNewMeasurements: this.handleNewMeasurements
170
+ });
171
+ };
172
+
173
+ handleNewMeasurements = (index, newSize) => {
174
+ const itemSizeDelta = newSize - this.getItemSize(index);
175
+
176
+ if (itemSizeDelta !== 0) {
177
+ this.rowSizes[index] = newSize;
178
+
179
+ const ref = this.listRef.current;
180
+
181
+ if (ref) {
182
+ const { isScrolling, scrollDirection } = ref.state;
183
+
184
+ if (isScrolling && scrollDirection === 'backward') {
185
+ ref._outerRef.scrollBy({
186
+ top: itemSizeDelta,
187
+ left: 0,
188
+ behavior: 'auto'
189
+ });
190
+ }
191
+ ref.resetAfterIndex(index, true);
192
+ }
193
+ }
194
+ };
195
+
196
+ getItemSize = index => {
197
+ // https://react-window.now.sh/#/api/VariableSizeList
198
+ const defaultEstimatedItemSize = 50;
199
+
200
+ return (
201
+ this.rowSizes[index]
202
+ || this.props.estimatedItemSize
203
+ || defaultEstimatedItemSize
204
+ );
205
+ };
206
+ }
207
+
208
+ export default DynamicSizeList;
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './DynamicSizeList';
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright ish group pty ltd. All rights reserved. https://www.ish.com.au
3
+ * No copying or use of this code is allowed without permission in writing from ish.
4
+ */
5
+
6
+ import React from 'react';
7
+ import Error from '@mui/icons-material/Error';
8
+ import Typography from '@mui/material/Typography';
9
+ import withStyles from '@mui/styles/withStyles';
10
+ import clsx from 'clsx';
11
+ import styles from './styles';
12
+
13
+ interface Props {
14
+ classes?: any;
15
+ className?: string;
16
+ message: string;
17
+ }
18
+
19
+ const ErrorMessage: React.FC<Props> = ({ classes, className, message }) => (
20
+ <div className={clsx(classes.root, className)}>
21
+ <Error color="error" className={classes.icon} />
22
+ <Typography variant="caption" className="errorColor">
23
+ {message}
24
+ </Typography>
25
+ </div>
26
+ );
27
+
28
+ export default withStyles(styles)(ErrorMessage);
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright ish group pty ltd. All rights reserved. https://www.ish.com.au
3
+ * No copying or use of this code is allowed without permission in writing from ish.
4
+ */
5
+
6
+ import React from 'react';
7
+ import Warning from '@mui/icons-material/Warning';
8
+ import Typography from '@mui/material/Typography';
9
+ import withStyles from '@mui/styles/withStyles';
10
+ import clsx from 'clsx';
11
+ import styles from './styles';
12
+
13
+ interface Props {
14
+ classes?: any;
15
+ className?: string;
16
+ warning: string;
17
+ }
18
+
19
+ const WarningMessage: React.FC<Props> = ({ classes, className, warning }) => (
20
+ <div className={clsx(classes.root, className)}>
21
+ <Warning className={clsx(classes.icon, 'warningColor')} />
22
+ <Typography variant="caption" className="warningColor">
23
+ {warning}
24
+ </Typography>
25
+ </div>
26
+ );
27
+
28
+ export default withStyles(styles)(WarningMessage);
@@ -0,0 +1,11 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './styles';
10
+ export * from './ErrorMessage';
11
+ export * from './WarningMessage';
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright ish group pty ltd. All rights reserved. https://www.ish.com.au
3
+ * No copying or use of this code is allowed without permission in writing from ish.
4
+ */
5
+
6
+ import { createStyles } from '@mui/styles';
7
+ import { AppTheme } from '@src/model';
8
+
9
+ export default (theme: AppTheme) => createStyles({
10
+ root: {
11
+ marginTop: `-${theme.spacing(1)}`,
12
+ // @ts-ignore
13
+ paddingBottom: `${theme.spacing(2) - 3}`,
14
+ },
15
+ icon: {
16
+ fontSize: theme.spacing(2),
17
+ display: 'inline-block',
18
+ verticalAlign: 'middle',
19
+ marginRight: theme.spacing(0.5),
20
+ }
21
+ });
@@ -0,0 +1,158 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ import React from 'react';
10
+ import clsx from 'clsx';
11
+ import { useDropzone } from 'react-dropzone';
12
+ import { createStyles, withStyles } from '@mui/styles';
13
+ import { darken } from '@mui/material/styles';
14
+ import Typography from '@mui/material/Typography';
15
+ import Dialog from '@mui/material/Dialog';
16
+ import IconButton from '@mui/material/IconButton';
17
+ import CloseIcon from '@mui/icons-material/Close';
18
+ import Button from '@mui/material/Button';
19
+ import { AppTheme } from '@src/model';
20
+
21
+ const styles = createStyles((theme: AppTheme) => ({
22
+ fileContainer: {
23
+ border: `2px dotted ${theme.palette.primary.main}`,
24
+ borderRadius: 6,
25
+ transition: theme.transitions.create('background-color', {
26
+ duration: theme.transitions.duration.shorter,
27
+ easing: theme.transitions.easing.easeInOut
28
+ })
29
+ },
30
+ dragActive: {
31
+ backgroundColor: darken(theme.palette.background.default, 0.03),
32
+ boxShadow: theme.shadows[2]
33
+ },
34
+ fullScreenFileDropContainer: {
35
+ zIndex: 1300,
36
+ left: 0,
37
+ top: 0,
38
+ position: 'fixed'
39
+ },
40
+ boxDropContainer: {
41
+ zIndex: 1400
42
+ },
43
+ dialogCloseButton: {
44
+ right: theme.spacing(1),
45
+ top: theme.spacing(1),
46
+ color: theme.palette.grey[100]
47
+ }
48
+ }));
49
+
50
+ interface Props {
51
+ fileRef?: any;
52
+ classes?: any;
53
+ opened?: boolean;
54
+ backdropEnabled?: boolean;
55
+ dialog?: boolean;
56
+ onChange?: (acceptedfiles: any[], fileRejections: any[]) => void;
57
+ disabled?: boolean;
58
+ accept?: string | string[];
59
+ onClose?: () => void;
60
+ isBackdropDragging?: boolean;
61
+ }
62
+
63
+ const FileUploaderDialog: React.FC<Props> = (props => {
64
+ const {
65
+ fileRef, accept, disabled, classes, dialog, onChange, onClose, opened, backdropEnabled, isBackdropDragging
66
+ } = props;
67
+
68
+ const onFileDrop = (acceptedfiles, fileRejections) => {
69
+ if (onChange) onChange(acceptedfiles, fileRejections);
70
+ };
71
+
72
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
73
+ onDrop: onFileDrop,
74
+ multiple: false,
75
+ disabled,
76
+ accept
77
+ } as any);
78
+
79
+ const acceptText = () => {
80
+ const text = [];
81
+ if (Array.isArray(accept)) {
82
+ accept.forEach(type => {
83
+ const typePart = type.split('/');
84
+ if (typePart.length > 1) text.push(`*.${typePart[1]}`);
85
+ });
86
+ } else {
87
+ const typePart = accept.split('/');
88
+ if (typePart.length > 1) text.push(`*.${typePart[1]}`);
89
+ }
90
+ return text.join(', ');
91
+ };
92
+ const backdropUploaderContent = (
93
+ <div {...getRootProps()} className={clsx('w-100 h-100', classes.fullScreenFileDropContainer)}>
94
+ <div className="h-100 outline-none overflow-hidden cursor-pointer">
95
+ <div className="h-100 p-1">
96
+ <input {...getInputProps()} />
97
+ </div>
98
+ </div>
99
+ </div>
100
+ );
101
+
102
+ const uploadContent = (
103
+ <div {...getRootProps()} className={clsx('w-100 overflow-y-auto relative', classes.boxDropContainer, { 'zIndex2': isBackdropDragging })}>
104
+ <div className="h-100 outline-none overflow-hidden cursor-pointer">
105
+ <div className="h-100 p-1">
106
+ <input {...getInputProps()} />
107
+ <div
108
+ className={clsx('w-100 h-100 flex-column align-items-center justify-content-center text-center p-2 pb-3',
109
+ classes.fileContainer,
110
+ { [classes.dragActive]: isDragActive })}
111
+ >
112
+ <Typography variant="subtitle1" gutterBottom className="mb-0">Drop files here</Typography>
113
+ <Typography variant="caption" className="mb-1">or</Typography>
114
+ <Button
115
+ variant="contained"
116
+ size="small"
117
+ color="primary"
118
+ className="mb-1 fontWeight-normal"
119
+ >
120
+ Browse
121
+ </Button>
122
+ {accept && (
123
+ <Typography variant="caption" color="error">
124
+ Please upload only:
125
+ {' '}
126
+ {acceptText()}
127
+ </Typography>
128
+ )}
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ );
134
+
135
+ return dialog ? (
136
+ <Dialog
137
+ ref={fileRef}
138
+ open={opened}
139
+ disableEscapeKeyDown
140
+ onClose={onClose}
141
+ classes={{
142
+ paper: 'w-100'
143
+ }}
144
+ >
145
+ <div>
146
+ {onClose && (
147
+ <IconButton className={clsx('fixed zIndex1401 p-1', classes.dialogCloseButton)} onClick={onClose}>
148
+ <CloseIcon fontSize="small" />
149
+ </IconButton>
150
+ )}
151
+ {uploadContent}
152
+ {isBackdropDragging && backdropEnabled && backdropUploaderContent}
153
+ </div>
154
+ </Dialog>
155
+ ) : backdropEnabled ? backdropUploaderContent : uploadContent;
156
+ });
157
+
158
+ export default withStyles(styles)(FileUploaderDialog);
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './FileUploaderDialog';
@@ -0,0 +1,90 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ /**
10
+ * Redux Form field checkbox component creator
11
+ * */
12
+
13
+ import React, { useCallback } from 'react';
14
+ import Checkbox from '@mui/material/Checkbox';
15
+ import withStyles from '@mui/styles/withStyles';
16
+ import clsx from 'clsx';
17
+ import { CheckboxFieldProps, FieldInputProps } from '@src/model';
18
+
19
+ const getValue = (value, stringValue) => {
20
+ if (!stringValue) {
21
+ return !!value;
22
+ }
23
+
24
+ switch (value) {
25
+ case 'false':
26
+ return false;
27
+ case 'true':
28
+ return true;
29
+ default:
30
+ return Boolean(value);
31
+ }
32
+ };
33
+
34
+ const styles = theme => ({
35
+ root: {
36
+ width: theme.spacing(4),
37
+ height: theme.spacing(4),
38
+ margin: theme.spacing(0.5)
39
+ }
40
+ });
41
+
42
+ const StyledCheckboxBase = props => {
43
+ const {
44
+ classes, uncheckedClass, className, ...rest
45
+ } = props;
46
+
47
+ return (
48
+ <Checkbox
49
+ classes={{
50
+ root: clsx(classes.root, uncheckedClass, className),
51
+ }}
52
+ {...rest}
53
+ />
54
+ );
55
+ };
56
+
57
+ export const StyledCheckbox = withStyles(styles)(StyledCheckboxBase);
58
+
59
+ export function CheckboxField<IP extends FieldInputProps>({ input, color, disabled, stringValue, className, uncheckedClass, onChangeHandler, stopPropagation }: CheckboxFieldProps<IP>) {
60
+ const onChange = useCallback(
61
+ (e, value) => {
62
+ let checked = value;
63
+
64
+ if (stringValue) {
65
+ checked = checked.toString();
66
+ }
67
+ if (typeof onChangeHandler === 'function') {
68
+ onChangeHandler(e, checked);
69
+ }
70
+ if (!e.isDefaultPrevented()) {
71
+ input.onChange(checked);
72
+ }
73
+ },
74
+ [stringValue, input, onChangeHandler]
75
+ );
76
+
77
+ return (
78
+ <StyledCheckbox
79
+ checked={getValue(input.value, stringValue)}
80
+ onChange={onChange}
81
+ color={color}
82
+ disabled={disabled}
83
+ className={className}
84
+ uncheckedClass={uncheckedClass}
85
+ onClick={stopPropagation ? e => e.stopPropagation() : undefined}
86
+ id={`input-${input.name}`}
87
+ name={input.name}
88
+ />
89
+ );
90
+ }
@@ -0,0 +1,103 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ import React from 'react';
10
+ import clsx from 'clsx';
11
+ import AceEditor from 'react-ace';
12
+ import 'ace-builds/src-noconflict/mode-groovy';
13
+ import 'ace-builds/src-noconflict/theme-textmate';
14
+ import { CodeFieldProps, FieldInputProps, FieldMetaProps } from '@src/model';
15
+ import { makeAppStyles } from '@src/styles';
16
+
17
+ const useStyles = makeAppStyles(theme => (
18
+ {
19
+ editor: {
20
+ filter: theme.palette.mode === 'dark' ? 'invert(80%)' : '',
21
+ zIndex: 0,
22
+ outline: 'none'
23
+ },
24
+ errorBackground: {
25
+ '&.ace-tm': {
26
+ backgroundColor: theme.palette.error.light
27
+ }
28
+ },
29
+ errorMessage: {
30
+ position: 'absolute',
31
+ top: '50%',
32
+ left: '50%',
33
+ transform: 'translate(calc(-50% + 21px), -50%)',
34
+ color: '#fff',
35
+ fontFamily: 'sans-serif',
36
+ zIndex: 1
37
+ },
38
+ queryMarker: {
39
+ borderRadius: '4px',
40
+ width: '55px',
41
+ paddingLeft: '4px',
42
+ height: '25px',
43
+ background: '#fff',
44
+ cursor: 'pointer',
45
+ position: 'absolute',
46
+ zIndex: 2,
47
+ boxShadow: theme.shadows[1],
48
+ '&:after': {
49
+ content: '\'Query\'',
50
+ marginLeft: '2px'
51
+ },
52
+ '&:hover': {
53
+ background: theme.palette.grey[100]
54
+ }
55
+ }
56
+ }
57
+ ))
58
+
59
+ function CodeEditorField<IP extends FieldInputProps, MP extends FieldMetaProps>({
60
+ input,
61
+ meta: { error },
62
+ errorMessage,
63
+ disabled,
64
+ onFocus,
65
+ className
66
+ }: CodeFieldProps<IP, MP> ) {
67
+
68
+ const classes = useStyles();
69
+
70
+ return (
71
+ <div id={input.name} className={className}>
72
+ {error && <div className={classes.errorMessage}><div className="shakingError">{errorMessage || error}</div></div>}
73
+ <AceEditor
74
+ mode="groovy"
75
+ theme="textmate"
76
+ value={input.value || ' '}
77
+ onFocus={onFocus}
78
+ onChange={input.onChange}
79
+ fontSize={14}
80
+ showPrintMargin={false}
81
+ showGutter
82
+ highlightActiveLine
83
+ width="100%"
84
+ maxLines={Infinity}
85
+ className={clsx(classes.editor, {
86
+ [classes.errorBackground]: error
87
+ })}
88
+ wrapEnabled
89
+ setOptions={{
90
+ enableBasicAutocompletion: true,
91
+ enableLiveAutocompletion: true,
92
+ enableSnippets: true,
93
+ showLineNumbers: true,
94
+ readOnly: disabled,
95
+ tabSize: 2
96
+ }}
97
+ editorProps={{ $blockScrolling: Infinity }}
98
+ />
99
+ </div>
100
+ );
101
+ }
102
+
103
+ export default CodeEditorField;