Starting guac clients

This commit is contained in:
Sean Edmunds
2025-12-23 14:55:47 -06:00
parent 063a936cf7
commit 64605a341c
23 changed files with 853 additions and 480 deletions

View File

@@ -20,6 +20,7 @@ import type {
Bookmark,
CurrentWeather,
ExtendedForecast,
GuacamoleClient,
Provider,
SearchHistoryItem,
} from 'types';
@@ -48,9 +49,14 @@ export default function Search({
endpoint: 'api/providers',
});
const [providers, setProviders] = useState<Provider[]>([]);
const [guacamoleClients, setGuacamoleClients] = useState<GuacamoleClient[]>([]);
const { data: applicationData, isFetching: isApplicationDataFetching } = useQueryAPI({
endpoint: 'api/enabledApplications',
});
const { data: guacamoleClientData, isFetched: guacamoleClientDataIsFetched } =
useQueryAPI({
endpoint: 'api/guacamoleClients',
});
const { data: bookmarkData, isFetched: bookmarksIsFetched } = useQueryAPI({
endpoint: 'api/bookmarks',
});
@@ -130,10 +136,6 @@ export default function Search({
item.target.value.substr(1, item.target.value.indexOf(' ') - 1) ??
item.target.value.substr(1);
subtext = item.target.value.substr(2 + option.length);
} else if (item.target.value.startsWith('!')) {
if (item.target.value.startsWith('!w')) {
subtext = item.target.value.substr(2);
}
} else {
subtext = item.target.value;
}
@@ -162,6 +164,13 @@ export default function Search({
? url
: `http://${url}`;
open(validUrl, '_self');
} else if (providerLabel.startsWith('Connect to')) {
const id = guacamoleClients.find(
(client: GuacamoleClient) =>
client.clientName.substring(1).toLowerCase() === item.target.value.substr(1),
)?.id;
open(`https://sean.bet/guacamole/#/${id}`, '_self');
} else if (urlPattern.test(item.target.value)) {
if (/^(https?:\/\/).*/i.test(item.target.value))
globalThis.location = item.target.value;
@@ -250,7 +259,6 @@ export default function Search({
}
}
};
const onInput = (item: any) => {
openDropdown();
setSearchValue(item.currentTarget.value);
@@ -288,6 +296,17 @@ export default function Search({
} else {
setProviderLabel('Invalid function');
}
} else if (item.target.value.startsWith('>')) {
if (
guacamoleClients?.find(
(client: GuacamoleClient) =>
client.clientName.substring(1).toLowerCase() === item.target.value.substr(1),
)
) {
setProviderLabel(`Connect to ${item.target.value.substr(1)}`);
} else {
setProviderLabel('Invalid connection');
}
} else {
setProviderLabel(defaultProviderLabel);
setProviderURL(defaultProviderURL);
@@ -311,6 +330,21 @@ export default function Search({
};
});
}
if (splittedSearch[0].startsWith('>')) {
return guacamoleClientData
.filter((guacamoleClient: GuacamoleClient) =>
guacamoleClient.clientName
.toLowerCase()
.includes(splittedSearch[0].substring(1).toLowerCase()),
)
.map((guacamoleClient: GuacamoleClient) => {
return {
label: guacamoleClient.clientName,
value: guacamoleClient.clientIdentifier,
...guacamoleClient,
};
});
}
const historyOptions = options
.filter((option: any) => {
return splittedSearch.every((searchWord) =>
@@ -350,7 +384,9 @@ export default function Search({
: (providers.find((p: Provider) => p.prefix === item.option.prefix)?.icon ??
'')
];
return searchValue.startsWith('!') ? (
if ((searchValue as string).startsWith('>')) {
}
return (searchValue as string).startsWith('!') ? (
<Group
pos={'relative'}
m={0}
@@ -380,6 +416,26 @@ export default function Search({
{item.option.name}
</Text>
</Group>
) : (searchValue as string).startsWith('>') ? (
<Group
pos={'relative'}
m={0}
p={0}
gap={0}
justify='center'
w={'100%'}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}>
Connect to
</Text>
<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'}
@@ -419,6 +475,12 @@ export default function Search({
}
}, [providerData, providerDataIsFetched]);
useEffect(() => {
if (guacamoleClientData && guacamoleClientDataIsFetched) {
setGuacamoleClients(guacamoleClientData);
}
}, [guacamoleClientData, guacamoleClientDataIsFetched]);
useEffect(() => {
if (applicationData && !isApplicationDataFetching) {
setApplications(applicationData);
@@ -429,7 +491,7 @@ export default function Search({
if (applications) {
setFilteredApplications(
applications.filter((app: Application) =>
app.name.toLowerCase().includes(searchValue.toLowerCase()),
app.name.toLowerCase().includes((searchValue as string).toLowerCase()),
),
);
}
@@ -441,7 +503,7 @@ export default function Search({
bookmarkData.filter(
(bookmark: Bookmark) =>
bookmark.enabled === 1 &&
bookmark.name.toLowerCase().includes(searchValue.toLowerCase()),
bookmark.name.toLowerCase().includes((searchValue as string).toLowerCase()),
),
);
}
@@ -467,7 +529,7 @@ export default function Search({
}, [listIndex, dropdownOpened]);
useEffect(() => {
const splittedSearch = searchValue.toLowerCase().trim().split(' ');
const splittedSearch = (searchValue as string).toLowerCase().trim().split(' ');
const filtered = searchHistory.filter((item: SearchHistoryItem) => {
const option = `${item.prefix} ${item.searchTerm}`;
const words = option.toLowerCase().trim().split(' ');
@@ -514,8 +576,8 @@ export default function Search({
...item,
}))}
filter={optionsFilter}
value={searchValue}
searchValue={searchValue}
value={searchValue as string}
searchValue={searchValue as string}
placeholder={placeholderValue}
nothingFoundMessage={
<Text c={'var(--mantine-color-primary-0)'}>Nothing found...</Text>