Adding a progress bar

This commit is contained in:
Eric van der Vlist 2023-03-02 13:18:40 +01:00
parent 6b2569aed0
commit fe8ca05fd4
2 changed files with 167 additions and 97 deletions

View File

@ -1,6 +1,14 @@
import { createForm } from '@felte/solid';
import { Component, Index, Match, onMount, Show, Switch } from 'solid-js';
import { TextField, Button } from '@kobalte/core';
import {
Component,
createSignal,
Index,
Match,
onMount,
Show,
Switch,
} from 'solid-js';
import { TextField, Button, Progress } from '@kobalte/core';
import reporter from '@felte/reporter-tippy';
import './style.css';
import { useNavigate } from 'solid-start';
@ -18,6 +26,8 @@ interface Props {
const User: Component<Props> = (props) => {
const navigate = useNavigate();
const [progress, setProgress] = createSignal(-1);
const credentials = adminCredentials();
const { database } = credentials || { database: null };
@ -37,6 +47,7 @@ const User: Component<Props> = (props) => {
values,
context,
});
setProgress(0);
const id = getValues()?._id ?? userId(values.username, values.database);
await put(id, values, isNew());
const couchUserId = `org.couchdb.user:${values.username}`;
@ -49,6 +60,8 @@ const User: Component<Props> = (props) => {
};
await put(couchUserId, userDoc, isNew(), '_users');
setProgress(1);
const subscriptions = !!props?.values
? props.values().subscriptions ?? []
: [];
@ -74,6 +87,8 @@ const User: Component<Props> = (props) => {
}
}
setProgress(2);
for (let i = 0; i < subscriptions.length; i++) {
let subscription = subscriptions[i];
if (!isIn(subscription.username, updatedSubscriptions)) {
@ -83,10 +98,12 @@ const User: Component<Props> = (props) => {
});
}
}
setProgress(3);
setInitialValues(values);
setIsDirty(false);
setProgress(-1);
navigate(`/user/${id}`);
};
@ -200,102 +217,125 @@ const User: Component<Props> = (props) => {
return (
<>
<Show when={!isNew()}>
<h2>{userId(data('username'), data('database'))}</h2>
<Show when={progress() >= 0}>
<Progress.Root
value={progress()}
minValue={0}
maxValue={10}
getValueLabel={({ value, max }) =>
`${value} of ${max} tasks completed`
}
class='progress'
>
<div class='progress__label-container'>
<Progress.Label class='progress__label'>
Processing...
</Progress.Label>
<Progress.ValueLabel class='progress__value-label' />
</div>
<Progress.Track class='progress__track'>
<Progress.Fill class='progress__fill' />
</Progress.Track>
</Progress.Root>
</Show>
<Show when={progress() < 0}>
<Show when={!isNew()}>
<h2>{userId(data('username'), data('database'))}</h2>
</Show>
<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>
<table>
<thead>
<tr>
<th>
<button type='button' onClick={addSubscription()}>
+
</button>
</th>
<th>User name</th>
</tr>
</thead>
<tbody>
<Index each={subscriptions()}>
{(_, index) => (
<tr>
<td>
<button type='button' onClick={removeSubscription(index)}>
-
</button>
</td>
<td>
<TextField.Root>
<TextField.Input
type='text'
name={`subscriptions.${index}.username`}
required={true}
placeholder='user name'
/>
</TextField.Root>
</td>
</tr>
)}
</Index>
</tbody>
</table>
<Switch>
<Match when={!isNew()}>
<Button.Root type='submit' disabled={!isDirty() || !isValid()}>
Save
</Button.Root>
<Button.Root onclick={deleteHandler}>Delete</Button.Root>
</Match>
<Match when={isNew()}>
<Button.Root type='submit' isDisabled={!isValid()}>
Create
</Button.Root>
</Match>
</Switch>
<Button.Root onclick={cancelHandler}>Back</Button.Root>
</form>
</Show>
<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>
<table>
<thead>
<tr>
<th>
<button type='button' onClick={addSubscription()}>
+
</button>
</th>
<th>User name</th>
</tr>
</thead>
<tbody>
<Index each={subscriptions()}>
{(_, index) => (
<tr>
<td>
<button type='button' onClick={removeSubscription(index)}>
-
</button>
</td>
<td>
<TextField.Root>
<TextField.Input
type='text'
name={`subscriptions.${index}.username`}
required={true}
placeholder='user name'
/>
</TextField.Root>
</td>
</tr>
)}
</Index>
</tbody>
</table>
<Switch>
<Match when={!isNew()}>
<Button.Root type='submit' disabled={!isDirty() || !isValid()}>
Save
</Button.Root>
<Button.Root onclick={deleteHandler}>Delete</Button.Root>
</Match>
<Match when={isNew()}>
<Button.Root type='submit' isDisabled={!isValid()}>
Create
</Button.Root>
</Match>
</Switch>
<Button.Root onclick={cancelHandler}>Back</Button.Root>
</form>
</>
);
};

View File

@ -142,3 +142,33 @@ form {
transform: scale(0.96);
}
}
.progress {
display: flex;
flex-direction: column;
gap: 2px;
width: 300px;
}
.progress__label-container {
display: flex;
justify-content: space-between;
}
.progress__label,
.progress__value-label {
color: hsl(240 4% 16%);
font-size: 14px;
}
.progress__track {
height: 10px;
background-color: hsl(240 6% 90%);
}
.progress__fill {
background-color: hsl(200 98% 39%);
height: 100%;
width: var(--kb-progress-fill-width);
transition: width 250ms linear;
}
.progress__fill[data-progress="complete"] {
background-color: #16a34a;
}