@onehat/ui 0.4.37 → 0.4.39
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/package.json +1 -1
- package/src/Components/Form/Field/Combo/MeterTypesCombo.js +27 -0
- package/src/Components/Grid/Grid.js +12 -2
- package/src/Components/Grid/GridRow.js +45 -26
- package/src/Components/Viewer/MeterTypeText.js +23 -0
- package/src/Components/Viewer/TextWithLinks.js +98 -0
- package/src/Components/index.js +6 -0
- package/src/Constants/MeterTypes.js +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COPYRIGHT NOTICE
|
|
3
|
+
* This file is categorized as "Custom Source Code"
|
|
4
|
+
* and is subject to the terms and conditions defined in the
|
|
5
|
+
* "LICENSE.txt" file, which is part of this source code package.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import ArrayCombo from './ArrayCombo.js';
|
|
9
|
+
import {
|
|
10
|
+
METER_TYPES__HOURS,
|
|
11
|
+
METER_TYPES__MILES,
|
|
12
|
+
} from '../../../../Constants/MeterTypes.js';
|
|
13
|
+
|
|
14
|
+
const data = [
|
|
15
|
+
[METER_TYPES__HOURS, 'Hours'],
|
|
16
|
+
[METER_TYPES__MILES, 'Miles'],
|
|
17
|
+
];
|
|
18
|
+
function MeterTypesCombo(props) {
|
|
19
|
+
return <ArrayCombo
|
|
20
|
+
reference="MeterTypeCombo"
|
|
21
|
+
data={data}
|
|
22
|
+
disableDirectEntry={true}
|
|
23
|
+
{...props}
|
|
24
|
+
/>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default MeterTypesCombo;
|
|
@@ -763,8 +763,18 @@ function GridComponent(props) {
|
|
|
763
763
|
const
|
|
764
764
|
headerHeight = showHeaders ? 50 : 0,
|
|
765
765
|
footerHeight = !disablePagination ? 50 : 0,
|
|
766
|
-
height = containerHeight - headerHeight - footerHeight
|
|
767
|
-
|
|
766
|
+
height = containerHeight - headerHeight - footerHeight;
|
|
767
|
+
|
|
768
|
+
const rowsPerContainer = Math.floor(height / defaultRowHeight);
|
|
769
|
+
|
|
770
|
+
// // Get the total height of all rows
|
|
771
|
+
// const rows = gridRef.current._listRef._scrollRef.childNodes[0].childNodes;
|
|
772
|
+
// let totalRowHeight = 0;
|
|
773
|
+
// rows.forEach((row) => {
|
|
774
|
+
// totalRowHeight += row.getBoundingClientRect().height;
|
|
775
|
+
// });
|
|
776
|
+
// const rowsPerContainer = Math.floor(height / (totalRowHeight / rows.length));
|
|
777
|
+
|
|
768
778
|
let pageSize = rowsPerContainer;
|
|
769
779
|
if (showHeaders) {
|
|
770
780
|
pageSize--;
|
|
@@ -83,13 +83,17 @@ function GridRow(props) {
|
|
|
83
83
|
if (config.isHidden) {
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
|
-
const
|
|
87
|
-
|
|
86
|
+
const
|
|
87
|
+
propsToPass = columnProps[key] || {},
|
|
88
|
+
colStyle = {};
|
|
88
89
|
let colClassName = `
|
|
89
90
|
GridRow-column
|
|
90
91
|
p-1
|
|
91
92
|
justify-center
|
|
92
93
|
border-r-black-100
|
|
94
|
+
block
|
|
95
|
+
max-h-[40px]
|
|
96
|
+
overflow-scroll
|
|
93
97
|
`;
|
|
94
98
|
if (isOnlyOneVisibleColumn) {
|
|
95
99
|
colClassName = ' w-full';
|
|
@@ -152,9 +156,10 @@ function GridRow(props) {
|
|
|
152
156
|
if (config.fieldName) {
|
|
153
157
|
|
|
154
158
|
if (item?.properties && item.properties[config.fieldName]) {
|
|
155
|
-
const
|
|
159
|
+
const
|
|
160
|
+
property = item.properties[config.fieldName],
|
|
161
|
+
type = property?.viewerType?.type;
|
|
156
162
|
value = property.displayValue;
|
|
157
|
-
const type = property?.viewerType?.type;
|
|
158
163
|
|
|
159
164
|
if (type) {
|
|
160
165
|
const Element = getComponentFromType(type);
|
|
@@ -165,6 +170,24 @@ function GridRow(props) {
|
|
|
165
170
|
if (config.getCellProps) {
|
|
166
171
|
_.assign(elementProps, config.getCellProps(item));
|
|
167
172
|
}
|
|
173
|
+
let elementClassName = `
|
|
174
|
+
GridRow-Element
|
|
175
|
+
self-center
|
|
176
|
+
text-ellipsis
|
|
177
|
+
px-2
|
|
178
|
+
py-3
|
|
179
|
+
block
|
|
180
|
+
max-h-[40px]
|
|
181
|
+
overflow-scroll
|
|
182
|
+
${colClassName}
|
|
183
|
+
${styles.GRID_CELL_CLASSNAME}
|
|
184
|
+
`;
|
|
185
|
+
if (config.className) {
|
|
186
|
+
elementClassName += ' ' + config.className;
|
|
187
|
+
}
|
|
188
|
+
if (type.match(/(Tag|TagEditor)$/)) {
|
|
189
|
+
elementClassName += ' max-h-[80px]';
|
|
190
|
+
}
|
|
168
191
|
return <Element
|
|
169
192
|
{...testProps('cell-' + config.fieldName)}
|
|
170
193
|
value={value}
|
|
@@ -175,15 +198,7 @@ function GridRow(props) {
|
|
|
175
198
|
...colStyle,
|
|
176
199
|
}}
|
|
177
200
|
minimizeForRow={true}
|
|
178
|
-
className={
|
|
179
|
-
GridRow-Element
|
|
180
|
-
self-center
|
|
181
|
-
text-ellipsis
|
|
182
|
-
px-2
|
|
183
|
-
py-3
|
|
184
|
-
${colClassName}
|
|
185
|
-
${styles.GRID_CELL_CLASSNAME}
|
|
186
|
-
`}
|
|
201
|
+
className={elementClassName}
|
|
187
202
|
numberOfLines={1}
|
|
188
203
|
ellipsizeMode="head"
|
|
189
204
|
{...propsToPass}
|
|
@@ -213,6 +228,22 @@ function GridRow(props) {
|
|
|
213
228
|
if (config.getCellProps) {
|
|
214
229
|
_.assign(elementProps, config.getCellProps(item));
|
|
215
230
|
}
|
|
231
|
+
let textClassName = `
|
|
232
|
+
GridRow-TextNative
|
|
233
|
+
self-center
|
|
234
|
+
overflow-hidden
|
|
235
|
+
text-ellipsis
|
|
236
|
+
truncate
|
|
237
|
+
whitespace-nowrap
|
|
238
|
+
overflow-hidden
|
|
239
|
+
${colClassName}
|
|
240
|
+
${styles.GRID_CELL_CLASSNAME}
|
|
241
|
+
${styles.GRID_CELL_PX}
|
|
242
|
+
${styles.GRID_CELL_PY}
|
|
243
|
+
`;
|
|
244
|
+
if (config.className) {
|
|
245
|
+
textClassName += ' ' + config.className;
|
|
246
|
+
}
|
|
216
247
|
return <TextNative
|
|
217
248
|
{...testProps('cell-' + config.fieldName)}
|
|
218
249
|
key={key}
|
|
@@ -222,19 +253,7 @@ function GridRow(props) {
|
|
|
222
253
|
}}
|
|
223
254
|
numberOfLines={1}
|
|
224
255
|
ellipsizeMode="head"
|
|
225
|
-
className={
|
|
226
|
-
GridRow-TextNative
|
|
227
|
-
self-center
|
|
228
|
-
overflow-hidden
|
|
229
|
-
text-ellipsis
|
|
230
|
-
truncate
|
|
231
|
-
whitespace-nowrap
|
|
232
|
-
overflow-hidden
|
|
233
|
-
${colClassName}
|
|
234
|
-
${styles.GRID_CELL_CLASSNAME}
|
|
235
|
-
${styles.GRID_CELL_PX}
|
|
236
|
-
${styles.GRID_CELL_PY}
|
|
237
|
-
`}
|
|
256
|
+
className={textClassName}
|
|
238
257
|
{...elementProps}
|
|
239
258
|
{...propsToPass}
|
|
240
259
|
>{value}</TextNative>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Text,
|
|
3
|
+
} from '@project-components/Gluestack';
|
|
4
|
+
import UiGlobals from '../../UiGlobals';
|
|
5
|
+
|
|
6
|
+
export default function MeterTypeText(props) {
|
|
7
|
+
const styles = UiGlobals.styles;
|
|
8
|
+
|
|
9
|
+
let className = `
|
|
10
|
+
Text
|
|
11
|
+
flex-1
|
|
12
|
+
px-3
|
|
13
|
+
py-2
|
|
14
|
+
${styles.FORM_TEXT_CLASSNAME}
|
|
15
|
+
`;
|
|
16
|
+
if (props.className) {
|
|
17
|
+
className += ' ' + props.className;
|
|
18
|
+
}
|
|
19
|
+
return <Text
|
|
20
|
+
{...props}
|
|
21
|
+
className={className}
|
|
22
|
+
>{props.value ? 'Hours' : 'Miles'}</Text>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Linking,
|
|
3
|
+
} from 'react-native';
|
|
4
|
+
import {
|
|
5
|
+
BoxNative,
|
|
6
|
+
Text,
|
|
7
|
+
TextNative,
|
|
8
|
+
} from '@project-components/Gluestack';
|
|
9
|
+
import {
|
|
10
|
+
UI_MODE_WEB,
|
|
11
|
+
} from '../../Constants/UiModes.js';
|
|
12
|
+
import UiGlobals from '../../UiGlobals.js';
|
|
13
|
+
import withComponent from '../Hoc/withComponent.js';
|
|
14
|
+
import _ from 'lodash';
|
|
15
|
+
|
|
16
|
+
function TextWithLinksElement(props) {
|
|
17
|
+
const {
|
|
18
|
+
value: text,
|
|
19
|
+
} = props,
|
|
20
|
+
styles = UiGlobals.styles,
|
|
21
|
+
openLink = (url) => {
|
|
22
|
+
Linking.openURL(url);
|
|
23
|
+
},
|
|
24
|
+
extractLinks = (text) => {
|
|
25
|
+
|
|
26
|
+
if (_.isNil(text) || _.isEmpty(text)) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const
|
|
30
|
+
regex = /\b(?:https?|ftp):\/\/\S+/g,
|
|
31
|
+
links = text.match(regex) || [];
|
|
32
|
+
|
|
33
|
+
return links.map((link, ix) => ({
|
|
34
|
+
link,
|
|
35
|
+
key: `link_${ix}`,
|
|
36
|
+
}));
|
|
37
|
+
},
|
|
38
|
+
renderTextWithLinks = () => {
|
|
39
|
+
const links = extractLinks(text);
|
|
40
|
+
let modifiedText = text;
|
|
41
|
+
|
|
42
|
+
if (_.isNil(modifiedText) || _.isEmpty(modifiedText)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
links.forEach(({ link, key }) => {
|
|
47
|
+
modifiedText = modifiedText.replace(link, key);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const
|
|
51
|
+
textClassName = `
|
|
52
|
+
TextWithLinks-Text
|
|
53
|
+
text-base
|
|
54
|
+
overflow-hidden
|
|
55
|
+
`,
|
|
56
|
+
textSegments = modifiedText.split(/(link_\d+)/);
|
|
57
|
+
if (textSegments.length === 1) {
|
|
58
|
+
return <Text className={textClassName}>{modifiedText}</Text>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return textSegments.map((segment, ix) => {
|
|
62
|
+
const foundLink = links.find(({ key }) => segment === key);
|
|
63
|
+
let ret = <Text key={ix} className={textClassName}>{segment}</Text>;
|
|
64
|
+
|
|
65
|
+
if (foundLink) {
|
|
66
|
+
ret = <TextNative
|
|
67
|
+
key={foundLink.key}
|
|
68
|
+
className={`
|
|
69
|
+
text-blue-600
|
|
70
|
+
${textClassName}
|
|
71
|
+
`}
|
|
72
|
+
onPress={() => openLink(foundLink.link)}
|
|
73
|
+
>{foundLink.link}</TextNative>;
|
|
74
|
+
}
|
|
75
|
+
return ret;
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const elementProps = {};
|
|
80
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
81
|
+
elementProps.textOverflow = 'ellipsis';
|
|
82
|
+
}
|
|
83
|
+
let className = `
|
|
84
|
+
overflow-auto
|
|
85
|
+
min-h-[40px]
|
|
86
|
+
px-3
|
|
87
|
+
py-2
|
|
88
|
+
`;
|
|
89
|
+
if (props.className) {
|
|
90
|
+
className += ` ${props.className}`;
|
|
91
|
+
}
|
|
92
|
+
return <BoxNative
|
|
93
|
+
className={className}
|
|
94
|
+
{...props}
|
|
95
|
+
>{renderTextWithLinks()}</BoxNative>;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default withComponent(TextWithLinksElement);
|
package/src/Components/index.js
CHANGED
|
@@ -218,6 +218,8 @@ import Input from './Form/Field/Input.js';
|
|
|
218
218
|
import IntervalsCombo from './Form/Field/Combo/IntervalsCombo.js';
|
|
219
219
|
import Json from './Form/Field/Json.js';
|
|
220
220
|
import Label from './Form/Label.js';
|
|
221
|
+
import MeterTypesCombo from './Form/Field/Combo/MeterTypesCombo.js';
|
|
222
|
+
import MeterTypeText from './Viewer/MeterTypeText.js';
|
|
221
223
|
import MonthsCombo from './Form/Field/Combo/MonthsCombo.js';
|
|
222
224
|
import Number from './Form/Field/Number.js';
|
|
223
225
|
import NumberRange from './Filter/NumberRange.js';
|
|
@@ -231,6 +233,7 @@ import TabPanel from './Panel/TabPanel.js';
|
|
|
231
233
|
import Tag from './Form/Field/Tag/Tag.js';
|
|
232
234
|
import TextArea from './Form/Field/TextArea.js';
|
|
233
235
|
import Text from './Form/Field/Text.js';
|
|
236
|
+
import TextWithLinks from './Viewer/TextWithLinks.js';
|
|
234
237
|
import TimezonesCombo from './Form/Field/Combo/TimezonesCombo.js';
|
|
235
238
|
import Toggle from './Form/Field/Toggle.js';
|
|
236
239
|
import Toolbar from './Toolbar/Toolbar.js';
|
|
@@ -458,6 +461,8 @@ const components = {
|
|
|
458
461
|
IntervalsCombo,
|
|
459
462
|
Json,
|
|
460
463
|
Label,
|
|
464
|
+
MeterTypesCombo,
|
|
465
|
+
MeterTypeText,
|
|
461
466
|
MonthsCombo,
|
|
462
467
|
Number,
|
|
463
468
|
NumberRange,
|
|
@@ -471,6 +476,7 @@ const components = {
|
|
|
471
476
|
Tag,
|
|
472
477
|
Text,
|
|
473
478
|
TextArea,
|
|
479
|
+
TextWithLinks,
|
|
474
480
|
TimezonesCombo,
|
|
475
481
|
Toggle,
|
|
476
482
|
Toolbar,
|