@cccsaurora/howler-ui 2.17.2-patch.628 → 2.17.2-patch.630

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,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ArrowDropDown, List, Settings, TableChart, ViewComfy, ViewCompact, ViewModule } from '@mui/icons-material';
3
- import { FormLabel, Stack, ToggleButton, ToggleButtonGroup } from '@mui/material';
2
+ import { ArrowDropDown, InfoOutlined, List, Settings, TableChart, ViewComfy, ViewCompact, ViewModule } from '@mui/icons-material';
3
+ import { Checkbox, Divider, FormLabel, Stack, TextField, ToggleButton, ToggleButtonGroup, Tooltip } from '@mui/material';
4
4
  import { HitSearchContext } from '@cccsaurora/howler-ui/components/app/providers/HitSearchProvider';
5
5
  import ChipPopper from '@cccsaurora/howler-ui/components/elements/display/ChipPopper';
6
6
  import { HitLayout } from '@cccsaurora/howler-ui/components/elements/hit/HitLayout';
@@ -13,6 +13,12 @@ const LayoutSettings = () => {
13
13
  const displayType = useContextSelector(HitSearchContext, ctx => ctx.displayType);
14
14
  const setDisplayType = useContextSelector(HitSearchContext, ctx => ctx.setDisplayType);
15
15
  const [hitLayout, setHitLayout] = useMyLocalStorageItem(StorageKey.HIT_LAYOUT, false);
16
- return (_jsx(ChipPopper, { icon: _jsx(Settings, {}), deleteIcon: _jsx(ArrowDropDown, {}), toggleOnDelete: true, disablePortal: false, slotProps: { chip: { size: 'medium' } }, placement: "bottom-end", children: _jsxs(Stack, { spacing: 1, children: [_jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", spacing: 1, children: [_jsx(FormLabel, { children: t('page.settings.local.hits.display_type') }), _jsxs(ToggleButtonGroup, { exclusive: true, value: displayType, onChange: (__, value) => setDisplayType(value), size: "small", children: [_jsx(ToggleButton, { value: "list", children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(List, {}), _jsx("span", { children: t('page.settings.local.hits.display_type.list') })] }) }), _jsx(ToggleButton, { value: "grid", children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(TableChart, {}), _jsx("span", { children: t('page.settings.local.hits.display_type.grid') })] }) })] })] }), _jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", spacing: 1, children: [_jsx(FormLabel, { children: t('page.settings.local.hits.layout') }), _jsxs(ToggleButtonGroup, { exclusive: true, size: "small", value: hitLayout, onChange: (_, value) => setHitLayout(value), children: [_jsx(ToggleButton, { value: HitLayout.DENSE, children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(ViewCompact, {}), _jsx("span", { children: t('page.settings.local.hits.layout.dense') })] }) }), _jsx(ToggleButton, { value: HitLayout.NORMAL, children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(ViewModule, {}), _jsx("span", { children: t('page.settings.local.hits.layout.normal') })] }) }), _jsx(ToggleButton, { value: HitLayout.COMFY, children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(ViewComfy, {}), _jsx("span", { children: t('page.settings.local.hits.layout.comfy') })] }) })] })] })] }) }));
16
+ const [templateFieldCount, setTemplateFieldCount] = useMyLocalStorageItem(StorageKey.TEMPLATE_FIELD_COUNT, null);
17
+ return (_jsx(ChipPopper, { icon: _jsx(Tooltip, { title: t('search.layout.settings'), children: _jsx(Settings, {}) }), deleteIcon: _jsx(ArrowDropDown, {}), toggleOnDelete: true, disablePortal: false, slotProps: { chip: { size: 'medium', 'aria-label': t('search.layout.settings') } }, placement: "bottom-end", children: _jsxs(Stack, { spacing: 1, alignItems: "start", children: [_jsxs(Stack, { direction: "row", spacing: 0.5, alignItems: "center", alignSelf: "stretch", children: [_jsx(FormLabel, { id: "display_type", children: t('page.settings.local.hits.display_type') }), _jsx("div", { style: { flex: 1 } }), _jsx(Tooltip, { title: t('page.settings.local.hits.display_type.description'), children: _jsx(InfoOutlined, { fontSize: "inherit" }) })] }), _jsxs(ToggleButtonGroup, { exclusive: true, value: displayType, onChange: (__, value) => setDisplayType(value), size: "small", "aria-labelledby": "display_type", children: [_jsx(ToggleButton, { value: "list", children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(List, {}), _jsx("span", { children: t('page.settings.local.hits.display_type.list') })] }) }), _jsx(ToggleButton, { value: "grid", children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(TableChart, {}), _jsx("span", { children: t('page.settings.local.hits.display_type.grid') })] }) })] }), _jsx(Divider, { flexItem: true }), _jsxs(Stack, { direction: "row", spacing: 0.5, alignItems: "center", alignSelf: "stretch", children: [_jsx(FormLabel, { id: "layout", children: t('page.settings.local.hits.layout') }), _jsx("div", { style: { flex: 1 } }), _jsx(Tooltip, { title: t('page.settings.local.hits.layout.description'), children: _jsx(InfoOutlined, { fontSize: "inherit" }) })] }), _jsxs(ToggleButtonGroup, { exclusive: true, size: "small", value: hitLayout, onChange: (_, value) => setHitLayout(value), "aria-labelledby": "layout", children: [_jsx(ToggleButton, { value: HitLayout.DENSE, children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(ViewCompact, {}), _jsx("span", { children: t('page.settings.local.hits.layout.dense') })] }) }), _jsx(ToggleButton, { value: HitLayout.NORMAL, children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(ViewModule, {}), _jsx("span", { children: t('page.settings.local.hits.layout.normal') })] }) }), _jsx(ToggleButton, { value: HitLayout.COMFY, children: _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(ViewComfy, {}), _jsx("span", { children: t('page.settings.local.hits.layout.comfy') })] }) })] }), _jsx(Divider, { flexItem: true }), _jsxs(Stack, { direction: "row", spacing: 0.5, alignItems: "center", alignSelf: "stretch", children: [_jsx(FormLabel, { id: "field_count", children: t('page.settings.local.hits.field_count') }), _jsx("div", { style: { flex: 1 } }), _jsx(Tooltip, { title: t('page.settings.local.hits.field_count.description'), children: _jsx(InfoOutlined, { fontSize: "inherit" }) })] }), _jsxs(Stack, { direction: "row", spacing: 0.5, alignSelf: "stretch", children: [_jsx(Checkbox, { checked: templateFieldCount !== null, onChange: (_, checked) => setTemplateFieldCount(checked ? 3 : null), size: "small" }), _jsx(TextField, { type: "number", size: "small", disabled: templateFieldCount === null, value: templateFieldCount ?? 3, fullWidth: true, onChange: e => {
18
+ const val = parseInt(e.target.value);
19
+ if (!isNaN(val)) {
20
+ setTemplateFieldCount(Math.min(15, Math.max(0, val)));
21
+ }
22
+ }, inputProps: { min: 0, max: 15, 'aria-labelledby': 'field_count' } })] })] }) }));
17
23
  };
18
24
  export default LayoutSettings;
@@ -7,10 +7,8 @@ import useMatchers from '@cccsaurora/howler-ui/components/app/hooks/useMatchers'
7
7
  import { HitContext } from '@cccsaurora/howler-ui/components/app/providers/HitProvider';
8
8
  import { HitSearchContext } from '@cccsaurora/howler-ui/components/app/providers/HitSearchProvider';
9
9
  import { ParameterContext } from '@cccsaurora/howler-ui/components/app/providers/ParameterProvider';
10
- import FlexOne from '@cccsaurora/howler-ui/components/elements/addons/layout/FlexOne';
11
10
  import SearchTotal from '@cccsaurora/howler-ui/components/elements/addons/search/SearchTotal';
12
11
  import DevelopmentBanner from '@cccsaurora/howler-ui/components/elements/display/features/DevelopmentBanner';
13
- import DevelopmentIcon from '@cccsaurora/howler-ui/components/elements/display/features/DevelopmentIcon';
14
12
  import useHitSelection from '@cccsaurora/howler-ui/components/hooks/useHitSelection';
15
13
  import { useMyLocalStorageItem } from '@cccsaurora/howler-ui/components/hooks/useMyLocalStorage';
16
14
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
@@ -38,15 +36,15 @@ const HitGrid = () => {
38
36
  const query = useContextSelector(ParameterContext, ctx => ctx.query);
39
37
  const selected = useContextSelector(ParameterContext, ctx => ctx.selected);
40
38
  const [collapseMainColumn, setCollapseMainColumn] = useMyLocalStorageItem(StorageKey.GRID_COLLAPSE_COLUMN, false);
41
- const [analyticIds, setAnalyticIds] = useState({});
42
- const columnModalRef = useRef();
43
- const [columns, setColumns] = useState([
39
+ const [columns, setColumns] = useMyLocalStorageItem(StorageKey.GRID_COLUMNS, [
44
40
  'howler.outline.threat',
45
41
  'howler.outline.target',
46
42
  'howler.outline.indicators',
47
43
  'howler.outline.summary'
48
44
  ]);
49
- const [columnWidths, setColumnWidths] = useState({});
45
+ const [columnWidths, setColumnWidths] = useMyLocalStorageItem(StorageKey.GRID_COLUMN_WIDTHS, {});
46
+ const [analyticIds, setAnalyticIds] = useState({});
47
+ const columnModalRef = useRef();
50
48
  const [showAddColumn, setShowAddColumn] = useState(false);
51
49
  const resizingCol = useRef();
52
50
  const showSelectBar = useMemo(() => {
@@ -78,10 +76,10 @@ const HitGrid = () => {
78
76
  }, []);
79
77
  const onMouseUp = useCallback(() => {
80
78
  const [col, element] = resizingCol.current;
81
- setColumnWidths(_widths => ({
82
- ..._widths,
79
+ setColumnWidths({
80
+ ...columnWidths,
83
81
  [col]: element.style.width
84
- }));
82
+ });
85
83
  element.style.width = null;
86
84
  element.style.maxWidth = null;
87
85
  document.querySelectorAll(`.col-${col.replaceAll('.', '-')}`).forEach(el => {
@@ -90,7 +88,7 @@ const HitGrid = () => {
90
88
  });
91
89
  window.removeEventListener('mousemove', onMouseMove);
92
90
  window.removeEventListener('mouseup', onMouseUp);
93
- }, [onMouseMove]);
91
+ }, [columnWidths, onMouseMove, setColumnWidths]);
94
92
  const onMouseDown = useCallback((col, event) => {
95
93
  event.stopPropagation();
96
94
  event.preventDefault();
@@ -111,7 +109,7 @@ const HitGrid = () => {
111
109
  const newIndex = (columns ?? []).findIndex(entry => entry === over.id);
112
110
  setColumns(arrayMove(columns, oldIndex, newIndex));
113
111
  }
114
- }, [columns]);
112
+ }, [columns, setColumns]);
115
113
  const getSelectedId = useCallback((event) => {
116
114
  const target = event.target;
117
115
  const selectedElement = target.closest('[id]');
@@ -120,14 +118,14 @@ const HitGrid = () => {
120
118
  }
121
119
  return selectedElement.id;
122
120
  }, []);
123
- return (_jsxs(Stack, { spacing: 1, p: 2, width: "100%", sx: { overflow: 'hidden', height: `calc(100vh - ${theme.spacing(showSelectBar ? 13 : 8)})` }, children: [_jsx(DevelopmentBanner, {}), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [_jsx(Typography, { sx: { color: 'text.secondary', fontSize: '0.9em', fontStyle: 'italic', mb: 0.5, textAlign: 'left' }, variant: "body2", children: t('hit.search.prompt') }), _jsx(DevelopmentIcon, {})] }), _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsxs(Stack, { position: "relative", flex: 1, children: [_jsx(HitQuery, { searching: searching, triggerSearch: search, compact: true }), searching && (_jsx(LinearProgress, { sx: {
121
+ return (_jsxs(Stack, { spacing: 1, p: 2, width: "100%", sx: { overflow: 'hidden', height: `calc(100vh - ${theme.spacing(showSelectBar ? 13 : 8)})` }, children: [_jsx(DevelopmentBanner, {}), _jsxs(Stack, { direction: "row", justifyContent: "space-between", children: [_jsx(Typography, { sx: { color: 'text.secondary', fontSize: '0.9em', fontStyle: 'italic', mb: 0.5, textAlign: 'left' }, variant: "body2", children: t('hit.search.prompt') }), _jsx(SearchTotal, { sx: { color: 'text.secondary', fontSize: '0.9em', fontStyle: 'italic', mb: 0.5 }, variant: "body2", offset: response.offset, pageLength: response.rows, total: response.total })] }), _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsxs(Stack, { position: "relative", flex: 1, children: [_jsx(HitQuery, { searching: searching, triggerSearch: search, compact: true }), searching && (_jsx(LinearProgress, { sx: {
124
122
  position: 'absolute',
125
123
  left: 0,
126
124
  right: 0,
127
125
  bottom: 0,
128
126
  borderBottomLeftRadius: theme.shape.borderRadius,
129
127
  borderBottomRightRadius: theme.shape.borderRadius
130
- } }))] }), _jsxs(ToggleButtonGroup, { exclusive: true, value: displayType, onChange: (__, value) => setDisplayType(value), size: "small", children: [_jsx(ToggleButton, { value: "list", children: _jsx(List, {}) }), _jsx(ToggleButton, { value: "grid", children: _jsx(TableChart, {}) })] })] }), _jsxs(Stack, { direction: "row", spacing: 1, width: "100%", sx: { '& > *': { flex: 1 } }, children: [_jsx(QuerySettings, {}), response && (_jsx(SearchTotal, { sx: { alignSelf: 'center' }, color: "text.secondary", offset: response.offset, pageLength: response.rows, total: response.total })), _jsxs(Stack, { direction: "row", children: [_jsx(FlexOne, {}), _jsx(IconButton, { ref: columnModalRef, onClick: () => setShowAddColumn(true), children: _jsx(Add, { fontSize: "small" }) })] }), _jsx(AddColumnModal, { anchorEl: columnModalRef.current, open: showAddColumn, onClose: () => setShowAddColumn(false), columns: columns, addColumn: key => setColumns(_columns => [..._columns, key]) })] }), _jsxs(Stack, { component: Paper, spacing: 1, width: "100%", height: "100%", sx: { overflow: 'auto', flex: 1 }, onScroll: onScroll, children: [_jsxs(Table, { sx: { '& td,th': { px: 1, py: 0.25, whiteSpace: 'nowrap' } }, children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { sx: {
128
+ } }))] }), _jsxs(ToggleButtonGroup, { exclusive: true, value: displayType, onChange: (__, value) => setDisplayType(value), size: "small", children: [_jsx(ToggleButton, { value: "list", children: _jsx(List, {}) }), _jsx(ToggleButton, { value: "grid", children: _jsx(TableChart, {}) })] })] }), _jsxs(Stack, { direction: "row", spacing: 1, width: "100%", alignItems: "center", children: [_jsx(QuerySettings, { boxSx: { flex: 1 } }), _jsx(IconButton, { ref: columnModalRef, onClick: () => setShowAddColumn(true), children: _jsx(Add, { fontSize: "small" }) }), _jsx(AddColumnModal, { anchorEl: columnModalRef.current, open: showAddColumn, onClose: () => setShowAddColumn(false), columns: columns, addColumn: key => setColumns([...columns, key]) })] }), _jsxs(Stack, { component: Paper, spacing: 1, width: "100%", height: "100%", sx: { overflow: 'auto', flex: 1 }, onScroll: onScroll, children: [_jsxs(Table, { sx: { '& td,th': { px: 1, py: 0.25, whiteSpace: 'nowrap' } }, children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { sx: {
131
129
  borderRight: 'thin solid',
132
130
  borderRightColor: 'divider'
133
131
  }, children: _jsx(IconButton, { onClick: () => setCollapseMainColumn(!collapseMainColumn), children: collapseMainColumn ? (_jsx(FormatIndentIncrease, { fontSize: "small" })) : (_jsx(FormatIndentDecrease, { fontSize: "small" })) }) }), _jsx(DndContext, { sensors: sensors, collisionDetection: pointerWithin, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: columns, children: columns.map(col => (_jsx(ColumnHeader, { col: col, width: columnWidths[col], onMouseDown: onMouseDown, setColumns: setColumns }, col))) }) }), _jsx(TableCell, { sx: { width: '100%' } })] }) }), _jsxs(HitContextMenu, { Component: TableBody, getSelectedId: getSelectedId, children: [response?.items.map(hit => (_jsx(HitRow, { hit: hit, analyticIds: analyticIds, columns: columns, columnWidths: columnWidths, collapseMainColumn: collapseMainColumn, onClick: onClick }, hit.howler.id))), _jsx(TableRow, { children: _jsx(TableCell, { colSpan: columns.length + 2, children: _jsx(Stack, { alignItems: "center", justifyContent: "center", py: 0.5, px: 1, children: _jsx(IconButton, { onClick: () => search(query, true), children: _jsx(Search, {}) }) }) }) })] })] }), (response?.total ?? 0) < 1 && (_jsx(Stack, { direction: "row", spacing: 1, alignItems: "center", p: 1, justifyContent: "center", flex: 1, children: _jsxs(Typography, { variant: "h3", color: "text.secondary", display: "flex", flexDirection: "row", alignItems: "center", children: [_jsx(Info, { fontSize: "inherit", sx: { color: 'text.secondary', mr: 1 } }), _jsx("span", { children: t('app.list.empty') })] }) }))] })] }));
package/package.json CHANGED
@@ -101,7 +101,7 @@
101
101
  "internal-slot": "1.0.7"
102
102
  },
103
103
  "type": "module",
104
- "version": "2.17.2-patch.628",
104
+ "version": "2.17.2-patch.630",
105
105
  "exports": {
106
106
  "./i18n": "./i18n.js",
107
107
  "./index.css": "./index.css",
@@ -55,6 +55,8 @@ export declare enum StorageKey {
55
55
  SEARCH_PANE_WIDTH = "search_pane_width",
56
56
  TEMPLATE_FIELD_COUNT = "template_field_count",
57
57
  GRID_COLLAPSE_COLUMN = "grid_collapse_column",
58
+ GRID_COLUMNS = "grid_columns",
59
+ GRID_COLUMN_WIDTHS = "grid_column_widths",
58
60
  QUERY_HISTORY = "query_history",
59
61
  LOGIN_NONCE = "login_nonce",
60
62
  DISPLAY_TYPE = "display_type"
@@ -60,6 +60,8 @@ export var StorageKey;
60
60
  StorageKey["SEARCH_PANE_WIDTH"] = "search_pane_width";
61
61
  StorageKey["TEMPLATE_FIELD_COUNT"] = "template_field_count";
62
62
  StorageKey["GRID_COLLAPSE_COLUMN"] = "grid_collapse_column";
63
+ StorageKey["GRID_COLUMNS"] = "grid_columns";
64
+ StorageKey["GRID_COLUMN_WIDTHS"] = "grid_column_widths";
63
65
  StorageKey["QUERY_HISTORY"] = "query_history";
64
66
  StorageKey["LOGIN_NONCE"] = "login_nonce";
65
67
  StorageKey["DISPLAY_TYPE"] = "display_type";