@onehat/ui 0.2.81 → 0.2.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 +5 -3
- package/src/Components/Editor/Editor.js +6 -2
- package/src/Components/Editor/Viewer.js +4 -3
- package/src/Components/Form/Form.js +2 -2
- package/src/Components/Grid/Grid.js +2 -0
- package/src/Components/Hoc/withEditor.js +12 -0
- package/src/Components/Hoc/withSideEditor.js +4 -7
- package/src/Components/Panel/GridPanel.js +5 -1
- package/src/Components/Screens/Manager.js +4 -2
- package/src/Constants/Styles.js +2 -0
- package/src/Hooks/useRedux.js +40 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onehat/ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.84",
|
|
4
4
|
"description": "Base UI for OneHat apps",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,12 +25,14 @@
|
|
|
25
25
|
},
|
|
26
26
|
"license": "UNLICENSED",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onehat/data": "^1.18.
|
|
29
|
-
"@hookform/resolvers": "^3.
|
|
28
|
+
"@onehat/data": "^1.18.12",
|
|
29
|
+
"@hookform/resolvers": "^3.3.1",
|
|
30
30
|
"@k-renwick/colour-mixer": "^1.2.1",
|
|
31
|
+
"@reduxjs/toolkit": "^1.9.5",
|
|
31
32
|
"js-cookie": "^3.0.5",
|
|
32
33
|
"native-base": "^3.4.28",
|
|
33
34
|
"react-hook-form": "^7.45.0",
|
|
35
|
+
"react-redux": "^8.1.2",
|
|
34
36
|
"yup": "^1.2.0"
|
|
35
37
|
},
|
|
36
38
|
"peerDependencies": {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box,
|
|
3
|
+
} from 'native-base';
|
|
1
4
|
import {
|
|
2
5
|
EDITOR_MODE__VIEW,
|
|
3
6
|
} from '../../Constants/Editor.js';
|
|
@@ -25,10 +28,11 @@ export default function Editor(props) {
|
|
|
25
28
|
} = props;
|
|
26
29
|
|
|
27
30
|
if (_.isEmpty(selection)) {
|
|
28
|
-
return null;
|
|
31
|
+
return null; // hide the editor when no selection
|
|
32
|
+
return <Box {...props} bg="#ddd" />;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
if (Repository
|
|
35
|
+
if (Repository?.isRemotePhantomMode && selection.length === 1 && editorMode === EDITOR_MODE__VIEW) {
|
|
32
36
|
return <Viewer
|
|
33
37
|
{...props}
|
|
34
38
|
record={selection[0]}
|
|
@@ -31,6 +31,7 @@ export default function Viewer(props) {
|
|
|
31
31
|
onDelete,
|
|
32
32
|
} = props,
|
|
33
33
|
styles = UiGlobals.styles,
|
|
34
|
+
flex = props.flex || 1,
|
|
34
35
|
buildAncillary = () => {
|
|
35
36
|
let components = [];
|
|
36
37
|
if (ancillaryItems.length) {
|
|
@@ -55,14 +56,14 @@ export default function Viewer(props) {
|
|
|
55
56
|
fontWeight="bold"
|
|
56
57
|
>{title}</Text>;
|
|
57
58
|
}
|
|
58
|
-
return <Column key={'ancillary-' + ix}
|
|
59
|
+
return <Column key={'ancillary-' + ix} my={5}>{title}{element}</Column>;
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
return components;
|
|
62
63
|
};
|
|
63
64
|
|
|
64
|
-
return <Column flex={
|
|
65
|
-
<ScrollView
|
|
65
|
+
return <Column flex={flex} {...props}>
|
|
66
|
+
<ScrollView width="100%" _web={{ height: 1 }}>
|
|
66
67
|
<Column m={2}>
|
|
67
68
|
{onEditMode && <Row mb={4} justifyContent="flex-end">
|
|
68
69
|
<Button
|
|
@@ -427,7 +427,7 @@ function Form(props) {
|
|
|
427
427
|
fontWeight="bold"
|
|
428
428
|
>{title}</Text>;
|
|
429
429
|
}
|
|
430
|
-
return <Column key={'ancillary-' + ix}
|
|
430
|
+
return <Column key={'ancillary-' + ix} mx={2} my={5}>{title}{element}</Column>;
|
|
431
431
|
});
|
|
432
432
|
}
|
|
433
433
|
return components;
|
|
@@ -499,7 +499,7 @@ function Form(props) {
|
|
|
499
499
|
// for all other editor types
|
|
500
500
|
formComponents = buildFromItems();
|
|
501
501
|
const formAncillaryComponents = buildAncillary();
|
|
502
|
-
editor = <ScrollView
|
|
502
|
+
editor = <ScrollView _web={{ height: 1 }} width="100%" pb={1}>
|
|
503
503
|
<Row>{formComponents}</Row>
|
|
504
504
|
<Column pt={4}>{formAncillaryComponents}</Column>
|
|
505
505
|
</ScrollView>;
|
|
@@ -52,6 +52,17 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
52
52
|
[isEditorShown, setIsEditorShown] = useState(false),
|
|
53
53
|
[isEditorViewOnly, setIsEditorViewOnly] = useState(false),
|
|
54
54
|
[lastSelection, setLastSelection] = useState(),
|
|
55
|
+
setSelectionDecorated = (newSelection) => {
|
|
56
|
+
function doIt() {
|
|
57
|
+
setSelection(newSelection);
|
|
58
|
+
}
|
|
59
|
+
const formState = editorStateRef.current;
|
|
60
|
+
if (!_.isEmpty(formState?.dirtyFields) && newSelection !== selection && editorMode === EDITOR_MODE__EDIT) {
|
|
61
|
+
confirm('This record has unsaved changes. Are you sure you want to cancel editing? Changes will be lost.', doIt);
|
|
62
|
+
} else {
|
|
63
|
+
doIt();
|
|
64
|
+
}
|
|
65
|
+
},
|
|
55
66
|
getListeners = () => {
|
|
56
67
|
return listeners.current;
|
|
57
68
|
},
|
|
@@ -342,6 +353,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
342
353
|
disableDelete={disableDelete}
|
|
343
354
|
disableDuplicate={disableDuplicate}
|
|
344
355
|
disableView ={disableView}
|
|
356
|
+
setSelection={setSelectionDecorated}
|
|
345
357
|
/>;
|
|
346
358
|
};
|
|
347
359
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useState, } from 'react';
|
|
2
1
|
import {
|
|
3
2
|
EDITOR_TYPE__SIDE,
|
|
4
3
|
} from '../../Constants/Editor.js';
|
|
@@ -13,9 +12,7 @@ export default function withSideEditor(WrappedComponent, isTree = false) {
|
|
|
13
12
|
Editor,
|
|
14
13
|
editorProps = {},
|
|
15
14
|
sideFlex = 100,
|
|
16
|
-
} = props
|
|
17
|
-
[selection, setSelection] = useState(null);
|
|
18
|
-
|
|
15
|
+
} = props;
|
|
19
16
|
|
|
20
17
|
if (!Editor) {
|
|
21
18
|
throw Error('Editor is not defined');
|
|
@@ -25,13 +22,13 @@ export default function withSideEditor(WrappedComponent, isTree = false) {
|
|
|
25
22
|
center={<WrappedComponent
|
|
26
23
|
isTree={isTree}
|
|
27
24
|
{...props}
|
|
28
|
-
onSelectionChange={setSelection}
|
|
29
25
|
/>}
|
|
30
26
|
east={<Editor
|
|
27
|
+
{...props}
|
|
31
28
|
editorType={EDITOR_TYPE__SIDE}
|
|
32
29
|
flex={sideFlex}
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
borderLeftWidth={1}
|
|
31
|
+
borderLeftColor="#ccc"
|
|
35
32
|
{...editorProps}
|
|
36
33
|
/>}
|
|
37
34
|
/>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect,
|
|
1
|
+
import React, { useState, useEffect, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Column,
|
|
4
4
|
Row,
|
|
@@ -20,8 +20,8 @@ export default function ManagerScreen(props) {
|
|
|
20
20
|
title,
|
|
21
21
|
sideModeComponent,
|
|
22
22
|
fullModeComponent,
|
|
23
|
+
id,
|
|
23
24
|
} = props,
|
|
24
|
-
id = useId(),
|
|
25
25
|
[isReady, setIsReady] = useState(false),
|
|
26
26
|
[mode, setModeRaw] = useState(MODE_FULL),
|
|
27
27
|
setMode = (newMode) => {
|
|
@@ -64,6 +64,8 @@ export default function ManagerScreen(props) {
|
|
|
64
64
|
<Row
|
|
65
65
|
h="80px"
|
|
66
66
|
py={2}
|
|
67
|
+
borderBottomWidth={2}
|
|
68
|
+
borderBottomColor="#ccc"
|
|
67
69
|
>
|
|
68
70
|
<Text p={4} fontSize="26" fontWeight={700}>{title}</Text>
|
|
69
71
|
<IconButton
|
package/src/Constants/Styles.js
CHANGED
|
@@ -63,6 +63,8 @@ const defaults = {
|
|
|
63
63
|
GRID_ROW_HOVER_BG: 'hover',
|
|
64
64
|
GRID_ROW_SELECTED_BG: 'selected',
|
|
65
65
|
GRID_ROW_SELECTED_HOVER_BG: 'selectedHover',
|
|
66
|
+
GRID_BORDER_WIDTH: 1,
|
|
67
|
+
GRID_BORDER_COLOR: 'trueGray.300',
|
|
66
68
|
ICON_BUTTON_BG: 'trueGray.200:alpha.0',
|
|
67
69
|
ICON_BUTTON_BG_DISABLED: 'trueGray.200',
|
|
68
70
|
ICON_BUTTON_BG_HOVER: '#000:alpha.20',
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useSelector, useDispatch } from 'react-redux'
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// Usage example:
|
|
6
|
+
// const [
|
|
7
|
+
// {
|
|
8
|
+
// user,
|
|
9
|
+
// isLoading,
|
|
10
|
+
// },
|
|
11
|
+
// dispatch
|
|
12
|
+
// ] = useRedux([
|
|
13
|
+
// 'user',
|
|
14
|
+
// 'isLoading',
|
|
15
|
+
// ]);
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export default function useRedux(properties) {
|
|
19
|
+
let values = {};
|
|
20
|
+
_.forEach(properties, (property) => {
|
|
21
|
+
values[property] = useSelector((state) => getPropertyFromState(property, state));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return [
|
|
25
|
+
values,
|
|
26
|
+
useDispatch(),
|
|
27
|
+
];
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function getPropertyFromState(property, state) {
|
|
31
|
+
let found;
|
|
32
|
+
const reducers = _.keys(state);
|
|
33
|
+
_.each(reducers, (reducer) => {
|
|
34
|
+
if (state[reducer].hasOwnProperty(property)) {
|
|
35
|
+
found = state[reducer][property];
|
|
36
|
+
return false; // break
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return found;
|
|
40
|
+
}
|