@gpa-gemstone/common-pages 0.0.14
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/README.md +14 -0
- package/lib/Note.d.ts +17 -0
- package/lib/Note.js +179 -0
- package/lib/Setting.d.ts +8 -0
- package/lib/Setting.js +125 -0
- package/lib/SliceInterfaces.d.ts +76 -0
- package/lib/SliceInterfaces.js +2 -0
- package/lib/ValueList/ByValueList.d.ts +10 -0
- package/lib/ValueList/ByValueList.js +115 -0
- package/lib/ValueList/Group.d.ts +11 -0
- package/lib/ValueList/Group.js +71 -0
- package/lib/ValueList/GroupForm.d.ts +9 -0
- package/lib/ValueList/GroupForm.js +51 -0
- package/lib/ValueList/GroupInfo.d.ts +8 -0
- package/lib/ValueList/GroupInfo.js +69 -0
- package/lib/ValueList/GroupItem.d.ts +9 -0
- package/lib/ValueList/GroupItem.js +116 -0
- package/lib/ValueList/ItemForm.d.ts +9 -0
- package/lib/ValueList/ItemForm.js +59 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +37 -0
- package/lib/user/AdditionalField.d.ts +26 -0
- package/lib/user/AdditionalField.js +260 -0
- package/lib/user/ByUser.d.ts +12 -0
- package/lib/user/ByUser.js +148 -0
- package/lib/user/User.d.ts +14 -0
- package/lib/user/User.js +71 -0
- package/lib/user/UserForm.d.ts +12 -0
- package/lib/user/UserForm.js +141 -0
- package/lib/user/UserInfo.d.ts +7 -0
- package/lib/user/UserInfo.js +97 -0
- package/lib/user/UserPermissions.d.ts +8 -0
- package/lib/user/UserPermissions.js +83 -0
- package/package.json +66 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { SystemCenter } from '@gpa-gemstone/application-typings';
|
3
|
+
import { IAdditionalFieldSlice, IGenericSlice } from '../SliceInterfaces';
|
4
|
+
interface IField {
|
5
|
+
FieldName: string;
|
6
|
+
Type: string;
|
7
|
+
}
|
8
|
+
interface IValue {
|
9
|
+
Value: string | number;
|
10
|
+
ID: number;
|
11
|
+
}
|
12
|
+
interface IProps<Field extends IField, Value extends IValue> {
|
13
|
+
Id: string | number;
|
14
|
+
AdditionalFieldSlice: IAdditionalFieldSlice<Field, Value>;
|
15
|
+
ValueListItemSlice: IGenericSlice<SystemCenter.Types.ValueListItem>;
|
16
|
+
ValueListGroupSlice: IGenericSlice<SystemCenter.Types.ValueListGroup>;
|
17
|
+
EmptyField: Field;
|
18
|
+
GetFieldValueIndex: (field: Field, values: Value[]) => number;
|
19
|
+
GetFieldIndex: (value: Value, fields: Field[]) => number;
|
20
|
+
FieldKeySelector: (field: Field) => string;
|
21
|
+
ValidateField: (field: Field) => string[];
|
22
|
+
CreateValue: (field: Field) => Value;
|
23
|
+
FieldUI: (field: Field, setField: (field: Field) => void) => JSX.Element;
|
24
|
+
}
|
25
|
+
declare function AdditionalField<Field extends IField, Value extends IValue>(props: IProps<Field, Value>): JSX.Element;
|
26
|
+
export default AdditionalField;
|
@@ -0,0 +1,260 @@
|
|
1
|
+
"use strict";
|
2
|
+
// ******************************************************************************************************
|
3
|
+
// AdditionalField.tsx - Gbtc
|
4
|
+
//
|
5
|
+
// Copyright © 2020, Grid Protection Alliance. All Rights Reserved.
|
6
|
+
//
|
7
|
+
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
|
8
|
+
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
|
9
|
+
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
|
10
|
+
// file except in compliance with the License. You may obtain a copy of the License at:
|
11
|
+
//
|
12
|
+
// http://opensource.org/licenses/MIT
|
13
|
+
//
|
14
|
+
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
|
15
|
+
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
|
16
|
+
// License for the specific language governing permissions and limitations.
|
17
|
+
//
|
18
|
+
// Code Modification History:
|
19
|
+
// ----------------------------------------------------------------------------------------------------
|
20
|
+
// 07/14/2021 - C. Lackner
|
21
|
+
// Generated original version of source code.
|
22
|
+
// ******************************************************************************************************
|
23
|
+
var __assign = (this && this.__assign) || function () {
|
24
|
+
__assign = Object.assign || function(t) {
|
25
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
26
|
+
s = arguments[i];
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
28
|
+
t[p] = s[p];
|
29
|
+
}
|
30
|
+
return t;
|
31
|
+
};
|
32
|
+
return __assign.apply(this, arguments);
|
33
|
+
};
|
34
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
35
|
+
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
36
|
+
to[j] = from[i];
|
37
|
+
return to;
|
38
|
+
};
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
40
|
+
var React = require("react");
|
41
|
+
var react_table_1 = require("@gpa-gemstone/react-table");
|
42
|
+
var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
|
43
|
+
var react_interactive_1 = require("@gpa-gemstone/react-interactive");
|
44
|
+
var react_forms_1 = require("@gpa-gemstone/react-forms");
|
45
|
+
var react_redux_1 = require("react-redux");
|
46
|
+
var helper_functions_1 = require("@gpa-gemstone/helper-functions");
|
47
|
+
function AdditionalField(props) {
|
48
|
+
var dispatch = react_redux_1.useDispatch();
|
49
|
+
var valueListItems = react_redux_1.useSelector(props.ValueListItemSlice.Data);
|
50
|
+
var valueListItemStatus = react_redux_1.useSelector(props.ValueListItemSlice.Status);
|
51
|
+
var valueListGroups = react_redux_1.useSelector(props.ValueListGroupSlice.Data);
|
52
|
+
var valueListGroupStatus = react_redux_1.useSelector(props.ValueListGroupSlice.Status);
|
53
|
+
var fields = react_redux_1.useSelector(props.AdditionalFieldSlice.Fields);
|
54
|
+
var values = react_redux_1.useSelector(props.AdditionalFieldSlice.Values);
|
55
|
+
var fieldStatus = react_redux_1.useSelector(props.AdditionalFieldSlice.FieldStatus);
|
56
|
+
var valueStatus = react_redux_1.useSelector(props.AdditionalFieldSlice.ValueStatus);
|
57
|
+
var valueParentID = react_redux_1.useSelector(props.AdditionalFieldSlice.ValueParentId);
|
58
|
+
var _a = React.useState('unintiated'), pageStatus = _a[0], setPageStatus = _a[1];
|
59
|
+
var _b = React.useState([]), editValues = _b[0], setEditValues = _b[1];
|
60
|
+
var sortField = react_redux_1.useSelector(props.AdditionalFieldSlice.SortField);
|
61
|
+
var ascending = react_redux_1.useSelector(props.AdditionalFieldSlice.Ascending);
|
62
|
+
var _c = React.useState(props.EmptyField), newField = _c[0], setNewField = _c[1];
|
63
|
+
var _d = React.useState(false), showWarning = _d[0], setShowWarning = _d[1];
|
64
|
+
var _e = React.useState(false), showEdit = _e[0], setShowEdit = _e[1];
|
65
|
+
var _f = React.useState('None'), hover = _f[0], setHover = _f[1];
|
66
|
+
var _g = React.useState('View'), mode = _g[0], setMode = _g[1];
|
67
|
+
var _h = React.useState([]), changedFields = _h[0], setChangedFields = _h[1];
|
68
|
+
var _j = React.useState([]), errorFields = _j[0], setErrorFields = _j[1];
|
69
|
+
var _k = React.useState([]), fieldErrors = _k[0], setFieldErrors = _k[1];
|
70
|
+
React.useEffect(function () {
|
71
|
+
if (fieldStatus === 'error' || valueStatus === 'error' || valueListGroupStatus === 'error' || valueListItemStatus === 'error')
|
72
|
+
setPageStatus('error');
|
73
|
+
else if (fieldStatus === 'loading' || valueStatus === 'loading' || valueListGroupStatus === 'loading' || valueListItemStatus === 'loading')
|
74
|
+
setPageStatus('loading');
|
75
|
+
else
|
76
|
+
setPageStatus('idle');
|
77
|
+
}, [fieldStatus, valueStatus, valueListGroupStatus, valueListItemStatus]);
|
78
|
+
React.useEffect(function () {
|
79
|
+
if (fieldStatus === 'unintiated' || fieldStatus === 'changed')
|
80
|
+
dispatch(props.AdditionalFieldSlice.FetchField());
|
81
|
+
}, [dispatch, fieldStatus]);
|
82
|
+
React.useEffect(function () {
|
83
|
+
if (valueStatus === 'unintiated' || valueStatus === 'changed' || props.Id !== valueParentID)
|
84
|
+
dispatch(props.AdditionalFieldSlice.FetchValues(props.Id));
|
85
|
+
}, [dispatch, valueStatus, props.Id, valueParentID]);
|
86
|
+
React.useEffect(function () {
|
87
|
+
if (valueListItemStatus === 'unintiated' || valueListItemStatus === 'changed')
|
88
|
+
dispatch(props.ValueListItemSlice.Fetch());
|
89
|
+
}, [dispatch, valueListItemStatus]);
|
90
|
+
React.useEffect(function () {
|
91
|
+
if (valueListGroupStatus === 'unintiated' || valueListGroupStatus === 'changed')
|
92
|
+
dispatch(props.ValueListGroupSlice.Fetch());
|
93
|
+
}, [dispatch, valueListGroupStatus]);
|
94
|
+
React.useEffect(function () { setEditValues(values); }, [values]);
|
95
|
+
var typeOptions = [{ Value: 'string', Label: 'string' }, { Value: 'integer', Label: 'integer' }, { Value: 'number', Label: 'number' }].concat(valueListGroups.map(function (x) { return { Value: x.Name, Label: x.Name }; }));
|
96
|
+
React.useEffect(function () {
|
97
|
+
var e = props.ValidateField(newField);
|
98
|
+
if (newField.FieldName == null || newField.FieldName.length === 0)
|
99
|
+
e.push('A FieldName is required');
|
100
|
+
else if (fields.findIndex(function (f) { return f.FieldName.toLowerCase() === newField.FieldName.toLowerCase() && props.FieldKeySelector(f) !== props.FieldKeySelector(newField); }) > -1)
|
101
|
+
e.push('A Field with this FieldName already exists');
|
102
|
+
setFieldErrors(e);
|
103
|
+
}, [newField]);
|
104
|
+
React.useEffect(function () {
|
105
|
+
var c = [];
|
106
|
+
var e = [];
|
107
|
+
editValues.forEach(function (v) {
|
108
|
+
var eIndex = values.findIndex(function (val) { return val.ID === v.ID; });
|
109
|
+
var fldIndex = props.GetFieldIndex(v, fields);
|
110
|
+
if (eIndex === -1 && fldIndex > -1)
|
111
|
+
c.push(fields[fldIndex].FieldName);
|
112
|
+
else if (fldIndex > -1 && v.Value !== values[eIndex].Value)
|
113
|
+
c.push(fields[fldIndex].FieldName);
|
114
|
+
if (fldIndex > -1 && fields[fldIndex].Type === 'integer' && !helper_functions_1.IsInteger(v.Value))
|
115
|
+
e.push("'" + fields[fldIndex].FieldName + "' has to be a valid integer");
|
116
|
+
if (fldIndex > -1 && fields[fldIndex].Type === 'number' && !helper_functions_1.IsNumber(v.Value))
|
117
|
+
e.push("'" + fields[fldIndex].FieldName + "' has to be a valid number");
|
118
|
+
});
|
119
|
+
setErrorFields(e);
|
120
|
+
setChangedFields(c);
|
121
|
+
}, [values, editValues]);
|
122
|
+
if (pageStatus === 'error')
|
123
|
+
return React.createElement("div", { className: "card", style: { marginBottom: 10, maxHeight: window.innerHeight - 215 } },
|
124
|
+
React.createElement("div", { className: "card-header" },
|
125
|
+
React.createElement("div", { className: "row" },
|
126
|
+
React.createElement("div", { className: "col" },
|
127
|
+
React.createElement("h4", null, "Additional Fields:")))),
|
128
|
+
React.createElement("div", { className: "card-body", style: { maxHeight: window.innerHeight - 315, overflowY: 'auto' } },
|
129
|
+
React.createElement("div", { style: { width: '100%', height: '200px' } },
|
130
|
+
React.createElement("div", { style: { height: '40px', marginLeft: 'auto', marginRight: 'auto', marginTop: 'calc(50% - 20 px)' } },
|
131
|
+
React.createElement(react_interactive_1.ServerErrorIcon, { Show: true, Size: 40, Label: 'A Server Error Occurred. Please Reload the Application' })))));
|
132
|
+
return (React.createElement("div", { className: "card", style: { marginBottom: 10, maxHeight: window.innerHeight - 215 } },
|
133
|
+
React.createElement("div", { className: "card-header" },
|
134
|
+
React.createElement("div", { className: "row" },
|
135
|
+
React.createElement("div", { className: "col" },
|
136
|
+
React.createElement("h4", null, "Additional Fields:")),
|
137
|
+
React.createElement("div", { className: "col" },
|
138
|
+
(mode === 'Edit') ?
|
139
|
+
React.createElement("button", { className: "btn btn-default pull-right", "data-tooltip": 'View', onClick: function () { setMode('View'); setEditValues(values); }, onMouseEnter: function () { return setHover('View'); }, onMouseLeave: function () { return setHover('None'); } }, "View") :
|
140
|
+
React.createElement("button", { className: "btn btn-primary pull-right", onClick: function () { return setMode('Edit'); } }, "Edit"),
|
141
|
+
React.createElement(react_interactive_1.ToolTip, { Show: hover === 'View' && changedFields.length > 0, Position: 'left', Theme: 'dark', Target: "View" }, changedFields.map(function (fld, i) { return React.createElement("p", { key: i },
|
142
|
+
gpa_symbols_1.Warning,
|
143
|
+
" Changes to '",
|
144
|
+
fld,
|
145
|
+
"' will be lost. "); }))))),
|
146
|
+
React.createElement("div", { className: "card-body", style: { maxHeight: window.innerHeight - 315, overflowY: 'auto' } },
|
147
|
+
React.createElement(react_table_1.default, { cols: [
|
148
|
+
{ key: 'FieldName', field: 'FieldName', label: 'Field', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' } },
|
149
|
+
{ key: 'Type', field: 'Type', label: 'Type', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' } },
|
150
|
+
{
|
151
|
+
key: 'Value', label: 'Value', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' }, content: function (item) {
|
152
|
+
var valueListgrpId = valueListGroups.findIndex(function (g) { return g.Name === item.Type; });
|
153
|
+
valueListgrpId = (valueListgrpId > -1 ? valueListGroups[valueListgrpId].ID : -1);
|
154
|
+
var vList = valueListItems.filter(function (i) { return i.GroupID === valueListgrpId; });
|
155
|
+
var valIdx = props.GetFieldValueIndex(item, editValues);
|
156
|
+
if (valIdx > -1)
|
157
|
+
return React.createElement(ValueDisplay, { Mode: mode, Type: item.Type, ValueListItems: vList, Value: editValues[valIdx], Setter: function (val) { return setEditValues(function (d) { var u = __spreadArray([], d); u[valIdx] = val; return u; }); } });
|
158
|
+
return React.createElement(ValueDisplay, { Mode: mode, Type: item.Type, ValueListItems: vList, Value: props.CreateValue(item), Setter: function (val) { return setEditValues(function (d) { var u = __spreadArray([], d); u.push(val); return u; }); } });
|
159
|
+
}
|
160
|
+
},
|
161
|
+
{ key: 'EditButton', label: '', headerStyle: { width: 40, paddingRight: 0, paddingLeft: 10 }, rowStyle: { width: 40, paddingRight: 0, paddingLeft: 10, paddingTop: 36 }, content: function (item) { return (mode === 'Edit' ? React.createElement("button", { className: "btn btn-sm", onClick: function () { setNewField(item); setShowEdit(true); } },
|
162
|
+
React.createElement("span", null,
|
163
|
+
React.createElement("i", { className: "fa fa-pencil" }))) : ''); } },
|
164
|
+
{ key: 'DeleteButton', label: '', headerStyle: { width: 40, paddingLeft: 0, paddingRight: 10 }, rowStyle: { width: 40, paddingLeft: 0, paddingTop: 36, paddingRight: 10 }, content: function (item) { return (mode === 'Edit' ? React.createElement("button", { className: "btn btn-sm", onClick: function () { setNewField(item); setShowWarning(true); } },
|
165
|
+
React.createElement("span", null,
|
166
|
+
React.createElement("i", { className: "fa fa-times" }))) : ''); } },
|
167
|
+
], tableClass: "table table-hover", data: fields, sortKey: sortField, ascending: ascending, onSort: function (d) {
|
168
|
+
if (d.colField === undefined)
|
169
|
+
return;
|
170
|
+
if (d.colKey === sortField)
|
171
|
+
dispatch(props.AdditionalFieldSlice.Sort({ SortField: d.colField, Ascending: !ascending }));
|
172
|
+
else
|
173
|
+
dispatch(props.AdditionalFieldSlice.Sort({ SortField: d.colField, Ascending: true }));
|
174
|
+
}, onClick: function () { }, theadStyle: { fontSize: 'smaller', display: 'table', tableLayout: 'fixed', width: '100%' }, tbodyStyle: { display: 'block', overflowY: 'scroll', maxHeight: window.innerHeight - 455, }, rowStyle: { display: 'table', tableLayout: 'fixed', width: '100%' }, selected: function () { return false; }, keySelector: props.FieldKeySelector })),
|
175
|
+
React.createElement("div", { className: "card-footer" },
|
176
|
+
React.createElement("div", { className: "btn-group mr-2" },
|
177
|
+
React.createElement("button", { className: "btn btn-primary" + (mode === 'View' ? ' disabled' : ''), onMouseEnter: function () { return setHover('New'); }, onMouseLeave: function () { return setHover('None'); }, onClick: function () { if (mode === 'Edit') {
|
178
|
+
setShowEdit(true);
|
179
|
+
setNewField(props.EmptyField);
|
180
|
+
} }, "data-tooltip": 'New' }, "Add Field")),
|
181
|
+
React.createElement(react_interactive_1.ToolTip, { Show: hover === 'New' && mode === 'View', Position: 'top', Theme: 'dark', Target: "New" },
|
182
|
+
React.createElement("p", null, " To add a new Field switch to Edit mode by clicking on the Edit Button on the upper right corner.")),
|
183
|
+
React.createElement("div", { className: "btn-group mr-2" },
|
184
|
+
React.createElement("button", { className: "btn btn-primary" + (changedFields.length === 0 || mode === 'View' || errorFields.length > 0 ? ' disabled' : ''), onClick: function () { if (errorFields.length === 0 && changedFields.length > 0 && mode === 'Edit')
|
185
|
+
dispatch(props.AdditionalFieldSlice.UpdateValues({ ParentID: props.Id, Values: editValues })); }, onMouseEnter: function () { return setHover('Save'); }, onMouseLeave: function () { return setHover('None'); }, "data-tooltip": 'SaveValues' }, "Save Changes")),
|
186
|
+
React.createElement(react_interactive_1.ToolTip, { Show: hover === 'Save' && (mode === 'View' || changedFields.length > 0), Position: 'top', Theme: 'dark', Target: "SaveValues" },
|
187
|
+
mode === 'View' ? React.createElement("p", null, " To change any Fields switch to Edit mode by clicking on the Edit Button on the upper right corner.") : null,
|
188
|
+
changedFields.length > 0 && errorFields.length === 0 ? changedFields.map(function (fld, i) { return React.createElement("p", { key: i },
|
189
|
+
" ",
|
190
|
+
gpa_symbols_1.HeavyCheckMark,
|
191
|
+
" Changes to '",
|
192
|
+
fld,
|
193
|
+
"' are valid."); }) : null,
|
194
|
+
changedFields.length > 0 && errorFields.length > 0 ? errorFields.map(function (t, i) { return React.createElement("p", { key: i },
|
195
|
+
" ",
|
196
|
+
gpa_symbols_1.CrossMark,
|
197
|
+
" ",
|
198
|
+
t,
|
199
|
+
"."); }) : null),
|
200
|
+
React.createElement("div", { className: "btn-group mr-2" },
|
201
|
+
React.createElement("button", { className: "btn btn-default" + (changedFields.length === 0 || mode === 'View' ? ' disabled' : ''), onClick: function () {
|
202
|
+
if (changedFields.length > 0 && mode === 'Edit')
|
203
|
+
setEditValues(values);
|
204
|
+
}, onMouseEnter: function () { return setHover('Clear'); }, onMouseLeave: function () { return setHover('None'); }, "data-tooltip": 'Reset' }, "Reset")),
|
205
|
+
React.createElement(react_interactive_1.ToolTip, { Show: hover === 'Clear' && (mode === 'View' || changedFields.length > 0), Position: 'top', Theme: 'dark', Target: 'Reset' },
|
206
|
+
mode === 'View' ? React.createElement("p", null, " To change any Fields switch to Edit mode by clicking on the Edit Button on the upper right corner.") : null,
|
207
|
+
changedFields.length > 0 ? changedFields.map(function (fld, i) { return React.createElement("p", { key: i },
|
208
|
+
gpa_symbols_1.Warning,
|
209
|
+
" Changes to '",
|
210
|
+
fld,
|
211
|
+
"' will be lost. "); }) : null)),
|
212
|
+
React.createElement(react_interactive_1.Warning, { Show: showWarning, Title: 'Delete ' + newField.FieldName, Message: "This will delete all instances of '" + newField.FieldName + "' and will also delete all information assigned to these fields.", CallBack: function (confirm) { if (confirm)
|
213
|
+
dispatch(props.AdditionalFieldSlice.FieldAction({ Verb: 'DELETE', Record: newField })); setShowWarning(false); } }),
|
214
|
+
React.createElement(react_interactive_1.Modal, { Title: 'Additional Field', ConfirmText: 'Save', ShowX: true, ShowCancel: false, ConfirmBtnClass: 'btn-primary' + (fieldErrors.length > 0 ? ' disabled' : ''), Show: showEdit, Size: 'lg', CallBack: function (confirmation) {
|
215
|
+
if (confirmation) {
|
216
|
+
if (props.FieldKeySelector(newField) === "new")
|
217
|
+
dispatch(props.AdditionalFieldSlice.FieldAction({ Verb: "POST", Record: newField }));
|
218
|
+
else
|
219
|
+
dispatch(props.AdditionalFieldSlice.FieldAction({ Verb: "PATCH", Record: newField }));
|
220
|
+
}
|
221
|
+
setShowEdit(false);
|
222
|
+
}, ConfirmShowToolTip: fieldErrors.length > 0, ConfirmToolTipContent: fieldErrors.map(function (t, i) { return React.createElement("p", { key: i },
|
223
|
+
gpa_symbols_1.CrossMark,
|
224
|
+
" ",
|
225
|
+
t,
|
226
|
+
" "); }) },
|
227
|
+
React.createElement(react_forms_1.Input, { Record: newField, Field: 'FieldName', Valid: function (field) {
|
228
|
+
return newField.FieldName != null && newField.FieldName.length > 0
|
229
|
+
&& fields.findIndex(function (f) { return f.FieldName.toLowerCase() === newField.FieldName.toLowerCase() && props.FieldKeySelector(f) !== props.FieldKeySelector(newField); }) < 0;
|
230
|
+
}, Label: "Field Name", Setter: setNewField, Feedback: 'The additional field needs to have a unique Field Name' }),
|
231
|
+
React.createElement(react_forms_1.Select, { Record: newField, Field: 'Type', Options: typeOptions, Label: "Field Type", Setter: setNewField }),
|
232
|
+
props.FieldUI !== undefined ? props.FieldUI(newField, setNewField) : null)));
|
233
|
+
}
|
234
|
+
exports.default = AdditionalField;
|
235
|
+
function ValueDisplay(props) {
|
236
|
+
React.useEffect(function () {
|
237
|
+
if (props.Type === 'integer' || props.Type === 'number' || props.Type === 'string')
|
238
|
+
return;
|
239
|
+
else if (props.Type !== 'boolean' &&
|
240
|
+
props.ValueListItems.findIndex(function (i) { return i.Value.toLowerCase() === props.Value.Value.toString().toLowerCase(); }) < 0
|
241
|
+
&& props.ValueListItems.length > 0)
|
242
|
+
props.Setter(__assign(__assign({}, props.Value), { Value: props.ValueListItems[0].Value }));
|
243
|
+
}, [props.Type, props.Value, props.ValueListItems]);
|
244
|
+
if (props.Mode === 'View') {
|
245
|
+
if (props.Type === 'boolean')
|
246
|
+
return React.createElement("span", null, props.Value.Value.toString().toLowerCase() === "true" ? "true" : "false");
|
247
|
+
else
|
248
|
+
return React.createElement("span", null, props.Value.Value);
|
249
|
+
}
|
250
|
+
if (props.Type === 'number')
|
251
|
+
return React.createElement(react_forms_1.Input, { Record: props.Value, Field: 'Value', Valid: function () { return helper_functions_1.IsInteger(props.Value.Value); }, Label: '', Type: 'number', Setter: props.Setter, Feedback: 'Thi Field is a numeric field.' });
|
252
|
+
if (props.Type === 'integer')
|
253
|
+
return React.createElement(react_forms_1.Input, { Record: props.Value, Field: 'Value', Valid: function () { return helper_functions_1.IsNumber(props.Value.Value); }, Label: '', Type: 'number', Setter: props.Setter, Feedback: 'Thi Field is an integer field.' });
|
254
|
+
else if (props.Type === 'string')
|
255
|
+
return React.createElement(react_forms_1.Input, { Record: props.Value, Field: 'Value', Valid: function () { return true; }, Label: '', Type: 'text', Setter: props.Setter });
|
256
|
+
else if (props.Type === 'boolean')
|
257
|
+
return React.createElement(react_forms_1.CheckBox, { Record: props.Value, Field: 'Value', Label: '', Setter: props.Setter });
|
258
|
+
else
|
259
|
+
return React.createElement(react_forms_1.Select, { EmptyOption: true, Record: props.Value, Field: 'Value', Label: '', Setter: props.Setter, Options: props.ValueListItems.map(function (x) { return ({ Value: x.ID.toString(), Label: x.Value }); }) });
|
260
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { SystemCenter, Application } from '@gpa-gemstone/application-typings';
|
3
|
+
import { IAdditionalFieldSlice, IGenericSlice, IUserAccountSlice } from '../SliceInterfaces';
|
4
|
+
interface IProps {
|
5
|
+
UserSlice: IUserAccountSlice;
|
6
|
+
AdditionalFieldSlice: IAdditionalFieldSlice<Application.Types.iAdditionalUserField, Application.Types.iAdditionalUserFieldValue>;
|
7
|
+
ValueListItemSlice: IGenericSlice<SystemCenter.Types.ValueListItem>;
|
8
|
+
ValueListGroupSlice: IGenericSlice<SystemCenter.Types.ValueListGroup>;
|
9
|
+
OnUserSelect: (userID: string) => void;
|
10
|
+
}
|
11
|
+
declare function ByUser(props: IProps): JSX.Element;
|
12
|
+
export default ByUser;
|
@@ -0,0 +1,148 @@
|
|
1
|
+
"use strict";
|
2
|
+
// ******************************************************************************************************
|
3
|
+
// ByUser.tsx - Gbtc
|
4
|
+
//
|
5
|
+
// Copyright © 2020, Grid Protection Alliance. All Rights Reserved.
|
6
|
+
//
|
7
|
+
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
|
8
|
+
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
|
9
|
+
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
|
10
|
+
// file except in compliance with the License. You may obtain a copy of the License at:
|
11
|
+
//
|
12
|
+
// http://opensource.org/licenses/MIT
|
13
|
+
//
|
14
|
+
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
|
15
|
+
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
|
16
|
+
// License for the specific language governing permissions and limitations.
|
17
|
+
//
|
18
|
+
// Code Modification History:
|
19
|
+
// ----------------------------------------------------------------------------------------------------
|
20
|
+
// 07/14/2021 - C. Lackner
|
21
|
+
// Generated original version of source code.
|
22
|
+
// ******************************************************************************************************
|
23
|
+
var __assign = (this && this.__assign) || function () {
|
24
|
+
__assign = Object.assign || function(t) {
|
25
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
26
|
+
s = arguments[i];
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
28
|
+
t[p] = s[p];
|
29
|
+
}
|
30
|
+
return t;
|
31
|
+
};
|
32
|
+
return __assign.apply(this, arguments);
|
33
|
+
};
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
35
|
+
var React = require("react");
|
36
|
+
var react_table_1 = require("@gpa-gemstone/react-table");
|
37
|
+
var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
|
38
|
+
var react_interactive_1 = require("@gpa-gemstone/react-interactive");
|
39
|
+
var CryptoJS = require("crypto-js");
|
40
|
+
var _ = require("lodash");
|
41
|
+
var UserForm_1 = require("./UserForm");
|
42
|
+
var react_redux_1 = require("react-redux");
|
43
|
+
var defaultSearchcols = [
|
44
|
+
{ label: 'First Name', key: 'FirstName', type: 'string', isPivotField: false },
|
45
|
+
{ label: 'Last Name', key: 'LastName', type: 'string', isPivotField: false },
|
46
|
+
{ label: 'Location', key: 'Location', type: 'string', isPivotField: false },
|
47
|
+
{ label: 'Phone', key: 'Phone', type: 'string', isPivotField: false },
|
48
|
+
{ label: 'Email', key: 'Email', type: 'string', isPivotField: false },
|
49
|
+
];
|
50
|
+
function ByUser(props) {
|
51
|
+
var dispatch = react_redux_1.useDispatch();
|
52
|
+
var search = react_redux_1.useSelector(props.UserSlice.SearchFilters);
|
53
|
+
var data = react_redux_1.useSelector(props.UserSlice.SearchResults);
|
54
|
+
var userStatus = react_redux_1.useSelector(props.UserSlice.Status);
|
55
|
+
var searchStatus = react_redux_1.useSelector(props.UserSlice.SearchStatus);
|
56
|
+
var sortField = react_redux_1.useSelector(props.UserSlice.SortField);
|
57
|
+
var ascending = react_redux_1.useSelector(props.UserSlice.Ascending);
|
58
|
+
var currentUserAccount = react_redux_1.useSelector(props.UserSlice.CurrentUser);
|
59
|
+
var adlFields = react_redux_1.useSelector(props.AdditionalFieldSlice.Fields);
|
60
|
+
var adlFieldStatus = react_redux_1.useSelector(props.AdditionalFieldSlice.FieldStatus);
|
61
|
+
var _a = React.useState(defaultSearchcols), filterableList = _a[0], setFilterableList = _a[1];
|
62
|
+
var _b = React.useState(false), showModal = _b[0], setShowModal = _b[1];
|
63
|
+
var _c = React.useState([]), userError = _c[0], setUserError = _c[1];
|
64
|
+
var valueListItems = react_redux_1.useSelector(props.ValueListItemSlice.Data);
|
65
|
+
var valueListItemStatus = react_redux_1.useSelector(props.ValueListItemSlice.Status);
|
66
|
+
var valueListGroups = react_redux_1.useSelector(props.ValueListGroupSlice.Data);
|
67
|
+
var valueListGroupStatus = react_redux_1.useSelector(props.ValueListGroupSlice.Status);
|
68
|
+
var _d = React.useState('unintiated'), pageStatus = _d[0], setPageStatus = _d[1];
|
69
|
+
React.useEffect(function () {
|
70
|
+
if (userStatus === 'error' || adlFieldStatus === 'error' || valueListItemStatus === 'error' || valueListGroupStatus === 'error')
|
71
|
+
setPageStatus('error');
|
72
|
+
else if (userStatus === 'loading' || adlFieldStatus === 'loading' || valueListItemStatus === 'loading' || valueListGroupStatus === 'loading')
|
73
|
+
setPageStatus('loading');
|
74
|
+
else
|
75
|
+
setPageStatus('idle');
|
76
|
+
}, [userStatus, adlFieldStatus, valueListItemStatus, valueListGroupStatus]);
|
77
|
+
React.useEffect(function () {
|
78
|
+
if (adlFieldStatus === 'unintiated' || adlFieldStatus === 'changed')
|
79
|
+
dispatch(props.AdditionalFieldSlice.FetchField());
|
80
|
+
}, [dispatch, adlFieldStatus]);
|
81
|
+
React.useEffect(function () {
|
82
|
+
dispatch(props.UserSlice.DBSearch({ sortField: sortField, ascending: ascending, filter: search }));
|
83
|
+
dispatch(props.UserSlice.SetNewUser());
|
84
|
+
}, [dispatch]);
|
85
|
+
React.useEffect(function () {
|
86
|
+
if (valueListItemStatus === 'unintiated' || valueListItemStatus === 'changed')
|
87
|
+
dispatch(props.ValueListItemSlice.Fetch());
|
88
|
+
}, [dispatch, valueListItemStatus]);
|
89
|
+
React.useEffect(function () {
|
90
|
+
if (valueListGroupStatus === 'unintiated' || valueListGroupStatus === 'changed')
|
91
|
+
dispatch(props.ValueListGroupSlice.Fetch());
|
92
|
+
}, [dispatch, valueListGroupStatus]);
|
93
|
+
React.useEffect(function () {
|
94
|
+
function ConvertType(type) {
|
95
|
+
if (type === 'string' || type === 'integer' || type === 'number' || type === 'datetime' || type === 'boolean')
|
96
|
+
return { type: type };
|
97
|
+
return { type: 'enum', enum: [{ Label: type, Value: type }] };
|
98
|
+
}
|
99
|
+
var ordered = _.orderBy(defaultSearchcols.concat(adlFields.map(function (item) { return (__assign({ label: "[AF] " + item.FieldName, key: item.FieldName }, ConvertType(item.Type))); })), ['label'], ["asc"]);
|
100
|
+
setFilterableList(ordered);
|
101
|
+
}, [adlFields]);
|
102
|
+
if (pageStatus === 'error')
|
103
|
+
return React.createElement("div", { style: { width: '100%', height: '100%' } },
|
104
|
+
React.createElement(react_interactive_1.ServerErrorIcon, { Show: true, Label: 'A Server Error Occured. Please Reload the Application' }));
|
105
|
+
return (React.createElement("div", { style: { width: '100%', height: '100%' } },
|
106
|
+
React.createElement(react_interactive_1.LoadingScreen, { Show: pageStatus === 'loading' }),
|
107
|
+
React.createElement(react_interactive_1.SearchBar, { CollumnList: filterableList, SetFilter: function (flds) { return dispatch(props.UserSlice.DBSearch({ sortField: sortField, ascending: ascending, filter: flds })); }, Direction: 'left', defaultCollumn: { label: 'Last Name', key: 'LastName', type: 'string', isPivotField: false }, Width: '50%', Label: 'Search', ShowLoading: searchStatus === 'loading', ResultNote: searchStatus === 'error' ? 'Could not complete Search' : 'Found ' + data.length + ' UserAccounts', GetEnum: function (setOptions, field) {
|
108
|
+
if (field.type !== 'enum' || field.enum === undefined || field.enum.length !== 1)
|
109
|
+
return function () { };
|
110
|
+
var grpName = (field.enum !== undefined ? field.enum[0].Value.toLowerCase() : '');
|
111
|
+
var grpIndex = valueListGroups.findIndex(function (g) { return g.Name.toLowerCase() === grpName; });
|
112
|
+
if (grpIndex < 0)
|
113
|
+
return function () { };
|
114
|
+
setOptions(valueListItems.filter(function (v) { return v.GroupID === valueListGroups[grpIndex].ID; }).map(function (item) { return ({ Value: item.ID.toString(), Label: item.Value }); }));
|
115
|
+
return function () { };
|
116
|
+
} },
|
117
|
+
React.createElement("li", { className: "nav-item", style: { width: '15%', paddingRight: 10 } },
|
118
|
+
React.createElement("fieldset", { className: "border", style: { padding: '10px', height: '100%' } },
|
119
|
+
React.createElement("legend", { className: "w-auto", style: { fontSize: 'large' } }, "Actions:"),
|
120
|
+
React.createElement("form", null,
|
121
|
+
React.createElement("button", { className: "btn btn-primary", onClick: function (event) { event.preventDefault(); setShowModal(true); } }, "Add User"))))),
|
122
|
+
React.createElement("div", { style: { width: '100%', height: 'calc( 100% - 136px)' } },
|
123
|
+
React.createElement(react_table_1.default, { cols: [
|
124
|
+
{ key: 'Name', field: 'Name', label: 'User Name', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
|
125
|
+
{ key: 'FirstName', field: 'FirstName', label: 'First Name', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
|
126
|
+
{ key: 'LastName', field: 'LastName', label: 'Last Name', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
|
127
|
+
{ key: 'Phone', field: 'Phone', label: 'Phone', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
|
128
|
+
{ key: 'Email', field: 'Email', label: 'Email', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' } },
|
129
|
+
{ key: 'scroll', label: '', headerStyle: { width: 17, padding: 0 }, rowStyle: { width: 0, padding: 0 } },
|
130
|
+
], tableClass: "table table-hover", data: data, sortKey: sortField, ascending: ascending, onSort: function (d) {
|
131
|
+
if (d.colField === undefined)
|
132
|
+
return;
|
133
|
+
if (d.colField !== sortField)
|
134
|
+
dispatch(props.UserSlice.DBSearch({ sortField: sortField, ascending: !ascending, filter: search }));
|
135
|
+
else
|
136
|
+
dispatch(props.UserSlice.DBSearch({ sortField: d.colField, ascending: true, filter: search }));
|
137
|
+
}, onClick: function (d) { return props.OnUserSelect(d.row.ID); }, theadStyle: { fontSize: 'smaller', display: 'table', tableLayout: 'fixed', width: '100%' }, tbodyStyle: { display: 'block', overflowY: 'scroll', maxHeight: window.innerHeight - 300, width: '100%' }, rowStyle: { fontSize: 'smaller', display: 'table', tableLayout: 'fixed', width: '100%' }, selected: function (item) { return false; } })),
|
138
|
+
React.createElement(react_interactive_1.Modal, { Show: showModal, Size: 'lg', ShowCancel: false, ShowX: true, ConfirmText: 'Save', Title: 'Add User', CallBack: function (confirm) {
|
139
|
+
if (confirm)
|
140
|
+
dispatch(props.UserSlice.DBAction({ verb: 'POST', record: __assign(__assign({}, currentUserAccount), { Password: CryptoJS.SHA256(currentUserAccount.Password + "0").toString(CryptoJS.enc.Base64) }) }));
|
141
|
+
dispatch(props.UserSlice.SetNewUser());
|
142
|
+
setShowModal(false);
|
143
|
+
}, ConfirmShowToolTip: userError.length > 0, ConfirmToolTipContent: userError.map(function (t, i) { return React.createElement("p", { key: i },
|
144
|
+
gpa_symbols_1.CrossMark,
|
145
|
+
" ",
|
146
|
+
t); }), DisableConfirm: userError.length > 0 }, currentUserAccount !== undefined ? React.createElement(UserForm_1.default, { UserAccount: currentUserAccount, Setter: function (u) { return dispatch(props.UserSlice.SetCurrentUser(u)); }, Edit: false, SetErrors: setUserError, UserSlice: props.UserSlice }) : null)));
|
147
|
+
}
|
148
|
+
exports.default = ByUser;
|