@gpa-gemstone/common-pages 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|