Updated WoL Settings

This commit is contained in:
Sean Edmunds
2025-03-21 10:33:50 -05:00
parent 27a9db82f0
commit 27a7dd2fb9
12 changed files with 637 additions and 135 deletions

View File

@@ -1,8 +1,31 @@
import { Stack, Text } from '@mantine/core';
import { DataTable, WolClientColumns } from 'components';
import { useQueryAPI } from 'hooks';
import {
ActionIcon,
Box,
Button,
Divider,
Grid,
GridCol,
Group,
Highlight,
Modal,
Popover,
Stack,
Text,
TextInput,
} from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { textClasses } from 'styles';
import { FiHelpCircle, FiPlus } from 'react-icons/fi';
import {
actionIconClasses,
buttonClasses,
modalClasses,
textClasses,
textInputClasses,
} from 'styles';
import DebouncedWolClient from './DebouncedWolClient';
import WolClientSettingsItem from './WolClientSettingsItem';
const WolClientSettings = () => {
const endpoint = 'api/wolClients';
@@ -15,26 +38,201 @@ const WolClientSettings = () => {
endpoint: endpoint,
});
const [wolClients, setWolClients] = useState<any>([]);
const { mutateAsync } = useMutationAPI();
const { theme } = useCommonHooks();
const [newWolClient, setNewWolClient] = useState<any>({
name: '',
url: '',
icon: '',
baseUrl: '',
filterName: '',
});
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
const [searchValue, setSearchValue] = useState('');
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
const handleDelete = (application: any) => {
mutateAsync({ method: 'DELETE', endpoint: endpoint, body: application });
};
useEffect(() => {
if (wolClientsData && wolClientsIsFetched) {
setWolClients(wolClientsData);
setWolClients(
wolClientsData.filter((a: any) =>
a.hostname.toLowerCase().includes(debouncedSearch.toLowerCase()),
),
);
}
}, [wolClientsData, wolClientsIsFetched]);
}, [wolClientsData, wolClientsIsFetched, debouncedSearch]);
return (
<Stack>
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
WoL Clients
</Text>
<DataTable
tableName='WoL Clients'
columns={WolClientColumns()}
tableData={wolClients}
isFetching={wolClientsIsFetching}
isLoading={wolClientsIsLoading}
endpoint={endpoint}
/>
<Modal.Root
size={'60%'}
className={modalClasses.helpModal}
classNames={modalClasses}
opened={modalOpened}
onClose={() => {
closeModal();
}}
style={{
'--color-text-pri': theme.primaryColor,
'--color-text-acc': theme.accentColor,
'--color-background': theme.backgroundColor,
'--color-border': theme.borderColor,
'--color-search-background': theme.searchColor,
'--image-background': `url(${theme.backgroundImage})`,
}}
closeOnEscape
closeOnClickOutside
>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>
<Modal.Title>Add a new application</Modal.Title>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body pb={'2rem'}>
<Stack gap={0} w={'100%'} align='center'>
<Group w={'100%'} justify='center'>
<TextInput
label={'Hostname'}
className={textInputClasses.settingsItem}
pt={16}
classNames={textInputClasses}
defaultValue={newWolClient.hostname}
onChange={(event) => {
setNewWolClient({
...newWolClient,
hostname: event.target.value,
});
}}
/>
<TextInput
label={'MAC Address'}
className={textInputClasses.settingsItem}
pt={16}
classNames={textInputClasses}
defaultValue={newWolClient.macAddress}
onChange={(event) => {
setNewWolClient({
...newWolClient,
macAddress: event.target.value,
});
}}
/>
</Group>
<Divider color='black' my='sm' />
<Group pos={'absolute'} bottom={8}>
<Button
color={'green'}
styles={{ label: { color: 'black' } }}
onClick={() => {
if (newWolClient) {
mutateAsync({
method: 'POST',
endpoint: endpoint,
body: newWolClient,
});
closeModal();
}
}}
>
Save
</Button>
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={() => {
closeModal();
}}
>
Cancel
</Button>
</Group>
</Stack>
</Modal.Body>
</Modal.Content>
</Modal.Root>
<Group align='center'>
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
WoL Clients
</Text>
<Popover withArrow withOverlay withinPortal={false}>
<Popover.Target>
<ActionIcon
className={actionIconClasses.settingsTooltip}
classNames={actionIconClasses}
>
<FiHelpCircle />
</ActionIcon>
</Popover.Target>
<Popover.Dropdown
style={{
color: theme.primaryColor,
backgroundColor: theme.backgroundColor,
}}
>
<Stack>
<Text className={textClasses.settingsTooltip} classNames={textClasses}>
{'Wake on Lan clients can be configured here.'}
</Text>
<Highlight
ta={'center'}
highlight={['Clients', 'homepage']}
className={textClasses.settingsTooltip}
classNames={textClasses}
highlightStyles={{
backgroundImage:
'linear-gradient(45deg, var(--color-text-acc), var(--color-text-pri))',
fontWeight: 700,
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
}}
>
{'Clients can be powered on from the settings button the homepage.'}
</Highlight>
</Stack>
</Popover.Dropdown>
</Popover>
<Button
className={buttonClasses.tableButton}
classNames={buttonClasses}
onClick={openModal}
>
<FiPlus />
</Button>
<TextInput
className={textInputClasses.settingsItem}
classNames={textInputClasses}
autoFocus
placeholder='Search...'
value={searchValue}
onInput={(event: any) => {
setSearchValue(event.target.value);
}}
/>
</Group>
<Stack w={'100%'} align='center'>
<Grid columns={18} w={'75%'}>
{wolClients?.map((client: any) => (
<GridCol span={6} key={client.id}>
<Popover withArrow withOverlay withinPortal={false}>
<Popover.Target>
<Box
onClick={(e) => {
e.stopPropagation();
}}
>
<WolClientSettingsItem client={client} />
</Box>
</Popover.Target>
<Popover.Dropdown>
<DebouncedWolClient wolClient={client} handleDelete={handleDelete} />
</Popover.Dropdown>
</Popover>
</GridCol>
))}
</Grid>
</Stack>
</Stack>
);
};