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

add remove device feature

parent 9091cc88
No related branches found
No related tags found
No related merge requests found
import { useDeviceBoxViewModel } from '@component/devices/view_model/device.box.viewmodel' import { useDeviceBoxViewModel } from '@component/devices/view_model/device.box.viewmodel'
import { faPlus } from '@fortawesome/free-solid-svg-icons' import { faPenToSquare, faPlus, faTrashCan } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { insertMarkTags } from '@helper/text' import { insertMarkTags } from '@helper/text'
import { Scrollbar } from '@shared/components/scrollbar/Scrollbar.view' import { Scrollbar } from '@shared/components/scrollbar/Scrollbar.view'
...@@ -22,7 +22,8 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen ...@@ -22,7 +22,8 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen
closeModal, closeModal,
searchValue, searchValue,
handleSearch, handleSearch,
} = useDeviceBoxViewModel(searchRef) removeDevice,
} = useDeviceBoxViewModel()
const cropUUID = (uuid: string): string => { const cropUUID = (uuid: string): string => {
return uuid.substring(0, 3) + '...' + uuid.substring(uuid.length - 3, uuid.length) return uuid.substring(0, 3) + '...' + uuid.substring(uuid.length - 3, uuid.length)
...@@ -44,8 +45,8 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen ...@@ -44,8 +45,8 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen
isSelected && 'bg-gradient-fade py-2' isSelected && 'bg-gradient-fade py-2'
} ${!isSelected && 'text-disabled disabled-hover'}`} } ${!isSelected && 'text-disabled disabled-hover'}`}
onClick={() => handleItemClick(device)}> onClick={() => handleItemClick(device)}>
<Row className="align-items-center clickable"> <Row className="align-items-center clickable device-row">
<Col xs={12} sm={5}> <Col xs={12} sm={4}>
<span <span
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: searchValue __html: searchValue
...@@ -76,6 +77,16 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen ...@@ -76,6 +77,16 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen
}} }}
/> />
</Col> </Col>
<Col xs={12} sm={1}>
<div className="d-flex icons justify-content-end align-items-center">
<FontAwesomeIcon icon={faPenToSquare} size="sm" />
<FontAwesomeIcon
icon={faTrashCan}
size="sm"
onClick={() => removeDevice(device)}
/>
</div>
</Col>
</Row> </Row>
</div> </div>
) )
...@@ -119,7 +130,7 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen ...@@ -119,7 +130,7 @@ export const DeviceList = ({ searchRef }: { searchRef: RefObject<HTMLInputElemen
{/* Fixed header */} {/* Fixed header */}
<div className="sticky-top bg-white border-bottom border-primary"> <div className="sticky-top bg-white border-bottom border-primary">
<Row className="px-2 py-2 mx-0"> <Row className="px-2 py-2 mx-0">
<Col xs={12} sm={5}> <Col xs={12} sm={4}>
<span className="font-medium">{t('device.table.header.name')}</span> <span className="font-medium">{t('device.table.header.name')}</span>
</Col> </Col>
<Col xs={12} sm={3}> <Col xs={12} sm={3}>
......
...@@ -24,7 +24,7 @@ export const DeviceListCollapsable = ({ search }: DeviceListCollapsableProps) => ...@@ -24,7 +24,7 @@ export const DeviceListCollapsable = ({ search }: DeviceListCollapsableProps) =>
const user = pnds.find(pnd => pnd.id === selected?.device.pid) const user = pnds.find(pnd => pnd.id === selected?.device.pid)
const username = user?.name || '' const username = user?.name || ''
const deviceId = selected?.device.id || '' const deviceId = selected?.device.id || ''
const json = selected?.json || {} const json = JSON.parse(selected?.mne?.model || '{}')
const metadataKey = Object.keys(json).at(2) as keyof typeof json const metadataKey = Object.keys(json).at(2) as keyof typeof json
const metadataObject = (json[metadataKey] as JSON) || {} const metadataObject = (json[metadataKey] as JSON) || {}
......
...@@ -93,3 +93,10 @@ ...@@ -93,3 +93,10 @@
$primary-color: rgba(map-get($theme-colors, "dark"), 0.1); $primary-color: rgba(map-get($theme-colors, "dark"), 0.1);
background: linear-gradient(to bottom, rgb(223, 223, 223) 1%, white 100%); background: linear-gradient(to bottom, rgb(223, 223, 223) 1%, white 100%);
} }
.device-row:hover .icons {
color: map-get($theme-colors, "black") !important;
opacity: 100%;
transition: gap 0.3s;
gap: 0.7em;
}
// devices.box.viewmodel.ts import { NetworkelementFlattenedManagedNetworkElement, NetworkElementServiceDeleteApiArg, useNetworkElementServiceDeleteMutation } from "@api/api";
import { useAppDispatch, useAppSelector } from "@hooks"; import { useAppDispatch, useAppSelector } from "@hooks";
import { RefObject, useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
import { Device, setSelectedDevice } from "../reducer/device.reducer"; import { toast } from "react-toastify";
import { Device, setDevices, setSelectedDevice } from "../reducer/device.reducer";
import { fetchPluginsThunk } from "../routines/plugin.routine"; import { fetchPluginsThunk } from "../routines/plugin.routine";
export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) => { export const useDeviceBoxViewModel = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [deleteNetworkElement] = useNetworkElementServiceDeleteMutation()
const { devices, pnds, selected: selectedDevice } = useAppSelector( const { devices, pnds, selected: selectedDevice } = useAppSelector(
(state) => state.device (state) => state.device
); );
...@@ -29,6 +32,33 @@ export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) => ...@@ -29,6 +32,33 @@ export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) =>
setAddModal(false); setAddModal(false);
}, []); }, []);
const removeDevice = useCallback(async (device: NetworkelementFlattenedManagedNetworkElement) => {
if (!device?.id) {
toast.error("Error: Please reload the page and try it again")
return
}
const pnd = pnds.find(pnd => pnd.id === device.pid)
if (!pnd) {
toast.error("Error: Please reload the page and try it again")
return
}
const payload: NetworkElementServiceDeleteApiArg = {
mneid: device.id,
timestamp: new Date().getTime().toString(),
pid: pnd.id
}
try {
await deleteNetworkElement(payload).unwrap()
const newDevices = devices.filter(_device => _device.id !== device.id)
dispatch(setDevices(newDevices))
toast.success("Device successfully deleted")
} catch (error) {
toast.error("Error: Delete was not successful. Please reload the page and try it again")
}
}, [])
const filteredDevices = useMemo(() => { const filteredDevices = useMemo(() => {
if (!searchValue) return devices; if (!searchValue) return devices;
...@@ -40,7 +70,7 @@ export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) => ...@@ -40,7 +70,7 @@ export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) =>
user?.name?.toLowerCase().includes(searchValue.toLowerCase()) user?.name?.toLowerCase().includes(searchValue.toLowerCase())
); );
}); });
}, [devices, pnds, searchValue]); // Now depends on searchValue instead of ref }, [devices, pnds, searchValue]);
return { return {
filteredDevices, filteredDevices,
...@@ -52,5 +82,6 @@ export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) => ...@@ -52,5 +82,6 @@ export const useDeviceBoxViewModel = (searchRef: RefObject<HTMLInputElement>) =>
closeModal, closeModal,
searchValue, searchValue,
handleSearch, handleSearch,
removeDevice
}; };
}; };
\ No newline at end of file
...@@ -7,11 +7,7 @@ import { useEffect, useState } from "react"; ...@@ -7,11 +7,7 @@ import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
<<<<<<< HEAD:react-ui/src/components/devices/view_model/information.box.viewmodel.ts
export const useInformationViewModel = (searchRef, listRef) => { export const useInformationViewModel = (searchRef, listRef) => {
=======
export const useDeviceTableViewModel = (searchRef, tableRef) => {
>>>>>>> parent of 9ea90588 (Merge branch 'master' into ui-implement-metadata-screen):react-ui/src/components/devices/view_model/device.table.viewmodel.ts
const [searchTerm, setSearchTerm] = useState(''); const [searchTerm, setSearchTerm] = useState('');
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { subscribe } = useMenu(); const { subscribe } = useMenu();
...@@ -20,8 +16,12 @@ export const useDeviceTableViewModel = (searchRef, tableRef) => { ...@@ -20,8 +16,12 @@ export const useDeviceTableViewModel = (searchRef, tableRef) => {
const registerMenuOptions = () => { const registerMenuOptions = () => {
if (!subscribe) {
return
}
const subscription = subscribe({ const subscription = subscribe({
target: tableRef.current, target: listRef.current,
actions: [ actions: [
{ {
key: t('device.table.actions.copy'), key: t('device.table.actions.copy'),
...@@ -67,7 +67,7 @@ export const useDeviceTableViewModel = (searchRef, tableRef) => { ...@@ -67,7 +67,7 @@ export const useDeviceTableViewModel = (searchRef, tableRef) => {
// seperate use effect to rerun this after tableref and subscribe are initialized // seperate use effect to rerun this after tableref and subscribe are initialized
useEffect(() => { useEffect(() => {
if (!subscribe || !tableRef.current) { if (!subscribe || !listRef.current) {
return return
} }
...@@ -76,7 +76,7 @@ export const useDeviceTableViewModel = (searchRef, tableRef) => { ...@@ -76,7 +76,7 @@ export const useDeviceTableViewModel = (searchRef, tableRef) => {
return () => { return () => {
unsubscribe() unsubscribe()
} }
}, [tableRef, subscribe]) }, [listRef, subscribe])
useEffect(() => { useEffect(() => {
......
...@@ -63,8 +63,6 @@ td .icon { ...@@ -63,8 +63,6 @@ td .icon {
color: lighten(map-get($map: $theme-colors, $key: "dark"), 20%); color: lighten(map-get($map: $theme-colors, $key: "dark"), 20%);
gap: 0.5em; gap: 0.5em;
opacity: 0%; opacity: 0%;
min-width: 3em;
} }
span.highlight { span.highlight {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment