Skip to content
Snippets Groups Projects
Commit eed9fbb5 authored by Matthias Feyll's avatar Matthias Feyll
Browse files

(ui): add highlight on search in table

parent 7dfa8398
No related branches found
No related tags found
4 merge requests!1196[renovate] Update module golang.org/x/net to v0.32.0,!1195UI: implement add device functionality,!1167Ui refactor style,!1161Ui refactor style
import { PndServiceGetPndListApiArg, api } from "@api/api"
import { createAsyncThunk } from "@reduxjs/toolkit"
import { setPnds } from "../reducer/device.reducer"
// TODO rethink this. This should be in the shared part bc its getting invoked in the procteded layout
export const fetchPnds = createAsyncThunk('device/fetchPnds', (_, thunkApi) => {
const payload: PndServiceGetPndListApiArg = {
timestamp: new Date().getTime().toString(),
}
const subscription = thunkApi.dispatch(api.endpoints.pndServiceGetPndList.initiate(payload))
subscription.unwrap().then((response) => {
thunkApi.dispatch(setPnds(response.pnd))
})
})
\ No newline at end of file
import { insertMarkTags } from "@helper/text";
import { useAppSelector } from "@hooks";
import DOMPurify from 'dompurify';
import { MutableRefObject, useCallback } from "react";
import { OverlayTrigger, Table, Tooltip } from "react-bootstrap";
import { useTranslation } from "react-i18next";
......@@ -15,25 +17,30 @@ export const DeviceViewTable = (searchRef: MutableRefObject<HTMLInputElement>) =
}
const getDeviceTable = useCallback(() => {
return devices.filter((device) => {
if (!searchRef.current?.value) {
return true;
}
const search = searchRef.current?.value;
let filtered = devices
const searchInput = searchRef.current!.value;
const user = pnds.find(pnd => pnd.id === device.pid);
// filter if something is in search
if (search) {
filtered = devices.filter((device) => {
const user = pnds.find(pnd => pnd.id === device.pid);
return device.id?.includes(search) ||
device.name?.includes(search) ||
user?.name?.includes(search);
})
}
return device.id.includes(searchInput) || device.name.includes(searchInput) || user?.name.includes(searchInput);
}).map((device, index) => {
return filtered.map((device, index) => {
const user = pnds.find(pnd => pnd.id === device.pid);
return (
<tr key={index} onClick={() => trClickHandler(device)} className={selectedDevice?.device.id === device.id ? 'active' : ''}>
<td>{device.name}</td>
<td key={0} dangerouslySetInnerHTML={{ __html: search ? insertMarkTags(device.name!, search) : DOMPurify.sanitize(device.name) }}></td>
<OverlayTrigger overlay={<Tooltip id={device.id}>{device.id}</Tooltip>}>
<td>{cropUUID(device.id)}</td>
<td dangerouslySetInnerHTML={{ __html: search ? insertMarkTags(cropUUID(device.id!), search) : DOMPurify.sanitize(cropUUID(device.id!)) }}></td>
</OverlayTrigger>
<td>{user?.name || ''}</td>
<td key={1} dangerouslySetInnerHTML={{ __html: search ? insertMarkTags(user?.name || '', search) : DOMPurify.sanitize(user?.name || '') }}></td>
<td></td>
</tr>
)
......@@ -41,6 +48,7 @@ export const DeviceViewTable = (searchRef: MutableRefObject<HTMLInputElement>) =
}, [devices, searchRef, pnds, selectedDevice, trClickHandler]);
return (
<Table striped responsive className="device-table">
<thead>
......
import { faAlignRight, faPenToSquare, faTrashCan } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { insertMarkTags } from "@helper/text"
import DOMPurify from 'dompurify'
import React, { Suspense, useMemo, useRef } from "react"
import { Form, Table } from "react-bootstrap"
......@@ -30,13 +31,6 @@ export const JsonViewer = ({ json }: JsonViewerProbs) => {
)
}, [breadcrumbs])
const insertMarkTags = (text: string, search: string): string => {
const start = text.indexOf(search)
const end = start + search.length
return DOMPurify.sanitize(text.substring(0, start)) + "<span class='highlight'>" + DOMPurify.sanitize(search) + "</span>" + DOMPurify.sanitize(text.substring(end, text.length))
}
const renderInner = (innerJson: JSON, nested: number = 0, parentKey: string = "", path: string = "/network-instance/0/"): JSX.Element => {
path += parentKey + (parentKey === "" ? "" : "/")
......
import DOMPurify from 'dompurify'
export const insertMarkTags = (text: string, search: string): string => {
const start = text.indexOf(search)
if (start === -1) {
return DOMPurify.sanitize(text)
}
const end = start + search.length
return DOMPurify.sanitize(text.substring(0, start)) + "<span class='highlight'>" + DOMPurify.sanitize(search) + "</span>" + DOMPurify.sanitize(text.substring(end, text.length))
}
\ No newline at end of file
import { fetchUser } from '@api/user.fetch';
import logo from '@assets/logo.svg';
import { fetchPnds } from '@component/devices/api/pnd.fetch';
import { faCircleUser, faRightFromBracket } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useAppDispatch, useAppSelector } from '@hooks';
import { useAuth } from "@provider/auth.provider";
import { MenuProvider } from '@provider/menu/menu.provider';
import { DEVICE_URL, LOGIN_URL } from '@routes';
import { fetchPnds, fetchUser } from '@shared/routine/user.routine';
import React, { useEffect } from "react";
import { Dropdown } from "react-bootstrap";
import { useTranslation } from "react-i18next";
......
import { api, PndServiceGetPndListApiArg, UserServiceGetUsersApiArg } from "@api/api"
import { setPnds } from "@component/devices/reducer/device.reducer"
import { createAsyncThunk } from "@reduxjs/toolkit"
import { setUser } from "@shared/reducer/user.reducer"
import { RootState } from "src/stores"
import { api, UserServiceGetUsersApiArg } from "./api"
export const fetchUser = createAsyncThunk('user/fetchUser', (_, thunkAPI) => {
const payload: UserServiceGetUsersApiArg = {}
......@@ -23,3 +24,14 @@ export const fetchUser = createAsyncThunk('user/fetchUser', (_, thunkAPI) => {
thunkAPI.dispatch(setUser(matchedUser))
})
})
export const fetchPnds = createAsyncThunk('device/fetchPnds', (_, thunkApi) => {
const payload: PndServiceGetPndListApiArg = {
timestamp: new Date().getTime().toString(),
}
const subscription = thunkApi.dispatch(api.endpoints.pndServiceGetPndList.initiate(payload))
subscription.unwrap().then((response) => {
thunkApi.dispatch(setPnds(response.pnd))
})
})
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment