lhcb-ntuple-wizard-test 0.0.1

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.
Files changed (41) hide show
  1. package/COPYING +674 -0
  2. package/README.md +79 -0
  3. package/dist/components/App.js +99 -0
  4. package/dist/components/ConfigDict.js +103 -0
  5. package/dist/components/ConfigList.js +94 -0
  6. package/dist/components/ConfigNode.js +323 -0
  7. package/dist/components/ConfigValue.js +85 -0
  8. package/dist/components/Dataset.js +67 -0
  9. package/dist/components/Decay.js +51 -0
  10. package/dist/components/DecayItem.js +101 -0
  11. package/dist/components/DecayTag.js +50 -0
  12. package/dist/components/DecayTree.js +452 -0
  13. package/dist/components/DecaysList.js +108 -0
  14. package/dist/components/DeleteButton.js +56 -0
  15. package/dist/components/DescriptorsSearch.js +351 -0
  16. package/dist/components/EventTypeBadge.js +42 -0
  17. package/dist/components/ItemSearch.js +119 -0
  18. package/dist/components/LinesTable.js +1111 -0
  19. package/dist/components/NtupleWizard.js +141 -0
  20. package/dist/components/ParticleTag.js +52 -0
  21. package/dist/components/PolarityBadge.js +35 -0
  22. package/dist/components/SearchItem.js +100 -0
  23. package/dist/components/SelectParticle.js +61 -0
  24. package/dist/components/SelectTag.js +66 -0
  25. package/dist/components/SelectTool.js +59 -0
  26. package/dist/components/SelectVariables.js +105 -0
  27. package/dist/components/StrippingBadge.js +62 -0
  28. package/dist/components/StrippingLine.js +48 -0
  29. package/dist/components/TupleTool.js +46 -0
  30. package/dist/components/VariablesSearch.js +127 -0
  31. package/dist/components/YearBadge.js +35 -0
  32. package/dist/config.json +70 -0
  33. package/dist/contexts/MetadataContext.js +134 -0
  34. package/dist/index.js +18 -0
  35. package/dist/lib/BKPath.js +58 -0
  36. package/dist/lib/DTTConfig.js +174 -0
  37. package/dist/lib/analysisHelpers.js +30 -0
  38. package/dist/lib/mathjax.js +35 -0
  39. package/dist/lib/utils.js +191 -0
  40. package/dist/style/DecaysList.css +15 -0
  41. package/package.json +66 -0
@@ -0,0 +1,1111 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _emailValidator = _interopRequireDefault(require("email-validator"));
8
+ var _jsYaml = _interopRequireDefault(require("js-yaml"));
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ var _react = _interopRequireDefault(require("react"));
11
+ var _reactBootstrap = require("react-bootstrap");
12
+ var _reactBootstrapIcons = require("react-bootstrap-icons");
13
+ var _reactRouterDom = require("react-router-dom");
14
+ var _reactSelect = _interopRequireDefault(require("react-select"));
15
+ var _creatable = _interopRequireDefault(require("react-select/creatable"));
16
+ var _MetadataContext = _interopRequireDefault(require("../contexts/MetadataContext"));
17
+ var _BKPath = _interopRequireDefault(require("../lib/BKPath"));
18
+ var _DTTConfig = _interopRequireDefault(require("../lib/DTTConfig"));
19
+ var _analysisHelpers = _interopRequireDefault(require("../lib/analysisHelpers"));
20
+ var _utils = require("../lib/utils");
21
+ var _Dataset = _interopRequireDefault(require("./Dataset"));
22
+ var _Decay = _interopRequireDefault(require("./Decay"));
23
+ var _DeleteButton = _interopRequireDefault(require("./DeleteButton"));
24
+ var _StrippingLine = _interopRequireDefault(require("./StrippingLine"));
25
+ var _jsxRuntime = require("react/jsx-runtime");
26
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
28
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
29
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /*****************************************************************************\
30
+ * (c) Copyright 2021-2024 CERN for the benefit of the LHCb Collaboration *
31
+ * *
32
+ * This software is distributed under the terms of the GNU General Public *
33
+ * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
34
+ * *
35
+ * In applying this licence, CERN does not waive the privileges and immunities *
36
+ * granted to it by virtue of its status as an Intergovernmental Organization *
37
+ * or submit itself to any jurisdiction. *
38
+ \*****************************************************************************/
39
+ function streamLinesToOption(row) {
40
+ let opts = {};
41
+ let streamArr = [];
42
+ let lineArr = [];
43
+ let groups = [];
44
+ Object.keys(row.decay.lines).forEach(streamLine => {
45
+ const [stream, line] = streamLine.split("/");
46
+ streamArr.push(stream);
47
+ lineArr.push(line);
48
+ });
49
+ const uniqStreamArr = [...new Set(streamArr)];
50
+ uniqStreamArr.forEach(uniq => {
51
+ opts[uniq] = [];
52
+ lineArr.forEach((element, index) => {
53
+ if (streamArr[index] === uniq) {
54
+ let dup = false;
55
+ const opt = {
56
+ value: element,
57
+ label: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StrippingLine.default, {
58
+ line: element,
59
+ stream: uniq,
60
+ versions: row.decay.lines[uniq + "/" + element]
61
+ }),
62
+ group: uniq
63
+ };
64
+ opts[uniq].forEach(obj => {
65
+ if (obj["label"] === element) {
66
+ dup = true;
67
+ }
68
+ });
69
+ if (!dup) {
70
+ opts[uniq].push(opt);
71
+ }
72
+ }
73
+ });
74
+ groups.push({
75
+ label: uniq,
76
+ options: opts[uniq]
77
+ });
78
+ });
79
+ return groups;
80
+ }
81
+ function pathToOption(path) {
82
+ return Object({
83
+ value: path,
84
+ label: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Dataset.default, {
85
+ path: path
86
+ })
87
+ });
88
+ }
89
+ class LinesTable extends _react.default.Component {
90
+ constructor(props) {
91
+ super(props);
92
+ _defineProperty(this, "state", {
93
+ rows: this.props.rows.map(row => ({
94
+ ...row,
95
+ dtt: row.dtt ? new _DTTConfig.default(row.dtt, []) : false
96
+ })),
97
+ showUploadModal: false,
98
+ showProdUploadModal: false,
99
+ prodUploadLoading: false,
100
+ modalID: -99,
101
+ productionName: this.props.name,
102
+ contactEmail: this.props.email,
103
+ reasonForRequest: this.props.reasonForRequest,
104
+ submitLocation: this.props.submitLocation,
105
+ hideDownloadButtons: this.props.hideDownloadButtons,
106
+ hideUploadButtons: this.props.hideUploadButtons,
107
+ requestLoading: false,
108
+ requestSubmitted: false,
109
+ emailIsKnown: this.props.emailIsKnown,
110
+ csrfToken: this.props.csrfToken,
111
+ showReasonForRequestModal: false,
112
+ requestReasonMessage: this.props.requestReasonMessage,
113
+ requestSubmittedMessage: this.props.requestSubmittedMessage
114
+ });
115
+ _defineProperty(this, "handleSubmitRows", history => {
116
+ let rows = [...this.state.rows];
117
+ rows.forEach(row => {
118
+ row.editTree = true;
119
+ });
120
+ this.props.parentCallbackRows(rows);
121
+ this.props.parentCallbackInfo(this.state.productionName, this.state.contactEmail, this.state.reasonForRequest);
122
+ history.push(this.propsVar.variablesPath);
123
+ });
124
+ _defineProperty(this, "handleSubmitSpecificRow", (history, idx) => {
125
+ let rows = [...this.state.rows];
126
+ rows.forEach(row => {
127
+ row.editTree = row.id === idx;
128
+ });
129
+ this.props.parentCallbackRows(rows);
130
+ this.props.parentCallbackInfo(this.state.productionName, this.state.contactEmail, this.state.reasonForRequest);
131
+ history.push(this.propsVar.variablesPath);
132
+ });
133
+ _defineProperty(this, "handleAddRow", history => {
134
+ let rows = [...this.state.rows];
135
+ this.props.parentCallbackRows(rows);
136
+ this.props.parentCallbackInfo(this.state.productionName, this.state.contactEmail, this.state.reasonForRequest);
137
+ history.push(this.propsVar.decaysPath);
138
+ });
139
+ _defineProperty(this, "handleRemoveSpecificRow", id => () => {
140
+ let rows = [...this.state.rows];
141
+ rows = rows.filter(row => row.id !== id);
142
+ this.setState({
143
+ rows
144
+ });
145
+ this.props.parentCallbackRows(rows);
146
+ });
147
+ _defineProperty(this, "handleRemoveSpecificRowDTT", id => () => {
148
+ let rows = [...this.state.rows];
149
+ const index = this.state.rows.findIndex(item => item.id === id);
150
+ rows[index].dtt = false;
151
+ this.setState({
152
+ rows
153
+ });
154
+ this.props.parentCallbackRows(rows);
155
+ });
156
+ _defineProperty(this, "handleCreateDTT", id => () => {
157
+ let rows = [...this.state.rows];
158
+ const index = this.state.rows.findIndex(item => item.id === id);
159
+ rows[index].dtt = _DTTConfig.default.createDTT(rows[index].decay.descriptors.template, rows[index].decay.descriptors.mapped_list.flat(Infinity), [], "", this.context.metadata.tupleTools.tupleTools);
160
+ this.setInputs(id, rows[index].lines);
161
+ this.setState({
162
+ rows
163
+ });
164
+ this.props.parentCallbackRows(rows);
165
+ });
166
+ _defineProperty(this, "validateDTTIsSetForAllRows", () => {
167
+ return this.state.rows.every(row => row.dtt);
168
+ });
169
+ _defineProperty(this, "setInputs", (id, lines) => {
170
+ let rows = [...this.state.rows];
171
+ const index = this.state.rows.findIndex(item => item.id === id);
172
+ const inputs = lines.map(_ref => {
173
+ let {
174
+ stream,
175
+ line
176
+ } = _ref;
177
+ const lineLocation = String(line).replace("Stripping", "");
178
+ return "/Event/".concat(stream, "/Phys/").concat(lineLocation, "/Particles");
179
+ });
180
+ rows[index].dtt.setInputs(inputs);
181
+ this.setState({
182
+ rows
183
+ });
184
+ this.props.parentCallbackRows(rows);
185
+ });
186
+ _defineProperty(this, "changeSelStrLines", id => choices => {
187
+ let rows = [...this.state.rows];
188
+ const index = this.state.rows.findIndex(item => item.id === id); // All choices have the same value (row.id)
189
+
190
+ rows[index].lines = choices.map(choice => Object({
191
+ stream: choice.group,
192
+ line: choice.value,
193
+ versions: this.state.rows[index].decay.lines[choice.group + "/" + choice.value]
194
+ }));
195
+ this.setState({
196
+ rows
197
+ });
198
+ this.pathChoiceHandler(id)(rows[index].paths.map(path => ({
199
+ value: path
200
+ })));
201
+ if (rows[index].dtt) {
202
+ this.setInputs(id, rows[index].lines);
203
+ }
204
+ });
205
+ _defineProperty(this, "validatePath", (choice, lines) => {
206
+ const path = new _BKPath.default(choice);
207
+ if (!path.isValid()) {
208
+ return false;
209
+ }
210
+ return lines.every(line => {
211
+ const streamName = line.stream.toLowerCase();
212
+ const filename = path.getFilename().split(".")[0].toLowerCase();
213
+ const matchingVersion = line.versions.some(version => path.getStrippingVersion() === version);
214
+ return ["allstreams", streamName].includes(filename) && matchingVersion;
215
+ });
216
+ });
217
+ _defineProperty(this, "pathChoiceHandler", id => choices => {
218
+ let rows = [...this.state.rows];
219
+ const index = this.state.rows.findIndex(item => item.id === id); // All choices have the same value (row.id)
220
+ const validPaths = choices.filter(choice => this.validatePath(choice.value, this.state.rows[index].lines)).map(choice => choice.value);
221
+ const validPathOptions = rows[index].pathOptions.filter(choice => this.validatePath(choice, this.state.rows[index].lines));
222
+ rows[index].paths = validPaths;
223
+ rows[index].pathOptions = validPathOptions;
224
+ this.setState({
225
+ rows
226
+ });
227
+ this.props.parentCallbackRows(rows);
228
+ });
229
+ _defineProperty(this, "pathCreateHandler", id => choice => {
230
+ let rows = [...this.state.rows];
231
+ const index = this.state.rows.findIndex(item => item.id === id); // All choices have the same value (row.id)
232
+ if (this.validatePath(choice.value, this.state.rows[index].lines)) {
233
+ rows[index].paths.push(choice.value);
234
+ rows[index].pathOptions.push(choice.value);
235
+ }
236
+ this.setState({
237
+ rows
238
+ });
239
+ });
240
+ _defineProperty(this, "setRowName", id => _ref2 => {
241
+ let {
242
+ target
243
+ } = _ref2;
244
+ let rows = [...this.state.rows];
245
+ const index = this.state.rows.findIndex(item => item.id === id);
246
+ rows[index].dtt.setName(target.value);
247
+ this.setState({
248
+ rows
249
+ });
250
+ this.props.parentCallbackRows(rows);
251
+ });
252
+ _defineProperty(this, "setProductionName", _ref3 => {
253
+ let {
254
+ target
255
+ } = _ref3;
256
+ const safeName = target.value.replaceAll(/[^\w]/g, "");
257
+ this.setState({
258
+ productionName: safeName
259
+ });
260
+ this.props.parentCallbackInfo(safeName, this.state.contactEmail, this.state.reasonForRequest);
261
+ });
262
+ _defineProperty(this, "setContactEmail", _ref4 => {
263
+ let {
264
+ target
265
+ } = _ref4;
266
+ const emails = target.value.split(/[\s,]+/);
267
+ this.setState({
268
+ contactEmail: emails
269
+ });
270
+ const validEmails = emails.filter(email => _emailValidator.default.validate(email));
271
+ this.props.parentCallbackInfo(this.state.productionName, validEmails, this.state.reasonForRequest);
272
+ });
273
+ _defineProperty(this, "setReasonForRequest", _ref5 => {
274
+ let {
275
+ target
276
+ } = _ref5;
277
+ const reasonForRequest = target.value;
278
+ this.setState({
279
+ reasonForRequest: reasonForRequest
280
+ });
281
+ this.props.parentCallbackInfo(this.state.productionName, this.state.contactEmail, reasonForRequest);
282
+ });
283
+ _defineProperty(this, "clearAll", () => {
284
+ this.setState({
285
+ productionName: "",
286
+ contactEmail: [],
287
+ rows: [],
288
+ reasonForRequest: ""
289
+ });
290
+ this.props.parentCallbackRows([]);
291
+ this.props.parentCallbackInfo("", [], "");
292
+ });
293
+ _defineProperty(this, "getBKPaths", id => {
294
+ const index = this.state.rows.findIndex(item => item.id === id);
295
+ const row = this.state.rows[index];
296
+ const options = row.paths.map(path => pathToOption(path));
297
+ return options;
298
+ });
299
+ _defineProperty(this, "defaultBKPaths", id => {
300
+ const index = this.state.rows.findIndex(item => item.id === id);
301
+ const row = this.state.rows[index];
302
+ const defaultOptions = this.context.loaded.dataset ? this.context.metadata.dataset.filter(path => this.validatePath(path, row.lines)).map(path => pathToOption(path)) : [];
303
+ const options = row.pathOptions.map(path => pathToOption(path));
304
+ return [].concat(defaultOptions, options);
305
+ });
306
+ _defineProperty(this, "createInfoYaml", () => {
307
+ const rows = [...this.state.rows];
308
+ const uniquePaths = new Set([].concat(...rows.map(row => row.paths)));
309
+ let email = this.state.contactEmail;
310
+ if (this.state.emailIsKnown) {
311
+ email = [localStorage.getItem("email")] || [];
312
+ }
313
+ const uniquePathList = [...uniquePaths].sort();
314
+ let info = {
315
+ defaults: {
316
+ application: "DaVinci/" + this.context.metadata.tupleTools.applicationInfo["DaVinci"],
317
+ wg: "OpenData",
318
+ // TODO: get input from (LHCb) user. keep "OpenData" if open data
319
+ automatically_configure: true,
320
+ inform: email,
321
+ output: "DVNtuple.root" // Probably okay to leave this as the default
322
+ }
323
+ };
324
+ rows.forEach(row => {
325
+ row.paths.forEach((path, _index) => {
326
+ const jobID = uniquePathList.findIndex(otherPath => otherPath === path);
327
+ const key = "job".concat(jobID);
328
+ const dttFile = "".concat(row.dtt.getSafeName(), ".py");
329
+ if (key in info) {
330
+ info[key].options.push(dttFile);
331
+ } else {
332
+ info[key] = {
333
+ input: {
334
+ bk_query: path
335
+ },
336
+ options: [dttFile] // TODO: figure out the actual syntax that AnaProd needs to indicate that this is to be parsed into a DecayTreeTuple
337
+ };
338
+ if (path.includes("MDST")) {
339
+ const stream = row.lines[0].stream; // XXX: in the validation we enforce that each BK location be compatible with every line, so effectively forcing one stream per row
340
+ info[key].root_in_tes = "/Event/".concat(stream);
341
+ }
342
+ }
343
+ });
344
+ });
345
+ return info;
346
+ });
347
+ _defineProperty(this, "uploadConfig", (e, id) => {
348
+ let rows = [...this.state.rows];
349
+ const index = this.state.rows.findIndex(item => item.id === id);
350
+ e.preventDefault();
351
+ const reader = new FileReader();
352
+ reader.onload = async e => {
353
+ const text = e.target.result;
354
+ const config = _jsYaml.default.load(text);
355
+ if (config.descriptorTemplate === rows[index].decay.descriptors.template) {
356
+ rows[index].dtt = new _DTTConfig.default(config, []);
357
+ this.setInputs(id, rows[index].lines);
358
+ this.setState({
359
+ rows,
360
+ showUploadModal: false
361
+ });
362
+ this.props.parentCallbackRows(rows);
363
+ } else {
364
+ alert("Make sure to upload a previously downloaded configuration file for the same decay.");
365
+ }
366
+ };
367
+ reader.readAsText(e.target.files[0]);
368
+ });
369
+ _defineProperty(this, "uploadProductionConfig", async (e, isClone) => {
370
+ let rows = [];
371
+ let decays = Object.values(this.context.metadata.decays);
372
+ let email = [];
373
+ //let descriptorTemplates = decays.descriptors.template
374
+
375
+ let filelist = e.target.files || [];
376
+ let files = [].slice.call(filelist);
377
+ if (files.length) {
378
+ for (let index = 0; index < files.length; index++) {
379
+ if (files[index].name === "info.yaml") {
380
+ files.push(files.splice(index, 1)[0]);
381
+ break;
382
+ }
383
+ }
384
+ for (let index = 0; index < files.length; index++) {
385
+ let text;
386
+ if (isClone) {
387
+ text = await this.readFileAsync(files[index].blob);
388
+ } else {
389
+ text = await this.readFileAsync(files[index]);
390
+ }
391
+ const config = _jsYaml.default.load(text);
392
+ if (files[index].name !== "info.yaml") {
393
+ decays.forEach(decay => {
394
+ if (config.descriptorTemplate === decay.descriptors.template) {
395
+ let row = Object({
396
+ id: index,
397
+ decay: decay,
398
+ lines: config.inputs.map(input => Object({
399
+ stream: input.split("/")[2],
400
+ line: "Stripping" + input.split("/")[4],
401
+ versions: decay.lines[input.split("/")[2] + "/" + "Stripping" + input.split("/")[4]]
402
+ })),
403
+ paths: [],
404
+ // Currently-selected paths
405
+ pathOptions: [],
406
+ // Keep a history of valid paths
407
+ dtt: new _DTTConfig.default(config, [])
408
+ });
409
+ rows.push(row);
410
+ }
411
+ });
412
+ } else {
413
+ email.push(config.defaults.inform[0]);
414
+ rows.forEach(row => {
415
+ Object.keys(config).forEach(job => {
416
+ if (job !== "defaults" && job !== "name" && job !== "blob") {
417
+ config[job].options.forEach(option => {
418
+ let optionName = option.split(".")[0];
419
+ let dttname = row.dtt.config.name.split("/")[1];
420
+ if (optionName === dttname) {
421
+ row.paths.push(config[job].input.bk_query);
422
+ }
423
+ });
424
+ }
425
+ });
426
+ });
427
+ }
428
+ }
429
+ }
430
+ this.setState({
431
+ rows: rows
432
+ });
433
+ if (!isClone) {
434
+ this.setState({
435
+ contactEmail: email
436
+ });
437
+ }
438
+ this.props.parentCallbackRows(rows);
439
+ this.props.parentCallbackInfo(this.state.productionName, this.state.contactEmail, this.state.reasonForRequest);
440
+ // this.handleCloseProdUploadModal();
441
+ });
442
+ _defineProperty(this, "readFileAsync", file => {
443
+ return new Promise((resolve, reject) => {
444
+ const reader = new FileReader();
445
+ reader.onload = function () {
446
+ resolve(reader.result);
447
+ };
448
+ reader.onerror = function (error) {
449
+ reject(error);
450
+ };
451
+ reader.readAsText(file);
452
+ });
453
+ });
454
+ _defineProperty(this, "handleShowUploadModal", id => {
455
+ this.setState({
456
+ showUploadModal: true,
457
+ modalID: id
458
+ });
459
+ });
460
+ _defineProperty(this, "handleCloseUploadModal", () => {
461
+ this.setState({
462
+ showUploadModal: false
463
+ });
464
+ });
465
+ _defineProperty(this, "handleShowProdUploadModal", () => {
466
+ this.setState({
467
+ showProdUploadModal: true
468
+ });
469
+ });
470
+ _defineProperty(this, "handleCloseProdUploadModal", () => {
471
+ this.setState({
472
+ showProdUploadModal: false
473
+ });
474
+ });
475
+ _defineProperty(this, "processSubmission", () => {
476
+ if (this.state.submitLocation) {
477
+ this.setState({
478
+ showReasonForRequestModal: true
479
+ });
480
+ } else {
481
+ this.downloadAll();
482
+ }
483
+ });
484
+ _defineProperty(this, "downloadAll", () => {
485
+ const allFiles = this.generateAllFiles();
486
+ return (0, _utils.downloadZip)(allFiles, "".concat(this.state.productionName, ".zip"));
487
+ });
488
+ _defineProperty(this, "generateAllFiles", () => {
489
+ return [...this.state.rows.map(row => ["".concat(row.dtt.getSafeName(), ".yaml"), _jsYaml.default.dump(row.dtt.config)]), ["info.yaml", _jsYaml.default.dump(this.createInfoYaml())]];
490
+ });
491
+ _defineProperty(this, "submitRequest", url => {
492
+ this.setState({
493
+ requestLoading: true,
494
+ showReasonForRequestModal: false,
495
+ requestError: "",
496
+ requestSubmitted: false
497
+ });
498
+ const allFiles = this.generateAllFiles();
499
+ const formData = new FormData();
500
+ _analysisHelpers.default.forEach(file => {
501
+ formData.append("analysisHelpersFiles[]", new Blob([file.content], {
502
+ type: "text/plain"
503
+ }), file.name);
504
+ });
505
+ allFiles.forEach(file => {
506
+ formData.append("generatedFiles[]", new Blob([file[1]], {
507
+ type: "text/plain"
508
+ }), file[0]);
509
+ });
510
+ formData.append("email", localStorage.getItem("email") || "");
511
+ formData.append("name", this.state.productionName);
512
+ formData.append("reasonForRequest", this.state.reasonForRequest);
513
+ let headers = {};
514
+ if (this.state.csrfToken !== "") {
515
+ headers = {
516
+ "X-Csrf-Token": this.state.csrfToken
517
+ };
518
+ }
519
+ fetch(url, {
520
+ method: "POST",
521
+ body: formData,
522
+ credentials: "include",
523
+ headers: headers
524
+ }).then(response => {
525
+ if (!response.ok) {
526
+ throw new Error("HTTP error! Status: ".concat(response.status));
527
+ }
528
+ this.setState({
529
+ requestLoading: false,
530
+ requestSubmitted: true
531
+ });
532
+ }).catch(error => {
533
+ console.error("Fetch error:", error);
534
+ this.setState({
535
+ requestLoading: false,
536
+ requestError: "Something went wrong while submitting your request. Please try again later or contact support."
537
+ });
538
+ });
539
+ });
540
+ _defineProperty(this, "handleShowReasonForRequestModal", () => {
541
+ this.setState({
542
+ showReasonForRequestModal: true
543
+ });
544
+ });
545
+ _defineProperty(this, "handleCloseReasonForRequestModal", () => {
546
+ this.setState({
547
+ showReasonForRequestModal: false
548
+ });
549
+ });
550
+ _defineProperty(this, "dismissSubmitSuccess", () => {
551
+ this.setState({
552
+ requestSubmitted: false
553
+ });
554
+ });
555
+ _defineProperty(this, "dismissSubmitError", () => {
556
+ this.setState({
557
+ requestError: ""
558
+ });
559
+ });
560
+ this.propsVar = this.props;
561
+ }
562
+ componentDidMount() {
563
+ const urlParams = new URLSearchParams(window.location.search);
564
+ const isCloneParam = urlParams.get("clone");
565
+ if (isCloneParam === "1") {
566
+ if (!localStorage.getItem("yamlFilesToClone")) {
567
+ window.history.replaceState({}, document.title, window.location.pathname);
568
+ return;
569
+ }
570
+ this.setState({
571
+ prodUploadLoading: true,
572
+ rows: []
573
+ });
574
+ let files = JSON.parse(localStorage.getItem("yamlFilesToClone"));
575
+ for (let i = 0; i < files.length; i++) {
576
+ if (files[i].defaults) {
577
+ files[i].name = "info.yaml";
578
+ }
579
+ files[i].blob = new Blob([_jsYaml.default.dump(files[i])]);
580
+ }
581
+ this.uploadProductionConfig({
582
+ target: {
583
+ files
584
+ }
585
+ }, true);
586
+ setTimeout(() => {
587
+ this.uploadProductionConfig({
588
+ target: {
589
+ files
590
+ }
591
+ }, true);
592
+ this.setState({
593
+ prodUploadLoading: false
594
+ });
595
+ localStorage.removeItem("yamlFilesToClone");
596
+ }, 5000);
597
+ }
598
+ }
599
+ render() {
600
+ const emptySession = !this.state.productionName && this.state.contactEmail.length === 0 && this.state.rows.length === 0;
601
+ const validEmail = this.state.contactEmail.length > 0 && this.state.contactEmail.every(email => _emailValidator.default.validate(email));
602
+ const nRows = this.state.rows.filter(row => row.dtt).length;
603
+ const ready = nRows > 0 && nRows === this.state.rows.length;
604
+ const readyPaths = this.state.rows.every(row => row.paths.length > 0);
605
+
606
+ // add a check for each row to see if it has an empty name or if it has a name that is not unique
607
+ const hasValidNames = this.state.rows.every(row => {
608
+ const safeName = row.dtt ? row.dtt.getSafeName() : "";
609
+ const allSafeNames = this.state.rows.filter(otherRow => otherRow.dtt).map(otherRow => otherRow.dtt.getSafeName());
610
+ return safeName.trim().length > 0 && allSafeNames.filter(name => name === safeName).length === 1;
611
+ });
612
+ const tableContent = this.state.rows.map(row => {
613
+ const safeName = row.dtt ? row.dtt.getSafeName() : "";
614
+ const allSafeNames = this.state.rows.filter(otherRow => otherRow.dtt).map(otherRow => otherRow.dtt.getSafeName());
615
+ const hasValidName = safeName.trim().length > 0 && allSafeNames.filter(name => name === safeName).length === 1;
616
+ const urls = row.lines.map(strline => /*#__PURE__*/(0, _jsxRuntime.jsx)(_StrippingLine.default, {
617
+ line: strline.line,
618
+ stream: strline.stream,
619
+ versions: strline.versions,
620
+ showlink: true
621
+ }, "".concat(strline.line)));
622
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Row, {
623
+ className: "align-items-center",
624
+ style: {
625
+ marginBottom: 10
626
+ },
627
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
628
+ lg: true,
629
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Card, {
630
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Card.Header, {
631
+ className: "d-flex justify-content-between align-items-start",
632
+ children: [row.dtt ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.InputGroup, {
633
+ hasValidation: true,
634
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.FormControl, {
635
+ placeholder: "DecayTree",
636
+ value: row.dtt.getName(),
637
+ onChange: this.setRowName(row.id),
638
+ isInvalid: !hasValidName
639
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.FormControl.Feedback, {
640
+ type: "invalid",
641
+ children: row.dtt.getName().trim() === "" ? "Name cannot be empty" : "Must give a unique name"
642
+ })]
643
+ }) : "", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.ButtonGroup, {
644
+ children: row.dtt ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
645
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.Route, {
646
+ render: _ref6 => {
647
+ let {
648
+ history
649
+ } = _ref6;
650
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
651
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
652
+ children: "Configure this DecayTreeTuple"
653
+ }),
654
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
655
+ type: "submit",
656
+ variant: "secondary",
657
+ onClick: () => {
658
+ this.handleSubmitSpecificRow(history, row.id);
659
+ },
660
+ disabled: !hasValidName && !this.context.loaded.tupleTools,
661
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.PencilSquare, {})
662
+ })
663
+ });
664
+ }
665
+ }), this.state.hideDownloadButtons ? "" : /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
666
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
667
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
668
+ children: "Download DecayTreeTuple YAML configuration file"
669
+ }),
670
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
671
+ className: "ms-auto",
672
+ type: "button",
673
+ onClick: () => {
674
+ (0, _utils.download)(_jsYaml.default.dump(row.dtt.config), "".concat(row.dtt.getSafeName(), ".yaml"));
675
+ },
676
+ disabled: !hasValidName,
677
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.Download, {})
678
+ })
679
+ })
680
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DeleteButton.default, {
681
+ action: this.handleRemoveSpecificRowDTT(row.id)
682
+ })]
683
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
684
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
685
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
686
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
687
+ children: "Please add a DecayTreeTuple in order to complete the production configuration"
688
+ }),
689
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.ExclamationCircle, {
690
+ width: 20,
691
+ height: 20,
692
+ style: {
693
+ verticalAlign: "middle"
694
+ },
695
+ className: "text-danger me-2"
696
+ })
697
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
698
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
699
+ children: "Add a DecayTreeTuple"
700
+ }),
701
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
702
+ type: "submit",
703
+ variant: "success",
704
+ onClick: this.handleCreateDTT(row.id),
705
+ disabled: !this.context.loaded.tupleTools,
706
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.PlusLg, {})
707
+ })
708
+ }), !this.state.hideUploadButtons && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
709
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
710
+ children: "Upload DecayTreeTuple configuration file"
711
+ }),
712
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
713
+ className: "ms-auto",
714
+ type: "button",
715
+ onClick: () => {
716
+ this.handleShowUploadModal(row.id);
717
+ },
718
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.Upload, {})
719
+ })
720
+ })]
721
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Modal, {
722
+ show: this.state.showUploadModal,
723
+ animation: false,
724
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Header, {
725
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Title, {
726
+ children: " Upload configuration file "
727
+ })
728
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Body, {
729
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Group, {
730
+ controlId: "formFile1",
731
+ className: "mb-3",
732
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
733
+ type: "file",
734
+ onChange: event => {
735
+ this.uploadConfig(event, this.state.modalID);
736
+ }
737
+ //onClick={(event) => {
738
+ // event.target.value = null;
739
+ //}}
740
+ })
741
+ })
742
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Footer, {
743
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
744
+ variant: "secondary",
745
+ onClick: this.handleCloseUploadModal,
746
+ children: "Close"
747
+ })
748
+ })]
749
+ })]
750
+ })
751
+ })]
752
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Card.Body, {
753
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Decay.default, {
754
+ decay: row.decay,
755
+ display: false
756
+ })
757
+ })]
758
+ })
759
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
760
+ lg: true,
761
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactSelect.default, {
762
+ isMulti: true,
763
+ options: streamLinesToOption(row),
764
+ defaultValue: row.lines.map(lineInfo => Object({
765
+ value: lineInfo.line,
766
+ label: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StrippingLine.default, {
767
+ line: lineInfo.line,
768
+ stream: lineInfo.stream,
769
+ versions: lineInfo.versions,
770
+ showlink: false
771
+ }),
772
+ group: lineInfo.stream
773
+ })),
774
+ placeholder: "Stripping line",
775
+ onChange: this.changeSelStrLines(row.id)
776
+ })
777
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
778
+ xs: "auto",
779
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
780
+ trigger: "click",
781
+ placement: "right",
782
+ rootClose: true,
783
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Popover, {
784
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Popover.Body, {
785
+ children: urls
786
+ })
787
+ }),
788
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
789
+ className: "ms-auto",
790
+ type: "button",
791
+ disabled: urls.length === 0,
792
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.QuestionCircle, {})
793
+ })
794
+ })
795
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
796
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_creatable.default, {
797
+ isMulti: true,
798
+ options: this.defaultBKPaths(row.id) /*TODO: use ODP records when ready*/,
799
+ value: this.getBKPaths(row.id),
800
+ isDisabled: row.lines.length === 0,
801
+ placeholder: "Bookkeeping path",
802
+ onChange: this.pathChoiceHandler(row.id),
803
+ onCreateOption: this.pathCreateHandler(row.id),
804
+ closeMenuOnSelect: false
805
+ })
806
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
807
+ xs: "auto",
808
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DeleteButton.default, {
809
+ action: this.handleRemoveSpecificRow(row.id)
810
+ })
811
+ })]
812
+ }, row.id);
813
+ });
814
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
815
+ children: [tableContent, this.state.requestLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Spinner, {
816
+ animation: "border",
817
+ role: "status",
818
+ className: "mt-1 mb-2"
819
+ }) : "", this.state.prodUploadLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Row, {
820
+ className: "mt-3",
821
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
822
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
823
+ variant: "primary",
824
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Row, {
825
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
826
+ xs: 1,
827
+ style: {
828
+ width: "50px",
829
+ verticalAlign: "middle"
830
+ },
831
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Spinner, {
832
+ animation: "border",
833
+ role: "status",
834
+ className: "mt-1 mb-2"
835
+ })
836
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Col, {
837
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert.Heading, {
838
+ children: "Uploading configuration files..."
839
+ }), "Please wait while the cloned configuration files are being uploaded."]
840
+ })]
841
+ })
842
+ })
843
+ })
844
+ }) : "", this.state.requestSubmitted ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Row, {
845
+ className: "mt-3",
846
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
847
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
848
+ variant: "success",
849
+ dismissible: true,
850
+ onClose: this.dismissSubmitSuccess,
851
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert.Heading, {
852
+ children: "Request submitted!"
853
+ }), this.state.requestSubmittedMessage]
854
+ })
855
+ })
856
+ }) : "", this.state.requestError && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Row, {
857
+ className: "mt-3",
858
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
859
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Alert, {
860
+ variant: "danger",
861
+ dismissible: true,
862
+ onClose: this.dismissSubmitError,
863
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert.Heading, {
864
+ children: "An error occurred!"
865
+ }), this.state.requestError]
866
+ })
867
+ })
868
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Row, {
869
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Col, {
870
+ xs: "auto",
871
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.ButtonGroup, {
872
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.Route, {
873
+ render: _ref7 => {
874
+ let {
875
+ history
876
+ } = _ref7;
877
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
878
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
879
+ children: "Select decays"
880
+ }),
881
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
882
+ type: "submit",
883
+ variant: "success",
884
+ onClick: () => this.handleAddRow(history),
885
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
886
+ style: {
887
+ verticalAlign: "middle"
888
+ },
889
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.PlusLg, {}), " Select decays"]
890
+ })
891
+ })
892
+ });
893
+ }
894
+ }), !this.state.hideUploadButtons && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
895
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
896
+ children: "Upload Production configuration file"
897
+ }),
898
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
899
+ className: "ms-auto",
900
+ type: "button",
901
+ onClick: () => {
902
+ this.handleShowProdUploadModal();
903
+ },
904
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.Upload, {})
905
+ })
906
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Modal, {
907
+ show: this.state.showProdUploadModal,
908
+ animation: false,
909
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Header, {
910
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Title, {
911
+ children: " Upload configuration file "
912
+ })
913
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Body, {
914
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Group, {
915
+ controlId: "formFile2",
916
+ className: "mb-3",
917
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
918
+ type: "file",
919
+ multiple: true,
920
+ onChange: event => {
921
+ this.uploadProductionConfig(event);
922
+ }
923
+ //onClick={(event) => {
924
+ // event.target.value = null;
925
+ //}}
926
+ })
927
+ })
928
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Footer, {
929
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
930
+ variant: "secondary",
931
+ onClick: this.handleCloseProdUploadModal,
932
+ children: "Close"
933
+ })
934
+ })]
935
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.Route, {
936
+ render: _ref8 => {
937
+ let {
938
+ history
939
+ } = _ref8;
940
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
941
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
942
+ children: "Configure all DecayTreeTuples"
943
+ }),
944
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Button, {
945
+ type: "submit",
946
+ variant: "secondary",
947
+ onClick: () => this.handleSubmitRows(history),
948
+ disabled: !ready,
949
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.PencilSquare, {}), " ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Badge, {
950
+ pill: true,
951
+ bg: "primary",
952
+ children: nRows
953
+ })]
954
+ })
955
+ });
956
+ }
957
+ }), this.state.hideDownloadButtons ? "" : /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
958
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
959
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
960
+ children: "Download Analysis Production configuration file (info.yaml)"
961
+ }),
962
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
963
+ type: "download",
964
+ onClick: () => (0, _utils.download)(_jsYaml.default.dump(this.createInfoYaml()), "info.yaml"),
965
+ disabled: !ready || !readyPaths || !validEmail,
966
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.Download, {})
967
+ })
968
+ })
969
+ })]
970
+ })
971
+ })
972
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Row, {
973
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Col, {
974
+ xs: 4,
975
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.InputGroup, {
976
+ hasValidation: true,
977
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
978
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
979
+ children: "Name of this production. This will become the subdirectory in AnalysisProductions"
980
+ }),
981
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.InputGroup.Text, {
982
+ children: "Production name"
983
+ })
984
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.FormControl, {
985
+ value: this.state.productionName,
986
+ onChange: this.setProductionName,
987
+ isValid: this.state.productionName,
988
+ placeholder: "MyAnalysis"
989
+ })]
990
+ }), this.state.emailIsKnown ? "" : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.InputGroup, {
991
+ hasValidation: true,
992
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
993
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
994
+ children: "Email addresses to notify (comma-separated)"
995
+ }),
996
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.InputGroup.Text, {
997
+ children: "Email"
998
+ })
999
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.FormControl, {
1000
+ type: "email",
1001
+ value: this.state.contactEmail.join(","),
1002
+ onChange: this.setContactEmail,
1003
+ isValid: validEmail,
1004
+ placeholder: "name@example.com"
1005
+ })]
1006
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.ButtonGroup, {
1007
+ children: [this.state.hideDownloadButtons ? "" : /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
1008
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
1009
+ overlay: this.validateDTTIsSetForAllRows() ? !ready || !readyPaths || !this.state.productionName || !(this.state.emailIsKnown ? true : validEmail) || !hasValidNames ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1010
+ children: "Please make sure all fields are filled in before downloading"
1011
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1012
+ children: "Download all DecayTreeTuple configurations"
1013
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1014
+ children: "Please configure a DecayTreeTuple for each selected decay before downloading"
1015
+ }),
1016
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
1017
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Button, {
1018
+ disabled: !ready || !readyPaths || !this.state.productionName || !(this.state.emailIsKnown ? true : validEmail) || !hasValidNames,
1019
+ onClick: this.downloadAll,
1020
+ type: "info",
1021
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.Download, {}), " Download"]
1022
+ })
1023
+ })
1024
+ })
1025
+ }), this.state.submitLocation ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
1026
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
1027
+ overlay: this.validateDTTIsSetForAllRows() ? !ready || !readyPaths || !this.state.productionName || !(this.state.emailIsKnown ? true : validEmail) || !hasValidNames ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1028
+ children: "Please make sure all fields are filled in before submitting"
1029
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1030
+ children: "Submit a request with the chosen configuration"
1031
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1032
+ children: "Please configure a DecayTreeTuple for each selected decay before submitting"
1033
+ }),
1034
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
1035
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Button, {
1036
+ disabled: !ready || !readyPaths || !this.state.productionName || !(this.state.emailIsKnown ? true : validEmail) || !hasValidNames,
1037
+ onClick: this.handleShowReasonForRequestModal,
1038
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrapIcons.Send, {}), " Submit"]
1039
+ })
1040
+ })
1041
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Modal, {
1042
+ show: this.state.showReasonForRequestModal,
1043
+ onHide: this.handleCloseReasonForRequestModal,
1044
+ size: "lg",
1045
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Header, {
1046
+ closeButton: true,
1047
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Title, {
1048
+ children: "Reason for request"
1049
+ })
1050
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Modal.Body, {
1051
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
1052
+ children: this.state.requestReasonMessage
1053
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.InputGroup, {
1054
+ hasValidation: true,
1055
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.OverlayTrigger, {
1056
+ overlay: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Tooltip, {
1057
+ children: "Reason for requesting the chosen ntuples"
1058
+ }),
1059
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.InputGroup.Text, {
1060
+ children: "Reason for request"
1061
+ })
1062
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.FormControl, {
1063
+ as: "textarea",
1064
+ rows: 3,
1065
+ value: this.state.reasonForRequest,
1066
+ onChange: this.setReasonForRequest,
1067
+ isValid: this.state.reasonForRequest,
1068
+ placeholder: "I need these ntuples for..."
1069
+ })]
1070
+ })]
1071
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Footer, {
1072
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
1073
+ variant: "primary",
1074
+ onClick: () => this.submitRequest(this.state.submitLocation),
1075
+ disabled: !ready || !readyPaths || !this.state.productionName || !this.state.reasonForRequest || !(this.state.emailIsKnown ? true : validEmail) || !hasValidNames,
1076
+ children: "Submit request"
1077
+ })
1078
+ })]
1079
+ })]
1080
+ }) : "", /*#__PURE__*/(0, _jsxRuntime.jsx)(_DeleteButton.default, {
1081
+ action: this.clearAll,
1082
+ disabled: emptySession,
1083
+ children: "Clear"
1084
+ })]
1085
+ })]
1086
+ })
1087
+ })]
1088
+ });
1089
+ }
1090
+ }
1091
+ _defineProperty(LinesTable, "contextType", _MetadataContext.default);
1092
+ LinesTable.propTypes = {
1093
+ rows: _propTypes.default.arrayOf(_propTypes.default.object),
1094
+ name: _propTypes.default.string,
1095
+ email: _propTypes.default.arrayOf(_propTypes.default.string),
1096
+ reasonForRequest: _propTypes.default.string,
1097
+ parentCallbackInfo: _propTypes.default.func,
1098
+ parentCallbackRows: _propTypes.default.func,
1099
+ decaysPath: _propTypes.default.string.isRequired,
1100
+ submitLocation: _propTypes.default.string,
1101
+ hideDownloadButtons: _propTypes.default.bool,
1102
+ hideUploadButtons: _propTypes.default.bool,
1103
+ emailIsKnown: _propTypes.default.bool,
1104
+ requestReasonMessage: _propTypes.default.string,
1105
+ requestSubmittedMessage: _propTypes.default.object,
1106
+ csrfToken: _propTypes.default.string
1107
+ };
1108
+ LinesTable.defaultProps = {
1109
+ csrfToken: ""
1110
+ };
1111
+ var _default = exports.default = LinesTable;