@onehat/ui 0.4.82 → 0.4.84
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 +7 -6
- package/src/Components/Container/Container.js +336 -147
- package/src/Components/Form/Field/Combo/Combo.js +84 -15
- package/src/Components/Form/Field/Hidden.js +13 -0
- package/src/Components/Form/Field/Json.js +2 -1
- package/src/Components/Form/Field/Tag/Tag.js +93 -78
- package/src/Components/Form/Field/Tag/ValueBox.js +2 -2
- package/src/Components/Form/Form.js +3 -2
- package/src/Components/Grid/Grid.js +79 -42
- package/src/Components/Grid/GridRow.js +10 -0
- package/src/Components/Hoc/Secondary/withSecondaryEditor.js +137 -43
- package/src/Components/Hoc/Secondary/withSecondarySideEditor.js +6 -4
- package/src/Components/Hoc/withContextMenu.js +13 -4
- package/src/Components/Hoc/withDraggable.js +7 -3
- package/src/Components/Hoc/withSideEditor.js +7 -4
- package/src/Components/Layout/AsyncOperation.js +54 -25
- package/src/Components/Panel/Mask.js +1 -14
- package/src/Components/Screens/Manager.js +4 -5
- package/src/Components/Toolbar/Pagination.js +108 -106
- package/src/Components/Tree/Tree.js +24 -0
- package/src/Components/Tree/TreeNode.js +2 -1
- package/src/Components/Viewer/Viewer.js +2 -5
- package/src/Components/index.js +2 -0
- package/src/Constants/Progress.js +6 -1
- package/src/PlatformImports/Web/Attachments.js +3 -3
|
@@ -45,11 +45,12 @@ export default function withSideEditor(WrappedComponent, isTree = false) {
|
|
|
45
45
|
throw Error('Editor is not defined');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
const containerProps = {};
|
|
48
49
|
if (isResizable) {
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
containerProps.eastIsResizable = true;
|
|
51
|
+
containerProps.eastInitialWidth = 500;
|
|
51
52
|
} else {
|
|
52
|
-
|
|
53
|
+
containerProps.eastInitialFlex = sideFlex;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
if (!_editor.className) {
|
|
@@ -61,10 +62,10 @@ export default function withSideEditor(WrappedComponent, isTree = false) {
|
|
|
61
62
|
parent={self}
|
|
62
63
|
reference="SideEditor"
|
|
63
64
|
center={<WrappedComponent
|
|
65
|
+
{...props}
|
|
64
66
|
ref={ref}
|
|
65
67
|
isTree={isTree}
|
|
66
68
|
isSideEditor={true}
|
|
67
|
-
{...props}
|
|
68
69
|
/>}
|
|
69
70
|
east={props.isEditorShown && <Editor
|
|
70
71
|
{...propsToPass}
|
|
@@ -73,6 +74,8 @@ export default function withSideEditor(WrappedComponent, isTree = false) {
|
|
|
73
74
|
parent={self}
|
|
74
75
|
reference="editor"
|
|
75
76
|
/>}
|
|
77
|
+
{...containerProps}
|
|
78
|
+
isDisabled={props.isDisabled}
|
|
76
79
|
/>;
|
|
77
80
|
});
|
|
78
81
|
return withAdditionalProps(withEditor(SideEditor, isTree));
|
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
import clsx from 'clsx';
|
|
10
10
|
import * as Progress from 'react-native-progress';
|
|
11
11
|
import useForceUpdate from '../../Hooks/useForceUpdate';
|
|
12
|
+
import {
|
|
13
|
+
EDITOR_TYPE__PLAIN,
|
|
14
|
+
} from '../../Constants/Editor.js';
|
|
12
15
|
import {
|
|
13
16
|
PROGRESS__NONE_FOUND,
|
|
14
17
|
PROGRESS__IN_PROCESS,
|
|
@@ -16,10 +19,15 @@ import {
|
|
|
16
19
|
PROGRESS__FAILED,
|
|
17
20
|
PROGRESS__STUCK,
|
|
18
21
|
PROGRESS__UNSTUCK,
|
|
22
|
+
ASYNC_OPERATION_MODES__INIT,
|
|
23
|
+
ASYNC_OPERATION_MODES__START,
|
|
24
|
+
ASYNC_OPERATION_MODES__PROCESSING,
|
|
25
|
+
ASYNC_OPERATION_MODES__RESULTS,
|
|
19
26
|
} from '../../Constants/Progress.js';
|
|
20
27
|
import {
|
|
21
28
|
MOMENT_DATE_FORMAT_2,
|
|
22
29
|
} from '../../Constants/Dates.js';
|
|
30
|
+
import inArray from '../../Functions/inArray.js';
|
|
23
31
|
import isJson from '../../Functions/isJson.js';
|
|
24
32
|
import Form from '../Form/Form.js';
|
|
25
33
|
import Button from '../Buttons/Button.js';
|
|
@@ -38,11 +46,12 @@ import Toolbar from '../Toolbar/Toolbar.js';
|
|
|
38
46
|
import moment from 'moment';
|
|
39
47
|
import _ from 'lodash';
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
// MODES:
|
|
50
|
+
// ASYNC_OPERATION_MODES__INIT - no footer shown; used when component initially loads, to see if operation is already in progress
|
|
51
|
+
// ASYNC_OPERATION_MODES__START - shows the start form
|
|
52
|
+
// ASYNC_OPERATION_MODES__PROCESSING - shows the loading indicator while starting the operation
|
|
53
|
+
// ASYNC_OPERATION_MODES__RESULTS - shows the results of the operation, or any in-progress updates
|
|
54
|
+
|
|
46
55
|
|
|
47
56
|
// If getProgressUpdates is false, the component will show the start form initially.
|
|
48
57
|
// If getProgressUpdates is true, the component will initially query the server to see if
|
|
@@ -63,9 +72,11 @@ function AsyncOperation(props) {
|
|
|
63
72
|
formStartingValues = {},
|
|
64
73
|
_form = {},
|
|
65
74
|
getProgressUpdates = false,
|
|
75
|
+
getInitialProgress = true, // applies only if getProgressUpdates is true
|
|
66
76
|
parseProgress, // optional fn, accepts 'response' as arg and returns an object like this: { status, errors, started, lastUpdated, timeElapsed, count, current, total, percentage }
|
|
67
77
|
updateInterval = 10000, // ms
|
|
68
78
|
progressColor = '#666',
|
|
79
|
+
onChangeMode,
|
|
69
80
|
|
|
70
81
|
// withComponent
|
|
71
82
|
self,
|
|
@@ -81,15 +92,18 @@ function AsyncOperation(props) {
|
|
|
81
92
|
getIsValid = () => {
|
|
82
93
|
return isValid.current;
|
|
83
94
|
},
|
|
84
|
-
|
|
85
|
-
setMode = (
|
|
86
|
-
|
|
95
|
+
modeRef = useRef(ASYNC_OPERATION_MODES__INIT),
|
|
96
|
+
setMode = (mode) => {
|
|
97
|
+
modeRef.current = mode;
|
|
98
|
+
|
|
99
|
+
if (onChangeMode) {
|
|
100
|
+
onChangeMode(mode);
|
|
101
|
+
}
|
|
87
102
|
},
|
|
88
103
|
getMode = () => {
|
|
89
|
-
return
|
|
104
|
+
return modeRef.current;
|
|
90
105
|
},
|
|
91
|
-
isInProcess = getMode() ===
|
|
92
|
-
currentTabIx = (getMode() === PROCESSING ? 1 : (getMode() === RESULTS ? 2 : 0)),
|
|
106
|
+
isInProcess = getMode() === ASYNC_OPERATION_MODES__PROCESSING,
|
|
93
107
|
intervalRef = useRef(null),
|
|
94
108
|
getInterval = () => {
|
|
95
109
|
return intervalRef.current;
|
|
@@ -113,9 +127,9 @@ function AsyncOperation(props) {
|
|
|
113
127
|
},
|
|
114
128
|
getFooter = () => {
|
|
115
129
|
switch(getMode()) {
|
|
116
|
-
case
|
|
130
|
+
case ASYNC_OPERATION_MODES__INIT:
|
|
117
131
|
return null;
|
|
118
|
-
case
|
|
132
|
+
case ASYNC_OPERATION_MODES__START:
|
|
119
133
|
return <Toolbar>
|
|
120
134
|
<Button
|
|
121
135
|
text="Start"
|
|
@@ -124,7 +138,7 @@ function AsyncOperation(props) {
|
|
|
124
138
|
isDisabled={!getIsValid()}
|
|
125
139
|
/>
|
|
126
140
|
</Toolbar>;
|
|
127
|
-
case
|
|
141
|
+
case ASYNC_OPERATION_MODES__PROCESSING:
|
|
128
142
|
// TODO: Add a cancellation option to the command.
|
|
129
143
|
// would require a backend controller action to support it
|
|
130
144
|
return null;
|
|
@@ -135,7 +149,7 @@ function AsyncOperation(props) {
|
|
|
135
149
|
// variant="link"
|
|
136
150
|
// />
|
|
137
151
|
// </Toolbar>;
|
|
138
|
-
case
|
|
152
|
+
case ASYNC_OPERATION_MODES__RESULTS:
|
|
139
153
|
let button;
|
|
140
154
|
if (getIsStuck()) {
|
|
141
155
|
button = <Button
|
|
@@ -160,13 +174,13 @@ function AsyncOperation(props) {
|
|
|
160
174
|
[progress, setProgress] = useState(null),
|
|
161
175
|
[isReady, setIsReady] = useState(false),
|
|
162
176
|
showResults = (results) => {
|
|
163
|
-
setMode(
|
|
177
|
+
setMode(ASYNC_OPERATION_MODES__RESULTS);
|
|
164
178
|
setFooter(getFooter());
|
|
165
179
|
setResults(results);
|
|
166
180
|
},
|
|
167
181
|
startProcess = async () => {
|
|
168
182
|
stopGettingProgress();
|
|
169
|
-
setMode(
|
|
183
|
+
setMode(ASYNC_OPERATION_MODES__PROCESSING);
|
|
170
184
|
setFooter(getFooter());
|
|
171
185
|
|
|
172
186
|
const
|
|
@@ -264,11 +278,11 @@ function AsyncOperation(props) {
|
|
|
264
278
|
statusMessage = '',
|
|
265
279
|
errorMessage = null;
|
|
266
280
|
if (status === PROGRESS__IN_PROCESS) {
|
|
267
|
-
setMode(
|
|
281
|
+
setMode(ASYNC_OPERATION_MODES__PROCESSING);
|
|
268
282
|
color = 'text-green-600';
|
|
269
283
|
statusMessage = 'In process...';
|
|
270
284
|
} else {
|
|
271
|
-
setMode(
|
|
285
|
+
setMode(ASYNC_OPERATION_MODES__RESULTS);
|
|
272
286
|
stopGettingProgress();
|
|
273
287
|
if (status === PROGRESS__COMPLETED) {
|
|
274
288
|
statusMessage = 'Completed';
|
|
@@ -328,7 +342,7 @@ function AsyncOperation(props) {
|
|
|
328
342
|
})}
|
|
329
343
|
</VStack>);
|
|
330
344
|
}
|
|
331
|
-
if (getMode() ===
|
|
345
|
+
if (getMode() === ASYNC_OPERATION_MODES__PROCESSING) {
|
|
332
346
|
setProgress(renderItems);
|
|
333
347
|
} else {
|
|
334
348
|
setResults(renderItems);
|
|
@@ -351,7 +365,7 @@ function AsyncOperation(props) {
|
|
|
351
365
|
},
|
|
352
366
|
unstick = async () => {
|
|
353
367
|
stopGettingProgress();
|
|
354
|
-
setMode(
|
|
368
|
+
setMode(ASYNC_OPERATION_MODES__PROCESSING);
|
|
355
369
|
setFooter(getFooter());
|
|
356
370
|
|
|
357
371
|
const
|
|
@@ -379,7 +393,7 @@ function AsyncOperation(props) {
|
|
|
379
393
|
resetToInitialState();
|
|
380
394
|
},
|
|
381
395
|
resetToInitialState = () => {
|
|
382
|
-
setMode(
|
|
396
|
+
setMode(ASYNC_OPERATION_MODES__START);
|
|
383
397
|
setFooter(getFooter());
|
|
384
398
|
setIsStuck(false);
|
|
385
399
|
stopGettingProgress();
|
|
@@ -394,10 +408,10 @@ function AsyncOperation(props) {
|
|
|
394
408
|
};
|
|
395
409
|
|
|
396
410
|
useEffect(() => {
|
|
397
|
-
if (getProgressUpdates) {
|
|
411
|
+
if (getProgressUpdates && getInitialProgress) {
|
|
398
412
|
getProgress(true);
|
|
399
413
|
} else {
|
|
400
|
-
setMode(
|
|
414
|
+
setMode(ASYNC_OPERATION_MODES__START);
|
|
401
415
|
setIsReady(true);
|
|
402
416
|
}
|
|
403
417
|
return () => {
|
|
@@ -409,6 +423,20 @@ function AsyncOperation(props) {
|
|
|
409
423
|
};
|
|
410
424
|
}, []);
|
|
411
425
|
|
|
426
|
+
let currentTabIx = 0;
|
|
427
|
+
switch(getMode()) {
|
|
428
|
+
case ASYNC_OPERATION_MODES__INIT:
|
|
429
|
+
case ASYNC_OPERATION_MODES__START:
|
|
430
|
+
currentTabIx = 0;
|
|
431
|
+
break;
|
|
432
|
+
case ASYNC_OPERATION_MODES__PROCESSING:
|
|
433
|
+
currentTabIx = 1;
|
|
434
|
+
break;
|
|
435
|
+
case ASYNC_OPERATION_MODES__RESULTS:
|
|
436
|
+
currentTabIx = 2;
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
|
|
412
440
|
return <Panel
|
|
413
441
|
{...props}
|
|
414
442
|
footer={footer}
|
|
@@ -421,10 +449,11 @@ function AsyncOperation(props) {
|
|
|
421
449
|
title: 'Start',
|
|
422
450
|
icon: Play,
|
|
423
451
|
isDisabled: currentTabIx !== 0,
|
|
424
|
-
content: getMode()
|
|
452
|
+
content: inArray(getMode(), [ASYNC_OPERATION_MODES__INIT, ASYNC_OPERATION_MODES__PROCESSING, ASYNC_OPERATION_MODES__RESULTS]) ?
|
|
425
453
|
<Loading /> :
|
|
426
454
|
<ScrollView className="ScrollView h-full w-full">
|
|
427
455
|
<Form
|
|
456
|
+
editorType={EDITOR_TYPE__PLAIN}
|
|
428
457
|
reference="form"
|
|
429
458
|
parent={self}
|
|
430
459
|
className="w-full h-full flex-1"
|
|
@@ -2,20 +2,7 @@ import {
|
|
|
2
2
|
Box,
|
|
3
3
|
} from '@project-components/Gluestack';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
-
import {
|
|
6
|
-
CURRENT_MODE,
|
|
7
|
-
UI_MODE_WEB,
|
|
8
|
-
UI_MODE_NATIVE,
|
|
9
|
-
} from '../../Constants/UiModes.js';
|
|
10
5
|
|
|
11
6
|
export default function Mask(props) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return <div className="mask"></div>;
|
|
15
|
-
|
|
16
|
-
} else if (CURRENT_MODE === UI_MODE_NATIVE) {
|
|
17
|
-
|
|
18
|
-
return <Box className="absolute h-full w-full bg-grey-400:alpha.20 z-100000"></Box>;
|
|
19
|
-
|
|
20
|
-
}
|
|
7
|
+
return <Box className="mask flex-none absolute h-full w-full bg-grey-400/20 z-[100000]"></Box>;
|
|
21
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { cloneElement, useState, useEffect, } from 'react';
|
|
1
2
|
import {
|
|
2
3
|
VStackNative,
|
|
3
4
|
} from '@project-components/Gluestack';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
|
-
import React, { useState, useEffect, } from 'react';
|
|
6
6
|
import {
|
|
7
7
|
SCREEN_MODES__FULL,
|
|
8
8
|
SCREEN_MODES__SIDE,
|
|
@@ -21,10 +21,9 @@ function ManagerScreen(props) {
|
|
|
21
21
|
sideModeComponent,
|
|
22
22
|
fullModeComponent,
|
|
23
23
|
onChangeMode,
|
|
24
|
-
|
|
25
|
-
// withComponent
|
|
26
|
-
self,
|
|
24
|
+
...propsToPass
|
|
27
25
|
} = props,
|
|
26
|
+
self = props.self,
|
|
28
27
|
id = props.id || props.self?.path,
|
|
29
28
|
[isRendered, setIsRendered] = useState(false),
|
|
30
29
|
[isModeSet, setIsModeSet] = useState(false),
|
|
@@ -79,7 +78,7 @@ function ManagerScreen(props) {
|
|
|
79
78
|
self.mode = actualMode;
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
const whichComponent = actualMode === SCREEN_MODES__FULL ? fullModeComponent : sideModeComponent;
|
|
81
|
+
const whichComponent = cloneElement((actualMode === SCREEN_MODES__FULL ? fullModeComponent : sideModeComponent), propsToPass);
|
|
83
82
|
|
|
84
83
|
return <VStackNative
|
|
85
84
|
{...testProps(self)}
|
|
@@ -56,8 +56,8 @@ export default function Pagination(props) {
|
|
|
56
56
|
let items = [],
|
|
57
57
|
isDisabled = false;
|
|
58
58
|
if (showMoreOnly) {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if (totalPages > 1 && showPagination) {
|
|
60
|
+
isDisabled = (pageEnd === total);
|
|
61
61
|
items.push(<Button
|
|
62
62
|
{...testProps('showMoreBtn')}
|
|
63
63
|
key="showMoreBtn"
|
|
@@ -88,120 +88,122 @@ export default function Pagination(props) {
|
|
|
88
88
|
self={self}
|
|
89
89
|
/>);
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
91
|
+
if (totalPages > 1) {
|
|
92
|
+
isDisabled = page === 1;
|
|
93
|
+
if (showPagination) {
|
|
94
|
+
items.push(<IconButton
|
|
95
|
+
{...testProps('firstPageBtn')}
|
|
96
|
+
key="firstPageBtn"
|
|
97
|
+
reference="firstPageBtn"
|
|
98
|
+
className="Pagination-firstPageBtn"
|
|
99
|
+
parent={self}
|
|
100
|
+
isDisabled={isDisabled}
|
|
101
|
+
icon={AnglesLeft}
|
|
102
|
+
_icon={iconProps}
|
|
103
|
+
onPress={() => Repository.setPage(1)}
|
|
104
|
+
tooltip="First Page"
|
|
105
|
+
/>);
|
|
106
|
+
items.push(<IconButton
|
|
107
|
+
{...testProps('prevPageBtn')}
|
|
108
|
+
key="prevPageBtn"
|
|
109
|
+
reference="prevPageBtn"
|
|
110
|
+
className="Pagination-prevPageBtn"
|
|
111
|
+
parent={self}
|
|
112
|
+
isDisabled={isDisabled}
|
|
113
|
+
icon={AngleLeft}
|
|
114
|
+
_icon={iconProps}
|
|
115
|
+
onPress={() => Repository.prevPage()}
|
|
116
|
+
tooltip="Previous Page"
|
|
117
|
+
/>);
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
parent={self}
|
|
125
|
-
isDisabled={isDisabled}
|
|
126
|
-
icon={AngleRight}
|
|
127
|
-
_icon={iconProps}
|
|
128
|
-
onPress={() => Repository.nextPage()}
|
|
129
|
-
tooltip="Next Page"
|
|
130
|
-
/>);
|
|
131
|
-
items.push(<IconButton
|
|
132
|
-
{...testProps('lastPageBtn')}
|
|
133
|
-
key="lastPageBtn"
|
|
134
|
-
reference="lastPageBtn"
|
|
135
|
-
className="Pagination-lastPageBtn"
|
|
136
|
-
parent={self}
|
|
137
|
-
isDisabled={isDisabled}
|
|
138
|
-
icon={AnglesRight}
|
|
139
|
-
_icon={iconProps}
|
|
140
|
-
onPress={() => Repository.setPage(totalPages)}
|
|
141
|
-
tooltip="Last Page"
|
|
142
|
-
/>);
|
|
143
|
-
if (!minimize) {
|
|
144
|
-
items.push(<Text
|
|
145
|
-
key="page"
|
|
146
|
-
className="Pagination-page mx-1"
|
|
147
|
-
>Page</Text>);
|
|
148
|
-
items.push(<Input
|
|
149
|
-
{...testProps('pageInput')}
|
|
150
|
-
key="pageInput"
|
|
151
|
-
reference="pageInput"
|
|
119
|
+
isDisabled = page === totalPages || totalPages <= 1;
|
|
120
|
+
items.push(<IconButton
|
|
121
|
+
{...testProps('nextPageBtn')}
|
|
122
|
+
key="nextPageBtn"
|
|
123
|
+
reference="nextPageBtn"
|
|
124
|
+
className="Pagination-nextPageBtn"
|
|
152
125
|
parent={self}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
126
|
+
isDisabled={isDisabled}
|
|
127
|
+
icon={AngleRight}
|
|
128
|
+
_icon={iconProps}
|
|
129
|
+
onPress={() => Repository.nextPage()}
|
|
130
|
+
tooltip="Next Page"
|
|
131
|
+
/>);
|
|
132
|
+
items.push(<IconButton
|
|
133
|
+
{...testProps('lastPageBtn')}
|
|
134
|
+
key="lastPageBtn"
|
|
135
|
+
reference="lastPageBtn"
|
|
136
|
+
className="Pagination-lastPageBtn"
|
|
137
|
+
parent={self}
|
|
138
|
+
isDisabled={isDisabled}
|
|
139
|
+
icon={AnglesRight}
|
|
140
|
+
_icon={iconProps}
|
|
141
|
+
onPress={() => Repository.setPage(totalPages)}
|
|
142
|
+
tooltip="Last Page"
|
|
143
|
+
/>);
|
|
144
|
+
if (!minimize) {
|
|
145
|
+
items.push(<Text
|
|
146
|
+
key="page"
|
|
147
|
+
className="Pagination-page mx-1"
|
|
148
|
+
>Page</Text>);
|
|
149
|
+
items.push(<Input
|
|
150
|
+
{...testProps('pageInput')}
|
|
151
|
+
key="pageInput"
|
|
152
|
+
reference="pageInput"
|
|
153
|
+
parent={self}
|
|
154
|
+
keyboardType="numeric"
|
|
155
|
+
value={page?.toString()}
|
|
156
|
+
onChangeValue={(value) => Repository.setPage(value)}
|
|
157
|
+
maxValue={totalPages}
|
|
158
|
+
isDisabled={totalPages === 1}
|
|
159
|
+
className={clsx(
|
|
160
|
+
'Pagination-pageInput',
|
|
161
|
+
'min-w-[40px]',
|
|
162
|
+
'w-[40px]',
|
|
163
|
+
'text-center',
|
|
164
|
+
'bg-grey-100',
|
|
165
|
+
)}
|
|
166
|
+
textAlignIsCenter={true}
|
|
167
|
+
tooltip="Set Page"
|
|
168
|
+
tooltipClassName="w-[40px]"
|
|
169
|
+
/>);
|
|
170
|
+
items.push(<Text
|
|
171
|
+
key="totalPages"
|
|
172
|
+
className={clsx(
|
|
173
|
+
'Pagination-totalPages',
|
|
174
|
+
'whitespace-nowrap',
|
|
175
|
+
'inline-flex',
|
|
176
|
+
'mx-1',
|
|
177
|
+
)}
|
|
178
|
+
>{`of ${totalPages}`}</Text>);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (showPagination && !minimize && !disablePageSize) {
|
|
183
|
+
items.push(<PageSizeSelect
|
|
184
|
+
{...testProps('pageSize')}
|
|
185
|
+
key="pageSize"
|
|
186
|
+
reference="pageSize"
|
|
187
|
+
parent={self}
|
|
188
|
+
pageSize={pageSize}
|
|
189
|
+
Repository={Repository}
|
|
168
190
|
/>);
|
|
191
|
+
}
|
|
192
|
+
if (showPagination && !minimize) {
|
|
193
|
+
let pageSpan = `${pageStart} – ${pageEnd}`;
|
|
194
|
+
if (pageStart === pageEnd) {
|
|
195
|
+
pageSpan = pageStart;
|
|
196
|
+
}
|
|
169
197
|
items.push(<Text
|
|
170
|
-
key="
|
|
198
|
+
key="pageDisplay"
|
|
171
199
|
className={clsx(
|
|
172
|
-
'Pagination-
|
|
200
|
+
'Pagination-pageDisplay',
|
|
173
201
|
'whitespace-nowrap',
|
|
174
202
|
'inline-flex',
|
|
175
203
|
'mx-1',
|
|
176
204
|
)}
|
|
177
|
-
>{`of ${
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (showPagination && !minimize && !disablePageSize) {
|
|
182
|
-
items.push(<PageSizeSelect
|
|
183
|
-
{...testProps('pageSize')}
|
|
184
|
-
key="pageSize"
|
|
185
|
-
reference="pageSize"
|
|
186
|
-
parent={self}
|
|
187
|
-
pageSize={pageSize}
|
|
188
|
-
Repository={Repository}
|
|
189
|
-
/>);
|
|
190
|
-
}
|
|
191
|
-
if (showPagination && !minimize) {
|
|
192
|
-
let pageSpan = `${pageStart} – ${pageEnd}`;
|
|
193
|
-
if (pageStart === pageEnd) {
|
|
194
|
-
pageSpan = pageStart;
|
|
205
|
+
>{`Displaying ${pageSpan} of ${total}`}</Text>);
|
|
195
206
|
}
|
|
196
|
-
items.push(<Text
|
|
197
|
-
key="pageDisplay"
|
|
198
|
-
className={clsx(
|
|
199
|
-
'Pagination-pageDisplay',
|
|
200
|
-
'whitespace-nowrap',
|
|
201
|
-
'inline-flex',
|
|
202
|
-
'mx-1',
|
|
203
|
-
)}
|
|
204
|
-
>{`Displaying ${pageSpan} of ${total}`}</Text>);
|
|
205
207
|
}
|
|
206
208
|
}
|
|
207
209
|
return <HStack
|
|
@@ -1106,6 +1106,30 @@ function TreeComponent(props) {
|
|
|
1106
1106
|
onContextMenu(item, e, selection);
|
|
1107
1107
|
}
|
|
1108
1108
|
}}
|
|
1109
|
+
onContextMenu={(e) => {
|
|
1110
|
+
// web only; happens before onLongPress triggers
|
|
1111
|
+
// different behavior here than onLongPress:
|
|
1112
|
+
// if user clicks on a phantom record, or if onContextMenu is not set, pass to the browser's context menu
|
|
1113
|
+
if (selection && selection[0] && selection[0].isRemotePhantom) {
|
|
1114
|
+
return; // block context menu or changing selection when a remote phantom is already selected
|
|
1115
|
+
}
|
|
1116
|
+
if (onContextMenu) {
|
|
1117
|
+
e.preventDefault();
|
|
1118
|
+
e.stopPropagation(); // disallow browser's default behavior for context menu
|
|
1119
|
+
|
|
1120
|
+
// if the right-clicked item is not in the current selection,
|
|
1121
|
+
// set the selection only to this one item.
|
|
1122
|
+
let newSelection = selection;
|
|
1123
|
+
if (!isInSelection(item)) {
|
|
1124
|
+
newSelection = [item];
|
|
1125
|
+
setSelection(newSelection);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
if (onContextMenu) {
|
|
1129
|
+
onContextMenu(item, e, newSelection);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}}
|
|
1109
1133
|
className={clsx(
|
|
1110
1134
|
'Pressable',
|
|
1111
1135
|
'Node',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo, useEffect, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
|
+
BoxNative,
|
|
4
5
|
HStackNative,
|
|
5
6
|
Icon,
|
|
6
7
|
Spinner,
|
|
@@ -185,7 +186,7 @@ export default function TreeNode(props) {
|
|
|
185
186
|
styles.TREE_NODE_EXPAND_BTN_CLASSNAME,
|
|
186
187
|
)}
|
|
187
188
|
/> :
|
|
188
|
-
<
|
|
189
|
+
<BoxNative
|
|
189
190
|
{...testProps('spacer')}
|
|
190
191
|
className={clsx(
|
|
191
192
|
'TreeNode-spacer',
|
|
@@ -161,11 +161,8 @@ function Viewer(props) {
|
|
|
161
161
|
viewerTypeProps.isViewOnly = true;
|
|
162
162
|
viewerTypeProps.SourceRepository = Repository;
|
|
163
163
|
}
|
|
164
|
-
if (type?.match(/(GridEditor)$/)) {
|
|
165
|
-
viewerTypeProps.
|
|
166
|
-
viewerTypeProps.disableEdit = true;
|
|
167
|
-
viewerTypeProps.disableDelete = true;
|
|
168
|
-
viewerTypeProps.disableDuplicate = true;
|
|
164
|
+
if (type?.match(/(Grid|GridEditor)$/)) {
|
|
165
|
+
viewerTypeProps.canEditorViewOnly = true;
|
|
169
166
|
}
|
|
170
167
|
const Element = getComponentFromType(type);
|
|
171
168
|
|
package/src/Components/index.js
CHANGED
|
@@ -264,6 +264,7 @@ import FiltersForm from './Form/FiltersForm.js';
|
|
|
264
264
|
import Form from './Form/Form.js';
|
|
265
265
|
import Grid from './Grid/Grid.js';
|
|
266
266
|
import GridPanel from './Panel/GridPanel.js';
|
|
267
|
+
import Hidden from './Form/Field/Hidden.js';
|
|
267
268
|
import IconButton from './Buttons/IconButton.js';
|
|
268
269
|
import Input from './Form/Field/Input.js';
|
|
269
270
|
import IntervalsCombo from './Form/Field/Combo/IntervalsCombo.js';
|
|
@@ -558,6 +559,7 @@ const components = {
|
|
|
558
559
|
Form,
|
|
559
560
|
Grid,
|
|
560
561
|
GridPanel,
|
|
562
|
+
Hidden,
|
|
561
563
|
IconButton,
|
|
562
564
|
Input,
|
|
563
565
|
IntervalsCombo,
|
|
@@ -3,4 +3,9 @@ export const PROGRESS__IN_PROCESS = 'IN_PROCESS';
|
|
|
3
3
|
export const PROGRESS__COMPLETED = 'COMPLETED';
|
|
4
4
|
export const PROGRESS__FAILED = 'FAILED';
|
|
5
5
|
export const PROGRESS__STUCK = 'STUCK';
|
|
6
|
-
export const PROGRESS__UNSTUCK = 'UNSTUCK';
|
|
6
|
+
export const PROGRESS__UNSTUCK = 'UNSTUCK';
|
|
7
|
+
|
|
8
|
+
export const ASYNC_OPERATION_MODES__INIT = 'INIT';
|
|
9
|
+
export const ASYNC_OPERATION_MODES__START = 'START';
|
|
10
|
+
export const ASYNC_OPERATION_MODES__PROCESSING = 'PROCESSING';
|
|
11
|
+
export const ASYNC_OPERATION_MODES__RESULTS = 'RESULTS';
|
|
@@ -474,9 +474,9 @@ function AttachmentsElement(props) {
|
|
|
474
474
|
},
|
|
475
475
|
isPdf = currentFile.attachments__mimetype === 'application/pdf';
|
|
476
476
|
|
|
477
|
-
let url = currentFile.attachments__uri;
|
|
477
|
+
let url = encodeURI(currentFile.attachments__uri);
|
|
478
478
|
try {
|
|
479
|
-
const response = await fetch(
|
|
479
|
+
const response = await fetch(url, {
|
|
480
480
|
headers: Attachments.headers // Use your repository's headers
|
|
481
481
|
});
|
|
482
482
|
|
|
@@ -1019,7 +1019,7 @@ function AttachmentsElement(props) {
|
|
|
1019
1019
|
},
|
|
1020
1020
|
{
|
|
1021
1021
|
"id": "attachments__size_formatted",
|
|
1022
|
-
"header": "Size
|
|
1022
|
+
"header": "Size",
|
|
1023
1023
|
"fieldName": "attachments__size_formatted",
|
|
1024
1024
|
"isSortable": false,
|
|
1025
1025
|
"isEditable": false,
|