@dexteel/mesf-core 7.22.0 → 7.22.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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "7.22.0"
2
+ ".": "7.22.1"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [7.22.1](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.22.0...@dexteel/mesf-core-v7.22.1) (2026-05-11)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **logs:** improve large log filtering performance ([80eaa0a](https://github.com/dexteel/mesf-core-frontend/commit/80eaa0a0f0535e0e3f67397d85b97efaa7b8659b))
9
+
3
10
  ## [7.22.0](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.21.0...@dexteel/mesf-core-v7.22.0) (2026-05-09)
4
11
 
5
12
 
@@ -1,4 +1,4 @@
1
1
  import { ColDef } from "ag-grid-community";
2
- export declare const useLogTableData: () => {
2
+ export declare const useLogTableData: (timezone: "UTC" | "Server") => {
3
3
  columnDefs: ColDef<any, any>[];
4
4
  };
package/dist/index.esm.js CHANGED
@@ -7853,14 +7853,14 @@ const TagFilter = ({ tagFilters, setTagFilters, filterContext, }) => {
7853
7853
  startDate: filterContext.startDate,
7854
7854
  endDate: filterContext.endDate,
7855
7855
  logTypeCode: filterContext.logTypeCode,
7856
- tagFilters,
7856
+ tagFilters: filterContext.tagFilters,
7857
7857
  });
7858
7858
  const { data: tagValues, isLoading: isLoadingValues, error: valuesError, isError: isValuesError, } = useSearchLogTagValues({
7859
7859
  tagName: selectedTag ? selectedTag.TagName : "",
7860
7860
  startDate: filterContext.startDate,
7861
7861
  endDate: filterContext.endDate,
7862
7862
  logTypeCode: filterContext.logTypeCode,
7863
- tagFilters,
7863
+ tagFilters: filterContext.tagFilters,
7864
7864
  });
7865
7865
  const handleOpenPopover = (event) => {
7866
7866
  setAnchorEl(event.currentTarget);
@@ -8056,17 +8056,24 @@ const SearchFilter = ({ search, setSearch }) => {
8056
8056
  }, label: "Search", variant: "outlined", size: "small", value: search, onChange: (e) => setSearch(e.target.value), autoComplete: "off" })));
8057
8057
  };
8058
8058
 
8059
- const useLogTableData = () => {
8059
+ const useLogTableData = (timezone) => {
8060
8060
  const backgroundColor = (logTypeCode) => {
8061
8061
  return get(LOG_TYPE_CODES, `${logTypeCode[0]}.color`, "#BBBBBB");
8062
8062
  };
8063
- const [columnDefs] = useState([
8063
+ const columnDefs = useMemo(() => [
8064
8064
  {
8065
8065
  field: "Timestamp",
8066
8066
  headerName: "Time",
8067
8067
  minWidth: 220,
8068
8068
  flex: 1,
8069
8069
  headerClass: "ag-header-cell-centered",
8070
+ valueFormatter: ({ value }) => {
8071
+ if (!value)
8072
+ return "";
8073
+ return timezone === "UTC"
8074
+ ? moment$g(value).utc().format("YYYY-MM-DD HH:mm:ss z")
8075
+ : dxtToLocalServerTime(value, "yyyy-MM-dd HH:mm:ss z");
8076
+ },
8070
8077
  },
8071
8078
  {
8072
8079
  field: "Source",
@@ -8126,7 +8133,7 @@ const useLogTableData = () => {
8126
8133
  valueFormatter: ({ value }) => value || " ",
8127
8134
  headerClass: "ag-header-cell-centered",
8128
8135
  },
8129
- ]);
8136
+ ], [timezone]);
8130
8137
  return { columnDefs };
8131
8138
  };
8132
8139
 
@@ -8148,7 +8155,7 @@ const getLogs = (params, signal) => __awaiter(void 0, void 0, void 0, function*
8148
8155
  },
8149
8156
  { name: "TagFilters", value: tagFiltersJson },
8150
8157
  ];
8151
- const resp = yield apiService.callV2("[MES].[GetLogs]", parameters);
8158
+ const resp = yield apiService.callV2("[MES].[GetLogs]", parameters, signal);
8152
8159
  if (resp.ok) {
8153
8160
  let rows = get(resp, "data.tables[0].rows", []);
8154
8161
  rows = rows.map((log) => (Object.assign(Object.assign({}, log), { Timestamp: log.Timestamp ? moment$g.utc(log["Timestamp"]).toDate() : null })));
@@ -8271,48 +8278,55 @@ const useSearchLogs = ({ startDate, endDate, logTypeCode, autoRefresh, tagFilter
8271
8278
  endDate,
8272
8279
  logTypeCode,
8273
8280
  tagFilters,
8274
- }),
8281
+ }, signal),
8275
8282
  refetchInterval: autoRefresh ? 5000 : false,
8276
8283
  enabled: !!startDate && (!!endDate || autoRefresh),
8284
+ keepPreviousData: true,
8277
8285
  staleTime: 10000,
8278
8286
  });
8279
8287
  };
8280
8288
  const getLogTypeByCodeId = (logTypeCodeId) => {
8281
8289
  return get(LOG_TYPE_CODES, `${logTypeCodeId}.description`, " -");
8282
8290
  };
8291
+ const getDefaultFilters = () => ({
8292
+ startDate: moment$g().add(-5, "days").hour(0).minute(0).second(0).toDate(),
8293
+ endDate: moment$g().hour(23).minute(59).second(59).toDate(),
8294
+ logTypeCode: ["I", "W", "E"],
8295
+ autoRefresh: false,
8296
+ tagFilters: [],
8297
+ });
8298
+ const copyFilters = (filters) => (Object.assign(Object.assign({}, filters), { logTypeCode: [...filters.logTypeCode], tagFilters: [...filters.tagFilters] }));
8283
8299
  const TableLogs = () => {
8284
- const [startDate, setStartDate] = useState(moment$g().add(-5, "days").hour(0).minute(0).second(0).toDate());
8285
- const [endDate, setEndDate] = useState(moment$g().hour(23).minute(59).second(59).toDate());
8300
+ var _a;
8301
+ const [draftFilters, setDraftFilters] = useState(() => getDefaultFilters());
8302
+ const [appliedFilters, setAppliedFilters] = useState(() => getDefaultFilters());
8303
+ const [isApplyingFilters, setIsApplyingFilters] = useState(false);
8304
+ const hasMountedRef = useRef(false);
8286
8305
  const [timezone, setTimezone] = useState("UTC");
8287
8306
  const [search, setSearch] = useState("");
8288
- const [logTypeCode, setLogTypeCode] = useState(["I", "W", "E"]);
8289
- const [autoRefresh, setAutoRefresh] = useState(false);
8290
- const [tagFilters, setTagFilters] = useState([]);
8291
8307
  const [gridAPI, setGridAPI] = useState(null);
8292
8308
  const [error, setError] = useState("");
8293
8309
  const [showLogModal, setShowLogModal] = useState(false);
8294
8310
  const [selectedLog, setSelectedLog] = useState(undefined);
8295
- const { data: rows, isLoading, refetch, isError, error: e, } = useSearchLogs({
8296
- startDate,
8297
- endDate,
8298
- logTypeCode: logTypeCode.join(","),
8299
- autoRefresh,
8300
- tagFilters,
8311
+ const { data: rows, isLoading, isFetching, isError, error: e, } = useSearchLogs({
8312
+ startDate: appliedFilters.startDate,
8313
+ endDate: appliedFilters.endDate,
8314
+ logTypeCode: appliedFilters.logTypeCode.join(","),
8315
+ autoRefresh: appliedFilters.autoRefresh,
8316
+ tagFilters: appliedFilters.tagFilters,
8301
8317
  });
8302
8318
  const onGridReady = (params) => {
8303
8319
  setGridAPI(params.api);
8304
8320
  };
8305
- const formattedRows = rows === null || rows === void 0 ? void 0 : rows.map(({ LogId, Timestamp, Source, Message, LogTypeCode, User }) => ({
8321
+ const formattedRows = useMemo(() => rows === null || rows === void 0 ? void 0 : rows.map(({ LogId, Timestamp, Source, Message, LogTypeCode, User }) => ({
8306
8322
  id: LogId,
8307
- Timestamp: timezone === "UTC"
8308
- ? moment$g(Timestamp).utc().format("YYYY-MM-DD HH:mm:ss z")
8309
- : dxtToLocalServerTime(Timestamp, "yyyy-MM-dd HH:mm:ss z"),
8323
+ Timestamp,
8310
8324
  Source,
8311
8325
  Message: isNil(Message) ? "" : Message.replaceAll("Added", " Added"),
8312
8326
  LogTypeCode: getLogTypeByCodeId(LogTypeCode),
8313
8327
  User,
8314
- }));
8315
- const { columnDefs } = useLogTableData();
8328
+ })), [rows]);
8329
+ const { columnDefs } = useLogTableData(timezone);
8316
8330
  const defaultColDef = useMemo(() => {
8317
8331
  return {
8318
8332
  sortable: true,
@@ -8328,16 +8342,17 @@ const TableLogs = () => {
8328
8342
  };
8329
8343
  }, []);
8330
8344
  const { showContextMenu, registerConfig } = useContextMenuMESF();
8345
+ const handleAutoRefreshChange = (checked) => {
8346
+ const nextFilters = checked
8347
+ ? Object.assign(Object.assign({}, draftFilters), { startDate: moment$g().add(-15, "minutes").toDate(), endDate: null, autoRefresh: true }) : Object.assign(Object.assign({}, draftFilters), { endDate: moment$g().hour(23).minute(59).second(59).toDate(), autoRefresh: false });
8348
+ setDraftFilters(copyFilters(nextFilters));
8349
+ };
8331
8350
  const handleResetButtonClick = () => {
8332
- setStartDate(moment$g().add(-5, "days").hour(0).minute(0).second(0).toDate());
8333
- setEndDate(moment$g().hour(23).minute(59).second(59).toDate());
8351
+ const filters = getDefaultFilters();
8352
+ setDraftFilters(copyFilters(filters));
8334
8353
  setSearch("");
8335
- gridAPI === null || gridAPI === void 0 ? void 0 : gridAPI.setGridOption("quickFilterText", "");
8336
- setLogTypeCode(["I", "W", "E"]);
8337
- setTagFilters([]);
8338
8354
  setSelectedLog(undefined);
8339
8355
  setError("");
8340
- refetch();
8341
8356
  };
8342
8357
  const rowClicked = (rowClickedEvent) => {
8343
8358
  let data = rowClickedEvent.data;
@@ -8360,11 +8375,11 @@ const TableLogs = () => {
8360
8375
  handleResetButtonClick,
8361
8376
  });
8362
8377
  const filterContext = useMemo(() => ({
8363
- startDate,
8364
- endDate,
8365
- logTypeCode: logTypeCode.join(","),
8366
- tagFilters,
8367
- }), [startDate, endDate, logTypeCode, tagFilters]);
8378
+ startDate: appliedFilters.startDate,
8379
+ endDate: appliedFilters.endDate,
8380
+ logTypeCode: appliedFilters.logTypeCode.join(","),
8381
+ tagFilters: appliedFilters.tagFilters,
8382
+ }), [appliedFilters]);
8368
8383
  useEffect(() => {
8369
8384
  registerConfig({
8370
8385
  id: "TableLogs",
@@ -8376,6 +8391,24 @@ const TableLogs = () => {
8376
8391
  setError(e.message);
8377
8392
  }
8378
8393
  }, [isError, e]);
8394
+ useEffect(() => {
8395
+ if (!hasMountedRef.current) {
8396
+ hasMountedRef.current = true;
8397
+ return;
8398
+ }
8399
+ setIsApplyingFilters(true);
8400
+ const timeout = window.setTimeout(() => {
8401
+ setAppliedFilters(copyFilters(draftFilters));
8402
+ setIsApplyingFilters(false);
8403
+ }, 100);
8404
+ return () => window.clearTimeout(timeout);
8405
+ }, [draftFilters]);
8406
+ useEffect(() => {
8407
+ const timeout = window.setTimeout(() => {
8408
+ gridAPI === null || gridAPI === void 0 ? void 0 : gridAPI.setGridOption("quickFilterText", search);
8409
+ }, 350);
8410
+ return () => window.clearTimeout(timeout);
8411
+ }, [gridAPI, search]);
8379
8412
  return (React.createElement(React.Fragment, null,
8380
8413
  React.createElement(Grid2, { container: true, justifyContent: "flex-start", p: 1, spacing: 1 },
8381
8414
  React.createElement(Grid2, { size: { md: 12, xs: 12 } },
@@ -8402,43 +8435,32 @@ const TableLogs = () => {
8402
8435
  React.createElement(CardContent, { sx: { width: "100%" } },
8403
8436
  React.createElement(Grid2, { container: true, alignItems: "center", direction: "row", spacing: 2 },
8404
8437
  React.createElement(Grid2, { size: { md: 1.5 } },
8405
- React.createElement(DateFilter, { label: "From", date: startDate, setDate: (date) => setStartDate(date || new Date()), maxDate: endDate !== null && endDate !== void 0 ? endDate : undefined })),
8438
+ React.createElement(DateFilter, { label: "From", date: draftFilters.startDate, setDate: (date) => setDraftFilters(Object.assign(Object.assign({}, draftFilters), { startDate: date || new Date() })), maxDate: (_a = draftFilters.endDate) !== null && _a !== void 0 ? _a : undefined })),
8406
8439
  React.createElement(Grid2, { size: { md: 1.5 } },
8407
- React.createElement(DateFilter, { label: "To", date: endDate, setDate: (date) => {
8440
+ React.createElement(DateFilter, { label: "To", date: draftFilters.endDate, setDate: (date) => {
8408
8441
  if (date) {
8409
- setEndDate(date);
8410
- setAutoRefresh(false);
8442
+ setDraftFilters(Object.assign(Object.assign({}, draftFilters), { endDate: date, autoRefresh: false }));
8411
8443
  }
8412
- }, minDate: startDate })),
8444
+ }, minDate: draftFilters.startDate })),
8413
8445
  React.createElement(Grid2, { size: { md: 2, xs: 12 } },
8414
- React.createElement(CodeFilter, { LogTypeCode: logTypeCode, setLogTypeCodeFilter: (logTypeCodes) => setLogTypeCode(logTypeCodes) })),
8446
+ React.createElement(CodeFilter, { LogTypeCode: draftFilters.logTypeCode, setLogTypeCodeFilter: (logTypeCodes) => setDraftFilters(Object.assign(Object.assign({}, draftFilters), { logTypeCode: logTypeCodes })) })),
8415
8447
  React.createElement(Grid2, { size: { md: 1, xs: 12 } },
8416
8448
  React.createElement(TimezoneSelector, { value: timezone, onChange: setTimezone })),
8417
8449
  React.createElement(Grid2, { size: { md: 1.5, xs: 12 } },
8418
- React.createElement(FormControlLabel, { checked: autoRefresh, control: React.createElement(Switch, { color: "primary" }), label: "Auto Refresh", onChange: (e, checked) => {
8419
- if (checked) {
8420
- setEndDate(null);
8421
- }
8422
- else {
8423
- setEndDate(moment$g().hour(23).minute(59).second(59).toDate());
8424
- }
8425
- setAutoRefresh(checked);
8426
- } })),
8450
+ React.createElement(FormControlLabel, { checked: draftFilters.autoRefresh, control: React.createElement(Switch, { color: "primary" }), label: "Auto Refresh", onChange: (e, checked) => handleAutoRefreshChange(checked) })),
8427
8451
  React.createElement(Grid2, { size: { md: 3.5, xs: 12 } },
8428
- React.createElement(SearchFilter, { search: search, setSearch: (search) => {
8429
- setSearch(search);
8430
- gridAPI === null || gridAPI === void 0 ? void 0 : gridAPI.setGridOption("quickFilterText", search);
8431
- } })),
8452
+ React.createElement(SearchFilter, { search: search, setSearch: setSearch })),
8432
8453
  React.createElement(Grid2, { size: { md: 1, xs: 12 }, style: { paddingTop: 8 } },
8433
8454
  React.createElement(Button, { variant: "contained", color: "inherit", onClick: handleResetButtonClick, fullWidth: true }, "Reset")),
8434
8455
  React.createElement(Grid2, { size: { md: 12, xs: 12 }, sx: { mt: 1 } },
8435
- React.createElement(TagFilter, { tagFilters: tagFilters, setTagFilters: setTagFilters, filterContext: filterContext })))))),
8456
+ React.createElement(TagFilter, { tagFilters: draftFilters.tagFilters, setTagFilters: (tagFilters) => setDraftFilters(Object.assign(Object.assign({}, draftFilters), { tagFilters })), filterContext: filterContext })))))),
8436
8457
  React.createElement(Grid2, { size: { md: 12, xs: 12 }, style: {
8437
8458
  height: "70vh",
8438
8459
  } },
8439
8460
  React.createElement(Paper, { style: { height: "100%", width: "100%" } },
8440
- React.createElement(AgGridReact, { loading: isLoading, gridOptions: {
8461
+ React.createElement(AgGridReact, { loading: isLoading || isApplyingFilters || isFetching, gridOptions: {
8441
8462
  theme: themeDXT,
8463
+ cacheQuickFilter: true,
8442
8464
  }, rowData: formattedRows, columnDefs: columnDefs, defaultColDef: defaultColDef, onGridReady: onGridReady, getRowId: (params) => params.data.id, rowHeight: 34, headerHeight: 40, animateRows: true, loadingOverlayComponent: CenteredLazyLoading, getContextMenuItems: (e) => getContextMenuItems(e), rowSelection: "single", onRowDoubleClicked: (e) => {
8443
8465
  rowClicked(e);
8444
8466
  } })))),