Merge pull request #526 from appwrite/chore-upgrade-svelte-4

chore: upgrade Svelte 4 and other dependencies
This commit is contained in:
Torsten Dittmann
2023-10-02 11:46:26 +02:00
committed by GitHub
60 changed files with 1978 additions and 7842 deletions
+23 -11
View File
@@ -1,24 +1,36 @@
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
parserOptions: {
extraFileExtensions: ['.svelte'], // This is a required setting in `@typescript-eslint/parser` v4.24.0.
sourceType: 'module',
ecmaVersion: 2020
},
ignorePatterns: ['*.cjs'],
overrides: [
{
files: ['*.svelte'],
processor: 'svelte3/svelte3',
rules: {
'no-redeclare': 'off'
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser' //This is required to parse TypeScript inside Svelte files.
}
}
],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
rules: {
'no-redeclare': 'off',
'@typescript-eslint/no-duplicate-enum-values': 'off',
'svelte/no-at-html-tags': 'off',
'no-unused-vars': 'off', // This rule is handled by `@typescript-eslint/no-unused-vars` so it needs to be disabled to avoid conflicts.
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_', varsIgnorePattern: '^(_|\\$\\$)' } // Ignore unused variables starting with `_` or `$$`.
]
},
env: {
browser: true,
+1 -1
View File
@@ -5,5 +5,5 @@
"trailingComma": "none",
"printWidth": 100,
"bracketSameLine": true,
"svelteSortOrder": "scripts-options-markup-styles"
"plugins": ["prettier-plugin-svelte"]
}
+1737 -7673
View File
File diff suppressed because it is too large Load Diff
+35 -35
View File
@@ -10,66 +10,66 @@
"sync": "svelte-kit sync",
"check": "svelte-check --tsconfig ./tsconfig.json --fail-on-warnings --threshold warning",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint .",
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. .",
"lint": "prettier --ignore-path .gitignore --check --plugin prettier-plugin-svelte . && eslint .",
"format": "prettier --ignore-path .gitignore --write --plugin prettier-plugin-svelte .",
"test": "vitest run",
"test:ui": "vitest --ui",
"test:watch": "vitest watch",
"e2e": "playwright test tests/e2e"
},
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
"@analytics/google-tag-manager": "^0.5.3",
"@analytics/google-analytics": "^1.0.7",
"@analytics/google-tag-manager": "^0.5.5",
"@appwrite.io/console": "^0.3.0",
"@appwrite.io/pink": "0.1.0-next.9",
"@appwrite.io/pink-icons": "^0.1.0-next.9",
"@popperjs/core": "^2.11.6",
"@sentry/svelte": "^7.44.2",
"@sentry/tracing": "^7.44.2",
"ai": "^2.1.15",
"analytics": "^0.8.1",
"@popperjs/core": "^2.11.8",
"@sentry/svelte": "^7.66.0",
"@sentry/tracing": "^7.66.0",
"ai": "^2.2.11",
"analytics": "^0.8.9",
"dayjs": "^1.11.9",
"deep-equal": "^2.2.2",
"dotenv": "^16.0.3",
"echarts": "^5.4.1",
"logrocket": "^3.0.1",
"dotenv": "^16.3.1",
"echarts": "^5.4.3",
"logrocket": "^5.0.1",
"nanoid": "^4.0.2",
"pretty-bytes": "^6.1.0",
"pretty-bytes": "^6.1.1",
"prismjs": "^1.29.0",
"svelte-confetti": "^1.2.2",
"svelte-confetti": "^1.3.0",
"tippy.js": "^6.3.7",
"web-vitals": "^3.1.1"
"web-vitals": "^3.4.0"
},
"devDependencies": {
"@playwright/test": "^1.31.2",
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/kit": "^1.15.4",
"@sveltejs/vite-plugin-svelte": "^2.0.4",
"@playwright/test": "^1.37.1",
"@sveltejs/adapter-static": "^2.0.3",
"@sveltejs/kit": "^1.24.0",
"@sveltejs/vite-plugin-svelte": "^2.4.5",
"@testing-library/dom": "^9.0.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "^3.2.2",
"@testing-library/svelte": "^4.0.3",
"@testing-library/user-event": "^14.4.3",
"@types/deep-equal": "^1.0.1",
"@types/prismjs": "^1.26.0",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"@vitest/ui": "^0.29.7",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-svelte3": "^4.0.0",
"jsdom": "^21.1.1",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^2.33.0",
"jsdom": "^22.1.0",
"kleur": "^4.1.5",
"pre-commit": "^1.2.2",
"prettier": "^2.8.6",
"prettier-plugin-svelte": "^2.9.0",
"sass": "^1.59.3",
"svelte": "^3.57.0",
"svelte-check": "^3.1.4",
"prettier": "^3.0.3",
"prettier-plugin-svelte": "^3.0.3",
"sass": "^1.66.1",
"svelte": "^4.2.0",
"svelte-check": "^3.5.1",
"svelte-jester": "^2.3.2",
"svelte-preprocess": "^5.0.3",
"tslib": "^2.5.0",
"typescript": "^5.0.2",
"vite": "^4.2.1",
"svelte-preprocess": "^5.0.4",
"tslib": "^2.6.2",
"typescript": "^5.2.2",
"vite": "^4.4.9",
"vitest": "^0.29.7"
},
"type": "module",
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
+1 -1
View File
@@ -187,7 +187,7 @@ export enum Submit {
FunctionUpdateLogging = 'submit_function_update_logging',
FunctionUpdateTimeout = 'submit_function_update_timeout',
FunctionUpdateEvents = 'submit_function_update_events',
FunctionConnectRepo = 'submit_function_disconnect_repo',
FunctionConnectRepo = 'submit_function_connect_repo',
FunctionDisconnectRepo = 'submit_function_disconnect_repo',
FunctionRedeploy = 'submit_function_redeploy',
DeploymentCreate = 'submit_deployment_create',
+3 -1
View File
@@ -1,6 +1,8 @@
import type { Action } from 'svelte/action';
export type MultiActionArray = Array<(node: HTMLElement) => ReturnType<Action>>;
export type MultiActionArray = Array<
(node: HTMLElement) => ReturnType<Action<HTMLElement, unknown>>
>;
export function multiAction(node: HTMLElement, arr: MultiActionArray) {
const destroyFns = arr.map((fn) => {
+2 -2
View File
@@ -112,7 +112,7 @@
<svelte:window on:mousedown={handleBlur} on:keydown={handleKeydown} />
{#if openSubPanel}
<div class="dialog" bind:this={dialog} transition:fade={{ duration: 100 }}>
<div class="dialog" bind:this={dialog} transition:fade|global={{ duration: 100 }}>
<svelte:component this={openSubPanel.component} />
</div>
{/if}
@@ -120,7 +120,7 @@
{#if dev && debugOverlayEnabled}
<div class="debug-keys" use:portal>
{#each keys as key, i (i)}
<kbd class="kbd" transition:fade|local={{ duration: 150 }}>
<kbd class="kbd" transition:fade={{ duration: 150 }}>
{key.length === 1 ? key.toUpperCase() : key}
</kbd>
{/each}
@@ -9,6 +9,7 @@
import { clearSubPanels, popSubPanel, subPanels } from '../subPanels';
/* eslint no-undef: "off" */
type Option = $$Generic<Omit<Command, 'group'> & { group?: string }>;
export let options: Option[] | null = null;
export let search = '';
@@ -22,6 +22,6 @@ export const collectionsSearcher = (async (query: string) => {
`/console/project-${projectId}/databases/database-${databaseId}/collection-${col.$id}`
);
}
} as const)
}) as const
);
}) satisfies Searcher;
+1 -1
View File
@@ -18,6 +18,6 @@ export const dbSearcher = (async (query: string) => {
goto(`/console/project-${get(project).$id}/databases/database-${db.$id}`);
},
icon: 'database'
} as const)
}) as const
);
}) satisfies Searcher;
+1 -1
View File
@@ -13,7 +13,7 @@ const getTeamCommand = (team: Models.Team<Models.Preferences>, projectId: string
},
group: 'teams',
icon: 'user-circle'
} satisfies Command);
}) satisfies Command;
export const teamSearcher = (async (query: string) => {
const { teams } = await sdk.forProject.teams.list([], query);
+1 -1
View File
@@ -14,7 +14,7 @@ const getUserCommand = (user: Models.User<Models.Preferences>, projectId: string
},
group: 'users',
icon: 'user-circle'
} satisfies Command);
}) satisfies Command;
export const userSearcher = (async (query: string) => {
const { users } = await sdk.forProject.users.list([], query || undefined);
+2 -2
View File
@@ -1,9 +1,9 @@
import type { SvelteComponentDev } from 'svelte/internal';
import type { SvelteComponent } from 'svelte';
import { writable } from 'svelte/store';
export type SubPanel = {
name: string;
component: typeof SvelteComponentDev;
component: typeof SvelteComponent<unknown>;
};
type CastSubPanel = Omit<SubPanel, 'component'> & {
+1
View File
@@ -46,6 +46,7 @@
class:is-allowed-focus={href}
on:click
on:keyup={clickOnEnter}
role={href || isButton ? 'button' : 'generic'}
{href}>
<slot />
</svelte:element>
+7 -1
View File
@@ -64,6 +64,7 @@
class:line-numbers={withLineNumbers}><code>{code}</code></pre>
</section>
<!-- svelte-ignore css-unused-selector -->
<style lang="scss" global>
@import 'prismjs/themes/prism.css';
@import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
@@ -189,7 +190,6 @@
color: #62aed2;
}
}
&.prism-regex,
&.prism-important,
&.prism-variable {
color: #a1c4ff;
@@ -197,5 +197,11 @@
color: #62aed2;
}
}
&.prism-regex {
color: #a1c4ff;
body.theme-light & {
color: #62aed2;
}
}
}
</style>
+7 -1
View File
@@ -7,7 +7,13 @@
<li class="collapsible-item">
<details class="collapsible-wrapper" {open}>
<summary class="collapsible-button" on:keyup={clickOnEnter} on:click>
<!-- svelte-ignore a11y-no-redundant-roles -->
<summary
class="collapsible-button"
on:keyup={clickOnEnter}
on:click
role="button"
tabindex="0">
<slot name="beforetitle" />
<div>
<span class="text"><slot name="title" /></span>
+2
View File
@@ -34,6 +34,8 @@
<span
data-private
role="button"
tabindex="0"
style:cursor="pointer"
on:click|preventDefault={handleClick}
on:keyup={clickOnEnter}
+1
View File
@@ -115,6 +115,7 @@
{/if}
</div>
<!-- svelte-ignore css-unused-selector -->
<style global lang="scss">
.drop-tooltip[data-popper-placement^='top'] > .drop-arrow {
bottom: -4px;
+2 -3
View File
@@ -1,14 +1,13 @@
<script lang="ts">
import { clickOnEnter } from '$lib/helpers/a11y';
export let href: string;
export let icon: string = null;
export let disabled = false;
export let external = false;
</script>
<li class="drop-list-item" on:click on:keyup={clickOnEnter}>
<li class="drop-list-item">
<a
on:click
{href}
class="drop-button"
class:is-disabled={disabled}
+1
View File
@@ -339,6 +339,7 @@
<div {...{ type: 'text' }} style="min-height: 2.5rem;">
{#each eventString as route, i}
<span
role="tooltip"
class:u-opacity-0-5={helper !== route.description}
on:mouseenter={() => (helper = route.description)}
on:mouseleave={() => (helper = null)}>
@@ -1,6 +1,4 @@
<script lang="ts">
import { clickOnEnter } from '$lib/helpers/a11y';
export let value: number = null;
</script>
@@ -9,9 +7,10 @@
<slot />
</legend>
<ul class="u-flex u-main-space-between u-margin-block-start-16">
{#each Array(10) as _, i}
<li on:keyup={clickOnEnter} on:click={() => (value = i)}>
{#each Array(11) as _, i}
<li>
<input
on:click={() => (value = i)}
type="radio"
name="recommend"
class="radio-button"
+1 -1
View File
@@ -6,7 +6,7 @@
</script>
{#if show}
<div class="floating-action-bar" transition:fly|local={{ y: '6rem' }} use:portal>
<div class="floating-action-bar" transition:fly={{ y: '6rem' }} use:portal>
<slot />
</div>
{/if}
+1 -1
View File
@@ -57,7 +57,7 @@
fetchMigrations();
onMount(async () => {
return sdk.forConsole.client.subscribe(['project', 'console'], async (response) => {
sdk.forConsole.client.subscribe(['project', 'console'], async (response) => {
if (response.events.includes('migrations.*')) {
fetchMigrations();
}
@@ -115,6 +115,7 @@
</div>
</div>
<!-- svelte-ignore css-unused-selector -->
<style lang="scss" global>
.tippy-user .tippy-box {
--p-drop-bg-color: var(--color-neutral-500);
+31 -30
View File
@@ -1,6 +1,4 @@
<script lang="ts">
import { clickOnEnter } from '$lib/helpers/a11y';
export let completed = false;
export let current = false;
export let currentSub = 0;
@@ -9,37 +7,40 @@
</script>
<li
on:click|preventDefault
on:keyup|self={clickOnEnter}
class:steps-item={!isSub}
class:steps-sub-item={isSub}
style={`cursor: ${completed ? 'pointer' : 'default'};`}
aria-label={`${completed ? 'done' : current ? 'current' : ''} step`}>
{#if isSub}
<span class="text">{step.text}</span>
{:else}
<div class="steps-item-wrapper">
{#if completed}
<div class="bullet is-done">
<span class="icon-check" aria-hidden="true" />
</div>
{:else}
<div class="bullet" class:is-current={current} />
{/if}
<div class="steps-item-content">
<span class="text">{step.text}</span>
{#if step?.substeps}
<ul class="steps-sub">
{#each step.substeps as subStep, index}
<svelte:self
isSub={true}
step={subStep}
current={currentSub === index}
completed={index < currentSub} />
{/each}
</ul>
<button
type="button"
on:click|preventDefault
disabled={!completed}
style={`cursor: ${completed ? 'pointer' : 'default'};`}>
{#if isSub}
<span class="text">{step.text}</span>
{:else}
<div class="steps-item-wrapper">
{#if completed}
<div class="bullet is-done">
<span class="icon-check" aria-hidden="true" />
</div>
{:else}
<div class="bullet" class:is-current={current} />
{/if}
<div class="steps-item-content">
<span class="text">{step.text}</span>
{#if step?.substeps}
<ul class="steps-sub">
{#each step.substeps as subStep, index}
<svelte:self
isSub={true}
step={subStep}
current={currentSub === index}
completed={index < currentSub} />
{/each}
</ul>
{/if}
</div>
</div>
</div>
{/if}
{/if}
</button>
</li>
+1 -1
View File
@@ -47,7 +47,7 @@
);
}
return columns.subscribe((ctx) => {
columns.subscribe((ctx) => {
const columns = ctx.filter((n) => n.show).map((n) => n.id);
if (isCustomCollection) {
+19 -7
View File
@@ -1,17 +1,29 @@
<script lang="ts">
import { FormItem, Helper, Label } from '.';
interface $$Props extends Partial<HTMLLabelElement> {
id: string;
label?: string;
optionalText?: string;
tooltip?: string;
showLabel?: boolean;
checked?: boolean;
required?: boolean;
disabled?: boolean;
element?: HTMLInputElement | undefined;
indeterminate?: boolean;
}
export let id: string;
export let label: string | undefined = undefined;
export let optionalText: string | undefined = undefined;
export let tooltip: string = null;
export let showLabel = true;
export let id: string;
export let value = false;
export let indeterminate = false;
export let checked = false;
export let required = false;
export let disabled = false;
export let element: HTMLInputElement | undefined = undefined;
let error: string;
const handleInvalid = (event: Event) => {
@@ -23,7 +35,7 @@
error = element.validationMessage;
};
$: if (value) {
$: if (checked) {
error = null;
}
</script>
@@ -40,10 +52,10 @@
{id}
{disabled}
{required}
{indeterminate}
{...$$restProps}
type="checkbox"
bind:this={element}
bind:checked={value}
bind:checked
on:invalid={handleInvalid}
on:click
on:change />
+1
View File
@@ -98,6 +98,7 @@
</Label>
{/if}
<div
role="region"
class="box is-no-shadow u-padding-24"
style="--box-border-radius:var(--border-radius-xsmall); z-index: 1"
class:u-margin-block-start-8={!!label}
@@ -4,6 +4,7 @@
import { createEventDispatcher, onMount } from 'svelte';
import { Label } from '.';
/* eslint no-undef: "off" */
type Option = $$Generic<{
value: string | boolean | number;
label: string;
@@ -128,6 +129,8 @@
<div class="input-text-wrapper" style="--amount-of-buttons:2">
{#if $$slots.output && selectedOption}
<div
role="button"
tabindex="0"
on:keyup={clickOnEnter}
on:click={() => {
if (interactiveOutput) hasFocus = !hasFocus;
+2 -3
View File
@@ -62,7 +62,7 @@
{label}
</Label>
<div class="input-text-wrapper" on:click on:keyup={clickOnEnter}>
<div class="input-text-wrapper" on:click on:keyup={clickOnEnter} role="textbox" tabindex="-1">
<textarea
{id}
{name}
@@ -73,11 +73,10 @@
{maxlength}
class="input-text"
class:u-padding-block-end-32={maxlength}
style={maxlength ? '--amount-of-buttons: 0.25' : ''}
bind:value
bind:this={element}
on:invalid={handleInvalid}
style:--amount-of-buttons={required ? undefined : 0.25} />
style:--amount-of-buttons={maxlength ? 0.25 : required ? undefined : 0.25} />
{#if showTextCounter || showNullCheckbox}
<ul
class="buttons-list u-gap-8 u-cross-center u-position-absolute d u-inset-block-end-1 u-inset-inline-end-1 u-padding-block-8 u-padding-inline-12"
+7 -2
View File
@@ -24,11 +24,16 @@
</script>
<TableCell class="u-position-relative">
<div class="touch-area" on:click={handleClick} on:keypress={handleClick} />
<div
class="touch-area"
role="button"
tabindex="-1"
on:click={handleClick}
on:keypress={handleClick} />
<InputCheckbox
bind:element={el}
id="select-{id}"
value={selectedIds.includes(id)}
checked={selectedIds.includes(id)}
on:click={handleClick} />
</TableCell>
+1 -1
View File
@@ -28,6 +28,6 @@
<InputCheckbox
id="select-all"
indeterminate={someSelected && !allSelected}
value={allSelected}
checked={allSelected}
on:click={handleClick} />
</TableCellHead>
+1 -1
View File
@@ -5,7 +5,7 @@
export let noMargin = false;
let isOverflowing = false;
const hasOverflow: Action<HTMLDivElement> = (node) => {
const hasOverflow: Action<HTMLDivElement, unknown> = (node) => {
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
let overflowing = false;
+2
View File
@@ -26,6 +26,8 @@ export function deepClone<T>(obj: T): T {
export type DeepObj<T> = {
[K in keyof T]: T[K] extends object ? DeepObj<T[K]> : T[K];
};
/* eslint @typescript-eslint/no-explicit-any: 'off' */
export function deepMap<T, U>(
obj: DeepObj<T>,
fn: (value: T, key: string, parentKey?: string) => unknown,
+1 -1
View File
@@ -136,7 +136,7 @@
{#if showDropdown}
<div
class="drop is-no-arrow is-block-end is-inline-end"
transition:slideFade={{ duration: 150 }}>
transition:slideFade|global={{ duration: 150 }}>
{#if $organizationList?.total}
<section class="drop-section u-overflow-y-auto u-max-height-200">
<ul class="drop-list">
+1 -1
View File
@@ -197,7 +197,7 @@
</div>
{#if subNavigation}
<div class="side-nav-level-2 is-open" transition:slide|local={{ axis: 'x', duration: 250 }}>
<div class="side-nav-level-2 is-open" transition:slide={{ axis: 'x', duration: 250 }}>
<div class="side-nav-main">
<svelte:component this={subNavigation} />
</div>
+1 -1
View File
@@ -17,7 +17,7 @@
class:is-warning={type === 'warning'}
class:is-danger={type === 'error'}
class:is-info={type === 'info'}
transition:fly={{ x: 50 }}>
transition:fly|global={{ x: 50 }}>
<button
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
+1 -1
View File
@@ -3,7 +3,7 @@
number,
{
label: string;
component: typeof SvelteComponent;
component: typeof SvelteComponent<unknown>;
optional?: boolean;
}
>;
+3 -2
View File
@@ -24,7 +24,7 @@ export type FeedbackOption = {
type: Feedback['type'];
title: string;
desc: string;
component: typeof SvelteComponent;
component: typeof SvelteComponent<unknown>;
};
export const feedbackOptions: FeedbackOption[] = [
@@ -45,13 +45,14 @@ export const feedbackOptions: FeedbackOption[] = [
export const selectedFeedback = writable<FeedbackOption>();
function createFeedbackDataStore() {
const { subscribe, update } = writable<FeedbackData>({
const { set, subscribe, update } = writable<FeedbackData>({
message: '',
name: '',
email: '',
value: 0
});
return {
set,
subscribe,
update,
reset: () => {
+4 -4
View File
@@ -14,12 +14,12 @@ export type Breadcrumb = {
export type View = 'list' | 'grid';
export type updateLayoutArguments = {
header?: typeof SvelteComponent;
breadcrumb?: typeof SvelteComponent;
header?: typeof SvelteComponent<unknown>;
breadcrumb?: typeof SvelteComponent<unknown>;
};
export const header = writable<typeof SvelteComponent>();
export const breadcrumb = writable<typeof SvelteComponent>();
export const header = writable<typeof SvelteComponent<unknown>>();
export const breadcrumb = writable<typeof SvelteComponent<unknown>>();
export function updateLayout(args: updateLayoutArguments) {
header.set(args.header ?? null);
+1 -1
View File
@@ -15,7 +15,7 @@ export type Provider = Models.Provider & {
key: string;
icon: string;
docs?: string;
component?: typeof SvelteComponent;
component?: typeof SvelteComponent<unknown>;
};
export type Providers = {
+4 -4
View File
@@ -5,8 +5,8 @@ import { writable } from 'svelte/store';
export type WizardStore = {
show: boolean;
media?: string;
component?: typeof SvelteComponent;
cover?: typeof SvelteComponent;
component?: typeof SvelteComponent<unknown>;
cover?: typeof SvelteComponent<unknown>;
interceptor?: () => Promise<void>;
nextDisabled: boolean;
step: number;
@@ -26,7 +26,7 @@ function createWizardStore() {
return {
subscribe,
set,
start: (component: typeof SvelteComponent, media: string = null) =>
start: (component: typeof SvelteComponent<unknown>, media: string = null) =>
update((n) => {
n.show = true;
n.component = component;
@@ -59,7 +59,7 @@ function createWizardStore() {
n.cover = null;
return n;
}),
showCover: (component: typeof SvelteComponent) =>
showCover: (component: typeof SvelteComponent<unknown>) =>
update((n) => {
n.cover = component;
return n;
@@ -35,7 +35,7 @@
function selectComponent(
variableType: 'password' | 'text' | 'number' | 'email' | 'url' | 'phone'
): typeof SvelteComponent {
): typeof SvelteComponent<unknown> {
switch (variableType) {
case 'password':
return InputPassword;
+8 -4
View File
@@ -10,7 +10,6 @@
import { user } from '$lib/stores/user';
import { ENV, isCloud } from '$lib/system';
import * as Sentry from '@sentry/svelte';
import { BrowserTracing } from '@sentry/tracing';
import LogRocket from 'logrocket';
import { onMount } from 'svelte';
import { onCLS, onFCP, onFID, onINP, onLCP, onTTFB } from 'web-vitals';
@@ -45,7 +44,7 @@
*/
Sentry.init({
dsn: 'https://c7ce178bdedd486480317b72f282fd39@o1063647.ingest.sentry.io/4504158071422976',
integrations: [new BrowserTracing()],
integrations: [new Sentry.BrowserTracing()],
tracesSampleRate: 1.0
});
@@ -134,6 +133,7 @@
<Progress />
<!-- svelte-ignore css-unused-selector -->
<style lang="scss" global>
@import '@appwrite.io/pink/src/abstract/variables/_devices.scss';
.tippy-box {
@@ -202,8 +202,12 @@
border-radius: var(--border-radius);
border: var(--border-size) solid transparent;
background: var(--border-gradient) border-box;
mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
-webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
mask:
linear-gradient(#fff 0 0) padding-box,
linear-gradient(#fff 0 0);
-webkit-mask:
linear-gradient(#fff 0 0) padding-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: destination-out;
mask-composite: exclude;
pointer-events: none;
+6 -4
View File
@@ -91,7 +91,7 @@
delay={i === 0 ? [500, 500] : [0, 100]}
x={[0.5, 2]}
y={[0, 1.5]}
amount="30"
amount={30}
fallDistance="50px"
colorArray={confettiColors} />
{/each}
@@ -151,12 +151,12 @@
</div>
<div class="cbc-wrapper">
{#if !cardActive}
<div class="cbc-confetti" transition:fade|local>
<div class="cbc-confetti" transition:fade>
<Confetti
x={[-1.75, 1.85]}
y={[-1.875, 1]}
amount={100}
size="10"
size={10}
infinite
delay={[2000, 7000]}
colorArray={confettiColors}
@@ -174,7 +174,9 @@
on:keydown={() => {
/* no-op */
}}
transition:fade|local />
transition:fade
role="button"
tabindex="0" />
{/if}
<div class="controls" class:invisible={!cardActive}>
<button
@@ -138,9 +138,7 @@
error = true;
}
return () => {
isOpen = false;
};
isOpen = false;
});
$: resources = providerResources[$provider.provider];
+1 -1
View File
@@ -145,7 +145,7 @@
},
group: 'security',
icon: 'pencil'
} as const)
}) as const
),
// Settings
{
@@ -88,7 +88,9 @@
<div
class="input-text-wrapper u-stretch"
on:click={() => (isLimited = true)}
on:keyup|self={clickOnEnter}>
on:keyup|self={clickOnEnter}
role="button"
tabindex="0">
<input
type="number"
name="limit"
@@ -87,6 +87,7 @@
}
// We cast to any to not cause type errors in the input components
/* eslint @typescript-eslint/no-explicit-any: 'off' */
let value: any = null;
$: {
@@ -160,7 +160,7 @@
<SelectSearchItem data={o.data}>
{o.label}
</SelectSearchItem>
<svelte:fragment slot="output">
<svelte:fragment slot="output" let:option={o}>
<output class="input-text" class:is-read-only={editing}>
<SelectSearchItem data={o.data}>
{o.label}
@@ -24,7 +24,7 @@ export type Option = {
| 'URL'
| 'Enum'
| 'Relationship';
component: typeof SvelteComponent;
component: typeof SvelteComponent<unknown>;
type: 'string' | 'integer' | 'double' | 'boolean' | 'datetime' | 'relationship';
create: (
databaseId: string,
@@ -131,7 +131,7 @@
<SelectSearchItem data={o.data}>
{o.label}
</SelectSearchItem>
<svelte:fragment slot="output">
<svelte:fragment slot="output" let:option={o}>
<output class="input-text is-read-only">
<SelectSearchItem data={o.data}>
{o.label}
@@ -173,7 +173,7 @@
<SelectSearchItem data={o.data}>
{o.label}
</SelectSearchItem>
<svelte:fragment slot="output">
<svelte:fragment slot="output" let:option={o}>
<output class="input-text is-read-only">
<SelectSearchItem data={o.data}>
{o.label}
@@ -205,7 +205,7 @@
<SelectSearchItem data={o.data}>
{o.label}
</SelectSearchItem>
<svelte:fragment slot="output">
<svelte:fragment slot="output" let:option={o}>
<output class="input-text is-read-only">
<SelectSearchItem data={o.data}>
{o.label}
@@ -265,7 +265,7 @@
<SelectSearchItem data={o.data}>
{o.label}
</SelectSearchItem>
<svelte:fragment slot="output">
<svelte:fragment slot="output" let:option={o}>
<output class="input-text">
<SelectSearchItem data={o.data}>
{o.label}
@@ -0,0 +1,11 @@
<script lang="ts">
export let indeterminate: boolean = false;
export let checked: boolean = false;
interface $$Props extends Partial<HTMLInputElement> {
indeterminate?: boolean;
checked?: boolean;
}
</script>
<input type="checkbox" bind:checked {...$$restProps} bind:indeterminate on:change />
@@ -4,6 +4,7 @@
import { scopes as allScopes } from '$lib/constants';
import { onMount } from 'svelte';
import { symmetricDifference } from '$lib/helpers/array';
import Checkbox from './checkbox.svelte';
export let scopes: string[];
@@ -48,13 +49,12 @@
}
}
function onCategoryChange(
event: Event & { currentTarget: EventTarget & HTMLInputElement },
category: Category
) {
function onCategoryChange(event: Event, category: Category) {
allScopes.forEach((s) => {
if (s.category === category) {
activeScopes[s.scope] = event.currentTarget.checked;
activeScopes[s.scope] = (
event.currentTarget as EventTarget & HTMLInputElement
).checked;
}
});
}
@@ -91,8 +91,7 @@
{@const checked = categoryState(category, scopes)}
<CollapsibleItem withIndentation>
<svelte:fragment slot="beforetitle">
<input
type="checkbox"
<Checkbox
{checked}
indeterminate={checked === null ? true : false}
on:change={(e) => onCategoryChange(e, category)} />
@@ -22,7 +22,7 @@
import { Dependencies } from '$lib/constants';
import { invalidate } from '$app/navigation';
const types: Record<string, typeof SvelteComponent> = {
const types: Record<string, typeof SvelteComponent<unknown>> = {
web: Web,
android: Android,
'apple-ios': AppleiOs,
@@ -39,7 +39,7 @@
};
onMount(async () => {
return sdk.forConsole.client.subscribe(['project', 'console'], (response) => {
sdk.forConsole.client.subscribe(['project', 'console'], (response) => {
if (response.events.includes('migrations.*')) {
invalidate(Dependencies.MIGRATIONS);
}
@@ -10,7 +10,6 @@
} from '$lib/elements/forms';
import { Container } from '$lib/layout';
import { project } from '../../store';
import { onMount } from 'svelte/internal';
import InputPassword from '$lib/elements/forms/inputPassword.svelte';
import { sdk } from '$lib/stores/sdk';
import { invalidate } from '$app/navigation';
@@ -20,6 +19,7 @@
import InputNumber from '$lib/elements/forms/inputNumber.svelte';
import { base } from '$app/paths';
import deepEqual from 'deep-equal';
import { onMount } from 'svelte';
let enabled = false;
let senderName: string;
+1 -1
View File
@@ -5,7 +5,7 @@
import AppwriteLogoLight from '$lib/images/appwrite-logo-light.svg';
</script>
<div class="load-screen" out:fade>
<div class="load-screen" out:fade|global>
<div class="animation">
<div />
<div />
+9 -9
View File
@@ -35,9 +35,9 @@ test('state', async () => {
const { component, getByLabelText } = render(InputCheckbox, { id: 'input', label: 'checkbox' });
const checkbox = getByLabelText('checkbox');
expect(component.value).toEqual(false);
expect(component.checked).toEqual(false);
await userEvent.click(checkbox);
expect(component.value).toEqual(true);
expect(component.checked).toEqual(true);
});
test('state', async () => {
@@ -45,21 +45,21 @@ test('state', async () => {
const checkbox = getByLabelText('checkbox');
expect(checkbox).not.toBeChecked();
expect(component.value).toStrictEqual(false);
expect(component.checked).toStrictEqual(false);
await fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(component.value).toStrictEqual(true);
expect(component.checked).toStrictEqual(true);
await fireEvent.click(checkbox);
expect(checkbox).not.toBeChecked();
expect(component.value).toStrictEqual(false);
expect(component.checked).toStrictEqual(false);
component.value = true;
component.checked = true;
expect(checkbox).toBeChecked();
expect(component.value).toStrictEqual(true);
expect(component.checked).toStrictEqual(true);
component.value = false;
component.checked = false;
expect(checkbox).not.toBeChecked();
expect(component.value).toStrictEqual(false);
expect(component.checked).toStrictEqual(false);
});