Type fixes
This commit is contained in:
@@ -139,8 +139,6 @@ export function useMutationAPI() {
|
||||
queryClient.refetchQueries({ queryKey: ['GET', 'api/providers/default'] });
|
||||
endpoint === 'api/personalData' &&
|
||||
queryClient.refetchQueries({ queryKey: ['GET', 'api/personalData'] });
|
||||
queryClient.refetchQueries({ queryKey: ['GET', 'api/wolEnabled'] });
|
||||
queryClient.refetchQueries({ queryKey: ['GET', 'api/guacamoleEnabled'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ function Applications({ contentType }: { contentType: string[] }) {
|
||||
endpoint: 'api/enabledApplications',
|
||||
});
|
||||
const { appSort, appDensity, appScale, theme, textShadowStyle } = useCommonHooks();
|
||||
const applications = applicationData
|
||||
const applications: Application[] = applicationData
|
||||
?.sort((a: Application, b: Application) => {
|
||||
switch (appSort) {
|
||||
case 'A>Z':
|
||||
|
||||
@@ -13,12 +13,12 @@ function Bookmarks({ contentType }: { contentType: string[] }) {
|
||||
});
|
||||
const { bookmarkSort, bookmarkDensity, bookmarkScale, theme, textShadowStyle } =
|
||||
useCommonHooks();
|
||||
const groupList = groupData?.map((category: BookmarkGroup) => {
|
||||
const groupList: BookmarkGroup[] = groupData?.map((category: BookmarkGroup) => {
|
||||
return category;
|
||||
});
|
||||
const bookmarks = bookmarkData || [];
|
||||
const groups = groupList
|
||||
?.sort((a: BookmarkGroup, b: BookmarkGroup) => {
|
||||
const bookmarks: Bookmark[] = bookmarkData || [];
|
||||
const groups: BookmarkGroup[] = groupList
|
||||
?.toSorted((a: BookmarkGroup, b: BookmarkGroup) => {
|
||||
switch (bookmarkSort) {
|
||||
case 'A>Z':
|
||||
return a.categoryName.toLocaleLowerCase() > b.categoryName.toLocaleLowerCase()
|
||||
|
||||
@@ -28,7 +28,7 @@ import type {
|
||||
import RecommendedApplications from './components/RecommendedApplications';
|
||||
import RecommendedBookmarks from './components/RecommendedBookmarks';
|
||||
import RecommendedClients from './components/RecommendedClients';
|
||||
import SearchSelectItem from './components/SearchSelectItem';
|
||||
import RenderItem from './components/RenderItem';
|
||||
|
||||
export default function Search({
|
||||
current,
|
||||
@@ -47,9 +47,6 @@ export default function Search({
|
||||
position: string;
|
||||
personal: PersonalData;
|
||||
}) {
|
||||
const { ref, height } = useElementSize();
|
||||
const allIcons: any = { ...fa6, ...vsc, ...si };
|
||||
const searchEndpoint = 'api/searchHistory';
|
||||
const {
|
||||
isMobile,
|
||||
urlPattern,
|
||||
@@ -72,6 +69,12 @@ export default function Search({
|
||||
defaultProviderIcon,
|
||||
setDefaultProviderIcon,
|
||||
} = useCommonHooks();
|
||||
const { ref, height } = useElementSize();
|
||||
const { mutateAsync } = useMutationAPI();
|
||||
const allIcons: any = { ...fa6, ...vsc, ...si };
|
||||
const Icon = allIcons[providerIcon];
|
||||
const searchEndpoint = 'api/searchHistory';
|
||||
|
||||
const { data: applicationData } = useQueryAPI({
|
||||
endpoint: 'api/enabledApplications',
|
||||
});
|
||||
@@ -94,8 +97,14 @@ export default function Search({
|
||||
const { data: historyData, isFetched: historyDataIsFetched } = useQueryAPI({
|
||||
endpoint: searchEndpoint,
|
||||
});
|
||||
|
||||
const applications: Application[] = applicationData || [];
|
||||
const filteredApplications = applications?.filter((app: Application) =>
|
||||
const providers: Provider[] = providerData || [];
|
||||
const guacamoleHost: string = guacamoleHostData?.[0]?.guacamoleHost;
|
||||
const guacamoleClients: GuacamoleClient[] = guacamoleClientData || [];
|
||||
const searchHistory: SearchHistoryItem[] = historyData || [];
|
||||
|
||||
const filteredApplications: Application[] = applications?.filter((app: Application) =>
|
||||
app.name.toLowerCase().includes((searchValue as string).substring(1).toLowerCase()),
|
||||
);
|
||||
const bookmarks: Bookmark[] =
|
||||
@@ -114,26 +123,23 @@ export default function Search({
|
||||
bookmark.enabled === 1 &&
|
||||
bookmark.name.toLowerCase().includes((searchValue as string).toLowerCase()),
|
||||
) || [];
|
||||
const providers = providerData || [];
|
||||
const guacamoleHost = guacamoleHostData?.[0]?.guacamoleHost;
|
||||
const guacamoleClients = guacamoleClientData || [];
|
||||
const filteredGuacamoleClients =
|
||||
|
||||
const filteredGuacamoleClients: GuacamoleClient[] =
|
||||
guacamoleClients.filter((client: GuacamoleClient) =>
|
||||
client.clientName
|
||||
.toLowerCase()
|
||||
.includes((searchValue as string).substring(1).toLowerCase()),
|
||||
) || [];
|
||||
const searchHistory = historyData || [];
|
||||
|
||||
const [filteredHistory, setFilteredHistory] = useState<SearchHistoryItem[]>([]);
|
||||
const { mutateAsync } = useMutationAPI();
|
||||
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
|
||||
useDisclosure(false);
|
||||
const [dropdownOpened, { open: openDropdown, close: closeDropdown }] = useDisclosure();
|
||||
const [listIndex, setListIndex] = useState(-1);
|
||||
const [placeholderValue, setPlaceholderValue] = useState<string>('');
|
||||
const [listIndex, setListIndex] = useState(-1);
|
||||
const [value, setValue] = useState(0);
|
||||
const [historyMultiplier, setHistoryMultiplier] = useState(1);
|
||||
const Icon = allIcons[providerIcon];
|
||||
|
||||
const [dropdownOpened, { open: openDropdown, close: closeDropdown }] = useDisclosure();
|
||||
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
|
||||
useDisclosure(false);
|
||||
|
||||
const handleResetSearch = () => {
|
||||
setSearchValue('');
|
||||
@@ -143,21 +149,6 @@ export default function Search({
|
||||
setProviderURL(defaultProviderURL);
|
||||
};
|
||||
|
||||
const handleSearchHistoryItem = ({ option }: { option: SearchHistoryItem }) => {
|
||||
const url =
|
||||
providerData.find((provider: Provider) => provider.prefix === option.prefix)?.url ??
|
||||
defaultProviderURL;
|
||||
open(`${url}${option.searchTerm}`, '_self');
|
||||
};
|
||||
|
||||
const handleAppLaunchItem = ({ option }: { option: any }) => {
|
||||
const validUrl =
|
||||
option.url.startsWith('http://') || option.url.startsWith('https://')
|
||||
? option.url
|
||||
: `http://${option.url}`;
|
||||
open(validUrl, '_self');
|
||||
};
|
||||
|
||||
const handleGuacamoleClientLaunchItem = ({ option }: { option: any }) => {
|
||||
const validUrl = `${guacamoleHost}/#/client/${option.clientIdentifier}`;
|
||||
open(validUrl, '_self');
|
||||
@@ -324,7 +315,7 @@ export default function Search({
|
||||
setProviderPrefix('/g');
|
||||
setProviderIcon('FaGoogle');
|
||||
} else if (item.target.value.startsWith('/')) {
|
||||
const provider = providers?.find(
|
||||
const provider: Provider | undefined = providers?.find(
|
||||
(p: Provider) => p.prefix === item.target.value.split(' ')[0],
|
||||
);
|
||||
setProviderLabel(provider?.name ?? 'Invalid Search');
|
||||
@@ -434,112 +425,6 @@ export default function Search({
|
||||
return historyOptions;
|
||||
};
|
||||
|
||||
const renderItem: any = (item: any) => {
|
||||
const Icon = item.option.prefix
|
||||
? allIcons[
|
||||
item.option.prefix === '/g'
|
||||
? 'FaGoogle'
|
||||
: (providers.find((p: Provider) => p.prefix === item.option.prefix)?.icon ??
|
||||
'')
|
||||
]
|
||||
: item.option.icon
|
||||
? allIcons[item.option.icon]
|
||||
: item.option.type && item.option.type === 'SSH'
|
||||
? allIcons.FaTerminal
|
||||
: item.option.type === 'RDP'
|
||||
? allIcons.FaComputer
|
||||
: allIcons.FaDesktop;
|
||||
return (searchValue as string).startsWith('!') ? (
|
||||
<Group
|
||||
pos={'relative'}
|
||||
m={0}
|
||||
p={0}
|
||||
gap={0}
|
||||
justify='center'
|
||||
w={'100%'}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleAppLaunchItem(item);
|
||||
}}
|
||||
>
|
||||
<Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
Launch
|
||||
</Text>
|
||||
{Icon && (
|
||||
<Icon
|
||||
style={{
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
height: '2rem',
|
||||
width: '2rem',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Text pos={'absolute'} right={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
{item.option.name}
|
||||
</Text>
|
||||
</Group>
|
||||
) : (searchValue as string).startsWith('>') && personal.enableGuacamole === 1 ? (
|
||||
<Group
|
||||
pos={'relative'}
|
||||
m={0}
|
||||
p={0}
|
||||
gap={0}
|
||||
justify='center'
|
||||
w={'100%'}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleGuacamoleClientLaunchItem(item);
|
||||
}}
|
||||
>
|
||||
<Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
Connect to
|
||||
</Text>
|
||||
<Icon
|
||||
style={{
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
height: '2rem',
|
||||
width: '2rem',
|
||||
}}
|
||||
/>
|
||||
<Text pos={'absolute'} right={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
{item.option.name || item.option.clientName || 'Invalid connection'}
|
||||
</Text>
|
||||
</Group>
|
||||
) : item.option.value === 'load' ? (
|
||||
<Group
|
||||
pos={'relative'}
|
||||
m={0}
|
||||
p={0}
|
||||
gap={0}
|
||||
w={'100%'}
|
||||
h={'2rem'}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setHistoryMultiplier((prev: number) => prev + 1);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
w={'100%'}
|
||||
c={'var(--mantine-color-accent-0)'}
|
||||
style={{ textAlign: 'center' }}
|
||||
>
|
||||
{item.option.label}
|
||||
</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<SearchSelectItem
|
||||
item={item}
|
||||
handleSearchHistoryItem={handleSearchHistoryItem}
|
||||
searchEndpoint={searchEndpoint}
|
||||
setSearchValue={setSearchValue}
|
||||
Icon={Icon}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (historyData && historyDataIsFetched) {
|
||||
if (filteredHistory.length === 0) {
|
||||
@@ -580,6 +465,7 @@ export default function Search({
|
||||
setDefaultProviderIcon(defaultProviderData[0]?.icon ?? 'FaGoogle');
|
||||
}
|
||||
}, [defaultProviderData, defaultProviderDataIsFetched]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{dropdownOpened && <Overlay blur={5} onClick={closeDropdown} fixed zIndex={200} />}
|
||||
@@ -647,7 +533,19 @@ export default function Search({
|
||||
bg: 'transparent',
|
||||
}}
|
||||
scrollAreaProps={{ viewportRef: ref }}
|
||||
renderOption={(item: any) => renderItem(item)}
|
||||
renderOption={(item: any) => (
|
||||
<RenderItem
|
||||
item={item}
|
||||
allIcons={allIcons}
|
||||
providers={providers}
|
||||
searchValue={searchValue}
|
||||
setSearchValue={setSearchValue}
|
||||
personal={personal}
|
||||
handleGuacamoleClientLaunchItem={handleGuacamoleClientLaunchItem}
|
||||
setHistoryMultiplier={setHistoryMultiplier}
|
||||
searchEndpoint={searchEndpoint}
|
||||
/>
|
||||
)}
|
||||
onFocus={() => {
|
||||
if (searchValue !== '') {
|
||||
openDropdown();
|
||||
@@ -703,17 +601,22 @@ export default function Search({
|
||||
</Text>
|
||||
<Group align='start' justify='space-between'>
|
||||
<Stack w={'49%'} gap={8}>
|
||||
{bookmarks.length > 0 && (
|
||||
<RecommendedBookmarks
|
||||
bookmarks={bookmarks}
|
||||
searchValue={searchValue}
|
||||
dropdownOpened={dropdownOpened}
|
||||
/>
|
||||
)}
|
||||
{personal.enableGuacamole === 1 &&
|
||||
filteredGuacamoleClients.length > 0 && (
|
||||
<RecommendedClients
|
||||
filteredGuacamoleClients={filteredGuacamoleClients}
|
||||
searchValue={searchValue}
|
||||
dropdownOpened={dropdownOpened}
|
||||
handleGuacamoleClientLaunchItem={handleGuacamoleClientLaunchItem}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
<RecommendedApplications
|
||||
searchValue={searchValue}
|
||||
|
||||
144
src/pages/homepage/components/Search/components/RenderItem.tsx
Normal file
144
src/pages/homepage/components/Search/components/RenderItem.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
import { Group, Text } from '@mantine/core';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import type { PersonalData, Provider, SearchHistoryItem } from 'types';
|
||||
import SearchSelectItem from './SearchSelectItem';
|
||||
|
||||
export default function RenderItem({
|
||||
item,
|
||||
allIcons,
|
||||
providers,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
personal,
|
||||
handleGuacamoleClientLaunchItem,
|
||||
setHistoryMultiplier,
|
||||
searchEndpoint,
|
||||
}: {
|
||||
item: any;
|
||||
allIcons: any;
|
||||
providers: Provider[];
|
||||
searchValue: string | number;
|
||||
setSearchValue: React.Dispatch<React.SetStateAction<string | number>>;
|
||||
personal: PersonalData;
|
||||
handleGuacamoleClientLaunchItem: ({ option }: { option: any }) => void;
|
||||
setHistoryMultiplier: React.Dispatch<React.SetStateAction<number>>;
|
||||
searchEndpoint: string;
|
||||
}) {
|
||||
const { defaultProviderURL } = useCommonHooks();
|
||||
const handleSearchHistoryItem = ({ option }: { option: SearchHistoryItem }) => {
|
||||
const url =
|
||||
providers.find((provider: Provider) => provider.prefix === option.prefix)?.url ??
|
||||
defaultProviderURL;
|
||||
open(`${url}${option.searchTerm}`, '_self');
|
||||
};
|
||||
|
||||
const handleAppLaunchItem = ({ option }: { option: any }) => {
|
||||
const validUrl =
|
||||
option.url.startsWith('http://') || option.url.startsWith('https://')
|
||||
? option.url
|
||||
: `http://${option.url}`;
|
||||
open(validUrl, '_self');
|
||||
};
|
||||
const Icon = item.option.prefix
|
||||
? allIcons[
|
||||
item.option.prefix === '/g'
|
||||
? 'FaGoogle'
|
||||
: (providers.find((p: Provider) => p.prefix === item.option.prefix)?.icon ?? '')
|
||||
]
|
||||
: item.option.icon
|
||||
? allIcons[item.option.icon]
|
||||
: item.option.type && item.option.type === 'SSH'
|
||||
? allIcons.FaTerminal
|
||||
: item.option.type === 'RDP'
|
||||
? allIcons.FaComputer
|
||||
: allIcons.FaDesktop;
|
||||
return (searchValue as string).startsWith('!') ? (
|
||||
<Group
|
||||
pos={'relative'}
|
||||
m={0}
|
||||
p={0}
|
||||
gap={0}
|
||||
justify='center'
|
||||
w={'100%'}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleAppLaunchItem(item);
|
||||
}}
|
||||
>
|
||||
<Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
Launch
|
||||
</Text>
|
||||
{Icon && (
|
||||
<Icon
|
||||
style={{
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
height: '2rem',
|
||||
width: '2rem',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Text pos={'absolute'} right={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
{item.option.name}
|
||||
</Text>
|
||||
</Group>
|
||||
) : (searchValue as string).startsWith('>') && personal.enableGuacamole === 1 ? (
|
||||
<Group
|
||||
pos={'relative'}
|
||||
m={0}
|
||||
p={0}
|
||||
gap={0}
|
||||
justify='center'
|
||||
w={'100%'}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleGuacamoleClientLaunchItem(item);
|
||||
}}
|
||||
>
|
||||
<Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
Connect to
|
||||
</Text>
|
||||
<Icon
|
||||
style={{
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
height: '2rem',
|
||||
width: '2rem',
|
||||
}}
|
||||
/>
|
||||
<Text pos={'absolute'} right={'1rem'} c={'var(--mantine-color-accent-0)'}>
|
||||
{item.option.name || item.option.clientName || 'Invalid connection'}
|
||||
</Text>
|
||||
</Group>
|
||||
) : item.option.value === 'load' ? (
|
||||
<Group
|
||||
pos={'relative'}
|
||||
m={0}
|
||||
p={0}
|
||||
gap={0}
|
||||
w={'100%'}
|
||||
h={'2rem'}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setHistoryMultiplier((prev: number) => prev + 1);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
w={'100%'}
|
||||
c={'var(--mantine-color-accent-0)'}
|
||||
style={{ textAlign: 'center' }}
|
||||
>
|
||||
{item.option.label}
|
||||
</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<SearchSelectItem
|
||||
item={item}
|
||||
handleSearchHistoryItem={handleSearchHistoryItem}
|
||||
searchEndpoint={searchEndpoint}
|
||||
setSearchValue={setSearchValue}
|
||||
Icon={Icon}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ function SettingsButton() {
|
||||
const { data: wolEnabledData, isFetched: wolEnabledDataIsFetched } = useQueryAPI({
|
||||
endpoint: 'api/wolEnabled',
|
||||
});
|
||||
const wolClients = wolClientData || [];
|
||||
const wolClients: WolClient[] = wolClientData || [];
|
||||
const [enabled, setEnabled] = useState<number>(0);
|
||||
const { mutateAsync } = useMutationAPI();
|
||||
const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]);
|
||||
|
||||
@@ -36,7 +36,7 @@ const BookmarkSettings = () => {
|
||||
const { data: bookmarkData, isFetching: bookmarkDataIsFetching } = useQueryAPI({
|
||||
endpoint: bookmarksEndpoint,
|
||||
});
|
||||
const bookmarks = bookmarkData || [];
|
||||
const bookmarks: Bookmark[] = bookmarkData || [];
|
||||
const categoriesEndpoint = 'api/bookmarkCategories';
|
||||
const { data: groupData, isFetched: groupsIsFetched } = useQueryAPI({
|
||||
endpoint: categoriesEndpoint,
|
||||
@@ -50,7 +50,7 @@ const BookmarkSettings = () => {
|
||||
const [debouncedGroupSearch] = useDebouncedValue(searchValue, 500);
|
||||
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const foundBookmarkGroups = [
|
||||
const foundBookmarkGroups: BookmarkGroup[] = [
|
||||
...new Set(
|
||||
bookmarks
|
||||
.filter(
|
||||
@@ -68,7 +68,7 @@ const BookmarkSettings = () => {
|
||||
),
|
||||
),
|
||||
];
|
||||
const foundGroups = groupData.filter((a: BookmarkGroup) =>
|
||||
const foundGroups: BookmarkGroup[] = groupData.filter((a: BookmarkGroup) =>
|
||||
a.categoryName.toLowerCase().includes((debouncedGroupSearch as string).toLowerCase()),
|
||||
);
|
||||
const handleClose = () => {
|
||||
|
||||
@@ -46,7 +46,7 @@ const GuacamoleClients = () => {
|
||||
useQueryAPI({
|
||||
endpoint: endpoint,
|
||||
});
|
||||
const guacamoleClients =
|
||||
const guacamoleClients: GuacamoleClient[] =
|
||||
guacamoleClientsData.filter(
|
||||
(a: GuacamoleClient) =>
|
||||
a.clientName.toLowerCase().includes((debouncedSearch as string).toLowerCase()) ||
|
||||
|
||||
@@ -33,7 +33,7 @@ const MessageSettings = () => {
|
||||
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
|
||||
const { isMobile, theme } = useCommonHooks();
|
||||
const { mutateAsync } = useMutationAPI();
|
||||
const messages =
|
||||
const messages: Message[] =
|
||||
messageData?.filter((m: Message) =>
|
||||
m.message.toLowerCase().includes((debouncedSearch as string).toLowerCase()),
|
||||
) || [];
|
||||
|
||||
@@ -36,12 +36,14 @@ import SearchProviderSettingsItem from './SearchProviderSettingsItem';
|
||||
|
||||
const SearchProviderSettings = () => {
|
||||
const allIcons: any = { ...fa6, ...vsc, ...si };
|
||||
const defaultProvider = {
|
||||
const defaultProvider: Provider = {
|
||||
id: undefined,
|
||||
name: '',
|
||||
url: '',
|
||||
prefix: '',
|
||||
default: 0,
|
||||
enabled: 1,
|
||||
icon: null,
|
||||
};
|
||||
const form = useForm({
|
||||
initialValues: defaultProvider,
|
||||
@@ -57,7 +59,7 @@ const SearchProviderSettings = () => {
|
||||
});
|
||||
const [searchValue, setSearchValue] = useState<string | number>('');
|
||||
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
|
||||
const providers =
|
||||
const providers: Provider[] =
|
||||
providerData
|
||||
.filter(
|
||||
(a: Provider) =>
|
||||
|
||||
Reference in New Issue
Block a user