mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge branch 'main' of https://github.com/appwrite/appwrite-console-poc into databases
This commit is contained in:
Generated
+417
-578
File diff suppressed because it is too large
Load Diff
+12
-13
@@ -8,7 +8,6 @@
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prepare": "svelte-kit sync",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint .",
|
||||
@@ -26,33 +25,33 @@
|
||||
"tippy.js": "^6.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.24.0",
|
||||
"@sveltejs/adapter-auto": "1.0.0-next.63",
|
||||
"@sveltejs/kit": "1.0.0-next.390",
|
||||
"@playwright/test": "^1.25.0",
|
||||
"@sveltejs/adapter-auto": "1.0.0-next.64",
|
||||
"@sveltejs/kit": "1.0.0-next.405",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.0.1",
|
||||
"@testing-library/dom": "^8.16.0",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/dom": "^8.17.1",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/svelte": "^3.1.3",
|
||||
"@testing-library/user-event": "^14.3.0",
|
||||
"@types/gtag.js": "^0.0.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.7",
|
||||
"@typescript-eslint/parser": "^5.30.7",
|
||||
"@vitest/ui": "^0.18.1",
|
||||
"eslint": "^8.20.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.1",
|
||||
"@typescript-eslint/parser": "^5.33.1",
|
||||
"@vitest/ui": "^0.22.0",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-svelte": "^2.7.0",
|
||||
"sass": "^1.53.0",
|
||||
"sass": "^1.54.4",
|
||||
"svelte": "^3.49.0",
|
||||
"svelte-check": "^2.8.0",
|
||||
"svelte-jester": "^2.3.2",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "^4.7.4",
|
||||
"vite": "^3.0.0",
|
||||
"vitest": "^0.18.1"
|
||||
"vite": "^3.0.8",
|
||||
"vitest": "^0.22.0"
|
||||
},
|
||||
"type": "module",
|
||||
"pre-commit": [
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</button>
|
||||
<p class="u-flex-basis-100-percent">
|
||||
<slot />
|
||||
<slot name="subtitle" />
|
||||
</p>
|
||||
</header>
|
||||
<div class="modal-content">
|
||||
|
||||
@@ -3,13 +3,18 @@
|
||||
import type { Buttons } from '../stores/notifications';
|
||||
|
||||
export let dismissible = false;
|
||||
export let type: '' | 'info' | 'success' | 'warning' | 'danger' = 'info';
|
||||
export let type: 'info' | 'success' | 'warning' | 'error' = 'info';
|
||||
export let buttons: Buttons[] = [];
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<section class={`alert is-${type} `}>
|
||||
<section
|
||||
class="alert"
|
||||
class:is-success={type === 'success'}
|
||||
class:is-warning={type === 'warning'}
|
||||
class:is-danger={type === 'error'}
|
||||
class:is-info={type === 'info'}>
|
||||
<div class="alert-grid">
|
||||
{#if dismissible}
|
||||
<button
|
||||
@@ -19,7 +24,12 @@
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</button>
|
||||
{/if}
|
||||
<span class="icon-info" aria-hidden="true" />
|
||||
<span
|
||||
class:icon-info={type === 'info'}
|
||||
class:icon-check-circle={type === 'success'}
|
||||
class:icon-exclamation={type === 'warning'}
|
||||
class:icon-exclamation-circle={type === 'error'}
|
||||
aria-hidden="true" />
|
||||
<div class="content">
|
||||
{#if $$slots.title}
|
||||
<h6 class="title">
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { browser } from '$app/env';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade, fly, type FadeParams, type FlyParams } from 'svelte/transition';
|
||||
import { Alert } from '$lib/components';
|
||||
|
||||
export let show = false;
|
||||
export let size: 'small' | 'big' = null;
|
||||
export let warning = false;
|
||||
let browser = false;
|
||||
//TODO: explore other solutions compatible with testing library
|
||||
onMount(() => {
|
||||
browser = true;
|
||||
});
|
||||
export let error: string = null;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const transitionFly: FlyParams = {
|
||||
@@ -26,19 +24,20 @@
|
||||
closeModal();
|
||||
}
|
||||
};
|
||||
|
||||
const handleBLur = (event: MouseEvent) => {
|
||||
const target: Partial<HTMLElement> = event.target;
|
||||
if (target.hasAttribute('data-curtain')) {
|
||||
closeModal();
|
||||
}
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
show = false;
|
||||
dispatch('close');
|
||||
};
|
||||
|
||||
/**
|
||||
* Workaround until https://github.com/sveltejs/svelte/issues/3105 is resolved.
|
||||
*/
|
||||
$: if (browser) {
|
||||
if (show) {
|
||||
document.body.classList.add('u-overflow-hidden');
|
||||
@@ -76,6 +75,16 @@
|
||||
</button>
|
||||
</header>
|
||||
<div class="modal-content">
|
||||
{#if error}
|
||||
<Alert
|
||||
dismissible
|
||||
type="warning"
|
||||
on:dismiss={() => {
|
||||
error = null;
|
||||
}}>
|
||||
{error}
|
||||
</Alert>
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
{#if $$slots.footer}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<form class="form" on:submit|preventDefault>
|
||||
<form class="form common-section" on:submit|preventDefault>
|
||||
<slot />
|
||||
</form>
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
<script lang="ts">
|
||||
export let type: false | 'success' | 'warning' | 'error' = 'warning';
|
||||
|
||||
let icon = '';
|
||||
switch (type) {
|
||||
case 'success':
|
||||
icon = 'check-circle';
|
||||
break;
|
||||
case 'warning':
|
||||
icon = 'exclamation';
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
icon = 'exclamation-circle';
|
||||
break;
|
||||
|
||||
default:
|
||||
icon = '';
|
||||
break;
|
||||
}
|
||||
export let type: 'success' | 'warning' | 'error' | 'info' | 'neutral' = 'warning';
|
||||
</script>
|
||||
|
||||
<li class={`helper u-${type} u-margin-block-start-8"`}>
|
||||
{#if icon !== ''}
|
||||
<span class={`icon-${icon}`} aria-hidden="true" />
|
||||
<p
|
||||
class="helper u-margin-block-start-12"
|
||||
class:u-info={type === 'info'}
|
||||
class:u-error={type === 'error'}
|
||||
class:u-success={type === 'success'}
|
||||
class:u-warning={type === 'warning'}
|
||||
class:u-neutral={type === 'neutral'}>
|
||||
{#if type}
|
||||
<span
|
||||
class:icon-info={type === 'info'}
|
||||
class:icon-error={type === 'error'}
|
||||
class:icon-success={type === 'success'}
|
||||
class:icon-warning={type === 'warning'}
|
||||
class:icon-neutral={type === 'neutral'}
|
||||
aria-hidden="true" />
|
||||
{/if}
|
||||
<span class="text">
|
||||
<slot />
|
||||
</span>
|
||||
</li>
|
||||
</p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -7,11 +7,37 @@
|
||||
export let value = false;
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
<label class:u-hide={!showLabel} class="label" for={id}>{label}</label>
|
||||
<div class="input-text-wrapper">
|
||||
<input {id} {disabled} {required} type="checkbox" bind:checked={value} />
|
||||
<input
|
||||
{id}
|
||||
{disabled}
|
||||
{required}
|
||||
type="checkbox"
|
||||
bind:this={element}
|
||||
bind:checked={value}
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
export let placeholder = '';
|
||||
export let required = false;
|
||||
export let autofocus = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let unique = true;
|
||||
let bench = '';
|
||||
|
||||
const toggle = async () => {
|
||||
unique = !unique;
|
||||
if (unique) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -14,12 +14,30 @@
|
||||
export let autocomplete = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
onMount(() => {
|
||||
if (element && autofocus) {
|
||||
element.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
if (element.validity.typeMismatch) {
|
||||
error = 'Your email should be formatted as: name@example.com';
|
||||
return;
|
||||
}
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -31,10 +49,14 @@
|
||||
{disabled}
|
||||
{required}
|
||||
{readonly}
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
type="email"
|
||||
class="input-text"
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
<FormItem>
|
||||
<label class:u-hide={!showLabel} class="label" for={id}>{label}</label>
|
||||
<div class="input-text-wrapper">
|
||||
<input {id} {disabled} {required} bind:files type="file" />
|
||||
<input {id} {disabled} {required} type="file" bind:files />
|
||||
</div>
|
||||
</FormItem>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -16,12 +16,28 @@
|
||||
export let step: number | 'any' = 1;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
onMount(() => {
|
||||
if (element && autofocus) {
|
||||
element.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -39,6 +55,10 @@
|
||||
type="number"
|
||||
class="input-text"
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let id: string;
|
||||
export let label: string;
|
||||
@@ -13,8 +13,11 @@
|
||||
export let meter = false;
|
||||
export let autocomplete = false;
|
||||
export let showPasswordButton = false;
|
||||
export let minlength = 8;
|
||||
export let maxlength: number = null;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
let showInPlainText = false;
|
||||
|
||||
onMount(() => {
|
||||
@@ -23,7 +26,24 @@
|
||||
}
|
||||
});
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
if (element.validity.tooShort) {
|
||||
error = 'Password should contain at least 8 characters';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: strength = value ? value.length * 10 : 0;
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -31,27 +51,32 @@
|
||||
<div class="input-text-wrapper">
|
||||
{#if showInPlainText}
|
||||
<input
|
||||
type="text"
|
||||
{id}
|
||||
name={id}
|
||||
{placeholder}
|
||||
{required}
|
||||
{disabled}
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
{minlength}
|
||||
{maxlength}
|
||||
name={id}
|
||||
type="text"
|
||||
class="input-text"
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
{:else}
|
||||
<input
|
||||
{id}
|
||||
{placeholder}
|
||||
{disabled}
|
||||
{required}
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
{minlength}
|
||||
{maxlength}
|
||||
type="password"
|
||||
class="input-text"
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
{/if}
|
||||
|
||||
{#if meter}
|
||||
@@ -67,6 +92,7 @@
|
||||
{/if}
|
||||
{#if showPasswordButton}
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => (showInPlainText = !showInPlainText)}
|
||||
class="show-password-button"
|
||||
aria-label="show password">
|
||||
@@ -77,4 +103,7 @@
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -14,13 +14,35 @@
|
||||
export let autocomplete = false;
|
||||
export let maxlength: number = null;
|
||||
|
||||
const pattern = String.raw`^\+?[1-9]\d{1,14}$`;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
onMount(() => {
|
||||
if (element && autofocus) {
|
||||
element.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.patternMismatch) {
|
||||
error = "Allowed characters: leading '+' and maximum of 15 digits";
|
||||
return;
|
||||
}
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -32,11 +54,15 @@
|
||||
{disabled}
|
||||
{required}
|
||||
{maxlength}
|
||||
{pattern}
|
||||
{readonly}
|
||||
type="text"
|
||||
autocomplete={autocomplete ? 'on' : 'off'}
|
||||
type="tel"
|
||||
class="input-text"
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -9,11 +9,40 @@
|
||||
export let name: string;
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
<div class="input-text-wrapper">
|
||||
<input {id} {name} {disabled} {required} {value} type="radio" bind:group />
|
||||
<input
|
||||
{id}
|
||||
{name}
|
||||
{disabled}
|
||||
{required}
|
||||
{value}
|
||||
type="radio"
|
||||
bind:group
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
<label class:u-hide={!showLabel} class="label" for={id}>{label}</label>
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -40,16 +40,11 @@
|
||||
{required}
|
||||
type="search"
|
||||
class="input-text"
|
||||
on:input={valueChange}
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:input={valueChange} />
|
||||
<span class="icon-search" aria-hidden="true" />
|
||||
{#if isWithEndButton && value}
|
||||
<button
|
||||
class="x-button"
|
||||
aria-label="Clear search"
|
||||
on:click={() => {
|
||||
value = '';
|
||||
}}>
|
||||
<button class="x-button" aria-label="Clear search" on:click={() => (value = '')}>
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -12,12 +12,35 @@
|
||||
value: string | boolean | number;
|
||||
label: string;
|
||||
}[];
|
||||
|
||||
let element: HTMLSelectElement;
|
||||
let error: string;
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
<label class:u-hide={!showLabel} class="label" for={id}>{label}</label>
|
||||
<div class="select">
|
||||
<select bind:value {id} {required} {disabled}>
|
||||
<select
|
||||
{id}
|
||||
{required}
|
||||
{disabled}
|
||||
bind:this={element}
|
||||
bind:value
|
||||
on:invalid={handleInvalid}>
|
||||
{#if placeholder}
|
||||
<option value={null} disabled selected hidden>{placeholder}</option>
|
||||
{/if}
|
||||
@@ -29,4 +52,7 @@
|
||||
</select>
|
||||
<span class="icon-cheveron-down" aria-hidden="true" />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,11 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let id: string;
|
||||
export let value = false;
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -18,11 +35,16 @@
|
||||
type="checkbox"
|
||||
class="switch"
|
||||
role="switch"
|
||||
bind:this={element}
|
||||
bind:checked={value}
|
||||
on:change />
|
||||
on:change
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
<div class="choice-item-content">
|
||||
<div class="choice-item-title">{label}</div>
|
||||
</div>
|
||||
</label>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let id: string;
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
export let tags: string[] = [];
|
||||
export let placeholder = '';
|
||||
export let helper = '';
|
||||
export let autofocus = false;
|
||||
export let disabled = false;
|
||||
export let readonly = false;
|
||||
|
||||
let value = '';
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
onMount(() => {
|
||||
if (element && autofocus) {
|
||||
@@ -50,6 +50,20 @@
|
||||
const removeValue = (value: string) => {
|
||||
tags = tags.filter((tag) => tag !== value);
|
||||
};
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -75,19 +89,20 @@
|
||||
</ul>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
class="tags-input-text"
|
||||
{id}
|
||||
{placeholder}
|
||||
{disabled}
|
||||
{readonly}
|
||||
type="text"
|
||||
class="tags-input-text"
|
||||
bind:value
|
||||
bind:this={element}
|
||||
on:keydown={handleInput}
|
||||
on:blur={addValue}
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
</div>
|
||||
{#if helper}
|
||||
<p class="helper u-margin-block-start-12">{helper}</p>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -15,12 +15,28 @@
|
||||
export let maxlength: number = null;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
let error: string;
|
||||
|
||||
onMount(() => {
|
||||
if (element && autofocus) {
|
||||
element.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -37,6 +53,10 @@
|
||||
type="text"
|
||||
class="input-text"
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { FormItem } from '.';
|
||||
import { FormItem, Helper } from '.';
|
||||
|
||||
export let label: string;
|
||||
export let showLabel = true;
|
||||
@@ -14,12 +14,26 @@
|
||||
export let maxlength: number = null;
|
||||
|
||||
let element: HTMLTextAreaElement;
|
||||
let error: string;
|
||||
|
||||
onMount(() => {
|
||||
if (element && autofocus) {
|
||||
element.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const handleInvalid = (event: Event) => {
|
||||
event.preventDefault();
|
||||
if (element.validity.valueMissing) {
|
||||
error = 'This field is required';
|
||||
return;
|
||||
}
|
||||
error = element.validationMessage;
|
||||
};
|
||||
|
||||
$: if (value) {
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormItem>
|
||||
@@ -34,6 +48,10 @@
|
||||
{maxlength}
|
||||
class="input-text"
|
||||
bind:value
|
||||
bind:this={element} />
|
||||
bind:this={element}
|
||||
on:invalid={handleInvalid} />
|
||||
</div>
|
||||
{#if error}
|
||||
<Helper type="warning">{error}</Helper>
|
||||
{/if}
|
||||
</FormItem>
|
||||
|
||||
@@ -6,37 +6,25 @@
|
||||
export let title: Notification['title'];
|
||||
export let buttons: Notification['buttons'];
|
||||
|
||||
let icon: string;
|
||||
switch (type) {
|
||||
case 'success':
|
||||
icon = 'check-circle';
|
||||
break;
|
||||
case 'warning':
|
||||
icon = 'exclamation';
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
icon = 'exclamation-circle';
|
||||
break;
|
||||
|
||||
case 'info':
|
||||
icon = 'info';
|
||||
break;
|
||||
|
||||
default:
|
||||
icon = '';
|
||||
break;
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<li class={`alert-sticky is-${type}`}>
|
||||
<li
|
||||
class="alert-sticky"
|
||||
class:is-success={type === 'success'}
|
||||
class:is-warning={type === 'warning'}
|
||||
class:is-error={type === 'error'}
|
||||
class:is-info={type === 'info'}>
|
||||
<button class="x-button" aria-label="close alert" on:click={() => dispatch('dismiss')}>
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</button>
|
||||
<div class="alert-sticky-image">
|
||||
<span class={`icon-${icon}`} aria-hidden="true" />
|
||||
<span
|
||||
class:icon-check-cirle={type === 'success'}
|
||||
class:icon-exclamation={type === 'warning'}
|
||||
class:icon-exclamation-circle={type === 'error'}
|
||||
class:icon-info={type === 'info'}
|
||||
aria-hidden="true" />
|
||||
</div>
|
||||
<div class="alert-sticky-content">
|
||||
{#if title}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
class="icon-button is-no-desktop"
|
||||
aria-label="Open Menu"
|
||||
on:click={() => (isOpen = !isOpen)}>
|
||||
<span class={isOpen ? 'icon-x' : 'icon-menu'} aria-hidden="true" />
|
||||
<span class:icon-x={isOpen} class:icon-menu={!isOpen} aria-hidden="true" />
|
||||
</button>
|
||||
<slot name="header" />
|
||||
</header>
|
||||
@@ -88,10 +88,10 @@
|
||||
</h1>
|
||||
{#if $copyData?.value}
|
||||
<Copy value={$copyData.value}>
|
||||
<Pill button
|
||||
><span
|
||||
class="icon-duplicate"
|
||||
aria-hidden="true" />{$copyData.text}</Pill>
|
||||
<Pill button>
|
||||
<span class="icon-duplicate" aria-hidden="true" />
|
||||
{$copyData.text}
|
||||
</Pill>
|
||||
</Copy>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
export let provider: Provider;
|
||||
|
||||
let { keyID, teamID, p8 } = JSON.parse(provider.secret);
|
||||
let error: string;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
const update = async () => {
|
||||
@@ -35,24 +36,22 @@
|
||||
provider.active ? 'enabled' : 'disabled'
|
||||
}`
|
||||
});
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<Form on:submit={update}>
|
||||
<Modal size="big" bind:show={showModal}>
|
||||
<Modal {error} size="big" bind:show={showModal}>
|
||||
<svelte:fragment slot="header">{provider.name} OAuth2 Settings</svelte:fragment>
|
||||
<FormList>
|
||||
<p>
|
||||
To use {provider.name} authentication in your application, first fill in this form. For
|
||||
more info you can
|
||||
<a class="link" href={provider.docs} target="_blank" rel="noopener noreferrer"
|
||||
>visit the docs.</a>
|
||||
<a class="link" href={provider.docs} target="_blank" rel="noopener noreferrer">
|
||||
visit the docs.
|
||||
</a>
|
||||
</p>
|
||||
<InputSwitch
|
||||
id="state"
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
Form,
|
||||
FormList
|
||||
} from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdkForConsole } from '$lib/stores/sdk';
|
||||
import type { Provider } from '$lib/stores/oauth-providers';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
|
||||
export let showModal = false;
|
||||
export let provider: Provider;
|
||||
|
||||
let { clientSecret, auth0Domain } = JSON.parse(provider.secret);
|
||||
let error: string;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
const update = async () => {
|
||||
@@ -35,17 +36,14 @@
|
||||
provider.active ? 'enabled' : 'disabled'
|
||||
}`
|
||||
});
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<Form on:submit={update}>
|
||||
<Modal size="big" bind:show={showModal}>
|
||||
<Modal {error} size="big" bind:show={showModal}>
|
||||
<svelte:fragment slot="header">{provider.name} OAuth2 Settings</svelte:fragment>
|
||||
<FormList>
|
||||
<p>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let name: string, id: string;
|
||||
let name: string, id: string, error: string;
|
||||
let showDropdown = false;
|
||||
|
||||
const create = async () => {
|
||||
@@ -24,11 +24,8 @@
|
||||
message: `${team.name} has been created`
|
||||
});
|
||||
dispatch('created', team);
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,11 +34,12 @@
|
||||
}
|
||||
$: if (!showCreate) {
|
||||
showDropdown = false;
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Form on:submit={create}>
|
||||
<Modal size="big" bind:show={showCreate}>
|
||||
<Modal {error} size="big" bind:show={showCreate}>
|
||||
<svelte:fragment slot="header">Create Team</svelte:fragment>
|
||||
<FormList>
|
||||
<InputText
|
||||
@@ -60,7 +58,9 @@
|
||||
{:else}
|
||||
<InnerModal bind:show={showDropdown}>
|
||||
<svelte:fragment slot="title">Team ID</svelte:fragment>
|
||||
Enter a custom team ID. Leave blank for a randomly generated one.
|
||||
<svelte:fragment slot="subtitle">
|
||||
Enter a custom team ID. Leave blank for a randomly generated one.
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="form">
|
||||
<InputText
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
let showDropdown = false;
|
||||
let name: string, mail: string, pass: string, id: string;
|
||||
let error: string;
|
||||
|
||||
const create = async () => {
|
||||
try {
|
||||
@@ -31,11 +32,8 @@
|
||||
message: `${user.name} has been created`
|
||||
});
|
||||
dispatch('created', user);
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,11 +42,12 @@
|
||||
}
|
||||
$: if (!showCreate) {
|
||||
showDropdown = false;
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Form on:submit={create}>
|
||||
<Modal size="big" bind:show={showCreate}>
|
||||
<Modal {error} size="big" bind:show={showCreate}>
|
||||
<svelte:fragment slot="header">Create User</svelte:fragment>
|
||||
<FormList>
|
||||
<InputText
|
||||
@@ -73,15 +72,18 @@
|
||||
|
||||
{#if !showDropdown}
|
||||
<div>
|
||||
<Pill button on:click={() => (showDropdown = !showDropdown)}
|
||||
><span class="icon-pencil" aria-hidden="true" /><span class="text">
|
||||
<Pill button on:click={() => (showDropdown = !showDropdown)}>
|
||||
<span class="icon-pencil" aria-hidden="true" /><span class="text">
|
||||
User ID
|
||||
</span></Pill>
|
||||
</span>
|
||||
</Pill>
|
||||
</div>
|
||||
{:else}
|
||||
<InnerModal bind:show={showDropdown}>
|
||||
<svelte:fragment slot="title">User ID</svelte:fragment>
|
||||
Enter a custom user ID. Leave blank for a randomly generated one.
|
||||
<svelte:fragment slot="subtitle">
|
||||
Enter a custom user ID. Leave blank for a randomly generated one.
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="form">
|
||||
<InputText
|
||||
@@ -96,9 +98,10 @@
|
||||
<span
|
||||
class="icon-info u-cross-center u-margin-block-start-2 u-line-height-1 u-icon-small"
|
||||
aria-hidden="true" />
|
||||
<span class="text u-line-height-1-5"
|
||||
>Allowed characters: alphanumeric, hyphen, non-leading
|
||||
underscore, period</span>
|
||||
<span class="text u-line-height-1-5">
|
||||
Allowed characters: alphanumeric, hyphen, non-leading
|
||||
underscore, period
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
Form,
|
||||
FormList
|
||||
} from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdkForConsole } from '$lib/stores/sdk';
|
||||
import type { Provider } from '$lib/stores/oauth-providers';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
|
||||
export let showModal = false;
|
||||
export let provider: Provider;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
|
||||
let error: string;
|
||||
|
||||
const update = async () => {
|
||||
try {
|
||||
await sdkForConsole.projects.updateOAuth2(
|
||||
@@ -31,17 +35,14 @@
|
||||
provider.active ? 'enabled' : 'disabled'
|
||||
}`
|
||||
});
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<Form on:submit={update}>
|
||||
<Modal size="big" bind:show={showModal}>
|
||||
<Modal {error} size="big" bind:show={showModal}>
|
||||
<svelte:fragment slot="header">{provider.name} OAuth2 Settings</svelte:fragment>
|
||||
<FormList>
|
||||
<p>
|
||||
|
||||
@@ -9,15 +9,18 @@
|
||||
Form,
|
||||
FormList
|
||||
} from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdkForConsole } from '$lib/stores/sdk';
|
||||
import type { Provider } from '$lib/stores/oauth-providers';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
|
||||
export let showModal = false;
|
||||
export let provider: Provider;
|
||||
|
||||
let { clientSecret, tenantID } = JSON.parse(provider.secret);
|
||||
let error: string;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
|
||||
const update = async () => {
|
||||
try {
|
||||
const secret = JSON.stringify({ clientSecret, tenantID });
|
||||
@@ -35,24 +38,22 @@
|
||||
provider.active ? 'enabled' : 'disabled'
|
||||
}`
|
||||
});
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<Form on:submit={update}>
|
||||
<Modal size="big" bind:show={showModal}>
|
||||
<Modal {error} size="big" bind:show={showModal}>
|
||||
<svelte:fragment slot="header">{provider.name} OAuth2 Settings</svelte:fragment>
|
||||
<FormList>
|
||||
<p>
|
||||
To use {provider.name} authentication in your application, first fill in this form. For
|
||||
more info you can
|
||||
<a class="link" href={provider.docs} target="_blank" rel="noopener noreferrer"
|
||||
>visit the docs.</a>
|
||||
<a class="link" href={provider.docs} target="_blank" rel="noopener noreferrer">
|
||||
visit the docs.
|
||||
</a>
|
||||
</p>
|
||||
<InputSwitch
|
||||
id="state"
|
||||
|
||||
@@ -9,16 +9,18 @@
|
||||
Form,
|
||||
FormList
|
||||
} from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdkForConsole } from '$lib/stores/sdk';
|
||||
import type { Provider } from '$lib/stores/oauth-providers';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
|
||||
export let showModal = false;
|
||||
export let provider: Provider;
|
||||
|
||||
let { clientSecret, oktaDomain, authorizationServerId } = JSON.parse(provider.secret);
|
||||
let error: string;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
|
||||
const update = async () => {
|
||||
try {
|
||||
const secret = JSON.stringify({ clientSecret, oktaDomain, authorizationServerId });
|
||||
@@ -35,17 +37,14 @@
|
||||
provider.active ? 'enabled' : 'disabled'
|
||||
}`
|
||||
});
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<Form on:submit={update}>
|
||||
<Modal size="big" bind:show={showModal}>
|
||||
<Modal {error} size="big" bind:show={showModal}>
|
||||
<svelte:fragment slot="header">{provider.name} OAuth2 Settings</svelte:fragment>
|
||||
<FormList>
|
||||
<p>
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let name: string, email: string, roles: [];
|
||||
let name: string, email: string, roles: string[];
|
||||
let error: string;
|
||||
|
||||
const create = async () => {
|
||||
const url = `${$page.url.origin}/console/${$page.params.project}/authentication/teams/${$page.params.team}/members`;
|
||||
@@ -32,17 +33,14 @@
|
||||
roles = [];
|
||||
showCreate = false;
|
||||
dispatch('created', user);
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<Form on:submit={create}>
|
||||
<Modal bind:show={showCreate}>
|
||||
<Modal {error} size="big" bind:show={showCreate}>
|
||||
<svelte:fragment slot="header">Create Membership</svelte:fragment>
|
||||
<FormList>
|
||||
<InputEmail
|
||||
|
||||
@@ -35,9 +35,8 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteMembership}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete Member</svelte:fragment>
|
||||
|
||||
<p>
|
||||
Are you sure you want to delete <b>{selectedMembership.userName}</b> from '{selectedMembership.teamName}'?
|
||||
</p>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteTeam}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete Team</svelte:fragment>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { page } from '$app/stores';
|
||||
import { Avatar, CardGrid, Box } from '$lib/components';
|
||||
import { Container } from '$lib/layout';
|
||||
import { Button, InputText, Helper } from '$lib/elements/forms';
|
||||
import { Button, InputText, Form } from '$lib/elements/forms';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
@@ -14,9 +14,6 @@
|
||||
const getAvatar = (name: string) => sdkForProject.avatars.getInitials(name, 48, 48).toString();
|
||||
|
||||
let showDelete = false;
|
||||
let showError: false | 'name' | 'email' | 'password' = false;
|
||||
let errorMessage = 'Something went wrong';
|
||||
let errorType: 'error' | 'warning' | 'success' = 'error';
|
||||
let teamName: string = null;
|
||||
|
||||
onMount(async () => {
|
||||
@@ -24,12 +21,6 @@
|
||||
teamName ??= $team.name;
|
||||
});
|
||||
|
||||
function addError(location: typeof showError, message: string, type: typeof errorType) {
|
||||
showError = location;
|
||||
errorMessage = message;
|
||||
errorType = type;
|
||||
}
|
||||
|
||||
async function updateName() {
|
||||
try {
|
||||
await sdkForProject.teams.update($page.params.team, teamName);
|
||||
@@ -43,7 +34,10 @@
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
addError('name', error.message, 'error');
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -65,31 +59,30 @@
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Name</h6>
|
||||
<Form on:submit={updateName}>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Name</h6>
|
||||
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="Enter team name"
|
||||
autocomplete={false}
|
||||
bind:value={teamName} />
|
||||
{#if showError === 'name'}
|
||||
<Helper type={errorType}>{errorMessage}</Helper>
|
||||
{/if}
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="Enter team name"
|
||||
autocomplete={false}
|
||||
bind:value={teamName} />
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
disabled={teamName === $team.name || !teamName}
|
||||
on:click={() => {
|
||||
updateName();
|
||||
}}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
disabled={teamName === $team.name || !teamName}
|
||||
on:click={() => {
|
||||
updateName();
|
||||
}}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
</Form>
|
||||
|
||||
<CardGrid>
|
||||
<div>
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteAllMemberships}>
|
||||
<Modal warning={true} bind:show={showDeleteAll}>
|
||||
<Modal bind:show={showDeleteAll} warning>
|
||||
<svelte:fragment slot="header">Delete All Memberships</svelte:fragment>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteAllSessions}>
|
||||
<Modal warning={true} bind:show={showDeleteAll}>
|
||||
<Modal bind:show={showDeleteAll} warning>
|
||||
<svelte:fragment slot="header">Delete All Sessions</svelte:fragment>
|
||||
|
||||
<p>
|
||||
Are you sure you want to delete <b>all of {$user.name}'s sessions?</b>
|
||||
</p>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteMembership}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete Member</svelte:fragment>
|
||||
<p>
|
||||
Are you sure you want to delete <b>{selectedMembership.userName}</b> from '{selectedMembership.teamName}'?
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteSession}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete Sessions</svelte:fragment>
|
||||
|
||||
<p>Are you sure you want to delete this session?</p>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteUser}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete User</svelte:fragment>
|
||||
<p>Are you sure you want to delete <b>{$user.name}</b> from '{$project.name}'?</p>
|
||||
<svelte:fragment slot="footer">
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
import { Pill } from '$lib/elements';
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
InputText,
|
||||
InputEmail,
|
||||
InputPassword,
|
||||
InputPhone,
|
||||
Helper
|
||||
InputPhone
|
||||
} from '$lib/elements/forms';
|
||||
import { Container } from '$lib/layout';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
@@ -28,10 +28,8 @@
|
||||
arePrefsDisabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
let showDelete = false;
|
||||
let showError: false | 'name' | 'email' | 'phone' | 'password' = false;
|
||||
let errorMessage = 'Something went wrong';
|
||||
let errorType: 'error' | 'warning' | 'success' = 'error';
|
||||
let userName: string = null,
|
||||
userEmail: string = null,
|
||||
userPhone: string = null,
|
||||
@@ -53,12 +51,6 @@
|
||||
|
||||
const getAvatar = (name: string) => sdkForProject.avatars.getInitials(name, 48, 48).toString();
|
||||
|
||||
function addError(location: typeof showError, message: string, type: typeof errorType) {
|
||||
showError = location;
|
||||
errorMessage = message;
|
||||
errorType = type;
|
||||
}
|
||||
|
||||
async function updateVerificationEmail() {
|
||||
showVerifcationDropdown = false;
|
||||
try {
|
||||
@@ -118,53 +110,60 @@
|
||||
const breadcrumb = $breadcrumbs.get($breadcrumbs.size);
|
||||
breadcrumb.title = userName;
|
||||
$breadcrumbs = $breadcrumbs.set($breadcrumbs.size, breadcrumb);
|
||||
|
||||
showError = false;
|
||||
addNotification({
|
||||
message: 'Name has been updated',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
addError('name', error.message, 'error');
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
async function updateEmail() {
|
||||
try {
|
||||
await sdkForProject.users.updateEmail($user.$id, userEmail);
|
||||
$user.email = userEmail;
|
||||
showError = false;
|
||||
addNotification({
|
||||
message: 'Email has been updated',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
addError('email', error.message, 'error');
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
async function updatePhone() {
|
||||
try {
|
||||
await sdkForProject.users.updatePhone($user.$id, userPhone);
|
||||
$user.phone = userPhone;
|
||||
showError = false;
|
||||
addNotification({
|
||||
message: 'Phone has been updated',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
addError('phone', error.message, 'error');
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
async function updatePassword() {
|
||||
try {
|
||||
await sdkForProject.users.updatePassword($user.$id, newPassword);
|
||||
newPassword = null;
|
||||
showError = false;
|
||||
addNotification({
|
||||
message: 'Password has been updated',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
addError('password', error.message, 'error');
|
||||
addNotification({
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +235,8 @@
|
||||
text={$user.status}
|
||||
secondary={!$user.status}
|
||||
on:click={() => updateStatus()}
|
||||
>{$user.status ? 'Block account' : 'Unblock account'}</Button>
|
||||
>{$user.status ? 'Block account' : 'Unblock account'}
|
||||
</Button>
|
||||
{#if $user.status}
|
||||
{#if $user.phone && $user.email}
|
||||
<DropList
|
||||
@@ -252,12 +252,16 @@
|
||||
{$user.emailVerification ? 'Unverify' : 'Verify'} account
|
||||
</Button>
|
||||
<svelte:fragment slot="list">
|
||||
<DropListItem icon="mail" on:click={() => updateVerificationEmail()}
|
||||
>{$user.emailVerification ? 'Unverify' : 'Verify'} email</DropListItem>
|
||||
<DropListItem
|
||||
icon="mail"
|
||||
on:click={() => updateVerificationEmail()}>
|
||||
{$user.emailVerification ? 'Unverify' : 'Verify'} email
|
||||
</DropListItem>
|
||||
<DropListItem
|
||||
icon="phone"
|
||||
on:click={() => updateVerificationPhone()}>
|
||||
{$user.phoneVerification ? 'Unverify' : 'Verify'} phone</DropListItem>
|
||||
{$user.phoneVerification ? 'Unverify' : 'Verify'} phone
|
||||
</DropListItem>
|
||||
</svelte:fragment>
|
||||
</DropList>
|
||||
{:else if !$user.phone}
|
||||
@@ -271,182 +275,175 @@
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Name</h6>
|
||||
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="Enter name"
|
||||
autocomplete={false}
|
||||
bind:value={userName} />
|
||||
{#if showError === 'name'}
|
||||
<Helper type={errorType}>{errorMessage}</Helper>
|
||||
{/if}
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
<Form on:submit={updateName}>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Name</h6>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
disabled={userName === $user.name || !userName}
|
||||
on:click={() => {
|
||||
updateName();
|
||||
}}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Email</h6>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputEmail
|
||||
id="email"
|
||||
label="Email"
|
||||
placeholder="Enter email"
|
||||
autocomplete={false}
|
||||
bind:value={userEmail} />
|
||||
{#if showError === 'email'}
|
||||
<Helper type={errorType}>{errorMessage}</Helper>
|
||||
{/if}
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
disabled={userEmail === $user.email || !userEmail}
|
||||
on:click={() => {
|
||||
updateEmail();
|
||||
}}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Phone</h6>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputPhone
|
||||
id="phone"
|
||||
label="Phone"
|
||||
placeholder="Enter phone number"
|
||||
autocomplete={false}
|
||||
bind:value={userPhone} />
|
||||
{#if showError === 'phone'}
|
||||
<Helper type={errorType}>{errorMessage}</Helper>
|
||||
{/if}
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
disabled={userPhone === $user.phone || !userPhone}
|
||||
on:click={() => {
|
||||
updatePhone();
|
||||
}}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<CardGrid>
|
||||
<div>
|
||||
<h6 class="heading-level-7">Update Password</h6>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Enter a new password. A password must contain <b> at least 8 characters.</b>
|
||||
</p>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputPassword
|
||||
id="newPassword"
|
||||
label="New Password"
|
||||
placeholder="Enter new password"
|
||||
autocomplete={false}
|
||||
meter={false}
|
||||
showPasswordButton={true}
|
||||
bind:value={newPassword} />
|
||||
{#if showError === 'password'}
|
||||
<Helper type={errorType}>{errorMessage}</Helper>
|
||||
{/if}
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button
|
||||
disabled={!newPassword}
|
||||
on:click={() => {
|
||||
updatePassword();
|
||||
}}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">User Preferences</h6>
|
||||
<p>
|
||||
You can update your user preferences by storing information on the user's objects so
|
||||
they can easily be shared across devices and sessions.
|
||||
</p>
|
||||
<svelte:fragment slot="aside">
|
||||
<form class="form u-grid u-gap-16">
|
||||
<ul class="form-list">
|
||||
{#if prefs}
|
||||
{#each prefs as [key, value], index}
|
||||
<li class="form-item is-multiple">
|
||||
<div class="form-item-part u-stretch">
|
||||
<label class="label" for={`key-${index}`}>Key</label>
|
||||
<div class="input-text-wrapper">
|
||||
<input
|
||||
id={`key-${key}`}
|
||||
placeholder="Enter key"
|
||||
type="text"
|
||||
class="input-text"
|
||||
bind:value={key} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item-part u-stretch">
|
||||
<label class="label" for={`value-${index}`}>Value</label>
|
||||
<div class="input-text-wrapper">
|
||||
<input
|
||||
id={`value-${value}`}
|
||||
placeholder="Enter value"
|
||||
type="text"
|
||||
class="input-text"
|
||||
bind:value />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item-part u-cross-child-end">
|
||||
<Button
|
||||
text
|
||||
disabled={(!key || !value) && index === 0}
|
||||
on:click={() => {
|
||||
if (index === 0) {
|
||||
prefs = [['', '']];
|
||||
} else {
|
||||
prefs.splice(index, 1);
|
||||
prefs = prefs;
|
||||
}
|
||||
}}>
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="Enter name"
|
||||
autocomplete={false}
|
||||
bind:value={userName} />
|
||||
</ul>
|
||||
<button
|
||||
class="button is-text u-padding-inline-0"
|
||||
disabled={prefs?.length
|
||||
? !prefs[prefs.length - 1][0] || !prefs[prefs.length - 1][1]
|
||||
: true}
|
||||
on:click={() => {
|
||||
prefs.push(['', '']);
|
||||
prefs = prefs;
|
||||
}}>
|
||||
<span class="icon-plus" aria-hidden="true" />
|
||||
<span class="text"> Add preference </span></button>
|
||||
</form>
|
||||
</svelte:fragment>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button disabled={arePrefsDisabled} on:click={() => updatePrefs()}>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
<svelte:fragment slot="actions">
|
||||
<Button disabled={userName === $user.name || !userName} submit>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
</Form>
|
||||
|
||||
<Form on:submit={updateEmail}>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Email</h6>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputEmail
|
||||
id="email"
|
||||
label="Email"
|
||||
placeholder="Enter email"
|
||||
autocomplete={false}
|
||||
bind:value={userEmail} />
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button disabled={userEmail === $user.email || !userEmail} submit>
|
||||
Update
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
</Form>
|
||||
|
||||
<Form on:submit={updatePhone}>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">Update Phone</h6>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputPhone
|
||||
id="phone"
|
||||
label="Phone"
|
||||
placeholder="Enter phone number"
|
||||
autocomplete={false}
|
||||
bind:value={userPhone} />
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button disabled={userPhone === $user.phone || !userPhone} submit>
|
||||
Update
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
</Form>
|
||||
|
||||
<Form on:submit={updatePassword}>
|
||||
<CardGrid>
|
||||
<div>
|
||||
<h6 class="heading-level-7">Update Password</h6>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Enter a new password. A password must contain <b>at least 8 characters.</b>
|
||||
</p>
|
||||
<svelte:fragment slot="aside">
|
||||
<ul>
|
||||
<InputPassword
|
||||
id="newPassword"
|
||||
label="New Password"
|
||||
placeholder="Enter new password"
|
||||
autocomplete={false}
|
||||
meter={false}
|
||||
showPasswordButton={true}
|
||||
bind:value={newPassword} />
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button disabled={!newPassword} submit>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
</Form>
|
||||
|
||||
<Form on:submit={updatePrefs}>
|
||||
<CardGrid>
|
||||
<h6 class="heading-level-7">User Preferences</h6>
|
||||
<p>
|
||||
You can update your user preferences by storing information on the user's
|
||||
objects so they can easily be shared across devices and sessions.
|
||||
</p>
|
||||
<svelte:fragment slot="aside">
|
||||
<form class="form u-grid u-gap-16">
|
||||
<ul class="form-list">
|
||||
{#if prefs}
|
||||
{#each prefs as [key, value], index}
|
||||
<li class="form-item is-multiple">
|
||||
<div class="form-item-part u-stretch">
|
||||
<label class="label" for={`key-${index}`}>Key</label>
|
||||
<div class="input-text-wrapper">
|
||||
<input
|
||||
id={`key-${key}`}
|
||||
placeholder="Enter key"
|
||||
type="text"
|
||||
class="input-text"
|
||||
bind:value={key} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item-part u-stretch">
|
||||
<label class="label" for={`value-${index}`}>
|
||||
Value
|
||||
</label>
|
||||
<div class="input-text-wrapper">
|
||||
<input
|
||||
id={`value-${value}`}
|
||||
placeholder="Enter value"
|
||||
type="text"
|
||||
class="input-text"
|
||||
bind:value />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item-part u-cross-child-end">
|
||||
<Button
|
||||
text
|
||||
disabled={(!key || !value) && index === 0}
|
||||
on:click={() => {
|
||||
if (index === 0) {
|
||||
prefs = [['', '']];
|
||||
} else {
|
||||
prefs.splice(index, 1);
|
||||
prefs = prefs;
|
||||
}
|
||||
}}>
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
<Button
|
||||
text
|
||||
on:click={() => {
|
||||
if (prefs[prefs.length - 1][0] && prefs[prefs.length - 1][1]) {
|
||||
prefs.push(['', '']);
|
||||
prefs = prefs;
|
||||
}
|
||||
}}>
|
||||
<span class="icon-plus" aria-hidden="true" />
|
||||
<span class="text">Add Preference</span>
|
||||
</Button>
|
||||
</form>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
<Button disabled={arePrefsDisabled} submit>Update</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
</Form>
|
||||
|
||||
<CardGrid>
|
||||
<div>
|
||||
|
||||
+2
-1
@@ -3,14 +3,15 @@
|
||||
import { CardGrid } from '$lib/components';
|
||||
import { collection } from '../../store';
|
||||
import { doc } from './store';
|
||||
import Attribute from './_attribute.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import Attribute from './_attribute.svelte';
|
||||
|
||||
let currentDoc: string;
|
||||
let updateBtnDisabled = true;
|
||||
|
||||
onMount(async () => {
|
||||
await doc.load($collection.$id, $page.params.document);
|
||||
currentDoc = JSON.stringify($doc);
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
import { Modal, InnerModal } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { Button, InputText, Form, FormList } from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
@@ -14,6 +12,7 @@
|
||||
let name = '';
|
||||
let id: string = null;
|
||||
let showDropdown = false;
|
||||
let error: string;
|
||||
|
||||
const create = async () => {
|
||||
try {
|
||||
@@ -25,11 +24,8 @@
|
||||
name = null;
|
||||
showCreate = false;
|
||||
dispatch('created', bucket);
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,11 +34,12 @@
|
||||
}
|
||||
$: if (!showCreate) {
|
||||
showDropdown = false;
|
||||
error = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Form on:submit={create}>
|
||||
<Modal size="big" bind:show={showCreate}>
|
||||
<Modal {error} size="big" bind:show={showCreate}>
|
||||
<svelte:fragment slot="header">Create Bucket</svelte:fragment>
|
||||
<FormList>
|
||||
<InputText
|
||||
@@ -55,15 +52,17 @@
|
||||
|
||||
{#if !showDropdown}
|
||||
<div>
|
||||
<Pill button on:click={() => (showDropdown = !showDropdown)}
|
||||
><span class="icon-pencil" aria-hidden="true" /><span class="text">
|
||||
Bucket ID
|
||||
</span></Pill>
|
||||
<Pill button on:click={() => (showDropdown = !showDropdown)}>
|
||||
<span class="icon-pencil" aria-hidden="true" />
|
||||
<span class="text"> Bucket ID </span>
|
||||
</Pill>
|
||||
</div>
|
||||
{:else}
|
||||
<InnerModal bind:show={showDropdown}>
|
||||
<svelte:fragment slot="title">Bucket ID</svelte:fragment>
|
||||
<p>Enter a custom bucket ID. Leave blank for a randomly generated one.</p>
|
||||
<svelte:fragment slot="subtitle">
|
||||
Enter a custom bucket ID. Leave blank for a randomly generated one.
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="form">
|
||||
<InputText
|
||||
@@ -78,9 +77,10 @@
|
||||
<span
|
||||
class="icon-info u-cross-center u-margin-block-start-2 u-line-height-1 u-icon-small"
|
||||
aria-hidden="true" />
|
||||
<span class="text u-line-height-1-5"
|
||||
>Allowed characters: alphanumeric, hyphen, non-leading
|
||||
underscore, period</span>
|
||||
<span class="text u-line-height-1-5">
|
||||
Allowed characters: alphanumeric, hyphen, non-leading
|
||||
underscore, period
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import { Modal, Alert, InnerModal } from '$lib/components';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { page } from '$app/stores';
|
||||
import { uploader } from '$lib/stores/uploader';
|
||||
import { bucket } from './store';
|
||||
@@ -20,6 +19,7 @@
|
||||
let read: string[] = [];
|
||||
let write: string[] = [];
|
||||
let id: string = null;
|
||||
let error: string;
|
||||
let showDropdown = false;
|
||||
|
||||
const create = async () => {
|
||||
@@ -36,11 +36,8 @@
|
||||
showDropdown = false;
|
||||
uploader.addFile(file);
|
||||
dispatch('created');
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} catch ({ message }) {
|
||||
error = message;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,9 +68,8 @@
|
||||
}
|
||||
|
||||
$: if (!showCreate) {
|
||||
id = null;
|
||||
id = files = error = null;
|
||||
list = new DataTransfer();
|
||||
files = null;
|
||||
read = [];
|
||||
write = [];
|
||||
}
|
||||
@@ -86,7 +82,7 @@
|
||||
<input bind:files id="file" type="file" style="display: none" />
|
||||
|
||||
<Form on:submit={create}>
|
||||
<Modal bind:show={showCreate}>
|
||||
<Modal {error} bind:show={showCreate}>
|
||||
<svelte:fragment slot="header">Upload File</svelte:fragment>
|
||||
<FormList>
|
||||
<div>
|
||||
@@ -137,7 +133,9 @@
|
||||
{:else}
|
||||
<InnerModal bind:show={showDropdown}>
|
||||
<svelte:fragment slot="title">File ID</svelte:fragment>
|
||||
<p>Enter a custom file ID. Leave blank for a randomly generated one.</p>
|
||||
<svelte:fragment slot="subtitle">
|
||||
Enter a custom file ID. Leave blank for a randomly generated one.
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="form">
|
||||
<InputText
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteUser}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete Bucket</svelte:fragment>
|
||||
<p>Are you sure you want to delete <b>{$bucket.name}</b>?</p>
|
||||
<svelte:fragment slot="footer">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteFile}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete File</svelte:fragment>
|
||||
<p>Are you sure you want to delete <b>{file.name}</b>?</p>
|
||||
<svelte:fragment slot="footer">
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</script>
|
||||
|
||||
<Form on:submit={deleteFile}>
|
||||
<Modal warning={true} bind:show={showDelete}>
|
||||
<Modal bind:show={showDelete} warning>
|
||||
<svelte:fragment slot="header">Delete File</svelte:fragment>
|
||||
<p>Are you sure you want to delete <b>{$file.name}</b>?</p>
|
||||
<svelte:fragment slot="footer">
|
||||
|
||||
@@ -9,7 +9,6 @@ test('shows phone input', () => {
|
||||
|
||||
expect(getByText('input')).toBeInTheDocument();
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toHaveAttribute('type', 'tel');
|
||||
});
|
||||
|
||||
test('shows phone input - required', () => {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ const config = {
|
||||
include: ['tests/**/*.test.ts'],
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
thread: true
|
||||
threads: true
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user