@cccsaurora/howler-ui 2.19.0-dev.1085 → 2.19.0-dev.1143
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/components/app/App.js +4 -2
- package/components/app/providers/GridColumnsProvider.d.ts +52 -0
- package/components/app/providers/GridColumnsProvider.js +177 -0
- package/components/app/providers/GridColumnsProvider.test.js +255 -0
- package/components/elements/hit/HitContextMenu.test.d.ts +1 -0
- package/components/elements/hit/HitLabels.test.d.ts +1 -0
- package/components/elements/hit/HitLabels.test.js +77 -0
- package/components/elements/hit/HitLinks.d.ts +5 -4
- package/components/elements/hit/HitLinks.js +28 -10
- package/components/elements/hit/HitNotebooks.js +23 -22
- package/components/elements/hit/NotebookTooltip.d.ts +3 -0
- package/components/elements/hit/NotebookTooltip.js +8 -0
- package/components/elements/hit/PivotTooltip.d.ts +7 -0
- package/components/elements/hit/PivotTooltip.js +9 -0
- package/components/elements/hit/RelatedLinkTooltip.d.ts +6 -0
- package/components/elements/hit/RelatedLinkTooltip.js +8 -0
- package/components/elements/hit/ResolvePivotUrl.d.ts +4 -0
- package/components/elements/hit/ResolvePivotUrl.js +22 -0
- package/components/{routes/hits/search → elements/hit}/grid/ColumnHeader.d.ts +2 -1
- package/components/{routes/hits/search → elements/hit}/grid/ColumnHeader.js +3 -3
- package/components/{routes/hits/search → elements/hit}/grid/HitRow.d.ts +1 -1
- package/components/elements/hit/grid/HitTable.d.ts +12 -0
- package/components/elements/hit/grid/HitTable.js +82 -0
- package/components/elements/hit/related/PivotLink.d.ts +3 -0
- package/components/elements/hit/related/PivotLink.js +5 -2
- package/components/elements/hit/related/RelatedLink.d.ts +1 -0
- package/components/elements/hit/related/RelatedLink.js +18 -15
- package/components/elements/view/LayoutToggle.d.ts +8 -0
- package/components/elements/view/LayoutToggle.js +12 -0
- package/components/elements/view/ViewTitle.d.ts +3 -0
- package/components/elements/view/ViewTitle.js +6 -3
- package/components/routes/hits/search/HitBrowser.js +2 -1
- package/components/routes/hits/search/SearchPane.js +6 -8
- package/components/routes/hits/search/ViewLink.js +3 -2
- package/components/routes/hits/search/grid/HitGrid.js +17 -85
- package/components/routes/hits/search/shared/LayoutSettings.js +25 -0
- package/components/routes/hits/search/shared/SearchActionMenu.d.ts +4 -0
- package/components/routes/hits/search/shared/SearchActionMenu.js +17 -0
- package/components/routes/home/ViewCard.js +1 -1
- package/components/routes/views/ViewComposer.js +32 -6
- package/locales/en/translation.json +11 -3
- package/locales/fr/translation.json +11 -3
- package/models/entities/generated/Column.d.ts +7 -0
- package/models/entities/generated/Host.d.ts +1 -0
- package/models/entities/generated/Settings.d.ts +4 -0
- package/package.json +2 -1
- package/utils/stringUtils.d.ts +1 -0
- package/utils/stringUtils.js +7 -0
- package/utils/stringUtils.test.js +21 -1
- package/components/routes/hits/search/LayoutSettings.js +0 -24
- /package/components/{routes/hits/search/HitContextMenu.test.d.ts → app/providers/GridColumnsProvider.test.d.ts} +0 -0
- /package/components/{routes/hits/search → elements/hit}/HitContextMenu.d.ts +0 -0
- /package/components/{routes/hits/search → elements/hit}/HitContextMenu.js +0 -0
- /package/components/{routes/hits/search → elements/hit}/HitContextMenu.test.js +0 -0
- /package/components/{routes/hits/search → elements/hit}/grid/AddColumnModal.d.ts +0 -0
- /package/components/{routes/hits/search → elements/hit}/grid/AddColumnModal.js +0 -0
- /package/components/{routes/hits/search → elements/hit}/grid/EnhancedCell.d.ts +0 -0
- /package/components/{routes/hits/search → elements/hit}/grid/EnhancedCell.js +0 -0
- /package/components/{routes/hits/search → elements/hit}/grid/HitRow.js +0 -0
- /package/components/routes/hits/search/{BundleParentMenu.d.ts → shared/BundleParentMenu.d.ts} +0 -0
- /package/components/routes/hits/search/{BundleParentMenu.js → shared/BundleParentMenu.js} +0 -0
- /package/components/routes/hits/search/{LayoutSettings.d.ts → shared/LayoutSettings.d.ts} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Avatar, Backdrop, Box, Button, Chip, CircularProgress, ClickAwayListener, Fade, MenuItem, Paper, Popper, Stack, TextField } from '@mui/material';
|
|
2
|
+
import { Avatar, Backdrop, Box, Button, Chip, CircularProgress, ClickAwayListener, Fade, MenuItem, Paper, Popper, Stack, TextField, Tooltip } from '@mui/material';
|
|
3
3
|
import api from '@cccsaurora/howler-ui/api';
|
|
4
4
|
import { ApiConfigContext } from '@cccsaurora/howler-ui/components/app/providers/ApiConfigProvider';
|
|
5
5
|
import { ModalContext } from '@cccsaurora/howler-ui/components/app/providers/ModalProvider';
|
|
6
|
+
import NotebookTooltip from '@cccsaurora/howler-ui/components/elements/hit/NotebookTooltip';
|
|
6
7
|
import useMyApi from '@cccsaurora/howler-ui/components/hooks/useMyApi';
|
|
7
8
|
import useMySnackbar from '@cccsaurora/howler-ui/components/hooks/useMySnackbar';
|
|
8
9
|
import { memo, useCallback, useContext, useEffect, useState } from 'react';
|
|
@@ -124,26 +125,26 @@ const HitNotebooks = ({ analytic, selectedNotebook, hit, compact }) => {
|
|
|
124
125
|
MenuProps: {
|
|
125
126
|
style: { zIndex: 35001 }
|
|
126
127
|
}
|
|
127
|
-
}, defaultValue: selectedNotebook ? analytic?.notebooks.find(n => n.name === selectedNotebook).value : '', children: [_jsx(MenuItem, { disabled: true, value: "", children: _jsx("em", { children: t('hit.notebook.select') }) }), analytic?.notebooks.sort(safeStringPropertyCompare('detection')).map(e => (_jsx(MenuItem, { value: e.value, children: _jsxs(Stack, { direction: 'row', sx: { width: '100%' }, children: [e.name, e.detection && (_jsxs(_Fragment, { children: [_jsx(Box, { flex: 1 }), _jsx(Chip, { label: e.detection, size: "small" })] }))] }) }, e.value)))] }), _jsx(Button, { variant: "outlined", disabled: loadedNotebook.name === '' || envs.length === 0, color: "success", onClick: () => checkJupyhub(), children: t('hit.notebook.goTo') })] })] }) })) }), _jsx(HowlerCard, { variant: compact ? 'outlined' : 'elevation', onClick: handleToggle, sx: [
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
128
|
+
}, defaultValue: selectedNotebook ? analytic?.notebooks.find(n => n.name === selectedNotebook).value : '', children: [_jsx(MenuItem, { disabled: true, value: "", children: _jsx("em", { children: t('hit.notebook.select') }) }), analytic?.notebooks.sort(safeStringPropertyCompare('detection')).map(e => (_jsx(MenuItem, { value: e.value, children: _jsxs(Stack, { direction: 'row', sx: { width: '100%' }, children: [e.name, e.detection && (_jsxs(_Fragment, { children: [_jsx(Box, { flex: 1 }), _jsx(Chip, { label: e.detection, size: "small" })] }))] }) }, e.value)))] }), _jsx(Button, { variant: "outlined", disabled: loadedNotebook.name === '' || envs.length === 0, color: "success", onClick: () => checkJupyhub(), children: t('hit.notebook.goTo') })] })] }) })) }), _jsx(Tooltip, { title: _jsx(NotebookTooltip, {}), children: _jsx("span", { children: _jsx(HowlerCard, { variant: compact ? 'outlined' : 'elevation', onClick: handleToggle, sx: [
|
|
129
|
+
theme => ({
|
|
130
|
+
cursor: 'pointer',
|
|
131
|
+
backgroundColor: 'transparent',
|
|
132
|
+
transition: theme.transitions.create(['border-color']),
|
|
133
|
+
'&:hover': { borderColor: 'primary.main', '& a': { textDecoration: 'underline' } },
|
|
134
|
+
'& > div': {
|
|
135
|
+
height: '100%'
|
|
136
|
+
},
|
|
137
|
+
'& a': { textDecoration: 'none', color: 'text.primary' }
|
|
138
|
+
}),
|
|
139
|
+
!compact && { border: 'thin solid', borderColor: 'transparent' }
|
|
140
|
+
], children: _jsxs(Stack, { direction: "row", p: 1, spacing: 1, alignItems: "center", children: [_jsx(Avatar, { variant: "rounded", src: '/images/jupyter_notebook_file_icon.png', sx: [
|
|
141
|
+
theme => ({
|
|
142
|
+
width: theme.spacing(3),
|
|
143
|
+
height: theme.spacing(3),
|
|
144
|
+
'& img': {
|
|
145
|
+
objectFit: 'contain'
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
], children: 'jupyter_notebook_file_icon.png' }), t('hit.notebook.tooltip')] }) }) }) })] }) })));
|
|
148
149
|
};
|
|
149
150
|
export default memo(HitNotebooks);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Typography } from '@mui/material';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
const NotebookTooltip = () => {
|
|
5
|
+
const { t } = useTranslation();
|
|
6
|
+
return (_jsxs(Box, { sx: { maxWidth: 300 }, children: [_jsx(Typography, { variant: "subtitle2", children: t('notebook.title') }), _jsx(Typography, { variant: "body2", color: "text.secondary", children: t('notebook.opens.panel') })] }));
|
|
7
|
+
};
|
|
8
|
+
export default NotebookTooltip;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Link, Typography } from '@mui/material';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
const PivotTooltip = ({ dossier, resolvedUrl }) => {
|
|
5
|
+
const dossierUrl = `/dossiers/${dossier.dossier_id}/edit?tab=leads&query=${encodeURIComponent(dossier.query)}`;
|
|
6
|
+
const { t } = useTranslation();
|
|
7
|
+
return (_jsxs(Box, { sx: { maxWidth: 300 }, children: [_jsx(Typography, { variant: "subtitle2", children: dossier.title }), _jsx(Typography, { variant: "body2", color: "text.secondary", children: dossier.owner }), _jsx(Typography, { variant: "body2", sx: { mt: 2 }, children: dossier.leads?.[0]?.content?.slice(0, 120) ?? t('pivot.description.none') }), _jsxs(Box, { sx: { mt: 2, wordBreak: 'break-all' }, children: [_jsx(Typography, { variant: "caption", display: "block", children: t('pivot.url') }), _jsx(Link, { href: resolvedUrl, target: "_blank", rel: "noopener noreferrer", underline: "hover", children: resolvedUrl })] }), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Link, { href: dossierUrl, target: "_blank", rel: "noopener noreferrer", underline: "hover", children: t('pivot.dossier.open') }) })] }));
|
|
8
|
+
};
|
|
9
|
+
export default PivotTooltip;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Link, Typography } from '@mui/material';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
const RelatedLinkTooltip = ({ title, href }) => {
|
|
5
|
+
const { t } = useTranslation();
|
|
6
|
+
return (_jsxs(Box, { sx: { maxWidth: 300 }, children: [_jsx(Typography, { variant: "subtitle2", children: title }), _jsx(Box, { sx: { mt: 1, wordBreak: 'break-all' }, children: _jsx(Link, { href: href, target: "_blank", rel: "noopener noreferrer", underline: "hover", children: href }) }), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Link, { href: href, target: "_blank", rel: "noopener noreferrer", underline: "hover", children: t('hit.header.link') }) })] }));
|
|
7
|
+
};
|
|
8
|
+
export default RelatedLinkTooltip;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Dossier } from '@cccsaurora/howler-ui/models/entities/generated/Dossier';
|
|
2
|
+
import type { Hit } from '@cccsaurora/howler-ui/models/entities/generated/Hit';
|
|
3
|
+
declare const resolvePivotUrl: (pivot: NonNullable<Dossier["pivots"]>[number], currentHit?: Hit) => string;
|
|
4
|
+
export default resolvePivotUrl;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Handlebars from 'handlebars';
|
|
2
|
+
import { flattenDeep } from '@cccsaurora/howler-ui/utils/utils';
|
|
3
|
+
const resolvePivotUrl = (pivot, currentHit) => {
|
|
4
|
+
const flatHit = flattenDeep(currentHit ?? {});
|
|
5
|
+
const templateObject = Object.fromEntries((pivot.mappings ?? []).map(mapping => {
|
|
6
|
+
const value = mapping.field === 'custom'
|
|
7
|
+
? mapping.custom_value
|
|
8
|
+
: Array.isArray(flatHit[mapping.field])
|
|
9
|
+
? flatHit[mapping.field][0]
|
|
10
|
+
: flatHit[mapping.field];
|
|
11
|
+
return [mapping.key, value];
|
|
12
|
+
}));
|
|
13
|
+
try {
|
|
14
|
+
return Handlebars.compile(pivot.value)(templateObject);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.error(`Failed to compile pivot template for value "${pivot.value}":`, e);
|
|
19
|
+
return pivot.value;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export default resolvePivotUrl;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type FC, type SetStateAction } from 'react';
|
|
2
2
|
declare const ColumnHeader: FC<{
|
|
3
|
-
width:
|
|
3
|
+
width: number;
|
|
4
4
|
col: string;
|
|
5
|
+
colSource?: string[];
|
|
5
6
|
setColumns: (val: SetStateAction<string[]>) => void;
|
|
6
7
|
onMouseDown: (col: string, event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
|
7
8
|
}>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useSortable } from '@dnd-kit/sortable';
|
|
3
3
|
import { CSS } from '@dnd-kit/utilities';
|
|
4
|
-
import { DragIndicator, Remove } from '@mui/icons-material';
|
|
4
|
+
import { DragIndicator, JoinFull, Remove } from '@mui/icons-material';
|
|
5
5
|
import { Box, IconButton, Stack, TableCell, Tooltip, useTheme } from '@mui/material';
|
|
6
6
|
import { ApiConfigContext } from '@cccsaurora/howler-ui/components/app/providers/ApiConfigProvider';
|
|
7
7
|
import FlexOne from '@cccsaurora/howler-ui/components/elements/addons/layout/FlexOne';
|
|
8
8
|
import { useContext } from 'react';
|
|
9
|
-
const ColumnHeader = ({ col, width, setColumns, onMouseDown }) => {
|
|
9
|
+
const ColumnHeader = ({ col, width, colSource, setColumns, onMouseDown }) => {
|
|
10
10
|
const theme = useTheme();
|
|
11
11
|
const { config } = useContext(ApiConfigContext);
|
|
12
12
|
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: col });
|
|
@@ -15,7 +15,7 @@ const ColumnHeader = ({ col, width, setColumns, onMouseDown }) => {
|
|
|
15
15
|
borderRightColor: 'divider',
|
|
16
16
|
py: 0.5,
|
|
17
17
|
position: 'relative'
|
|
18
|
-
}, style: { transform: CSS.Translate.toString(transform), transition }, children: _jsxs(Stack, { className: `col-${col.replaceAll('.', '-')}`, direction: "row", spacing: 1, alignItems: "center", sx: [{ minWidth: '220px' }, !!width ? { width, maxWidth: width } : { maxWidth: '300px' }], children: [_jsx(Tooltip, { title: config.indexes.hit[col].description, children: _jsx("span", { children: col }) }), _jsx(FlexOne, {}), _jsx(IconButton, { size: "small", sx: { fontSize: '1rem' }, onClick: () => setColumns(_columns => _columns.filter(_col => _col !== col)), children: _jsx(Remove, { fontSize: "inherit" }) }), _jsx(DragIndicator, { fontSize: "small", sx: { cursor: 'grab' }, ...attributes, ...listeners }), _jsx(Box, { sx: {
|
|
18
|
+
}, style: { transform: CSS.Translate.toString(transform), transition }, children: _jsxs(Stack, { className: `col-${col.replaceAll('.', '-')}`, direction: "row", spacing: 1, alignItems: "center", sx: [{ minWidth: '220px' }, !!width ? { width, maxWidth: width } : { maxWidth: '300px' }], children: [_jsx(Tooltip, { title: config.indexes.hit[col].description, children: _jsx("span", { children: col }) }), colSource?.length > 1 && (_jsx(Tooltip, { title: colSource.join(', '), children: _jsx(JoinFull, { fontSize: "small" }) })), _jsx(FlexOne, {}), _jsx(IconButton, { size: "small", sx: { fontSize: '1rem' }, onClick: () => setColumns(_columns => _columns.filter(_col => _col !== col)), children: _jsx(Remove, { fontSize: "inherit" }) }), _jsx(DragIndicator, { fontSize: "small", sx: { cursor: 'grab' }, ...attributes, ...listeners }), _jsx(Box, { sx: {
|
|
19
19
|
position: 'absolute',
|
|
20
20
|
top: theme.spacing(0.75),
|
|
21
21
|
bottom: theme.spacing(0.75),
|
|
@@ -3,7 +3,7 @@ declare const _default: import("react").NamedExoticComponent<{
|
|
|
3
3
|
hit: Hit;
|
|
4
4
|
analyticIds: Record<string, string>;
|
|
5
5
|
columns: string[];
|
|
6
|
-
columnWidths: Record<string,
|
|
6
|
+
columnWidths: Record<string, number>;
|
|
7
7
|
collapseMainColumn: boolean;
|
|
8
8
|
onClick: (e: React.MouseEvent<HTMLDivElement>, hit: Hit) => void;
|
|
9
9
|
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Hit } from '@cccsaurora/howler-ui/models/entities/generated/Hit';
|
|
2
|
+
import type { WithMetadata } from '@cccsaurora/howler-ui/models/WithMetadata';
|
|
3
|
+
import React, { type PropsWithChildren } from 'react';
|
|
4
|
+
declare const HitTable: ({ query, items, refreshItems, ContextMenu, contextMenuProps, onItemClick }: {
|
|
5
|
+
query: string;
|
|
6
|
+
items?: WithMetadata<Hit>[];
|
|
7
|
+
refreshItems?: (query: string, append?: boolean) => void;
|
|
8
|
+
ContextMenu?: React.FC<PropsWithChildren<object>>;
|
|
9
|
+
contextMenuProps?: object;
|
|
10
|
+
onItemClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>, hit: Hit) => void;
|
|
11
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default HitTable;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DndContext, KeyboardSensor, PointerSensor, pointerWithin, useSensor, useSensors } from '@dnd-kit/core';
|
|
3
|
+
import { arrayMove, SortableContext, sortableKeyboardCoordinates } from '@dnd-kit/sortable';
|
|
4
|
+
import { FormatIndentDecrease, FormatIndentIncrease, Search } from '@mui/icons-material';
|
|
5
|
+
import { IconButton, Stack, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material';
|
|
6
|
+
import useMatchers from '@cccsaurora/howler-ui/components/app/hooks/useMatchers';
|
|
7
|
+
import { GridColumnsContext } from '@cccsaurora/howler-ui/components/app/providers/GridColumnsProvider';
|
|
8
|
+
import ColumnHeader from '@cccsaurora/howler-ui/components/elements/hit/grid/ColumnHeader';
|
|
9
|
+
import { useMyLocalStorageItem } from '@cccsaurora/howler-ui/components/hooks/useMyLocalStorage';
|
|
10
|
+
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
|
11
|
+
import { StorageKey } from '@cccsaurora/howler-ui/utils/constants';
|
|
12
|
+
import HitRow from './HitRow';
|
|
13
|
+
const HitTable = ({ query, items, refreshItems, ContextMenu, contextMenuProps, onItemClick }) => {
|
|
14
|
+
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
15
|
+
const { getMatchingAnalytic } = useMatchers();
|
|
16
|
+
const [collapseMainColumn, setCollapseMainColumn] = useMyLocalStorageItem(StorageKey.GRID_COLLAPSE_COLUMN, false);
|
|
17
|
+
const [analyticIds, setAnalyticIds] = useState({});
|
|
18
|
+
const { columns, columnWidths, columnSources, setColumnWidth, setColumns, isReady } = useContext(GridColumnsContext);
|
|
19
|
+
const resizingCol = useRef();
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
items?.forEach(hit => {
|
|
22
|
+
if (!analyticIds[hit.howler.analytic]) {
|
|
23
|
+
getMatchingAnalytic(hit).then(_analytic => {
|
|
24
|
+
if (_analytic) {
|
|
25
|
+
setAnalyticIds(_analyticIds => ({ ..._analyticIds, [hit.howler.analytic]: _analytic.analytic_id }));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
|
+
}, [analyticIds, items]);
|
|
32
|
+
const onMouseMove = useCallback((event) => {
|
|
33
|
+
event.stopPropagation();
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
const { col, width } = resizingCol.current;
|
|
36
|
+
const newWidth = width + event.movementX;
|
|
37
|
+
document.querySelectorAll(`.col-${col.replaceAll('.', '-')}`).forEach(el => {
|
|
38
|
+
el.style.maxWidth = newWidth + 'px';
|
|
39
|
+
el.style.width = newWidth + 'px';
|
|
40
|
+
});
|
|
41
|
+
resizingCol.current.width = newWidth;
|
|
42
|
+
}, []);
|
|
43
|
+
const onMouseUp = useCallback(() => {
|
|
44
|
+
const { col, width, element } = resizingCol.current;
|
|
45
|
+
if (isReady) {
|
|
46
|
+
setColumnWidth(col, Math.round(width));
|
|
47
|
+
}
|
|
48
|
+
element.style.width = null;
|
|
49
|
+
element.style.maxWidth = null;
|
|
50
|
+
document.querySelectorAll(`.col-${col.replaceAll('.', '-')}`).forEach(el => {
|
|
51
|
+
el.style.maxWidth = null;
|
|
52
|
+
el.style.width = null;
|
|
53
|
+
});
|
|
54
|
+
window.removeEventListener('mousemove', onMouseMove);
|
|
55
|
+
window.removeEventListener('mouseup', onMouseUp);
|
|
56
|
+
}, [onMouseMove, setColumnWidth, isReady]);
|
|
57
|
+
const onMouseDown = useCallback((col, event) => {
|
|
58
|
+
event.stopPropagation();
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
const element = event.target.parentElement;
|
|
61
|
+
const rect = element.getBoundingClientRect();
|
|
62
|
+
resizingCol.current = { col, width: rect.width, element };
|
|
63
|
+
window.addEventListener('mousemove', onMouseMove);
|
|
64
|
+
window.addEventListener('mouseup', onMouseUp);
|
|
65
|
+
}, [onMouseMove, onMouseUp]);
|
|
66
|
+
const handleDragEnd = useCallback((event) => {
|
|
67
|
+
const { active, over } = event;
|
|
68
|
+
if (over && active.id !== over.id) {
|
|
69
|
+
const oldIndex = (columns ?? []).findIndex(entry => entry === active.id);
|
|
70
|
+
const newIndex = (columns ?? []).findIndex(entry => entry === over.id);
|
|
71
|
+
if (isReady) {
|
|
72
|
+
setColumns(arrayMove(columns, oldIndex, newIndex));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}, [columns, setColumns, isReady]);
|
|
76
|
+
const tableContent = (_jsxs(_Fragment, { children: [items?.map(hit => (_jsx(HitRow, { hit: hit, analyticIds: analyticIds, columns: columns, columnWidths: columnWidths, collapseMainColumn: collapseMainColumn, onClick: onItemClick ? onItemClick : (_ev, _hit) => null }, hit.howler.id))), refreshItems && (_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: () => refreshItems(query, true), children: _jsx(Search, {}) }) }) }) }))] }));
|
|
77
|
+
return (_jsxs(Table, { sx: { '& td,th': { px: 1, py: 0.25, whiteSpace: 'nowrap' } }, children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { sx: {
|
|
78
|
+
borderRight: 'thin solid',
|
|
79
|
+
borderRightColor: 'divider'
|
|
80
|
+
}, 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], colSource: columnSources[col], onMouseDown: onMouseDown, setColumns: isReady ? setColumns : () => null }, col))) }) }), _jsx(TableCell, { sx: { width: '100%' } })] }) }), ContextMenu ? (_jsx(ContextMenu, { ...contextMenuProps, children: tableContent })) : (_jsx(TableBody, { children: tableContent }))] }));
|
|
81
|
+
};
|
|
82
|
+
export default HitTable;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Dossier } from '@cccsaurora/howler-ui/models/entities/generated/Dossier';
|
|
1
2
|
import type { Hit } from '@cccsaurora/howler-ui/models/entities/generated/Hit';
|
|
2
3
|
import type { Pivot } from '@cccsaurora/howler-ui/models/entities/generated/Pivot';
|
|
3
4
|
import { type FC } from 'react';
|
|
@@ -5,6 +6,8 @@ export interface PivotLinkProps {
|
|
|
5
6
|
pivot: Pivot;
|
|
6
7
|
hit: Hit;
|
|
7
8
|
compact?: boolean;
|
|
9
|
+
dossier: Dossier;
|
|
10
|
+
resolvedUrl: string;
|
|
8
11
|
}
|
|
9
12
|
declare const PivotLink: FC<PivotLinkProps>;
|
|
10
13
|
export default PivotLink;
|
|
@@ -3,6 +3,7 @@ import { ErrorOutline } from '@mui/icons-material';
|
|
|
3
3
|
import { Tooltip } from '@mui/material';
|
|
4
4
|
import { useHelpers } from '@cccsaurora/howler-ui/components/elements/display/handlebars/helpers';
|
|
5
5
|
import HowlerCard from '@cccsaurora/howler-ui/components/elements/display/HowlerCard';
|
|
6
|
+
import PivotTooltip from '@cccsaurora/howler-ui/components/elements/hit/PivotTooltip';
|
|
6
7
|
import Handlebars from 'handlebars';
|
|
7
8
|
import { isEmpty } from 'lodash-es';
|
|
8
9
|
import React, { useMemo } from 'react';
|
|
@@ -10,7 +11,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
10
11
|
import { usePluginStore } from 'react-pluggable';
|
|
11
12
|
import { flattenDeep } from '@cccsaurora/howler-ui/utils/utils';
|
|
12
13
|
import RelatedLink from './RelatedLink';
|
|
13
|
-
const PivotLink = ({ pivot, hit, compact = false }) => {
|
|
14
|
+
const PivotLink = ({ pivot, hit, compact = false, dossier, resolvedUrl }) => {
|
|
14
15
|
const { i18n } = useTranslation();
|
|
15
16
|
const helpers = useHelpers({ async: false, components: false });
|
|
16
17
|
const pluginStore = usePluginStore();
|
|
@@ -47,11 +48,13 @@ const PivotLink = ({ pivot, hit, compact = false }) => {
|
|
|
47
48
|
return handlebars.compile(pivot.value)(templateObject);
|
|
48
49
|
}
|
|
49
50
|
catch (e) {
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.error(`Failed to compile pivot template for value "${pivot.value}":`, e);
|
|
50
53
|
return pivot.value;
|
|
51
54
|
}
|
|
52
55
|
}, [flatHit, pivot, handlebars, helpers]);
|
|
53
56
|
if (href) {
|
|
54
|
-
return (_jsx(RelatedLink, { title: pivot.label[i18n.language], href: href, compact: compact, icon: pivot.icon, target: "_blank", rel: "noopener noreferrer" }));
|
|
57
|
+
return (_jsx(RelatedLink, { title: pivot.label[i18n.language], href: href, compact: compact, icon: pivot.icon, target: "_blank", rel: "noopener noreferrer", tooltip: _jsx(PivotTooltip, { dossier: dossier, resolvedUrl: resolvedUrl }) }));
|
|
55
58
|
}
|
|
56
59
|
// Hide a relatively useless console error, we'll show a UI component instead
|
|
57
60
|
// eslint-disable-next-line no-console
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Stack, Typography } from '@mui/material';
|
|
2
|
+
import { Stack, Tooltip, Typography } from '@mui/material';
|
|
3
3
|
import HowlerCard from '@cccsaurora/howler-ui/components/elements/display/HowlerCard';
|
|
4
|
+
import RelatedLinkTooltip from '@cccsaurora/howler-ui/components/elements/hit/RelatedLinkTooltip';
|
|
4
5
|
import React, {} from 'react';
|
|
5
6
|
import { Link } from 'react-router-dom';
|
|
6
7
|
import RelatedIcon from './RelatedIcon';
|
|
7
|
-
const RelatedLink = ({ icon, title, href, target, rel, compact = false, children }) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
const RelatedLink = ({ icon, title, href, target, rel, compact = false, tooltip, children }) => {
|
|
9
|
+
const safeTitle = title ?? href ?? '';
|
|
10
|
+
const tooltipContent = tooltip ?? _jsx(RelatedLinkTooltip, { title: safeTitle, href: href ?? '' });
|
|
11
|
+
return (_jsx(Tooltip, { title: tooltipContent, children: _jsx("div", { style: { display: 'flex' }, children: _jsx(HowlerCard, { variant: compact ? 'outlined' : 'elevation', onClick: () => href && window.open(href, target), sx: [
|
|
12
|
+
theme => ({
|
|
13
|
+
cursor: 'pointer',
|
|
14
|
+
backgroundColor: 'transparent',
|
|
15
|
+
transition: theme.transitions.create(['border-color']),
|
|
16
|
+
'&:hover': { borderColor: 'primary.main', '& a': { textDecoration: 'underline' } },
|
|
17
|
+
'& > div': {
|
|
18
|
+
height: '100%'
|
|
19
|
+
},
|
|
20
|
+
'& a': { textDecoration: 'none', color: 'text.primary' }
|
|
21
|
+
}),
|
|
22
|
+
!compact && { border: 'thin solid', borderColor: 'transparent' }
|
|
23
|
+
], children: _jsxs(Stack, { direction: "row", p: compact ? 0.5 : 1, spacing: 1, alignItems: "center", children: [children || _jsx(RelatedIcon, { icon: icon, title: title, href: href, compact: compact }), _jsx(Typography, { component: Link, to: href ?? '#', target: target, rel: rel, onClick: e => e.stopPropagation(), children: safeTitle })] }) }, href) }) }));
|
|
21
24
|
};
|
|
22
25
|
export default RelatedLink;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type HowlerViewLayoutType = 'list' | 'grid' | null;
|
|
2
|
+
declare const LayoutToggle: ({ displayType, setDisplayType, size, allowNullValue }: {
|
|
3
|
+
displayType: HowlerViewLayoutType;
|
|
4
|
+
setDisplayType: (type: HowlerViewLayoutType) => void;
|
|
5
|
+
size?: "small" | "medium" | "large";
|
|
6
|
+
allowNullValue?: boolean;
|
|
7
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default LayoutToggle;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { List, TableChart } from '@mui/icons-material';
|
|
3
|
+
import { ToggleButton, ToggleButtonGroup } from '@mui/material';
|
|
4
|
+
const LayoutToggle = ({ displayType, setDisplayType, size, allowNullValue = false }) => {
|
|
5
|
+
return (_jsxs(ToggleButtonGroup, { exclusive: true, value: displayType, onChange: (__, value) => {
|
|
6
|
+
if (!value && !allowNullValue) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
setDisplayType(value);
|
|
10
|
+
}, size: size ?? 'small', children: [_jsx(ToggleButton, { value: "list", children: _jsx(List, { fontSize: size ?? 'medium' }) }), _jsx(ToggleButton, { value: "grid", children: _jsx(TableChart, { fontSize: size ?? 'medium' }) })] }));
|
|
11
|
+
};
|
|
12
|
+
export default LayoutToggle;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ArrowDownward, ArrowUpward, Language, Lock, Person } from '@mui/icons-material';
|
|
2
|
+
import { ArrowDownward, ArrowUpward, Language, List, Lock, Person, TableChart } from '@mui/icons-material';
|
|
3
3
|
import { Chip, Stack, Tooltip, Typography } from '@mui/material';
|
|
4
4
|
import { useMemo } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { convertLuceneToDate } from '@cccsaurora/howler-ui/utils/utils';
|
|
7
|
-
export const ViewTitle = ({ title, type, query, sort, span }) => {
|
|
7
|
+
export const ViewTitle = ({ title, type, query, sort, span, settings }) => {
|
|
8
8
|
const { t } = useTranslation();
|
|
9
9
|
const spanLabel = useMemo(() => {
|
|
10
10
|
if (!span) {
|
|
@@ -21,5 +21,8 @@ export const ViewTitle = ({ title, type, query, sort, span }) => {
|
|
|
21
21
|
readonly: _jsx(Lock, { fontSize: "small" }),
|
|
22
22
|
global: _jsx(Language, { fontSize: "small" }),
|
|
23
23
|
personal: _jsx(Person, { fontSize: "small" })
|
|
24
|
-
}[type] }),
|
|
24
|
+
}[type] }), settings?.display && (_jsx(Tooltip, { title: t(`page.settings.local.hits.display_type.${settings.display}`), children: {
|
|
25
|
+
list: _jsx(List, { fontSize: "small" }),
|
|
26
|
+
grid: _jsx(TableChart, { fontSize: "small" })
|
|
27
|
+
}[settings.display] })), _jsx(Typography, { variant: "body1", children: t(title) })] }), _jsx(Typography, { variant: "caption", children: _jsx("code", { children: query }) }), (sort || span) && (_jsxs(Stack, { direction: "row", sx: { mt: 1 }, spacing: 1, children: [sort?.split(',').map(_sort => (_jsx(Chip, { size: "small", label: _sort.split(' ')[0], icon: _sort.endsWith('desc') ? _jsx(ArrowDownward, {}) : _jsx(ArrowUpward, {}) }, _sort.split(' ')[0]))), spanLabel && _jsx(Chip, { size: "small", label: spanLabel })] }))] }));
|
|
25
28
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ChevronLeft, Close, ManageSearch } from '@mui/icons-material';
|
|
3
3
|
import { Box, Card, Checkbox, Collapse, Drawer, Fab, IconButton, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
4
|
+
import GridColumnsProvider from '@cccsaurora/howler-ui/components/app/providers/GridColumnsProvider';
|
|
4
5
|
import { HitContext } from '@cccsaurora/howler-ui/components/app/providers/HitProvider';
|
|
5
6
|
import HitSearchProvider, { HitSearchContext } from '@cccsaurora/howler-ui/components/app/providers/HitSearchProvider';
|
|
6
7
|
import ParameterProvider, { ParameterContext } from '@cccsaurora/howler-ui/components/app/providers/ParameterProvider';
|
|
@@ -128,6 +129,6 @@ const HitBrowser = () => {
|
|
|
128
129
|
}, children: _jsx(ChevronLeft, { sx: { transition: 'rotate 250ms', rotate: show ? '180deg' : '0deg' } }) }))] }));
|
|
129
130
|
};
|
|
130
131
|
const HitBrowserProvider = () => {
|
|
131
|
-
return (_jsx(ParameterProvider, { children: _jsx(HitSearchProvider, { children: _jsx(HitBrowser, {}) }) }));
|
|
132
|
+
return (_jsx(ParameterProvider, { children: _jsx(HitSearchProvider, { children: _jsx(GridColumnsProvider, { children: _jsx(HitBrowser, {}) }) }) }));
|
|
132
133
|
};
|
|
133
134
|
export default HitBrowserProvider;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { Box,
|
|
2
|
+
import { ErrorOutline } from '@mui/icons-material';
|
|
3
|
+
import { Box, LinearProgress, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
4
4
|
import { grey } from '@mui/material/colors';
|
|
5
5
|
import AppListEmpty from '@cccsaurora/howler-ui/commons/components/display/AppListEmpty';
|
|
6
6
|
import PageCenter from '@cccsaurora/howler-ui/commons/components/pages/PageCenter';
|
|
@@ -17,21 +17,20 @@ import SearchTotal from '@cccsaurora/howler-ui/components/elements/addons/search
|
|
|
17
17
|
import HowlerCard from '@cccsaurora/howler-ui/components/elements/display/HowlerCard';
|
|
18
18
|
import HitBanner from '@cccsaurora/howler-ui/components/elements/hit/HitBanner';
|
|
19
19
|
import HitCard from '@cccsaurora/howler-ui/components/elements/hit/HitCard';
|
|
20
|
+
import HitContextMenu from '@cccsaurora/howler-ui/components/elements/hit/HitContextMenu';
|
|
20
21
|
import { HitLayout } from '@cccsaurora/howler-ui/components/elements/hit/HitLayout';
|
|
21
22
|
import useHitSelection from '@cccsaurora/howler-ui/components/hooks/useHitSelection';
|
|
22
23
|
import { useMyLocalStorageItem } from '@cccsaurora/howler-ui/components/hooks/useMyLocalStorage';
|
|
23
24
|
import React, { memo, useCallback, useEffect, useMemo } from 'react';
|
|
24
25
|
import { isMobile } from 'react-device-detect';
|
|
25
26
|
import { useTranslation } from 'react-i18next';
|
|
26
|
-
import {
|
|
27
|
+
import { useLocation, useParams } from 'react-router-dom';
|
|
27
28
|
import { useContextSelector } from 'use-context-selector';
|
|
28
29
|
import { StorageKey } from '@cccsaurora/howler-ui/utils/constants';
|
|
29
|
-
import BundleParentMenu from './BundleParentMenu';
|
|
30
30
|
import { BundleScroller } from './BundleScroller';
|
|
31
|
-
import HitContextMenu from './HitContextMenu';
|
|
32
31
|
import HitQuery from './HitQuery';
|
|
33
|
-
import LayoutSettings from './LayoutSettings';
|
|
34
32
|
import QuerySettings from './QuerySettings';
|
|
33
|
+
import SearchActionMenu from './shared/SearchActionMenu';
|
|
35
34
|
const Item = memo(({ hit, onClick }) => {
|
|
36
35
|
const theme = useTheme();
|
|
37
36
|
const selectedHits = useContextSelector(HitContext, ctx => ctx.selectedHits);
|
|
@@ -80,7 +79,6 @@ const Item = memo(({ hit, onClick }) => {
|
|
|
80
79
|
const SearchPane = () => {
|
|
81
80
|
const { t } = useTranslation();
|
|
82
81
|
const location = useLocation();
|
|
83
|
-
const navigate = useNavigate();
|
|
84
82
|
const routeParams = useParams();
|
|
85
83
|
const selected = useContextSelector(ParameterContext, ctx => ctx.selected);
|
|
86
84
|
const setSelected = useContextSelector(ParameterContext, ctx => ctx.setSelected);
|
|
@@ -117,7 +115,7 @@ const SearchPane = () => {
|
|
|
117
115
|
], onClick: () => {
|
|
118
116
|
clearSelectedHits(bundleHit.howler.id);
|
|
119
117
|
setSelected(bundleHit.howler.id);
|
|
120
|
-
}, children: _jsx(HitBanner, { hit: bundleHit, layout: HitLayout.DENSE, useListener: true }) }) }) }) })), _jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", children: [_jsx(Typography, { sx: { color: 'text.secondary', fontSize: '0.9em', fontStyle: 'italic', mb: 0.5 }, variant: "body2", children: t('hit.search.prompt') }), error && (_jsx(Tooltip, { title: `${t('route.advanced.error')}: ${error}`, children: _jsx(ErrorOutline, { fontSize: "small", color: "error" }) })), _jsx(FlexOne, {}),
|
|
118
|
+
}, children: _jsx(HitBanner, { hit: bundleHit, layout: HitLayout.DENSE, useListener: true }) }) }) }) })), _jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", children: [_jsx(Typography, { sx: { color: 'text.secondary', fontSize: '0.9em', fontStyle: 'italic', mb: 0.5 }, variant: "body2", children: t('hit.search.prompt') }), error && (_jsx(Tooltip, { title: `${t('route.advanced.error')}: ${error}`, children: _jsx(ErrorOutline, { fontSize: "small", color: "error" }) })), _jsx(FlexOne, {}), _jsx(SearchActionMenu, { query: query })] })] }), _jsxs(VSBoxHeader, { ml: -3, mr: -3, px: 2, pb: 1, sx: { zIndex: 989 }, children: [_jsxs(Stack, { sx: { pt: 1 }, children: [_jsxs(Stack, { sx: { position: 'relative', flex: 1 }, children: [_jsx(HitQuery, { searching: searching, triggerSearch: triggerSearch }), searching && (_jsx(LinearProgress, { sx: theme => ({
|
|
121
119
|
position: 'absolute',
|
|
122
120
|
left: 0,
|
|
123
121
|
right: 0,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createElement as _createElement } from "react";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { ArrowDropDown, Delete, Edit, Language, Lock, OpenInNew, Person, Refresh, SavedSearch, SelectAll } from '@mui/icons-material';
|
|
3
|
+
import { ArrowDropDown, Delete, Edit, Language, Lock, OpenInNew, Person, Refresh, SavedSearch, SelectAll, Warning } from '@mui/icons-material';
|
|
4
4
|
import { Autocomplete, Chip, CircularProgress, IconButton, Stack, TextField, Tooltip, Typography } from '@mui/material';
|
|
5
5
|
import { HitSearchContext } from '@cccsaurora/howler-ui/components/app/providers/HitSearchProvider';
|
|
6
6
|
import { ParameterContext } from '@cccsaurora/howler-ui/components/app/providers/ParameterProvider';
|
|
@@ -21,6 +21,7 @@ const ViewLink = ({ id, viewId }) => {
|
|
|
21
21
|
const removeView = useContextSelector(ParameterContext, ctx => ctx.removeView);
|
|
22
22
|
const setParamView = useContextSelector(ParameterContext, ctx => ctx.setView);
|
|
23
23
|
const search = useContextSelector(HitSearchContext, ctx => ctx.search);
|
|
24
|
+
const displayType = useContextSelector(HitSearchContext, ctx => ctx.displayType);
|
|
24
25
|
const [loading, setLoading] = useState(true);
|
|
25
26
|
const [view, setView] = useState(null);
|
|
26
27
|
useEffect(() => {
|
|
@@ -60,6 +61,6 @@ const ViewLink = ({ id, viewId }) => {
|
|
|
60
61
|
readonly: _jsx(Lock, { fontSize: "small", "aria-label": t(`route.views.manager.${view.type}`) }),
|
|
61
62
|
global: _jsx(Language, { fontSize: "small", "aria-label": t(`route.views.manager.${view.type}`) }),
|
|
62
63
|
personal: _jsx(Person, { fontSize: "small", "aria-label": t(`route.views.manager.${view.type}`) })
|
|
63
|
-
}[view.type] }), label: _jsx(Tooltip, { title: view.query, children: _jsx(Typography, { role: "link", sx: { color: 'text.primary' }, variant: "body2", component: Link, to: `/views/${view.view_id}/edit`, "aria-label": `${t(view.title)} - ${view.query ?? t('unknown')}`, children: t(view.title) }) }), onDelete: () => removeView(viewId), children: _jsxs(Stack, { direction: "row", spacing: 0.5, alignItems: "center", children: [_jsx(Tooltip, { title: view ? t('route.views.edit') : t('route.views.create'), children: _jsx(IconButton, { "aria-label": view ? t('route.views.edit') : t('route.views.create'), size: "small", component: Link, disabled: (!view && !query) || span?.endsWith('custom'), to: viewUrl, role: "link", children: view ? _jsx(Edit, { fontSize: "small" }) : _jsx(SavedSearch, {}) }) }), _jsx(Tooltip, { title: t('view.refresh'), children: _jsx(IconButton, { size: "small", onClick: () => search(query), "aria-label": t('view.refresh'), children: _jsx(Refresh, { fontSize: "small" }) }) }), _jsx(Tooltip, { title: t('view.open'), children: _jsx(IconButton, { size: "small", component: Link, to: `/search?query=${view.query}`, "aria-label": t('view.open'), role: "link", children: _jsx(OpenInNew, { fontSize: "small" }) }) })] }) }));
|
|
64
|
+
}[view.type] }), label: _jsxs(Stack, { direction: "row", spacing: 0.5, alignItems: "center", children: [_jsx(Tooltip, { title: view.query, children: _jsx(Typography, { role: "link", sx: { color: 'text.primary' }, variant: "body2", component: Link, to: `/views/${view.view_id}/edit`, "aria-label": `${t(view.title)} - ${view.query ?? t('unknown')}`, children: t(view.title) }) }), view.settings?.display === 'grid' && displayType !== 'grid' && (_jsx(Tooltip, { title: t('view.display.grid.inactive_warning'), children: _jsx(Warning, { fontSize: "small", color: "warning" }) }))] }), onDelete: () => removeView(viewId), children: _jsxs(Stack, { direction: "row", spacing: 0.5, alignItems: "center", children: [_jsx(Tooltip, { title: view ? t('route.views.edit') : t('route.views.create'), children: _jsx(IconButton, { "aria-label": view ? t('route.views.edit') : t('route.views.create'), size: "small", component: Link, disabled: (!view && !query) || span?.endsWith('custom'), to: viewUrl, role: "link", children: view ? _jsx(Edit, { fontSize: "small" }) : _jsx(SavedSearch, {}) }) }), _jsx(Tooltip, { title: t('view.refresh'), children: _jsx(IconButton, { size: "small", onClick: () => search(query), "aria-label": t('view.refresh'), children: _jsx(Refresh, { fontSize: "small" }) }) }), _jsx(Tooltip, { title: t('view.open'), children: _jsx(IconButton, { size: "small", component: Link, to: `/search?query=${view.query}`, "aria-label": t('view.open'), role: "link", children: _jsx(OpenInNew, { fontSize: "small" }) }) })] }) }));
|
|
64
65
|
};
|
|
65
66
|
export default memo(ViewLink);
|