mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: more plan limits
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { Buttons } from '../stores/notifications';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
|
||||
export let dismissible = false;
|
||||
export let type: 'info' | 'success' | 'warning' | 'error' | 'default' = 'info';
|
||||
@@ -53,12 +54,9 @@
|
||||
<div class="alert-buttons u-flex">
|
||||
<slot name="buttons">
|
||||
{#each buttons as button}
|
||||
<button
|
||||
type="button"
|
||||
class="button is-text"
|
||||
on:click={button.method}>
|
||||
<Button text on:click={button.method}>
|
||||
<span class="text">{button.name}</span>
|
||||
</button>
|
||||
</Button>
|
||||
{/each}
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
AvatarInitials,
|
||||
EmptySearch,
|
||||
Heading,
|
||||
PaginationWithLimit,
|
||||
Trim
|
||||
} from '$lib/components';
|
||||
import { AvatarInitials, EmptySearch, PaginationWithLimit, Trim } from '$lib/components';
|
||||
import {
|
||||
TableBody,
|
||||
TableHeader,
|
||||
@@ -15,17 +9,19 @@
|
||||
TableCellText,
|
||||
TableScroll
|
||||
} from '$lib/elements/table';
|
||||
import { Container } from '$lib/layout';
|
||||
import { Container, ContainerHeader } from '$lib/layout';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
|
||||
export let logs: Models.LogList;
|
||||
export let offset = 0;
|
||||
export let limit = 0;
|
||||
|
||||
// TODO: add limit for activity
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Heading tag="h2" size="5">Activity</Heading>
|
||||
<ContainerHeader title="Activity" alertType="info" />
|
||||
{#if logs.total}
|
||||
<TableScroll>
|
||||
<TableHeader>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { tierToPlan, type Tier, getServiceLimit } from '$lib/stores/billing';
|
||||
import { tierToPlan, getServiceLimit } from '$lib/stores/billing';
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import { Alert, Heading } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
@@ -16,6 +16,7 @@
|
||||
export let titleSize: '1' | '2' | '3' | '4' | '5' | '6' | '7' = '5';
|
||||
export let serviceId = title.toLocaleLowerCase();
|
||||
export let total: number = null;
|
||||
export let alertType: 'info' | 'success' | 'warning' | 'error' | 'default' = 'warning';
|
||||
|
||||
export let buttonText: string = null;
|
||||
export let buttonMethod: () => void = null;
|
||||
@@ -25,19 +26,17 @@
|
||||
let tooltipContent: HTMLDivElement;
|
||||
|
||||
const limit = getServiceLimit(serviceId) || Infinity;
|
||||
const upgradeMethod = () => wizard.start(ChangeOrganizationTierCloud);
|
||||
|
||||
$: tier = tierToPlan($organization?.billingPlan as Tier)?.name;
|
||||
$: tier = tierToPlan($organization?.billingPlan)?.name;
|
||||
</script>
|
||||
|
||||
{#if isCloud && total && limit !== 0 && total >= limit}
|
||||
<slot name="alert">
|
||||
<Alert type="warning">
|
||||
<slot name="alert" {limit} {tier} {title} {upgradeMethod}>
|
||||
<Alert type={alertType}>
|
||||
<span class="text">
|
||||
You've reached the maximum number of {title.toLowerCase()} for the {tier} plan.
|
||||
<button
|
||||
class="link"
|
||||
type="button"
|
||||
on:click|preventDefault={() => wizard.start(ChangeOrganizationTierCloud)}
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button>
|
||||
for additional {title.toLocaleLowerCase()}.
|
||||
</span>
|
||||
@@ -89,14 +88,11 @@
|
||||
{#if isCloud}
|
||||
<div class="u-hide">
|
||||
<div bind:this={tooltipContent}>
|
||||
<slot name="tooltip">
|
||||
<slot name="tooltip" {limit} {tier} {title} {upgradeMethod}>
|
||||
<p class="text">
|
||||
Your are limited to {limit}
|
||||
{title.toLocaleLowerCase()} per project on the {tier}.
|
||||
<button
|
||||
class="link"
|
||||
type="button"
|
||||
on:click|preventDefault={() => wizard.start(ChangeOrganizationTierCloud)}
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button>
|
||||
for addtional {title.toLocaleLowerCase()}.
|
||||
</p>
|
||||
|
||||
@@ -34,8 +34,10 @@ export function getCreditCardImage(brand: string, width = 46, height = 32) {
|
||||
}
|
||||
|
||||
export function getServiceLimit(serviceId: string): number {
|
||||
if (!isCloud) return 0;
|
||||
if (!serviceId) return 0;
|
||||
const plan = get(plansInfo).plans.find((p) => p.$id === get(organization)?.billingPlan);
|
||||
console.log(plan);
|
||||
return plan[serviceId];
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
// import { baseEmailTemplate, baseSmsTemplate, emailTemplate, smsTemplate } from './store';
|
||||
import { baseEmailTemplate, emailTemplate } from './store';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
|
||||
const projectId = $page.params.project;
|
||||
|
||||
@@ -114,6 +117,18 @@
|
||||
</p>
|
||||
|
||||
<svelte:fragment slot="aside">
|
||||
{#if $organization.billingPlan === 'tier-0'}
|
||||
<Alert
|
||||
buttons={[
|
||||
{
|
||||
name: 'Upgrade plan',
|
||||
method: () => wizard.start(ChangeOrganizationTierCloud)
|
||||
}
|
||||
]}>
|
||||
All emails sent using the Free plan will include attribution to Appwrite in the
|
||||
signature. To send attribution-free emails, upgrade your plan.
|
||||
</Alert>
|
||||
{/if}
|
||||
<Collapsible>
|
||||
<CollapsibleItem
|
||||
bind:open={emailVerificationOpen}
|
||||
|
||||
@@ -28,12 +28,20 @@
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<ContainerHeader title="Sessions" serviceId="logs">
|
||||
<ContainerHeader title="Sessions" serviceId="logs" alertType="info">
|
||||
{#if data.sessions.total}
|
||||
<Button secondary on:click={() => (showDeleteAll = true)}>
|
||||
<span class="text">Delete All</span>
|
||||
</Button>
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="tooltip" let:limit let:tier let:upgradeMethod>
|
||||
<p class="text">
|
||||
You are limited to {limit} hour of logs on the {tier} plan.
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button> to increase log retention for a longer period.
|
||||
</p>
|
||||
</svelte:fragment>
|
||||
</ContainerHeader>
|
||||
{#if data.sessions.total}
|
||||
<Table>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
TableScroll
|
||||
} from '$lib/elements/table';
|
||||
import { deploymentList, execute, func, proxyRuleList } from './store';
|
||||
import { Container } from '$lib/layout';
|
||||
import { Container, ContainerHeader } from '$lib/layout';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { calculateSize, humanFileSize } from '$lib/helpers/sizeConvertion';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
@@ -56,10 +56,16 @@
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<div class="u-flex u-gap-12 common-section u-main-space-between">
|
||||
<Heading tag="h2" size="5">Deployments</Heading>
|
||||
<ContainerHeader title="Deployments" serviceId="logs">
|
||||
<svelte:fragment slot="tooltip" let:limit let:tier let:upgradeMethod>
|
||||
<p class="text">
|
||||
You are limited to {limit} hour of logs on the {tier} plan.
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button> to increase log retention for a longer period.
|
||||
</p>
|
||||
</svelte:fragment>
|
||||
<Create main />
|
||||
</div>
|
||||
</ContainerHeader>
|
||||
{#if $deploymentList?.total}
|
||||
{@const activeDeployment = data.activeDeployment}
|
||||
<div class="common-section">
|
||||
|
||||
+19
-1
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { Card, CardGrid, Id } from '$lib/components';
|
||||
import { Alert, Card, CardGrid, Id } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { humanFileSize } from '$lib/helpers/sizeConvertion';
|
||||
@@ -20,6 +20,11 @@
|
||||
import DeploymentCreatedBy from '../deploymentCreatedBy.svelte';
|
||||
import DeploymentDomains from '../deploymentDomains.svelte';
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
|
||||
import { getServiceLimit, tierToPlan } from '$lib/stores/billing';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { isCloud } from '$lib/system';
|
||||
|
||||
let logs = '';
|
||||
|
||||
@@ -41,9 +46,22 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const limit = getServiceLimit('logs');
|
||||
const tier = tierToPlan($organization?.billingPlan)?.name;
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
{#if isCloud && limit !== 0 && limit < Infinity}
|
||||
<Alert>
|
||||
You are limited to {limit} hour of logs on the {tier} plan.
|
||||
<button
|
||||
class="link"
|
||||
type="button"
|
||||
on:click|preventDefault={() => wizard.start(ChangeOrganizationTierCloud)}
|
||||
>Upgrade</button> to increase log retention for a longer period.
|
||||
</Alert>
|
||||
{/if}
|
||||
<CardGrid>
|
||||
<div class="grid-1-2-col-1 u-flex u-cross-center u-gap-16">
|
||||
<div class="avatar is-medium" aria-hidden="true">
|
||||
|
||||
+5
-11
@@ -22,14 +22,13 @@
|
||||
import { func } from '../store';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { tierToPlan, type Tier, getServiceLimit } from '$lib/stores/billing';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
|
||||
import { getServiceLimit } from '$lib/stores/billing';
|
||||
import { isCloud } from '$lib/system';
|
||||
import UsageRates from '$routes/console/wizard/cloudOrganization/usageRates.svelte';
|
||||
import { project } from '$routes/console/project-[project]/store';
|
||||
import Create from '../create.svelte';
|
||||
import Execute from '../execute.svelte';
|
||||
import { abbreviateNumber } from '$lib/helpers/numbers';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -50,8 +49,6 @@
|
||||
$log.data = execution;
|
||||
}
|
||||
|
||||
const tier = tierToPlan($organization?.billingPlan as Tier)?.name;
|
||||
const executions = getServiceLimit('executions');
|
||||
const logs = getServiceLimit('logs');
|
||||
</script>
|
||||
|
||||
@@ -61,11 +58,11 @@
|
||||
buttonText="Execute now"
|
||||
buttonEvent="execute_function"
|
||||
buttonMethod={() => (selectedFunction = $func)}>
|
||||
<svelte:fragment slot="tooltip">
|
||||
<svelte:fragment slot="tooltip" let:tier let:limit let:upgradeMethod>
|
||||
<p class="u-bold">The {tier} plan has limits</p>
|
||||
<ul>
|
||||
<li>
|
||||
{executions} function executions
|
||||
{abbreviateNumber(limit)} function executions
|
||||
</li>
|
||||
<li>
|
||||
{logs} hour of logs
|
||||
@@ -73,10 +70,7 @@
|
||||
</ul>
|
||||
{#if $organization?.billingPlan === 'tier-0'}
|
||||
<p class="text">
|
||||
<button
|
||||
class="link"
|
||||
type="button"
|
||||
on:click|preventDefault={() => wizard.start(ChangeOrganizationTierCloud)}
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button>
|
||||
to increase your resource limits.
|
||||
</p>
|
||||
|
||||
@@ -46,10 +46,7 @@
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import { getServiceLimit, tierToPlan, type Tier, readOnly } from '$lib/stores/billing';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
|
||||
import { getServiceLimit, readOnly } from '$lib/stores/billing';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export let data: PageData;
|
||||
@@ -89,22 +86,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
const limit = getServiceLimit('storage') ?? Infinity;
|
||||
$: tier = tierToPlan($organization?.billingPlan as Tier)?.name;
|
||||
|
||||
// TODO: fetch the total storage used
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<ContainerHeader title="Files" serviceId="storage" isFlex={false} total={10}>
|
||||
<svelte:fragment slot="alert">
|
||||
<svelte:fragment slot="alert" let:tier let:upgradeMethod>
|
||||
<Alert type="warning">
|
||||
<span class="text">
|
||||
You've reached the storage limit for the {tier} plan.
|
||||
<button
|
||||
class="link"
|
||||
type="button"
|
||||
on:click|preventDefault={() => wizard.start(ChangeOrganizationTierCloud)}
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button>
|
||||
for additional storage.
|
||||
</span>
|
||||
@@ -125,14 +116,11 @@
|
||||
</Button>
|
||||
</div>
|
||||
</SearchQuery>
|
||||
<svelte:fragment slot="tooltip">
|
||||
<svelte:fragment slot="tooltip" let:limit let:tier let:upgradeMethod>
|
||||
<p class="text">
|
||||
You are limited to {limit} of storage on the {tier} plan.
|
||||
|
||||
<button
|
||||
class="link"
|
||||
type="button"
|
||||
on:click|preventDefault={() => wizard.start(ChangeOrganizationTierCloud)}
|
||||
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
|
||||
>Upgrade</button>
|
||||
for addtional storage.
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user