More performance updates
This commit is contained in:
62
package-lock.json
generated
62
package-lock.json
generated
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "triggerfrontend",
|
"name": "triggerfrontend",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "triggerfrontend",
|
"name": "triggerfrontend",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gfazioli/mantine-text-animate": "^2.3.10",
|
"@gfazioli/mantine-text-animate": "^2.3.10",
|
||||||
"@hello-pangea/dnd": "^18.0.1",
|
"@hello-pangea/dnd": "^18.0.1",
|
||||||
"@mantine/core": "^8.3.11",
|
"@mantine/core": "^8.3.12",
|
||||||
"@mantine/dates": "^8.3.11",
|
"@mantine/dates": "^8.3.12",
|
||||||
"@mantine/form": "^8.3.11",
|
"@mantine/form": "^8.3.12",
|
||||||
"@mantine/hooks": "^8.3.11",
|
"@mantine/hooks": "^8.3.12",
|
||||||
"@mantine/notifications": "^8.3.11",
|
"@mantine/notifications": "^8.3.12",
|
||||||
"@tanstack/react-query": "^5.90.16",
|
"@tanstack/react-query": "^5.90.16",
|
||||||
"@tanstack/react-query-devtools": "^5.91.2",
|
"@tanstack/react-query-devtools": "^5.91.2",
|
||||||
"@tanstack/react-query-persist-client": "^5.90.18",
|
"@tanstack/react-query-persist-client": "^5.90.18",
|
||||||
@@ -911,9 +911,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/core": {
|
"node_modules/@mantine/core": {
|
||||||
"version": "8.3.11",
|
"version": "8.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.3.12.tgz",
|
||||||
"integrity": "sha512-FWXp94tiTFdh8BKc7UTNdIuumD96JFxLF/VvUWGRzf5i563Ye0Ma/aZtOBwpdEtdIQkojOhoMMV76k5toOQgEQ==",
|
"integrity": "sha512-bDEoUl4SneltfI1GeEaBk6BVDbLuB/w15YwseAmUvc8ldAbNcsVhxKxY/BdhwqUo6O3L2vhdlb3WwxR1y8741g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react": "^0.27.16",
|
"@floating-ui/react": "^0.27.16",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -923,30 +923,30 @@
|
|||||||
"type-fest": "^4.41.0"
|
"type-fest": "^4.41.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/hooks": "8.3.11",
|
"@mantine/hooks": "8.3.12",
|
||||||
"react": "^18.x || ^19.x",
|
"react": "^18.x || ^19.x",
|
||||||
"react-dom": "^18.x || ^19.x"
|
"react-dom": "^18.x || ^19.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/dates": {
|
"node_modules/@mantine/dates": {
|
||||||
"version": "8.3.11",
|
"version": "8.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-8.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-8.3.12.tgz",
|
||||||
"integrity": "sha512-e5QBHMpTjKDkYHFEYkD3bho4Kk/M04jmXLu9Txb/XkWVDb5A0CNGg6+A8TinXING4B7kn2dMOLmL3s7r6vnJJA==",
|
"integrity": "sha512-rL2kYJRTrU29l1KjQt5bdUweiZuJs3DjiIcc6VGHUuj7OwfYZbEpWzMbcu8fSrya/+kZAe8JM0irX22CjmsDGw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clsx": "^2.1.1"
|
"clsx": "^2.1.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/core": "8.3.11",
|
"@mantine/core": "8.3.12",
|
||||||
"@mantine/hooks": "8.3.11",
|
"@mantine/hooks": "8.3.12",
|
||||||
"dayjs": ">=1.0.0",
|
"dayjs": ">=1.0.0",
|
||||||
"react": "^18.x || ^19.x",
|
"react": "^18.x || ^19.x",
|
||||||
"react-dom": "^18.x || ^19.x"
|
"react-dom": "^18.x || ^19.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/form": {
|
"node_modules/@mantine/form": {
|
||||||
"version": "8.3.11",
|
"version": "8.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/form/-/form-8.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/form/-/form-8.3.12.tgz",
|
||||||
"integrity": "sha512-546npW8gHCXUShVL/OOnKBJ1So5bcKTdmiNxzXn8q2eGhMIB+zdj7/v4QUz2j55OjDRPq0dAVJhzDjLfzeibTg==",
|
"integrity": "sha512-bjXL1Ah3lAZYHrjrF37FeHV8DFGeXV+apn0PRQw2MTLpdUSqKsiYIDDgugzRfNXWX1cn1ELtxtDXsMfdj/LI7Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"klona": "^2.0.6"
|
"klona": "^2.0.6"
|
||||||
@@ -956,32 +956,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/hooks": {
|
"node_modules/@mantine/hooks": {
|
||||||
"version": "8.3.11",
|
"version": "8.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.3.12.tgz",
|
||||||
"integrity": "sha512-WJFKDnJJM2fAOCkrO8qRsi3wDdicSFqElruPj5TEYWDL93vl0pITOyN0oRF93bUtx190waqela3edfGH3r5/1g==",
|
"integrity": "sha512-lMMDzDewd3lUNtJCAHDj3g8On9X5aBl4q6EBwgOixKQSby9RG9ASEpK8oYHundHTm9tzo3MDeXWV/z32oSQWuw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^18.x || ^19.x"
|
"react": "^18.x || ^19.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/notifications": {
|
"node_modules/@mantine/notifications": {
|
||||||
"version": "8.3.11",
|
"version": "8.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-8.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-8.3.12.tgz",
|
||||||
"integrity": "sha512-bcFzw9m4uzxHMflNeWqa9imCy8T5mHCAV8WRqzAwK/Yls8GL9uJoQH/e1v6Pl4g4yvBmaF9yUHu7Zq3iyKhHhQ==",
|
"integrity": "sha512-lqPPa11XdcndG8ywMao8yVkMA4jg/pBNbS85bR7OwHQa1yUftmfVlqJl9PZZCiWLX2AgKY3+xM5dHo4LidL+DA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mantine/store": "8.3.11",
|
"@mantine/store": "8.3.12",
|
||||||
"react-transition-group": "4.4.5"
|
"react-transition-group": "4.4.5"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/core": "8.3.11",
|
"@mantine/core": "8.3.12",
|
||||||
"@mantine/hooks": "8.3.11",
|
"@mantine/hooks": "8.3.12",
|
||||||
"react": "^18.x || ^19.x",
|
"react": "^18.x || ^19.x",
|
||||||
"react-dom": "^18.x || ^19.x"
|
"react-dom": "^18.x || ^19.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/store": {
|
"node_modules/@mantine/store": {
|
||||||
"version": "8.3.11",
|
"version": "8.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.3.12.tgz",
|
||||||
"integrity": "sha512-ku48CzN9HobVUjd7o41voaaHKz2CMrtkk454vwXWAspfbpqR4hklL5zq/MzctETFCG6HBDiPRfZAvNm8WaM3Tw==",
|
"integrity": "sha512-EC4eIKpm5s7neMbBrWsP6jGKLqrzHf63Ao3penYr7fn25dFXdbXZYw+IG8GYzxOC4yG61b2zTS+bpy5+vwzXpw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^18.x || ^19.x"
|
"react": "^18.x || ^19.x"
|
||||||
}
|
}
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -12,11 +12,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gfazioli/mantine-text-animate": "^2.3.10",
|
"@gfazioli/mantine-text-animate": "^2.3.10",
|
||||||
"@hello-pangea/dnd": "^18.0.1",
|
"@hello-pangea/dnd": "^18.0.1",
|
||||||
"@mantine/core": "^8.3.11",
|
"@mantine/core": "^8.3.12",
|
||||||
"@mantine/dates": "^8.3.11",
|
"@mantine/dates": "^8.3.12",
|
||||||
"@mantine/form": "^8.3.11",
|
"@mantine/form": "^8.3.12",
|
||||||
"@mantine/hooks": "^8.3.11",
|
"@mantine/hooks": "^8.3.12",
|
||||||
"@mantine/notifications": "^8.3.11",
|
"@mantine/notifications": "^8.3.12",
|
||||||
"@tanstack/react-query": "^5.90.16",
|
"@tanstack/react-query": "^5.90.16",
|
||||||
"@tanstack/react-query-devtools": "^5.91.2",
|
"@tanstack/react-query-devtools": "^5.91.2",
|
||||||
"@tanstack/react-query-persist-client": "^5.90.18",
|
"@tanstack/react-query-persist-client": "^5.90.18",
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { ActionIcon, Box, Group, Text } from '@mantine/core';
|
import { ActionIcon, Box, Group, Text } from '@mantine/core';
|
||||||
import { createColumnHelper } from '@tanstack/react-table';
|
import { createColumnHelper } from '@tanstack/react-table';
|
||||||
import { FaFilter, FaTrash } from 'react-icons/fa';
|
import { FaFilter, FaTrash } from 'react-icons/fa';
|
||||||
|
import type { SearchHistoryItem } from 'types';
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<any>();
|
const columnHelper = createColumnHelper<SearchHistoryItem>();
|
||||||
export const SearchHistoryColumns = (
|
export const SearchHistoryColumns = (
|
||||||
setSelectedItem: React.Dispatch<React.SetStateAction<any>>,
|
setSelectedItem: React.Dispatch<React.SetStateAction<any>>,
|
||||||
deleteItemOpen: () => void,
|
deleteItemOpen: () => void,
|
||||||
@@ -109,11 +110,11 @@ export const SearchHistoryColumns = (
|
|||||||
id: 'dateTimeStamp',
|
id: 'dateTimeStamp',
|
||||||
cell: ({ cell }: any) => {
|
cell: ({ cell }: any) => {
|
||||||
const m = new Date(cell.getValue());
|
const m = new Date(cell.getValue());
|
||||||
const year = `${m.getUTCFullYear()}`.slice(-2);
|
const year = `${m.getFullYear()}`.slice(-2);
|
||||||
const month = `0${m.getUTCMonth() + 1}`.slice(-2);
|
const month = `0${m.getMonth() + 1}`.slice(-2);
|
||||||
const day = `0${m.getUTCDate()}`.slice(-2);
|
const day = `0${m.getDate()}`.slice(-2);
|
||||||
const hours = `0${m.getUTCHours()}`.slice(-2);
|
const hours = `0${m.getHours()}`.slice(-2);
|
||||||
const minutes = `0${m.getUTCMinutes()}`.slice(-2);
|
const minutes = `0${m.getMinutes()}`.slice(-2);
|
||||||
const dateString = `${month}/${day}/${year} ${hours}:${minutes}`;
|
const dateString = `${month}/${day}/${year} ${hours}:${minutes}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export function DataTable({
|
|||||||
setColumnFilters([]);
|
setColumnFilters([]);
|
||||||
}
|
}
|
||||||
}, [filtersEnabled]);
|
}, [filtersEnabled]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
className={scrollAreaClasses.default}
|
className={scrollAreaClasses.default}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ export function Filter({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
return filterVariant === 'range' ? (
|
return filterVariant === 'range' ? (
|
||||||
<div>
|
|
||||||
<DatePickerInput
|
<DatePickerInput
|
||||||
type='range'
|
type='range'
|
||||||
clearable
|
clearable
|
||||||
@@ -61,7 +60,6 @@ export function Filter({
|
|||||||
value={columnFilterValue as [Date, Date]}
|
value={columnFilterValue as [Date, Date]}
|
||||||
onChange={(value) => column.setFilterValue(value)}
|
onChange={(value) => column.setFilterValue(value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
) : filterVariant === 'select' ? (
|
) : filterVariant === 'select' ? (
|
||||||
<select
|
<select
|
||||||
onChange={(e) => column.setFilterValue(e.target.value)}
|
onChange={(e) => column.setFilterValue(e.target.value)}
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ export function DebouncedInput({
|
|||||||
} & Omit<TextInputProps, 'onChange'>) {
|
} & Omit<TextInputProps, 'onChange'>) {
|
||||||
const [value, setValue] = useState(initialValue);
|
const [value, setValue] = useState(initialValue);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setValue(initialValue);
|
|
||||||
}, [initialValue]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Modal, Stack } from '@mantine/core';
|
import { Modal, Stack } from '@mantine/core';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { modalClasses } from 'styles';
|
import { modalClasses } from 'styles';
|
||||||
import type { Application, Provider } from 'types';
|
import type { Application, GuacamoleClient, Provider } from 'types';
|
||||||
import HelpSection from './HelpSection';
|
import HelpSection from './HelpSection';
|
||||||
|
|
||||||
export function HelpModal({
|
export function HelpModal({
|
||||||
@@ -10,12 +10,14 @@ export function HelpModal({
|
|||||||
closeProviderModal,
|
closeProviderModal,
|
||||||
applicationData,
|
applicationData,
|
||||||
providerData,
|
providerData,
|
||||||
|
clientData,
|
||||||
}: {
|
}: {
|
||||||
handleResetSearch: () => void;
|
handleResetSearch: () => void;
|
||||||
providerModalOpened: boolean;
|
providerModalOpened: boolean;
|
||||||
closeProviderModal: () => void;
|
closeProviderModal: () => void;
|
||||||
applicationData: Application[];
|
applicationData: Application[];
|
||||||
providerData: Provider[];
|
providerData: Provider[];
|
||||||
|
clientData: GuacamoleClient[];
|
||||||
}) {
|
}) {
|
||||||
const { isMobile } = useCommonHooks();
|
const { isMobile } = useCommonHooks();
|
||||||
return (
|
return (
|
||||||
@@ -61,6 +63,16 @@ export function HelpModal({
|
|||||||
};
|
};
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
<Stack my={'.5rem'} />
|
||||||
|
<HelpSection
|
||||||
|
name={'Available Clients'}
|
||||||
|
items={clientData.map((client: GuacamoleClient) => {
|
||||||
|
return {
|
||||||
|
name: `${client.clientName} (${client.clientIdentifier})`,
|
||||||
|
command: `>${client.clientName}`,
|
||||||
|
};
|
||||||
|
})}
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
</Modal.Content>
|
</Modal.Content>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { Box, Card, Group, Stack, Text } from '@mantine/core';
|
import { Box, Card, Group, Stack, Text } from '@mantine/core';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks, useSunStateAPI } from 'hooks';
|
||||||
import { useSunStateAPI } from 'hooks/useAPI';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa';
|
import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa';
|
||||||
import { WiBarometer, WiHumidity, WiSunrise, WiSunset } from 'react-icons/wi';
|
import { WiBarometer, WiHumidity, WiSunrise, WiSunset } from 'react-icons/wi';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
@@ -16,21 +14,15 @@ export default function CurrentWeather({ current }: { current: CW }) {
|
|||||||
lon: currentLocation.lon,
|
lon: currentLocation.lon,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [sunStates, setSunStates] = useState<SunState[]>([]);
|
const sunStates: SunState[] =
|
||||||
|
sunStateData?.results.map((item: SunState) => {
|
||||||
useEffect(() => {
|
|
||||||
if (sunStateData) {
|
|
||||||
setSunStates(
|
|
||||||
sunStateData.results.map((item: SunState) => {
|
|
||||||
return {
|
return {
|
||||||
date: item.date,
|
date: item.date,
|
||||||
sunrise: item.sunrise,
|
sunrise: item.sunrise,
|
||||||
sunset: item.sunset,
|
sunset: item.sunset,
|
||||||
};
|
};
|
||||||
}),
|
}) || [];
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [sunStateData]);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{current && (
|
{current && (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ function WeatherFeaturePill({
|
|||||||
}: {
|
}: {
|
||||||
leftSide: React.ReactNode;
|
leftSide: React.ReactNode;
|
||||||
rightSide: React.ReactNode;
|
rightSide: React.ReactNode;
|
||||||
highlight?: string;
|
highlight?: 'left' | 'right';
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Center, Group, Modal, Stack, Text } from '@mantine/core';
|
import { Center, Group, Modal, Stack, Text } from '@mantine/core';
|
||||||
import { useCommonHooks, useWeatherAPI } from 'hooks';
|
import { useCommonHooks, useWeatherAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { modalClasses } from 'styles';
|
import { modalClasses } from 'styles';
|
||||||
|
|
||||||
import type { CurrentWeather as CW, ExtendedForecast, HourlyForecast } from 'types';
|
import type { CurrentWeather as CW, ExtendedForecast, HourlyForecast } from 'types';
|
||||||
@@ -28,13 +27,9 @@ export function WeatherModal({
|
|||||||
x: currentLocation.x,
|
x: currentLocation.x,
|
||||||
y: currentLocation.y,
|
y: currentLocation.y,
|
||||||
});
|
});
|
||||||
const [hourlyForecast, setHourlyForecast] = useState<HourlyForecast[]>([]);
|
const hourlyForecast: HourlyForecast[] =
|
||||||
|
hourly?.properties?.periods?.slice(1, 25) || [];
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (hourly) {
|
|
||||||
setHourlyForecast(hourly.properties.periods.slice(1, 25));
|
|
||||||
}
|
|
||||||
}, [hourly]);
|
|
||||||
return (
|
return (
|
||||||
<Modal.Root
|
<Modal.Root
|
||||||
fullScreen={isMobile}
|
fullScreen={isMobile}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export {
|
|||||||
useMutationAPI,
|
useMutationAPI,
|
||||||
useOSMAPI,
|
useOSMAPI,
|
||||||
useQueryAPI,
|
useQueryAPI,
|
||||||
|
useSunStateAPI,
|
||||||
useWeatherAPI,
|
useWeatherAPI,
|
||||||
} from './useAPI';
|
} from './useAPI';
|
||||||
export { useCommonHooks } from './useCommonHooks';
|
export { useCommonHooks } from './useCommonHooks';
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export function Homepage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const personal: PersonalData = personalData?.[0];
|
const personal: PersonalData = personalData?.[0];
|
||||||
const message: Message = messageData?.[0];
|
const message: Message = messageData?.[0] || {};
|
||||||
const [displayedGreeting, setDisplayedGreeting] = useState<string | undefined>('');
|
const [displayedGreeting, setDisplayedGreeting] = useState<string | undefined>('');
|
||||||
const [current, setCurrent] = useState<CW>({
|
const [current, setCurrent] = useState<CW>({
|
||||||
icon: '',
|
icon: '',
|
||||||
@@ -122,7 +122,7 @@ export function Homepage() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (personal) {
|
if (personal) {
|
||||||
setDisplayedGreeting(() => {
|
setDisplayedGreeting(() => {
|
||||||
if (Math.floor(Math.random() * 100) > 10 || message === undefined) {
|
if (Math.floor(Math.random() * 100) > 10 || message.message === undefined) {
|
||||||
switch (Math.floor(new Date().getHours() / 6)) {
|
switch (Math.floor(new Date().getHours() / 6)) {
|
||||||
case 0:
|
case 0:
|
||||||
return `Good night, ${personal?.firstName}!`;
|
return `Good night, ${personal?.firstName}!`;
|
||||||
|
|||||||
@@ -632,6 +632,7 @@ export default function Search({
|
|||||||
handleResetSearch={handleResetSearch}
|
handleResetSearch={handleResetSearch}
|
||||||
applicationData={applications}
|
applicationData={applications}
|
||||||
providerData={providers}
|
providerData={providers}
|
||||||
|
clientData={guacamoleClients}
|
||||||
providerModalOpened={providerModalOpened}
|
providerModalOpened={providerModalOpened}
|
||||||
closeProviderModal={closeProviderModal}
|
closeProviderModal={closeProviderModal}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ function SearchSelectItem({
|
|||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
const [showFillButton, setShowFillButton] = useState(false);
|
const [showFillButton, setShowFillButton] = useState(false);
|
||||||
const m = new Date(item.option.dateTimeStamp);
|
const m = new Date(item.option.dateTimeStamp);
|
||||||
const year = `${m.getUTCFullYear()}`.slice(-2);
|
const year = `${m.getFullYear()}`.slice(-2);
|
||||||
const month = `0${m.getUTCMonth() + 1}`.slice(-2);
|
const month = `0${m.getMonth() + 1}`.slice(-2);
|
||||||
const day = `0${m.getUTCDate()}`.slice(-2);
|
const day = `0${m.getDate()}`.slice(-2);
|
||||||
const hours = `0${m.getUTCHours()}`.slice(-2);
|
const hours = `0${m.getHours()}`.slice(-2);
|
||||||
const minutes = `0${m.getUTCMinutes()}`.slice(-2);
|
const minutes = `0${m.getMinutes()}`.slice(-2);
|
||||||
const dateString = isMobile
|
const dateString = isMobile
|
||||||
? `${month}/${day}/${year}`
|
? `${month}/${day}/${year}`
|
||||||
: `${month}/${day}/${year} ${hours}:${minutes}`;
|
: `${month}/${day}/${year} ${hours}:${minutes}`;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Box, Button, Group, Menu, Overlay, Stack } from '@mantine/core';
|
import { Box, Button, Group, Menu, Overlay, Stack } from '@mantine/core';
|
||||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { FiMenu, FiSettings } from 'react-icons/fi';
|
import { FiMenu, FiSettings } from 'react-icons/fi';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { buttonClasses, menuClasses } from 'styles';
|
import { buttonClasses, menuClasses } from 'styles';
|
||||||
@@ -10,21 +10,29 @@ import ThemingCard from './ThemingCard';
|
|||||||
import WakeOnLan from './WakeOnLanCard';
|
import WakeOnLan from './WakeOnLanCard';
|
||||||
|
|
||||||
function SettingsButton() {
|
function SettingsButton() {
|
||||||
const { data: appCategoryData, isFetched: appCategoryDataIsFetched } = useQueryAPI({
|
const { data: appCategoryData } = useQueryAPI({
|
||||||
endpoint: 'api/appCategories',
|
endpoint: 'api/appCategories',
|
||||||
});
|
});
|
||||||
const { data: wolClientData } = useQueryAPI({
|
const { data: wolClientData } = useQueryAPI({
|
||||||
endpoint: 'api/wolClients',
|
endpoint: 'api/wolClients',
|
||||||
});
|
});
|
||||||
const { data: wolEnabledData, isFetched: wolEnabledDataIsFetched } = useQueryAPI({
|
const { data: wolEnabledData } = useQueryAPI({
|
||||||
endpoint: 'api/wolEnabled',
|
endpoint: 'api/wolEnabled',
|
||||||
});
|
});
|
||||||
const wolClients: WolClient[] = wolClientData || [];
|
const wolClients: WolClient[] = wolClientData || [];
|
||||||
const [enabled, setEnabled] = useState<number>(0);
|
const enabled: number = wolEnabledData?.[0].enableWol || 0;
|
||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]);
|
const categories = appCategoryData
|
||||||
|
? [
|
||||||
|
{ value: 'All', label: 'All' },
|
||||||
|
...appCategoryData.map((category: AppCategory) => {
|
||||||
|
return { value: category.filterName, label: category.filterName };
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
: [{ value: 'All', label: 'All' }];
|
||||||
const [selectedClient, setSelectedClient] = useState<WolClient>(wolClientData?.[0]);
|
const [selectedClient, setSelectedClient] = useState<WolClient>(wolClientData?.[0]);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
theme,
|
theme,
|
||||||
isMobile,
|
isMobile,
|
||||||
@@ -54,21 +62,6 @@ function SettingsButton() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (appCategoryData) {
|
|
||||||
const list: [any] = appCategoryData.map((category: AppCategory) => {
|
|
||||||
return { value: category.filterName, label: category.filterName };
|
|
||||||
});
|
|
||||||
list.unshift({ value: 'All', label: 'All' });
|
|
||||||
setCategories(list);
|
|
||||||
}
|
|
||||||
}, [appCategoryData, appCategoryDataIsFetched]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (wolEnabledData && wolEnabledDataIsFetched) {
|
|
||||||
setEnabled(wolEnabledData[0].enableWol);
|
|
||||||
}
|
|
||||||
}, [wolEnabledData, wolEnabledDataIsFetched]);
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
classNames={menuClasses}
|
classNames={menuClasses}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import * as fa6 from 'react-icons/fa6';
|
import * as fa6 from 'react-icons/fa6';
|
||||||
import * as si from 'react-icons/si';
|
import * as si from 'react-icons/si';
|
||||||
import * as vsc from 'react-icons/vsc';
|
import * as vsc from 'react-icons/vsc';
|
||||||
import { popoverClasses, selectClasses, textInputClasses } from 'styles';
|
import { buttonClasses, popoverClasses, selectClasses, textInputClasses } from 'styles';
|
||||||
import type { Application } from 'types';
|
import type { Application } from 'types';
|
||||||
import DebouncedApplication from './DebouncedApplication';
|
import DebouncedApplication from './DebouncedApplication';
|
||||||
|
|
||||||
@@ -281,12 +281,16 @@ const ApplicationSettings = () => {
|
|||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
|||||||
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
||||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { textInputClasses } from 'styles';
|
import { buttonClasses, textInputClasses } from 'styles';
|
||||||
import type { Bookmark, BookmarkGroup } from 'types';
|
import type { Bookmark, BookmarkGroup } from 'types';
|
||||||
import DebouncedGroupSettingsItem from './DebouncedGroupSettingsItem';
|
import DebouncedGroupSettingsItem from './DebouncedGroupSettingsItem';
|
||||||
|
|
||||||
@@ -175,12 +175,16 @@ const BookmarkSettings = () => {
|
|||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -420,12 +420,16 @@ function DebouncedGroupSettingsItem({
|
|||||||
align='center'
|
align='center'
|
||||||
justify='center'
|
justify='center'
|
||||||
>
|
>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPopoverOpened(false);
|
setPopoverOpened(false);
|
||||||
form.reset();
|
form.reset();
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ import { isNotEmpty, useForm } from '@mantine/form';
|
|||||||
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
||||||
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
||||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FaTerminal } from 'react-icons/fa';
|
import { FaTerminal } from 'react-icons/fa';
|
||||||
import { FaComputer, FaDesktop } from 'react-icons/fa6';
|
import { FaComputer, FaDesktop } from 'react-icons/fa6';
|
||||||
import { popoverClasses, selectClasses, textInputClasses } from 'styles';
|
import { buttonClasses, popoverClasses, selectClasses, textInputClasses } from 'styles';
|
||||||
import type { GuacamoleClient } from 'types';
|
import type { GuacamoleClient } from 'types';
|
||||||
import DebouncedGuacamoleClient from './DebouncedGuacamoleClient';
|
import DebouncedGuacamoleClient from './DebouncedGuacamoleClient';
|
||||||
import GuacamoleClientSettingsItem from './GuacamoleClientSettingsItem';
|
import GuacamoleClientSettingsItem from './GuacamoleClientSettingsItem';
|
||||||
@@ -65,6 +65,12 @@ const GuacamoleClients = () => {
|
|||||||
form.reset();
|
form.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (debouncedSearch === searchValue) {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
}, [debouncedSearch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
@@ -169,12 +175,16 @@ const GuacamoleClients = () => {
|
|||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
|||||||
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
||||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { textInputClasses } from 'styles';
|
import { buttonClasses, textInputClasses } from 'styles';
|
||||||
import type { Message } from 'types';
|
import type { Message } from 'types';
|
||||||
import DebouncedMessage from './DebouncedMessage';
|
import DebouncedMessage from './DebouncedMessage';
|
||||||
|
|
||||||
@@ -53,6 +53,12 @@ const MessageSettings = () => {
|
|||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (debouncedSearch === searchValue) {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
}, [debouncedSearch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack w={'100%'}>
|
<Stack w={'100%'}>
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
@@ -112,12 +118,16 @@ const MessageSettings = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -17,25 +17,15 @@ import type { PersonalData } from 'types';
|
|||||||
|
|
||||||
const PersonalizationSettings = () => {
|
const PersonalizationSettings = () => {
|
||||||
const endpoint = 'api/personalData';
|
const endpoint = 'api/personalData';
|
||||||
const {
|
const { data: personalData, isFetching: personalDataIsFetching } = useQueryAPI({
|
||||||
data: personalData,
|
|
||||||
isFetched: personalDataIsFetched,
|
|
||||||
isFetching: personalDataIsFetching,
|
|
||||||
} = useQueryAPI({
|
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
});
|
});
|
||||||
const [personal, setPersonal] = useState<PersonalData>();
|
const [personal, setPersonal] = useState<PersonalData>(personalData?.[0] || {});
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<any>({});
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
const { isMobile, theme } = useCommonHooks();
|
const { isMobile, theme } = useCommonHooks();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (personalData && personalDataIsFetched) {
|
|
||||||
setPersonal(personalData[0]);
|
|
||||||
}
|
|
||||||
}, [personalData, personalDataIsFetched]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (Object.keys(debounced).length) {
|
||||||
setPersonal(update);
|
setPersonal(update);
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ function DebouncedSearchProvider({
|
|||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: '1rem',
|
right: '1rem',
|
||||||
top: '.5rem',
|
top: '.5rem',
|
||||||
|
zIndex: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ManagementPill
|
<ManagementPill
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { FiPower } from 'react-icons/fi';
|
|||||||
import * as si from 'react-icons/si';
|
import * as si from 'react-icons/si';
|
||||||
import * as vsc from 'react-icons/vsc';
|
import * as vsc from 'react-icons/vsc';
|
||||||
import {
|
import {
|
||||||
|
buttonClasses,
|
||||||
popoverClasses,
|
popoverClasses,
|
||||||
selectClasses,
|
selectClasses,
|
||||||
switchClasses,
|
switchClasses,
|
||||||
@@ -236,12 +237,16 @@ const SearchProviderSettings = () => {
|
|||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Button, Card, FileInput, Group, Image, Stack, TextInput } from '@mantine/core';
|
import { Button, Card, FileInput, Group, Image, Stack, TextInput } from '@mantine/core';
|
||||||
import { useFileUploadAPI } from 'hooks/useAPI';
|
import { useFileUploadAPI } from 'hooks/useAPI';
|
||||||
|
import { buttonClasses } from 'styles';
|
||||||
|
|
||||||
export function AddBackground({
|
export function AddBackground({
|
||||||
fileName,
|
fileName,
|
||||||
@@ -131,7 +132,8 @@ export function AddBackground({
|
|||||||
Upload
|
Upload
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color='var(--mantine-color-red-6)'
|
className={buttonClasses.cancelButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleAddBackgroundModalClose();
|
handleAddBackgroundModalClose();
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Button, Card, Group, Stack, Text } from '@mantine/core';
|
import { Button, Card, Group, Stack, Text } from '@mantine/core';
|
||||||
import { useMutationAPI } from 'hooks';
|
import { useMutationAPI } from 'hooks';
|
||||||
|
import { buttonClasses } from 'styles';
|
||||||
|
|
||||||
export function DeleteBackground({
|
export function DeleteBackground({
|
||||||
fileName,
|
fileName,
|
||||||
@@ -63,7 +64,12 @@ export function DeleteBackground({
|
|||||||
>
|
>
|
||||||
DELETE
|
DELETE
|
||||||
</Button>
|
</Button>
|
||||||
<Button mt={'auto'} onClick={handleDeleteBackgroundModalClose}>
|
<Button
|
||||||
|
className={buttonClasses.cancelButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
mt={'auto'}
|
||||||
|
onClick={handleDeleteBackgroundModalClose}
|
||||||
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Button, Group, Image, Stack, Text, TextInput } from '@mantine/core';
|
import { Button, Group, Image, Stack, Text, TextInput } from '@mantine/core';
|
||||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { textInputClasses } from 'styles';
|
import { buttonClasses, textInputClasses } from 'styles';
|
||||||
|
|
||||||
export function EditBackground({
|
export function EditBackground({
|
||||||
fileName,
|
fileName,
|
||||||
@@ -54,7 +54,8 @@ export function EditBackground({
|
|||||||
<Group>
|
<Group>
|
||||||
<Button
|
<Button
|
||||||
mt={'auto'}
|
mt={'auto'}
|
||||||
color='green'
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
!rename.endsWith('.png') &&
|
!rename.endsWith('.png') &&
|
||||||
@@ -88,8 +89,9 @@ export function EditBackground({
|
|||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
className={buttonClasses.cancelButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
mt={'auto'}
|
mt={'auto'}
|
||||||
color={'var(--mantine-color-red-6)'}
|
|
||||||
onClick={handleEditBackgroundModalClose}
|
onClick={handleEditBackgroundModalClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Button, Group, Modal, Text, TextInput } from '@mantine/core';
|
|||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FaTag } from 'react-icons/fa';
|
import { FaTag } from 'react-icons/fa';
|
||||||
import { modalClasses, textInputClasses } from 'styles';
|
import { buttonClasses, modalClasses, textInputClasses } from 'styles';
|
||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
import { ThemePreviewMiddleware } from '../../Themes';
|
import { ThemePreviewMiddleware } from '../../Themes';
|
||||||
import { TimeOfDay } from './TimeOfDay';
|
import { TimeOfDay } from './TimeOfDay';
|
||||||
@@ -115,12 +115,17 @@ export function ThemePlaylistModal({
|
|||||||
})}
|
})}
|
||||||
</Group>
|
</Group>
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button color={'green'} onClick={handleSavePlaylist}>
|
<Button
|
||||||
|
color={'green'}
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
onClick={handleSavePlaylist}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleClose();
|
handleClose();
|
||||||
setThemeList('[]');
|
setThemeList('[]');
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { useRef, useState } from 'react';
|
|||||||
import { FaShuffle } from 'react-icons/fa6';
|
import { FaShuffle } from 'react-icons/fa6';
|
||||||
import { FiImage, FiSave, FiShuffle, FiX } from 'react-icons/fi';
|
import { FiImage, FiSave, FiShuffle, FiX } from 'react-icons/fi';
|
||||||
import {
|
import {
|
||||||
|
buttonClasses,
|
||||||
colorSwatchClasses,
|
colorSwatchClasses,
|
||||||
scrollAreaClasses,
|
scrollAreaClasses,
|
||||||
textClasses,
|
textClasses,
|
||||||
@@ -657,14 +658,15 @@ export function ThemeEditor({
|
|||||||
<Group>
|
<Group>
|
||||||
<Button
|
<Button
|
||||||
disabled={JSON.stringify(defaultTheme) === JSON.stringify(selectedTheme)}
|
disabled={JSON.stringify(defaultTheme) === JSON.stringify(selectedTheme)}
|
||||||
color={'green'}
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
onClick={handleSaveTheme}
|
onClick={handleSaveTheme}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleClose();
|
handleClose();
|
||||||
closeBackgroundPicker();
|
closeBackgroundPicker();
|
||||||
|
|||||||
@@ -33,11 +33,7 @@ export function Themes() {
|
|||||||
const allThemes: Theme[] = allThemeData?.filter((a: Theme) =>
|
const allThemes: Theme[] = allThemeData?.filter((a: Theme) =>
|
||||||
a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()),
|
a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()),
|
||||||
);
|
);
|
||||||
const {
|
const { data: backgroundData, isFetching: backgroundDataIsFetching } = useQueryAPI({
|
||||||
data: backgroundData,
|
|
||||||
isFetched: backgroundDataIsFetched,
|
|
||||||
isFetching: backgroundDataIsFetching,
|
|
||||||
} = useQueryAPI({
|
|
||||||
endpoint: backgroundsEndpoint,
|
endpoint: backgroundsEndpoint,
|
||||||
});
|
});
|
||||||
const { data: themePlaylistData } = useQueryAPI({
|
const { data: themePlaylistData } = useQueryAPI({
|
||||||
@@ -50,7 +46,9 @@ export function Themes() {
|
|||||||
backgroundModalOpened,
|
backgroundModalOpened,
|
||||||
{ open: openBackgroundModal, close: closeBackgroundModal },
|
{ open: openBackgroundModal, close: closeBackgroundModal },
|
||||||
] = useDisclosure(false);
|
] = useDisclosure(false);
|
||||||
const [backgroundList, setBackgroundList] = useState<string[]>(['None']);
|
const backgroundList = backgroundData
|
||||||
|
? ['None', ...backgroundData.sort((a: string, b: string) => a.localeCompare(b))]
|
||||||
|
: ['None'];
|
||||||
const inUseBackgrounds: string[] = [
|
const inUseBackgrounds: string[] = [
|
||||||
...new Set(
|
...new Set(
|
||||||
allThemes
|
allThemes
|
||||||
@@ -76,6 +74,7 @@ export function Themes() {
|
|||||||
textShadowsEnabled: 0,
|
textShadowsEnabled: 0,
|
||||||
appShadowsEnabled: 0,
|
appShadowsEnabled: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [isNew, setIsNew] = useState(false);
|
const [isNew, setIsNew] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -93,15 +92,6 @@ export function Themes() {
|
|||||||
openThemeModal();
|
openThemeModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (backgroundData && backgroundDataIsFetched) {
|
|
||||||
setBackgroundList([
|
|
||||||
'None',
|
|
||||||
...backgroundData.sort((a: string, b: string) => a.localeCompare(b)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}, [backgroundData, backgroundDataIsFetched]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (debouncedSearch === searchValue) {
|
if (debouncedSearch === searchValue) {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
|||||||
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
import { AddItemModal, NoItemsFound, SettingsHeader } from 'components';
|
||||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { popoverClasses, textInputClasses } from 'styles';
|
import { buttonClasses, popoverClasses, textInputClasses } from 'styles';
|
||||||
import type { WolClient } from 'types';
|
import type { WolClient } from 'types';
|
||||||
import DebouncedWolClient from './DebouncedWolClient';
|
import DebouncedWolClient from './DebouncedWolClient';
|
||||||
import WolClientSettingsItem from './WolClientSettingsItem';
|
import WolClientSettingsItem from './WolClientSettingsItem';
|
||||||
@@ -116,12 +116,16 @@ const WolClientSettings = () => {
|
|||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group mt={'1rem'}>
|
<Group mt={'1rem'}>
|
||||||
<Button type='submit' color={'green'}>
|
<Button
|
||||||
|
type='submit'
|
||||||
|
className={buttonClasses.saveButton}
|
||||||
|
classNames={buttonClasses}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color={'red'}
|
className={buttonClasses.cancelButton}
|
||||||
styles={{ label: { color: 'black' } }}
|
classNames={buttonClasses}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -74,3 +74,27 @@
|
|||||||
color: var(--mantine-color-background-0) !important;
|
color: var(--mantine-color-background-0) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.saveButton {
|
||||||
|
&.root {
|
||||||
|
background-color: var(--mantine-color-green-filled);
|
||||||
|
.label {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--mantine-color-green-filled-hover) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancelButton {
|
||||||
|
&.root {
|
||||||
|
background-color: var(--mantine-color-red-filled);
|
||||||
|
.label {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--mantine-color-red-filled-hover) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user