Can launch guac clients from search bar

This commit is contained in:
Sean Edmunds
2025-12-29 12:04:33 -06:00
parent 64605a341c
commit c3cbf43647
3 changed files with 57 additions and 46 deletions

62
package-lock.json generated
View File

@@ -15,12 +15,12 @@
"@mantine/form": "^8.3.10", "@mantine/form": "^8.3.10",
"@mantine/hooks": "^8.3.10", "@mantine/hooks": "^8.3.10",
"@mantine/notifications": "^8.3.10", "@mantine/notifications": "^8.3.10",
"@tanstack/react-query": "^5.90.12", "@tanstack/react-query": "^5.90.15",
"@tanstack/react-query-devtools": "^5.91.1", "@tanstack/react-query-devtools": "^5.91.2",
"@tanstack/react-query-persist-client": "^5.90.14", "@tanstack/react-query-persist-client": "^5.90.17",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"idb-keyval": "^6.2.2", "idb-keyval": "^6.2.2",
"jotai": "^2.16.0", "jotai": "^2.16.1",
"react": "^19.2.3", "react": "^19.2.3",
"react-dom": "^19.2.3", "react-dom": "^19.2.3",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
@@ -1608,29 +1608,29 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tanstack/query-core": { "node_modules/@tanstack/query-core": {
"version": "5.90.12", "version": "5.90.15",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.12.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.15.tgz",
"integrity": "sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==", "integrity": "sha512-mInIZNUZftbERE+/Hbtswfse49uUQwch46p+27gP9DWJL927UjnaWEF2t3RMOqBcXbfMdcNkPe06VyUIAZTV1g==",
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/tannerlinsley" "url": "https://github.com/sponsors/tannerlinsley"
} }
}, },
"node_modules/@tanstack/query-devtools": { "node_modules/@tanstack/query-devtools": {
"version": "5.91.1", "version": "5.92.0",
"resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.91.1.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.92.0.tgz",
"integrity": "sha512-l8bxjk6BMsCaVQH6NzQEE/bEgFy1hAs5qbgXl0xhzezlaQbPk6Mgz9BqEg2vTLPOHD8N4k+w/gdgCbEzecGyNg==", "integrity": "sha512-N8D27KH1vEpVacvZgJL27xC6yPFUy0Zkezn5gnB3L3gRCxlDeSuiya7fKge8Y91uMTnC8aSxBQhcK6ocY7alpQ==",
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/tannerlinsley" "url": "https://github.com/sponsors/tannerlinsley"
} }
}, },
"node_modules/@tanstack/query-persist-client-core": { "node_modules/@tanstack/query-persist-client-core": {
"version": "5.91.11", "version": "5.91.14",
"resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.91.11.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.91.14.tgz",
"integrity": "sha512-NNpRGxQY/nVOdzfs5QbevPjGsUVoEiFwqxxaopLyu6todwtDOCfIOfhXSmpMVXBiCxUn7kqaUB1iwaBKqoAVRQ==", "integrity": "sha512-22vWKM2SXU29AUAzCv4pjKWx+mVam5QjPH+XZ1FQeH4DgO9HFPjWN8Bf9NVF2ki8eFGzTy+7FCBylEgV+LZgJw==",
"dependencies": { "dependencies": {
"@tanstack/query-core": "5.90.12" "@tanstack/query-core": "5.90.15"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@@ -1638,11 +1638,11 @@
} }
}, },
"node_modules/@tanstack/react-query": { "node_modules/@tanstack/react-query": {
"version": "5.90.12", "version": "5.90.15",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.12.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.15.tgz",
"integrity": "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==", "integrity": "sha512-uQvnDDcTOgJouNtAyrgRej+Azf0U5WDov3PXmHFUBc+t1INnAYhIlpZtCGNBLwCN41b43yO7dPNZu8xWkUFBwQ==",
"dependencies": { "dependencies": {
"@tanstack/query-core": "5.90.12" "@tanstack/query-core": "5.90.15"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@@ -1653,34 +1653,34 @@
} }
}, },
"node_modules/@tanstack/react-query-devtools": { "node_modules/@tanstack/react-query-devtools": {
"version": "5.91.1", "version": "5.91.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.91.1.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.91.2.tgz",
"integrity": "sha512-tRnJYwEbH0kAOuToy8Ew7bJw1lX3AjkkgSlf/vzb+NpnqmHPdWM+lA2DSdGQSLi1SU0PDRrrCI1vnZnci96CsQ==", "integrity": "sha512-ZJ1503ay5fFeEYFUdo7LMNFzZryi6B0Cacrgr2h1JRkvikK1khgIq6Nq2EcblqEdIlgB/r7XDW8f8DQ89RuUgg==",
"dependencies": { "dependencies": {
"@tanstack/query-devtools": "5.91.1" "@tanstack/query-devtools": "5.92.0"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/tannerlinsley" "url": "https://github.com/sponsors/tannerlinsley"
}, },
"peerDependencies": { "peerDependencies": {
"@tanstack/react-query": "^5.90.10", "@tanstack/react-query": "^5.90.14",
"react": "^18 || ^19" "react": "^18 || ^19"
} }
}, },
"node_modules/@tanstack/react-query-persist-client": { "node_modules/@tanstack/react-query-persist-client": {
"version": "5.90.14", "version": "5.90.17",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.90.14.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.90.17.tgz",
"integrity": "sha512-jTGnr/DBlzV/UYqU+b8bZWECBuqh3Q3g7Ih50IktZkvmwTUsidQhhl2JyknNYVZkl5AgMfPAywNKZLTI82wmlA==", "integrity": "sha512-iipmRT7CpW/Is/RKHXPDuWS0FP7RrmJL/KofNb0aKYMl5dH88R0PZ7N0PvJ44SZCwl44p4VG/4ugGDISutCgtQ==",
"dependencies": { "dependencies": {
"@tanstack/query-persist-client-core": "5.91.11" "@tanstack/query-persist-client-core": "5.91.14"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/tannerlinsley" "url": "https://github.com/sponsors/tannerlinsley"
}, },
"peerDependencies": { "peerDependencies": {
"@tanstack/react-query": "^5.90.12", "@tanstack/react-query": "^5.90.15",
"react": "^18 || ^19" "react": "^18 || ^19"
} }
}, },
@@ -2962,9 +2962,9 @@
"dev": true "dev": true
}, },
"node_modules/jotai": { "node_modules/jotai": {
"version": "2.16.0", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.16.0.tgz", "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.16.1.tgz",
"integrity": "sha512-NmkwPBet0SHQ28GBfEb10sqnbVOYyn6DL4iazZgGRDUKxSWL0iqcm+IK4TqTSFC2ixGk+XX2e46Wbv364a3cKg==", "integrity": "sha512-vrHcAbo3P7Br37C8Bv6JshMtlKMPqqmx0DDREtTjT4nf3QChDrYdbH+4ik/9V0cXA57dK28RkJ5dctYvavcIlg==",
"engines": { "engines": {
"node": ">=12.20.0" "node": ">=12.20.0"
}, },

View File

@@ -17,12 +17,12 @@
"@mantine/form": "^8.3.10", "@mantine/form": "^8.3.10",
"@mantine/hooks": "^8.3.10", "@mantine/hooks": "^8.3.10",
"@mantine/notifications": "^8.3.10", "@mantine/notifications": "^8.3.10",
"@tanstack/react-query": "^5.90.12", "@tanstack/react-query": "^5.90.15",
"@tanstack/react-query-devtools": "^5.91.1", "@tanstack/react-query-devtools": "^5.91.2",
"@tanstack/react-query-persist-client": "^5.90.14", "@tanstack/react-query-persist-client": "^5.90.17",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"idb-keyval": "^6.2.2", "idb-keyval": "^6.2.2",
"jotai": "^2.16.0", "jotai": "^2.16.1",
"react": "^19.2.3", "react": "^19.2.3",
"react-dom": "^19.2.3", "react-dom": "^19.2.3",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",

View File

@@ -27,6 +27,7 @@ import type {
import RecommendedApplications from './components/RecommendedApplications'; import RecommendedApplications from './components/RecommendedApplications';
import RecommendedBookmarks from './components/RecommendedBookmarks'; import RecommendedBookmarks from './components/RecommendedBookmarks';
import SearchSelectItem from './components/SearchSelectItem'; import SearchSelectItem from './components/SearchSelectItem';
import { FaComputer } from 'react-icons/fa6';
export default function Search({ export default function Search({
current, current,
@@ -128,6 +129,11 @@ export default function Search({
open(validUrl, '_self'); open(validUrl, '_self');
}; };
const handleGuacamoleClientLaunchItem = ({ option }: { option: any }) => {
const validUrl = `https://sean.bet/guacamole/#/client/${option.clientIdentifier}`;
open(validUrl, '_self');
};
const handleKeyPress = (item: any) => { const handleKeyPress = (item: any) => {
let option = ''; let option = '';
let subtext = ''; let subtext = '';
@@ -165,12 +171,11 @@ export default function Search({
: `http://${url}`; : `http://${url}`;
open(validUrl, '_self'); open(validUrl, '_self');
} else if (providerLabel.startsWith('Connect to')) { } else if (providerLabel.startsWith('Connect to')) {
const id = guacamoleClients.find( const client = guacamoleClients?.find(
(client: GuacamoleClient) => (client: GuacamoleClient) =>
client.clientName.substring(1).toLowerCase() === item.target.value.substr(1), client.clientName.toLowerCase() === item.target.value.toLowerCase().substr(1),
)?.id; );
open(`https://sean.bet/guacamole/#/client/${client?.clientIdentifier}`, '_self');
open(`https://sean.bet/guacamole/#/${id}`, '_self');
} else if (urlPattern.test(item.target.value)) { } else if (urlPattern.test(item.target.value)) {
if (/^(https?:\/\/).*/i.test(item.target.value)) if (/^(https?:\/\/).*/i.test(item.target.value))
globalThis.location = item.target.value; globalThis.location = item.target.value;
@@ -300,7 +305,7 @@ export default function Search({
if ( if (
guacamoleClients?.find( guacamoleClients?.find(
(client: GuacamoleClient) => (client: GuacamoleClient) =>
client.clientName.substring(1).toLowerCase() === item.target.value.substr(1), client.clientName.toLowerCase() === item.target.value.toLowerCase().substr(1),
) )
) { ) {
setProviderLabel(`Connect to ${item.target.value.substr(1)}`); setProviderLabel(`Connect to ${item.target.value.substr(1)}`);
@@ -375,17 +380,15 @@ export default function Search({
}; };
const renderItem: any = (item: any) => { const renderItem: any = (item: any) => {
const Icon = const Icon = item.option.icon ?
allIcons[ (allIcons[
item.option.icon item.option.icon
? item.option.icon ? item.option.icon
: item.option.prefix === '/g' : item.option.prefix === '/g'
? 'FaGoogle' ? 'FaGoogle'
: (providers.find((p: Provider) => p.prefix === item.option.prefix)?.icon ?? : (providers.find((p: Provider) => p.prefix === item.option.prefix)?.icon ??
'') '')
]; ]) : (allIcons['FaComputer']);
if ((searchValue as string).startsWith('>')) {
}
return (searchValue as string).startsWith('!') ? ( return (searchValue as string).startsWith('!') ? (
<Group <Group
pos={'relative'} pos={'relative'}
@@ -427,11 +430,19 @@ export default function Search({
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
handleGuacamoleClientLaunchItem(item);
}} }}
> >
<Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}> <Text pos={'absolute'} left={'1rem'} c={'var(--mantine-color-accent-0)'}>
Connect to Connect to
</Text> </Text>
<Icon
style={{
color: 'var(--mantine-color-primary-0)',
height: '2rem',
width: '2rem',
}}
/>
<Text pos={'absolute'} right={'1rem'} c={'var(--mantine-color-accent-0)'}> <Text pos={'absolute'} right={'1rem'} c={'var(--mantine-color-accent-0)'}>
{item.option.name || item.option.clientName || 'Invalid connection'} {item.option.name || item.option.clientName || 'Invalid connection'}
</Text> </Text>