@gpa-gemstone/common-pages 0.0.123 → 0.0.125
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/lib/BulkUpload.js +17 -13
- package/lib/Pipelines/CSVPipeline.js +69 -26
- package/package.json +61 -61
- package/lib/Setting.d.ts +0 -8
- package/lib/Setting.js +0 -151
- package/lib/TimeFilter.d.ts +0 -28
- package/lib/TimeFilter.js +0 -273
- package/lib/TimeWindowUtils.d.ts +0 -26
- package/lib/TimeWindowUtils.js +0 -110
- package/lib/ValueList/ByValueList.d.ts +0 -10
- package/lib/ValueList/ByValueList.js +0 -141
- package/lib/ValueList/Group.d.ts +0 -11
- package/lib/ValueList/Group.js +0 -97
- package/lib/ValueList/GroupForm.d.ts +0 -9
- package/lib/ValueList/GroupForm.js +0 -74
- package/lib/ValueList/GroupInfo.d.ts +0 -8
- package/lib/ValueList/GroupInfo.js +0 -95
- package/lib/ValueList/GroupItem.d.ts +0 -9
- package/lib/ValueList/GroupItem.js +0 -142
- package/lib/ValueList/ItemForm.d.ts +0 -9
- package/lib/ValueList/ItemForm.js +0 -82
- package/lib/user/AdditionalField.d.ts +0 -26
- package/lib/user/AdditionalField.js +0 -290
- package/lib/user/ByUser.d.ts +0 -12
- package/lib/user/ByUser.js +0 -174
- package/lib/user/User.d.ts +0 -14
- package/lib/user/User.js +0 -97
- package/lib/user/UserForm.d.ts +0 -12
- package/lib/user/UserForm.js +0 -166
- package/lib/user/UserInfo.d.ts +0 -7
- package/lib/user/UserInfo.js +0 -123
- package/lib/user/UserPermissions.d.ts +0 -8
- package/lib/user/UserPermissions.js +0 -106
package/lib/BulkUpload.js
CHANGED
@@ -57,6 +57,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
57
|
exports.default = BulkUpload;
|
58
58
|
var React = __importStar(require("react"));
|
59
59
|
var react_interactive_1 = require("@gpa-gemstone/react-interactive");
|
60
|
+
var react_forms_1 = require("@gpa-gemstone/react-forms");
|
60
61
|
var steps = [{ short: 'Upload', long: 'Upload', id: 'Upload' }, { short: 'Process', long: 'Process', id: 'Process' }, { short: "Review", id: 'Review', long: 'Review' }, { short: 'Complete', long: 'Complete', id: 'Complete' }];
|
61
62
|
var fileExtRegex = /(\.[^.]+)$/;
|
62
63
|
function BulkUpload(props) {
|
@@ -98,12 +99,14 @@ function BulkUpload(props) {
|
|
98
99
|
React.useEffect(function () {
|
99
100
|
var pipelineErrs = props.Step == 'Process' ? pipelineErrors : [];
|
100
101
|
var errors = __spreadArray([], pipelineErrs, true);
|
101
|
-
if (
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
102
|
+
if (props.Step === 'Upload') {
|
103
|
+
if (fileName == null)
|
104
|
+
errors.push('A file must be uploaded to continue');
|
105
|
+
if (rawFileContent == null || rawFileContent == '')
|
106
|
+
errors.push('File content is empty');
|
107
|
+
if (!isFileTypeValid)
|
108
|
+
errors.push("File must be of type ".concat(props.FileTypeAttribute));
|
109
|
+
}
|
107
110
|
props.SetErrors(errors);
|
108
111
|
}, [rawFileContent, fileName, isFileTypeValid, pipelineErrors, props.Step]);
|
109
112
|
React.useEffect(function () {
|
@@ -111,10 +114,7 @@ function BulkUpload(props) {
|
|
111
114
|
return;
|
112
115
|
props.OnComplete(data);
|
113
116
|
}, [props.Step, data, props.OnComplete]);
|
114
|
-
var handleFileUpload = function (
|
115
|
-
if (evt.target == null || evt.target.files == null || evt.target.files.length === 0)
|
116
|
-
return;
|
117
|
-
var file = evt.target.files[0];
|
117
|
+
var handleFileUpload = function (file) {
|
118
118
|
var matchArray = file.name.match(fileExtRegex);
|
119
119
|
var fileExtension = matchArray != null ? matchArray[0].substring(1) : '';
|
120
120
|
var pipelineIndex = props.Pipelines.findIndex(function (pipe) { return pipe.Select(file.type, fileExtension); });
|
@@ -132,6 +132,12 @@ function BulkUpload(props) {
|
|
132
132
|
setRawFileContent(e.target.result);
|
133
133
|
};
|
134
134
|
};
|
135
|
+
var handleFileOnClear = function () {
|
136
|
+
setIsFileTypeValid(true);
|
137
|
+
setCurrentPipelineIndex(null);
|
138
|
+
setFileName(null);
|
139
|
+
setRawFileContent(null);
|
140
|
+
};
|
135
141
|
return (React.createElement("div", { className: "container-fluid d-flex flex-column p-0 h-100" },
|
136
142
|
React.createElement("div", { className: 'row h-100' },
|
137
143
|
React.createElement("div", { className: 'col-12 d-flex flex-column h-100' },
|
@@ -142,9 +148,7 @@ function BulkUpload(props) {
|
|
142
148
|
React.createElement(React.Fragment, null,
|
143
149
|
React.createElement("div", { className: 'row justify-content-center' },
|
144
150
|
React.createElement("div", { className: 'col-6' },
|
145
|
-
React.createElement(
|
146
|
-
React.createElement("input", { type: "file", className: "custom-file-input", id: "inputGroupFile02", onChange: handleFileUpload, accept: props.FileTypeAttribute, style: { cursor: 'pointer' } }),
|
147
|
-
React.createElement("label", { className: "custom-file-label", htmlFor: "inputGroupFile02", "aria-describedby": "inputGroupFileAddon02" }, fileName == null ? 'Upload File' : fileName)))),
|
151
|
+
React.createElement(react_forms_1.FileUpload, { OnLoadHandler: handleFileUpload, OnClearHandler: handleFileOnClear, FileTypeAttribute: props.FileTypeAttribute }))),
|
148
152
|
React.createElement("div", { className: 'row' },
|
149
153
|
React.createElement("div", { className: 'col-12 h-100' }, currentPipelineIndex != null && ((_a = props.Pipelines[currentPipelineIndex]) === null || _a === void 0 ? void 0 : _a.AdditionalUploadUI) != null ? (_b = props.Pipelines[currentPipelineIndex]) === null || _b === void 0 ? void 0 : _b.AdditionalUploadUI : null)))
|
150
154
|
: null,
|
@@ -62,6 +62,7 @@ var react_forms_1 = require("@gpa-gemstone/react-forms");
|
|
62
62
|
var react_table_1 = require("@gpa-gemstone/react-table");
|
63
63
|
var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
|
64
64
|
var react_table_2 = require("@gpa-gemstone/react-table");
|
65
|
+
var lodash_1 = require("lodash");
|
65
66
|
var AdditionalUploadUI = function (props) {
|
66
67
|
return (React.createElement("div", { className: 'row justify-content-center m-0' },
|
67
68
|
React.createElement("div", { className: 'col-6 p-0' },
|
@@ -76,19 +77,19 @@ function useCSVPipeline(csvFields) {
|
|
76
77
|
};
|
77
78
|
}
|
78
79
|
function CsvPipelineEditStep(props) {
|
79
|
-
var _a, _b;
|
80
|
+
var _a, _b, _c, _d;
|
80
81
|
var rawDataRef = React.useRef();
|
81
|
-
var
|
82
|
-
var
|
83
|
-
var
|
84
|
-
var
|
85
|
-
var
|
86
|
-
var
|
87
|
-
var
|
88
|
-
var
|
89
|
-
var
|
90
|
-
var
|
91
|
-
var
|
82
|
+
var _e = React.useState([]), headers = _e[0], setHeaders = _e[1];
|
83
|
+
var _f = React.useState(new Map()), headerMap = _f[0], setHeaderMap = _f[1];
|
84
|
+
var _g = React.useState([]), data = _g[0], setData = _g[1];
|
85
|
+
var _h = React.useState([]), pagedData = _h[0], setPagedData = _h[1];
|
86
|
+
var _j = React.useState(true), isFileParseable = _j[0], setIsFileParseable = _j[1];
|
87
|
+
var _k = React.useState(false), isCSVMissingHeaders = _k[0], setIsCSVMissingHeaders = _k[1];
|
88
|
+
var _l = React.useState(false), isCSVMissingDataCells = _l[0], setIsCSVMissingDataCells = _l[1];
|
89
|
+
var _m = React.useState(0), page = _m[0], setPage = _m[1];
|
90
|
+
var _o = React.useState(1), totalPages = _o[0], setTotalPages = _o[1];
|
91
|
+
var _p = React.useState(true), showDataHeaderAlert = _p[0], setShowDataHeaderAlert = _p[1];
|
92
|
+
var _q = React.useState(true), showDataOrHeaderAlert = _q[0], setShowDataOrHeaderAlert = _q[1];
|
92
93
|
React.useEffect(function () {
|
93
94
|
if (data.length === 0)
|
94
95
|
return;
|
@@ -102,7 +103,7 @@ function CsvPipelineEditStep(props) {
|
|
102
103
|
if (props.AdditionalProps == null)
|
103
104
|
return;
|
104
105
|
props.AdditionalProps.Fields.forEach(function (field) {
|
105
|
-
var _a;
|
106
|
+
var _a, _b;
|
106
107
|
var matchedHeader = (_a = Array.from(headerMap.entries()).find(function (_a) {
|
107
108
|
var value = _a[1];
|
108
109
|
return value === field.Field;
|
@@ -113,27 +114,43 @@ function CsvPipelineEditStep(props) {
|
|
113
114
|
return; // return early if the field was never mapped to a header
|
114
115
|
}
|
115
116
|
var fieldIndex = headers.indexOf(matchedHeader);
|
117
|
+
var foundDuplicate = false;
|
118
|
+
var foundEmpty = false;
|
119
|
+
var foundInvalid = false;
|
116
120
|
var uniqueValues = new Set();
|
117
121
|
//Need to also make sure that all the fields that have the Required flag got mapped to a header...
|
118
122
|
data.forEach(function (row) {
|
119
123
|
var value = row[fieldIndex + 1]; //+1 for row index value
|
120
|
-
//
|
124
|
+
// Unique check
|
121
125
|
if (field.Unique) {
|
122
126
|
if (uniqueValues.has(value))
|
123
|
-
|
127
|
+
foundDuplicate = true;
|
124
128
|
else
|
125
129
|
uniqueValues.add(value);
|
126
130
|
}
|
127
|
-
//
|
128
|
-
if (!field.AllowEmpty && (value == null || (value
|
129
|
-
|
130
|
-
//
|
131
|
+
// Allowed emptiness
|
132
|
+
if (!field.AllowEmpty && (value == null || (value.trim() === '')))
|
133
|
+
foundEmpty = true;
|
134
|
+
// Validate
|
131
135
|
if (!field.Validate(value))
|
132
|
-
|
136
|
+
foundInvalid = true;
|
133
137
|
});
|
138
|
+
if (field.Unique && foundDuplicate)
|
139
|
+
errors.push("All ".concat(field.Label, " values must be unique."));
|
140
|
+
if (foundEmpty)
|
141
|
+
errors.push("All ".concat(field.Label, " cannot be empty."));
|
142
|
+
if (foundInvalid)
|
143
|
+
errors.push("All ".concat(field.Label, " must contain valid values."));
|
144
|
+
//Check for SameValueForAllRows
|
145
|
+
if ((_b = field.SameValueForAllRows) !== null && _b !== void 0 ? _b : false) {
|
146
|
+
var allValues = data.map(function (row) { var _a; return (_a = row[fieldIndex + 1]) !== null && _a !== void 0 ? _a : ''; });
|
147
|
+
if (new Set(allValues).size > 1)
|
148
|
+
errors.push("All rows for ".concat(field.Label, " must contain the same value."));
|
149
|
+
}
|
134
150
|
});
|
135
|
-
props.
|
136
|
-
|
151
|
+
if (!(0, lodash_1.isEqual)(props.Errors.sort(), errors.sort()))
|
152
|
+
props.SetErrors(errors);
|
153
|
+
}, [data, headers, headerMap, isFileParseable, (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Fields]);
|
137
154
|
React.useEffect(function () {
|
138
155
|
if (props.RawFileData == null || props.AdditionalProps == null || rawDataRef.current === props.RawFileData)
|
139
156
|
return;
|
@@ -153,6 +170,31 @@ function CsvPipelineEditStep(props) {
|
|
153
170
|
setHeaderMap(autoMapHeaders(parsedData.Headers, props.AdditionalProps.Fields.map(function (field) { return field.Field; })));
|
154
171
|
rawDataRef.current = props.RawFileData;
|
155
172
|
}, [props.RawFileData, props.AdditionalProps]);
|
173
|
+
React.useEffect(function () {
|
174
|
+
var _a, _b;
|
175
|
+
if (((_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Fields) == null || ((_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.Fields.length) === 0 || data.length === 0)
|
176
|
+
return;
|
177
|
+
var requiredCount = props.AdditionalProps.Fields.filter(function (f) { return f.Required; }).length;
|
178
|
+
// If we already have enough columns, do nothing
|
179
|
+
if (headers.length >= requiredCount)
|
180
|
+
return;
|
181
|
+
// Extend 'headers' array (e.g., "A", "B", "C"...)
|
182
|
+
var extendedHeaders = __spreadArray([], headers, true);
|
183
|
+
for (var i = headers.length; i < requiredCount; i++) {
|
184
|
+
extendedHeaders.push(String.fromCharCode(65 + i)); // 'A', 'B', 'C', ...
|
185
|
+
}
|
186
|
+
// Extend each row in 'data' with blank strings for the new columns
|
187
|
+
var extendedData = data.map(function (row) {
|
188
|
+
// row already has an index at row[0], plus (headers.length - 1) columns
|
189
|
+
var neededCols = requiredCount - (row.length - 1);
|
190
|
+
if (neededCols > 0) {
|
191
|
+
return __spreadArray(__spreadArray([], row, true), Array(neededCols).fill(''), true);
|
192
|
+
}
|
193
|
+
return row;
|
194
|
+
});
|
195
|
+
setHeaders(extendedHeaders);
|
196
|
+
setData(extendedData);
|
197
|
+
}, [(_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.Fields]);
|
156
198
|
React.useEffect(function () {
|
157
199
|
if (props.AdditionalProps == null || props.Errors.length !== 0)
|
158
200
|
return;
|
@@ -173,7 +215,7 @@ function CsvPipelineEditStep(props) {
|
|
173
215
|
mappedData.push(record);
|
174
216
|
});
|
175
217
|
props.SetData(mappedData);
|
176
|
-
}, [data, headers, headerMap, (
|
218
|
+
}, [data, headers, headerMap, (_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.Fields, props.Errors]);
|
177
219
|
var getFieldSelect = React.useCallback(function (header) {
|
178
220
|
var _a;
|
179
221
|
if (props.AdditionalProps == null || ((_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Fields.length) === 0)
|
@@ -185,7 +227,7 @@ function CsvPipelineEditStep(props) {
|
|
185
227
|
"=", matchedField === null || matchedField === void 0 ? void 0 :
|
186
228
|
matchedField.Help) : undefined;
|
187
229
|
return React.createElement(react_forms_1.Select, { Record: { Header: header, Value: field }, EmptyOption: true, Options: props.AdditionalProps.Fields.map(function (field) { return ({ Value: field.Field, Label: field.Label }); }), Field: "Value", Setter: function (record) { return updateMap(record.Header, record.Value); }, Label: ' ', Help: help });
|
188
|
-
}, [(
|
230
|
+
}, [(_d = props.AdditionalProps) === null || _d === void 0 ? void 0 : _d.Fields, headerMap]);
|
189
231
|
var handleValueChange = function (rowIndex, colIndex, value) {
|
190
232
|
setData(function (prevData) {
|
191
233
|
var newData = __spreadArray([], prevData, true);
|
@@ -225,7 +267,7 @@ function CsvPipelineEditStep(props) {
|
|
225
267
|
React.createElement("p", { style: { whiteSpace: 'nowrap' } }, isCSVMissingDataCells ? 'Missing data cells were added to meet the number of required fields.' : 'Missing headers were added to meet the number of required fields.'))))) : null,
|
226
268
|
React.createElement("div", { className: 'row flex-grow-1', style: { overflowY: 'hidden' } },
|
227
269
|
React.createElement("div", { className: 'col-12 h-100' },
|
228
|
-
React.createElement(react_table_1.ConfigurableTable, { Data: pagedData, SortKey: '', Ascending: false, OnSort: function () { }, KeySelector: function (data) { return data[0]; }, TheadStyle: { width: '100%', display: 'table-header-group', }, TbodyStyle: { width: '100%', display: 'block', height: '100%' }, RowStyle: { display: 'table-row', width: '100%', height: 'auto' }, TableStyle: { width: '100%', height: '100%', tableLayout: 'fixed', marginBottom: 0, display: 'block' }, TableClass: 'table', ModalZIndex: 9995 },
|
270
|
+
React.createElement(react_table_1.ConfigurableTable, { Data: pagedData, key: headers.join(','), SortKey: '', Ascending: false, OnSort: function () { }, KeySelector: function (data) { return data[0]; }, TheadStyle: { width: '100%', display: 'table-header-group', }, TbodyStyle: { width: '100%', display: 'block', height: '100%' }, RowStyle: { display: 'table-row', width: '100%', height: 'auto' }, TableStyle: { width: '100%', height: '100%', tableLayout: 'fixed', marginBottom: 0, display: 'block' }, TableClass: 'table', ModalZIndex: 9995 },
|
229
271
|
headers.map(function (header, i) {
|
230
272
|
return React.createElement(react_table_1.ConfigurableColumn, { Key: header, Label: header, Default: true },
|
231
273
|
React.createElement(react_table_1.Column, { Key: header, Field: i + 1, AllowSort: false, Content: function (_a) {
|
@@ -239,6 +281,7 @@ function CsvPipelineEditStep(props) {
|
|
239
281
|
var value = item[field];
|
240
282
|
var isValid = matchedField.Validate(value);
|
241
283
|
var feedback = matchedField.Feedback;
|
284
|
+
var selectOptions = matchedField.SelectOptions;
|
242
285
|
var allValues = {};
|
243
286
|
headers.forEach(function (header, index) {
|
244
287
|
var mappedField = headerMap.get(header);
|
@@ -246,7 +289,7 @@ function CsvPipelineEditStep(props) {
|
|
246
289
|
allValues[mappedField] = item[index + 1];
|
247
290
|
}
|
248
291
|
});
|
249
|
-
return (React.createElement(matchedField.EditComponent, { Value: value, SetValue: function (val) { return handleValueChange(parseInt(item[0]), field, val); }, Valid: isValid, Feedback: feedback, AllRecordValues: allValues }));
|
292
|
+
return (React.createElement(matchedField.EditComponent, { Value: value, SetValue: function (val) { return handleValueChange(parseInt(item[0]), field, val); }, Valid: isValid, Feedback: feedback, AllRecordValues: allValues, SelectOptions: selectOptions }));
|
250
293
|
} },
|
251
294
|
getHeader(header),
|
252
295
|
getFieldSelect(header)));
|
package/package.json
CHANGED
@@ -1,62 +1,62 @@
|
|
1
|
-
{
|
2
|
-
"name": "@gpa-gemstone/common-pages",
|
3
|
-
"version": "0.0.
|
4
|
-
"description": "Common UI pages for GPA products",
|
5
|
-
"main": "lib/index.js",
|
6
|
-
"types": "lib/index.d.ts",
|
7
|
-
"files": ["lib/**/*"],
|
8
|
-
"scripts": {
|
9
|
-
"test": "jest --config jestconfig.json",
|
10
|
-
"build": "tsc",
|
11
|
-
"format": "prettier --write \"src/**/*.tsx\"",
|
12
|
-
"lint": "eslint . --ext .ts,.tsx",
|
13
|
-
"prepare": "npm run build",
|
14
|
-
"prepublishOnly": "npm test && npm run lint",
|
15
|
-
"preversion": "npm run lint",
|
16
|
-
"version": "npm run format && git add -A src",
|
17
|
-
"postversion": "git push && git push --tags"
|
18
|
-
},
|
19
|
-
"repository": {
|
20
|
-
"type": "git",
|
21
|
-
"url": "https://github.com/GridProtectionAlliance/gpa-gemstone.git"
|
22
|
-
},
|
23
|
-
"keywords": [
|
24
|
-
"React",
|
25
|
-
"Interactive",
|
26
|
-
"GSF",
|
27
|
-
"Gemstone",
|
28
|
-
"GridProtectionAlliance"
|
29
|
-
],
|
30
|
-
"author": "GridProtectionAlliance",
|
31
|
-
"license": "MIT",
|
32
|
-
"bugs": {"url": "https://github.com/GridProtectionAlliance/gpa-gemstone/issues"},
|
33
|
-
"homepage": "https://github.com/GridProtectionAlliance/gpa-gemstone#readme",
|
34
|
-
"devDependencies": {
|
35
|
-
"@types/crypto-js": "^4.2.0",
|
36
|
-
"@types/jest": "^27.0.0",
|
37
|
-
"@types/jquery": "3.5.6",
|
38
|
-
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
39
|
-
"@typescript-eslint/parser": "^5.60.0",
|
40
|
-
"eslint": "^8.43.0",
|
41
|
-
"jest": "^29.0.0",
|
42
|
-
"prettier": "^2.3.2",
|
43
|
-
"ts-jest": "^29.0.0",
|
44
|
-
"typescript": "5.5.3"
|
45
|
-
},
|
46
|
-
"dependencies": {
|
47
|
-
"@gpa-gemstone/application-typings": "0.0.
|
48
|
-
"@gpa-gemstone/gpa-symbols": "0.0.
|
49
|
-
"@gpa-gemstone/helper-functions": "0.0.
|
50
|
-
"@gpa-gemstone/react-forms": "1.1.
|
51
|
-
"@gpa-gemstone/react-interactive": "1.0.
|
52
|
-
"@gpa-gemstone/react-table": "1.2.
|
53
|
-
"@reduxjs/toolkit": "1.8.3",
|
54
|
-
"crypto-js": "^4.2.0",
|
55
|
-
"moment": "^2.29.4",
|
56
|
-
"moment-timezone": "0.5.43",
|
57
|
-
"react": "^18.2.0",
|
58
|
-
"react-redux": "8.0.2",
|
59
|
-
"styled-components": "5.3.3"
|
60
|
-
},
|
61
|
-
"publishConfig": {"access": "public"}
|
1
|
+
{
|
2
|
+
"name": "@gpa-gemstone/common-pages",
|
3
|
+
"version": "0.0.125",
|
4
|
+
"description": "Common UI pages for GPA products",
|
5
|
+
"main": "lib/index.js",
|
6
|
+
"types": "lib/index.d.ts",
|
7
|
+
"files": ["lib/**/*"],
|
8
|
+
"scripts": {
|
9
|
+
"test": "jest --config jestconfig.json",
|
10
|
+
"build": "tsc",
|
11
|
+
"format": "prettier --write \"src/**/*.tsx\"",
|
12
|
+
"lint": "eslint . --ext .ts,.tsx",
|
13
|
+
"prepare": "npm run build",
|
14
|
+
"prepublishOnly": "npm test && npm run lint",
|
15
|
+
"preversion": "npm run lint",
|
16
|
+
"version": "npm run format && git add -A src",
|
17
|
+
"postversion": "git push && git push --tags"
|
18
|
+
},
|
19
|
+
"repository": {
|
20
|
+
"type": "git",
|
21
|
+
"url": "https://github.com/GridProtectionAlliance/gpa-gemstone.git"
|
22
|
+
},
|
23
|
+
"keywords": [
|
24
|
+
"React",
|
25
|
+
"Interactive",
|
26
|
+
"GSF",
|
27
|
+
"Gemstone",
|
28
|
+
"GridProtectionAlliance"
|
29
|
+
],
|
30
|
+
"author": "GridProtectionAlliance",
|
31
|
+
"license": "MIT",
|
32
|
+
"bugs": {"url": "https://github.com/GridProtectionAlliance/gpa-gemstone/issues"},
|
33
|
+
"homepage": "https://github.com/GridProtectionAlliance/gpa-gemstone#readme",
|
34
|
+
"devDependencies": {
|
35
|
+
"@types/crypto-js": "^4.2.0",
|
36
|
+
"@types/jest": "^27.0.0",
|
37
|
+
"@types/jquery": "3.5.6",
|
38
|
+
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
39
|
+
"@typescript-eslint/parser": "^5.60.0",
|
40
|
+
"eslint": "^8.43.0",
|
41
|
+
"jest": "^29.0.0",
|
42
|
+
"prettier": "^2.3.2",
|
43
|
+
"ts-jest": "^29.0.0",
|
44
|
+
"typescript": "5.5.3"
|
45
|
+
},
|
46
|
+
"dependencies": {
|
47
|
+
"@gpa-gemstone/application-typings": "0.0.79",
|
48
|
+
"@gpa-gemstone/gpa-symbols": "0.0.46",
|
49
|
+
"@gpa-gemstone/helper-functions": "0.0.37",
|
50
|
+
"@gpa-gemstone/react-forms": "1.1.78",
|
51
|
+
"@gpa-gemstone/react-interactive": "1.0.138",
|
52
|
+
"@gpa-gemstone/react-table": "1.2.59",
|
53
|
+
"@reduxjs/toolkit": "1.8.3",
|
54
|
+
"crypto-js": "^4.2.0",
|
55
|
+
"moment": "^2.29.4",
|
56
|
+
"moment-timezone": "0.5.43",
|
57
|
+
"react": "^18.2.0",
|
58
|
+
"react-redux": "8.0.2",
|
59
|
+
"styled-components": "5.3.3"
|
60
|
+
},
|
61
|
+
"publishConfig": {"access": "public"}
|
62
62
|
}
|
package/lib/Setting.d.ts
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
import * as React from '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): React.JSX.Element;
|
8
|
-
export default Setting;
|
package/lib/Setting.js
DELETED
@@ -1,151 +0,0 @@
|
|
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
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
24
|
-
if (k2 === undefined) k2 = k;
|
25
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
26
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
27
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
28
|
-
}
|
29
|
-
Object.defineProperty(o, k2, desc);
|
30
|
-
}) : (function(o, m, k, k2) {
|
31
|
-
if (k2 === undefined) k2 = k;
|
32
|
-
o[k2] = m[k];
|
33
|
-
}));
|
34
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
35
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
36
|
-
}) : function(o, v) {
|
37
|
-
o["default"] = v;
|
38
|
-
});
|
39
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
40
|
-
if (mod && mod.__esModule) return mod;
|
41
|
-
var result = {};
|
42
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
43
|
-
__setModuleDefault(result, mod);
|
44
|
-
return result;
|
45
|
-
};
|
46
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
47
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
48
|
-
};
|
49
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
50
|
-
var React = __importStar(require("react"));
|
51
|
-
var react_forms_1 = require("@gpa-gemstone/react-forms");
|
52
|
-
var react_table_1 = __importDefault(require("@gpa-gemstone/react-table"));
|
53
|
-
var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
|
54
|
-
var react_interactive_1 = require("@gpa-gemstone/react-interactive");
|
55
|
-
var react_redux_1 = require("react-redux");
|
56
|
-
function Setting(props) {
|
57
|
-
var dispatch = (0, react_redux_1.useDispatch)();
|
58
|
-
var search = (0, react_redux_1.useSelector)(props.SettingsSlice.SearchFilters);
|
59
|
-
var searchStatus = (0, react_redux_1.useSelector)(props.SettingsSlice.SearchStatus);
|
60
|
-
var data = (0, react_redux_1.useSelector)(props.SettingsSlice.SearchResults);
|
61
|
-
var allSettings = (0, react_redux_1.useSelector)(props.SettingsSlice.Data);
|
62
|
-
var status = (0, react_redux_1.useSelector)(props.SettingsSlice.Status);
|
63
|
-
var _a = React.useState('Name'), sortField = _a[0], setSortField = _a[1];
|
64
|
-
var _b = React.useState(true), ascending = _b[0], setAscending = _b[1];
|
65
|
-
var emptySetting = { ID: 0, Name: '', Value: '', DefaultValue: '' };
|
66
|
-
var _c = React.useState(emptySetting), editnewSetting = _c[0], setEditNewSetting = _c[1];
|
67
|
-
var _d = React.useState('New'), editNew = _d[0], setEditNew = _d[1];
|
68
|
-
var _e = React.useState(false), showModal = _e[0], setShowModal = _e[1];
|
69
|
-
var _f = React.useState(false), showWarning = _f[0], setShowWarning = _f[1];
|
70
|
-
var _g = React.useState(false), hasChanged = _g[0], setHasChanged = _g[1];
|
71
|
-
var _h = React.useState([]), errors = _h[0], setErrors = _h[1];
|
72
|
-
React.useEffect(function () {
|
73
|
-
if (status === 'unintiated' || status === 'changed')
|
74
|
-
dispatch(props.SettingsSlice.Fetch());
|
75
|
-
}, [dispatch, status]);
|
76
|
-
React.useEffect(function () {
|
77
|
-
if (searchStatus === 'unintiated' || status === 'changed')
|
78
|
-
dispatch(props.SettingsSlice.DBSearch({ filter: search, sortField: sortField, ascending: ascending }));
|
79
|
-
}, [dispatch, searchStatus, ascending, sortField, search]);
|
80
|
-
React.useEffect(function () { setHasChanged(false); }, [showModal]);
|
81
|
-
React.useEffect(function () {
|
82
|
-
var e = [];
|
83
|
-
if (editnewSetting.Name == null || editnewSetting.Name.length === 0)
|
84
|
-
e.push('A Name is required');
|
85
|
-
if (editnewSetting.Name != null && editnewSetting.Name.length > 0 && allSettings.findIndex(function (s) { return s.Name.toLowerCase() === editnewSetting.Name.toLowerCase() && s.ID !== editnewSetting.ID; }) > -1)
|
86
|
-
e.push('A Settign with this Name already exists.');
|
87
|
-
if (editnewSetting.Value == null || editnewSetting.Value.length === 0)
|
88
|
-
e.push('A Value is required');
|
89
|
-
setErrors(e);
|
90
|
-
}, [editnewSetting]);
|
91
|
-
var searchFields = [
|
92
|
-
{ key: 'Name', label: 'Name', type: 'string', isPivotField: false },
|
93
|
-
{ key: 'DefaultValue', label: 'Default Value', type: 'string', isPivotField: false },
|
94
|
-
{ key: 'Value', label: 'Value', type: 'string', isPivotField: false }
|
95
|
-
];
|
96
|
-
if (status === 'error')
|
97
|
-
return React.createElement("div", { style: { width: '100%', height: '100%' } },
|
98
|
-
React.createElement(react_interactive_1.ServerErrorIcon, { Show: true, Label: 'A Server Error Occured. Please Reload the Application' }));
|
99
|
-
return (React.createElement(React.Fragment, null,
|
100
|
-
React.createElement(react_interactive_1.LoadingScreen, { Show: status === 'loading' }),
|
101
|
-
React.createElement("div", { style: { width: '100%', height: '100%' } },
|
102
|
-
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 () {
|
103
|
-
return function () { };
|
104
|
-
} },
|
105
|
-
React.createElement("li", { className: "nav-item", style: { width: '15%', paddingRight: 10 } },
|
106
|
-
React.createElement("fieldset", { className: "border", style: { padding: '10px', height: '100%' } },
|
107
|
-
React.createElement("legend", { className: "w-auto", style: { fontSize: 'large' } }, "Actions:"),
|
108
|
-
React.createElement("form", null,
|
109
|
-
React.createElement("button", { className: "btn btn-primary", onClick: function (event) { setEditNewSetting(emptySetting); setEditNew('New'); setShowModal(true); event.preventDefault(); } }, "Add Setting"))))),
|
110
|
-
React.createElement("div", { style: { width: '100%', height: 'calc( 100% - 136px)' } },
|
111
|
-
React.createElement(react_table_1.default, { cols: [
|
112
|
-
{ key: 'Name', field: 'Name', label: 'Setting Name', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
|
113
|
-
{ key: 'Value', field: 'Value', label: 'Current Value', headerStyle: { width: '10%' }, rowStyle: { width: '10%' } },
|
114
|
-
{ key: 'DefaultValue', field: 'DefaultValue', label: 'Default Value', headerStyle: { width: '20%' }, rowStyle: { width: '20%' } },
|
115
|
-
{ key: 'scroll', label: '', headerStyle: { width: 17, padding: 0 }, rowStyle: { width: 0, padding: 0 } },
|
116
|
-
], tableClass: "table table-hover", data: data, sortKey: sortField, ascending: ascending, onSort: function (d) {
|
117
|
-
if (d.colKey === 'scroll' || d.colField === undefined)
|
118
|
-
return;
|
119
|
-
if (d.colField === sortField)
|
120
|
-
setAscending(!ascending);
|
121
|
-
else {
|
122
|
-
setAscending(true);
|
123
|
-
setSortField(d.colField);
|
124
|
-
}
|
125
|
-
if (d.colField === sortField)
|
126
|
-
dispatch(props.SettingsSlice.DBSearch({ filter: search, sortField: sortField, ascending: true }));
|
127
|
-
else
|
128
|
-
dispatch(props.SettingsSlice.DBSearch({ filter: search, sortField: d.colField, ascending: ascending }));
|
129
|
-
}, 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; } }))),
|
130
|
-
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) {
|
131
|
-
if (conf && editNew === 'New')
|
132
|
-
dispatch(props.SettingsSlice.DBAction({ verb: 'POST', record: editnewSetting }));
|
133
|
-
if (conf && editNew === 'Edit')
|
134
|
-
dispatch(props.SettingsSlice.DBAction({ verb: 'PATCH', record: editnewSetting }));
|
135
|
-
if (!conf && isBtn)
|
136
|
-
setShowWarning(true);
|
137
|
-
setShowModal(false);
|
138
|
-
}, DisableConfirm: (editNew === 'Edit' && !hasChanged) || errors.length > 0, ConfirmShowToolTip: errors.length > 0, ConfirmToolTipContent: errors.map(function (t, i) { return React.createElement("p", { key: i },
|
139
|
-
gpa_symbols_1.CrossMark,
|
140
|
-
" ",
|
141
|
-
t,
|
142
|
-
" "); }) },
|
143
|
-
React.createElement("div", { className: "row" },
|
144
|
-
React.createElement("div", { className: "col" },
|
145
|
-
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); } }),
|
146
|
-
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); } }),
|
147
|
-
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); } })))),
|
148
|
-
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)
|
149
|
-
dispatch(props.SettingsSlice.DBAction({ verb: 'DELETE', record: editnewSetting })); setShowWarning(false); } })));
|
150
|
-
}
|
151
|
-
exports.default = Setting;
|
package/lib/TimeFilter.d.ts
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
import * as React from 'react';
|
2
|
-
import { IStartEnd, IStartDuration, IEndDuration, ICenterDuration, TimeUnit } from './TimeWindowUtils';
|
3
|
-
import { DateUnit } from './TimeFilter/QuickSelects';
|
4
|
-
export type ITimeFilter = IStartEnd | IStartDuration | IEndDuration | ICenterDuration;
|
5
|
-
export declare function getTimeWindow(flt: ITimeFilter, format?: string): {
|
6
|
-
center: string;
|
7
|
-
start: string;
|
8
|
-
end: string;
|
9
|
-
unit: TimeUnit;
|
10
|
-
duration: number;
|
11
|
-
halfDuration: number;
|
12
|
-
};
|
13
|
-
/**
|
14
|
-
* filter: an interface of IStartEnd | IStartDuration | IEndDuration | ICenterDuration
|
15
|
-
* showQuickSelect: displays Quick Select component
|
16
|
-
* isHorizontal: displays Quick Selects in horizontal view
|
17
|
-
*/
|
18
|
-
interface IProps {
|
19
|
-
filter: ITimeFilter;
|
20
|
-
setFilter: (center: string, start: string, end: string, unit: TimeUnit, duration: number) => void;
|
21
|
-
showQuickSelect: boolean;
|
22
|
-
dateTimeSetting: 'center' | 'startWindow' | 'endWindow' | 'startEnd';
|
23
|
-
timeZone: string;
|
24
|
-
isHorizontal: boolean;
|
25
|
-
format?: DateUnit;
|
26
|
-
}
|
27
|
-
declare const TimeFilter: (props: IProps) => React.JSX.Element;
|
28
|
-
export default TimeFilter;
|