@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 ADDED
@@ -0,0 +1,14 @@
1
+ # react-table
2
+
3
+ ![gemstone logo](https://raw.githubusercontent.com/gemstone/web/master/docs/img/gemstone-wide-600.png)
4
+
5
+ The Gemstone Web Library organizes all Gemstone functionality related to web.
6
+
7
+ [![GitHub license](https://img.shields.io/github/license/gemstone/web?color=4CC61E)](https://github.com/gemstone/web/blob/master/LICENSE)
8
+
9
+ This library includes helpful npm package component for common gp pages across PQ Apps.
10
+
11
+ ## Usage
12
+ ### General Modal
13
+
14
+
package/lib/Note.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /// <reference types="react" />
2
+ import { OpenXDA } from '@gpa-gemstone/application-typings';
3
+ import { IGenericSlice } from './SliceInterfaces';
4
+ interface IProps {
5
+ NoteTypes: OpenXDA.Types.NoteType[];
6
+ NoteTags: OpenXDA.Types.NoteTag[];
7
+ NoteApplications: OpenXDA.Types.NoteApplication[];
8
+ MaxHeight: number;
9
+ Title?: string;
10
+ ReferenceTableID?: number;
11
+ NoteSlice: IGenericSlice<OpenXDA.Types.Note>;
12
+ AllowEdit?: boolean;
13
+ AllowRemove?: boolean;
14
+ AllowAdd?: boolean;
15
+ }
16
+ declare function Note(props: IProps): JSX.Element;
17
+ export default Note;
package/lib/Note.js ADDED
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ // ******************************************************************************************************
3
+ // Note.tsx - Gbtc
4
+ //
5
+ // Copyright © 2021, 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
+ // 04/28/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_forms_1 = require("@gpa-gemstone/react-forms");
37
+ var react_table_1 = require("@gpa-gemstone/react-table");
38
+ var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
39
+ var react_interactive_1 = require("@gpa-gemstone/react-interactive");
40
+ var moment = require("moment");
41
+ var react_redux_1 = require("react-redux");
42
+ function Note(props) {
43
+ var dispatch = react_redux_1.useDispatch();
44
+ var _a = React.useState(false), showEdit = _a[0], setEdit = _a[1];
45
+ var _b = React.useState('none'), hover = _b[0], setHover = _b[1];
46
+ var data = react_redux_1.useSelector(props.NoteSlice.Data);
47
+ var dataStatus = react_redux_1.useSelector(props.NoteSlice.Status);
48
+ var parentID = react_redux_1.useSelector((props.NoteSlice.ParentID === undefined ? function (state) { return props.ReferenceTableID; } : props.NoteSlice.ParentID));
49
+ var sortField = react_redux_1.useSelector(props.NoteSlice.SortField);
50
+ var ascending = react_redux_1.useSelector(props.NoteSlice.Ascending);
51
+ var _c = React.useState(CreateNewNote()), note = _c[0], setNote = _c[1];
52
+ React.useEffect(function () {
53
+ if (dataStatus === 'unintiated' || dataStatus === 'changed' || parentID !== props.ReferenceTableID)
54
+ dispatch(props.NoteSlice.Fetch(props.ReferenceTableID));
55
+ }, [props.ReferenceTableID, dispatch, dataStatus]);
56
+ React.useEffect(function () {
57
+ if (note.NoteTypeID > 0 || props.NoteTypes.length === 0)
58
+ return;
59
+ setNote(function (n) { return (__assign(__assign({}, n), { NoteTypeID: props.NoteTypes[0].ID })); });
60
+ }, [props.NoteTypes]);
61
+ React.useEffect(function () {
62
+ if (note.NoteApplicationID > 0 || props.NoteApplications.length === 0)
63
+ return;
64
+ setNote(function (n) { return (__assign(__assign({}, n), { NoteApplicationID: props.NoteApplications[0].ID })); });
65
+ }, [props.NoteApplications]);
66
+ React.useEffect(function () {
67
+ if (note.NoteTagID > 0 || props.NoteTags.length === 0)
68
+ return;
69
+ setNote(function (n) { return (__assign(__assign({}, n), { NoteTagID: props.NoteTags[0].ID })); });
70
+ }, [props.NoteTags]);
71
+ React.useEffect(function () {
72
+ if (note.ReferenceTableID === undefined)
73
+ return;
74
+ setNote(function (n) { return (__assign(__assign({}, n), { ReferenceTableID: props.ReferenceTableID !== undefined ? props.ReferenceTableID : -1 })); });
75
+ }, [props.ReferenceTableID]);
76
+ var allowEdit = props.AllowEdit === undefined ? true : props.AllowEdit;
77
+ var allowRemove = props.AllowRemove === undefined ? true : props.AllowRemove;
78
+ var allowAdd = props.AllowAdd === undefined ? true : props.AllowAdd;
79
+ function CreateNewNote() {
80
+ var newNote = { ID: -1, ReferenceTableID: -1, NoteTagID: -1, NoteTypeID: -1, NoteApplicationID: -1, Timestamp: '', UserAccount: '', Note: '' };
81
+ if (props.ReferenceTableID !== undefined)
82
+ newNote.ReferenceTableID = props.ReferenceTableID;
83
+ if (props.NoteApplications.length > 0)
84
+ newNote.NoteApplicationID = props.NoteApplications[0].ID;
85
+ if (props.NoteTypes.length > 0)
86
+ newNote.NoteTypeID = props.NoteTypes[0].ID;
87
+ if (props.NoteTags.length > 0)
88
+ newNote.NoteTagID = props.NoteTags[0].ID;
89
+ return newNote;
90
+ }
91
+ function handleEdit(d) {
92
+ setNote(d);
93
+ setEdit(true);
94
+ }
95
+ function handleAdd(d) {
96
+ dispatch(props.NoteSlice.DBAction({ verb: 'POST', record: __assign(__assign({}, d), { UserAccount: undefined, Timestamp: moment().format('MM/DD/YYYY HH:mm') }) }));
97
+ setNote(CreateNewNote());
98
+ }
99
+ function handleSaveEdit(confirm) {
100
+ if (note.Note.length === 0 && confirm)
101
+ return;
102
+ setEdit(false);
103
+ if (confirm && allowEdit)
104
+ dispatch(props.NoteSlice.DBAction({ verb: 'PATCH', record: note }));
105
+ setNote(CreateNewNote());
106
+ }
107
+ if (dataStatus === "error")
108
+ return (React.createElement("div", { style: { width: '100%', height: '100%' } },
109
+ React.createElement("div", { style: { height: '40px', margin: 'auto', marginTop: 'calc(50% - 20 px)' } },
110
+ React.createElement(react_interactive_1.ServerErrorIcon, { Show: true, Size: 40, Label: 'A Server Error Occured. Please Reload the Application' }))));
111
+ return (React.createElement("div", { className: "card", style: { marginBottom: 10, maxHeight: props.MaxHeight, width: '100%' } },
112
+ React.createElement(react_interactive_1.LoadingScreen, { Show: dataStatus === 'loading' }),
113
+ React.createElement("div", { className: "card-header" },
114
+ React.createElement("div", { className: "row" },
115
+ React.createElement("div", { className: "col" },
116
+ React.createElement("h4", null, props.Title !== undefined ? props.Title : 'Notes:')))),
117
+ React.createElement("div", { className: "card-body", style: { maxHeight: props.MaxHeight - 100, overflowY: 'auto', width: '100%' } },
118
+ React.createElement("div", null,
119
+ React.createElement(react_table_1.default, { cols: [
120
+ { key: 'Note', field: 'Note', label: 'Note', headerStyle: { width: '50%' }, rowStyle: { width: '50%' } },
121
+ { key: 'Timestamp', field: 'Timestamp', label: 'Time', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' }, content: function (item) { return moment.utc(item.Timestamp).format("MM/DD/YYYY HH:mm"); } },
122
+ { key: 'UserAccount', field: 'UserAccount', label: 'User', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' } },
123
+ {
124
+ key: 'buttons', label: '', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' }, content: function (item) { return React.createElement(React.Fragment, null,
125
+ allowEdit ? React.createElement("button", { className: "btn btn-sm", onClick: function () { return handleEdit(item); } },
126
+ React.createElement("span", null,
127
+ " ",
128
+ gpa_symbols_1.Pencil,
129
+ " ")) : null,
130
+ allowRemove ? React.createElement("button", { className: "btn btn-sm", onClick: function () { return dispatch(props.NoteSlice.DBAction({ verb: 'DELETE', record: item })); } },
131
+ React.createElement("span", null,
132
+ " ",
133
+ gpa_symbols_1.TrashCan,
134
+ " ")) : null); }
135
+ },
136
+ ], tableClass: "table table-hover", data: data, sortKey: sortField, ascending: ascending, onSort: function (d) {
137
+ if (d.colField === undefined)
138
+ return;
139
+ if (d.colField === sortField)
140
+ dispatch(props.NoteSlice.Sort({ SortField: sortField, Ascending: ascending }));
141
+ else
142
+ dispatch(props.NoteSlice.Sort({ SortField: d.colField, Ascending: true }));
143
+ }, onClick: function () { return; }, 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 () { return false; } })),
144
+ allowAdd ?
145
+ React.createElement(NoteOptions, { Record: note, Setter: function (n) { return setNote(n); }, NoteTags: props.NoteTags, NoteTypes: props.NoteTypes, NoteApplications: props.NoteApplications })
146
+ : null,
147
+ React.createElement(react_interactive_1.Modal, { Show: showEdit, Title: 'Edit Note', ShowCancel: true, CallBack: handleSaveEdit, DisableConfirm: note.Note == null || note.Note.length === 0, ShowX: true, ConfirmShowToolTip: note.Note == null || note.Note.length === 0, ConfirmToolTipContent: React.createElement("p", null,
148
+ " ",
149
+ gpa_symbols_1.CrossMark,
150
+ " An empty Note can not be saved. ") },
151
+ React.createElement(NoteOptions, { Record: note, Setter: function (n) { return setNote(n); }, NoteTags: props.NoteTags, NoteTypes: props.NoteTypes, NoteApplications: props.NoteApplications }))),
152
+ allowAdd ?
153
+ React.createElement("div", { className: "card-footer" },
154
+ React.createElement("div", { className: "btn-group mr-2" },
155
+ React.createElement("button", { className: "btn btn-primary" + (note.Note === null || note.Note.length === 0 ? ' disabled' : ''), onClick: function () { if (note.Note !== null && note.Note.length > 0)
156
+ handleAdd(note); }, "data-tooltip": "Add", style: { cursor: note.Note === null || note.Note.length === 0 ? 'not-allowed' : 'pointer' }, onMouseOver: function () { return setHover('add'); }, onMouseOut: function () { return setHover('none'); } }, "Add Note"),
157
+ React.createElement(react_interactive_1.ToolTip, { Show: hover === 'add' && (note.Note === null || note.Note.length === 0), Position: 'top', Theme: 'dark', Target: "Add" },
158
+ React.createElement("p", null,
159
+ gpa_symbols_1.CrossMark,
160
+ " A note needs to be entered. "))),
161
+ React.createElement("div", { className: "btn-group mr-2" },
162
+ React.createElement("button", { className: "btn btn-default" + (note.Note === null || note.Note.length === 0 ? ' disabled' : ''), onClick: function () { return setNote(function (n) { return (__assign(__assign({}, n), { Note: '' })); }); }, style: { cursor: note.Note === null || note.Note.length === 0 ? 'not-allowed' : 'pointer' }, "data-tooltip": "Remove", onMouseOver: function () { return setHover('clear'); }, onMouseOut: function () { return setHover('none'); } }, "Clear"),
163
+ React.createElement(react_interactive_1.ToolTip, { Show: hover === 'clear' && (note.Note === null || note.Note.length === 0), Position: 'top', Theme: 'dark', Target: "Remove" },
164
+ React.createElement("p", null,
165
+ gpa_symbols_1.CrossMark,
166
+ " The note field is already empty. "))))
167
+ : React.createElement("div", { className: "card-footer" }, " ")));
168
+ }
169
+ function NoteOptions(props) {
170
+ var showOptions = props.NoteTags.length > 1 || props.NoteTypes.length > 1 || props.NoteApplications.length > 1;
171
+ return (React.createElement("div", { className: "row" },
172
+ React.createElement("div", { className: showOptions ? "col-6" : 'col-12' },
173
+ React.createElement(react_forms_1.TextArea, { Record: props.Record, Rows: 4, Field: 'Note', Setter: function (n) { return props.Setter(n); }, Valid: function () { return props.Record.Note != null && props.Record.Note.length > 0; }, Label: '' })),
174
+ showOptions ? React.createElement("div", { className: "col-6" },
175
+ props.NoteTypes.length > 1 ? React.createElement(react_forms_1.Select, { Record: props.Record, Field: 'NoteTypeID', Label: 'Note for: ', Options: props.NoteTypes.map(function (r) { return ({ Value: r.ID.toString(), Label: r.Name }); }), Setter: function (record) { return props.Setter(__assign(__assign({}, record), { NoteTypeID: parseInt(record.NoteTypeID.toString(), 10) })); } }) : null,
176
+ props.NoteTags.length > 1 ? React.createElement(react_forms_1.Select, { Record: props.Record, Field: 'NoteTagID', Label: 'Type: ', Options: props.NoteTags.map(function (r) { return ({ Value: r.ID.toString(), Label: r.Name }); }), Setter: function (record) { return props.Setter(__assign(__assign({}, record), { NoteTagID: parseInt(record.NoteTagID.toString(), 10) })); } }) : null,
177
+ props.NoteApplications.length > 1 ? React.createElement(react_forms_1.Select, { Record: props.Record, Field: 'NoteApplicationID', Label: 'Application: ', Options: props.NoteApplications.map(function (r) { return ({ Value: r.ID.toString(), Label: r.Name }); }), Setter: function (record) { return props.Setter(__assign(__assign({}, record), { NoteApplicationID: parseInt(record.NoteApplicationID.toString(), 10) })); } }) : null) : null));
178
+ }
179
+ exports.default = Note;
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { ISearchableSlice } from './SliceInterfaces';
3
+ import { SystemCenter } from '@gpa-gemstone/application-typings';
4
+ interface IProps {
5
+ SettingsSlice: ISearchableSlice<SystemCenter.Types.Setting>;
6
+ }
7
+ declare function Setting(props: IProps): JSX.Element;
8
+ export default Setting;
package/lib/Setting.js ADDED
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ // ******************************************************************************************************
3
+ // Setting.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
+ // 04/28/2021 - C. Lackner
21
+ // Generated original version of source code.
22
+ // ******************************************************************************************************
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ var React = require("react");
25
+ var react_forms_1 = require("@gpa-gemstone/react-forms");
26
+ var react_table_1 = require("@gpa-gemstone/react-table");
27
+ var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
28
+ var react_interactive_1 = require("@gpa-gemstone/react-interactive");
29
+ var react_redux_1 = require("react-redux");
30
+ function Setting(props) {
31
+ var dispatch = react_redux_1.useDispatch();
32
+ var search = react_redux_1.useSelector(props.SettingsSlice.SearchFilters);
33
+ var searchStatus = react_redux_1.useSelector(props.SettingsSlice.SearchStatus);
34
+ var data = react_redux_1.useSelector(props.SettingsSlice.SearchResults);
35
+ var allSettings = react_redux_1.useSelector(props.SettingsSlice.Data);
36
+ var status = react_redux_1.useSelector(props.SettingsSlice.Status);
37
+ var _a = React.useState('Name'), sortField = _a[0], setSortField = _a[1];
38
+ var _b = React.useState(true), ascending = _b[0], setAscending = _b[1];
39
+ var emptySetting = { ID: 0, Name: '', Value: '', DefaultValue: '' };
40
+ var _c = React.useState(emptySetting), editnewSetting = _c[0], setEditNewSetting = _c[1];
41
+ var _d = React.useState('New'), editNew = _d[0], setEditNew = _d[1];
42
+ var _e = React.useState(false), showModal = _e[0], setShowModal = _e[1];
43
+ var _f = React.useState(false), showWarning = _f[0], setShowWarning = _f[1];
44
+ var _g = React.useState(false), hasChanged = _g[0], setHasChanged = _g[1];
45
+ var _h = React.useState([]), errors = _h[0], setErrors = _h[1];
46
+ React.useEffect(function () {
47
+ if (status === 'unintiated' || status === 'changed')
48
+ dispatch(props.SettingsSlice.Fetch());
49
+ }, [dispatch, status]);
50
+ React.useEffect(function () {
51
+ if (searchStatus === 'unintiated' || status === 'changed')
52
+ dispatch(props.SettingsSlice.DBSearch({ filter: search, sortField: sortField, ascending: ascending }));
53
+ }, [dispatch, searchStatus, ascending, sortField, search]);
54
+ React.useEffect(function () { setHasChanged(false); }, [showModal]);
55
+ React.useEffect(function () {
56
+ var e = [];
57
+ if (editnewSetting.Name == null || editnewSetting.Name.length === 0)
58
+ e.push('A Name is required');
59
+ if (editnewSetting.Name != null && editnewSetting.Name.length > 0 && allSettings.findIndex(function (s) { return s.Name.toLowerCase() === editnewSetting.Name.toLowerCase() && s.ID !== editnewSetting.ID; }) > -1)
60
+ e.push('A Settign with this Name already exists.');
61
+ if (editnewSetting.Value == null || editnewSetting.Value.length === 0)
62
+ e.push('A Value is required');
63
+ setErrors(e);
64
+ }, [editnewSetting]);
65
+ var searchFields = [
66
+ { key: 'Name', label: 'Name', type: 'string', isPivotField: false },
67
+ { key: 'DefaultValue', label: 'Default Value', type: 'string', isPivotField: false },
68
+ { key: 'Value', label: 'Value', type: 'string', isPivotField: false }
69
+ ];
70
+ if (status === 'error')
71
+ return React.createElement("div", { style: { width: '100%', height: '100%' } },
72
+ React.createElement(react_interactive_1.ServerErrorIcon, { Show: true, Label: 'A Server Error Occured. Please Reload the Application' }));
73
+ return (React.createElement(React.Fragment, null,
74
+ React.createElement(react_interactive_1.LoadingScreen, { Show: status === 'loading' }),
75
+ React.createElement("div", { style: { width: '100%', height: '100%' } },
76
+ React.createElement(react_interactive_1.SearchBar, { CollumnList: searchFields, SetFilter: function (flds) { return dispatch(props.SettingsSlice.DBSearch({ filter: flds, sortField: sortField, ascending: ascending })); }, Direction: 'left', defaultCollumn: { key: 'Name', label: 'Name', type: 'string', isPivotField: false }, Width: '50%', Label: 'Search', ShowLoading: searchStatus === 'loading', ResultNote: searchStatus === 'error' ? 'Could not complete Search' : 'Found ' + data.length + ' Settings', GetEnum: function () {
77
+ return function () { };
78
+ } },
79
+ React.createElement("li", { className: "nav-item", style: { width: '15%', paddingRight: 10 } },
80
+ React.createElement("fieldset", { className: "border", style: { padding: '10px', height: '100%' } },
81
+ React.createElement("legend", { className: "w-auto", style: { fontSize: 'large' } }, "Actions:"),
82
+ React.createElement("form", null,
83
+ React.createElement("button", { className: "btn btn-primary", onClick: function (event) { setEditNewSetting(emptySetting); setEditNew('New'); setShowModal(true); event.preventDefault(); } }, "Add Setting"))))),
84
+ React.createElement("div", { style: { width: '100%', height: 'calc( 100% - 136px)' } },
85
+ React.createElement(react_table_1.default, { cols: [
86
+ { key: 'Name', field: 'Name', label: 'Setting Name', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
87
+ { key: 'Value', field: 'Value', label: 'Current Value', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
88
+ { key: 'DefaultValue', field: 'DefaultValue', label: 'Default Value', headerStyle: { width: '20%' }, rowStyle: { width: '20%' } },
89
+ { key: 'scroll', label: '', headerStyle: { width: 17, padding: 0 }, rowStyle: { width: 0, padding: 0 } },
90
+ ], tableClass: "table table-hover", data: data, sortKey: sortField, ascending: ascending, onSort: function (d) {
91
+ if (d.colKey === 'scroll' || d.colField === undefined)
92
+ return;
93
+ if (d.colField === sortField)
94
+ setAscending(!ascending);
95
+ else {
96
+ setAscending(true);
97
+ setSortField(d.colField);
98
+ }
99
+ if (d.colField === sortField)
100
+ dispatch(props.SettingsSlice.DBSearch({ filter: search, sortField: sortField, ascending: true }));
101
+ else
102
+ dispatch(props.SettingsSlice.DBSearch({ filter: search, sortField: d.colField, ascending: ascending }));
103
+ }, onClick: function (item) { setEditNewSetting(item.row); setShowModal(true); setEditNew('Edit'); }, 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 () { return false; } }))),
104
+ React.createElement(react_interactive_1.Modal, { Title: editNew === 'Edit' ? editnewSetting.Name + ' - Setting' : 'Add New Setting', Show: showModal, ShowX: true, Size: 'lg', ShowCancel: editNew === 'Edit', ConfirmText: 'Save', CancelText: 'Delete', CallBack: function (conf, isBtn) {
105
+ if (conf && editNew === 'New')
106
+ dispatch(props.SettingsSlice.DBAction({ verb: 'POST', record: editnewSetting }));
107
+ if (conf && editNew === 'Edit')
108
+ dispatch(props.SettingsSlice.DBAction({ verb: 'PATCH', record: editnewSetting }));
109
+ if (!conf && isBtn)
110
+ setShowWarning(true);
111
+ setShowModal(false);
112
+ }, DisableConfirm: (editNew === 'Edit' && !hasChanged) || errors.length > 0, ConfirmShowToolTip: errors.length > 0, ConfirmToolTipContent: errors.map(function (t, i) { return React.createElement("p", { key: i },
113
+ gpa_symbols_1.CrossMark,
114
+ " ",
115
+ t,
116
+ " "); }) },
117
+ React.createElement("div", { className: "row" },
118
+ React.createElement("div", { className: "col" },
119
+ React.createElement(react_forms_1.Input, { Record: editnewSetting, Field: 'Name', Label: 'Setting Name', Feedback: 'A unique Name is required.', Valid: function (field) { return editnewSetting.Name != null && editnewSetting.Name.length > 0 && allSettings.findIndex(function (s) { return s.Name === editnewSetting.Name && s.ID !== editnewSetting.ID; }) < 0; }, Setter: function (record) { setEditNewSetting(record); setHasChanged(true); } }),
120
+ React.createElement(react_forms_1.Input, { Record: editnewSetting, Field: 'Value', Label: 'Value', Feedback: 'Value is required.', Valid: function (field) { return editnewSetting.Value != null && editnewSetting.Value.length > 0; }, Setter: function (record) { setEditNewSetting(record); setHasChanged(true); } }),
121
+ React.createElement(react_forms_1.Input, { Record: editnewSetting, Field: 'DefaultValue', Label: 'Default Value', Valid: function (field) { return true; }, Setter: function (record) { setEditNewSetting(record); setHasChanged(true); } })))),
122
+ React.createElement(react_interactive_1.Warning, { Title: 'Delete Setting', Message: 'This will Delete this Setting from the System. This can have unintended consequences and cause the System to crash. Are you sure you want to continue?', Show: showWarning, CallBack: function (conf) { if (conf)
123
+ dispatch(props.SettingsSlice.DBAction({ verb: 'DELETE', record: editnewSetting })); setShowWarning(false); } })));
124
+ }
125
+ exports.default = Setting;
@@ -0,0 +1,76 @@
1
+ import { Application } from '@gpa-gemstone/application-typings';
2
+ import { Search } from '@gpa-gemstone/react-interactive';
3
+ import { ActionCreatorWithPayload, AsyncThunk, ActionCreatorWithoutPayload } from '@reduxjs/toolkit';
4
+ declare type DBAction = 'POST' | 'DELETE' | 'PATCH';
5
+ export declare type UserValidation = 'Resolving' | 'Valid' | 'Invalid' | 'Unknown';
6
+ export interface IGenericSlice<T> {
7
+ Fetch: (AsyncThunk<any, void | number, {}>);
8
+ DBAction: (AsyncThunk<any, {
9
+ verb: DBAction;
10
+ record: T;
11
+ }, {}>);
12
+ Sort: ActionCreatorWithPayload<{
13
+ SortField: keyof T;
14
+ Ascending: boolean;
15
+ }, string>;
16
+ Data: (state: any) => T[];
17
+ Status: (state: any) => Application.Types.Status;
18
+ SortField: (state: any) => keyof T;
19
+ Ascending: (state: any) => boolean;
20
+ ParentID?: (state: any) => number | null;
21
+ }
22
+ export interface ISearchableSlice<T> extends IGenericSlice<T> {
23
+ DBSearch: (AsyncThunk<any, {
24
+ filter: Search.IFilter<T>[];
25
+ sortField?: keyof T;
26
+ ascending?: boolean;
27
+ }, {}>);
28
+ SearchFilters: (state: any) => Search.IFilter<T>[];
29
+ SearchResults: (state: any) => T[];
30
+ SearchStatus: (state: any) => Application.Types.Status;
31
+ }
32
+ export interface IAdditionalFieldSlice<F, V> {
33
+ FetchField: AsyncThunk<any, void, {}>;
34
+ FieldAction: AsyncThunk<any, {
35
+ Verb: DBAction;
36
+ Record: F;
37
+ }, {}>;
38
+ FetchValues: AsyncThunk<any, number | string, {}>;
39
+ UpdateValues: AsyncThunk<any, {
40
+ ParentID: number | string;
41
+ Values: V[];
42
+ }, {}>;
43
+ Sort: ActionCreatorWithPayload<{
44
+ SortField: keyof F;
45
+ Ascending: boolean;
46
+ }, string>;
47
+ Fields: (state: any) => F[];
48
+ Values: (state: any) => V[];
49
+ FieldStatus: (state: any) => Application.Types.Status;
50
+ ValueStatus: (state: any) => Application.Types.Status;
51
+ ValueParentId: (state: any) => number | string;
52
+ SortField: (state: any) => keyof F;
53
+ Ascending: (state: any) => boolean;
54
+ }
55
+ export interface IUserAccountSlice extends ISearchableSlice<Application.Types.iUserAccount> {
56
+ ADUpdate: (AsyncThunk<any, void, {}>);
57
+ SetCurrentUser: (AsyncThunk<any, Application.Types.iUserAccount, {}>);
58
+ LoadExistingUser: (AsyncThunk<any, string, {}>);
59
+ SetNewUser: ActionCreatorWithoutPayload;
60
+ CurrentID: (state: any) => string | undefined;
61
+ CurrentUser: (state: any) => Application.Types.iUserAccount;
62
+ ADValidation: (state: any) => UserValidation;
63
+ }
64
+ export interface ISecurityRoleSlice {
65
+ FetchRoles: (AsyncThunk<any, void, {}>);
66
+ FetchUserRoles: (AsyncThunk<any, string, {}>);
67
+ SetUserRoles: (AsyncThunk<any, {
68
+ UserId: string;
69
+ Roles: Application.Types.iApplicationRoleUserAccount[];
70
+ }, {}>);
71
+ Status: (state: any) => Application.Types.Status;
72
+ CurrentRoleStatus: (state: any) => Application.Types.Status;
73
+ Roles: (state: any) => Application.Types.iApplicationRoleUserAccount[];
74
+ AvailableRoles: (state: any) => Application.Types.iApplicationRole<Application.Types.SecurityRoleName>[];
75
+ }
76
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { SystemCenter } from '@gpa-gemstone/application-typings';
3
+ import { IGenericSlice, ISearchableSlice } from '../SliceInterfaces';
4
+ interface IProps {
5
+ OnValueListSelect: (id: number) => void;
6
+ ValueListSlice: ISearchableSlice<SystemCenter.Types.ValueListGroup>;
7
+ ValueListItemSlice: IGenericSlice<SystemCenter.Types.ValueListItem>;
8
+ }
9
+ declare function ByValueListGroup(props: IProps): JSX.Element;
10
+ export default ByValueListGroup;
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ // ******************************************************************************************************
3
+ // ValueList.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/10/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 GroupForm_1 = require("./GroupForm");
40
+ var react_redux_1 = require("react-redux");
41
+ function ByValueListGroup(props) {
42
+ var dispatch = react_redux_1.useDispatch();
43
+ var data = react_redux_1.useSelector(props.ValueListSlice.SearchResults);
44
+ var dataStatus = react_redux_1.useSelector(props.ValueListSlice.SearchStatus);
45
+ var groups = react_redux_1.useSelector(props.ValueListSlice.Data);
46
+ var groupStatus = react_redux_1.useSelector(props.ValueListSlice.Status);
47
+ var _a = React.useState('Name'), sortKey = _a[0], setSortKey = _a[1];
48
+ var _b = React.useState(false), asc = _b[0], setASC = _b[1];
49
+ var emptyRecord = { ID: 0, Name: '', Description: '' };
50
+ var _c = React.useState(false), showNew = _c[0], setShowNew = _c[1];
51
+ var _d = React.useState(emptyRecord), record = _d[0], setRecord = _d[1];
52
+ var items = react_redux_1.useSelector(props.ValueListItemSlice.Data);
53
+ var itemStatus = react_redux_1.useSelector(props.ValueListItemSlice.Status);
54
+ var _e = React.useState([]), search = _e[0], setSearch = _e[1];
55
+ var _f = React.useState([]), newErrors = _f[0], setNewErrors = _f[1];
56
+ var _g = React.useState(true), validName = _g[0], setValidName = _g[1];
57
+ React.useEffect(function () {
58
+ if (dataStatus === 'unintiated' || dataStatus === 'changed')
59
+ dispatch(props.ValueListSlice.DBSearch({ filter: search, sortField: sortKey, ascending: asc }));
60
+ }, [dispatch]);
61
+ React.useEffect(function () {
62
+ dispatch(props.ValueListSlice.DBSearch({ filter: search, sortField: sortKey, ascending: asc }));
63
+ }, [search, asc, sortKey]);
64
+ React.useEffect(function () {
65
+ if (itemStatus === 'unintiated' || itemStatus === 'changed')
66
+ dispatch(props.ValueListItemSlice.Fetch());
67
+ }, [dispatch]);
68
+ React.useEffect(function () {
69
+ if (groupStatus === 'unintiated' || groupStatus === 'changed')
70
+ dispatch(props.ValueListSlice.Fetch());
71
+ }, [dispatch]);
72
+ React.useEffect(function () {
73
+ if (record.Name == null)
74
+ setValidName(true);
75
+ else
76
+ setValidName(groups.findIndex(function (g) { return g.Name.toLowerCase() === record.Name.toLowerCase(); }) < 0);
77
+ }, [record]);
78
+ return (React.createElement("div", { style: { width: '100%', height: '100%' } },
79
+ React.createElement(react_interactive_1.SearchBar, { CollumnList: [{ label: 'Name', key: 'Name', type: 'string', isPivotField: false }], SetFilter: function (flds) { return setSearch(flds); }, Direction: 'left', defaultCollumn: { label: 'Name', key: 'Name', type: 'string', isPivotField: false }, Width: '50%', Label: 'Search', ShowLoading: dataStatus === 'loading' || itemStatus === 'loading', ResultNote: dataStatus === 'error' || itemStatus === 'error' ? 'Could not complete Search' : 'Found ' + data.length + ' Groups', GetEnum: function () { return function () { }; } },
80
+ React.createElement("li", { className: "nav-item", style: { width: '15%', paddingRight: 10 } },
81
+ React.createElement("fieldset", { className: "border", style: { padding: '10px', height: '100%' } },
82
+ React.createElement("legend", { className: "w-auto", style: { fontSize: 'large' } }, "Actions:"),
83
+ React.createElement("form", null,
84
+ React.createElement("button", { className: "btn btn-primary", onClick: function (evt) { evt.preventDefault(); setRecord(__assign({}, emptyRecord)); setShowNew(true); } }, "Add Group"))))),
85
+ React.createElement("div", { style: { width: '100%', height: 'calc( 100% - 136px)' } },
86
+ React.createElement(react_table_1.default, { cols: [
87
+ { key: 'Name', field: 'Name', label: 'Name', headerStyle: { width: '15%' }, rowStyle: { width: '15%' } },
88
+ { key: 'Description', field: 'Description', label: 'Description/Comments', headerStyle: { width: 'auto' }, rowStyle: { width: 'auto' } },
89
+ { key: 'Items', field: 'Items', label: 'Items', headerStyle: { width: '10%' }, rowStyle: { width: '10%' }, content: function (item) { return items.filter(function (i) { return i.GroupID === item.ID; }).length; } },
90
+ { key: 'Scroll', label: '', headerStyle: { width: 17, padding: 0 }, rowStyle: { width: 0, padding: 0 } },
91
+ ], tableClass: "table table-hover", data: data, sortKey: sortKey, ascending: asc, onSort: function (d) {
92
+ if (d.colKey === 'remove' || d.colKey === 'scroll' || d.colField === undefined)
93
+ return;
94
+ setSortKey(d.colField);
95
+ if (d.colField === sortKey)
96
+ setASC(function (b) { return !b; });
97
+ else
98
+ setASC(true);
99
+ }, onClick: function (d) { return props.OnValueListSelect(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; } })),
100
+ React.createElement(react_interactive_1.Modal, { Show: showNew, Title: 'Add new Value List', ShowX: true, ShowCancel: false, DisableConfirm: newErrors.length > 0 || !validName, ConfirmShowToolTip: newErrors.length > 0 || !validName, ConfirmToolTipContent: React.createElement(React.Fragment, null,
101
+ newErrors.map(function (t, i) { return React.createElement("p", { key: i },
102
+ " ",
103
+ gpa_symbols_1.CrossMark,
104
+ " ",
105
+ t); }),
106
+ !validName ? React.createElement("p", null,
107
+ gpa_symbols_1.CrossMark,
108
+ " The Name has to be unique.") : null), CallBack: function (c) {
109
+ setShowNew(false);
110
+ if (c)
111
+ dispatch(props.ValueListSlice.DBAction({ verb: 'POST', record: record }));
112
+ } },
113
+ React.createElement(GroupForm_1.default, { Record: record, Setter: setRecord, ErrorSetter: setNewErrors }))));
114
+ }
115
+ exports.default = ByValueListGroup;