@dexteel/mesf-core 7.11.2 → 7.12.0
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/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +7 -0
- package/dist/configuration/pages/log/components/Filters/TagFilter.d.ts +9 -0
- package/dist/configuration/pages/log/models/Tag.d.ts +19 -0
- package/dist/configuration/pages/log/repositories/LogsRepository.d.ts +3 -1
- package/dist/configuration/pages/log/repositories/TagsRepository.d.ts +3 -0
- package/dist/index.esm.js +275 -29
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [7.12.0](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.11.2...@dexteel/mesf-core-v7.12.0) (2026-01-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **Logs:** Implement tag filtering functionality in logs ([9dc7efa](https://github.com/dexteel/mesf-core-frontend/commit/9dc7efa6b7d337bd9bc5903c45cc7a8b13a7c6de))
|
|
9
|
+
|
|
3
10
|
## [7.11.2](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.11.1...@dexteel/mesf-core-v7.11.2) (2026-01-22)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { TagFilterContext, TagFilterType } from "../../models/Tag";
|
|
3
|
+
type Props = {
|
|
4
|
+
tagFilters: TagFilterType[];
|
|
5
|
+
setTagFilters: (filters: TagFilterType[]) => void;
|
|
6
|
+
filterContext: TagFilterContext;
|
|
7
|
+
};
|
|
8
|
+
export declare const TagFilter: ({ tagFilters, setTagFilters, filterContext, }: Props) => React.JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface Tag {
|
|
2
|
+
TagId: number;
|
|
3
|
+
TagName: string;
|
|
4
|
+
HasData: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface TagValue {
|
|
7
|
+
Value: string;
|
|
8
|
+
HasData: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface TagFilterType {
|
|
11
|
+
TagName: string;
|
|
12
|
+
Values: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface TagFilterContext {
|
|
15
|
+
startDate: Date;
|
|
16
|
+
endDate: Date | null;
|
|
17
|
+
logTypeCode: string | null;
|
|
18
|
+
tagFilters: TagFilterType[];
|
|
19
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Log } from "../models/Log";
|
|
2
|
+
import { TagFilterType } from "../models/Tag";
|
|
2
3
|
type Props = {
|
|
3
4
|
startDate: Date;
|
|
4
5
|
endDate: Date | null;
|
|
5
6
|
logTypeCode: number | string | null;
|
|
7
|
+
tagFilters?: TagFilterType[];
|
|
6
8
|
};
|
|
7
|
-
export declare const getLogs: ({ startDate, endDate, logTypeCode }: Props) => Promise<Log[]>;
|
|
9
|
+
export declare const getLogs: ({ startDate, endDate, logTypeCode, tagFilters, }: Props) => Promise<Log[]>;
|
|
8
10
|
export {};
|
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr';
|
|
2
2
|
export * from '@microsoft/signalr';
|
|
3
3
|
export { LicenseManager } from 'ag-grid-enterprise';
|
|
4
|
-
import { styled, DialogTitle as DialogTitle$1, DialogContent as DialogContent$1, DialogActions as DialogActions$1, Grid2, Button, Box, MenuItem, ListItemIcon, createTheme, TextField, Alert as Alert$2, useTheme, InputAdornment, Popover, MenuList, ListItemText, alpha, Dialog as Dialog$1, Paper, List, ListItem, Chip, SvgIcon, Typography as Typography$1, Checkbox, IconButton as IconButton$1, CircularProgress, FormControl, FormHelperText, FormControlLabel, Snackbar, DialogContentText, Badge, InputLabel, Select, Input, Divider, Card, CardContent, CardActions, Collapse, Tooltip, CssBaseline, AppBar, Toolbar, Container, Menu, Switch, Hidden, Drawer, Grid, Accordion, AccordionSummary, AccordionDetails, Tabs, Tab,
|
|
4
|
+
import { styled, DialogTitle as DialogTitle$1, DialogContent as DialogContent$1, DialogActions as DialogActions$1, Grid2, Button, Box, MenuItem, ListItemIcon, createTheme, TextField, Alert as Alert$2, useTheme, InputAdornment, Popover, MenuList, ListItemText, alpha, Dialog as Dialog$1, Paper, List, ListItem, Chip, SvgIcon, Typography as Typography$1, Checkbox, IconButton as IconButton$1, CircularProgress, FormControl, FormHelperText, FormControlLabel, Snackbar, DialogContentText, Badge, InputLabel, Select, Input, Divider, Card, CardContent, CardActions, Collapse, Tooltip, CssBaseline, AppBar, Toolbar, Container, Menu, Switch, Autocomplete, Hidden, Drawer, Grid, Accordion, AccordionSummary, AccordionDetails, Tabs, Tab, useMediaQuery, ListSubheader, ListItemButton, StyledEngineProvider, ThemeProvider, ListItemSecondaryAction } from '@mui/material';
|
|
5
5
|
import { useMutation, useQuery, useQueryClient, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import React__default, { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo, Component, lazy, Suspense } from 'react';
|
|
@@ -11,7 +11,7 @@ import { createPart, themeMaterial, provideGlobalGridOptions } from 'ag-grid-com
|
|
|
11
11
|
import { values, get, isEmpty, isNil } from 'lodash-es';
|
|
12
12
|
import { useForm, Controller } from 'react-hook-form';
|
|
13
13
|
import { isAncestor, Tree, DndProvider as DndProvider$1 } from '@minoru/react-dnd-treeview';
|
|
14
|
-
import { Alert as Alert$4, AlertTitle, Autocomplete } from '@mui/lab';
|
|
14
|
+
import { Alert as Alert$4, AlertTitle, Autocomplete as Autocomplete$1 } from '@mui/lab';
|
|
15
15
|
import { Helmet, HelmetProvider } from 'react-helmet-async';
|
|
16
16
|
import AccountTree from '@mui/icons-material/AccountTree';
|
|
17
17
|
import Settings$1 from '@mui/icons-material/Settings';
|
|
@@ -50,6 +50,8 @@ import ToggleOfIcon from '@mui/icons-material/ToggleOff';
|
|
|
50
50
|
import ToggleOnIcon from '@mui/icons-material/ToggleOn';
|
|
51
51
|
import { useComplexState } from 'use-complex-state';
|
|
52
52
|
import { createSlice } from '@reduxjs/toolkit';
|
|
53
|
+
import CheckBoxIcon from '@mui/icons-material/CheckBox';
|
|
54
|
+
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
|
|
53
55
|
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
|
|
54
56
|
import { DndProvider } from 'react-dnd';
|
|
55
57
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
@@ -7239,6 +7241,246 @@ const JobsPage = (props) => {
|
|
|
7239
7241
|
React.createElement(Jobs, null)));
|
|
7240
7242
|
};
|
|
7241
7243
|
|
|
7244
|
+
// Get all tags that have been used in logs
|
|
7245
|
+
const getLogTags = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7246
|
+
var _a;
|
|
7247
|
+
const apiService = new MESApiService();
|
|
7248
|
+
const tomorrow = new Date();
|
|
7249
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
7250
|
+
const parameters = context
|
|
7251
|
+
? [
|
|
7252
|
+
{ name: "Start", value: context.startDate },
|
|
7253
|
+
{ name: "End", value: (_a = context.endDate) !== null && _a !== void 0 ? _a : tomorrow },
|
|
7254
|
+
{
|
|
7255
|
+
name: "LogTypeCode",
|
|
7256
|
+
value: context.logTypeCode === "A" ? null : context.logTypeCode,
|
|
7257
|
+
},
|
|
7258
|
+
{
|
|
7259
|
+
name: "TagFilters",
|
|
7260
|
+
value: context.tagFilters.length > 0
|
|
7261
|
+
? JSON.stringify(context.tagFilters)
|
|
7262
|
+
: null,
|
|
7263
|
+
},
|
|
7264
|
+
]
|
|
7265
|
+
: [];
|
|
7266
|
+
const resp = yield apiService.callV2("[SYSTEM].[GetLogTags]", parameters);
|
|
7267
|
+
if (resp.ok) {
|
|
7268
|
+
const rows = get(resp, "data.tables[0].rows", []);
|
|
7269
|
+
return rows;
|
|
7270
|
+
}
|
|
7271
|
+
else {
|
|
7272
|
+
throw new Error(resp.message || "Error fetching log tags");
|
|
7273
|
+
}
|
|
7274
|
+
});
|
|
7275
|
+
// Get all distinct values for a specific tag
|
|
7276
|
+
const getLogTagValues = (tagName, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7277
|
+
var _a;
|
|
7278
|
+
const apiService = new MESApiService();
|
|
7279
|
+
const tomorrow = new Date();
|
|
7280
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
7281
|
+
// When getting values for a tag, exclude that tag from the filter context
|
|
7282
|
+
// so we show all possible values that match the OTHER filters
|
|
7283
|
+
const otherTagFilters = context === null || context === void 0 ? void 0 : context.tagFilters.filter((f) => f.TagName !== tagName);
|
|
7284
|
+
const parameters = [
|
|
7285
|
+
{ name: "TagName", value: tagName },
|
|
7286
|
+
...(context
|
|
7287
|
+
? [
|
|
7288
|
+
{ name: "Start", value: context.startDate },
|
|
7289
|
+
{ name: "End", value: (_a = context.endDate) !== null && _a !== void 0 ? _a : tomorrow },
|
|
7290
|
+
{
|
|
7291
|
+
name: "LogTypeCode",
|
|
7292
|
+
value: context.logTypeCode === "A" ? null : context.logTypeCode,
|
|
7293
|
+
},
|
|
7294
|
+
{
|
|
7295
|
+
name: "TagFilters",
|
|
7296
|
+
value: otherTagFilters && otherTagFilters.length > 0
|
|
7297
|
+
? JSON.stringify(otherTagFilters)
|
|
7298
|
+
: null,
|
|
7299
|
+
},
|
|
7300
|
+
]
|
|
7301
|
+
: []),
|
|
7302
|
+
];
|
|
7303
|
+
const resp = yield apiService.callV2("[SYSTEM].[GetLogTagValues]", parameters);
|
|
7304
|
+
if (resp.ok) {
|
|
7305
|
+
const rows = get(resp, "data.tables[0].rows", []);
|
|
7306
|
+
return rows;
|
|
7307
|
+
}
|
|
7308
|
+
else {
|
|
7309
|
+
throw new Error(resp.message || "Error fetching tag values");
|
|
7310
|
+
}
|
|
7311
|
+
});
|
|
7312
|
+
|
|
7313
|
+
const icon = React__default.createElement(CheckBoxOutlineBlankIcon, { fontSize: "small" });
|
|
7314
|
+
const checkedIcon = React__default.createElement(CheckBoxIcon, { fontSize: "small" });
|
|
7315
|
+
const useSearchLogTags = ({ startDate, endDate, logTypeCode, tagFilters, }) => {
|
|
7316
|
+
return useQuery({
|
|
7317
|
+
queryKey: [
|
|
7318
|
+
"logTags",
|
|
7319
|
+
startDate.getTime(),
|
|
7320
|
+
endDate === null || endDate === void 0 ? void 0 : endDate.getTime(),
|
|
7321
|
+
logTypeCode,
|
|
7322
|
+
tagFilters,
|
|
7323
|
+
],
|
|
7324
|
+
queryFn: () => getLogTags({ startDate, endDate, logTypeCode, tagFilters }),
|
|
7325
|
+
});
|
|
7326
|
+
};
|
|
7327
|
+
const useSearchLogTagValues = ({ tagName, startDate, endDate, logTypeCode, tagFilters, }) => {
|
|
7328
|
+
return useQuery({
|
|
7329
|
+
queryKey: [
|
|
7330
|
+
"logTagValues",
|
|
7331
|
+
tagName,
|
|
7332
|
+
startDate,
|
|
7333
|
+
endDate,
|
|
7334
|
+
logTypeCode,
|
|
7335
|
+
tagFilters,
|
|
7336
|
+
],
|
|
7337
|
+
queryFn: () => getLogTagValues(tagName, { startDate, endDate, logTypeCode, tagFilters }),
|
|
7338
|
+
enabled: !!tagName,
|
|
7339
|
+
});
|
|
7340
|
+
};
|
|
7341
|
+
const TagFilter = ({ tagFilters, setTagFilters, filterContext, }) => {
|
|
7342
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
7343
|
+
const [selectedTag, setSelectedTag] = useState(null);
|
|
7344
|
+
const [selectedValues, setSelectedValues] = useState([]);
|
|
7345
|
+
const [showOnlyWithData, setShowOnlyWithData] = useState(true);
|
|
7346
|
+
const [error, setError] = useState("");
|
|
7347
|
+
const { data: availableTags, isLoading: isLoadingTags, error: tagsError, isError: isTagsError, } = useSearchLogTags({
|
|
7348
|
+
startDate: filterContext.startDate,
|
|
7349
|
+
endDate: filterContext.endDate,
|
|
7350
|
+
logTypeCode: filterContext.logTypeCode,
|
|
7351
|
+
tagFilters,
|
|
7352
|
+
});
|
|
7353
|
+
const { data: tagValues, isLoading: isLoadingValues, error: valuesError, isError: isValuesError, } = useSearchLogTagValues({
|
|
7354
|
+
tagName: selectedTag ? selectedTag.TagName : "",
|
|
7355
|
+
startDate: filterContext.startDate,
|
|
7356
|
+
endDate: filterContext.endDate,
|
|
7357
|
+
logTypeCode: filterContext.logTypeCode,
|
|
7358
|
+
tagFilters,
|
|
7359
|
+
});
|
|
7360
|
+
const handleOpenPopover = (event) => {
|
|
7361
|
+
setAnchorEl(event.currentTarget);
|
|
7362
|
+
setSelectedTag(null);
|
|
7363
|
+
setSelectedValues([]);
|
|
7364
|
+
};
|
|
7365
|
+
const handleClosePopover = () => {
|
|
7366
|
+
setAnchorEl(null);
|
|
7367
|
+
setSelectedTag(null);
|
|
7368
|
+
setSelectedValues([]);
|
|
7369
|
+
};
|
|
7370
|
+
const handleAddFilter = () => {
|
|
7371
|
+
if (selectedTag && selectedValues.length > 0) {
|
|
7372
|
+
// Check if this tag already has a filter
|
|
7373
|
+
const existingIndex = tagFilters.findIndex((f) => f.TagName === selectedTag.TagName);
|
|
7374
|
+
const valueStrings = selectedValues.map((v) => v.Value);
|
|
7375
|
+
if (existingIndex >= 0) {
|
|
7376
|
+
// Update existing filter
|
|
7377
|
+
const newFilters = [...tagFilters];
|
|
7378
|
+
newFilters[existingIndex] = {
|
|
7379
|
+
TagName: selectedTag.TagName,
|
|
7380
|
+
Values: valueStrings,
|
|
7381
|
+
};
|
|
7382
|
+
setTagFilters(newFilters);
|
|
7383
|
+
}
|
|
7384
|
+
else {
|
|
7385
|
+
// Add new filter
|
|
7386
|
+
setTagFilters([
|
|
7387
|
+
...tagFilters,
|
|
7388
|
+
{
|
|
7389
|
+
TagName: selectedTag.TagName,
|
|
7390
|
+
Values: valueStrings,
|
|
7391
|
+
},
|
|
7392
|
+
]);
|
|
7393
|
+
}
|
|
7394
|
+
handleClosePopover();
|
|
7395
|
+
}
|
|
7396
|
+
};
|
|
7397
|
+
const handleRemoveFilter = (tagName) => {
|
|
7398
|
+
setTagFilters(tagFilters.filter((f) => f.TagName !== tagName));
|
|
7399
|
+
};
|
|
7400
|
+
const handleEditFilter = (event, filter) => {
|
|
7401
|
+
const tag = availableTags === null || availableTags === void 0 ? void 0 : availableTags.find((t) => t.TagName === filter.TagName);
|
|
7402
|
+
if (tag) {
|
|
7403
|
+
setSelectedTag(tag);
|
|
7404
|
+
setSelectedValues(filter.Values.map((v) => ({ Value: v, HasData: true })));
|
|
7405
|
+
setAnchorEl(event.currentTarget);
|
|
7406
|
+
}
|
|
7407
|
+
};
|
|
7408
|
+
const availableTagsForSelection = (availableTags === null || availableTags === void 0 ? void 0 : availableTags.filter((tag) => (!tagFilters.some((f) => f.TagName === tag.TagName) ||
|
|
7409
|
+
(selectedTag === null || selectedTag === void 0 ? void 0 : selectedTag.TagName) === tag.TagName) &&
|
|
7410
|
+
(!showOnlyWithData || tag.HasData))) || [];
|
|
7411
|
+
const availableTagValues = (tagValues === null || tagValues === void 0 ? void 0 : tagValues.filter((tv) => !showOnlyWithData || tv.HasData)) || [];
|
|
7412
|
+
const open = Boolean(anchorEl);
|
|
7413
|
+
useEffect(() => {
|
|
7414
|
+
if (tagValues && selectedValues.length > 0) {
|
|
7415
|
+
const syncedValues = selectedValues
|
|
7416
|
+
.map((sv) => tagValues.find((tv) => tv.Value === sv.Value))
|
|
7417
|
+
.filter((tv) => tv !== undefined);
|
|
7418
|
+
if (syncedValues.length > 0) {
|
|
7419
|
+
setSelectedValues(syncedValues);
|
|
7420
|
+
}
|
|
7421
|
+
}
|
|
7422
|
+
}, [tagValues]);
|
|
7423
|
+
useEffect(() => {
|
|
7424
|
+
if (isTagsError && tagsError) {
|
|
7425
|
+
setError(tagsError.message);
|
|
7426
|
+
}
|
|
7427
|
+
if (isValuesError && valuesError) {
|
|
7428
|
+
setError(valuesError.message);
|
|
7429
|
+
}
|
|
7430
|
+
}, [isTagsError, tagsError, isValuesError, valuesError]);
|
|
7431
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
7432
|
+
React__default.createElement(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" } },
|
|
7433
|
+
React__default.createElement(Typography$1, { variant: "body2", sx: { fontWeight: 500, color: "#666" } }, "Tags:"),
|
|
7434
|
+
tagFilters.map((filter) => {
|
|
7435
|
+
const tag = availableTags === null || availableTags === void 0 ? void 0 : availableTags.find((t) => t.TagName === filter.TagName);
|
|
7436
|
+
const hasData = (tag === null || tag === void 0 ? void 0 : tag.HasData) !== false;
|
|
7437
|
+
return (React__default.createElement(Chip, { key: filter.TagName, label: `${filter.TagName} = ${filter.Values.join(", ")}`, onDelete: () => handleRemoveFilter(filter.TagName), onClick: (e) => handleEditFilter(e, filter), size: "small", color: hasData ? "primary" : "default", variant: "outlined", sx: {
|
|
7438
|
+
cursor: "pointer",
|
|
7439
|
+
opacity: hasData ? 1 : 0.5,
|
|
7440
|
+
} }));
|
|
7441
|
+
}),
|
|
7442
|
+
isLoadingTags ? (React__default.createElement(CircularProgress, { size: 20 })) : (availableTagsForSelection.length > 0 && (React__default.createElement(Button, { size: "small", variant: "text", onClick: handleOpenPopover, sx: { minWidth: "auto", textTransform: "none" } }, "+ Add Tag Filter"))),
|
|
7443
|
+
React__default.createElement(Popover, { open: open, anchorEl: anchorEl, onClose: handleClosePopover, anchorOrigin: {
|
|
7444
|
+
vertical: "bottom",
|
|
7445
|
+
horizontal: "left",
|
|
7446
|
+
}, transformOrigin: {
|
|
7447
|
+
vertical: "top",
|
|
7448
|
+
horizontal: "left",
|
|
7449
|
+
} },
|
|
7450
|
+
React__default.createElement(Box, { sx: {
|
|
7451
|
+
p: 2,
|
|
7452
|
+
minWidth: 350,
|
|
7453
|
+
display: "flex",
|
|
7454
|
+
flexDirection: "column",
|
|
7455
|
+
gap: 2,
|
|
7456
|
+
} },
|
|
7457
|
+
React__default.createElement(Box, { sx: {
|
|
7458
|
+
display: "flex",
|
|
7459
|
+
justifyContent: "space-between",
|
|
7460
|
+
alignItems: "center",
|
|
7461
|
+
} },
|
|
7462
|
+
React__default.createElement(Typography$1, { variant: "subtitle2" }, selectedTag ? "Edit Tag Filter" : "Add Tag Filter"),
|
|
7463
|
+
React__default.createElement(FormControlLabel, { control: React__default.createElement(Checkbox, { size: "small", checked: showOnlyWithData, onChange: (e) => setShowOnlyWithData(e.target.checked) }), label: React__default.createElement(Typography$1, { variant: "caption" }, "Only with data"), sx: { mr: 0 } })),
|
|
7464
|
+
React__default.createElement(Autocomplete, { size: "small", options: availableTagsForSelection, getOptionLabel: (option) => option.TagName, value: selectedTag, onChange: (_, newValue) => {
|
|
7465
|
+
setSelectedTag(newValue);
|
|
7466
|
+
setSelectedValues([]);
|
|
7467
|
+
}, renderOption: (props, option) => (React__default.createElement("li", Object.assign({}, props, { style: {
|
|
7468
|
+
opacity: option.HasData ? 1 : 0.8,
|
|
7469
|
+
} }), option.TagName)), renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: "Tag Name", variant: "outlined" }))) }),
|
|
7470
|
+
selectedTag && (React__default.createElement(React__default.Fragment, null, isLoadingValues ? (React__default.createElement(Box, { sx: { display: "flex", justifyContent: "center", py: 2 } },
|
|
7471
|
+
React__default.createElement(CircularProgress, { size: 24 }))) : (React__default.createElement(Autocomplete, { multiple: true, size: "small", options: availableTagValues, getOptionLabel: (option) => option.Value, value: selectedValues, onChange: (_, newValue) => setSelectedValues(newValue), isOptionEqualToValue: (option, value) => option.Value === value.Value, disableCloseOnSelect: true, renderOption: (props, option, { selected }) => (React__default.createElement("li", Object.assign({}, props, { style: {
|
|
7472
|
+
opacity: option.HasData ? 1 : 0.8,
|
|
7473
|
+
} }),
|
|
7474
|
+
React__default.createElement(Checkbox, { icon: icon, checkedIcon: checkedIcon, style: { marginRight: 8 }, checked: selected, size: "small" }),
|
|
7475
|
+
option.Value)), renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: "Tag Values", variant: "outlined", placeholder: "Select values..." }))) })))),
|
|
7476
|
+
React__default.createElement(Box, { sx: { display: "flex", justifyContent: "flex-end", gap: 1 } },
|
|
7477
|
+
React__default.createElement(Button, { size: "small", onClick: handleClosePopover }, "Cancel"),
|
|
7478
|
+
React__default.createElement(Button, { size: "small", variant: "contained", onClick: handleAddFilter, disabled: !selectedTag || selectedValues.length === 0 }, tagFilters.some((f) => f.TagName === (selectedTag === null || selectedTag === void 0 ? void 0 : selectedTag.TagName))
|
|
7479
|
+
? "Update"
|
|
7480
|
+
: "Add"))))),
|
|
7481
|
+
React__default.createElement(ErrorModal, { error: error, onHide: () => setError("") })));
|
|
7482
|
+
};
|
|
7483
|
+
|
|
7242
7484
|
const LOG_TYPE_CODES = {
|
|
7243
7485
|
I: { id: "I", color: "#3f51b5", description: "Info" },
|
|
7244
7486
|
E: { id: "E", color: "#f44336", description: "Error" },
|
|
@@ -7384,11 +7626,12 @@ const useLogTableData = () => {
|
|
|
7384
7626
|
};
|
|
7385
7627
|
|
|
7386
7628
|
//fx obtener logs
|
|
7387
|
-
const getLogs = (_a) => __awaiter(void 0, [_a], void 0, function* ({ startDate, endDate, logTypeCode }) {
|
|
7629
|
+
const getLogs = (_a) => __awaiter(void 0, [_a], void 0, function* ({ startDate, endDate, logTypeCode, tagFilters, }) {
|
|
7388
7630
|
const apiService = new MESApiService();
|
|
7389
7631
|
const tomorrow = new Date();
|
|
7390
7632
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
7391
7633
|
const end = endDate ? endDate : tomorrow;
|
|
7634
|
+
const tagFiltersJson = tagFilters && tagFilters.length > 0 ? JSON.stringify(tagFilters) : null;
|
|
7392
7635
|
const parameters = [
|
|
7393
7636
|
{ name: "Start", value: startDate },
|
|
7394
7637
|
{ name: "End", value: end },
|
|
@@ -7396,6 +7639,7 @@ const getLogs = (_a) => __awaiter(void 0, [_a], void 0, function* ({ startDate,
|
|
|
7396
7639
|
name: "LogTypeCode",
|
|
7397
7640
|
value: logTypeCode === "A" ? null : logTypeCode,
|
|
7398
7641
|
},
|
|
7642
|
+
{ name: "TagFilters", value: tagFiltersJson },
|
|
7399
7643
|
];
|
|
7400
7644
|
const resp = yield apiService.callV2("[MES].[GetLogs]", parameters);
|
|
7401
7645
|
if (resp.ok) {
|
|
@@ -7506,13 +7750,14 @@ const useLogsOptionsFunctions = ({ setSelectedLog, setShowLogModal, handleResetB
|
|
|
7506
7750
|
};
|
|
7507
7751
|
};
|
|
7508
7752
|
|
|
7509
|
-
const useSearchLogs = ({ startDate, endDate, logTypeCode, autoRefresh, }) => {
|
|
7753
|
+
const useSearchLogs = ({ startDate, endDate, logTypeCode, autoRefresh, tagFilters, }) => {
|
|
7510
7754
|
return useQuery({
|
|
7511
|
-
queryKey: ["logs", startDate, endDate, logTypeCode],
|
|
7755
|
+
queryKey: ["logs", startDate, endDate, logTypeCode, tagFilters],
|
|
7512
7756
|
queryFn: () => getLogs({
|
|
7513
7757
|
startDate,
|
|
7514
7758
|
endDate,
|
|
7515
7759
|
logTypeCode,
|
|
7760
|
+
tagFilters,
|
|
7516
7761
|
}),
|
|
7517
7762
|
refetchInterval: autoRefresh ? 5000 : false,
|
|
7518
7763
|
});
|
|
@@ -7527,6 +7772,7 @@ const TableLogs = () => {
|
|
|
7527
7772
|
const [search, setSearch] = useState("");
|
|
7528
7773
|
const [logTypeCode, setLogTypeCode] = useState(["I", "W", "E"]);
|
|
7529
7774
|
const [autoRefresh, setAutoRefresh] = useState(false);
|
|
7775
|
+
const [tagFilters, setTagFilters] = useState([]);
|
|
7530
7776
|
const [gridAPI, setGridAPI] = useState(null);
|
|
7531
7777
|
const [error, setError] = useState("");
|
|
7532
7778
|
const [showLogModal, setShowLogModal] = useState(false);
|
|
@@ -7536,6 +7782,7 @@ const TableLogs = () => {
|
|
|
7536
7782
|
endDate,
|
|
7537
7783
|
logTypeCode: logTypeCode.join(","),
|
|
7538
7784
|
autoRefresh,
|
|
7785
|
+
tagFilters,
|
|
7539
7786
|
});
|
|
7540
7787
|
const onGridReady = (params) => {
|
|
7541
7788
|
setGridAPI(params.api);
|
|
@@ -7567,23 +7814,15 @@ const TableLogs = () => {
|
|
|
7567
7814
|
}, []);
|
|
7568
7815
|
const { showContextMenu, registerConfig } = useContextMenuMESF();
|
|
7569
7816
|
const handleResetButtonClick = () => {
|
|
7570
|
-
resetFilter();
|
|
7571
|
-
setStartDate(moment$f().add(-5, "days").hour(0).minute(0).second(0).toDate());
|
|
7572
|
-
setEndDate(moment$f().hour(23).minute(59).second(59).toDate());
|
|
7573
|
-
setSearch("");
|
|
7574
|
-
gridAPI === null || gridAPI === void 0 ? void 0 : gridAPI.setGridOption("quickFilterText", "");
|
|
7575
|
-
setLogTypeCode(["I", "W", "E"]);
|
|
7576
|
-
refetch();
|
|
7577
|
-
setError("");
|
|
7578
|
-
};
|
|
7579
|
-
// Btn reset data
|
|
7580
|
-
const resetFilter = () => {
|
|
7581
7817
|
setStartDate(moment$f().add(-5, "days").hour(0).minute(0).second(0).toDate());
|
|
7582
7818
|
setEndDate(moment$f().hour(23).minute(59).second(59).toDate());
|
|
7583
7819
|
setSearch("");
|
|
7584
7820
|
gridAPI === null || gridAPI === void 0 ? void 0 : gridAPI.setGridOption("quickFilterText", "");
|
|
7585
7821
|
setLogTypeCode(["I", "W", "E"]);
|
|
7822
|
+
setTagFilters([]);
|
|
7586
7823
|
setSelectedLog(undefined);
|
|
7824
|
+
setError("");
|
|
7825
|
+
refetch();
|
|
7587
7826
|
};
|
|
7588
7827
|
const rowClicked = (rowClickedEvent) => {
|
|
7589
7828
|
let data = rowClickedEvent.data;
|
|
@@ -7670,7 +7909,14 @@ const TableLogs = () => {
|
|
|
7670
7909
|
gridAPI === null || gridAPI === void 0 ? void 0 : gridAPI.setGridOption("quickFilterText", search);
|
|
7671
7910
|
} })),
|
|
7672
7911
|
React.createElement(Grid2, { size: { md: 1, xs: 12 }, style: { paddingTop: 8 } },
|
|
7673
|
-
React.createElement(Button, { variant: "contained", color: "inherit", onClick: handleResetButtonClick, fullWidth: true }, "Reset"))
|
|
7912
|
+
React.createElement(Button, { variant: "contained", color: "inherit", onClick: handleResetButtonClick, fullWidth: true }, "Reset")),
|
|
7913
|
+
React.createElement(Grid2, { size: { md: 12, xs: 12 }, sx: { mt: 1 } },
|
|
7914
|
+
React.createElement(TagFilter, { tagFilters: tagFilters, setTagFilters: setTagFilters, filterContext: {
|
|
7915
|
+
startDate,
|
|
7916
|
+
endDate,
|
|
7917
|
+
logTypeCode: logTypeCode.join(","),
|
|
7918
|
+
tagFilters,
|
|
7919
|
+
} })))))),
|
|
7674
7920
|
React.createElement(Grid2, { size: { md: 12, xs: 12 }, style: {
|
|
7675
7921
|
height: "70vh",
|
|
7676
7922
|
} },
|
|
@@ -9627,9 +9873,9 @@ const QueryCacheInvalidations = () => {
|
|
|
9627
9873
|
React__default.createElement(MesfModal.Content, { dividers: true },
|
|
9628
9874
|
React__default.createElement(Grid2, { container: true, spacing: 3 },
|
|
9629
9875
|
React__default.createElement(Grid2, { size: { xs: 12 } },
|
|
9630
|
-
React__default.createElement(Controller, { control: control, name: "source", render: (params) => (React__default.createElement(Autocomplete, { options: actions, getOptionLabel: (option) => `${option.ActionName}`, value: params.field.value, onChange: (_, value) => params.field.onChange(value), renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: "Select Source Action", variant: "outlined", size: "medium" }))), disabled: modal === "edit" })) })),
|
|
9876
|
+
React__default.createElement(Controller, { control: control, name: "source", render: (params) => (React__default.createElement(Autocomplete$1, { options: actions, getOptionLabel: (option) => `${option.ActionName}`, value: params.field.value, onChange: (_, value) => params.field.onChange(value), renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: "Select Source Action", variant: "outlined", size: "medium" }))), disabled: modal === "edit" })) })),
|
|
9631
9877
|
React__default.createElement(Grid2, { size: { xs: 12 } },
|
|
9632
|
-
React__default.createElement(Controller, { control: control, name: "targets", render: (params) => (React__default.createElement(Autocomplete, { multiple: true, options: actions.filter((a) => { var _a; return a.ActionId !== ((_a = control._formValues.source) === null || _a === void 0 ? void 0 : _a.ActionId); }), getOptionLabel: (option) => {
|
|
9878
|
+
React__default.createElement(Controller, { control: control, name: "targets", render: (params) => (React__default.createElement(Autocomplete$1, { multiple: true, options: actions.filter((a) => { var _a; return a.ActionId !== ((_a = control._formValues.source) === null || _a === void 0 ? void 0 : _a.ActionId); }), getOptionLabel: (option) => {
|
|
9633
9879
|
if (typeof option === "string") {
|
|
9634
9880
|
return option;
|
|
9635
9881
|
}
|
|
@@ -9928,7 +10174,7 @@ const ResultsList = ({ results, onDeleteResult, onClearAll }) => {
|
|
|
9928
10174
|
};
|
|
9929
10175
|
|
|
9930
10176
|
const SPAutocomplete = ({ procedures, value, onChange, isLoading, disabled = false, }) => {
|
|
9931
|
-
return (React__default.createElement(Autocomplete
|
|
10177
|
+
return (React__default.createElement(Autocomplete, { options: procedures, value: value, onChange: (_, newValue) => onChange(newValue), getOptionLabel: (option) => option.FullName, groupBy: (option) => option.SchemaName, disabled: disabled, isOptionEqualToValue: (option, val) => option.FullName === val.FullName, renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: "Select Stored Procedure", variant: "outlined", fullWidth: true, slotProps: {
|
|
9932
10178
|
input: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (React__default.createElement(React__default.Fragment, null, isLoading ? (React__default.createElement(CircularProgress, { color: "inherit", size: 20 })) : (params.InputProps.endAdornment))) }),
|
|
9933
10179
|
} }))), renderOption: (props, option) => (React__default.createElement("li", Object.assign({}, props, { key: option.FullName }),
|
|
9934
10180
|
option.SchemaName,
|
|
@@ -10812,7 +11058,7 @@ const SaveUpdateDeleteViewModalV2 = ({ open, mode, handleClose, view, }) => {
|
|
|
10812
11058
|
React__default.createElement("form", { onSubmit: handleSubmit(onSubmit) },
|
|
10813
11059
|
React__default.createElement(MesfModal.Content, { dividers: true, style: { padding: "15px 30px" } },
|
|
10814
11060
|
React__default.createElement(Grid2, { container: true, spacing: 1 },
|
|
10815
|
-
React__default.createElement(Grid2, { size: 12 }, mode === "create" && views.length > 0 && viewSelected ? (React__default.createElement(Autocomplete
|
|
11061
|
+
React__default.createElement(Grid2, { size: 12 }, mode === "create" && views.length > 0 && viewSelected ? (React__default.createElement(Autocomplete, { size: "small", id: "list-of-views", options: views, defaultValue: viewSelected, getOptionLabel: (option) => {
|
|
10816
11062
|
if (typeof option === "string") {
|
|
10817
11063
|
return option;
|
|
10818
11064
|
}
|
|
@@ -11242,7 +11488,7 @@ const HeaderSectionV2 = React__default.memo(({ autoRefresh, setAutoRefresh, setC
|
|
|
11242
11488
|
backgroundColor: "white",
|
|
11243
11489
|
width: "100%",
|
|
11244
11490
|
} },
|
|
11245
|
-
React__default.createElement(Autocomplete
|
|
11491
|
+
React__default.createElement(Autocomplete, { size: "small", id: "view-selector", options: views, getOptionLabel: (option) => option.ViewName, value: viewSelected, isOptionEqualToValue: (option, value) => option.ViewId === (value === null || value === void 0 ? void 0 : value.ViewId), onChange: handleViewChange, noOptionsText: "No views available", renderOption: (props, option) => (React__default.createElement(Box, Object.assign({}, props, { component: "li", style: {
|
|
11246
11492
|
display: "flex",
|
|
11247
11493
|
justifyContent: "space-between",
|
|
11248
11494
|
width: "100%",
|
|
@@ -12163,7 +12409,7 @@ const BitSelectorModal = ({ open, handleClose, viewTags, onAddBits, existingBitT
|
|
|
12163
12409
|
React__default.createElement(Grid2, { container: true, spacing: 2 },
|
|
12164
12410
|
React__default.createElement(Grid2, { size: 12 },
|
|
12165
12411
|
React__default.createElement(Typography$1, { variant: "subtitle2", sx: { mb: 1 } }, "Select Source Tag"),
|
|
12166
|
-
React__default.createElement(Autocomplete
|
|
12412
|
+
React__default.createElement(Autocomplete, { size: "small", id: "source-tag-selector", options: availableTags, getOptionLabel: (option) => option.Alias || option.TagName, value: selectedTag, onChange: handleTagChange, noOptionsText: "No tags available in current view", renderOption: (props, option) => (React__default.createElement(Box, Object.assign({}, props, { component: "li" }),
|
|
12167
12413
|
React__default.createElement(Box, { sx: {
|
|
12168
12414
|
display: "flex",
|
|
12169
12415
|
justifyContent: "space-between",
|
|
@@ -12273,7 +12519,7 @@ const LoadViewModalV2 = ({ open, handleClose }) => {
|
|
|
12273
12519
|
React__default.createElement("input", { type: "checkbox", checked: allViewsChecked, onChange: handleAllViewsCheckbox }),
|
|
12274
12520
|
React__default.createElement(Typography$1, null, "All Views")))),
|
|
12275
12521
|
React__default.createElement(Grid2, { size: 12 },
|
|
12276
|
-
React__default.createElement(Autocomplete
|
|
12522
|
+
React__default.createElement(Autocomplete, { size: "small", id: "list-of-views", noOptionsText: allViewsChecked
|
|
12277
12523
|
? "No views detected, please create a new view"
|
|
12278
12524
|
: "No public views detected, please create a new view", options: displayedViews, getOptionLabel: (option) => option.ViewName, onChange: (ev, val) => setOptionSelected(val), defaultValue: optionSelected || viewSelected, style: { width: "100%" }, renderOption: (props, option) => (React__default.createElement(Box, Object.assign({}, props, { component: "li" }),
|
|
12279
12525
|
React__default.createElement(Box, { sx: {
|
|
@@ -15501,7 +15747,7 @@ const AssetsFilter = ({ label = "Asset", value, onChange, filterAreaAssets = fal
|
|
|
15501
15747
|
];
|
|
15502
15748
|
const selectedOption = options.find((option) => option.value === (value || null)) || options[0];
|
|
15503
15749
|
return (React__default.createElement(React__default.Fragment, null,
|
|
15504
|
-
React__default.createElement(Autocomplete
|
|
15750
|
+
React__default.createElement(Autocomplete, { options: filterAreaAssets ? options.filter((o) => o.isAreaAsset) : options, value: selectedOption, onChange: (event, newValue) => {
|
|
15505
15751
|
var _a;
|
|
15506
15752
|
if (newValue) {
|
|
15507
15753
|
onChange((_a = newValue.value) !== null && _a !== void 0 ? _a : null);
|
|
@@ -15592,7 +15838,7 @@ const ShiftAutocomplete = ({ currentShiftId, value, onShiftSelected, disabled, s
|
|
|
15592
15838
|
return (React__default.createElement(React__default.Fragment, null,
|
|
15593
15839
|
React__default.createElement(Grid2, { container: true },
|
|
15594
15840
|
React__default.createElement(Grid2, { size: { xs: 12 } },
|
|
15595
|
-
React__default.createElement(Autocomplete, { loading: isLoading, options: rows || [], getOptionLabel: (option) => {
|
|
15841
|
+
React__default.createElement(Autocomplete$1, { loading: isLoading, options: rows || [], getOptionLabel: (option) => {
|
|
15596
15842
|
return `${moment$c
|
|
15597
15843
|
.utc(option.ProductionDate)
|
|
15598
15844
|
.format("MM/DD/YYYY")} - ${option.Shift} - ${option.Crew}`;
|
|
@@ -15620,7 +15866,7 @@ const ShiftSelector = ({ label = "Shift - Crew", value, onChange = () => { }, fi
|
|
|
15620
15866
|
}
|
|
15621
15867
|
}, [isError, e]);
|
|
15622
15868
|
return (React__default.createElement(React__default.Fragment, null,
|
|
15623
|
-
React__default.createElement(Autocomplete, { id: "clear-on-escape", clearOnEscape: true, options: shifts || [], getOptionLabel: (option) => `${option.CurrentShift} - ${option.CurrentCrew}`, disabled: disabled, renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: label, variant: "outlined", fullWidth: true, size: "small", error: !!fieldError, helperText: fieldError === null || fieldError === void 0 ? void 0 : fieldError.message, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (React__default.createElement(React__default.Fragment, null, isLoading ? (React__default.createElement(CircularProgress, { color: "inherit", size: 20 })) : (React__default.createElement(React__default.Fragment, null, params.InputProps.endAdornment)))) }) }))), value: selectedShift, onChange: (event, newValue) => {
|
|
15869
|
+
React__default.createElement(Autocomplete$1, { id: "clear-on-escape", clearOnEscape: true, options: shifts || [], getOptionLabel: (option) => `${option.CurrentShift} - ${option.CurrentCrew}`, disabled: disabled, renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: label, variant: "outlined", fullWidth: true, size: "small", error: !!fieldError, helperText: fieldError === null || fieldError === void 0 ? void 0 : fieldError.message, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (React__default.createElement(React__default.Fragment, null, isLoading ? (React__default.createElement(CircularProgress, { color: "inherit", size: 20 })) : (React__default.createElement(React__default.Fragment, null, params.InputProps.endAdornment)))) }) }))), value: selectedShift, onChange: (event, newValue) => {
|
|
15624
15870
|
var _a;
|
|
15625
15871
|
onChange((_a = newValue === null || newValue === void 0 ? void 0 : newValue.CurrentShiftId) !== null && _a !== void 0 ? _a : null);
|
|
15626
15872
|
} }),
|
|
@@ -17858,7 +18104,7 @@ const SectionSelector = ({ value, onChange, topSectionsCount = 5, disabled = fal
|
|
|
17858
18104
|
gap: 1,
|
|
17859
18105
|
flexWrap: "wrap",
|
|
17860
18106
|
} },
|
|
17861
|
-
React__default.createElement(Autocomplete
|
|
18107
|
+
React__default.createElement(Autocomplete, { open: open, onOpen: () => setOpen(true), onClose: () => setOpen(false), value: value, onChange: (_, newValue) => onChange(newValue), inputValue: inputValue, onInputChange: (_, newInputValue) => setInputValue(newInputValue), options: options, loading: loading, disabled: disabled, getOptionLabel: (option) => option.SectionName, isOptionEqualToValue: (option, value) => option.SectionId === value.SectionId, sx: { minWidth: 120, maxWidth: 150 }, renderOption: (props, option) => (React__default.createElement(Box, Object.assign({ component: "li" }, props, { key: option.SectionId, sx: { display: "flex", justifyContent: "space-between" } }),
|
|
17862
18108
|
React__default.createElement(Typography$1, { fontWeight: 500 }, option.SectionName))), renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: label, placeholder: "####", size: "small", slotProps: {
|
|
17863
18109
|
input: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (React__default.createElement(React__default.Fragment, null,
|
|
17864
18110
|
loading ? (React__default.createElement(CircularProgress, { color: "inherit", size: 16 })) : null,
|
|
@@ -17904,7 +18150,7 @@ const SectionMultiSelect = ({ value, onChange, topSectionsCount = 5, disabled =
|
|
|
17904
18150
|
gap: 1,
|
|
17905
18151
|
flexWrap: "wrap",
|
|
17906
18152
|
} },
|
|
17907
|
-
React__default.createElement(Autocomplete
|
|
18153
|
+
React__default.createElement(Autocomplete, { multiple: true, open: open, onOpen: () => setOpen(true), onClose: () => setOpen(false), value: value, onChange: (_, newValue) => onChange(newValue), inputValue: inputValue, onInputChange: (_, newInputValue) => setInputValue(newInputValue), options: options, loading: loading, disabled: disabled, getOptionLabel: (option) => option.SectionName, isOptionEqualToValue: (option, val) => option.SectionId === val.SectionId, limitTags: 2, size: "small", sx: { minWidth: 200, flex: 1 }, renderOption: (props, option) => (React__default.createElement(Box, Object.assign({ component: "li" }, props, { key: option.SectionId, sx: { display: "flex", justifyContent: "space-between" } }),
|
|
17908
18154
|
React__default.createElement(Typography$1, { fontWeight: 500 }, option.SectionName))), renderInput: (params) => (React__default.createElement(TextField, Object.assign({}, params, { label: label, placeholder: value.length === 0 ? "All sections" : "", size: "small", slotProps: {
|
|
17909
18155
|
input: Object.assign(Object.assign({}, params.InputProps), { endAdornment: (React__default.createElement(React__default.Fragment, null,
|
|
17910
18156
|
loading ? (React__default.createElement(CircularProgress, { color: "inherit", size: 16 })) : null,
|