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