Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 4 additions & 47 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"dependencies": {
"@ai-sdk/svelte": "^1.1.24",
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@6d0c948",
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@95547fc",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3",
"@appwrite.io/pink-legacy": "^1.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,6 @@
};

// addons (additional members, projects, etc.)
const billingAddonNames: Record<string, string> = {
addon_baa: 'HIPAA BAA'
};

const addons = (currentAggregation?.resources || [])
.filter(
(r) =>
Expand All @@ -269,8 +265,8 @@
? 'Additional members'
: addon.resourceId === 'projects'
? 'Additional projects'
: (billingAddonNames[addon.resourceId] ??
`${addon.resourceId} overage (${formatNum(addon.value)})`),
: addon.name ||
`${addon.resourceId} overage (${formatNum(addon.value)})`,
Comment on lines +268 to +269
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 BAA label regression if API omits name

The hardcoded billingAddonNames map (addon_baa → 'HIPAA BAA') has been removed in favour of addon.name. If the billing-aggregation API response doesn't populate name on existing BAA resources, BAA will display as addon_baa overage (1) in the plan summary for current BAA subscribers. Make sure the cloud API (and the new SDK pin) actually includes name on billing resource objects, or keep a fallback map alongside the API-provided name as a safety net.

usage: '',
price: formatCurrency(addon.amount)
},
Expand Down Expand Up @@ -400,6 +396,18 @@
priceFormatter: ({ amount }) => formatCurrency(amount),
includeProgress: false
}),
...resources
.filter((r) => r.resourceId?.startsWith('addon_') && (r.amount ?? 0) > 0)
.map((addon) =>
createRow({
id: `addon-${addon.resourceId}`,
label: addon.name || addon.resourceId,
resource: addon,
usageFormatter: ({ value }) => formatNum(value),
priceFormatter: ({ amount }) => formatCurrency(amount),
includeProgress: false
})
),
createRow({
id: 'usage-details',
label: `<a href="${base}/project-${String(projectData.region || 'default')}-${projectData.$id}/settings/usage" style="text-decoration: underline; color: var(--fgcolor-accent-neutral);">Usage details</a>`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import UpdateVariables from '../updateVariables.svelte';
import { page } from '$app/state';
import UpdateLabels from './updateLabels.svelte';
import PremiumGeoDB from './premiumGeoDB.svelte';
import { isCloud } from '$lib/system';

export let data;

Expand Down Expand Up @@ -93,6 +95,9 @@
<UpdateProtocols />
<UpdateServices />
<UpdateInstallations {...data.installations} limit={data.limit} offset={data.offset} />
{#if isCloud}
<PremiumGeoDB addons={data.addons} addonPrice={data.addonPrice} />
{/if}
<UpdateVariables
{sdkCreateVariable}
{sdkUpdateVariable}
Expand Down
27 changes: 23 additions & 4 deletions src/routes/(console)/project-[region]-[project]/settings/+page.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,48 @@
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import { isCloud } from '$lib/system';
import { sdk } from '$lib/stores/sdk';
import { Query } from '@appwrite.io/console';
import { Addon, Query } from '@appwrite.io/console';
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ depends, url, params }) => {
depends(Dependencies.PROJECT_VARIABLES);
depends(Dependencies.PROJECT_INSTALLATIONS);
depends(Dependencies.ADDONS);
const limit = PAGE_LIMIT;
const offset = Number(url.searchParams.get('offset') ?? 0);
const variablesOffset = Number(url.searchParams.get('variablesOffset') ?? 0);
const projectSdk = sdk.forProject(params.region, params.project);
const [variables, installations] = await Promise.all([
const [variables, installations, addons, addonPrice] = await Promise.all([
projectSdk.projectApi.listVariables({
queries: [Query.limit(limit), Query.offset(variablesOffset)]
}),
projectSdk.vcs.listInstallations({
queries: [Query.limit(limit), Query.offset(offset)]
})
}),
isCloud
? sdk
.forConsoleIn(params.region)
.projects.listAddons({ projectId: params.project })
.catch(() => null)
: Promise.resolve(null),
isCloud
? sdk
.forConsoleIn(params.region)
.projects.getAddonPrice({
projectId: params.project,
addon: Addon.Premiumgeodb
})
.catch(() => null)
: Promise.resolve(null)
]);

return {
limit,
offset,
variablesOffset,
variables,
installations
installations,
addons,
addonPrice
};
};
Loading
Loading