mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix: remaining routes
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
|
||||
- `src/`: SvelteKit app source.
|
||||
- `src/lib/`: reusable components, elements, actions, helpers, stores, charts, images.
|
||||
- `src/routes/`: route groups and pages (e.g., `+layout.svelte`, `+page.ts`).
|
||||
- `src/themes/`, `hooks.*.ts`, `service-worker.ts`: app-wide setup.
|
||||
- `static/`: public assets served as-is.
|
||||
- `build/`: compiled output (local builds).
|
||||
- `e2e/`: Playwright tests (`helpers/`, `journeys/`, `steps/`).
|
||||
- Tooling: `eslint.config.js`, `.prettierrc`, `playwright.config.ts`, `vitest-setup-client.ts`.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
- `pnpm dev`: start Vite dev server.
|
||||
- `pnpm build`: production build via `build.js`.
|
||||
- `pnpm preview`: preview the production build.
|
||||
- `pnpm check`: Svelte/TS diagnostics.
|
||||
- `pnpm format` / `pnpm lint`: format with Prettier, then lint with ESLint.
|
||||
- `pnpm test` | `pnpm test:watch` | `pnpm test:ui`: run Vitest (unit/component tests).
|
||||
- `pnpm e2e` | `pnpm e2e:ui`: run Playwright tests; config auto-builds and serves.
|
||||
Requires Node >= 20 and pnpm (see `packageManager`).
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
|
||||
- Language: TypeScript + Svelte.
|
||||
- Prettier: 4‑space indentation, single quotes, width 100, bracketSameLine.
|
||||
- Svelte files: PascalCase components in `src/lib`, route files follow SvelteKit (`+page.svelte`, `+layout.ts`).
|
||||
- Variables/functions: `camelCase`; constants: `SCREAMING_SNAKE_CASE`; types/interfaces: `PascalCase`.
|
||||
- Keep logic in `$lib` and thin route loaders/actions.
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
- Unit/component: Vitest + Testing Library.
|
||||
- Place near source or under `src/`; name `*.test.ts`/`*.test.svelte`.
|
||||
- Run with `pnpm test`.
|
||||
- End‑to‑end: Playwright under `e2e/`.
|
||||
- Start with `pnpm e2e` (uses `playwright.config.ts` to build/preview on port 4173).
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
|
||||
- Branch names: `TYPE-ISSUEID-short-description` (e.g., `feat-1234-add-billing-chart`).
|
||||
- Commits: imperative, concise, reference issues when relevant.
|
||||
- PRs: clear description, linked issues, screenshots/GIFs for UI changes, test coverage notes, and checklist of affected areas.
|
||||
- Keep PRs focused; include `pnpm format`, `pnpm lint`, `pnpm check`, and `pnpm test` clean runs before requesting review.
|
||||
|
||||
## Security & Configuration Tips
|
||||
|
||||
- Do not commit secrets; use `.env` based on `.env.example`.
|
||||
- Sentry/Stripe and other public keys are configured via env vars; prefer `PUBLIC_` prefix for client‑exposed values.
|
||||
- Use `compose.yml`/`Dockerfile` for containerized workflows when needed.
|
||||
Generated
+3751
-4964
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,8 @@
|
||||
import { canWriteProjects } from '$lib/stores/roles';
|
||||
import { Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/auth`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/auth`;
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
|
||||
+3
-3
@@ -6,7 +6,8 @@
|
||||
import { Cover, CoverTitle } from '$lib/layout';
|
||||
import { team } from './store';
|
||||
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/auth/teams/team-${page.params.team}`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/auth/teams/team-${page.params.team}`;
|
||||
export let back = `${base}/project-${page.params.region}-${page.params.project}/auth/teams`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
@@ -30,8 +31,7 @@
|
||||
|
||||
<Cover>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle
|
||||
href={`${base}/project-${page.params.region}-${page.params.project}/auth/teams`}>
|
||||
<CoverTitle href={back}>
|
||||
{$team?.name}
|
||||
</CoverTitle>
|
||||
<Id value={$team?.$id} event="team">{$team?.$id}</Id>
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
import { Cover, CoverTitle } from '$lib/layout';
|
||||
import { user } from './store';
|
||||
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/auth/user-${page.params.user}`;
|
||||
export let back = `${base}/project-${page.params.region}-${page.params.project}/auth`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/auth/user-${page.params.user}`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
@@ -44,7 +45,7 @@
|
||||
|
||||
<Cover>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle href={`${base}/project-${page.params.region}-${page.params.project}/auth`}>
|
||||
<CoverTitle href={back}>
|
||||
{$user.name ? $user.name : '-'}
|
||||
</CoverTitle>
|
||||
<Id value={$user.$id} event="user">{$user.$id}</Id>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Container } from '$lib/layout';
|
||||
import View from './view.svelte';
|
||||
import { canWriteDatabases } from '$lib/stores/roles';
|
||||
export let data;
|
||||
|
||||
const getDatabaseUrl = (database: Models.Database, firstTableId?: string | null) => {
|
||||
@@ -14,6 +15,7 @@
|
||||
|
||||
<Container>
|
||||
<View
|
||||
canWriteDatabases={$canWriteDatabases}
|
||||
databases={data.databases}
|
||||
tables={data.tables}
|
||||
policies={data.policies}
|
||||
|
||||
+2
@@ -4,6 +4,7 @@
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Container } from '$lib/layout';
|
||||
import View from './view.svelte';
|
||||
import { canWriteTables } from '$lib/stores/roles';
|
||||
export let data;
|
||||
|
||||
const createTableUrl = (table: Models.Table) => {
|
||||
@@ -13,6 +14,7 @@
|
||||
|
||||
<Container>
|
||||
<View
|
||||
canWriteTables={$canWriteTables}
|
||||
tables={data.tables}
|
||||
limit={data.limit}
|
||||
offset={data.offset}
|
||||
|
||||
+3
-2
@@ -9,7 +9,8 @@
|
||||
|
||||
const projectId = page.params.project;
|
||||
const databaseId = page.params.database;
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}`;
|
||||
export let back = `${base}/project-${page.params.region}-${projectId}/databases`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
@@ -40,7 +41,7 @@
|
||||
|
||||
<Cover expanded>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle href={`${base}/project-${page.params.region}-${projectId}/databases`}>
|
||||
<CoverTitle href={back}>
|
||||
{$database.name}
|
||||
</CoverTitle>
|
||||
<Id value={$database.$id}>{$database.$id}</Id>
|
||||
|
||||
+2
-246
@@ -1,252 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { Filters, hasPageQueries, queries } from '$lib/components/filters';
|
||||
import ViewSelector from '$lib/components/viewSelector.svelte';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import type { Column, ColumnType } from '$lib/helpers/types';
|
||||
import { Container } from '$lib/layout';
|
||||
import { preferences } from '$lib/stores/preferences';
|
||||
import { canWriteTables, canWriteRows } from '$lib/stores/roles';
|
||||
import { Icon, Layout, Divider } from '@appwrite.io/pink-svelte';
|
||||
import View from './view.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import {
|
||||
table,
|
||||
tableColumns,
|
||||
isCsvImportInProgress,
|
||||
showRowCreateSheet,
|
||||
showCreateColumnSheet,
|
||||
type Columns,
|
||||
randomDataModalState,
|
||||
expandTabs
|
||||
} from './store';
|
||||
import SpreadSheet from './spreadsheet.svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import FilePicker from '$lib/components/filePicker.svelte';
|
||||
import { page } from '$app/state';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { isSmallViewport } from '$lib/stores/viewport';
|
||||
import { IconChevronDown, IconChevronUp, IconPlus } from '@appwrite.io/pink-icons-svelte';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import EmptySheet from './layout/emptySheet.svelte';
|
||||
import CreateRow from './rows/create.svelte';
|
||||
import { onDestroy } from 'svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
let showImportCSV = false;
|
||||
|
||||
// todo: might need a type fix here.
|
||||
const filterColumns = writable<Column[]>([]);
|
||||
|
||||
function createTableColumns(columns: Columns[], selected: string[] = []): Column[] {
|
||||
return columns.map((column) => ({
|
||||
id: column.key,
|
||||
title: column.key,
|
||||
type: column.type as ColumnType,
|
||||
hide: !!selected?.includes(column.key),
|
||||
array: column?.array,
|
||||
format: 'format' in column && column?.format === 'enum' ? column.format : null,
|
||||
elements: 'elements' in column ? column.elements : null
|
||||
}));
|
||||
}
|
||||
|
||||
$: selected = preferences.getCustomTableColumns(page.params.table);
|
||||
|
||||
$: if ($table.columns) {
|
||||
const freshColumns = createTableColumns($table.columns, selected);
|
||||
tableColumns.set(freshColumns);
|
||||
filterColumns.set(freshColumns.filter((column) => !column.isAction));
|
||||
}
|
||||
|
||||
$: hasColumns = !!$table.columns.length;
|
||||
$: hasValidColumns = $table?.columns?.some((col) => col.status === 'available');
|
||||
|
||||
async function onSelect(file: Models.File, localFile = false) {
|
||||
$isCsvImportInProgress = true;
|
||||
|
||||
try {
|
||||
await sdk
|
||||
.forProject(page.params.region, page.params.project)
|
||||
.migrations.createCsvMigration({
|
||||
bucketId: file.bucketId,
|
||||
fileId: file.$id,
|
||||
resourceId: `${page.params.database}:${page.params.table}`,
|
||||
internalFile: localFile
|
||||
});
|
||||
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Rows import from csv has started'
|
||||
});
|
||||
|
||||
trackEvent(Submit.DatabaseImportCsv);
|
||||
} catch (e) {
|
||||
trackError(e, Submit.DatabaseImportCsv);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: e.message
|
||||
});
|
||||
} finally {
|
||||
$isCsvImportInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => ($showCreateColumnSheet.show = false));
|
||||
</script>
|
||||
|
||||
{#key page.params.table}
|
||||
<Container expanded expandHeightButton style="background: var(--bgcolor-neutral-primary)">
|
||||
<Layout.Stack direction="column" gap="xl">
|
||||
<Layout.Stack direction="row" justifyContent="space-between">
|
||||
<Layout.Stack direction="row" gap="s">
|
||||
<ViewSelector
|
||||
onlyIcon
|
||||
ui="new"
|
||||
view={data.view}
|
||||
columns={tableColumns}
|
||||
hideView
|
||||
showAnyway
|
||||
isCustomTable />
|
||||
|
||||
<Filters
|
||||
onlyIcon
|
||||
query={data.query}
|
||||
columns={filterColumns}
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
analyticsSource="database_rows" />
|
||||
</Layout.Stack>
|
||||
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
|
||||
<Button
|
||||
secondary
|
||||
event={Click.DatabaseImportCsv}
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
on:click={() => (showImportCSV = true)}>
|
||||
Import CSV
|
||||
</Button>
|
||||
{#if !$isSmallViewport}
|
||||
<Button
|
||||
secondary
|
||||
event="create_row"
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
on:click={() => ($showRowCreateSheet.show = true)}>
|
||||
<Icon icon={IconPlus} slot="start" size="s" />
|
||||
Create row
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
icon
|
||||
size="s"
|
||||
secondary
|
||||
class="small-button-dimensions"
|
||||
on:click={() => {
|
||||
$expandTabs = !$expandTabs;
|
||||
preferences.setKey('tableHeaderExpanded', $expandTabs);
|
||||
}}>
|
||||
<Icon icon={!$expandTabs ? IconChevronDown : IconChevronUp} size="s" />
|
||||
</Button>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
{#if $isSmallViewport}
|
||||
<Button
|
||||
secondary
|
||||
event="create_row"
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
on:click={() => ($showRowCreateSheet.show = true)}>
|
||||
<Icon icon={IconPlus} slot="start" size="s" />
|
||||
Create row
|
||||
</Button>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
<div class="databases-spreadsheet">
|
||||
{#if hasColumns && hasValidColumns}
|
||||
{#if data.rows.total}
|
||||
<Divider />
|
||||
<SpreadSheet {data} bind:showRowCreateSheet={$showRowCreateSheet} />
|
||||
{:else if $hasPageQueries}
|
||||
<EmptySheet
|
||||
mode="rows-filtered"
|
||||
title="There are no rows that match your filters"
|
||||
customColumns={createTableColumns($table.columns, selected)}
|
||||
actions={{
|
||||
primary: {
|
||||
text: 'Clear filters',
|
||||
onClick: () => {
|
||||
queries.clearAll();
|
||||
queries.apply();
|
||||
trackEvent(Submit.FilterClear, {
|
||||
source: 'database_rows'
|
||||
});
|
||||
}
|
||||
}
|
||||
}} />
|
||||
{:else}
|
||||
<EmptySheet
|
||||
mode="rows"
|
||||
customColumns={createTableColumns($table.columns, selected)}
|
||||
showActions={$canWriteRows}
|
||||
actions={{
|
||||
primary: {
|
||||
text: 'Create rows',
|
||||
onClick: () => {
|
||||
$showRowCreateSheet.show = true;
|
||||
}
|
||||
},
|
||||
random: {
|
||||
onClick: () => {
|
||||
$randomDataModalState.show = true;
|
||||
}
|
||||
}
|
||||
}} />
|
||||
{/if}
|
||||
{:else}
|
||||
<EmptySheet
|
||||
mode="rows"
|
||||
title="You have no columns yet"
|
||||
showActions={$canWriteTables}
|
||||
actions={{
|
||||
primary: {
|
||||
text: 'Create column',
|
||||
onClick: async () => {
|
||||
$showCreateColumnSheet.show = true;
|
||||
}
|
||||
},
|
||||
random: {
|
||||
onClick: () => {
|
||||
$randomDataModalState.show = true;
|
||||
}
|
||||
}
|
||||
}} />
|
||||
{/if}
|
||||
</div>
|
||||
{/key}
|
||||
|
||||
{#if showImportCSV}
|
||||
<!-- CSVs can be text/plain or text/csv sometimes! -->
|
||||
<FilePicker
|
||||
{onSelect}
|
||||
showLocalFileBucket
|
||||
localFileBucketTitle="Upload CSV file"
|
||||
mimeTypeQuery="text/"
|
||||
allowedExtension="csv"
|
||||
bind:show={showImportCSV}
|
||||
gridImageDimensions={{
|
||||
imageHeight: 32,
|
||||
imageWidth: 32
|
||||
}} />
|
||||
{/if}
|
||||
|
||||
<CreateRow
|
||||
table={$table}
|
||||
bind:showSheet={$showRowCreateSheet.show}
|
||||
bind:existingData={$showRowCreateSheet.row} />
|
||||
|
||||
<style>
|
||||
:global(.small-button-dimensions) {
|
||||
width: 32px !important;
|
||||
height: 32px !important;
|
||||
}
|
||||
</style>
|
||||
<View {data} />
|
||||
|
||||
+6
-3
@@ -14,9 +14,11 @@
|
||||
|
||||
const tableId = $derived(page.params.table);
|
||||
|
||||
const path = $derived(
|
||||
const computedPath = $derived(
|
||||
`${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}/table-${tableId}`
|
||||
);
|
||||
let { path: _path, back: _back } = $props();
|
||||
const path = $derived(_path ?? computedPath);
|
||||
|
||||
const tabs = $derived(
|
||||
[
|
||||
@@ -57,9 +59,10 @@
|
||||
].filter((tab) => !tab.disabled)
|
||||
);
|
||||
|
||||
const link = $derived(
|
||||
const computedBack = $derived(
|
||||
`${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}`
|
||||
);
|
||||
const back = $derived(_back ?? computedBack);
|
||||
|
||||
const nonSheetPages = $derived.by(() => {
|
||||
const endings = ['table-[table]', 'table-[table]/columns', 'table-[table]/indexes'];
|
||||
@@ -79,7 +82,7 @@
|
||||
<Cover animate expanded collapsed={!$expandTabs} blocksize={$expandTabs ? '152px' : '90px'}>
|
||||
<svelte:fragment slot="header">
|
||||
<Layout.Stack direction="row" alignContent="center" alignItems="center" inline>
|
||||
<AnimatedTitle href={link} collapsed={!$expandTabs}>
|
||||
<AnimatedTitle href={back} collapsed={!$expandTabs}>
|
||||
{$table?.name}
|
||||
</AnimatedTitle>
|
||||
|
||||
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
<script lang="ts">
|
||||
import { Filters, hasPageQueries, queries } from '$lib/components/filters';
|
||||
import ViewSelector from '$lib/components/viewSelector.svelte';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import type { Column, ColumnType } from '$lib/helpers/types';
|
||||
import { Container } from '$lib/layout';
|
||||
import { preferences } from '$lib/stores/preferences';
|
||||
import { canWriteTables, canWriteRows } from '$lib/stores/roles';
|
||||
import { Icon, Layout, Divider } from '@appwrite.io/pink-svelte';
|
||||
import { View } from '$lib/helpers/load';
|
||||
|
||||
import {
|
||||
table,
|
||||
tableColumns,
|
||||
isCsvImportInProgress,
|
||||
showRowCreateSheet,
|
||||
showCreateColumnSheet,
|
||||
type Columns,
|
||||
randomDataModalState,
|
||||
expandTabs
|
||||
} from './store';
|
||||
import SpreadSheet from './spreadsheet.svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import FilePicker from '$lib/components/filePicker.svelte';
|
||||
import { page } from '$app/state';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { isSmallViewport } from '$lib/stores/viewport';
|
||||
import { IconChevronDown, IconChevronUp, IconPlus } from '@appwrite.io/pink-icons-svelte';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import EmptySheet from './layout/emptySheet.svelte';
|
||||
import CreateRow from './rows/create.svelte';
|
||||
import { onDestroy } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
data: {
|
||||
offset: number;
|
||||
limit: number;
|
||||
view: string;
|
||||
query: string;
|
||||
currentSort: {
|
||||
column: string | number | string[] | null;
|
||||
direction: string;
|
||||
};
|
||||
rows: Models.RowList<Models.DefaultRow>;
|
||||
organization?: { $id: string };
|
||||
project?: { teamId: string };
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
let showImportCSV = $state(false);
|
||||
|
||||
// todo: might need a type fix here.
|
||||
const filterColumns = writable<Column[]>([]);
|
||||
|
||||
function createTableColumns(columns: Columns[], selected: string[] = []): Column[] {
|
||||
return columns.map((column) => ({
|
||||
id: column.key,
|
||||
title: column.key,
|
||||
type: column.type as ColumnType,
|
||||
hide: !!selected?.includes(column.key),
|
||||
array: column?.array,
|
||||
format: 'format' in column && column?.format === 'enum' ? column.format : null,
|
||||
elements: 'elements' in column ? column.elements : null
|
||||
}));
|
||||
}
|
||||
|
||||
const selected = $derived(preferences.getCustomTableColumns(page.params.table));
|
||||
|
||||
$effect(() => {
|
||||
if ($table.columns) {
|
||||
const freshColumns = createTableColumns($table.columns, selected);
|
||||
tableColumns.set(freshColumns);
|
||||
filterColumns.set(freshColumns.filter((column) => !column.isAction));
|
||||
}
|
||||
});
|
||||
|
||||
const hasColumns = $derived(!!$table.columns.length);
|
||||
const hasValidColumns = $derived($table?.columns?.some((col) => col.status === 'available'));
|
||||
|
||||
async function onSelect(file: Models.File, localFile = false) {
|
||||
$isCsvImportInProgress = true;
|
||||
|
||||
try {
|
||||
await sdk
|
||||
.forProject(page.params.region, page.params.project)
|
||||
.migrations.createCsvMigration({
|
||||
bucketId: file.bucketId,
|
||||
fileId: file.$id,
|
||||
resourceId: `${page.params.database}:${page.params.table}`,
|
||||
internalFile: localFile
|
||||
});
|
||||
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: 'Rows import from csv has started'
|
||||
});
|
||||
|
||||
trackEvent(Submit.DatabaseImportCsv);
|
||||
} catch (e) {
|
||||
trackError(e, Submit.DatabaseImportCsv);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: e.message
|
||||
});
|
||||
} finally {
|
||||
$isCsvImportInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => ($showCreateColumnSheet.show = false));
|
||||
</script>
|
||||
|
||||
{#key page.params.table}
|
||||
<Container expanded expandHeightButton style="background: var(--bgcolor-neutral-primary)">
|
||||
<Layout.Stack direction="column" gap="xl">
|
||||
<Layout.Stack direction="row" justifyContent="space-between">
|
||||
<Layout.Stack direction="row" gap="s">
|
||||
<ViewSelector
|
||||
onlyIcon
|
||||
ui="new"
|
||||
view={data.view as View}
|
||||
columns={tableColumns}
|
||||
hideView
|
||||
showAnyway
|
||||
isCustomTable />
|
||||
|
||||
<Filters
|
||||
onlyIcon
|
||||
query={data.query}
|
||||
columns={filterColumns}
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
analyticsSource="database_rows" />
|
||||
</Layout.Stack>
|
||||
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
|
||||
<Button
|
||||
secondary
|
||||
event={Click.DatabaseImportCsv}
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
on:click={() => (showImportCSV = true)}>
|
||||
Import CSV
|
||||
</Button>
|
||||
{#if !$isSmallViewport}
|
||||
<Button
|
||||
secondary
|
||||
event="create_row"
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
on:click={() => ($showRowCreateSheet.show = true)}>
|
||||
<Icon icon={IconPlus} slot="start" size="s" />
|
||||
Create row
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
icon
|
||||
size="s"
|
||||
secondary
|
||||
class="small-button-dimensions"
|
||||
on:click={() => {
|
||||
$expandTabs = !$expandTabs;
|
||||
preferences.setKey('tableHeaderExpanded', $expandTabs);
|
||||
}}>
|
||||
<Icon icon={!$expandTabs ? IconChevronDown : IconChevronUp} size="s" />
|
||||
</Button>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
{#if $isSmallViewport}
|
||||
<Button
|
||||
secondary
|
||||
event="create_row"
|
||||
disabled={!(hasColumns && hasValidColumns)}
|
||||
on:click={() => ($showRowCreateSheet.show = true)}>
|
||||
<Icon icon={IconPlus} slot="start" size="s" />
|
||||
Create row
|
||||
</Button>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
<div class="databases-spreadsheet">
|
||||
{#if hasColumns && hasValidColumns}
|
||||
{#if data.rows.total}
|
||||
<Divider />
|
||||
<SpreadSheet
|
||||
data={data as unknown as import('./$types.js').PageData}
|
||||
bind:showRowCreateSheet={$showRowCreateSheet} />
|
||||
{:else if $hasPageQueries}
|
||||
<EmptySheet
|
||||
mode="rows-filtered"
|
||||
title="There are no rows that match your filters"
|
||||
customColumns={createTableColumns($table.columns, selected)}
|
||||
actions={{
|
||||
primary: {
|
||||
text: 'Clear filters',
|
||||
onClick: () => {
|
||||
queries.clearAll();
|
||||
queries.apply();
|
||||
trackEvent(Submit.FilterClear, {
|
||||
source: 'database_rows'
|
||||
});
|
||||
}
|
||||
}
|
||||
}} />
|
||||
{:else}
|
||||
<EmptySheet
|
||||
mode="rows"
|
||||
customColumns={createTableColumns($table.columns, selected)}
|
||||
showActions={$canWriteRows}
|
||||
actions={{
|
||||
primary: {
|
||||
text: 'Create rows',
|
||||
onClick: () => {
|
||||
$showRowCreateSheet.show = true;
|
||||
}
|
||||
},
|
||||
random: {
|
||||
onClick: () => {
|
||||
$randomDataModalState.show = true;
|
||||
}
|
||||
}
|
||||
}} />
|
||||
{/if}
|
||||
{:else}
|
||||
<EmptySheet
|
||||
mode="rows"
|
||||
title="You have no columns yet"
|
||||
showActions={$canWriteTables}
|
||||
actions={{
|
||||
primary: {
|
||||
text: 'Create column',
|
||||
onClick: async () => {
|
||||
$showCreateColumnSheet.show = true;
|
||||
}
|
||||
},
|
||||
random: {
|
||||
onClick: () => {
|
||||
$randomDataModalState.show = true;
|
||||
}
|
||||
}
|
||||
}} />
|
||||
{/if}
|
||||
</div>
|
||||
{/key}
|
||||
|
||||
{#if showImportCSV}
|
||||
<!-- CSVs can be text/plain or text/csv sometimes! -->
|
||||
<FilePicker
|
||||
{onSelect}
|
||||
showLocalFileBucket
|
||||
localFileBucketTitle="Upload CSV file"
|
||||
mimeTypeQuery="text/"
|
||||
allowedExtension="csv"
|
||||
bind:show={showImportCSV}
|
||||
gridImageDimensions={{
|
||||
imageHeight: 32,
|
||||
imageWidth: 32
|
||||
}} />
|
||||
{/if}
|
||||
|
||||
<CreateRow
|
||||
table={$table}
|
||||
bind:showSheet={$showRowCreateSheet.show}
|
||||
bind:existingData={$showRowCreateSheet.row} />
|
||||
|
||||
<style>
|
||||
:global(.small-button-dimensions) {
|
||||
width: 32px !important;
|
||||
height: 32px !important;
|
||||
}
|
||||
</style>
|
||||
+7
-5
@@ -12,7 +12,6 @@
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { showCreate, tableViewColumns } from './store';
|
||||
import { Card, Empty, Icon, Layout, Table as PinkTable } from '@appwrite.io/pink-svelte';
|
||||
import { canWriteTables } from '$lib/stores/roles';
|
||||
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { app } from '$lib/stores/app';
|
||||
@@ -25,6 +24,7 @@
|
||||
offset,
|
||||
view,
|
||||
search,
|
||||
canWriteTables,
|
||||
createTableUrl
|
||||
}: {
|
||||
tables: { total: number; tables: Models.Table[] };
|
||||
@@ -32,11 +32,13 @@
|
||||
offset: number;
|
||||
view: View;
|
||||
search: string | null;
|
||||
canWriteTables: boolean;
|
||||
createTableUrl: (table: Models.Table) => string;
|
||||
} = $props();
|
||||
|
||||
const clearSearchHref = page.url.pathname;
|
||||
const databaseId = page.params.database;
|
||||
|
||||
$inspect($showCreate);
|
||||
</script>
|
||||
|
||||
<Layout.Stack direction="row" justifyContent="space-between">
|
||||
@@ -51,7 +53,7 @@
|
||||
hideColumns={!tables.total}
|
||||
hideView={!tables.total} />
|
||||
|
||||
{#if $canWriteTables}
|
||||
{#if canWriteTables}
|
||||
<Button event="create_table" on:click={() => ($showCreate = true)}>
|
||||
<Icon icon={IconPlus} slot="start" size="s" />
|
||||
Create table
|
||||
@@ -63,7 +65,7 @@
|
||||
{#if tables.total}
|
||||
{#if view === 'grid'}
|
||||
<CardContainer
|
||||
disableEmpty={!$canWriteTables}
|
||||
disableEmpty={!canWriteTables}
|
||||
total={tables.total}
|
||||
{offset}
|
||||
event="table"
|
||||
@@ -123,7 +125,7 @@
|
||||
text
|
||||
event="empty_documentation"
|
||||
ariaLabel={`create table`}>Documentation</Button>
|
||||
{#if $canWriteTables}
|
||||
{#if canWriteTables}
|
||||
<Button
|
||||
secondary
|
||||
on:click={() => {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const projectId = page.params.project;
|
||||
const path = `${base}/project-${page.params.region}-${projectId}/databases`;
|
||||
export let path = `${base}/project-${page.params.region}-${projectId}/databases`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
CardContainer,
|
||||
GridItem1
|
||||
} from '$lib/components';
|
||||
import { canWriteDatabases } from '$lib/stores/roles';
|
||||
import { columns } from './store';
|
||||
import { Icon, Layout, Table as PinkTable, Tooltip } from '@appwrite.io/pink-svelte';
|
||||
import Create from './create.svelte';
|
||||
@@ -31,6 +30,7 @@
|
||||
offset,
|
||||
view,
|
||||
search,
|
||||
canWriteDatabases,
|
||||
getDatabaseUrl
|
||||
}: {
|
||||
databases: { total: number; databases: Models.Database[] };
|
||||
@@ -41,6 +41,7 @@
|
||||
offset: number;
|
||||
view: View;
|
||||
search: string | null;
|
||||
canWriteDatabases: boolean;
|
||||
getDatabaseUrl: (database: Models.Database, firstTableId?: string | null) => string | null;
|
||||
} = $props();
|
||||
|
||||
@@ -69,8 +70,8 @@
|
||||
</Layout.Stack>
|
||||
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
|
||||
<ViewSelector {columns} {view} hideColumns={!databases.total} hideView={!databases.total} />
|
||||
{#if $canWriteDatabases}
|
||||
<Button event="create_database">
|
||||
{#if canWriteDatabases}
|
||||
<Button event="create_database" on:click={() => (showCreate = true)}>
|
||||
<Icon icon={IconPlus} slot="start" size="s" />
|
||||
Create database
|
||||
</Button>
|
||||
@@ -81,7 +82,7 @@
|
||||
{#if databases.total}
|
||||
{#if view === 'grid'}
|
||||
<CardContainer
|
||||
disableEmpty={!$canWriteDatabases}
|
||||
disableEmpty={!canWriteDatabases}
|
||||
total={databases.total}
|
||||
{offset}
|
||||
event="database"
|
||||
@@ -176,7 +177,7 @@
|
||||
single
|
||||
href="https://appwrite.io/docs/products/databases/databases"
|
||||
target="database"
|
||||
allowCreate={$canWriteDatabases} />
|
||||
allowCreate={canWriteDatabases} />
|
||||
{/if}
|
||||
|
||||
<Create bind:showCreate on:created={onCreated} />
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Cover } from '$lib/layout';
|
||||
import { Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/messaging`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/messaging`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import { isCloud } from '$lib/system';
|
||||
import { Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/settings`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/settings`;
|
||||
const tabs: TabElement[] = [
|
||||
{
|
||||
href: path,
|
||||
|
||||
+2
-1
@@ -6,11 +6,12 @@
|
||||
import { webhook } from './store';
|
||||
|
||||
const projectId = page.params.project;
|
||||
export let back = `${base}/project-${page.params.region}-${projectId}/settings/webhooks`;
|
||||
</script>
|
||||
|
||||
<Cover>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle href={`${base}/project-${page.params.region}-${projectId}/settings/webhooks`}>
|
||||
<CoverTitle href={back}>
|
||||
{$webhook?.name}
|
||||
</CoverTitle>
|
||||
<Id value={$webhook?.$id} event="webhook">{$webhook?.$id}</Id>
|
||||
|
||||
+2
-2
@@ -7,12 +7,12 @@
|
||||
|
||||
const projectId = page.params.project;
|
||||
const bucketId = page.params.bucket;
|
||||
export let back = `${base}/project-${page.params.region}-${projectId}/storage/bucket-${bucketId}`;
|
||||
</script>
|
||||
|
||||
<Cover>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle
|
||||
href={`${base}/project-${page.params.region}-${projectId}/storage/bucket-${bucketId}`}>
|
||||
<CoverTitle href={back}>
|
||||
{$file?.name}
|
||||
</CoverTitle>
|
||||
<Id value={$file?.$id} event="file">{$file?.$id}</Id>
|
||||
|
||||
+3
-2
@@ -9,7 +9,8 @@
|
||||
|
||||
const projectId = page.params.project;
|
||||
const bucketId = page.params.bucket;
|
||||
const path = `${base}/project-${page.params.region}-${projectId}/storage/bucket-${bucketId}`;
|
||||
export let path = `${base}/project-${page.params.region}-${projectId}/storage/bucket-${bucketId}`;
|
||||
export let back = `${base}/project-${page.params.region}-${projectId}/storage`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
@@ -34,7 +35,7 @@
|
||||
|
||||
<Cover>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle href={`${base}/project-${page.params.region}-${projectId}/storage`}>
|
||||
<CoverTitle href={back}>
|
||||
{$bucket?.name}
|
||||
</CoverTitle>
|
||||
{#if $bucket?.$id}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Cover } from '$lib/layout';
|
||||
import { Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const path = `${base}/project-${page.params.region}-${page.params.project}/storage`;
|
||||
export let path = `${base}/project-${page.params.region}-${page.params.project}/storage`;
|
||||
const tabs = [
|
||||
{
|
||||
href: path,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<script>
|
||||
import { page } from '$app/state';
|
||||
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
{#if page.data.header}
|
||||
{@const Header = page.data.header}
|
||||
<Header path={page.data.path} back={page.data.back} />
|
||||
{/if}
|
||||
|
||||
{@render children()}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
|
||||
export const load: LayoutLoad = async ({ params }) => {
|
||||
const project = await sdk.forConsole.projects.get({ projectId: params.project });
|
||||
const organization = await sdk.forConsole.teams.get({ teamId: project.teamId });
|
||||
const currentPlan = await sdk.forConsole.billing.getOrganizationPlan(organization.$id);
|
||||
const { roles, scopes } = await sdk.forConsole.billing.getRoles(organization.$id);
|
||||
|
||||
return {
|
||||
header: null,
|
||||
project,
|
||||
organization,
|
||||
currentPlan,
|
||||
roles,
|
||||
scopes
|
||||
};
|
||||
};
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { base } from '$app/paths';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/header.svelte';
|
||||
|
||||
export const load: LayoutLoad = async ({ params }) => {
|
||||
// Minimal layout data for embeds; no UI wrapping.
|
||||
const project = await sdk.forConsole.projects.get(params.project);
|
||||
return { project } as const;
|
||||
return {
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/auth/view.svelte';
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
let { data } = $props();
|
||||
|
||||
const createUserUrl = (user: Models.User<{}>) =>
|
||||
`${base}/embed/project-${page.params.region}-${page.params.project}/auth/user-${user.$id}`;
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<Container>
|
||||
<View
|
||||
users={data.users}
|
||||
limit={data.limit}
|
||||
offset={data.offset}
|
||||
search={data.search}
|
||||
{createUserUrl} />
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
import UpdatePasswordDictionary from '$routes/(console)/project-[region]-[project]/auth/security/updatePasswordDictionary.svelte';
|
||||
import UpdatePasswordHistory from '$routes/(console)/project-[region]-[project]/auth/security/updatePasswordHistory.svelte';
|
||||
import UpdatePersonalDataCheck from '$routes/(console)/project-[region]-[project]/auth/security/updatePersonalDataCheck.svelte';
|
||||
@@ -11,7 +11,7 @@
|
||||
import UpdateSessionInvalidation from '$routes/(console)/project-[region]-[project]/auth/security/updateSessionInvalidation.svelte';
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<Container>
|
||||
<UpdateUsersLimit />
|
||||
<UpdateSessionLength />
|
||||
<UpdateSessionsLimit />
|
||||
@@ -21,4 +21,4 @@
|
||||
<UpdateSessionAlerts />
|
||||
<UpdateSessionInvalidation />
|
||||
<UpdateMembershipPrivacy />
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/auth/teams/view.svelte';
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
let { data } = $props();
|
||||
|
||||
const createTeamUrl = (team: Models.Team<Record<string, unknown>>) =>
|
||||
`${base}/embed/project-${page.params.region}-${page.params.project}/auth/teams/team-${team.$id}`;
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<Container>
|
||||
<View
|
||||
teams={data.teams}
|
||||
limit={data.limit}
|
||||
offset={data.offset}
|
||||
search={data.search}
|
||||
{createTeamUrl} />
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/teams/team-[team]/header.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: PageLoad = async ({ params }) => {
|
||||
const team = await sdk
|
||||
.forProject(params.region, params.project)
|
||||
.teams.get({ teamId: params.team });
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth/teams`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/teams/team-${params.team}`,
|
||||
team
|
||||
};
|
||||
};
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import TeamActivityPage from '$routes/(console)/project-[region]-[project]/auth/teams/team-[team]/activity/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<TeamActivityPage data={data as any} />
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/teams/team-[team]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { getLimit, getPage, pageToOffset } from '$lib/helpers/load';
|
||||
import { PAGE_LIMIT } from '$lib/constants';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
|
||||
export const load: PageLoad = async ({ params, url, route }) => {
|
||||
const page = getPage(url);
|
||||
const limit = getLimit(url, route, PAGE_LIMIT);
|
||||
const offset = pageToOffset(page, limit);
|
||||
|
||||
const [team, logs] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).teams.get({ teamId: params.team }),
|
||||
sdk.forProject(params.region, params.project).teams.listLogs({
|
||||
teamId: params.team,
|
||||
queries: [Query.limit(limit), Query.offset(offset)]
|
||||
})
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth/teams`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/teams/team-${params.team}`,
|
||||
team,
|
||||
offset,
|
||||
limit,
|
||||
logs
|
||||
};
|
||||
};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import TeamMembersPage from '$routes/(console)/project-[region]-[project]/auth/teams/team-[team]/members/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<TeamMembersPage data={data as any} />
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/teams/team-[team]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { getLimit, getPage, getSearch, pageToOffset } from '$lib/helpers/load';
|
||||
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
|
||||
export const load: PageLoad = async ({ params, depends, url, route }) => {
|
||||
depends(Dependencies.MEMBERSHIPS);
|
||||
|
||||
const page = getPage(url);
|
||||
const search = getSearch(url);
|
||||
const limit = getLimit(url, route, PAGE_LIMIT);
|
||||
const offset = pageToOffset(page, limit);
|
||||
|
||||
const [team, memberships] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).teams.get({ teamId: params.team }),
|
||||
sdk.forProject(params.region, params.project).teams.listMemberships({
|
||||
teamId: params.team,
|
||||
queries: [Query.limit(limit), Query.offset(offset), Query.orderDesc('')],
|
||||
search
|
||||
})
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth/teams`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/teams/team-${params.team}`,
|
||||
team,
|
||||
offset,
|
||||
search,
|
||||
limit,
|
||||
memberships
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/user-[user]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: PageLoad = async ({ params }) => {
|
||||
const [user, userFactors] = await Promise.all([
|
||||
@@ -7,5 +9,11 @@ export const load: PageLoad = async ({ params }) => {
|
||||
sdk.forProject(params.region, params.project).users.listMfaFactors(params.user)
|
||||
]);
|
||||
|
||||
return { user, userFactors };
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/user-${params.user}`,
|
||||
user,
|
||||
userFactors
|
||||
};
|
||||
};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import UserActivityPage from '$routes/(console)/project-[region]-[project]/auth/user-[user]/activity/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UserActivityPage data={data as any} />
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/user-[user]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { getLimit, getPage, pageToOffset } from '$lib/helpers/load';
|
||||
import { PAGE_LIMIT } from '$lib/constants';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
|
||||
export const load: PageLoad = async ({ params, url, route }) => {
|
||||
const page = getPage(url);
|
||||
const limit = getLimit(url, route, PAGE_LIMIT);
|
||||
const offset = pageToOffset(page, limit);
|
||||
|
||||
const [user, logs] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).users.get(params.user),
|
||||
sdk.forProject(params.region, params.project).users.listLogs({
|
||||
userId: params.user,
|
||||
queries: [Query.limit(limit), Query.offset(offset)]
|
||||
})
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/user-${params.user}`,
|
||||
user,
|
||||
offset,
|
||||
limit,
|
||||
logs
|
||||
};
|
||||
};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import UserIdentitiesPage from '$routes/(console)/project-[region]-[project]/auth/user-[user]/identities/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UserIdentitiesPage data={data as any} />
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/user-[user]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { queries, queryParamToMap } from '$lib/components/filters';
|
||||
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
|
||||
import { getLimit, getPage, getQuery, getSearch, pageToOffset } from '$lib/helpers/load';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
|
||||
export const load: PageLoad = async ({ params, url, route, depends }) => {
|
||||
depends(Dependencies.USER_IDENTITIES);
|
||||
|
||||
const page = getPage(url);
|
||||
const limit = getLimit(url, route, PAGE_LIMIT);
|
||||
const offset = pageToOffset(page, limit);
|
||||
const query = getQuery(url);
|
||||
const search = getSearch(url);
|
||||
|
||||
const parsedQueries = queryParamToMap(query || '[]');
|
||||
queries.set(parsedQueries);
|
||||
|
||||
const [user, identities] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).users.get(params.user),
|
||||
sdk.forProject(params.region, params.project).users.listIdentities({
|
||||
queries: [
|
||||
Query.equal('userId', params.user),
|
||||
Query.limit(limit),
|
||||
Query.offset(offset),
|
||||
Query.orderDesc(''),
|
||||
...parsedQueries.values()
|
||||
],
|
||||
search
|
||||
})
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/user-${params.user}`,
|
||||
user,
|
||||
offset,
|
||||
limit,
|
||||
query,
|
||||
search,
|
||||
identities
|
||||
};
|
||||
};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import UserMembershipsPage from '$routes/(console)/project-[region]-[project]/auth/user-[user]/memberships/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UserMembershipsPage data={data as any} />
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/user-[user]/header.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: PageLoad = async ({ params }) => {
|
||||
const [codes, user, memberships] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).locale.listCodes(),
|
||||
sdk.forProject(params.region, params.project).users.get(params.user),
|
||||
sdk.forProject(params.region, params.project).users.listMemberships({ userId: params.user })
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/user-${params.user}`,
|
||||
user,
|
||||
localeCodes: codes.localeCodes,
|
||||
memberships
|
||||
};
|
||||
};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import UserSessionsPage from '$routes/(console)/project-[region]-[project]/auth/user-[user]/sessions/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UserSessionsPage data={data as any} />
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/user-[user]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
|
||||
export const load: PageLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.SESSIONS);
|
||||
|
||||
const [user, sessions] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).users.get(params.user),
|
||||
sdk.forProject(params.region, params.project).users.listSessions({ userId: params.user })
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/user-${params.user}`,
|
||||
user,
|
||||
sessions
|
||||
};
|
||||
};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import UserTargetsPage from '$routes/(console)/project-[region]-[project]/auth/user-[user]/targets/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UserTargetsPage data={data as any} />
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/auth/user-[user]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { queries, queryParamToMap } from '$lib/components/filters';
|
||||
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
|
||||
import { getLimit, getPage, getQuery, pageToOffset } from '$lib/helpers/load';
|
||||
import { Query, type Models } from '@appwrite.io/console';
|
||||
|
||||
export const load: PageLoad = async ({ params, url, route, depends }) => {
|
||||
depends(Dependencies.USER_TARGETS);
|
||||
|
||||
const page = getPage(url);
|
||||
const limit = getLimit(url, route, PAGE_LIMIT);
|
||||
const offset = pageToOffset(page, limit);
|
||||
const query = getQuery(url);
|
||||
|
||||
const parsedQueries = queryParamToMap(query || '[]');
|
||||
queries.set(parsedQueries);
|
||||
|
||||
const [user, targets] = await Promise.all([
|
||||
sdk.forProject(params.region, params.project).users.get(params.user),
|
||||
sdk.forProject(params.region, params.project).users.listTargets({
|
||||
userId: params.user,
|
||||
queries: [
|
||||
Query.limit(limit),
|
||||
Query.offset(offset),
|
||||
Query.orderDesc(''),
|
||||
...parsedQueries.values()
|
||||
]
|
||||
})
|
||||
]);
|
||||
|
||||
const promisesById: Record<string, Promise<Models.Provider>> = {};
|
||||
targets.targets.forEach((target) => {
|
||||
if (target.providerId && !promisesById[target.providerId]) {
|
||||
promisesById[target.providerId] = sdk
|
||||
.forProject(params.region, params.project)
|
||||
.messaging.getProvider({ providerId: target.providerId });
|
||||
}
|
||||
});
|
||||
|
||||
const providersById: Record<string, Models.Provider> = {};
|
||||
const resolved = await Promise.allSettled(Object.values(promisesById));
|
||||
resolved.forEach((result) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
const provider = result.value;
|
||||
providersById[provider.$id] = provider;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/auth`,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/auth/user-${params.user}`,
|
||||
user,
|
||||
offset,
|
||||
limit,
|
||||
query,
|
||||
targets,
|
||||
providersById
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { base } from '$app/paths';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/databases/header.svelte';
|
||||
|
||||
export const load: LayoutLoad = async ({ parent }) => {
|
||||
export const load: LayoutLoad = async ({ parent, params }) => {
|
||||
const { project } = await parent();
|
||||
return { project };
|
||||
return {
|
||||
project,
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/databases`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/databases/view.svelte';
|
||||
let { data } = $props();
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<Container>
|
||||
<View
|
||||
databases={data?.databases || { total: 0, databases: [] }}
|
||||
tables={data?.tables || {}}
|
||||
policies={data?.policies || {}}
|
||||
lastBackups={data?.lastBackups || {}}
|
||||
limit={data?.limit || 25}
|
||||
offset={data?.offset || 0}
|
||||
view={data?.view || 'grid'}
|
||||
search={data?.search || null}
|
||||
databases={data.databases}
|
||||
tables={data.tables}
|
||||
policies={data.policies}
|
||||
lastBackups={data.lastBackups}
|
||||
limit={data.limit}
|
||||
offset={data.offset}
|
||||
view={data.view}
|
||||
search={data.search}
|
||||
canWriteDatabases={true}
|
||||
{getDatabaseUrl} />
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
+5
@@ -1,6 +1,8 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { base } from '$app/paths';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.DATABASE);
|
||||
@@ -10,6 +12,9 @@ export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
});
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/databases/database-${params.database}`,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/databases`,
|
||||
database
|
||||
};
|
||||
};
|
||||
|
||||
+14
-2
@@ -3,15 +3,25 @@
|
||||
import { page } from '$app/state';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/databases/database-[database]/view.svelte';
|
||||
import CreateTable from '$routes/(console)/project-[region]-[project]/databases/database-[database]/createTable.svelte';
|
||||
import { showCreate } from '$routes/(console)/project-[region]-[project]/databases/database-[database]/store';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { goto } from '$app/navigation';
|
||||
let { data } = $props();
|
||||
|
||||
const createTableUrl = (table) => {
|
||||
function createTableUrl(table: Models.Table) {
|
||||
return `${base}/embed/project-${page.params.region}-${page.params.project}/databases/database-${page.params.database}/table-${table.$id}`;
|
||||
};
|
||||
}
|
||||
|
||||
async function handleCreate(event: CustomEvent<Models.Table>) {
|
||||
$showCreate = false;
|
||||
await goto(createTableUrl(event.detail));
|
||||
}
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<View
|
||||
canWriteTables
|
||||
tables={data.tables}
|
||||
limit={data.limit}
|
||||
offset={data.offset}
|
||||
@@ -19,3 +29,5 @@
|
||||
search={data.search}
|
||||
{createTableUrl} />
|
||||
</Layout.Stack>
|
||||
|
||||
<CreateTable bind:showCreate={$showCreate} on:created={handleCreate} />
|
||||
|
||||
+5
@@ -1,11 +1,16 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { base } from '$app/paths';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/header.svelte';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.TABLE);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/databases/database-${params.database}/table-${params.table}`,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/databases/database-${params.database}`,
|
||||
table: await sdk.forProject(params.region, params.project).tablesDB.getTable({
|
||||
databaseId: params.database,
|
||||
tableId: params.table
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import TablePage from '$routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+page.svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/view.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<TablePage {data} />
|
||||
<View {data} />
|
||||
</Layout.Stack>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/messaging/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: LayoutLoad = async ({ params }) => {
|
||||
return {
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/messaging`
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/settings/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: LayoutLoad = async ({ params }) => {
|
||||
return {
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/settings`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
import UpdateName from '$routes/(console)/project-[region]-[project]/settings/updateName.svelte';
|
||||
import DeleteProject from '$routes/(console)/project-[region]-[project]/settings/deleteProject.svelte';
|
||||
import { canWriteProjects } from '$lib/stores/roles';
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<UpdateName />
|
||||
{#if $canWriteProjects}
|
||||
<DeleteProject />
|
||||
{/if}
|
||||
</Container>
|
||||
@@ -0,0 +1,2 @@
|
||||
export { load } from '$routes/(console)/project-[region]-[project]/settings/+page.ts';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import DomainsPage from '$routes/(console)/project-[region]-[project]/settings/domains/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<DomainsPage {data} />
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { load } from '$routes/(console)/project-[region]-[project]/settings/domains/+page.ts';
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import AddDomainPage from '$routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<AddDomainPage {data} />
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { load } from '$routes/(console)/project-[region]-[project]/settings/domains/add-domain/+page.ts';
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import VerifyDomainPage from '$routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<VerifyDomainPage {data} />
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { load } from '$routes/(console)/project-[region]-[project]/settings/domains/add-domain/verify-[domain]/+page.ts';
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import MigrationsPage from '$routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<MigrationsPage {data} />
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { load } from '$routes/(console)/project-[region]-[project]/settings/migrations/+page.ts';
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import SMTPPage from '$routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte';
|
||||
</script>
|
||||
|
||||
<SMTPPage />
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import UsagePage from '$routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<UsagePage {data} />
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { load } from '$routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.ts';
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/storage/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: LayoutLoad = async ({ parent }) => {
|
||||
export const load: LayoutLoad = async ({ parent, params }) => {
|
||||
const { project } = await parent();
|
||||
return { project };
|
||||
return {
|
||||
project,
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/storage`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/storage/view.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
@@ -12,7 +12,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<Container>
|
||||
<View
|
||||
buckets={data?.buckets || { total: 0, buckets: [] }}
|
||||
limit={data?.limit || 25}
|
||||
@@ -20,4 +20,4 @@
|
||||
view={data?.view || 'grid'}
|
||||
search={data?.search || null}
|
||||
{createBucketUrl} />
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
+5
@@ -1,11 +1,16 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.BUCKET);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
path: `${base}/embed/project-${params.region}-${params.project}/storage/bucket-${params.bucket}`,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/storage`,
|
||||
bucket: await sdk.forProject(params.region, params.project).storage.getBucket({
|
||||
bucketId: params.bucket
|
||||
})
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import Container from '$lib/layout/container.svelte';
|
||||
import View from '$routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/view.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
@@ -12,11 +12,11 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<Container>
|
||||
<View
|
||||
files={data?.files || { total: 0, files: [] }}
|
||||
limit={data?.limit || 25}
|
||||
offset={data?.offset || 0}
|
||||
search={data?.search || null}
|
||||
{createFileUrl} />
|
||||
</Layout.Stack>
|
||||
</Container>
|
||||
|
||||
+4
@@ -1,12 +1,16 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import Header from '$routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/file-[file]/header.svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.FILE);
|
||||
depends(Dependencies.FILE_TOKENS);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
back: `${base}/embed/project-${params.region}-${params.project}/storage/bucket-${params.bucket}`,
|
||||
file: await sdk
|
||||
.forProject(params.region, params.project)
|
||||
.storage.getFile({ bucketId: params.bucket, fileId: params.file }),
|
||||
|
||||
+2
-3
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import FilePage from '$routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/file-[file]/+page.svelte';
|
||||
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<Layout.Stack>
|
||||
<FilePage {data} />
|
||||
<FilePage />
|
||||
<!-- Console page uses stores provided by layout; no props needed. -->
|
||||
</Layout.Stack>
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import BucketSettingsPage from '$routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/+page.svelte';
|
||||
let { data } = $props();
|
||||
</script>
|
||||
|
||||
<BucketSettingsPage data={data as any} />
|
||||
|
||||
@@ -34,9 +34,6 @@ export default defineConfig({
|
||||
'zrender'
|
||||
]
|
||||
},
|
||||
server: {
|
||||
port: 3000
|
||||
},
|
||||
test: {
|
||||
projects: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user