@gpa-gemstone/common-pages 0.0.124 → 0.0.126
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 +10 -8
- package/lib/Pipelines/CSVPipeline.d.ts +7 -1
- package/lib/Pipelines/CSVPipeline.js +195 -87
- package/package.json +7 -7
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) {
|
|
@@ -73,7 +74,7 @@ function BulkUpload(props) {
|
|
|
73
74
|
if (props.Step === 'Upload' || props.Step === 'Complete' || currentPipelineIndex == null || currentPipelineIndex > props.Pipelines.length - 1 || props.CurrentPipelineStep > ((_c = (_b = (_a = props.Pipelines) === null || _a === void 0 ? void 0 : _a[currentPipelineIndex]) === null || _b === void 0 ? void 0 : _b.Steps) === null || _c === void 0 ? void 0 : _c.length) - 1)
|
|
74
75
|
return React.createElement(React.Fragment, null);
|
|
75
76
|
var pipeline = props.Pipelines[currentPipelineIndex].Steps[props.CurrentPipelineStep];
|
|
76
|
-
return React.createElement(pipeline.UI, { AdditionalProps: (_d = props.Pipelines[currentPipelineIndex].Steps[props.CurrentPipelineStep]) === null || _d === void 0 ? void 0 : _d.AdditionalProps, RawFileData: rawFileContent, SetData: setData, SetPipelineStep: props.SetCurrentPipelineStep, CurrentPipelineStep: props.CurrentPipelineStep, Errors: pipelineErrors, SetErrors: setPipelineErrors });
|
|
77
|
+
return React.createElement(pipeline.UI, { AdditionalProps: (_d = props.Pipelines[currentPipelineIndex].Steps[props.CurrentPipelineStep]) === null || _d === void 0 ? void 0 : _d.AdditionalProps, RawFileData: rawFileContent, SetData: setData, Data: data, SetPipelineStep: props.SetCurrentPipelineStep, CurrentPipelineStep: props.CurrentPipelineStep, Errors: pipelineErrors, SetErrors: setPipelineErrors });
|
|
77
78
|
}, [props.Step, currentPipelineIndex, rawFileContent, props.CurrentPipelineStep, props.Pipelines]);
|
|
78
79
|
var progressSteps = React.useMemo(function () {
|
|
79
80
|
var _a, _b, _c;
|
|
@@ -113,10 +114,7 @@ function BulkUpload(props) {
|
|
|
113
114
|
return;
|
|
114
115
|
props.OnComplete(data);
|
|
115
116
|
}, [props.Step, data, props.OnComplete]);
|
|
116
|
-
var handleFileUpload = function (
|
|
117
|
-
if (evt.target == null || evt.target.files == null || evt.target.files.length === 0)
|
|
118
|
-
return;
|
|
119
|
-
var file = evt.target.files[0];
|
|
117
|
+
var handleFileUpload = function (file) {
|
|
120
118
|
var matchArray = file.name.match(fileExtRegex);
|
|
121
119
|
var fileExtension = matchArray != null ? matchArray[0].substring(1) : '';
|
|
122
120
|
var pipelineIndex = props.Pipelines.findIndex(function (pipe) { return pipe.Select(file.type, fileExtension); });
|
|
@@ -134,6 +132,12 @@ function BulkUpload(props) {
|
|
|
134
132
|
setRawFileContent(e.target.result);
|
|
135
133
|
};
|
|
136
134
|
};
|
|
135
|
+
var handleFileOnClear = function () {
|
|
136
|
+
setIsFileTypeValid(true);
|
|
137
|
+
setCurrentPipelineIndex(null);
|
|
138
|
+
setFileName(null);
|
|
139
|
+
setRawFileContent(null);
|
|
140
|
+
};
|
|
137
141
|
return (React.createElement("div", { className: "container-fluid d-flex flex-column p-0 h-100" },
|
|
138
142
|
React.createElement("div", { className: 'row h-100' },
|
|
139
143
|
React.createElement("div", { className: 'col-12 d-flex flex-column h-100' },
|
|
@@ -144,9 +148,7 @@ function BulkUpload(props) {
|
|
|
144
148
|
React.createElement(React.Fragment, null,
|
|
145
149
|
React.createElement("div", { className: 'row justify-content-center' },
|
|
146
150
|
React.createElement("div", { className: 'col-6' },
|
|
147
|
-
React.createElement(
|
|
148
|
-
React.createElement("input", { type: "file", className: "custom-file-input", id: "inputGroupFile02", onChange: handleFileUpload, accept: props.FileTypeAttribute, style: { cursor: 'pointer' } }),
|
|
149
|
-
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 }))),
|
|
150
152
|
React.createElement("div", { className: 'row' },
|
|
151
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)))
|
|
152
154
|
: null,
|
|
@@ -2,6 +2,12 @@ import { Gemstone } from '@gpa-gemstone/application-typings';
|
|
|
2
2
|
interface IAdditionalProps<T> {
|
|
3
3
|
Fields: Gemstone.TSX.Interfaces.ICSVField<T>[];
|
|
4
4
|
DataHasHeaders: boolean;
|
|
5
|
+
Headers: string[];
|
|
6
|
+
SetHeaders: (headers: string[]) => void;
|
|
7
|
+
Data: string[][];
|
|
8
|
+
SetData: (d: string[][]) => void;
|
|
9
|
+
HeaderMap: Map<string, keyof T | undefined>;
|
|
10
|
+
SetHeaderMap: (map: Map<string, keyof T | undefined>) => void;
|
|
5
11
|
}
|
|
6
|
-
export declare function useCSVPipeline<T = unknown>(csvFields: Gemstone.TSX.Interfaces.ICSVField<T>[]): Gemstone.TSX.Interfaces.IPipeline<T, IAdditionalProps<T>>;
|
|
12
|
+
export declare function useCSVPipeline<T = unknown, U extends IAdditionalProps<T> = IAdditionalProps<T>>(csvFields: Gemstone.TSX.Interfaces.ICSVField<T>[], additionalSteps?: Gemstone.TSX.Interfaces.IPipelineSteps<T, U>[]): Gemstone.TSX.Interfaces.IPipeline<T, IAdditionalProps<T>>;
|
|
7
13
|
export {};
|
|
@@ -61,49 +61,68 @@ var react_interactive_1 = require("@gpa-gemstone/react-interactive");
|
|
|
61
61
|
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
|
-
var
|
|
64
|
+
var lodash_1 = require("lodash");
|
|
65
65
|
var AdditionalUploadUI = function (props) {
|
|
66
66
|
return (React.createElement("div", { className: 'row justify-content-center m-0' },
|
|
67
67
|
React.createElement("div", { className: 'col-6 p-0' },
|
|
68
68
|
React.createElement(react_forms_1.CheckBox, { Record: { HasHeaders: props.HasHeaders }, Field: "HasHeaders", Setter: function (record) { return props.SetHasHeaders(record.HasHeaders); }, Label: 'My Data Has Headers' }))));
|
|
69
69
|
};
|
|
70
|
-
function useCSVPipeline(csvFields) {
|
|
70
|
+
function useCSVPipeline(csvFields, additionalSteps) {
|
|
71
71
|
var _a = React.useState(false), hasHeaders = _a[0], setHasHeaders = _a[1];
|
|
72
|
+
//Define
|
|
73
|
+
var _b = React.useState([]), headers = _b[0], setHeaders = _b[1];
|
|
74
|
+
var _c = React.useState(new Map()), headerMap = _c[0], setHeaderMap = _c[1];
|
|
75
|
+
var _d = React.useState([]), data = _d[0], setData = _d[1];
|
|
76
|
+
var baseStep = {
|
|
77
|
+
Label: 'Edit CSV',
|
|
78
|
+
UI: CsvPipelineEditStep,
|
|
79
|
+
AdditionalProps: {
|
|
80
|
+
Fields: csvFields,
|
|
81
|
+
DataHasHeaders: hasHeaders,
|
|
82
|
+
Headers: headers,
|
|
83
|
+
SetHeaders: setHeaders,
|
|
84
|
+
Data: data,
|
|
85
|
+
SetData: setData,
|
|
86
|
+
HeaderMap: headerMap,
|
|
87
|
+
SetHeaderMap: setHeaderMap
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var steps = additionalSteps == null ? [baseStep] : __spreadArray([baseStep], additionalSteps, true);
|
|
72
91
|
return {
|
|
73
92
|
Select: function (mimeType, fileExt) { return mimeType.toLowerCase() === 'text/csv' || fileExt === 'csv'; },
|
|
74
|
-
Steps:
|
|
93
|
+
Steps: steps,
|
|
75
94
|
AdditionalUploadUI: React.createElement(AdditionalUploadUI, { HasHeaders: hasHeaders, SetHasHeaders: setHasHeaders })
|
|
76
95
|
};
|
|
77
96
|
}
|
|
78
97
|
function CsvPipelineEditStep(props) {
|
|
79
|
-
var _a, _b;
|
|
98
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
80
99
|
var rawDataRef = React.useRef();
|
|
81
|
-
var
|
|
82
|
-
var
|
|
83
|
-
var
|
|
84
|
-
var
|
|
85
|
-
var
|
|
86
|
-
var
|
|
87
|
-
var
|
|
88
|
-
var
|
|
89
|
-
var _l = React.useState(1), totalPages = _l[0], setTotalPages = _l[1];
|
|
90
|
-
var _m = React.useState(true), showDataHeaderAlert = _m[0], setShowDataHeaderAlert = _m[1];
|
|
91
|
-
var _o = React.useState(true), showDataOrHeaderAlert = _o[0], setShowDataOrHeaderAlert = _o[1];
|
|
100
|
+
var _z = React.useState([]), pagedData = _z[0], setPagedData = _z[1];
|
|
101
|
+
var _0 = React.useState(true), isFileParseable = _0[0], setIsFileParseable = _0[1];
|
|
102
|
+
var _1 = React.useState(false), isCSVMissingHeaders = _1[0], setIsCSVMissingHeaders = _1[1];
|
|
103
|
+
var _2 = React.useState(false), isCSVMissingDataCells = _2[0], setIsCSVMissingDataCells = _2[1];
|
|
104
|
+
var _3 = React.useState(0), page = _3[0], setPage = _3[1];
|
|
105
|
+
var _4 = React.useState(1), totalPages = _4[0], setTotalPages = _4[1];
|
|
106
|
+
var _5 = React.useState(true), showDataHeaderAlert = _5[0], setShowDataHeaderAlert = _5[1];
|
|
107
|
+
var _6 = React.useState(true), showDataOrHeaderAlert = _6[0], setShowDataOrHeaderAlert = _6[1];
|
|
92
108
|
React.useEffect(function () {
|
|
93
|
-
|
|
109
|
+
var _a, _b, _c, _d, _e;
|
|
110
|
+
if (((_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Data.length) === 0)
|
|
94
111
|
return;
|
|
95
|
-
var pages = Math.ceil(
|
|
112
|
+
var pages = Math.ceil(((_c = (_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.Data.length) !== null && _c !== void 0 ? _c : 0) / 10);
|
|
96
113
|
setTotalPages(pages);
|
|
97
|
-
var Data = __spreadArray([],
|
|
114
|
+
var Data = __spreadArray([], ((_e = (_d = props.AdditionalProps) === null || _d === void 0 ? void 0 : _d.Data) !== null && _e !== void 0 ? _e : []), true);
|
|
98
115
|
setPagedData(Data.slice(page * 10, (page + 1) * 10));
|
|
99
|
-
}, [
|
|
116
|
+
}, [(_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Data, page]);
|
|
100
117
|
React.useEffect(function () {
|
|
118
|
+
var _a;
|
|
101
119
|
var errors = [];
|
|
102
120
|
if (props.AdditionalProps == null)
|
|
103
121
|
return;
|
|
122
|
+
var headerMap = (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.HeaderMap;
|
|
104
123
|
props.AdditionalProps.Fields.forEach(function (field) {
|
|
105
|
-
var _a;
|
|
106
|
-
var matchedHeader = (_a = Array.from(headerMap
|
|
124
|
+
var _a, _b, _c, _d, _e;
|
|
125
|
+
var matchedHeader = (_a = Array.from(headerMap).find(function (_a) {
|
|
107
126
|
var value = _a[1];
|
|
108
127
|
return value === field.Field;
|
|
109
128
|
})) === null || _a === void 0 ? void 0 : _a[0];
|
|
@@ -112,59 +131,135 @@ function CsvPipelineEditStep(props) {
|
|
|
112
131
|
errors.push("".concat(field.Label, " is required and must be mapped to a header."));
|
|
113
132
|
return; // return early if the field was never mapped to a header
|
|
114
133
|
}
|
|
115
|
-
var fieldIndex =
|
|
134
|
+
var fieldIndex = (_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.Headers.indexOf(matchedHeader);
|
|
135
|
+
var foundDuplicate = false;
|
|
136
|
+
var foundEmpty = false;
|
|
137
|
+
var foundInvalid = false;
|
|
116
138
|
var uniqueValues = new Set();
|
|
117
139
|
//Need to also make sure that all the fields that have the Required flag got mapped to a header...
|
|
118
|
-
|
|
140
|
+
(_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.Data.forEach(function (row) {
|
|
119
141
|
var value = row[fieldIndex + 1]; //+1 for row index value
|
|
120
|
-
//
|
|
142
|
+
// Unique check
|
|
121
143
|
if (field.Unique) {
|
|
122
144
|
if (uniqueValues.has(value))
|
|
123
|
-
|
|
145
|
+
foundDuplicate = true;
|
|
124
146
|
else
|
|
125
147
|
uniqueValues.add(value);
|
|
126
148
|
}
|
|
127
|
-
//
|
|
128
|
-
if (!field.AllowEmpty && (value == null || (value
|
|
129
|
-
|
|
130
|
-
//
|
|
149
|
+
// Allowed emptiness
|
|
150
|
+
if (!field.AllowEmpty && (value == null || (value.trim() === '')))
|
|
151
|
+
foundEmpty = true;
|
|
152
|
+
// Validate
|
|
131
153
|
if (!field.Validate(value))
|
|
132
|
-
|
|
154
|
+
foundInvalid = true;
|
|
133
155
|
});
|
|
156
|
+
if (field.Unique && foundDuplicate)
|
|
157
|
+
errors.push("All ".concat(field.Label, " values must be unique."));
|
|
158
|
+
if (foundEmpty)
|
|
159
|
+
errors.push("All ".concat(field.Label, " values cannot be empty."));
|
|
160
|
+
if (foundInvalid)
|
|
161
|
+
errors.push("All ".concat(field.Label, " values must be valid."));
|
|
162
|
+
//Check for SameValueForAllRows
|
|
163
|
+
if ((_d = field.SameValueForAllRows) !== null && _d !== void 0 ? _d : false) {
|
|
164
|
+
var allValues = (_e = props.AdditionalProps) === null || _e === void 0 ? void 0 : _e.Data.map(function (row) { var _a; return (_a = row[fieldIndex + 1]) !== null && _a !== void 0 ? _a : ''; });
|
|
165
|
+
if (new Set(allValues).size > 1)
|
|
166
|
+
errors.push("All rows must contain the same value for ".concat(field.Label, "."));
|
|
167
|
+
}
|
|
134
168
|
});
|
|
135
|
-
props.
|
|
136
|
-
|
|
169
|
+
if (!(0, lodash_1.isEqual)(props.Errors.sort(), errors.sort()))
|
|
170
|
+
props.SetErrors(errors);
|
|
171
|
+
}, [(_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.Data, (_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.Headers, (_d = props.AdditionalProps) === null || _d === void 0 ? void 0 : _d.HeaderMap, isFileParseable, (_e = props.AdditionalProps) === null || _e === void 0 ? void 0 : _e.Fields]);
|
|
172
|
+
//Effect to parse rawfiledata initially
|
|
137
173
|
React.useEffect(function () {
|
|
138
|
-
|
|
174
|
+
var _a, _b;
|
|
175
|
+
if (props.RawFileData == null || props.AdditionalProps == null || rawDataRef.current === props.RawFileData || props.AdditionalProps.Data.length !== 0 || props.AdditionalProps.Headers.length !== 0)
|
|
139
176
|
return;
|
|
140
177
|
var parsedData;
|
|
141
178
|
try {
|
|
142
179
|
parsedData = parseCSV(props.RawFileData, props.AdditionalProps.DataHasHeaders, props.AdditionalProps.Fields.filter(function (field) { return field.Required; }).length);
|
|
143
180
|
}
|
|
144
|
-
catch (
|
|
181
|
+
catch (_c) {
|
|
145
182
|
setIsFileParseable(false);
|
|
146
183
|
return;
|
|
147
184
|
}
|
|
148
185
|
setIsFileParseable(true);
|
|
149
186
|
setIsCSVMissingDataCells(parsedData.AddedMissingDataValues);
|
|
150
187
|
setIsCSVMissingHeaders(parsedData.AddedMissingHeaders);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
188
|
+
(_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.SetData(parsedData.Data);
|
|
189
|
+
props.AdditionalProps.SetHeaders(parsedData.Headers);
|
|
190
|
+
(_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.SetHeaderMap(autoMapHeaders(parsedData.Headers, props.AdditionalProps.Fields.map(function (field) { return field.Field; })));
|
|
154
191
|
rawDataRef.current = props.RawFileData;
|
|
155
192
|
}, [props.RawFileData, props.AdditionalProps]);
|
|
193
|
+
//Effect to add additional columns for required fields during mapping process
|
|
194
|
+
React.useEffect(function () {
|
|
195
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
196
|
+
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 || ((_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.Data.length) === 0 || props.AdditionalProps.Headers == null)
|
|
197
|
+
return;
|
|
198
|
+
var requiredCount = props.AdditionalProps.Fields.filter(function (f) { return f.Required; }).length;
|
|
199
|
+
var optionalFields = props.AdditionalProps.Fields.filter(function (f) { return !f.Required; }).map(function (f) { return f.Field; });
|
|
200
|
+
var mappedOptionalCount = 0;
|
|
201
|
+
Array.from((_d = props.AdditionalProps) === null || _d === void 0 ? void 0 : _d.HeaderMap.values()).forEach(function (mappedField) {
|
|
202
|
+
if (mappedField != null && optionalFields.includes(mappedField))
|
|
203
|
+
mappedOptionalCount++;
|
|
204
|
+
});
|
|
205
|
+
var neededCols = requiredCount + mappedOptionalCount;
|
|
206
|
+
if (props.AdditionalProps.Headers.length >= neededCols)
|
|
207
|
+
return;
|
|
208
|
+
// Extend headers (A, B, C, etc.) until we reach 'neededCols'
|
|
209
|
+
var extendedHeaders = __spreadArray([], props.AdditionalProps.Headers, true);
|
|
210
|
+
for (var i = (_e = props.AdditionalProps) === null || _e === void 0 ? void 0 : _e.Headers.length; i < neededCols; i++) {
|
|
211
|
+
extendedHeaders.push(String.fromCharCode(65 + i)); // 'A', 'B', ...
|
|
212
|
+
}
|
|
213
|
+
// Extend every row in 'data' accordingly
|
|
214
|
+
var extendedData = (_f = props.AdditionalProps) === null || _f === void 0 ? void 0 : _f.Data.map(function (row) {
|
|
215
|
+
var currentCols = row.length - 1; // minus the row index at row[0]
|
|
216
|
+
if (currentCols < neededCols)
|
|
217
|
+
return __spreadArray(__spreadArray([], row, true), Array(neededCols - currentCols).fill(''), true);
|
|
218
|
+
return row;
|
|
219
|
+
});
|
|
220
|
+
(_g = props.AdditionalProps) === null || _g === void 0 ? void 0 : _g.SetHeaders(extendedHeaders);
|
|
221
|
+
props.AdditionalProps.SetData(extendedData);
|
|
222
|
+
}, [(_f = props.AdditionalProps) === null || _f === void 0 ? void 0 : _f.Fields, (_g = props.AdditionalProps) === null || _g === void 0 ? void 0 : _g.Headers, (_h = props.AdditionalProps) === null || _h === void 0 ? void 0 : _h.Data, (_j = props.AdditionalProps) === null || _j === void 0 ? void 0 : _j.HeaderMap]);
|
|
223
|
+
//Effect to add additionalFields that cant be determined at build time
|
|
224
|
+
React.useEffect(function () {
|
|
225
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
226
|
+
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 || ((_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.Data.length) === 0 || ((_d = props.AdditionalProps) === null || _d === void 0 ? void 0 : _d.Headers) == null)
|
|
227
|
+
return;
|
|
228
|
+
var requiredCount = props.AdditionalProps.Fields.filter(function (f) { return f.Required; }).length;
|
|
229
|
+
// If we already have enough columns, do nothing
|
|
230
|
+
if (((_e = props.AdditionalProps) === null || _e === void 0 ? void 0 : _e.Headers.length) >= requiredCount)
|
|
231
|
+
return;
|
|
232
|
+
// Extend 'headers' array (e.g., "A", "B", "C"...)
|
|
233
|
+
var extendedHeaders = __spreadArray([], props.AdditionalProps.Headers, true);
|
|
234
|
+
for (var i = (_f = props.AdditionalProps) === null || _f === void 0 ? void 0 : _f.Headers.length; i < requiredCount; i++) {
|
|
235
|
+
extendedHeaders.push(String.fromCharCode(65 + i)); // 'A', 'B', 'C', ...
|
|
236
|
+
}
|
|
237
|
+
// Extend each row in 'data' with blank strings for the new columns
|
|
238
|
+
var extendedData = (_g = props.AdditionalProps) === null || _g === void 0 ? void 0 : _g.Data.map(function (row) {
|
|
239
|
+
// row already has an index at row[0], plus (headers.length - 1) columns
|
|
240
|
+
var neededCols = requiredCount - (row.length - 1);
|
|
241
|
+
if (neededCols > 0) {
|
|
242
|
+
return __spreadArray(__spreadArray([], row, true), Array(neededCols).fill(''), true);
|
|
243
|
+
}
|
|
244
|
+
return row;
|
|
245
|
+
});
|
|
246
|
+
(_h = props.AdditionalProps) === null || _h === void 0 ? void 0 : _h.SetHeaders(extendedHeaders);
|
|
247
|
+
(_j = props.AdditionalProps) === null || _j === void 0 ? void 0 : _j.SetData(extendedData);
|
|
248
|
+
}, [(_k = props.AdditionalProps) === null || _k === void 0 ? void 0 : _k.Fields, (_l = props.AdditionalProps) === null || _l === void 0 ? void 0 : _l.Headers, (_m = props.AdditionalProps) === null || _m === void 0 ? void 0 : _m.Data]);
|
|
156
249
|
React.useEffect(function () {
|
|
250
|
+
var _a;
|
|
157
251
|
if (props.AdditionalProps == null || props.Errors.length !== 0)
|
|
158
252
|
return;
|
|
159
253
|
var mappedData = [];
|
|
160
|
-
|
|
254
|
+
(_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Data.forEach(function (row) {
|
|
255
|
+
var _a;
|
|
161
256
|
var record = {};
|
|
162
|
-
|
|
163
|
-
var _a;
|
|
164
|
-
var mappedField =
|
|
257
|
+
(_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Headers.forEach(function (header, index) {
|
|
258
|
+
var _a, _b;
|
|
259
|
+
var mappedField = (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.HeaderMap.get(header);
|
|
165
260
|
if (mappedField == null)
|
|
166
261
|
return;
|
|
167
|
-
var field = (
|
|
262
|
+
var field = (_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.Fields.find(function (f) { return f.Field === mappedField; });
|
|
168
263
|
if (field == null)
|
|
169
264
|
return;
|
|
170
265
|
var value = row[index + 1];
|
|
@@ -173,35 +268,46 @@ function CsvPipelineEditStep(props) {
|
|
|
173
268
|
mappedData.push(record);
|
|
174
269
|
});
|
|
175
270
|
props.SetData(mappedData);
|
|
176
|
-
}, [
|
|
271
|
+
}, [(_o = props.AdditionalProps) === null || _o === void 0 ? void 0 : _o.Data, (_p = props.AdditionalProps) === null || _p === void 0 ? void 0 : _p.Headers, (_q = props.AdditionalProps) === null || _q === void 0 ? void 0 : _q.HeaderMap, (_r = props.AdditionalProps) === null || _r === void 0 ? void 0 : _r.Fields, props.Errors]);
|
|
177
272
|
var getFieldSelect = React.useCallback(function (header) {
|
|
178
|
-
var _a;
|
|
273
|
+
var _a, _b, _c;
|
|
179
274
|
if (props.AdditionalProps == null || ((_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Fields.length) === 0)
|
|
180
275
|
return;
|
|
181
|
-
var field =
|
|
182
|
-
var
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
setData(function (prevData) {
|
|
191
|
-
var newData = __spreadArray([], prevData, true);
|
|
192
|
-
newData[rowIndex][colIndex] = value;
|
|
193
|
-
return newData;
|
|
276
|
+
var field = (_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.HeaderMap.get(header);
|
|
277
|
+
var usedFields = Array.from((_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.HeaderMap.entries())
|
|
278
|
+
.filter(function (_a) {
|
|
279
|
+
var mappedHeader = _a[0], mappedField = _a[1];
|
|
280
|
+
return mappedHeader !== header && mappedField != null;
|
|
281
|
+
})
|
|
282
|
+
.map(function (_a) {
|
|
283
|
+
var mappedField = _a[1];
|
|
284
|
+
return mappedField;
|
|
194
285
|
});
|
|
195
|
-
|
|
286
|
+
var selectOptions = props.AdditionalProps.Fields
|
|
287
|
+
.filter(function (f) { return !usedFields.includes(f.Field) || f.Field === field; })
|
|
288
|
+
.map(function (f) { return ({ Value: f.Field, Label: f.Label }); });
|
|
289
|
+
var updateMap = function (head, val) { var _a, _b; return (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.SetHeaderMap(new Map((_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.HeaderMap).set(head, val)); };
|
|
290
|
+
var matchedField = props.AdditionalProps.Fields.find(function (f) { return f.Field === field; });
|
|
291
|
+
var help = (matchedField === null || matchedField === void 0 ? void 0 : matchedField.Help) != null ? matchedField === null || matchedField === void 0 ? void 0 : matchedField.Help : undefined;
|
|
292
|
+
return React.createElement(react_forms_1.Select, { Record: { Header: header, Value: field }, EmptyOption: true, Label: ' ', Help: help, Options: selectOptions, Field: "Value", Setter: function (record) { return updateMap(record.Header, record.Value); } });
|
|
293
|
+
}, [(_s = props.AdditionalProps) === null || _s === void 0 ? void 0 : _s.Fields, (_t = props.AdditionalProps) === null || _t === void 0 ? void 0 : _t.HeaderMap]);
|
|
294
|
+
var handleValueChange = React.useCallback(function (rowIndex, colIndex, value) {
|
|
295
|
+
var _a, _b, _c;
|
|
296
|
+
var data = __spreadArray([], ((_b = (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Data) !== null && _b !== void 0 ? _b : []), true);
|
|
297
|
+
data[rowIndex][colIndex] = value;
|
|
298
|
+
(_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.SetData(data);
|
|
299
|
+
}, [(_u = props.AdditionalProps) === null || _u === void 0 ? void 0 : _u.Data]);
|
|
196
300
|
var handleRowDelete = function (rowIndex) {
|
|
197
|
-
var
|
|
301
|
+
var _a, _b, _c;
|
|
302
|
+
var newData = __spreadArray([], ((_b = (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.Data) !== null && _b !== void 0 ? _b : []), true);
|
|
198
303
|
newData.splice(rowIndex, 1);
|
|
199
|
-
|
|
304
|
+
(_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.SetData(newData);
|
|
200
305
|
};
|
|
201
306
|
var getHeader = function (header) {
|
|
307
|
+
var _a;
|
|
202
308
|
if (props.AdditionalProps == null)
|
|
203
309
|
return;
|
|
204
|
-
var mappedField =
|
|
310
|
+
var mappedField = (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.HeaderMap.get(header);
|
|
205
311
|
if (mappedField == null)
|
|
206
312
|
return header;
|
|
207
313
|
var matchedField = props.AdditionalProps.Fields.find(function (field) { return field.Field === mappedField; });
|
|
@@ -225,31 +331,33 @@ function CsvPipelineEditStep(props) {
|
|
|
225
331
|
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
332
|
React.createElement("div", { className: 'row flex-grow-1', style: { overflowY: 'hidden' } },
|
|
227
333
|
React.createElement("div", { className: 'col-12 h-100' },
|
|
228
|
-
React.createElement(react_table_1.
|
|
229
|
-
|
|
230
|
-
return React.createElement(react_table_1.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
334
|
+
React.createElement(react_table_1.Table, { Data: pagedData, key: (_v = props.AdditionalProps) === null || _v === void 0 ? void 0 : _v.Headers.join(','), SortKey: '', Ascending: false, OnSort: function () { }, KeySelector: function (data) { return data[0]; }, TableClass: 'table', TableStyle: { height: '100%', width: ((_x = (_w = props.AdditionalProps) === null || _w === void 0 ? void 0 : _w.Headers.length) !== null && _x !== void 0 ? _x : 0) * 150 } }, (_y = props.AdditionalProps) === null || _y === void 0 ? void 0 :
|
|
335
|
+
_y.Headers.map(function (header, i) {
|
|
336
|
+
return React.createElement(react_table_1.Column, { Key: header, Field: i + 1, AllowSort: false, Content: function (_a) {
|
|
337
|
+
var _b, _c;
|
|
338
|
+
var item = _a.item, field = _a.field;
|
|
339
|
+
if (props.AdditionalProps == null)
|
|
340
|
+
return;
|
|
341
|
+
var mappedField = (_b = props.AdditionalProps) === null || _b === void 0 ? void 0 : _b.HeaderMap.get(header);
|
|
342
|
+
var matchedField = props.AdditionalProps.Fields.find(function (f) { return f.Field === mappedField; });
|
|
343
|
+
if (matchedField == null)
|
|
344
|
+
return item[field];
|
|
345
|
+
var value = item[field];
|
|
346
|
+
var isValid = matchedField.Validate(value);
|
|
347
|
+
var feedback = matchedField.Feedback;
|
|
348
|
+
var selectOptions = matchedField.SelectOptions;
|
|
349
|
+
var allValues = {};
|
|
350
|
+
(_c = props.AdditionalProps) === null || _c === void 0 ? void 0 : _c.Headers.forEach(function (header, index) {
|
|
351
|
+
var _a;
|
|
352
|
+
var mappedField = (_a = props.AdditionalProps) === null || _a === void 0 ? void 0 : _a.HeaderMap.get(header);
|
|
353
|
+
if (mappedField != null) {
|
|
354
|
+
allValues[mappedField] = item[index + 1];
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
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 }));
|
|
358
|
+
} },
|
|
359
|
+
getHeader(header),
|
|
360
|
+
getFieldSelect(header));
|
|
253
361
|
}),
|
|
254
362
|
React.createElement(react_table_1.Column, { Key: 'delete', Field: 0, AllowSort: false, RowStyle: { textAlign: 'right' }, Content: function (_a) {
|
|
255
363
|
var item = _a.item;
|
|
@@ -258,7 +366,7 @@ function CsvPipelineEditStep(props) {
|
|
|
258
366
|
} }, '')))),
|
|
259
367
|
React.createElement("div", { className: 'row' },
|
|
260
368
|
React.createElement("div", { className: 'col-12' },
|
|
261
|
-
React.createElement(
|
|
369
|
+
React.createElement(react_table_1.Paging, { Current: page + 1, Total: totalPages, SetPage: function (p) { return setPage(p - 1); } }))))
|
|
262
370
|
: null)))));
|
|
263
371
|
}
|
|
264
372
|
//Helper functions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gpa-gemstone/common-pages",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.126",
|
|
4
4
|
"description": "Common UI pages for GPA products",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
"typescript": "5.5.3"
|
|
45
45
|
},
|
|
46
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.
|
|
47
|
+
"@gpa-gemstone/application-typings": "0.0.80",
|
|
48
|
+
"@gpa-gemstone/gpa-symbols": "0.0.46",
|
|
49
|
+
"@gpa-gemstone/helper-functions": "0.0.37",
|
|
50
|
+
"@gpa-gemstone/react-forms": "1.1.79",
|
|
51
|
+
"@gpa-gemstone/react-interactive": "1.0.139",
|
|
52
|
+
"@gpa-gemstone/react-table": "1.2.60",
|
|
53
53
|
"@reduxjs/toolkit": "1.8.3",
|
|
54
54
|
"crypto-js": "^4.2.0",
|
|
55
55
|
"moment": "^2.29.4",
|