pull from main

This commit is contained in:
shimon
2023-10-04 11:47:03 +03:00
54 changed files with 405 additions and 128 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"]
}
+210 -2
View File
@@ -44,6 +44,7 @@
"@vitest/ui": "^0.29.7",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-svelte": "^2.33.2",
"eslint-plugin-svelte3": "^4.0.0",
"jsdom": "^21.1.1",
"kleur": "^4.1.5",
@@ -3137,6 +3138,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/cssstyle": {
"version": "3.0.0",
"dev": true,
@@ -3613,6 +3626,40 @@
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-plugin-svelte": {
"version": "2.33.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.33.2.tgz",
"integrity": "sha512-knWmauax+E/jvQ9CmuX5dAhQKP9P4eGQZxWa5RMutEJVCcy0wFmiUvOeDND2jR4vUkbDlX4khKjaceY7QzbkYw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@jridgewell/sourcemap-codec": "^1.4.14",
"debug": "^4.3.1",
"esutils": "^2.0.3",
"known-css-properties": "^0.28.0",
"postcss": "^8.4.5",
"postcss-load-config": "^3.1.4",
"postcss-safe-parser": "^6.0.0",
"postcss-selector-parser": "^6.0.11",
"semver": "^7.5.3",
"svelte-eslint-parser": ">=0.33.0 <1.0.0"
},
"engines": {
"node": "^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ota-meshi"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0-0",
"svelte": "^3.37.0 || ^4.0.0"
},
"peerDependenciesMeta": {
"svelte": {
"optional": true
}
}
},
"node_modules/eslint-plugin-svelte3": {
"version": "4.0.0",
"dev": true,
@@ -5695,6 +5742,12 @@
"node": ">=6"
}
},
"node_modules/known-css-properties": {
"version": "0.28.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz",
"integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==",
"dev": true
},
"node_modules/leven": {
"version": "3.1.0",
"dev": true,
@@ -5716,6 +5769,15 @@
"node": ">= 0.8.0"
}
},
"node_modules/lilconfig": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"dev": true,
@@ -6439,7 +6501,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.28",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"funding": [
{
"type": "opencollective",
@@ -6454,7 +6518,6 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
@@ -6464,6 +6527,90 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-load-config": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
"integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
"dev": true,
"dependencies": {
"lilconfig": "^2.0.5",
"yaml": "^1.10.2"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
"peerDependencies": {
"postcss": ">=8.0.9",
"ts-node": ">=9.0.0"
},
"peerDependenciesMeta": {
"postcss": {
"optional": true
},
"ts-node": {
"optional": true
}
}
},
"node_modules/postcss-safe-parser": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
"integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
"dev": true,
"engines": {
"node": ">=12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
"peerDependencies": {
"postcss": "^8.3.3"
}
},
"node_modules/postcss-scss": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz",
"integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss-scss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"engines": {
"node": ">=12.0"
},
"peerDependencies": {
"postcss": "^8.4.29"
}
},
"node_modules/postcss-selector-parser": {
"version": "6.0.13",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
"integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/postcss/node_modules/nanoid": {
"version": "3.3.6",
"funding": [
@@ -7422,6 +7569,58 @@
"version": "1.2.4",
"license": "MIT"
},
"node_modules/svelte-eslint-parser": {
"version": "0.33.0",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.0.tgz",
"integrity": "sha512-5awZ6Bs+Tb/zQwa41PSdcLynAVQTwW0HGyCBjtbAQ59taLZqDgQSMzRlDmapjZdDtzERm0oXDZNE0E+PKJ6ryg==",
"dev": true,
"dependencies": {
"eslint-scope": "^7.0.0",
"eslint-visitor-keys": "^3.0.0",
"espree": "^9.0.0",
"postcss": "^8.4.28",
"postcss-scss": "^4.0.7"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ota-meshi"
},
"peerDependencies": {
"svelte": "^3.37.0 || ^4.0.0"
},
"peerDependenciesMeta": {
"svelte": {
"optional": true
}
}
},
"node_modules/svelte-eslint-parser/node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/svelte-eslint-parser/node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"engines": {
"node": ">=4.0"
}
},
"node_modules/svelte-hmr": {
"version": "0.15.3",
"dev": true,
@@ -8268,6 +8467,15 @@
"license": "ISC",
"peer": true
},
"node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"dev": true,
"engines": {
"node": ">= 6"
}
},
"node_modules/yargs": {
"version": "17.7.2",
"dev": true,
+1
View File
@@ -56,6 +56,7 @@
"@vitest/ui": "^0.29.7",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-svelte": "^2.33.2",
"eslint-plugin-svelte3": "^4.0.0",
"jsdom": "^21.1.1",
"kleur": "^4.1.5",
+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 = '';
+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;
+2 -2
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 {
+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];
@@ -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 = false;
export let checked = 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);
});