diff --git a/package.json b/package.json index a2e1778fe3..bb9984abc3 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@9c55755", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@865e2fc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a968c01e9..530d6444a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f - version: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@9c55755 + version: https://pkg.vc/-/@appwrite/@appwrite.io/console@9c55755 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -272,9 +272,9 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f} - version: 1.10.0 + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@9c55755': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@9c55755} + version: 2.1.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': resolution: {integrity: sha512-iLFlV55hj8mGuAbmxJGenxN5RaZMmVT4GJb9dv/MP1xBAtYibFq7JvBcxm18qV2KU8c31Rntf+Ub4GL7HwqTYg==} @@ -3823,7 +3823,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@f21fc7f': {} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@9c55755': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index dea8860b55..d5ceb1c3e5 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -247,6 +247,7 @@ export enum Submit { ProjectDelete = 'submit_project_delete', ProjectUpdateName = 'submit_project_update_name', ProjectUpdateTeam = 'submit_project_update_team', + ProjectUpdateLabels = 'submit_project_update_labels', ProjectService = 'submit_project_service', ProjectUpdateSMTP = 'submit_project_update_smtp', MemberCreate = 'submit_member_create', diff --git a/src/routes/(console)/+layout.ts b/src/routes/(console)/+layout.ts index 44956eb5db..af48c06718 100644 --- a/src/routes/(console)/+layout.ts +++ b/src/routes/(console)/+layout.ts @@ -18,7 +18,7 @@ export const load: LayoutLoad = async ({ depends, parent }) => { sdk.forConsole.account.getPrefs(), isCloud ? sdk.forConsole.billing.getPlansInfo() : null, fetch(`${endpoint}/health/version`, { - headers: { 'X-Appwrite-Project': project } + headers: { 'X-Appwrite-Project': project as string } }).then((response) => response.json() as { version?: string }), sdk.forConsole.console.variables() ]); diff --git a/src/routes/(console)/organization-[organization]/+page.svelte b/src/routes/(console)/organization-[organization]/+page.svelte index 83c40623c3..37ef03204f 100644 --- a/src/routes/(console)/organization-[organization]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/+page.svelte @@ -170,7 +170,7 @@ - + {#if $canWriteProjects} {#if projectCreationDisabled && reachedProjectLimit} diff --git a/src/routes/(console)/organization-[organization]/+page.ts b/src/routes/(console)/organization-[organization]/+page.ts index 98dfed44b0..fc4256b032 100644 --- a/src/routes/(console)/organization-[organization]/+page.ts +++ b/src/routes/(console)/organization-[organization]/+page.ts @@ -24,8 +24,12 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => const archivedPage = Number.isFinite(archivedPageRaw) && archivedPageRaw > 0 ? archivedPageRaw : 1; const archivedOffset = pageToOffset(archivedPage, limit); - const common = [Query.equal('teamId', params.organization)]; - const active = isCloud + + const searchQueries = search + ? [Query.or([Query.search('search', search), Query.contains('labels', search)])] + : []; + const commonQueries = [Query.equal('teamId', params.organization)]; + const activeQueries = isCloud ? [Query.or([Query.equal('status', 'active'), Query.isNull('status')])] : []; @@ -35,10 +39,10 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.offset(offset), Query.limit(limit), Query.orderDesc(''), - ...common, - ...active - ], - search: search || undefined + ...commonQueries, + ...searchQueries, + ...activeQueries + ] }), isCloud ? sdk.forConsole.projects.list({ @@ -46,20 +50,18 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) => Query.offset(archivedOffset), Query.limit(limit), Query.orderDesc(''), - ...common, + ...commonQueries, + ...searchQueries, Query.equal('status', 'archived') - ], - search: search || undefined + ] }) : Promise.resolve({ projects: [], total: 0 }), sdk.forConsole.projects.list({ - queries: [...common, ...active], - search: search || undefined + queries: [...commonQueries, ...activeQueries, ...searchQueries] }), isCloud ? sdk.forConsole.projects.list({ - queries: [...common, Query.equal('status', 'archived')], - search: search || undefined + queries: [...commonQueries, ...searchQueries, Query.equal('status', 'archived')] }) : Promise.resolve({ projects: [], total: 0 }) ]); diff --git a/src/routes/(console)/project-[region]-[project]/settings/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/+page.svelte index edf09b92fb..8c427cc23f 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/+page.svelte @@ -15,6 +15,7 @@ import ChangeOrganization from './changeOrganization.svelte'; import UpdateVariables from '../updateVariables.svelte'; import { page } from '$app/state'; + import UpdateLabels from './updateLabels.svelte'; export let data; @@ -84,8 +85,9 @@ {#if $project} - {#if $canWriteProjects} + + + import { onMount } from 'svelte'; + import { invalidate } from '$app/navigation'; + import { Submit, trackEvent, trackError } from '$lib/actions/analytics'; + import { CardGrid } from '$lib/components'; + import { Dependencies } from '$lib/constants'; + import { Button, Form, InputTags } from '$lib/elements/forms'; + import { symmetricDifference } from '$lib/helpers/array'; + import { addNotification } from '$lib/stores/notifications'; + import { sdk } from '$lib/stores/sdk'; + import { project } from '../store'; + import { Tag, Input, Layout, Icon } from '@appwrite.io/pink-svelte'; + import { IconPlus } from '@appwrite.io/pink-icons-svelte'; + + const alphaNumericRegExp = /^[a-zA-Z0-9]+$/; + let suggestedLabels = ['live', 'stage', 'internal']; + let labels: string[] = []; + let error = ''; + + onMount(async () => { + labels = [...$project.labels]; + }); + + async function updateLabels() { + try { + await sdk.forConsole.projects.updateLabels({ projectId: $project.$id, labels }); + await invalidate(Dependencies.PROJECT); + isDisabled = true; + addNotification({ + type: 'success', + message: 'Project labels have been updated' + }); + trackEvent(Submit.ProjectUpdateLabels); + } catch (error) { + addNotification({ + message: error.message, + type: 'error' + }); + trackError(error, Submit.ProjectUpdateLabels); + } + } + + $: isDisabled = !!error || !symmetricDifference(labels, $project.labels).length; + + $: if (labels) { + const invalidLabels = []; + + labels.forEach((label) => { + if (!alphaNumericRegExp.test(label)) { + invalidLabels.push(label); + } + }); + + if (invalidLabels.length) { + error = `Invalid labels: ${invalidLabels.join(', ')}`; + } else { + error = ''; + } + } + + +
+ + Labels + Categorize and manage your projects for easy searching based on specific criteria by assigning + them customizable labels. + + + {#key labels.length} + + {/key} + + {#each suggestedLabels as suggestedLabel} + { + if (!labels.includes(suggestedLabel)) { + labels = [...labels, suggestedLabel]; + } else { + labels = labels.filter((e) => e !== suggestedLabel); + } + }}> + + {suggestedLabel} + + {/each} + + {error ? error : 'Only alphanumeric characters are allowed'} + + + + + + + +
diff --git a/src/routes/(public)/(guest)/register/invite/[slug]/+page.svelte b/src/routes/(public)/(guest)/register/invite/[slug]/+page.svelte index 898d16358c..fdd6c247a3 100644 --- a/src/routes/(public)/(guest)/register/invite/[slug]/+page.svelte +++ b/src/routes/(public)/(guest)/register/invite/[slug]/+page.svelte @@ -57,7 +57,7 @@ const res = await fetch(`${endpoint}/account/invite`, { method: 'POST', headers: { - 'X-Appwrite-Project': project, + 'X-Appwrite-Project': project as string, 'Content-Type': 'application/json' }, body: JSON.stringify({