This commit is contained in:
@@ -5,7 +5,7 @@ import type { SearchHistoryItem } from 'types';
|
|||||||
|
|
||||||
const columnHelper = createColumnHelper<SearchHistoryItem>();
|
const columnHelper = createColumnHelper<SearchHistoryItem>();
|
||||||
export const SearchHistoryColumns = (
|
export const SearchHistoryColumns = (
|
||||||
setSelectedItem: React.Dispatch<React.SetStateAction<any>>,
|
setSelectedItem: React.Dispatch<React.SetStateAction<SearchHistoryItem | undefined>>,
|
||||||
deleteItemOpen: () => void,
|
deleteItemOpen: () => void,
|
||||||
filtersEnabled: boolean,
|
filtersEnabled: boolean,
|
||||||
setFiltersEnabled: React.Dispatch<React.SetStateAction<boolean>>,
|
setFiltersEnabled: React.Dispatch<React.SetStateAction<boolean>>,
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import HelpSection from './HelpSection';
|
|||||||
|
|
||||||
export function HelpModal({
|
export function HelpModal({
|
||||||
handleResetSearch,
|
handleResetSearch,
|
||||||
providerModalOpened,
|
modalOpened,
|
||||||
closeProviderModal,
|
closeProviderModal,
|
||||||
applicationData,
|
applicationData,
|
||||||
providerData,
|
providerData,
|
||||||
clientData,
|
clientData,
|
||||||
}: {
|
}: {
|
||||||
handleResetSearch: () => void;
|
handleResetSearch: () => void;
|
||||||
providerModalOpened: boolean;
|
modalOpened: boolean;
|
||||||
closeProviderModal: () => void;
|
closeProviderModal: () => void;
|
||||||
applicationData: Application[];
|
applicationData: Application[];
|
||||||
providerData: Provider[];
|
providerData: Provider[];
|
||||||
@@ -25,7 +25,7 @@ export function HelpModal({
|
|||||||
size={'60%'}
|
size={'60%'}
|
||||||
className={modalClasses.helpModal}
|
className={modalClasses.helpModal}
|
||||||
classNames={modalClasses}
|
classNames={modalClasses}
|
||||||
opened={providerModalOpened}
|
opened={modalOpened}
|
||||||
fullScreen={isMobile}
|
fullScreen={isMobile}
|
||||||
centered
|
centered
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export { AddItemModal } from './AddItemModal';
|
export { AddItemModal } from './AddItemModal';
|
||||||
export { AppItem } from './Applications/AppItem';
|
export { AppItem } from './Applications/AppItem';
|
||||||
|
export { SearchHistoryColumns } from './Columns/SearchHistoryColumns';
|
||||||
export { DataTable } from './DataTable/DataTable';
|
export { DataTable } from './DataTable/DataTable';
|
||||||
export { DebouncedInput } from './DebouncedInput';
|
export { DebouncedInput } from './DebouncedInput';
|
||||||
export { DeleteItemModal } from './DeleteItemModal';
|
export { DeleteItemModal } from './DeleteItemModal';
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ import type {
|
|||||||
Message,
|
Message,
|
||||||
PersonalData,
|
PersonalData,
|
||||||
} from 'types';
|
} from 'types';
|
||||||
import Applications from './components/Applications/Applications';
|
import {
|
||||||
import Bookmarks from './components/Bookmarks/Bookmarks';
|
Applications,
|
||||||
import Header from './components/Header/Header';
|
Bookmarks,
|
||||||
import LargeHeader from './components/Header/LargeHeader';
|
Header,
|
||||||
import Search from './components/Search/Search';
|
LargeHeader,
|
||||||
import SettingsButton from './components/SettingsButton/SettingsButton';
|
Search,
|
||||||
|
SettingsButton,
|
||||||
|
} from './components';
|
||||||
|
|
||||||
export function Homepage() {
|
export function Homepage() {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useCommonHooks, useQueryAPI } from 'hooks';
|
|||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { Application } from 'types';
|
import type { Application } from 'types';
|
||||||
|
|
||||||
function Applications({ contentType }: { contentType: string[] }) {
|
export function Applications({ contentType }: { contentType: string[] }) {
|
||||||
const { data: applicationData } = useQueryAPI({
|
const { data: applicationData } = useQueryAPI({
|
||||||
endpoint: 'api/enabledApplications',
|
endpoint: 'api/enabledApplications',
|
||||||
});
|
});
|
||||||
@@ -76,5 +76,3 @@ function Applications({ contentType }: { contentType: string[] }) {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Applications;
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { textClasses } from 'styles';
|
|||||||
import type { Bookmark, BookmarkGroup } from 'types';
|
import type { Bookmark, BookmarkGroup } from 'types';
|
||||||
import BookmarkGroups from './BookmarkGroups';
|
import BookmarkGroups from './BookmarkGroups';
|
||||||
|
|
||||||
function Bookmarks({ contentType }: { contentType: string[] }) {
|
export function Bookmarks({ contentType }: { contentType: string[] }) {
|
||||||
const { data: bookmarkData, isFetched: bookmarksIsFetched } = useQueryAPI({
|
const { data: bookmarkData, isFetched: bookmarksIsFetched } = useQueryAPI({
|
||||||
endpoint: 'api/bookmarks',
|
endpoint: 'api/bookmarks',
|
||||||
});
|
});
|
||||||
@@ -95,5 +95,3 @@ function Bookmarks({ contentType }: { contentType: string[] }) {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Bookmarks;
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { CurrentWeather } from 'types';
|
import type { CurrentWeather } from 'types';
|
||||||
|
|
||||||
function Header({
|
export function Header({
|
||||||
greet,
|
greet,
|
||||||
date,
|
date,
|
||||||
current,
|
current,
|
||||||
@@ -140,5 +140,3 @@ function Header({
|
|||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Header;
|
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ import { useCommonHooks } from 'hooks';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
|
|
||||||
function LargeHeader({ greet, date }: { greet: string | undefined; date: string }) {
|
export function LargeHeader({
|
||||||
|
greet,
|
||||||
|
date,
|
||||||
|
}: {
|
||||||
|
greet: string | undefined;
|
||||||
|
date: string;
|
||||||
|
}) {
|
||||||
const [time, setTime] = useState(new Date());
|
const [time, setTime] = useState(new Date());
|
||||||
const {
|
const {
|
||||||
isMobile,
|
isMobile,
|
||||||
@@ -79,5 +85,3 @@ function LargeHeader({ greet, date }: { greet: string | undefined; date: string
|
|||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LargeHeader;
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import RecommendedBookmarks from './components/RecommendedBookmarks';
|
|||||||
import RecommendedClients from './components/RecommendedClients';
|
import RecommendedClients from './components/RecommendedClients';
|
||||||
import RenderItem from './components/RenderItem';
|
import RenderItem from './components/RenderItem';
|
||||||
|
|
||||||
export default function Search({
|
export function Search({
|
||||||
current,
|
current,
|
||||||
extendedForecast,
|
extendedForecast,
|
||||||
weatherModalOpened,
|
weatherModalOpened,
|
||||||
@@ -634,14 +634,17 @@ export default function Search({
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
{providerModalOpened && (
|
||||||
<HelpModal
|
<HelpModal
|
||||||
handleResetSearch={handleResetSearch}
|
handleResetSearch={handleResetSearch}
|
||||||
applicationData={applications}
|
applicationData={applications}
|
||||||
providerData={providers}
|
providerData={providers}
|
||||||
clientData={guacamoleClients}
|
clientData={guacamoleClients}
|
||||||
providerModalOpened={providerModalOpened}
|
modalOpened={providerModalOpened}
|
||||||
closeProviderModal={closeProviderModal}
|
closeProviderModal={closeProviderModal}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{weatherModalOpened && (
|
||||||
<WeatherModal
|
<WeatherModal
|
||||||
current={current}
|
current={current}
|
||||||
extendedForecast={extendedForecast}
|
extendedForecast={extendedForecast}
|
||||||
@@ -649,6 +652,7 @@ export default function Search({
|
|||||||
handleResetSearch={handleResetSearch}
|
handleResetSearch={handleResetSearch}
|
||||||
closeWeatherModal={closeWeatherModal}
|
closeWeatherModal={closeWeatherModal}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import SettingsCard from './SettingsCard';
|
|||||||
import ThemingCard from './ThemingCard';
|
import ThemingCard from './ThemingCard';
|
||||||
import WakeOnLan from './WakeOnLanCard';
|
import WakeOnLan from './WakeOnLanCard';
|
||||||
|
|
||||||
function SettingsButton({ openProviderModal }: { openProviderModal: () => void }) {
|
export function SettingsButton({ openProviderModal }: { openProviderModal: () => void }) {
|
||||||
const { data: appCategoryData } = useQueryAPI({
|
const { data: appCategoryData } = useQueryAPI({
|
||||||
endpoint: 'api/appCategories',
|
endpoint: 'api/appCategories',
|
||||||
});
|
});
|
||||||
@@ -171,5 +171,3 @@ function SettingsButton({ openProviderModal }: { openProviderModal: () => void }
|
|||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SettingsButton;
|
|
||||||
|
|||||||
6
src/pages/homepage/components/index.ts
Normal file
6
src/pages/homepage/components/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export { Applications } from './Applications/Applications';
|
||||||
|
export { Bookmarks } from './Bookmarks/Bookmarks';
|
||||||
|
export { Header } from './Header/Header';
|
||||||
|
export { LargeHeader } from './Header/LargeHeader';
|
||||||
|
export { Search } from './Search/Search';
|
||||||
|
export { SettingsButton } from './SettingsButton/SettingsButton';
|
||||||
@@ -13,16 +13,18 @@ import {
|
|||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { actionIconClasses, scrollAreaClasses, tabClasses, textClasses } from 'styles';
|
import { actionIconClasses, scrollAreaClasses, tabClasses, textClasses } from 'styles';
|
||||||
import type { PersonalData } from 'types';
|
import type { PersonalData } from 'types';
|
||||||
import Applications from './components/Applications/Applications';
|
import {
|
||||||
import Bookmarks from './components/Bookmarks/Bookmarks';
|
Applications,
|
||||||
import GuacamoleClients from './components/GuacamoleClients/GuacamoleClients';
|
Bookmarks,
|
||||||
import Messages from './components/Messages/Messages';
|
GuacamoleClients,
|
||||||
import Personalization from './components/Personalization/Personalization';
|
Messages,
|
||||||
import SearchHistory from './components/Search/SearchHistory';
|
Personalization,
|
||||||
import SearchProviders from './components/Search/SearchProviders';
|
SearchHistory,
|
||||||
import { ThemePlaylists } from './components/Theming/ThemePlaylists';
|
SearchProviders,
|
||||||
import { Themes } from './components/Theming/Themes';
|
ThemePlaylists,
|
||||||
import WolClients from './components/WoL/WolClients';
|
Themes,
|
||||||
|
WolClients,
|
||||||
|
} from './components';
|
||||||
|
|
||||||
export function Settings() {
|
export function Settings() {
|
||||||
const endpoint = 'api/personalData';
|
const endpoint = 'api/personalData';
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import { buttonClasses, popoverClasses, selectClasses, textInputClasses } from '
|
|||||||
import type { Application } from 'types';
|
import type { Application } from 'types';
|
||||||
import DebouncedApplication from './DebouncedApplication';
|
import DebouncedApplication from './DebouncedApplication';
|
||||||
|
|
||||||
const ApplicationSettings = () => {
|
export function Applications() {
|
||||||
const allIcons: any = { ...fa6, ...vsc, ...si };
|
const allIcons: any = { ...fa6, ...vsc, ...si };
|
||||||
const defaultApplication: Application = {
|
const defaultApplication: Application = {
|
||||||
id: null,
|
id: null,
|
||||||
@@ -141,6 +141,7 @@ const ApplicationSettings = () => {
|
|||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
setIsLoading={setIsLoading}
|
setIsLoading={setIsLoading}
|
||||||
/>
|
/>
|
||||||
|
{modalOpened && (
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -300,6 +301,7 @@ const ApplicationSettings = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<DragDropContext onDragEnd={onDragEnd}>
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
<Stack
|
<Stack
|
||||||
mt={isMobile ? '10rem' : '6rem'}
|
mt={isMobile ? '10rem' : '6rem'}
|
||||||
@@ -410,5 +412,4 @@ const ApplicationSettings = () => {
|
|||||||
</DragDropContext>
|
</DragDropContext>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default ApplicationSettings;
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ function DebouncedApplication({
|
|||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
|
|
||||||
const [app, setApp] = useState<Application>(application);
|
const [app, setApp] = useState<Application>(application);
|
||||||
const [update, setUpdate] = useState<any>();
|
const [update, setUpdate] = useState<Application>();
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
@@ -53,6 +53,7 @@ function DebouncedApplication({
|
|||||||
className={cardClasses.settingsItem}
|
className={cardClasses.settingsItem}
|
||||||
classNames={cardClasses}
|
classNames={cardClasses}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -69,6 +70,7 @@ function DebouncedApplication({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@@ -192,7 +194,7 @@ function DebouncedApplication({
|
|||||||
onChange={(value: string | null) => {
|
onChange={(value: string | null) => {
|
||||||
setUpdate({
|
setUpdate({
|
||||||
...app,
|
...app,
|
||||||
icon: value,
|
icon: value as Application['icon'],
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
renderOption={(item: ComboboxLikeRenderOptionInput<ComboboxItem>) => {
|
renderOption={(item: ComboboxLikeRenderOptionInput<ComboboxItem>) => {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ 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';
|
||||||
|
|
||||||
const BookmarkSettings = () => {
|
export function Bookmarks() {
|
||||||
const defaultGroup = {
|
const defaultGroup = {
|
||||||
id: null,
|
id: null,
|
||||||
categoryName: '',
|
categoryName: '',
|
||||||
@@ -68,7 +68,7 @@ const BookmarkSettings = () => {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
const foundGroups: BookmarkGroup[] = groupData.filter((a: BookmarkGroup) =>
|
const foundGroups: BookmarkGroup[] = groupData?.filter((a: BookmarkGroup) =>
|
||||||
a.categoryName.toLowerCase().includes((debouncedGroupSearch as string).toLowerCase()),
|
a.categoryName.toLowerCase().includes((debouncedGroupSearch as string).toLowerCase()),
|
||||||
);
|
);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
@@ -121,6 +121,7 @@ const BookmarkSettings = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
{modalOpened && (
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -194,6 +195,7 @@ const BookmarkSettings = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
setDragging={groups.length > 0 ? setDragging : undefined}
|
setDragging={groups.length > 0 ? setDragging : undefined}
|
||||||
openModal={openModal}
|
openModal={openModal}
|
||||||
@@ -337,5 +339,4 @@ const BookmarkSettings = () => {
|
|||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default BookmarkSettings;
|
|
||||||
|
|||||||
@@ -25,20 +25,20 @@ function DebouncedBookmarkItem({
|
|||||||
(a: BookmarkGroup, b: BookmarkGroup) =>
|
(a: BookmarkGroup, b: BookmarkGroup) =>
|
||||||
a.categoryName.toLocaleLowerCase() > b.categoryName.toLocaleLowerCase(),
|
a.categoryName.toLocaleLowerCase() > b.categoryName.toLocaleLowerCase(),
|
||||||
) || [];
|
) || [];
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<Bookmark>();
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
closeModal();
|
closeModal();
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (debounced && Object.keys(debounced).length) {
|
||||||
mutateAsync({ method: 'PATCH', endpoint: 'api/bookmarks', body: debounced });
|
mutateAsync({ method: 'PATCH', endpoint: 'api/bookmarks', body: debounced });
|
||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (update !== bookmark && Object.keys(update).length) {
|
if (update && update !== bookmark && Object.keys(update).length) {
|
||||||
setBookmark(update);
|
setBookmark(update);
|
||||||
}
|
}
|
||||||
}, [update]);
|
}, [update]);
|
||||||
@@ -49,6 +49,7 @@ function DebouncedBookmarkItem({
|
|||||||
className={cardClasses.settingsItem}
|
className={cardClasses.settingsItem}
|
||||||
classNames={cardClasses}
|
classNames={cardClasses}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -65,6 +66,7 @@ function DebouncedBookmarkItem({
|
|||||||
}
|
}
|
||||||
title='Delete Bookmark'
|
title='Delete Bookmark'
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@@ -142,7 +144,7 @@ function DebouncedBookmarkItem({
|
|||||||
onChange={(value: string | null) => {
|
onChange={(value: string | null) => {
|
||||||
setUpdate({
|
setUpdate({
|
||||||
...bookmark,
|
...bookmark,
|
||||||
category: value,
|
category: value as BookmarkGroup['categoryName'],
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
searchable
|
searchable
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function DebouncedGroupSettingsItem({
|
|||||||
const [popoverOpened, setPopoverOpened] = useState(false);
|
const [popoverOpened, setPopoverOpened] = useState(false);
|
||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
const [group, setGroup] = useState<BookmarkGroup>(bookmarkGroup);
|
const [group, setGroup] = useState<BookmarkGroup>(bookmarkGroup);
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<BookmarkGroup>();
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
const [newBookmark, setNewBookmark] = useState<Bookmark>({
|
const [newBookmark, setNewBookmark] = useState<Bookmark>({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
@@ -89,18 +89,18 @@ function DebouncedGroupSettingsItem({
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (debounced && Object.keys(debounced).length) {
|
||||||
mutateAsync({
|
mutateAsync({
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
endpoint: 'api/bookmarkCategories',
|
endpoint: 'api/bookmarkCategories',
|
||||||
body: debounced,
|
body: debounced,
|
||||||
});
|
});
|
||||||
setUpdate({});
|
setUpdate(undefined);
|
||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (update !== group && Object.keys(update).length) {
|
if (update && update !== group && Object.keys(update).length) {
|
||||||
setGroup(update);
|
setGroup(update);
|
||||||
}
|
}
|
||||||
}, [update]);
|
}, [update]);
|
||||||
@@ -113,6 +113,7 @@ function DebouncedGroupSettingsItem({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card w={'400px'} className={cardClasses.settingsItem} classNames={cardClasses}>
|
<Card w={'400px'} className={cardClasses.settingsItem} classNames={cardClasses}>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={closeModal}
|
handleClose={closeModal}
|
||||||
@@ -135,6 +136,7 @@ function DebouncedGroupSettingsItem({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Card.Section
|
<Card.Section
|
||||||
p={'1rem'}
|
p={'1rem'}
|
||||||
pt={0}
|
pt={0}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function DebouncedGuacamoleClient({
|
|||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
const types: string[] = ['SSH', 'RDP', 'VNC'];
|
const types: string[] = ['SSH', 'RDP', 'VNC'];
|
||||||
const [client, setClient] = useState<GuacamoleClient>(guacamoleClient);
|
const [client, setClient] = useState<GuacamoleClient>(guacamoleClient);
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<GuacamoleClient>();
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
@@ -46,13 +46,13 @@ function DebouncedGuacamoleClient({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (debounced && Object.keys(debounced).length) {
|
||||||
mutateAsync({ method: 'PATCH', endpoint: 'api/guacamoleClients', body: debounced });
|
mutateAsync({ method: 'PATCH', endpoint: 'api/guacamoleClients', body: debounced });
|
||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (update !== client && Object.keys(update).length) {
|
if (update && update !== client && Object.keys(update).length) {
|
||||||
setClient(update);
|
setClient(update);
|
||||||
}
|
}
|
||||||
}, [update]);
|
}, [update]);
|
||||||
@@ -62,6 +62,7 @@ function DebouncedGuacamoleClient({
|
|||||||
className={cardClasses.settingsItem}
|
className={cardClasses.settingsItem}
|
||||||
classNames={cardClasses}
|
classNames={cardClasses}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -78,6 +79,7 @@ function DebouncedGuacamoleClient({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
className={toolTipClasses.default}
|
className={toolTipClasses.default}
|
||||||
classNames={toolTipClasses}
|
classNames={toolTipClasses}
|
||||||
@@ -177,7 +179,7 @@ function DebouncedGuacamoleClient({
|
|||||||
onChange={(value: string | null) => {
|
onChange={(value: string | null) => {
|
||||||
setUpdate({
|
setUpdate({
|
||||||
...guacamoleClient,
|
...guacamoleClient,
|
||||||
type: value,
|
type: value as GuacamoleClient['type'],
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
searchable
|
searchable
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Card, Stack, Text } from '@mantine/core';
|
import { Card, Stack, Text } from '@mantine/core';
|
||||||
import { FaDesktop, FaTerminal } from 'react-icons/fa';
|
import { FaComputer, FaDesktop, FaTerminal } from 'react-icons/fa6';
|
||||||
import { FaComputer } from 'react-icons/fa6';
|
|
||||||
import { cardClasses } from 'styles';
|
import { cardClasses } from 'styles';
|
||||||
import type { GuacamoleClient } from 'types';
|
import type { GuacamoleClient } from 'types';
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,13 @@ 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 { FaTerminal } from 'react-icons/fa';
|
import { FaComputer, FaDesktop, FaTerminal } from 'react-icons/fa6';
|
||||||
import { FaComputer, FaDesktop } from 'react-icons/fa6';
|
|
||||||
import { buttonClasses, 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';
|
||||||
|
|
||||||
const GuacamoleClients = () => {
|
export function GuacamoleClients() {
|
||||||
const defaultGuacamoleClient: GuacamoleClient = {
|
const defaultGuacamoleClient: GuacamoleClient = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
clientName: '',
|
clientName: '',
|
||||||
@@ -73,6 +72,7 @@ const GuacamoleClients = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
{modalOpened && (
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -194,6 +194,7 @@ const GuacamoleClients = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
setDragging={undefined}
|
setDragging={undefined}
|
||||||
openModal={openModal}
|
openModal={openModal}
|
||||||
@@ -267,5 +268,4 @@ const GuacamoleClients = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default GuacamoleClients;
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ function DebouncedMessage({
|
|||||||
w={'100%'}
|
w={'100%'}
|
||||||
style={{ alignItems: 'center' }}
|
style={{ alignItems: 'center' }}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={closeModal}
|
handleClose={closeModal}
|
||||||
@@ -39,6 +40,7 @@ function DebouncedMessage({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { buttonClasses, textInputClasses } from 'styles';
|
|||||||
import type { Message } from 'types';
|
import type { Message } from 'types';
|
||||||
import DebouncedMessage from './DebouncedMessage';
|
import DebouncedMessage from './DebouncedMessage';
|
||||||
|
|
||||||
const MessageSettings = () => {
|
export function Messages() {
|
||||||
const endpoint = 'api/messages';
|
const endpoint = 'api/messages';
|
||||||
const { data: messageData, isFetching: messageDataIsFetching } = useQueryAPI({
|
const { data: messageData, isFetching: messageDataIsFetching } = useQueryAPI({
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
@@ -83,6 +83,7 @@ const MessageSettings = () => {
|
|||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
setIsLoading={setIsLoading}
|
setIsLoading={setIsLoading}
|
||||||
/>
|
/>
|
||||||
|
{modalOpened && (
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -137,6 +138,7 @@ const MessageSettings = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Stack
|
<Stack
|
||||||
mt={isMobile ? '10rem' : '6rem'}
|
mt={isMobile ? '10rem' : '6rem'}
|
||||||
mb={isMobile ? '6rem' : undefined}
|
mb={isMobile ? '6rem' : undefined}
|
||||||
@@ -173,5 +175,4 @@ const MessageSettings = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default MessageSettings;
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import FontPicker from 'react-fontpicker-ts';
|
|||||||
import { cardClasses, switchClasses, textClasses, textInputClasses } from 'styles';
|
import { cardClasses, switchClasses, textClasses, textInputClasses } from 'styles';
|
||||||
import type { PersonalData } from 'types';
|
import type { PersonalData } from 'types';
|
||||||
|
|
||||||
const PersonalizationSettings = () => {
|
export function Personalization() {
|
||||||
const endpoint = 'api/personalData';
|
const endpoint = 'api/personalData';
|
||||||
const { data: personalData, isFetching: personalDataIsFetching } = useQueryAPI({
|
const { data: personalData, isFetching: personalDataIsFetching } = useQueryAPI({
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
@@ -27,14 +27,14 @@ const PersonalizationSettings = () => {
|
|||||||
personal?.enableGuacamole === 1,
|
personal?.enableGuacamole === 1,
|
||||||
);
|
);
|
||||||
const [defaultFont, setDefaultFont] = useState<string>(personal?.defaultFont);
|
const [defaultFont, setDefaultFont] = useState<string>(personal?.defaultFont);
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<PersonalData>();
|
||||||
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(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (debounced && Object.keys(debounced).length) {
|
||||||
mutateAsync({ method: 'PATCH', endpoint: endpoint, body: debounced });
|
mutateAsync({ method: 'PATCH', endpoint: endpoint, body: debounced });
|
||||||
setUpdate({});
|
setUpdate(undefined);
|
||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
@@ -322,5 +322,4 @@ const PersonalizationSettings = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default PersonalizationSettings;
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ function DebouncedSearchProvider({
|
|||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
|
|
||||||
const [provider, setProvider] = useState<Provider>(searchProvider);
|
const [provider, setProvider] = useState<Provider>(searchProvider);
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<Provider>();
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
@@ -39,13 +39,13 @@ function DebouncedSearchProvider({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (debounced && Object.keys(debounced).length) {
|
||||||
mutateAsync({ method: 'PATCH', endpoint: 'api/providers', body: debounced });
|
mutateAsync({ method: 'PATCH', endpoint: 'api/providers', body: debounced });
|
||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (update !== provider && Object.keys(update).length) {
|
if (update && update !== provider && Object.keys(update).length) {
|
||||||
setProvider(update);
|
setProvider(update);
|
||||||
}
|
}
|
||||||
}, [update]);
|
}, [update]);
|
||||||
@@ -56,6 +56,7 @@ function DebouncedSearchProvider({
|
|||||||
className={cardClasses.settingsItem}
|
className={cardClasses.settingsItem}
|
||||||
classNames={cardClasses}
|
classNames={cardClasses}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -72,6 +73,7 @@ function DebouncedSearchProvider({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import { Group, Stack, Text } from '@mantine/core';
|
import { Group, Stack, Text } from '@mantine/core';
|
||||||
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
||||||
import { DataTable, DeleteItemModal, SettingsHeader } from 'components';
|
import {
|
||||||
import { SearchHistoryColumns } from 'components/Columns/SearchHistoryColumns';
|
DataTable,
|
||||||
|
DeleteItemModal,
|
||||||
|
SearchHistoryColumns,
|
||||||
|
SettingsHeader,
|
||||||
|
} from 'components';
|
||||||
import { useCommonHooks, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { SearchHistoryItem } from 'types';
|
import type { SearchHistoryItem } from 'types';
|
||||||
|
|
||||||
const SearchHistory = () => {
|
export function SearchHistory() {
|
||||||
const searchEndpoint = 'api/searchHistory';
|
const searchEndpoint = 'api/searchHistory';
|
||||||
const { data: historyData, isFetching: historyDataIsFetching } = useQueryAPI({
|
const { data: historyData, isFetching: historyDataIsFetching } = useQueryAPI({
|
||||||
endpoint: searchEndpoint,
|
endpoint: searchEndpoint,
|
||||||
@@ -41,6 +45,7 @@ const SearchHistory = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack w={'100%'}>
|
<Stack w={'100%'}>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -63,6 +68,7 @@ const SearchHistory = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
setDragging={undefined}
|
setDragging={undefined}
|
||||||
openModal={undefined}
|
openModal={undefined}
|
||||||
@@ -107,6 +113,4 @@ const SearchHistory = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default SearchHistory;
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import type { Provider } from 'types';
|
|||||||
import DebouncedSearchProvider from './DebouncedSearchProvider';
|
import DebouncedSearchProvider from './DebouncedSearchProvider';
|
||||||
import SearchProviderSettingsItem from './SearchProviderSettingsItem';
|
import SearchProviderSettingsItem from './SearchProviderSettingsItem';
|
||||||
|
|
||||||
const SearchProviderSettings = () => {
|
export function SearchProviders() {
|
||||||
const allIcons: any = { ...fa6, ...vsc, ...si };
|
const allIcons: any = { ...fa6, ...vsc, ...si };
|
||||||
const defaultProvider: Provider = {
|
const defaultProvider: Provider = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
@@ -88,6 +88,7 @@ const SearchProviderSettings = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
{modalOpened && (
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -117,7 +118,9 @@ const SearchProviderSettings = () => {
|
|||||||
styles={
|
styles={
|
||||||
theme.textShadowsEnabled
|
theme.textShadowsEnabled
|
||||||
? {
|
? {
|
||||||
label: { boxShadow: '2px 2px var(--mantine-color-border-0)' },
|
label: {
|
||||||
|
boxShadow: '2px 2px var(--mantine-color-border-0)',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
@@ -134,7 +137,9 @@ const SearchProviderSettings = () => {
|
|||||||
styles={
|
styles={
|
||||||
theme.textShadowsEnabled
|
theme.textShadowsEnabled
|
||||||
? {
|
? {
|
||||||
label: { boxShadow: '2px 2px var(--mantine-color-border-0)' },
|
label: {
|
||||||
|
boxShadow: '2px 2px var(--mantine-color-border-0)',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
@@ -166,11 +171,15 @@ const SearchProviderSettings = () => {
|
|||||||
styles={
|
styles={
|
||||||
theme.textShadowsEnabled
|
theme.textShadowsEnabled
|
||||||
? {
|
? {
|
||||||
label: { boxShadow: '2px 2px var(--mantine-color-border-0)' },
|
label: {
|
||||||
|
boxShadow: '2px 2px var(--mantine-color-border-0)',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
renderOption={(item: ComboboxLikeRenderOptionInput<ComboboxItem>) => {
|
renderOption={(
|
||||||
|
item: ComboboxLikeRenderOptionInput<ComboboxItem>,
|
||||||
|
) => {
|
||||||
const Icon = allIcons[item.option.value];
|
const Icon = allIcons[item.option.value];
|
||||||
return (
|
return (
|
||||||
<Group>
|
<Group>
|
||||||
@@ -256,6 +265,7 @@ const SearchProviderSettings = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
setDragging={undefined}
|
setDragging={undefined}
|
||||||
openModal={openModal}
|
openModal={openModal}
|
||||||
@@ -333,5 +343,4 @@ const SearchProviderSettings = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default SearchProviderSettings;
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export function ThemePlaylists() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
{opened && (
|
||||||
<ThemePlaylistModal
|
<ThemePlaylistModal
|
||||||
opened={opened}
|
opened={opened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -77,6 +78,7 @@ export function ThemePlaylists() {
|
|||||||
allThemes={allThemeData}
|
allThemes={allThemeData}
|
||||||
createPlaylist={mutateAsync}
|
createPlaylist={mutateAsync}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
setDragging={undefined}
|
setDragging={undefined}
|
||||||
openModal={open}
|
openModal={open}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ export function ThemePlaylistCard({
|
|||||||
onMouseEnter={() => setHover(true)}
|
onMouseEnter={() => setHover(true)}
|
||||||
onMouseLeave={() => setHover(false)}
|
onMouseLeave={() => setHover(false)}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={closeModal}
|
handleClose={closeModal}
|
||||||
@@ -58,6 +59,7 @@ export function ThemePlaylistCard({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ export function ThemePlaylistModal({
|
|||||||
}) {
|
}) {
|
||||||
const { isMobile } = useCommonHooks();
|
const { isMobile } = useCommonHooks();
|
||||||
const [themeList, setThemeList] = useState<any>([]);
|
const [themeList, setThemeList] = useState<any>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedPlaylist?.themeList) {
|
if (selectedPlaylist?.themeList) {
|
||||||
setThemeList(JSON.parse(selectedPlaylist?.themeList));
|
setThemeList(JSON.parse(selectedPlaylist?.themeList));
|
||||||
@@ -49,7 +48,7 @@ export function ThemePlaylistModal({
|
|||||||
centered
|
centered
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
handleClose();
|
handleClose();
|
||||||
setThemeList('[]');
|
setThemeList([]);
|
||||||
}}
|
}}
|
||||||
keepMounted={false}
|
keepMounted={false}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { ActionIcon, Group, isLightColor, Stack, Text } from '@mantine/core';
|
import { ActionIcon, Group, isLightColor, Stack, Text } from '@mantine/core';
|
||||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { FaTrashAlt } from 'react-icons/fa';
|
import { FaPencil, FaTrash } from 'react-icons/fa6';
|
||||||
import { FaPencil } from 'react-icons/fa6';
|
|
||||||
import { FiEdit, FiPower, FiShuffle } from 'react-icons/fi';
|
import { FiEdit, FiPower, FiShuffle } from 'react-icons/fi';
|
||||||
import { actionIconClasses } from 'styles';
|
import { actionIconClasses } from 'styles';
|
||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
@@ -238,7 +237,7 @@ export function ThemeManagementPill({
|
|||||||
onClick={openModal}
|
onClick={openModal}
|
||||||
disabled={cardTheme.name === theme.name}
|
disabled={cardTheme.name === theme.name}
|
||||||
>
|
>
|
||||||
<FaTrashAlt
|
<FaTrash
|
||||||
style={{ padding: '.25rem', filter: 'brightness(1.25)' }}
|
style={{ padding: '.25rem', filter: 'brightness(1.25)' }}
|
||||||
color='Brown'
|
color='Brown'
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function NewThemeStarter({
|
|||||||
setSelectedTheme: (selectedTheme: Theme) => void;
|
setSelectedTheme: (selectedTheme: Theme) => void;
|
||||||
setDefaultTheme: (selectedTheme: Theme) => void;
|
setDefaultTheme: (selectedTheme: Theme) => void;
|
||||||
}) {
|
}) {
|
||||||
const [pressed, setPressed] = useState<any>(false);
|
const [pressed, setPressed] = useState<boolean>(false);
|
||||||
const handlers = useLongPress(() => {
|
const handlers = useLongPress(() => {
|
||||||
setPressed(true);
|
setPressed(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import {
|
|||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { notifications } from '@mantine/notifications';
|
import { notifications } from '@mantine/notifications';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { FaClipboard } from 'react-icons/fa';
|
import { FaClipboard, FaX } from 'react-icons/fa6';
|
||||||
import { FiX } from 'react-icons/fi';
|
|
||||||
import { scrollAreaClasses, toolTipClasses } from 'styles';
|
import { scrollAreaClasses, toolTipClasses } from 'styles';
|
||||||
import { type Theme, ThemeProperties } from 'types';
|
import { type Theme, ThemeProperties } from 'types';
|
||||||
|
|
||||||
@@ -104,7 +103,7 @@ export default function ThemeChanges({
|
|||||||
pos={'absolute'}
|
pos={'absolute'}
|
||||||
right={0}
|
right={0}
|
||||||
>
|
>
|
||||||
<FiX />
|
<FaX />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import { Box, Stack, Text } from '@mantine/core';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { FiCheck } from 'react-icons/fi';
|
|
||||||
import { boxClasses, textClasses } from 'styles';
|
|
||||||
import type { Theme } from 'types';
|
|
||||||
|
|
||||||
export function ThemeExampleApp({ selectedTheme }: { selectedTheme: Theme }) {
|
|
||||||
const [textDecoration, setTextDecoration] = useState<string>('none');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
component='a'
|
|
||||||
onMouseOver={() => setTextDecoration('underline')}
|
|
||||||
onMouseOut={() => setTextDecoration('none')}
|
|
||||||
className={boxClasses.appItemBox}
|
|
||||||
h={'64px'}
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
style={{
|
|
||||||
marginRight: '1rem',
|
|
||||||
marginLeft: '1rem',
|
|
||||||
}}
|
|
||||||
justify='center'
|
|
||||||
>
|
|
||||||
<FiCheck style={{ color: selectedTheme?.primaryColor }} />
|
|
||||||
</Stack>
|
|
||||||
<Stack
|
|
||||||
style={{
|
|
||||||
justifyContent: 'center',
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
gap: 0,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
c={selectedTheme?.primaryColor}
|
|
||||||
className={textClasses.appName}
|
|
||||||
classNames={textClasses}
|
|
||||||
>
|
|
||||||
{'Example App'}
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
c={selectedTheme?.accentColor}
|
|
||||||
className={textClasses.appUrl}
|
|
||||||
classNames={textClasses}
|
|
||||||
style={{
|
|
||||||
textDecoration: textDecoration,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{'https://www.example.com'}
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -11,9 +11,7 @@ import {
|
|||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import FontPicker from 'react-fontpicker-ts';
|
import FontPicker from 'react-fontpicker-ts';
|
||||||
import { FaFont, FaGoogle } from 'react-icons/fa';
|
import { FaFont, FaGoogle, FaShuffle, FaX } from 'react-icons/fa6';
|
||||||
import { FaShuffle } from 'react-icons/fa6';
|
|
||||||
import { FiX } from 'react-icons/fi';
|
|
||||||
import { textClasses, toolTipClasses } from 'styles';
|
import { textClasses, toolTipClasses } from 'styles';
|
||||||
import type { Theme } from 'types';
|
import type { Theme } from 'types';
|
||||||
import ThemeChanges from './ThemeChanges';
|
import ThemeChanges from './ThemeChanges';
|
||||||
@@ -192,7 +190,7 @@ export default function ThemeOptions({
|
|||||||
borderRadius: '0px',
|
borderRadius: '0px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FiX />
|
<FaX />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export function ThemePreviewMiddleware({
|
|||||||
selectedPlaylist: any;
|
selectedPlaylist: any;
|
||||||
setSelectedPlaylist: (selectedPlaylist: any) => void;
|
setSelectedPlaylist: (selectedPlaylist: any) => void;
|
||||||
}) {
|
}) {
|
||||||
const [pressed, setPressed] = useState<any>(false);
|
const [pressed, setPressed] = useState<boolean>(false);
|
||||||
const handlers = useLongPress(() => {
|
const handlers = useLongPress(() => {
|
||||||
setPressed(true);
|
setPressed(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
|||||||
import { DeleteItemModal } from 'components';
|
import { DeleteItemModal } from 'components';
|
||||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FiTrash } from 'react-icons/fi';
|
import { FaTrash } from 'react-icons/fa';
|
||||||
import { cardClasses, textClasses, textInputClasses, toolTipClasses } from 'styles';
|
import { cardClasses, textClasses, textInputClasses, toolTipClasses } from 'styles';
|
||||||
import type { WolClient } from 'types';
|
import type { WolClient } from 'types';
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ function DebouncedWolClient({
|
|||||||
const { mutateAsync } = useMutationAPI();
|
const { mutateAsync } = useMutationAPI();
|
||||||
|
|
||||||
const [client, setClient] = useState<WolClient>(wolClient);
|
const [client, setClient] = useState<WolClient>(wolClient);
|
||||||
const [update, setUpdate] = useState<any>({});
|
const [update, setUpdate] = useState<WolClient>();
|
||||||
const [debounced] = useDebouncedValue(update, 1000);
|
const [debounced] = useDebouncedValue(update, 1000);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
@@ -27,13 +27,13 @@ function DebouncedWolClient({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(debounced).length) {
|
if (debounced && Object.keys(debounced).length) {
|
||||||
mutateAsync({ method: 'PATCH', endpoint: 'api/WolClients', body: debounced });
|
mutateAsync({ method: 'PATCH', endpoint: 'api/WolClients', body: debounced });
|
||||||
}
|
}
|
||||||
}, [debounced]);
|
}, [debounced]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (update !== client && Object.keys(update).length) {
|
if (update && update !== client && Object.keys(update).length) {
|
||||||
setClient(update);
|
setClient(update);
|
||||||
}
|
}
|
||||||
}, [update]);
|
}, [update]);
|
||||||
@@ -44,6 +44,7 @@ function DebouncedWolClient({
|
|||||||
className={cardClasses.settingsItem}
|
className={cardClasses.settingsItem}
|
||||||
classNames={cardClasses}
|
classNames={cardClasses}
|
||||||
>
|
>
|
||||||
|
{modalOpened && (
|
||||||
<DeleteItemModal
|
<DeleteItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -60,6 +61,7 @@ function DebouncedWolClient({
|
|||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
className={toolTipClasses.default}
|
className={toolTipClasses.default}
|
||||||
classNames={toolTipClasses}
|
classNames={toolTipClasses}
|
||||||
@@ -73,7 +75,7 @@ function DebouncedWolClient({
|
|||||||
openModal();
|
openModal();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FiTrash color='black' />
|
<FaTrash color='black' />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Group w={'100%'} justify='center'>
|
<Group w={'100%'} justify='center'>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import type { WolClient } from 'types';
|
|||||||
import DebouncedWolClient from './DebouncedWolClient';
|
import DebouncedWolClient from './DebouncedWolClient';
|
||||||
import WolClientSettingsItem from './WolClientSettingsItem';
|
import WolClientSettingsItem from './WolClientSettingsItem';
|
||||||
|
|
||||||
const WolClientSettings = () => {
|
export function WolClients() {
|
||||||
const defaultWolClient: WolClient = {
|
const defaultWolClient: WolClient = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
hostname: '',
|
hostname: '',
|
||||||
@@ -65,6 +65,7 @@ const WolClientSettings = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
{modalOpened && (
|
||||||
<AddItemModal
|
<AddItemModal
|
||||||
modalOpened={modalOpened}
|
modalOpened={modalOpened}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
@@ -135,6 +136,7 @@ const WolClientSettings = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<SettingsHeader
|
<SettingsHeader
|
||||||
setDragging={undefined}
|
setDragging={undefined}
|
||||||
openModal={openModal}
|
openModal={openModal}
|
||||||
@@ -204,5 +206,4 @@ const WolClientSettings = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
export default WolClientSettings;
|
|
||||||
|
|||||||
10
src/pages/settings/components/index.ts
Normal file
10
src/pages/settings/components/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export { Applications } from './Applications/Applications';
|
||||||
|
export { Bookmarks } from './Bookmarks/Bookmarks';
|
||||||
|
export { GuacamoleClients } from './GuacamoleClients/GuacamoleClients';
|
||||||
|
export { Messages } from './Messages/Messages';
|
||||||
|
export { Personalization } from './Personalization/Personalization';
|
||||||
|
export { SearchHistory } from './Search/SearchHistory';
|
||||||
|
export { SearchProviders } from './Search/SearchProviders';
|
||||||
|
export { ThemePlaylists } from './Theming/ThemePlaylists';
|
||||||
|
export { Themes } from './Theming/Themes';
|
||||||
|
export { WolClients } from './WoL/WolClients';
|
||||||
Reference in New Issue
Block a user