diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts
index fcd406638..15a3170b7 100644
--- a/src/lib/sdk/billing.ts
+++ b/src/lib/sdk/billing.ts
@@ -983,7 +983,7 @@ export class Billing {
};
const uri = new URL(this.client.config.endpoint + path);
return await this.client.call(
- 'post',
+ 'patch',
uri,
{
'content-type': 'application/json'
diff --git a/src/lib/stores/migration.ts b/src/lib/stores/migration.ts
index eaf142841..dcb4a6088 100644
--- a/src/lib/stores/migration.ts
+++ b/src/lib/stores/migration.ts
@@ -42,7 +42,7 @@ export const ResourcesFriendly = {
file: { singular: 'File', plural: 'Files' },
bucket: { singular: 'Bucket', plural: 'Buckets' },
function: { singular: 'Function', plural: 'Functions' },
- 'environment variable': { singular: 'Environment Variable', plural: 'Environment Variables' },
+ 'environment-variable': { singular: 'Environment Variable', plural: 'Environment Variables' },
deployment: { singular: 'Deployment', plural: 'Deployments' },
database: { singular: 'Database', plural: 'Databases' },
collection: { singular: 'Collection', plural: 'Collections' },
@@ -102,7 +102,7 @@ export const migrationFormToResources = (
addResource('function');
}
if (formData.functions.env) {
- addResource('environment variable');
+ addResource('environment-variable');
}
if (formData.functions.inactive) {
addResource('deployment');
@@ -156,7 +156,7 @@ export const resourcesToMigrationForm = (
if (resources.includes('function') && isVersionAtLeast(version, '1.4.0')) {
formData.functions.root = true;
}
- if (resources.includes('environment variable') && isVersionAtLeast(version, '1.4.0')) {
+ if (resources.includes('environment-variable') && isVersionAtLeast(version, '1.4.0')) {
formData.functions.env = true;
}
if (resources.includes('deployment') && isVersionAtLeast(version, '1.4.0')) {
diff --git a/src/routes/(console)/(migration-wizard)/resource-form.svelte b/src/routes/(console)/(migration-wizard)/resource-form.svelte
index cc7e34ca8..5ddae52fa 100644
--- a/src/routes/(console)/(migration-wizard)/resource-form.svelte
+++ b/src/routes/(console)/(migration-wizard)/resource-form.svelte
@@ -344,7 +344,7 @@
Import all functions and their active deployment
- {#if resources?.includes('environment variable')}
+ {#if resources?.includes('environment-variable')}
-
{
@@ -30,6 +31,11 @@
extraMembers = members.total > 1 ? members.total - 1 : 0;
currentPlan = await sdk.forConsole.billing.getPlan($organization?.$id);
+
+ const creditList = await sdk.forConsole.billing.listCredits($organization.$id, [
+ Query.offset(0)
+ ]);
+ availableCredit = creditList.available;
});
$: extraUsage = (currentInvoice?.amount ?? 0) - (currentPlan?.price ?? 0);
@@ -141,6 +147,33 @@
{/if}
+ {#if $organization?.billingPlan !== BillingPlan.FREE && availableCredit > 0}
+
+
+ Credits to be applied
+
+
+ -{formatCurrency(
+ Math.min(availableCredit, currentInvoice?.amount ?? 0)
+ )}
+
+
+ {/if}
+
Current total (USD)
@@ -156,7 +189,13 @@
{$organization?.billingPlan === BillingPlan.FREE ||
$organization?.billingPlan === BillingPlan.GITHUB_EDUCATION
? formatCurrency(0)
- : formatCurrency(currentInvoice?.amount ?? 0)}
+ : formatCurrency(
+ Math.max(
+ (currentInvoice?.amount ?? 0) -
+ Math.min(availableCredit, currentInvoice?.amount ?? 0),
+ 0
+ )
+ )}
diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts
index 243e5b52c..f469f97a8 100644
--- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts
+++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts
@@ -1,5 +1,5 @@
import { sdk } from '$lib/stores/sdk';
-import { Query } from '@appwrite.io/console';
+import { Query, type Models } from '@appwrite.io/console';
import type { PageLoad } from './$types';
import type { Organization } from '$lib/stores/organization';
import type { Invoice } from '$lib/sdk/billing';
@@ -48,22 +48,33 @@ export const load: PageLoad = async ({ params, parent }) => {
sdk.forConsole.teams.listMemberships(params.organization)
]);
- const queries: string[] = [];
-
+ const projectNames: { [key: string]: Models.Project } = {};
if (usage?.projects?.length > 0) {
- queries.push(
- Query.equal(
- '$id',
- usage.projects.map((p) => p.projectId)
- )
- );
- }
+ // in batches of 100 (the max number of values in a query)
+ const requests = [];
+ const chunk = 100;
+ for (let i = 0; i < usage.projects.length; i += chunk) {
+ const queries = [
+ Query.limit(chunk),
+ Query.equal(
+ '$id',
+ usage.projects.slice(i, i + chunk).map((p) => p.projectId)
+ )
+ ];
+ requests.push(sdk.forConsole.projects.list(queries));
+ }
- const projectNames = await sdk.forConsole.projects.list(queries);
+ const responses = await Promise.all(requests);
+ for (const response of responses) {
+ for (const project of response.projects) {
+ projectNames[project.$id] = project;
+ }
+ }
+ }
return {
organizationUsage: usage,
- projectNames: projectNames.projects,
+ projectNames,
invoices,
currentInvoice,
organizationMembers
diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte
index c7fc534de..964f50eee 100644
--- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte
+++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte
@@ -21,10 +21,6 @@
export let projects: OrganizationUsage['projects'];
export let metric: Metric;
- function getProjectName(projectId: string): string {
- return data.projectNames.find((project) => project.$id === projectId)?.name;
- }
-
function getProjectUsageLink(projectId: string): string {
return `${base}/project-${projectId}/settings/usage`;
}
@@ -69,7 +65,7 @@
{#each groupByProject(metric).sort((a, b) => b.usage - a.usage) as project}
- {getProjectName(project.projectId)}
+ {data.projectNames[project.projectId]?.name ?? 'Unknown'}
{format(project.usage)}
{#if $canSeeProjects}