2023-02-21 20:11:03 +00:00
|
|
|
import { createForm } from '@felte/solid';
|
2023-02-24 17:00:40 +00:00
|
|
|
import { Component, createEffect, Match, Switch } from 'solid-js';
|
|
|
|
import { TextField, Button } from '@kobalte/core';
|
|
|
|
import reporter from '@felte/reporter-tippy';
|
2023-02-21 20:11:03 +00:00
|
|
|
import { v4 as uuid } from 'uuid';
|
2023-02-24 17:00:40 +00:00
|
|
|
import './style.css';
|
2023-02-22 10:19:10 +00:00
|
|
|
import { useNavigate } from 'solid-start';
|
2023-02-24 17:00:40 +00:00
|
|
|
import { adminCredentials } from '../credentials';
|
|
|
|
import { put } from '~/lib/put';
|
|
|
|
import { del } from '~/lib/del';
|
|
|
|
import { isFunction } from 'lodash';
|
2023-02-21 10:23:35 +00:00
|
|
|
|
2023-02-22 10:19:10 +00:00
|
|
|
interface Props {
|
2023-02-24 17:00:40 +00:00
|
|
|
values?: () => any;
|
2023-02-22 10:19:10 +00:00
|
|
|
}
|
2023-02-21 10:23:35 +00:00
|
|
|
|
2023-02-22 20:18:57 +00:00
|
|
|
const User: Component<Props> = (props) => {
|
2023-02-22 10:19:10 +00:00
|
|
|
const navigate = useNavigate();
|
|
|
|
|
2023-02-24 17:00:40 +00:00
|
|
|
const getValues = () => {
|
|
|
|
if (!isFunction(props?.values)) {
|
|
|
|
return null;
|
2023-02-22 14:32:02 +00:00
|
|
|
}
|
2023-02-24 17:00:40 +00:00
|
|
|
return props.values();
|
|
|
|
};
|
|
|
|
|
|
|
|
const isNew = () => !getValues();
|
2023-02-22 13:54:41 +00:00
|
|
|
|
2023-02-22 10:19:10 +00:00
|
|
|
const submitHandler = async (values: any, context: any) => {
|
2023-02-21 10:23:35 +00:00
|
|
|
console.log({
|
2023-02-22 20:18:57 +00:00
|
|
|
caller: 'User / submitHandler',
|
2023-02-21 10:23:35 +00:00
|
|
|
props,
|
|
|
|
values,
|
|
|
|
context,
|
|
|
|
});
|
2023-02-24 17:00:40 +00:00
|
|
|
const id = getValues()?._id ?? `user:${uuid()}`;
|
|
|
|
await put(id, values, isNew());
|
|
|
|
if (isNew()) {
|
|
|
|
navigate(`/user/${id}`);
|
2023-02-22 10:19:10 +00:00
|
|
|
}
|
2023-02-21 10:23:35 +00:00
|
|
|
};
|
|
|
|
|
2023-02-22 10:58:56 +00:00
|
|
|
const cancelHandler = () => {
|
2023-02-22 20:18:57 +00:00
|
|
|
navigate(`/user/`);
|
2023-02-22 10:58:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const deleteHandler = async () => {
|
|
|
|
console.log({
|
2023-02-22 20:18:57 +00:00
|
|
|
caller: 'User / deleteHandler',
|
2023-02-24 17:00:40 +00:00
|
|
|
id: getValues()?._id,
|
2023-02-22 10:58:56 +00:00
|
|
|
props,
|
|
|
|
});
|
2023-02-24 17:00:40 +00:00
|
|
|
await del(getValues()?._id);
|
2023-02-22 20:18:57 +00:00
|
|
|
navigate(`/user/`);
|
2023-02-22 10:58:56 +00:00
|
|
|
};
|
|
|
|
|
2023-02-24 17:00:40 +00:00
|
|
|
const validationHandler = async (values: any) => {
|
|
|
|
let errors: any = {};
|
|
|
|
const credentials = adminCredentials();
|
|
|
|
if (!credentials) {
|
|
|
|
return errors;
|
|
|
|
}
|
|
|
|
const { database, username, password } = credentials;
|
|
|
|
try {
|
|
|
|
const response = await fetch(database, { mode: 'cors' });
|
|
|
|
const dbStatus = await response.json();
|
|
|
|
if (!dbStatus.couchdb) {
|
|
|
|
errors.database = 'The URL is not a couchdb instance';
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
errors.database = "Can't access the database";
|
|
|
|
}
|
|
|
|
if (!!errors.database) {
|
|
|
|
return errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isNew()) {
|
|
|
|
const authString = `${username}:${password}`;
|
|
|
|
const headers = new Headers();
|
|
|
|
headers.set('Authorization', 'Basic ' + btoa(authString));
|
|
|
|
const response = await fetch(
|
|
|
|
`${database}/_users/org.couchdb.user:${values.username}`,
|
|
|
|
{
|
|
|
|
method: 'HEAD',
|
|
|
|
mode: 'cors',
|
|
|
|
headers,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
if (response.status === 200) {
|
|
|
|
errors.username = 'The user is already existing';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors;
|
|
|
|
};
|
|
|
|
|
|
|
|
const { form, data, setData, setInitialValues, reset } = createForm({
|
2023-02-22 10:19:10 +00:00
|
|
|
onSubmit: submitHandler,
|
2023-02-24 17:00:40 +00:00
|
|
|
extend: reporter(),
|
|
|
|
validate: validationHandler,
|
|
|
|
initialValues: getValues(),
|
2023-02-22 10:19:10 +00:00
|
|
|
});
|
|
|
|
|
2023-02-24 17:00:40 +00:00
|
|
|
createEffect(() => {
|
|
|
|
console.log({ caller: 'user / createEffect', values: getValues() });
|
|
|
|
if (isNew()) {
|
|
|
|
const credentials = adminCredentials();
|
|
|
|
if (!credentials) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const { database } = credentials;
|
|
|
|
setData('database', database);
|
2023-02-22 14:32:02 +00:00
|
|
|
} else {
|
2023-02-24 17:00:40 +00:00
|
|
|
setInitialValues(getValues());
|
|
|
|
reset();
|
|
|
|
console.log({
|
|
|
|
caller: 'user / createEffect',
|
|
|
|
values: getValues(),
|
|
|
|
data: data(),
|
|
|
|
});
|
2023-02-22 14:32:02 +00:00
|
|
|
}
|
2023-02-24 17:00:40 +00:00
|
|
|
});
|
2023-02-22 13:54:41 +00:00
|
|
|
|
2023-02-22 14:45:52 +00:00
|
|
|
const createUserHandler = async () => {
|
|
|
|
console.log({
|
2023-02-22 20:18:57 +00:00
|
|
|
caller: 'User / createUserHandler',
|
2023-02-22 14:45:52 +00:00
|
|
|
props,
|
|
|
|
data: data(),
|
|
|
|
});
|
2023-02-24 17:00:40 +00:00
|
|
|
// setOpenUserNamePasswordDialog(true);
|
2023-02-22 17:24:06 +00:00
|
|
|
};
|
|
|
|
|
2023-02-22 10:19:10 +00:00
|
|
|
console.log({
|
2023-02-22 20:18:57 +00:00
|
|
|
caller: 'User ',
|
2023-02-22 10:19:10 +00:00
|
|
|
props,
|
2023-02-24 17:00:40 +00:00
|
|
|
values: getValues(),
|
2023-02-22 10:19:10 +00:00
|
|
|
});
|
2023-02-21 10:23:35 +00:00
|
|
|
|
|
|
|
return (
|
2023-02-24 17:00:40 +00:00
|
|
|
<form use:form>
|
|
|
|
<TextField.Root>
|
|
|
|
<TextField.Label>Mail address</TextField.Label>
|
|
|
|
<TextField.Input
|
|
|
|
type='mail'
|
|
|
|
name='mail'
|
|
|
|
required={true}
|
|
|
|
placeholder='Email address'
|
|
|
|
/>
|
|
|
|
<TextField.ErrorMessage>
|
|
|
|
Please provide a valid URL
|
|
|
|
</TextField.ErrorMessage>
|
|
|
|
</TextField.Root>
|
|
|
|
<TextField.Root>
|
|
|
|
<TextField.Label>Database</TextField.Label>
|
|
|
|
<TextField.Input
|
|
|
|
type='url'
|
|
|
|
name='database'
|
|
|
|
required={true}
|
|
|
|
placeholder='Database URL'
|
|
|
|
readOnly={true}
|
|
|
|
/>
|
|
|
|
</TextField.Root>
|
|
|
|
<TextField.Root>
|
|
|
|
<TextField.Label>User name</TextField.Label>
|
|
|
|
<TextField.Input
|
|
|
|
type='text'
|
|
|
|
name='username'
|
|
|
|
required={true}
|
|
|
|
placeholder='user name'
|
|
|
|
readOnly={!isNew()}
|
|
|
|
/>
|
|
|
|
</TextField.Root>
|
|
|
|
<TextField.Root>
|
|
|
|
<TextField.Label>Password</TextField.Label>
|
|
|
|
<TextField.Input
|
|
|
|
type='text'
|
|
|
|
name='password'
|
|
|
|
required={true}
|
|
|
|
placeholder='Password'
|
|
|
|
autocomplete='off'
|
|
|
|
/>
|
|
|
|
</TextField.Root>
|
|
|
|
<Switch>
|
|
|
|
<Match when={!isNew()}>
|
|
|
|
<Button.Root type='submit'>Save</Button.Root>
|
|
|
|
<Button.Root onclick={deleteHandler}>Delete</Button.Root>
|
|
|
|
</Match>
|
|
|
|
<Match when={isNew()}>
|
|
|
|
<Button.Root type='submit'>Create</Button.Root>
|
|
|
|
</Match>
|
|
|
|
</Switch>
|
|
|
|
<Button.Root onclick={cancelHandler}>Cancel</Button.Root>
|
|
|
|
</form>
|
2023-02-21 10:23:35 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2023-02-22 20:18:57 +00:00
|
|
|
export default User;
|