mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge branch 'main' into notification-modals.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
export let tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
||||
export let size: Size;
|
||||
export let trimmed = true;
|
||||
export let trimmedSecondLine = false;
|
||||
export let id: string = null;
|
||||
let classes = '';
|
||||
export { classes as class };
|
||||
@@ -15,6 +16,7 @@
|
||||
this={tag}
|
||||
class={`heading-level-${size} u-min-width-0 ${classes}`}
|
||||
class:u-trim-1={trimmed}
|
||||
class:u-trim-2={trimmedSecondLine}
|
||||
{style}
|
||||
{id}>
|
||||
<slot />
|
||||
|
||||
@@ -56,7 +56,7 @@ export { default as PaginationWithLimit } from './paginationWithLimit.svelte';
|
||||
export { default as ClickableList } from './clickableList.svelte';
|
||||
export { default as ClickableListItem } from './clickableListItem.svelte';
|
||||
export { default as Id } from './id.svelte';
|
||||
export { default as ProgressBar } from './progressBar.svelte';
|
||||
export * from './progressbar';
|
||||
export { default as ProgressBarBig } from './progressBarBig.svelte';
|
||||
export { default as CreditCardInfo } from './creditCardInfo.svelte';
|
||||
export { default as CreditCardBrandImage } from './creditCardBrandImage.svelte';
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script context="module" lang="ts">
|
||||
let inputDigitFields: InputDigits;
|
||||
|
||||
export async function verify(challenge: Models.MfaChallenge, code: string) {
|
||||
try {
|
||||
if (challenge == null) {
|
||||
@@ -10,6 +12,7 @@
|
||||
await invalidate(Dependencies.ACCOUNT);
|
||||
trackEvent(Submit.AccountCreate);
|
||||
} catch (error) {
|
||||
inputDigitFields?.clearInputsAndRefocus();
|
||||
trackError(error, Submit.AccountCreate);
|
||||
throw error;
|
||||
}
|
||||
@@ -81,7 +84,12 @@
|
||||
{:else if challengeType == AuthenticationFactor.Phone}
|
||||
<p>A 6-digit verification code was sent to your phone, enter it below.</p>
|
||||
{/if}
|
||||
<InputDigits bind:value={code} required autofocus {autoSubmit} />
|
||||
<InputDigits
|
||||
bind:value={code}
|
||||
required
|
||||
autofocus
|
||||
{autoSubmit}
|
||||
bind:this={inputDigitFields} />
|
||||
{/if}
|
||||
{#if showVerifyButton}
|
||||
<FormItem>
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
<script lang="ts">
|
||||
export let currentValue: string;
|
||||
export let currentUnit: string;
|
||||
export let maxValue: string;
|
||||
export let maxUnit: string;
|
||||
import { ProgressBar, type ProgressbarData } from '$lib/components/progressbar';
|
||||
|
||||
export let currentValue: string | undefined = undefined;
|
||||
export let currentUnit: string | undefined = undefined;
|
||||
export let maxValue: string | undefined = undefined;
|
||||
export let maxUnit: string | undefined = undefined;
|
||||
export let progressValue: number;
|
||||
export let progressMax: number;
|
||||
export let showBar = true;
|
||||
export let minimum = 0;
|
||||
export let maximum = 100;
|
||||
export let progressBarData: Array<ProgressbarData> = [];
|
||||
|
||||
$: progress = Math.round((progressValue / progressMax) * 100);
|
||||
</script>
|
||||
|
||||
<section class="progress-bar">
|
||||
<div class="u-flex u-flex-vertical">
|
||||
<div class="u-flex u-main-space-between">
|
||||
<p>
|
||||
<span class="heading-level-4">{currentValue}</span>
|
||||
<span class="body-text-1 u-bold">{currentUnit}</span>
|
||||
{#if currentValue !== undefined && currentUnit !== undefined && progress !== undefined && maxValue !== undefined && maxUnit !== undefined}
|
||||
<div class="u-flex u-flex-vertical">
|
||||
<div class="u-flex u-main-space-between">
|
||||
<p>
|
||||
<span class="heading-level-4">{currentValue}</span>
|
||||
<span class="body-text-1 u-bold">{currentUnit}</span>
|
||||
</p>
|
||||
<p class="heading-level-4">{progress}%</p>
|
||||
</div>
|
||||
|
||||
<p class="body-text-2">
|
||||
{maxValue}
|
||||
{maxUnit}
|
||||
</p>
|
||||
<p class="heading-level-4">{progress}%</p>
|
||||
</div>
|
||||
<p class="body-text-2">
|
||||
{maxValue}
|
||||
{maxUnit}
|
||||
</p>
|
||||
</div>
|
||||
{#if showBar}
|
||||
<div
|
||||
class="progress-bar-container u-margin-block-start-16"
|
||||
class:is-warning={progress >= 75 && progress < 100}
|
||||
class:is-danger={progress >= 100}
|
||||
style:--graph-size={Math.max(Math.min(progress, maximum), minimum) + '%'} />
|
||||
{/if}
|
||||
{#if showBar && progressBarData.length > 0}
|
||||
<ProgressBar maxSize={progressMax} data={progressBarData} />
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<script lang="ts">
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import type { ProgressbarData, ProgressbarProps } from '$lib/components';
|
||||
|
||||
type $$Props = ProgressbarProps;
|
||||
|
||||
/**
|
||||
* The max value of the progressbar
|
||||
*/
|
||||
export let maxSize: $$Props['maxSize'];
|
||||
|
||||
/**
|
||||
* The data for the progressbar
|
||||
*/
|
||||
export let data: $$Props['data'];
|
||||
|
||||
/**
|
||||
* The remaining value of the progressbar
|
||||
*/
|
||||
$: remainder = data.reduce((sum: number, item: ProgressbarData) => sum - item.size, maxSize);
|
||||
</script>
|
||||
|
||||
<section class="progressbar__container">
|
||||
{#each $$props.data as item}
|
||||
<div
|
||||
class="progressbar__content"
|
||||
style:background-color={item.color}
|
||||
style:width={`${(item.size / maxSize) * 100}%`}
|
||||
use:tooltip={{
|
||||
disabled: !item.tooltip,
|
||||
allowHTML: true,
|
||||
content: `<span class="u-bold">${item.tooltip.title}</span> ${item.tooltip.label}`
|
||||
}}>
|
||||
</div>
|
||||
{/each}
|
||||
{#if remainder > 0}
|
||||
<div class="progressbar__content" style:width={`${(remainder / maxSize) * 100}%`} />
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
:root {
|
||||
--progressbar-border-radius: 0.25rem;
|
||||
--progressbar-tooltip-label-color: #818186;
|
||||
--progressbar-tooltip-link-color: #6c6c71;
|
||||
}
|
||||
|
||||
:global(.theme-dark) {
|
||||
--progressbar-background-color: var(--neutral-800, #2d2d31);
|
||||
--progressbar-tooltip-background-color: var(--neutral-800, #2d2d31);
|
||||
--progressbar-tooltip-border-color: var(--neutral-80, #424248);
|
||||
}
|
||||
:global(.theme-light) {
|
||||
--progressbar-background-color: var(--neutral-40, #f4f4f7);
|
||||
--progressbar-tooltip-background-color: #ffffff;
|
||||
--progressbar-tooltip-border-color: #ededf0;
|
||||
}
|
||||
|
||||
.progressbar {
|
||||
&__container {
|
||||
height: 0.5rem;
|
||||
background-color: var(--progressbar-background-color);
|
||||
border-radius: var(--progressbar-border-radius);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
height: 100%;
|
||||
min-width: 4px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
height: 2.5rem;
|
||||
margin-top: -1.25rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: var(--progressbar-border-radius);
|
||||
border-bottom-left-radius: var(--progressbar-border-radius);
|
||||
}
|
||||
&:last-child {
|
||||
border-top-right-radius: var(--progressbar-border-radius);
|
||||
border-bottom-right-radius: var(--progressbar-border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
export type ProgressbarData = {
|
||||
size: number;
|
||||
color: string;
|
||||
tooltip?: {
|
||||
title: string;
|
||||
label: string;
|
||||
// linkTitle?: string;
|
||||
// linkPath?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type ProgressbarProps = {
|
||||
maxSize: number;
|
||||
data: Array<ProgressbarData>;
|
||||
};
|
||||
|
||||
export { default as ProgressBar } from './ProgressBar.svelte';
|
||||
@@ -38,6 +38,21 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Clears the input fields and moves the focus to the first input.
|
||||
* Usually used when resetting fields on auth fails, etc.
|
||||
*/
|
||||
export function clearInputsAndRefocus() {
|
||||
value = '';
|
||||
autoSubmitted = false;
|
||||
|
||||
if (element) {
|
||||
const inputs = element.querySelectorAll('input');
|
||||
inputs.forEach((input) => (input.value = ''));
|
||||
if (autofocus) inputs[0].focus();
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const interval = setInterval(() => {
|
||||
const input = element.querySelector('input');
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
<script>
|
||||
import { settings } from '$lib/components/consent.svelte';
|
||||
import { clickOnEnter } from '$lib/helpers/a11y';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { version } from '$routes/(console)/store';
|
||||
|
||||
|
||||
@@ -178,6 +178,9 @@ export type OrganizationUsage = {
|
||||
bandwidth: Array<Models.Metric>;
|
||||
executions: Array<Models.Metric>;
|
||||
executionsTotal: number;
|
||||
filesStorageTotal: number;
|
||||
buildsStorageTotal: number;
|
||||
deploymentsStorageTotal: number;
|
||||
storageTotal: number;
|
||||
users: Array<Models.Metric>;
|
||||
usersTotal: number;
|
||||
|
||||
@@ -138,6 +138,24 @@ campaigns
|
||||
description:
|
||||
'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan'
|
||||
})
|
||||
.set('NetNinja', {
|
||||
template: 'card',
|
||||
title: 'Claim your $50 Net Ninja credits.',
|
||||
description:
|
||||
'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan'
|
||||
})
|
||||
.set('CodeWithAntonio', {
|
||||
template: 'card',
|
||||
title: 'Claim your $50 Code With Antonio credits.',
|
||||
description:
|
||||
'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan'
|
||||
})
|
||||
.set('Hacktoberfest2024', {
|
||||
template: 'card',
|
||||
title: 'Claim your $60 Hacktobefest credits.',
|
||||
description:
|
||||
'Get $60 in Cloud credits when you upgrade or create an organization with a Pro plan'
|
||||
})
|
||||
.set('VueJS', {
|
||||
template: 'card',
|
||||
title: 'Claim your $50 VueJS credits.',
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
}} />
|
||||
</p>
|
||||
<p class="text u-margin-block-start-4">
|
||||
This could include unauthorized users and search engines.
|
||||
This could include unauthorized users and bots.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user