cloudmr-ux 4.2.7 → 4.2.9

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.
@@ -11,6 +11,12 @@ export interface CmrTableProps extends Omit<DataGridProps, 'rows'> {
11
11
  headerBgColor?: string;
12
12
  headerTextColor?: string;
13
13
  headerIconColor?: string;
14
+ /**
15
+ * Optional function to customize how rows are filtered/sorted before display.
16
+ * Receives the mapped rows; return a new array in the desired order.
17
+ * When omitted, rows are sorted by most recently submitted (createdAt/created_at descending).
18
+ */
19
+ processRows?: (rows: any[]) => any[];
14
20
  }
15
21
  declare const CmrTable: React.FC<CmrTableProps>;
16
22
  export default CmrTable;
@@ -20,14 +20,38 @@ var __rest = (this && this.__rest) || function (s, e) {
20
20
  }
21
21
  return t;
22
22
  };
23
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
24
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
25
+ if (ar || !(i in from)) {
26
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
27
+ ar[i] = from[i];
28
+ }
29
+ }
30
+ return to.concat(ar || Array.prototype.slice.call(from));
31
+ };
23
32
  import { jsx as _jsx } from "react/jsx-runtime";
24
33
  import './CmrTable.css';
25
34
  import { DataGrid } from '@mui/x-data-grid';
35
+ /** Extracts a comparable timestamp from a row for sorting. Supports createdAt, created_at, or similar date fields. */
36
+ function getSubmittedTimestamp(row) {
37
+ var _a, _b, _c;
38
+ var val = (_c = (_b = (_a = row.createdAt) !== null && _a !== void 0 ? _a : row.created_at) !== null && _b !== void 0 ? _b : row.updatedAt) !== null && _c !== void 0 ? _c : row.updated_at;
39
+ if (val == null)
40
+ return 0;
41
+ var ts = typeof val === 'number' ? val : new Date(val).getTime();
42
+ return isNaN(ts) ? 0 : ts;
43
+ }
44
+ /** Default sort: most recently submitted first (by createdAt or created_at descending). */
45
+ function defaultSortByRecent(rows) {
46
+ return __spreadArray([], rows, true).sort(function (a, b) { return getSubmittedTimestamp(b) - getSubmittedTimestamp(a); });
47
+ }
26
48
  var CmrTable = function (props) {
27
- var dataSource = props.dataSource, columns = props.columns, idAlias = props.idAlias, className = props.className, onRowSelectionModelChange = props.onRowSelectionModelChange, style = props.style, _a = props.showCheckbox, showCheckbox = _a === void 0 ? true : _a, _b = props.headerBgColor, headerBgColor = _b === void 0 ? '#F3E5F5' : _b, _c = props.headerTextColor, headerTextColor = _c === void 0 ? '#333' : _c, _d = props.headerIconColor, headerIconColor = _d === void 0 ? '#580f8b' : _d, rest = __rest(props, ["dataSource", "columns", "idAlias", "className", "onRowSelectionModelChange", "style", "showCheckbox", "headerBgColor", "headerTextColor", "headerIconColor"]);
28
- return (_jsx("div", __assign({ style: style !== null && style !== void 0 ? style : { height: '400px', width: '100%' }, className: className !== null && className !== void 0 ? className : '' }, { children: _jsx(DataGrid, __assign({ rows: dataSource
29
- ? dataSource.map(function (row) { return (__assign({ id: idAlias ? row[idAlias] : row['id'] }, row)); })
30
- : [], columns: columns, checkboxSelection: showCheckbox, onRowSelectionModelChange: onRowSelectionModelChange, initialState: {
49
+ var dataSource = props.dataSource, columns = props.columns, idAlias = props.idAlias, className = props.className, onRowSelectionModelChange = props.onRowSelectionModelChange, style = props.style, _a = props.showCheckbox, showCheckbox = _a === void 0 ? true : _a, _b = props.headerBgColor, headerBgColor = _b === void 0 ? '#F3E5F5' : _b, _c = props.headerTextColor, headerTextColor = _c === void 0 ? '#333' : _c, _d = props.headerIconColor, headerIconColor = _d === void 0 ? '#580f8b' : _d, processRows = props.processRows, rest = __rest(props, ["dataSource", "columns", "idAlias", "className", "onRowSelectionModelChange", "style", "showCheckbox", "headerBgColor", "headerTextColor", "headerIconColor", "processRows"]);
50
+ var mappedRows = dataSource
51
+ ? dataSource.map(function (row) { return (__assign({ id: idAlias ? row[idAlias] : row['id'] }, row)); })
52
+ : [];
53
+ var displayRows = processRows ? processRows(mappedRows) : defaultSortByRecent(mappedRows);
54
+ return (_jsx("div", __assign({ style: style !== null && style !== void 0 ? style : { height: '400px', width: '100%' }, className: className !== null && className !== void 0 ? className : '' }, { children: _jsx(DataGrid, __assign({ rows: displayRows, columns: columns, checkboxSelection: showCheckbox, onRowSelectionModelChange: onRowSelectionModelChange, initialState: {
31
55
  pagination: {
32
56
  paginationModel: { pageSize: 50, page: 0 }
33
57
  }
@@ -214,8 +214,7 @@ var Upload = function () {
214
214
  // return !name.endsWith(".zip") && !name.endsWith(".nii");
215
215
  // TODO RJW: does this make sense? confusing if you upload a zip, it just disappears
216
216
  return true; // Show all files for now
217
- })
218
- .reverse(), rowSelectionModel: selectedData, onRowSelectionModelChange: function (rowSelectionModel) {
217
+ }), rowSelectionModel: selectedData, onRowSelectionModelChange: function (rowSelectionModel) {
219
218
  setSelectedData(rowSelectionModel);
220
219
  }, columns: uploadedFilesColumns }), _jsxs("div", __assign({ className: "row mt-2" }, { children: [_jsx("div", __assign({ className: "col-4" }, { children: _jsxs(Button, __assign({ color: "error", style: { textTransform: "none" }, variant: "contained", fullWidth: true, onClick: function () {
221
220
  setName("Deleting Data");
@@ -42,19 +42,20 @@ import { AuthenticatedHttpClient } from "../../common/utilities/AuthenticatedReq
42
42
  export var submitJobs = createAsyncThunk("SUBMIT_JOBS", function (_a, thunkAPI) {
43
43
  var jobQueue = _a.jobQueue;
44
44
  return __awaiter(void 0, void 0, void 0, function () {
45
- var endpoints, responses, _i, jobQueue_1, job, job_setup_copy, _b, _c, file, res;
46
- return __generator(this, function (_d) {
47
- switch (_d.label) {
45
+ var endpoints, responses, _i, jobQueue_1, job, job_setup_copy, _b, _c, file, res, error_1, errorData, errorMsg, modeMatch, mode;
46
+ var _d, _e, _f;
47
+ return __generator(this, function (_g) {
48
+ switch (_g.label) {
48
49
  case 0:
49
50
  endpoints = getEndpoints();
50
51
  responses = [];
51
52
  _i = 0, jobQueue_1 = jobQueue;
52
- _d.label = 1;
53
+ _g.label = 1;
53
54
  case 1:
54
- if (!(_i < jobQueue_1.length)) return [3 /*break*/, 4];
55
+ if (!(_i < jobQueue_1.length)) return [3 /*break*/, 6];
55
56
  job = jobQueue_1[_i];
56
57
  if (job === undefined) {
57
- return [3 /*break*/, 3];
58
+ return [3 /*break*/, 5];
58
59
  }
59
60
  console.log(job);
60
61
  console.log(JSON.stringify(job.setup));
@@ -72,6 +73,9 @@ export var submitJobs = createAsyncThunk("SUBMIT_JOBS", function (_a, thunkAPI)
72
73
  console.log(e);
73
74
  }
74
75
  console.log(job_setup_copy);
76
+ _g.label = 2;
77
+ case 2:
78
+ _g.trys.push([2, 4, , 5]);
75
79
  return [4 /*yield*/, AuthenticatedHttpClient.post(endpoints.JOBS_API, job_setup_copy, {
76
80
  headers: {
77
81
  accept: "*/*",
@@ -79,17 +83,35 @@ export var submitJobs = createAsyncThunk("SUBMIT_JOBS", function (_a, thunkAPI)
79
83
  "Content-Type": "application/json"
80
84
  }
81
85
  })];
82
- case 2:
83
- res = _d.sent();
86
+ case 3:
87
+ res = _g.sent();
84
88
  responses.push({
85
89
  id: job.id,
86
90
  status: res.status
87
91
  });
88
- _d.label = 3;
89
- case 3:
92
+ return [3 /*break*/, 5];
93
+ case 4:
94
+ error_1 = _g.sent();
95
+ errorData = (_d = error_1 === null || error_1 === void 0 ? void 0 : error_1.response) === null || _d === void 0 ? void 0 : _d.data;
96
+ if (((_f = (_e = errorData === null || errorData === void 0 ? void 0 : errorData.error) === null || _e === void 0 ? void 0 : _e.includes) === null || _f === void 0 ? void 0 : _f.call(_e, 'Monthly limit')) ||
97
+ ((errorData === null || errorData === void 0 ? void 0 : errorData.current_count) !== undefined && (errorData === null || errorData === void 0 ? void 0 : errorData.limit) !== undefined)) {
98
+ errorMsg = (errorData === null || errorData === void 0 ? void 0 : errorData.error) || '';
99
+ modeMatch = errorMsg.match(/(mode_[12])/);
100
+ mode = modeMatch ? modeMatch[1] : undefined;
101
+ return [2 /*return*/, thunkAPI.rejectWithValue({
102
+ error: errorMsg || 'Monthly limit reached',
103
+ current_count: errorData === null || errorData === void 0 ? void 0 : errorData.current_count,
104
+ limit: errorData === null || errorData === void 0 ? void 0 : errorData.limit,
105
+ mode: mode,
106
+ app: (errorData === null || errorData === void 0 ? void 0 : errorData.app) || (errorData === null || errorData === void 0 ? void 0 : errorData.cloudapp_name)
107
+ })];
108
+ }
109
+ // Re-throw other errors
110
+ throw error_1;
111
+ case 5:
90
112
  _i++;
91
113
  return [3 /*break*/, 1];
92
- case 4:
114
+ case 6:
93
115
  // //Update upstream jobs right after submission
94
116
  thunkAPI.dispatch(getUpstreamJobs());
95
117
  // Return whether the submission was successful
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudmr-ux",
3
- "version": "4.2.7",
3
+ "version": "4.2.9",
4
4
  "author": "erosmontin@gmail.com",
5
5
  "license": "MIT",
6
6
  "repository": "erosmontin/cloudmr-ux",