Skip to content

Commit

Permalink
feat: add tabs and shortcut navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
invm committed Jul 2, 2023
1 parent 18add04 commit fc1470a
Show file tree
Hide file tree
Showing 20 changed files with 169 additions and 113 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" class="background h-full w-full"></div>
<div id="root" class="background-gradient h-full w-full"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
},
"license": "MIT",
"dependencies": {
"@solidjs/router": "^0.8.2",
"@tauri-apps/api": "^1.4.0",
"i18next": "^23.1.0",
"solid-form-handler": "^1.2.0",
"solid-js": "^1.7.7",
"split.js": "^1.6.5",
"zod": "^3.21.4"
},
"devDependencies": {
Expand Down
18 changes: 7 additions & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ path = "src/bin/main.rs"
tauri-build = { version = "1.4", features = [] }

[dependencies]
tauri = { version = "1.4", features = ["shell-open"] }
tauri = { version = "1.4", features = [ "global-shortcut-all", "shell-open"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rusqlite = { version = "0.29.0", features = ["bundled", "uuid"] }
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"shell": {
"all": false,
"open": true
},
"globalShortcut": {
"all": true
}
},
"bundle": {
Expand Down
79 changes: 42 additions & 37 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,52 @@
import './utils/i18n';
import Home from './pages/Home';
import { Route, Router, Routes } from "@solidjs/router"; // 👈 Import the router
import Connection from './pages/Connection';
import { StoreProvider } from './services/Context';
import { Alerts } from './components/Alerts';
import { createSignal, For } from 'solid-js';
import { createStore } from 'solid-js/store';
import { useAppSelector } from './services/Context';
import { Alerts } from './components/UI';
import { For, onMount } from 'solid-js';
import { register } from '@tauri-apps/api/globalShortcut';

function App() {
const [activeTab, setActiveTab] = createSignal(0);
const [tabs, setTabs] = createStore([
{ name: 'Home', component: Home },
{ name: 'Connection', component: Connection },
]);
const { tabsService: { tabsStore, setActiveTab, removeTab } } = useAppSelector()

onMount(async () => {
await register('CommandOrControl+1', () => { setActiveTab(1) });
});

const closeTab = async (id: string) => {
await removeTab(id)
setActiveTab(1)
}

return (
<StoreProvider>
<div class="w-full h-full">
<div class="p-2 tabs tabs-boxed rounded-none gap-2">
<For each={tabs}>
{(tab, i) =>
<a onClick={() => setActiveTab(i)} class="tab" classList={{
'tab-active': activeTab() === i(),
}}>{tab.name}</a>
}
</For>
</div>
<div class="bg-red-500">
<For each={tabs}>
{(tab, i) =>
<div classList={{
'hidden': activeTab() !== i(),
}}>
<h2 class="text">
{tab.name}
</h2>
</div>
}
</For>
</div>
<div class="w-full h-full flex flex-col">
<div class="px-2 bg-base-300 tabs tabs-boxed rounded-none gap-2">
<For each={tabsStore.tabs}>
{(tab, idx) =>
<div class="group flex items-center">
<div onClick={() => setActiveTab(idx() + 1)} class="tab tab-md "
classList={{ 'tab-active': tabsStore.activeTab === idx() + 1, }}
><span class="">{tab.label}</span> </div>
{idx() + 1 !== 1 && <button onClick={() => closeTab(tab.id!)} class="hidden group-hover:block pl-2 mb-1">
<svg class="w-2.5 h-2.5 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16">
<path d="m9.414 8 5.293-5.293a1 1 0 1 0-1.414-1.414L8 6.586 2.707 1.293a1 1 0 0 0-1.414 1.414L6.586 8l-5.293 5.293a1 1 0 1 0 1.414 1.414L8 9.414l5.293 5.293a1 1 0 0 0 1.414-1.414L9.414 8Z" />
</svg>
</button>}

</div>

}
</For>
</div>
<div class="h-full">
<For each={tabsStore.tabs}>
{(tab, idx) =>
<div class="h-full" classList={{ 'hidden': tabsStore.activeTab !== idx() + 1, }}>
{tab.component!()}
</div>
}
</For>
</div>
<Alerts />
</StoreProvider >
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { zodSchema } from 'solid-form-handler/zod';
import { t } from 'i18next';
import { Match, onMount, Show, Switch } from 'solid-js';

import { Alert, Button, TextInput, Select, ColorCircle } from './UI';
import { Alert, TextInput, Select, ColorCircle } from '../UI';
import {
PORTS_MAP, Schemes, AvailableConnectionModes, SocketPathDefaults,
connectionColors, ConnectionMode, connectionModes, schemes, HostCredentials, SocketCredentials, FileCredentials, ConnectionConfig, Scheme
} from '../interfaces';
import { titleCase } from '../utils/formatters';
import { FileInput } from './UI/FileInput';
import { omit } from '../utils/utils';
import { useAppSelector } from '../services/Context';
connectionColors, ConnectionMode, connectionModes, schemes, HostCredentials, SocketCredentials, FileCredentials, Scheme
} from '../../interfaces';
import { titleCase } from '../../utils/formatters';
import { FileInput } from './../UI/FileInput';
import { omit } from '../../utils/utils';
import { useAppSelector } from '../../services/Context';

const MIN_LENGTH_STR = 2;
const MAX_LENGTH_STR = 255;
Expand Down Expand Up @@ -229,7 +229,9 @@ const AddConnectionForm = (props: { addConnection: ({ name, scheme, color }: { n
</Show>
</div>
<div class="py-4">
<Button disabled={Object.keys(getFormErrors()).length} type="submit" >{t('components.add_connection_form.title')}</Button>
<button disabled={!!Object.keys(getFormErrors()).length} class="btn
btn-primary btn-md btn-block" type="submit"
>{t('components.add_connection_form.title')}</button>
</div>
</form >
</div >
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { t } from 'i18next';
import { ConnectionConfig } from '../../../../interfaces';
import { useAppSelector } from '../../../../services/Context';

export const ActionsMenu = (props: { connection: ConnectionConfig, deleteConnection: () => Promise<void> }) => {
const modal_id = `actions-menu-${props.connection.id}`
const { tabsService: { addTab } } = useAppSelector()


const onConnect = async () => {
await addTab({
id: props.connection.id,
label: props.connection.name,
connection: props.connection
})
}

export const ActionsMenu = (props: { id: string, deleteConnection: () => Promise<void> }) => {
const modal_id = `actions-menu-${props.id}`
return (
<div class="flex items-center">
<div class="dropdown dropdown-bottom dropdown-end">
Expand All @@ -16,7 +29,7 @@ export const ActionsMenu = (props: { id: string, deleteConnection: () => Promise
</button></li>
</ul>
</div>
<button class="btn btn-sm btn-ghost">
<button onClick={onConnect} class="btn btn-sm btn-ghost">
<svg class="w-4 h-4 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 16">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 8h11m0 0L8 4m4 4-4 4m4-11h3a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-3" />
</svg>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ConnectionConfig, ConnectionModeType, SchemeType } from '../../../interfaces';
import { firstKey } from '../../../utils/utils';
import { ColorCircle } from '../../UI';
import { ConnectionConfig, ConnectionModeType, SchemeType } from '../../../../interfaces';
import { firstKey } from '../../../../utils/utils';
import { ColorCircle } from '../../../UI';
import { ActionsMenu } from './ActionsMenu';

export const ConnectionItem = (props: { connection: ConnectionConfig, deleteConnection: (id: string) => Promise<void> }) => {
const scheme = firstKey(props.connection.scheme) as SchemeType;
const mode = firstKey(props.connection.scheme[scheme]) as ConnectionModeType;
const creds = props.connection.scheme[scheme][mode];
const mode = firstKey(props.connection.scheme[scheme]!) as ConnectionModeType;
const creds = props.connection.scheme[scheme]![mode];
const connectionString = mode === 'Host' ? creds.host : mode === 'File' ? creds.file : creds.sockets_path

const deleteConnection = async () => {
Expand All @@ -26,7 +26,7 @@ export const ConnectionItem = (props: { connection: ConnectionConfig, deleteConn
<p class="text text-sm dark:text-slate-500">{connectionString}</p>
</div>
<div class="hidden group-hover:block">
<ActionsMenu {...{ deleteConnection, id: props.connection.id! }} />
<ActionsMenu {...{ deleteConnection, connection: props.connection! }} />
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { invoke } from '@tauri-apps/api';
import { For } from 'solid-js';
import { SetStoreFunction } from 'solid-js/store';
import { ConnectionConfig } from '../../interfaces';
import { ConnectionConfig } from '../../../interfaces';
import { ConnectionItem } from './ConnectionItem/ConnectionItem';

export const ConnectionsList = (props: { connections: ConnectionConfig[], setConnections: SetStoreFunction<ConnectionConfig[]> }) => {
Expand All @@ -12,7 +12,7 @@ export const ConnectionsList = (props: { connections: ConnectionConfig[], setCon
}

return (
<div class="p-2 pt-5 bg-gray-900">
<div class="h-full p-2 pt-5 bg-gray-900">
<h3 class="text px-2 text-xl font-bold">Saved Connections</h3>
<div class="divider my-0"></div>
<ul class="grid grid-cols-1 gap-1">
Expand Down
2 changes: 1 addition & 1 deletion src/components/Alerts.tsx → src/components/UI/Alerts.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { For } from "solid-js"
import { useAppSelector } from "../services/Context"
import { useAppSelector } from "../../services/Context"

export const Alerts = () => {
const { errorService: { errors } } = useAppSelector()
Expand Down
9 changes: 0 additions & 9 deletions src/components/UI/Button.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions src/components/UI/FileInput.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Field, FieldProps } from 'solid-form-handler';
import { Component, JSX, Show, splitProps } from 'solid-js';
import { Button, Label } from '.';
import { Label } from '.';

export type FileInputProps = Omit<JSX.InputHTMLAttributes<HTMLInputElement>, 'type' | 'value'> &
FieldProps & { label?: string } & ({ multiple?: false; value?: File } | { multiple?: true; value?: File[] });
Expand All @@ -27,14 +27,14 @@ export const FileInput: Component<FileInputProps> = (props) => {
classList={{ 'hidden': true }}
onChange={field.props.onChange}
/>
<Button
<button
onBlur={field.props.onBlur}
classList={{ 'is-invalid': field.helpers.error }}
type="button"
onClick={() => fileInput?.click()}
>
<span class="p-2 border-end">Choose File</span>
</Button>
</button>
</div>
)}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/UI/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './Alert'
export * from './Button'
export * from './Alerts'
export * from './Card'
export * from './Checkbox'
export * from './ColorCircle'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { A } from "@solidjs/router"

const Tabs = () => {
return (
<div>
<h1>Tabs</h1>
<A href="/">Home</A>
</div>
)
}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/Home.tsx → src/components/main/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AddConnectionForm } from '../components/AddConnectionForm';
import { ConnectionsList } from '../components/ConnectionsList/ConnectionsList';
import { invoke } from '@tauri-apps/api';
import { ConnectionConfig, Scheme } from '../interfaces';
import { createStore } from 'solid-js/store';
import { onMount } from 'solid-js';
import { ConnectionConfig, Scheme } from '../../interfaces';
import { ConnectionsList } from '../Connections/ConnectionsList/ConnectionsList';
import { AddConnectionForm } from '../Connections/AddConnectionForm';

const Home = () => {
const addConnection = async (conn: { name: string, scheme: Scheme, color: string }) => {
Expand Down
Loading

0 comments on commit fc1470a

Please sign in to comment.