mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge branch '1.5.x' of https://github.com/appwrite/console into fix-messaging-smtp-provider
This commit is contained in:
Generated
+4
-4
@@ -6,7 +6,7 @@
|
||||
"": {
|
||||
"name": "@appwrite/console",
|
||||
"dependencies": {
|
||||
"@appwrite.io/console": "^0.6.0-rc.12",
|
||||
"@appwrite.io/console": "^0.6.0-rc.13",
|
||||
"@appwrite.io/pink": "0.4.0",
|
||||
"@appwrite.io/pink-icons": "0.4.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
@@ -158,9 +158,9 @@
|
||||
"integrity": "sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg=="
|
||||
},
|
||||
"node_modules/@appwrite.io/console": {
|
||||
"version": "0.6.0-rc.12",
|
||||
"resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.0-rc.12.tgz",
|
||||
"integrity": "sha512-pDov75TCkBmJdUPrWuzRW7uM28HYqiMFtVFrUoavDd/lMPBS7RnPXL4sBHsGY8AUldHE3oBcGVPkNoQfEAgLlw==",
|
||||
"version": "0.6.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.0-rc.13.tgz",
|
||||
"integrity": "sha512-/c+HGkqdqWjjlzVgOmC6vb4t2jsHgbmX/aaDLoQHXFmaakEDWzK1cgVYRHoU3o14xIEpBupteh3KzOoqdLvvsQ==",
|
||||
"dependencies": {
|
||||
"cross-fetch": "3.1.5",
|
||||
"isomorphic-form-data": "2.0.0"
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
"e2e": "playwright test tests/e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appwrite.io/console": "^0.6.0-rc.12",
|
||||
"@appwrite.io/console": "^0.6.0-rc.13",
|
||||
"@appwrite.io/pink": "0.4.0",
|
||||
"@appwrite.io/pink-icons": "0.4.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { AppwriteException } from '@appwrite.io/console';
|
||||
import type { HandleClientError } from '@sveltejs/kit';
|
||||
|
||||
export const handleError: HandleClientError = async ({ error, message, status }) => {
|
||||
if (error instanceof AppwriteException && error.code === 0) {
|
||||
status = undefined;
|
||||
message = error.message;
|
||||
}
|
||||
return {
|
||||
message,
|
||||
status
|
||||
};
|
||||
};
|
||||
@@ -1,18 +1,39 @@
|
||||
<script lang="ts">
|
||||
export let href: string;
|
||||
export let href: string = null;
|
||||
export let external: boolean = false;
|
||||
</script>
|
||||
|
||||
<li class="clickable-list-item">
|
||||
<a {href} class="clickable-list-button" on:click>
|
||||
{#if $$slots.default}
|
||||
<h5 class="clickable-list-title u-trim-1">
|
||||
<slot />
|
||||
</h5>
|
||||
{/if}
|
||||
{#if $$slots.desc}
|
||||
<div class="clickable-list-desc">
|
||||
<p class="text u-margin-block-start-8"><slot name="desc" /></p>
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
{#if href}
|
||||
<a
|
||||
{href}
|
||||
class="clickable-list-button"
|
||||
target={external ? '_blank' : ''}
|
||||
rel={external ? 'noopener noreferrer' : ''}
|
||||
on:click>
|
||||
{#if $$slots.default}
|
||||
<h5 class="clickable-list-title u-trim-1">
|
||||
<slot />
|
||||
</h5>
|
||||
{/if}
|
||||
{#if $$slots.desc}
|
||||
<div class="clickable-list-desc">
|
||||
<p class="text u-margin-block-start-8"><slot name="desc" /></p>
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
{:else}
|
||||
<button class="clickable-list-button u-width-full-line" on:click>
|
||||
{#if $$slots.default}
|
||||
<h5 class="clickable-list-title u-trim-1">
|
||||
<slot />
|
||||
</h5>
|
||||
{/if}
|
||||
{#if $$slots.desc}
|
||||
<div class="clickable-list-desc">
|
||||
<p class="text u-margin-block-start-8"><slot name="desc" /></p>
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
</li>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</script>
|
||||
|
||||
<li class="collapsible-item">
|
||||
<details class="collapsible-wrapper" {open}>
|
||||
<details class="collapsible-wrapper" bind:open>
|
||||
<!-- svelte-ignore a11y-no-redundant-roles -->
|
||||
<summary
|
||||
class="collapsible-button u-position-relative"
|
||||
@@ -22,7 +22,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="icon">
|
||||
<span class="icon-cheveron-down" aria-hidden="true" />
|
||||
<span class="icon-cheveron-down u-font-size-20" aria-hidden="true" />
|
||||
</div>
|
||||
</summary>
|
||||
<div
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
bind:value={operatorKey} />
|
||||
</ul>
|
||||
{#if column && operator && !operator?.hideInput}
|
||||
<div class="u-margin-block-start-8">
|
||||
<ul class="u-margin-block-start-8">
|
||||
{#if column.type === 'integer' || column.type === 'double'}
|
||||
<InputNumber id="value" bind:value placeholder="Enter value" />
|
||||
{:else if column.type === 'boolean'}
|
||||
@@ -150,7 +150,7 @@
|
||||
{:else}
|
||||
<InputText id="value" bind:value placeholder="Enter value" />
|
||||
{/if}
|
||||
</div>
|
||||
</ul>
|
||||
{/if}
|
||||
<Button text disabled={isDisabled} class="u-margin-block-start-4" submit>
|
||||
<i class="icon-plus" />
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</script>
|
||||
|
||||
<Unauthenticated>
|
||||
<Heading size="1" tag="h3">{$page.status}</Heading>
|
||||
<Heading size="1" tag="h3">{$page.error.status || 'Invalid Argument'}</Heading>
|
||||
<Heading size="3" tag="h4">{$page.error.message}</Heading>
|
||||
<Button href="/">Back to the console</Button>
|
||||
</Unauthenticated>
|
||||
|
||||
@@ -13,9 +13,10 @@ export const ssr = false;
|
||||
export const load: LayoutLoad = async ({ depends, url }) => {
|
||||
depends(Dependencies.ACCOUNT);
|
||||
|
||||
redirectTo.set(url.searchParams.get('forceRedirect') || null);
|
||||
|
||||
url.searchParams.delete('forceRedirect');
|
||||
if (url.searchParams.has('forceRedirect')) {
|
||||
redirectTo.set(url.searchParams.get('forceRedirect') || null);
|
||||
url.searchParams.delete('forceRedirect');
|
||||
}
|
||||
|
||||
try {
|
||||
const account = await sdk.forConsole.account.get<{ organization?: string }>();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Heading size="1" tag="h3">{$page.status}</Heading>
|
||||
<Heading size="1" tag="h3">{$page.error.status || 'Invalid Argument'}</Heading>
|
||||
<Heading size="3" tag="h4">{$page.error.message}</Heading>
|
||||
<Button href="/console">Back to the console</Button>
|
||||
</Container>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { headerAlert } from '$lib/stores/headerAlert';
|
||||
import ProjectsAtRisk from '$lib/components/billing/alerts/projectsAtRisk.svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import { preferences } from '$lib/stores/preferences';
|
||||
import type { Organization } from '$lib/stores/organization';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.ORGANIZATION);
|
||||
@@ -37,7 +38,9 @@ export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
return {
|
||||
header: Header,
|
||||
breadcrumbs: Breadcrumbs,
|
||||
organization: await sdk.forConsole.teams.get(params.organization),
|
||||
organization: await (sdk.forConsole.teams.get(
|
||||
params.organization
|
||||
) as Promise<Organization>),
|
||||
members: await sdk.forConsole.teams.listMemberships(params.organization)
|
||||
};
|
||||
} catch (e) {
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal title="Invite Member" {error} size="big" bind:show={showCreate} onSubmit={create}>
|
||||
<Modal title="Invite member" {error} size="big" bind:show={showCreate} onSubmit={create}>
|
||||
{#if isCloud}
|
||||
<Alert type="info">
|
||||
{#if $organization?.billingPlan === BillingPlan.SCALE}
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Heading size="1" tag="h3">{$page.status}</Heading>
|
||||
<Heading size="1" tag="h3">{$page.error.status || 'Invalid Argument'}</Heading>
|
||||
<p class="body-text-2 u-bold u-margin-block-start-4">{$page.error.message}</p>
|
||||
</Container>
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { LayoutLoad } from './$types';
|
||||
import { preferences } from '$lib/stores/preferences';
|
||||
import { failedInvoice } from '$lib/stores/billing';
|
||||
import { isCloud } from '$lib/system';
|
||||
import type { Organization } from '$lib/stores/organization';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.PROJECT);
|
||||
@@ -22,7 +23,7 @@ export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
|
||||
return {
|
||||
project,
|
||||
organization: await sdk.forConsole.teams.get(project.teamId)
|
||||
organization: await (sdk.forConsole.teams.get(project.teamId) as Promise<Organization>)
|
||||
};
|
||||
} catch (e) {
|
||||
error(e.code, e.message);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<CardGrid>
|
||||
<CardGrid hideFooter={$message.status != 'failed'}>
|
||||
<div class="grid-1-2-col-1 u-flex u-cross-center u-gap-16" data-private>
|
||||
<ProviderType type={$message.providerType} size="l">
|
||||
<Heading tag="h6" size="7">{providerType}</Heading>
|
||||
@@ -51,15 +51,13 @@
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="actions">
|
||||
{#if $message.status === 'failed'}
|
||||
<Button
|
||||
secondary
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
errors = $message.deliveryErrors;
|
||||
showFailed = true;
|
||||
}}>View logs</Button>
|
||||
{/if}
|
||||
<Button
|
||||
secondary
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
errors = $message.deliveryErrors;
|
||||
showFailed = true;
|
||||
}}>View logs</Button>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
$providerParams[$provider].authKeyId,
|
||||
$providerParams[$provider].teamId,
|
||||
$providerParams[$provider].bundleId,
|
||||
$providerParams[$provider].sandbox,
|
||||
$providerParams[$provider].enabled
|
||||
);
|
||||
break;
|
||||
|
||||
+2
-2
@@ -69,13 +69,13 @@
|
||||
);
|
||||
break;
|
||||
case Providers.FCM:
|
||||
response = await sdk.forProject.messaging.updateFCMProvider(
|
||||
response = await sdk.forProject.messaging.updateFcmProvider(
|
||||
providerId,
|
||||
providerName
|
||||
);
|
||||
break;
|
||||
case Providers.APNS:
|
||||
response = await sdk.forProject.messaging.updateAPNSProvider(
|
||||
response = await sdk.forProject.messaging.updateApnsProvider(
|
||||
providerId,
|
||||
providerName
|
||||
);
|
||||
|
||||
+2
-2
@@ -160,7 +160,7 @@
|
||||
);
|
||||
break;
|
||||
case Providers.FCM:
|
||||
response = await sdk.forProject.messaging.updateFCMProvider(
|
||||
response = await sdk.forProject.messaging.updateFcmProvider(
|
||||
providerId,
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -168,7 +168,7 @@
|
||||
);
|
||||
break;
|
||||
case Providers.APNS:
|
||||
response = await sdk.forProject.messaging.updateAPNSProvider(
|
||||
response = await sdk.forProject.messaging.updateApnsProvider(
|
||||
providerId,
|
||||
undefined,
|
||||
undefined,
|
||||
|
||||
+2
-2
@@ -94,14 +94,14 @@
|
||||
);
|
||||
break;
|
||||
case Providers.FCM:
|
||||
response = await sdk.forProject.messaging.updateFCMProvider(
|
||||
response = await sdk.forProject.messaging.updateFcmProvider(
|
||||
providerId,
|
||||
undefined,
|
||||
enabled
|
||||
);
|
||||
break;
|
||||
case Providers.APNS:
|
||||
response = await sdk.forProject.messaging.updateAPNSProvider(
|
||||
response = await sdk.forProject.messaging.updateApnsProvider(
|
||||
providerId,
|
||||
undefined,
|
||||
enabled
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Column } from '$lib/helpers/types';
|
||||
import { writable } from 'svelte/store';
|
||||
import { Providers } from '../provider.svelte';
|
||||
import { MessagingProviderType, Encryption } from '@appwrite.io/console';
|
||||
import { MessagingProviderType, SmtpEncryption } from '@appwrite.io/console';
|
||||
|
||||
export const columns = writable<Column[]>([
|
||||
{ id: '$id', title: 'Provider ID', type: 'string', show: true },
|
||||
@@ -162,6 +162,12 @@ export const providers: ProvidersMap = {
|
||||
},
|
||||
alt: 'Screenshot of where to download the Authentication Key in the Apple Developer Member Center'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Sandbox',
|
||||
name: 'sandbox',
|
||||
type: 'switch',
|
||||
description: 'Use the development APNS server.'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -348,9 +354,9 @@ export const providers: ProvidersMap = {
|
||||
name: 'encryption',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'None', value: Encryption.None },
|
||||
{ label: 'SSL', value: Encryption.Ssl },
|
||||
{ label: 'TLS', value: Encryption.Tls }
|
||||
{ label: 'None', value: SmtpEncryption.None },
|
||||
{ label: 'SSL', value: SmtpEncryption.Ssl },
|
||||
{ label: 'TLS', value: SmtpEncryption.Tls }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -559,7 +565,6 @@ type ProviderParams = {
|
||||
/**
|
||||
* SMS providers
|
||||
*/
|
||||
|
||||
export type TwilioProviderParams = ProviderParams & {
|
||||
accountSid: string;
|
||||
authToken: string;
|
||||
@@ -593,7 +598,6 @@ export type VonageProviderParams = ProviderParams & {
|
||||
/**
|
||||
* Email providers
|
||||
*/
|
||||
|
||||
export type MailgunProviderParams = ProviderParams & {
|
||||
fromEmail: string;
|
||||
fromName: string;
|
||||
@@ -621,7 +625,7 @@ export type SMTPProviderParams = ProviderParams & {
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
encryption: Encryption;
|
||||
encryption: SmtpEncryption;
|
||||
autoTLS: boolean;
|
||||
mailer: string;
|
||||
};
|
||||
@@ -629,7 +633,6 @@ export type SMTPProviderParams = ProviderParams & {
|
||||
/**
|
||||
* Push providers
|
||||
*/
|
||||
|
||||
export type FCMProviderParams = ProviderParams & {
|
||||
serviceAccountJSON: string;
|
||||
};
|
||||
@@ -639,6 +642,7 @@ export type APNSProviderParams = ProviderParams & {
|
||||
authKeyId: string;
|
||||
teamId: string;
|
||||
bundleId: string;
|
||||
sandbox: boolean;
|
||||
};
|
||||
|
||||
export type MQTTProviderParams = ProviderParams & {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { FormList, InputText } from '$lib/elements/forms';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { Providers } from '../../provider.svelte';
|
||||
import { Encryption } from '@appwrite.io/console';
|
||||
import { SmtpEncryption } from '@appwrite.io/console';
|
||||
|
||||
let name = '';
|
||||
let showCustomId = false;
|
||||
@@ -100,7 +100,7 @@
|
||||
username: '',
|
||||
password: '',
|
||||
autoTLS: true,
|
||||
encryption: Encryption.Tls,
|
||||
encryption: SmtpEncryption.Tls,
|
||||
mailer: '',
|
||||
fromEmail: '',
|
||||
fromName: '',
|
||||
@@ -124,7 +124,8 @@
|
||||
authKey: '',
|
||||
authKeyId: '',
|
||||
teamId: '',
|
||||
bundleId: ''
|
||||
bundleId: '',
|
||||
sandbox: false
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4,17 +4,21 @@
|
||||
import { providers } from '../store';
|
||||
import { providerType, provider, providerParams } from './store';
|
||||
import SettingsFormList from '../settingsFormList.svelte';
|
||||
import { Table, TableBody, TableCell, TableRowButton, TableRowLink } from '$lib/elements/table';
|
||||
import { newMemberModal } from '$lib/stores/organization';
|
||||
import CreateMember from '$routes/console/organization-[organization]/createMember.svelte';
|
||||
import Collapsible from '$lib/components/collapsible.svelte';
|
||||
import CollapsibleItem from '$lib/components/collapsibleItem.svelte';
|
||||
import Provider from '../../provider.svelte';
|
||||
import { MessagingProviderType } from '@appwrite.io/console';
|
||||
import ProviderTypeComponent from '$routes/console/project-[project]/messaging/providerType.svelte';
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleItem,
|
||||
ClickableList,
|
||||
ClickableListItem
|
||||
} from '$lib/components';
|
||||
|
||||
let files: Record<string, FileList> = {};
|
||||
const inputs = providers[$providerType].providers[$provider].configure;
|
||||
let open = false;
|
||||
|
||||
onMount(() => {
|
||||
for (const input of inputs) {
|
||||
@@ -55,81 +59,115 @@
|
||||
<div class="need-a-hand u-flex-vertical u-gap-8">
|
||||
<p class="body-text-2 u-bold u-margin-block-start-48">Need a hand?</p>
|
||||
|
||||
{#if providers[$providerType].providers[$provider].needAHand}
|
||||
{@const needAHand = providers[$providerType].providers[$provider].needAHand}
|
||||
<div class="box u-padding-inline-8 u-padding-0 u-border-width-0">
|
||||
<Collapsible>
|
||||
<CollapsibleItem withIndentation>
|
||||
<svelte:fragment slot="beforetitle">
|
||||
<div class="u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-size-small">
|
||||
<span
|
||||
class="icon-info"
|
||||
style:--p-text-size="1.25rem"
|
||||
aria-hidden="true" />
|
||||
<div>
|
||||
{#if providers[$providerType].providers[$provider].needAHand}
|
||||
{@const needAHand = providers[$providerType].providers[$provider].needAHand}
|
||||
<div
|
||||
class="how-to-enable u-padding-inline-8 u-padding-0"
|
||||
style={!open ? '' : 'background-color: hsl(var(--p-bg-color-hover));'}>
|
||||
<Collapsible>
|
||||
<CollapsibleItem withIndentation bind:open>
|
||||
<svelte:fragment slot="beforetitle">
|
||||
<div class="u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-size-small">
|
||||
<span
|
||||
class="icon-info"
|
||||
style:--p-text-size="1.25rem"
|
||||
aria-hidden="true" />
|
||||
</div>
|
||||
<span class="title body-text-2 u-small" class:u-bold={open}
|
||||
>How to enable <Provider provider={$provider} noIcon />
|
||||
{#if $providerType == MessagingProviderType.Push}notifications{:else}<ProviderTypeComponent
|
||||
type={$providerType}
|
||||
noIcon />{/if} service?</span>
|
||||
</div>
|
||||
<span class="body-text-2 u-small u-bold"
|
||||
>How to enable <Provider provider={$provider} noIcon />
|
||||
{#if $providerType == MessagingProviderType.Push}notifications{:else}<ProviderTypeComponent
|
||||
type={$providerType}
|
||||
noIcon />{/if} service?</span>
|
||||
</svelte:fragment>
|
||||
<div class="u-flex-vertical u-gap-16">
|
||||
{#each needAHand as p}
|
||||
<p>
|
||||
{@html p}
|
||||
</p>
|
||||
{/each}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<div class="u-flex-vertical u-gap-16">
|
||||
{#each needAHand as p}
|
||||
<p>
|
||||
{@html p}
|
||||
</p>
|
||||
{/each}
|
||||
</div>
|
||||
</CollapsibleItem>
|
||||
</Collapsible>
|
||||
</div>
|
||||
{/if}
|
||||
</CollapsibleItem>
|
||||
</Collapsible>
|
||||
</div>
|
||||
<div class="u-margin-block-start-4 u-sep-block-end" />
|
||||
{/if}
|
||||
|
||||
<Table noMargin noStyles>
|
||||
<TableBody>
|
||||
<TableRowLink href={`https://appwrite.io/docs/messaging/${$provider}`}>
|
||||
<TableCell>
|
||||
<div class="u-flex u-cross-center u-main-space-between u-padding-8">
|
||||
<div class="u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-size-small">
|
||||
<span
|
||||
class="icon-book-open"
|
||||
style:--p-text-size="1.25rem"
|
||||
aria-hidden="true" />
|
||||
</div>
|
||||
Read the full guide in the documentation
|
||||
<ClickableList>
|
||||
<ClickableListItem
|
||||
href={`https://appwrite.io/docs/messaging/${$provider}`}
|
||||
external>
|
||||
<div class="u-flex u-cross-center u-main-space-between">
|
||||
<div class="u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-size-small">
|
||||
<span
|
||||
class="icon-book-open"
|
||||
style:--p-text-size="1.25rem"
|
||||
aria-hidden="true" />
|
||||
</div>
|
||||
<span class="icon-arrow-right" aria-hidden="true" />
|
||||
<p>Read the full guide in the documentation</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRowLink>
|
||||
<TableRowButton on:click={() => ($newMemberModal = true)}>
|
||||
<TableCell>
|
||||
<div class="u-flex u-cross-center u-main-space-between u-padding-8">
|
||||
<div class="u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-size-small">
|
||||
<span
|
||||
class="icon-user-group"
|
||||
style:--p-text-size="1.25rem"
|
||||
aria-hidden="true" />
|
||||
</div>
|
||||
Invite a team member to complete this step
|
||||
<span class="icon-arrow-sm-right u-font-size-20" aria-hidden="true" />
|
||||
</div>
|
||||
</ClickableListItem>
|
||||
<ClickableListItem on:click={() => ($newMemberModal = true)}>
|
||||
<div class="u-flex u-cross-center u-main-space-between">
|
||||
<div class="u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-size-small">
|
||||
<span
|
||||
class="icon-user-group"
|
||||
style:--p-text-size="1.25rem"
|
||||
aria-hidden="true" />
|
||||
</div>
|
||||
<span class="icon-arrow-right" aria-hidden="true" />
|
||||
<p>Invite a team member to complete this step</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRowButton>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<span class="icon-arrow-sm-right u-font-size-20" aria-hidden="true" />
|
||||
</div>
|
||||
</ClickableListItem>
|
||||
</ClickableList>
|
||||
</div>
|
||||
</div>
|
||||
</WizardStep>
|
||||
|
||||
<CreateMember bind:showCreate={$newMemberModal} />
|
||||
|
||||
<style lang="scss">
|
||||
.need-a-hand :global(.table-row):last-child:last-child {
|
||||
border-block-end: none;
|
||||
.need-a-hand {
|
||||
--p-bg-color-hover: var(--color-neutral-10);
|
||||
.how-to-enable {
|
||||
border-radius: var(--border-radius-small);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: hsl(var(--p-bg-color-hover));
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global(.clickable-list) {
|
||||
--color-border: var(--color-neutral-10);
|
||||
|
||||
:global(.theme-dark) & {
|
||||
--color-border: var(--color-neutral-85);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.clickable-list-button) {
|
||||
padding-inline: 0.5rem;
|
||||
}
|
||||
|
||||
:global(.theme-dark) & {
|
||||
--p-bg-color-hover: var(--color-neutral-85);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.clickable-list-button):hover p,
|
||||
:global(.clickable-list-button):focus p {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,16 +2,16 @@ import type { MessagingProviderType } from '@appwrite.io/console';
|
||||
import { writable } from 'svelte/store';
|
||||
import type { Providers } from '../../provider.svelte';
|
||||
import type {
|
||||
TwilioProviderParams,
|
||||
APNSProviderParams,
|
||||
FCMProviderParams,
|
||||
MailgunProviderParams,
|
||||
Msg91ProviderParams,
|
||||
SMTPProviderParams,
|
||||
SendgridProviderParams,
|
||||
TelesignProviderParams,
|
||||
TextmagicProviderParams,
|
||||
VonageProviderParams,
|
||||
MailgunProviderParams,
|
||||
SendgridProviderParams,
|
||||
SMTPProviderParams,
|
||||
FCMProviderParams,
|
||||
APNSProviderParams
|
||||
TwilioProviderParams,
|
||||
VonageProviderParams
|
||||
} from '../store';
|
||||
|
||||
export const providerType = writable<MessagingProviderType>(null);
|
||||
|
||||
+8
-3
@@ -46,9 +46,14 @@
|
||||
const targetIds = Object.keys($targetsById).filter(
|
||||
(targetId) => !(targetId in subscribersByTargetId)
|
||||
);
|
||||
const promises = targetIds.map((targetId) =>
|
||||
sdk.forProject.messaging.createSubscriber($page.params.topic, ID.unique(), targetId)
|
||||
);
|
||||
const promises = targetIds.map(async (targetId) => {
|
||||
const subscriber = await sdk.forProject.messaging.createSubscriber(
|
||||
$page.params.topic,
|
||||
ID.unique(),
|
||||
targetId
|
||||
);
|
||||
subscribersByTargetId[targetId] = subscriber;
|
||||
});
|
||||
|
||||
try {
|
||||
await Promise.all(promises);
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<span
|
||||
class="collapsible-button-optional"
|
||||
style="--p-toggle-optional-color: var(--color-neutral-50);">
|
||||
({getTotal(topic)} subscribers)
|
||||
({getTotal(topic)} targets)
|
||||
</span>
|
||||
</span></span>
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
import type { Aggregation, Invoice } from '$lib/sdk/billing';
|
||||
import { accumulateUsage } from '$lib/sdk/usage';
|
||||
import { getSdkForProject, sdk } from '$lib/stores/sdk';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
import type { PageLoad } from './$types';
|
||||
import type { Organization } from '$lib/stores/organization';
|
||||
import type { Aggregation, Invoice } from '$lib/sdk/billing';
|
||||
import { accumulateUsage } from '$lib/sdk/usage';
|
||||
|
||||
export const load: PageLoad = async ({ params, parent }) => {
|
||||
const { invoice, project } = params;
|
||||
const parentData = await parent();
|
||||
const org = parentData.organization as Organization;
|
||||
const { organization } = await parent();
|
||||
|
||||
let startDate: string = org.billingCurrentInvoiceDate;
|
||||
let endDate: string = org.billingNextInvoiceDate;
|
||||
let startDate: string = organization.billingCurrentInvoiceDate;
|
||||
let endDate: string = organization.billingNextInvoiceDate;
|
||||
let currentInvoice: Invoice = undefined;
|
||||
let currentAggregation: Aggregation = undefined;
|
||||
|
||||
if (invoice) {
|
||||
currentInvoice = await sdk.forConsole.billing.getInvoice(org.$id, invoice);
|
||||
currentInvoice = await sdk.forConsole.billing.getInvoice(organization.$id, invoice);
|
||||
currentAggregation = await sdk.forConsole.billing.getAggregation(
|
||||
org.$id,
|
||||
organization.$id,
|
||||
currentInvoice.aggregationId
|
||||
);
|
||||
|
||||
@@ -27,7 +25,7 @@ export const load: PageLoad = async ({ params, parent }) => {
|
||||
}
|
||||
|
||||
const [invoices, usage] = await Promise.all([
|
||||
sdk.forConsole.billing.listInvoices(org.$id, [Query.orderDesc('from')]),
|
||||
sdk.forConsole.billing.listInvoices(organization.$id, [Query.orderDesc('from')]),
|
||||
/**
|
||||
* Workaround because project id might not be populated yet.
|
||||
*/
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
OAuthProvider.Github,
|
||||
window.location.origin + url,
|
||||
window.location.origin,
|
||||
undefined,
|
||||
['read:user', 'user:email']
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
async function verify() {
|
||||
try {
|
||||
disabled = true;
|
||||
const challenge = await sdk.forConsole.account.create2FAChallenge(
|
||||
const challenge = await sdk.forConsole.account.createChallenge(
|
||||
AuthenticationFactor.Totp
|
||||
);
|
||||
await sdk.forConsole.account.updateChallenge(challenge.$id, code);
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
OAuthProvider.Github,
|
||||
window.location.origin,
|
||||
window.location.origin,
|
||||
undefined,
|
||||
['read:user', 'user:email']
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user