mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix formatting
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { formatCurrency } from '$lib/helpers/numbers';
|
||||
import type { Coupon } from '$lib/sdk/billing'
|
||||
import type { Coupon } from '$lib/sdk/billing';
|
||||
|
||||
export let label: string;
|
||||
export let value: number;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
export let organizationId: string | undefined = undefined;
|
||||
export let billingPlan: string;
|
||||
export let collaborators: string[];
|
||||
export let couponId: string;
|
||||
export let fixedCoupon = false;
|
||||
export let error = '';
|
||||
export let couponData: Partial<Coupon>;
|
||||
@@ -22,7 +21,11 @@
|
||||
let budgetEnabled = false;
|
||||
let estimation: Estimation;
|
||||
|
||||
async function getEstimate(billingPlan: string, collaborators: string[], couponId: string) {
|
||||
async function getEstimate(
|
||||
billingPlan: string,
|
||||
collaborators: string[],
|
||||
couponId: string | undefined
|
||||
) {
|
||||
try {
|
||||
estimation = await sdk.forConsole.billing.estimationCreateOrganization(
|
||||
billingPlan,
|
||||
@@ -65,6 +68,19 @@
|
||||
collaborators ?? []
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof AppwriteException) {
|
||||
if (
|
||||
e.type === 'coupon_not_found' ||
|
||||
e.type === 'coupon_already_used' ||
|
||||
e.type === 'billing_credits_unsupported'
|
||||
) {
|
||||
couponData = {
|
||||
code: null,
|
||||
status: null,
|
||||
credits: null
|
||||
};
|
||||
}
|
||||
}
|
||||
addNotification({
|
||||
type: 'error',
|
||||
isHtml: false,
|
||||
@@ -74,8 +90,8 @@
|
||||
}
|
||||
|
||||
$: organizationId
|
||||
? getUpdatePlanEstimate(organizationId, billingPlan, collaborators, couponId)
|
||||
: getEstimate(billingPlan, collaborators, couponId);
|
||||
? getUpdatePlanEstimate(organizationId, billingPlan, collaborators, couponData?.code)
|
||||
: getEstimate(billingPlan, collaborators, couponData?.code);
|
||||
</script>
|
||||
|
||||
{#if estimation || error.length}
|
||||
|
||||
@@ -7,4 +7,4 @@ export { default as EmptyCardCloud } from './emptyCardCloud.svelte';
|
||||
export { default as CreditsApplied } from './creditsApplied.svelte';
|
||||
export { default as PlanSelection } from './planSelection.svelte';
|
||||
export { default as EstimatedTotal } from './estimatedTotal.svelte';
|
||||
export { default as SelectPlan } from './selectPlan.svelte';
|
||||
export { default as SelectPlan } from './selectPlan.svelte';
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<LabelCard
|
||||
name="plan"
|
||||
bind:group={billingPlan}
|
||||
disabled={ (plan.$id === BillingPlan.FREE && anyOrgFree) || !plan.selfService}
|
||||
disabled={(plan.$id === BillingPlan.FREE && anyOrgFree) || !plan.selfService}
|
||||
value={plan.$id}
|
||||
tooltipShow={plan.$id === BillingPlan.FREE && anyOrgFree}
|
||||
tooltipText={plan.$id === BillingPlan.FREE
|
||||
|
||||
+29
-46
@@ -75,21 +75,21 @@ export type Estimation = {
|
||||
trialDays: number;
|
||||
trialEndDate: string | undefined;
|
||||
error: string | undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export type EstimationItem = {
|
||||
label: string;
|
||||
value: number;
|
||||
}
|
||||
};
|
||||
|
||||
export type EstimationDeleteOrganization = {
|
||||
amount: number;
|
||||
grossAmount: number;
|
||||
credits: number;
|
||||
discount: number;
|
||||
items: EstimationItem[],
|
||||
items: EstimationItem[];
|
||||
unpaidInvoices: Invoice[];
|
||||
}
|
||||
};
|
||||
|
||||
export type Coupon = {
|
||||
$id: string;
|
||||
@@ -173,7 +173,7 @@ export type Aggregation = {
|
||||
*/
|
||||
amount: number;
|
||||
additionalMembers: number;
|
||||
|
||||
|
||||
/**
|
||||
* Price for additional members
|
||||
*/
|
||||
@@ -294,11 +294,10 @@ export type PlanAddon = {
|
||||
currency: string;
|
||||
invoiceDesc: string;
|
||||
price: number;
|
||||
limit: number,
|
||||
limit: number;
|
||||
value: number;
|
||||
type: string;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
export type Plan = {
|
||||
$id: string;
|
||||
@@ -328,8 +327,8 @@ export type Plan = {
|
||||
users: AdditionalResource;
|
||||
};
|
||||
addons: {
|
||||
seats: PlanAddon
|
||||
}
|
||||
seats: PlanAddon;
|
||||
};
|
||||
trialDays: number;
|
||||
isAvailable: boolean;
|
||||
selfService: boolean;
|
||||
@@ -431,13 +430,13 @@ export class Billing {
|
||||
async estimationCreateOrganization(
|
||||
billingPlan: string,
|
||||
couponId: string = null,
|
||||
invites: Array<string> = [],
|
||||
invites: Array<string> = []
|
||||
): Promise<Estimation> {
|
||||
const path = `/organizations/estimations/create-organization`;
|
||||
const params = {
|
||||
billingPlan,
|
||||
couponId,
|
||||
invites,
|
||||
invites
|
||||
};
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return await this.client.call(
|
||||
@@ -466,40 +465,30 @@ export class Billing {
|
||||
);
|
||||
}
|
||||
|
||||
async estimationDeleteOrganization(organizationId: string): Promise<EstimationDeleteOrganization> {
|
||||
async estimationDeleteOrganization(
|
||||
organizationId: string
|
||||
): Promise<EstimationDeleteOrganization> {
|
||||
const path = `/organizations/${organizationId}/estimations/delete-organization`;
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return await this.client.call(
|
||||
'patch',
|
||||
uri,
|
||||
{
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
);
|
||||
return await this.client.call('patch', uri, {
|
||||
'content-type': 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
async getOrganizationPlan(organizationId: string): Promise<Plan> {
|
||||
const path = `/organizations/${organizationId}/plan`;
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return await this.client.call(
|
||||
'get',
|
||||
uri,
|
||||
{
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
);
|
||||
return await this.client.call('get', uri, {
|
||||
'content-type': 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
async getPlan(planId: string): Promise<Plan> {
|
||||
const path = `/console/plans/${planId}`;
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return await this.client.call(
|
||||
'get',
|
||||
uri,
|
||||
{
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
);
|
||||
return await this.client.call('get', uri, {
|
||||
'content-type': 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
async getRoles(organizationId: string): Promise<Roles> {
|
||||
@@ -546,13 +535,13 @@ export class Billing {
|
||||
organizationId: string,
|
||||
billingPlan: string,
|
||||
couponId: string = null,
|
||||
invites: Array<string> = [],
|
||||
invites: Array<string> = []
|
||||
): Promise<Estimation> {
|
||||
const path = `/organizations/${organizationId}/estimations/update-plan`;
|
||||
const params = {
|
||||
billingPlan,
|
||||
couponId,
|
||||
invites,
|
||||
invites
|
||||
};
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return await this.client.call(
|
||||
@@ -565,18 +554,12 @@ export class Billing {
|
||||
);
|
||||
}
|
||||
|
||||
async cancelDowngrade(
|
||||
organizationId: string
|
||||
): Promise<Organization | OrganizationError> {
|
||||
async cancelDowngrade(organizationId: string): Promise<Organization | OrganizationError> {
|
||||
const path = `/organizations/${organizationId}/plan/cancel`;
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return await this.client.call(
|
||||
'patch',
|
||||
uri,
|
||||
{
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
);
|
||||
return await this.client.call('patch', uri, {
|
||||
'content-type': 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
async updateBudget(
|
||||
|
||||
@@ -275,7 +275,8 @@ export async function checkForUsageLimit(org: Organization) {
|
||||
|
||||
const members = org.total;
|
||||
const plan = get(plansInfo)?.get(org.billingPlan);
|
||||
const membersOverflow = (members - 1) > plan.addons.seats.limit ? members - (plan.addons.seats.limit || members) : 0;
|
||||
const membersOverflow =
|
||||
members - 1 > plan.addons.seats.limit ? members - (plan.addons.seats.limit || members) : 0;
|
||||
|
||||
if (resources.some((r) => r.value >= 100) || membersOverflow > 0) {
|
||||
readOnly.set(true);
|
||||
@@ -490,4 +491,4 @@ export function calculateResourceSurplus(total: number, limit: number, limitUnit
|
||||
|
||||
export function isOrganization(org: Organization | OrganizationError): org is Organization {
|
||||
return (org as Organization).$id !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
let billingPlan: BillingPlan = BillingPlan.FREE;
|
||||
let paymentMethodId: string;
|
||||
let collaborators: string[] = [];
|
||||
let couponId: string | undefined;
|
||||
let couponData: Partial<Coupon> = {
|
||||
code: null,
|
||||
status: null,
|
||||
@@ -240,7 +239,6 @@
|
||||
{billingBudget}
|
||||
{billingPlan}
|
||||
{collaborators}
|
||||
{couponId}
|
||||
{couponData} />
|
||||
{:else}
|
||||
<PlanComparisonBox />
|
||||
|
||||
@@ -20,42 +20,43 @@ export const load: PageLoad = async ({ parent, depends }) => {
|
||||
const billingAddressId = (organization as Organization)?.billingAddressId;
|
||||
const billingAddressPromise: Promise<Address> = billingAddressId
|
||||
? sdk.forConsole.billing
|
||||
.getOrganizationBillingAddress(organization.$id, billingAddressId)
|
||||
.catch(() => null)
|
||||
.getOrganizationBillingAddress(organization.$id, billingAddressId)
|
||||
.catch(() => null)
|
||||
: null;
|
||||
|
||||
/**
|
||||
* Needed to keep this out of Promise.all, as when organization is
|
||||
* Needed to keep this out of Promise.all, as when organization is
|
||||
* initially created, these might return 404
|
||||
* - can be removed later once that is fixed in back-end
|
||||
*/
|
||||
let billingAggregation = null;
|
||||
try {
|
||||
billingAggregation = await sdk.forConsole.billing.getAggregation(organization.$id, (organization as Organization)?.billingAggregationId);
|
||||
} catch (e) {
|
||||
// ignore error
|
||||
}
|
||||
|
||||
let billingInvoice = null;
|
||||
try {
|
||||
billingInvoice = await sdk.forConsole.billing.getInvoice(organization.$id, (organization as Organization)?.billingInvoiceId);
|
||||
billingAggregation = await sdk.forConsole.billing.getAggregation(
|
||||
organization.$id,
|
||||
(organization as Organization)?.billingAggregationId
|
||||
);
|
||||
} catch (e) {
|
||||
// ignore error
|
||||
}
|
||||
|
||||
const [
|
||||
paymentMethods,
|
||||
addressList,
|
||||
billingAddress,
|
||||
creditList,
|
||||
aggregationBillingPlan,
|
||||
] = await Promise.all([
|
||||
sdk.forConsole.billing.listPaymentMethods(),
|
||||
sdk.forConsole.billing.listAddresses(),
|
||||
billingAddressPromise,
|
||||
sdk.forConsole.billing.listCredits(organization.$id),
|
||||
sdk.forConsole.billing.getPlan(billingAggregation?.plan ?? organization.billingPlan),
|
||||
]);
|
||||
let billingInvoice = null;
|
||||
try {
|
||||
billingInvoice = await sdk.forConsole.billing.getInvoice(
|
||||
organization.$id,
|
||||
(organization as Organization)?.billingInvoiceId
|
||||
);
|
||||
} catch (e) {
|
||||
// ignore error
|
||||
}
|
||||
|
||||
const [paymentMethods, addressList, billingAddress, creditList, aggregationBillingPlan] =
|
||||
await Promise.all([
|
||||
sdk.forConsole.billing.listPaymentMethods(),
|
||||
sdk.forConsole.billing.listAddresses(),
|
||||
billingAddressPromise,
|
||||
sdk.forConsole.billing.listCredits(organization.$id),
|
||||
sdk.forConsole.billing.getPlan(billingAggregation?.plan ?? organization.billingPlan)
|
||||
]);
|
||||
|
||||
return {
|
||||
paymentMethods,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
export let currentPlan: Plan;
|
||||
export let creditList: CreditList;
|
||||
export let currentInvoice: Invoice | undefined = undefined;
|
||||
export let currentAggregation: Aggregation | undefined = undefined
|
||||
export let currentAggregation: Aggregation | undefined = undefined;
|
||||
|
||||
let showCancel: boolean = false;
|
||||
|
||||
@@ -46,8 +46,7 @@
|
||||
<Collapsible>
|
||||
<div class="u-flex-vertical u-gap-8">
|
||||
<div class="u-flex">
|
||||
<span class="body-text-2">
|
||||
{tierToPlan($organization?.billingPlan)?.name} plan</span>
|
||||
<span class="body-text-2"> {currentPlan.name} plan</span>
|
||||
<div class="body-text-2 u-margin-inline-start-auto">
|
||||
{isTrial ||
|
||||
$organization?.billingPlan === BillingPlan.GITHUB_EDUCATION
|
||||
@@ -63,7 +62,9 @@
|
||||
<svelte:fragment slot="beforetitle">
|
||||
<span class="body-text-2"><b>Add-ons</b></span><span
|
||||
class="inline-tag"
|
||||
>{currentAggregation.additionalMembers > 0 ? currentInvoice.usage.length + 1 : currentInvoice.usage.length}</span>
|
||||
>{currentAggregation.additionalMembers > 0
|
||||
? currentInvoice.usage.length + 1
|
||||
: currentInvoice.usage.length}</span>
|
||||
<div class="icon">
|
||||
<span class="icon-cheveron-down" aria-hidden="true"></span>
|
||||
</div>
|
||||
@@ -100,10 +101,12 @@
|
||||
{#if currentInvoice?.usage}
|
||||
{#each currentInvoice.usage as excess, i}
|
||||
<li
|
||||
class="u-flex-vertical u-gap-4 {currentAggregation.additionalMembers > 0
|
||||
class="u-flex-vertical u-gap-4 {currentAggregation.additionalMembers >
|
||||
0
|
||||
? 'u-padding-block-8'
|
||||
: 'u-padding-block-start-8'}"
|
||||
class:u-sep-block-start={i > 0 || currentAggregation.additionalMembers > 0}>
|
||||
class:u-sep-block-start={i > 0 ||
|
||||
currentAggregation.additionalMembers > 0}>
|
||||
{#if ['storage', 'bandwidth'].includes(excess.name)}
|
||||
{@const excessValue = humanFileSize(
|
||||
excess.value
|
||||
|
||||
Reference in New Issue
Block a user