Skip to content

Commit

Permalink
feat(console): add configure metadata page
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidsowardx committed Jan 16, 2024
1 parent 0578575 commit d65ce5d
Show file tree
Hide file tree
Showing 28 changed files with 1,699 additions and 45 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ yarn-error.log*
.turbo

.eslintcache
vitest.config.ts.timestamp*
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ pnpm-lock.yaml
pnpm-workspace.yaml
package-lock.json
yarn.lock
vitest.config.ts.timestamp*
3 changes: 3 additions & 0 deletions apps/console/src/lib/Label.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
font-weight: 500;
margin-bottom: 0.75rem;
user-select: none;
display: flex;
align-items: center;
gap: 0.5rem;
}
</style>
1 change: 0 additions & 1 deletion apps/console/src/lib/OwnerRole.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
} from '@api/_deprecated/utils/entities/resource'
import { shortenAddress } from '@utils'
import type { AccessRule } from '../helpers/simple-access-rule-builder'
import { goto } from '$app/navigation'
import { createEventDispatcher } from 'svelte'
type Resource =
Expand Down
158 changes: 136 additions & 22 deletions apps/console/src/lib/form/Form.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<script lang="ts" context="module">
type ItemBase = {
key: string
label: string
placeholder: string
label?: string
placeholder?: string
formItemType: string
showCondition?: (formState: Record<string, string>) => boolean
showCondition?: (formState: Record<string, any>) => boolean
schema?: ZodSchema
metadata?: Record<string, string>
transformValue?: (value: string) => any
transformValue?: (value: any) => any
error?: boolean
}
Expand All @@ -25,6 +25,17 @@
type InputFormItem = ItemBase & {
formItemType: 'input'
startDecorator?: new (...args: any[]) => SvelteComponent
startDecoratorPropertiesFn?: () => Record<string, any>
}
type SvelteComponentFormItem = ItemBase & {
formItemType: 'svelteComponent'
component: new (...args: any[]) => SvelteComponent
componentProperties?: Record<
string,
string | number | boolean | Record<string, any>
>
}
type InputWithCheckboxFormItem = ItemBase & {
Expand All @@ -38,12 +49,21 @@
items: { id: string; label: string }[]
}
type ListFormItem = ItemBase & {
formItemType: 'list'
addLabel?: string
startDecorator?: new (...args: any[]) => SvelteComponent
startDecoratorPropertiesFn?: () => Record<string, any>
}
export type FormItem =
| TextareaFormItem
| TextareaWithCheckboxFormItem
| InputFormItem
| InputWithCheckboxFormItem
| SelectFormItem
| ListFormItem
| SvelteComponentFormItem
</script>
<script lang="ts">
Expand All @@ -52,12 +72,18 @@
import Textarea from '../Textarea.svelte'
import Label from '../Label.svelte'
import type { ZodSchema, z } from '@common/zod'
import { writable } from 'svelte/store'
import { writable, type Writable } from 'svelte/store'
import Checkbox from '@components/_base/checkbox/Checkbox.svelte'
import type { SvelteComponent } from 'svelte'
import PadlockIcon from '@icons/validators-menu.svg'
import IconNew from '@components/_base/icon/IconNew.svelte'
export let items: FormItem[] = []
export let state = writable<Record<string, string>>({})
export let state = writable<Record<string, any>>({})
export let disabled = false
export let disabledFields: Record<string, any> = {}
export let initialState: Writable<Record<string, any>> | undefined = undefined
export let showPadLockWhenDisabled = false
const checkboxValue = (key: string) => $state[key] === 'true'
const handleCheckboxChange = (item: FormItem, value: boolean) => {
Expand All @@ -72,51 +98,68 @@
{#each items as item}
{#if item.showCondition && !item.showCondition($state)}{''}{:else}
<div class="form-item">
<Label {disabled}>{item.label}</Label>
{#if item.label}<Label {disabled}
>{item.label}{#if showPadLockWhenDisabled && disabledFields[item.key]}
<IconNew icon={PadlockIcon} />{/if}</Label
>{/if}
{#if item.formItemType === 'input'}
<Input
{disabled}
placeholder={item.placeholder}
bind:value={$state[item.key]}
schema={item.schema}
/>
<div class="with-action">
{#if item.startDecorator}
<svelte:component
this={item.startDecorator}
value={$state[item.key]}
{...item.startDecoratorPropertiesFn?.()}
/>
{/if}
<Input
disabled={disabled || disabledFields[item.key]}
placeholder={item.placeholder}
bind:value={$state[item.key]}
schema={item.schema}
/>
</div>
{:else if item.formItemType === 'inputWithCheckbox'}
<div class="with-checkbox">
<div class="with-action">
<div class="input">
<Input
{disabled}
disabled={disabled || disabledFields[item.key]}
placeholder={item.placeholder}
bind:value={$state[item.key]}
schema={item.schema}
/>
</div>
<Checkbox
checked={checkboxValue(item.checkboxKey)}
{disabled}
disabled={disabled || disabledFields[item.key]}
on:checked={() => handleCheckboxChange(item, true)}
on:unchecked={() => handleCheckboxChange(item, false)}
>{item.checkboxLabel}</Checkbox
>
</div>
{:else if item.formItemType === 'textarea'}
<Textarea
{disabled}
disabled={disabled || disabledFields[item.key]}
placeholder={item.placeholder}
bind:value={$state[item.key]}
schema={item.schema}
rows={item.rows}
/>
{:else if item.formItemType === 'svelteComponent'}
<svelte:component
this={item.component}
{...item.componentProperties || {}}
/>
{:else if item.formItemType === 'textareaWithCheckbox'}
<div class="with-checkbox">
<div class="with-action">
<Textarea
{disabled}
disabled={disabled || disabledFields[item.key]}
placeholder={item.placeholder}
bind:value={$state[item.key]}
schema={item.schema}
rows={item.rows}
/>
<Checkbox
{disabled}
disabled={disabled || disabledFields[item.key]}
checked={checkboxValue(item.checkboxKey)}
on:checked={() => handleCheckboxChange(item, true)}
on:unchecked={() => handleCheckboxChange(item, false)}
Expand All @@ -125,22 +168,78 @@
</div>
{:else if item.formItemType === 'select'}
<Select
{disabled}
disabled={disabled || disabledFields[item.key]}
placeholder={item.placeholder}
bind:selected={$state[item.key]}
items={item.items}
/>
{:else if item.formItemType === 'list'}
{#if !disabledFields[item.key]}
<button
class="add-button"
class:disabled={disabled || disabledFields[item.key]}
on:click={() => ($state[item.key] = [...$state[item.key], ''])}
>{item.addLabel || 'Add'}</button
>
{/if}
{#each $state[item.key] as listItem, index}
<div style:margin-bottom="1rem" class="with-action">
<div class="with-action input">
{#if item.startDecorator}
<svelte:component
this={item.startDecorator}
value={listItem}
{...item.startDecoratorPropertiesFn?.()}
/>
{/if}
<Input
disabled={disabled || disabledFields[item.key]}
placeholder={item.placeholder}
schema={item.schema}
bind:value={listItem}
/>
</div>

{#if !disabledFields[item.key]}
<button
class:disabled={disabled || disabledFields[item.key]}
on:click={() =>
($state[item.key] = $state[item.key].toSpliced(index, 1))}
>Remove</button
>
{/if}
</div>
{/each}
{/if}
{#if initialState && $initialState}
{#if JSON.stringify($initialState[item.key]) !== JSON.stringify($state[item.key])}
<div class="restore-original-value">
Value of "{item.label}" field has changed.
<button
class="restore-button"
on:click={() => {
$state[item.key] = $initialState?.[item.key]
}}>Restore to original value</button
>
</div>
{/if}
{/if}
</div>
{/if}
{/each}

<style lang="scss">
.restore-button {
text-decoration: underline;
margin-top: 0.5rem;
}
.form-item {
margin-bottom: 1rem;
position: relative;
}
.with-checkbox {
.with-action {
display: flex;
flex-direction: row;
align-items: center;
Expand All @@ -150,4 +249,19 @@
.input {
width: 100%;
}
.label {
font-weight: 500;
margin-bottom: 0.75rem;
user-select: none;
display: flex;
align-items: center;
justify-content: space-between;
}
.add-button {
position: absolute;
right: 0;
top: 0;
}
</style>
46 changes: 33 additions & 13 deletions apps/console/src/lib/input/Input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
export let disabled = false
export let placeholder = ''
export let error = false
export let error: boolean | string = false
export let value = ''
export let schema: ZodSchema | undefined = undefined
export let ref: ((el: HTMLInputElement) => void) | undefined = undefined
let element: HTMLInputElement
let state = writable<'initial' | 'touched'>('initial')
let zodError = writable<ZodError | undefined>(undefined)
Expand All @@ -17,6 +19,7 @@
const result = schema.safeParse(value)
error = !result.success
}
if (ref) ref(element)
})
$: {
Expand All @@ -39,19 +42,36 @@
}
</script>

<div class="content">
<input {placeholder} class:disabled class:error on:input bind:value />
</div>
<div class="input-with-error">
<div class="content" class:error={$state === 'touched' && !!error}>
<input
{placeholder}
class:disabled
on:input
bind:value
bind:this={element}
/>
</div>

{#if schema}
{#if $zodError}
{#each $zodError.issues as issue}
<div class="error-message">{issue.message}</div>
{/each}
{/if}
{/if}

{#if schema}
{#if $zodError}
{#each $zodError.issues as issue}
<div class="error-message">{issue.message}</div>
{/each}
{#if error && typeof error === 'string'}
<div class="error-message">{error}</div>
{/if}
{/if}
</div>

<style lang="scss">
.input-with-error {
display: flex;
width: 100%;
flex-direction: column;
}
.content {
border: 1px solid var(--theme-border);
background: var(--theme-surface-2);
Expand All @@ -61,16 +81,16 @@
line-height: 1.5rem;
display: flex;
flex-direction: column;
&.error {
border-color: var(--theme-error-primary);
}
}
input {
width: 100%;
&.disabled {
user-select: none;
}
&.error {
border-color: var(--theme-error-primary);
}
}
.error-message {
color: var(--theme-error-primary);
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/lib/select/Select.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" context="module">
export type Item = {
id: string
id: any
label: string
}
</script>
Expand Down
Loading

0 comments on commit d65ce5d

Please sign in to comment.