Skip to content

Commit

Permalink
feat: refresh connection list after adding connection
Browse files Browse the repository at this point in the history
  • Loading branch information
invm committed Jul 1, 2023
1 parent d994898 commit eb6e641
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 46 deletions.
55 changes: 28 additions & 27 deletions src/components/AddConnectionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import { useFormHandler } from 'solid-form-handler';
import { zodSchema } from 'solid-form-handler/zod';
import { t } from 'i18next';
import { Match, onMount, Show, Switch } from 'solid-js';
import { invoke } from '@tauri-apps/api';

import { Alert, Button, TextInput, Select, ColorCircle } from './UI';
import {
PORTS_MAP, Schemes, AvailableConnectionModes, SocketPathDefaults,
connectionColors, ConnectionMode, connectionModes, schemes, HostCredentials, SocketCredentials, FileCredentials
connectionColors, ConnectionMode, connectionModes, schemes, HostCredentials, SocketCredentials, FileCredentials, ConnectionConfig, Scheme
} from '../interfaces';
import { titleCase } from '../utils/formatters';
import { FileInput } from './UI/FileInput';
Expand All @@ -28,13 +27,13 @@ export const ConnectionFormSchema = z.object({
name: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length),
scheme: z.enum(schemes),
mode: z.enum(connectionModes),
username: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional(),
password: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional(),
host: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional(),
file: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional(),
socket_path: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional(),
port: z.number().min(MIN_PORT).max(MAX_PORT).optional(),
dbname: z.string().optional(),
username: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional().or(z.literal('')),
password: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional().or(z.literal('')),
host: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional().or(z.literal('')),
file: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional().or(z.literal('')),
socket_path: z.string().min(MIN_LENGTH_STR, messages.length).max(MAX_LENGTH_STR, messages.length).optional().or(z.literal('')),
port: z.coerce.number().min(MIN_PORT).max(MAX_PORT).optional().or(z.literal(0)),
dbname: z.string().optional().or(z.literal('')),
color: z.enum(connectionColors),
});

Expand All @@ -55,7 +54,7 @@ export const formToConnectionStruct = (form: ConnectionForm) => {
}
case ConnectionMode.File: {
const creds: FileCredentials = omit(rest, 'host', 'port', 'socket_path');
return { name, scheme: { [scheme]: { [mode]: creds } }, color }
return { name, scheme: { [scheme]: { [mode]: creds } } as Partial<Scheme>, color }
}
}
}
Expand All @@ -75,10 +74,10 @@ const defaultValues = {
dbname: 'noir',
}

const AddConnectionForm = () => {
const AddConnectionForm = (props: { addConnection: ({ name, scheme, color }: { name: string, scheme: Scheme, color: string }) => Promise<void> }) => {
const { errorService: { addError } } = useAppSelector()
const formHandler = useFormHandler(zodSchema(ConnectionFormSchema));
const { formData, isFormInvalid, setFieldDefaultValue, getFormErrors, setFieldValue } = formHandler;
const { formData, setFieldDefaultValue, getFormErrors, setFieldValue } = formHandler;

onMount(() => {
for (const key in defaultValues) {
Expand All @@ -88,19 +87,19 @@ const AddConnectionForm = () => {

const submit = async (event: Event) => {
event.preventDefault();
await formHandler.validateForm().catch(() => { });
try {
await formHandler.validateForm();
const { name, color, scheme } = formToConnectionStruct(formData());
await invoke('add_connection', { name, color, scheme })
const { name, scheme, color } = formToConnectionStruct(formData());
await props.addConnection({ name, scheme, color });
} catch (error) {
console.error(error);
addError((error as any).message);
}
};

return (
<div class="flex-2 p-3 max-w-lg">
<form class="flex w-full flex-col gap-1" autocomplete="off" onSubmit={submit}>
<div class="p-3 w-full flex justify-center items-around pt-20">
<form class="flex max-w-lg flex-col gap-1" autocomplete="off" onSubmit={submit}>
<div>
<h2 class="text-2xl font-bold text">{t('components.add_connection_form.title')}</h2>
</div>
Expand Down Expand Up @@ -218,17 +217,19 @@ const AddConnectionForm = () => {
</div>
</div>
</Show>
<Show when={Object.keys(getFormErrors()).length}>
<Alert color="error">
{getFormErrors().map((error) => (
<p class="text-bold">
{t(`components.add_connection_form.labels.${error.path}`)}: {error.message}
</p>
))}
</Alert>
</Show>
<div class="py-3">
<Show when={Object.keys(getFormErrors()).length}>
<Alert color="error">
{getFormErrors().map((error) => (
<p class="text-bold">
{t(`components.add_connection_form.labels.${error.path}`)}: {error.message}
</p>
))}
</Alert>
</Show>
</div>
<div class="py-4">
<Button disabled={isFormInvalid()} type="submit" >{t('components.add_connection_form.title')}</Button>
<Button disabled={Object.keys(getFormErrors()).length} type="submit" >{t('components.add_connection_form.title')}</Button>
</div>
</form >
</div >
Expand Down
18 changes: 6 additions & 12 deletions src/components/ConnectionsList/ConnectionsList.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import { invoke } from '@tauri-apps/api';
import { For, onMount } from 'solid-js';
import { createStore } from 'solid-js/store';
import { For } from 'solid-js';
import { SetStoreFunction } from 'solid-js/store';
import { ConnectionConfig } from '../../interfaces';
import { ConnectionItem } from './ConnectionItem/ConnectionItem';

export const ConnectionsList = () => {
const [connections, setConnections] = createStore<ConnectionConfig[]>([]);

onMount(async () => {
const res = await invoke('get_connections', {})
setConnections(res as ConnectionConfig[]);
});
export const ConnectionsList = (props: { connections: ConnectionConfig[], setConnections: SetStoreFunction<ConnectionConfig[]> }) => {

const deleteConnection = async (id: string) => {
await invoke('delete_connection', { id })
setConnections((prev) => prev.filter((c) => c.id !== id));
props.setConnections((prev) => prev.filter((c) => c.id !== id));
}

return (
<div class="p-2 bg-gray-900">
<div class="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">
<For each={connections}>
<For each={props.connections}>
{(connection) =>
<li>
<ConnectionItem {...{ connection, deleteConnection }} />
Expand Down
2 changes: 1 addition & 1 deletion src/components/UI/ColorCircle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ConnectionColor } from "../../interfaces"

export const ColorCircle = (props: { color: ConnectionColor }) => {
return <span class={`min-w-[20px] w-[20px] min-h-[20px] h-[20px] mb-1 rounded-full border-2 bg-${props.color}-500`}></span>
return <div class="flex h-[26px]"><span class={`min-w-[20px] w-[20px] min-h-[20px] h-[20px] rounded-full border-2 bg-${props.color}-500`}></span></div>
}
2 changes: 1 addition & 1 deletion src/components/UI/Label.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Label = (props: { for: string, value?: string, children?: any }) => {
return (
<label for={props.for} class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">{props.children ?? props.value}</label>
<label for={props.for} class="text-sm font-medium text-gray-900 dark:text-gray-300">{props.children ?? props.value}</label>
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ input[type=number] {
}

.app-input {
@apply block w-full p-2 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-base py-1 px-2 font-bold;
@apply block w-full p-2 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-sm focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 py-1.5 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-base;
}

.app-checkbox{
Expand All @@ -92,7 +92,7 @@ input[type=number] {
}

.app-select {
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-base py-1 px-2 font-bold sm:text-xs;
@apply bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-base sm:text-sm py-0.5;
}

.background {
Expand Down
4 changes: 3 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ export const AvailableConnectionModes = {

export const connectionModes = [ConnectionMode.Host, ConnectionMode.Socket, ConnectionMode.File] as const;

export type Scheme = Partial<Record<SchemeType, Record<ConnectionModeType, Record<string, string>>>>

export type ConnectionConfig = {
id?: string;
name: string;
scheme: Record<SchemeType, Record<ConnectionModeType, Record<string, string>>>;
scheme: Scheme;
color: ConnectionColor;
}

Expand Down
21 changes: 19 additions & 2 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
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';

const Home = () => {
const addConnection = async ({ name, scheme, color }: { name: string, scheme: Scheme, color: string }) => {
await invoke('add_connection', { name, scheme, color })
const res = await invoke('get_connections', {})
setConnections(res as ConnectionConfig[]);
}

const [connections, setConnections] = createStore<ConnectionConfig[]>([]);

onMount(async () => {
const res = await invoke('get_connections', {})
setConnections(res as ConnectionConfig[]);
});

return (
<div class="grid grid-cols-2 h-full">
<ConnectionsList />
<AddConnectionForm />
<ConnectionsList {...{ connections, setConnections }} />
<AddConnectionForm {...{ addConnection }} />
</div>
)
}
Expand Down

0 comments on commit eb6e641

Please sign in to comment.