diff --git a/src/lib/components/filters/store.ts b/src/lib/components/filters/store.ts
index 6be45f6a0..970874334 100644
--- a/src/lib/components/filters/store.ts
+++ b/src/lib/components/filters/store.ts
@@ -1,10 +1,10 @@
import { goto } from '$app/navigation';
-import { derived, get, writable } from 'svelte/store';
import { page } from '$app/stores';
import deepEqual from 'deep-equal';
-import type { Column, ColumnType } from '$lib/helpers/types';
import { Query } from '@appwrite.io/console';
import { toLocaleDateTime } from '$lib/helpers/date';
+import { derived, get, writable } from 'svelte/store';
+import type { SheetColumn, SheetColumnType } from '$lib/helpers/types';
export type TagValue = {
tag: string;
@@ -14,7 +14,7 @@ export type TagValue = {
export type Operator = {
toTag: (attribute: string, input?: string | number | string[], type?: string) => TagValue;
toQuery: (attribute: string, input?: string | number | string[]) => string;
- types: ColumnType[];
+ types: SheetColumnType[];
hideInput?: boolean;
};
@@ -33,7 +33,7 @@ function initQueries(initialValue = new Map()) {
type AddFilterArgs = {
operator: Operator;
- column: Column;
+ column: SheetColumn;
value: string | number | string[];
};
@@ -91,14 +91,14 @@ export const tags = derived(queries, ($queries) => Array.from($queries.keys()));
/* eslint @typescript-eslint/no-explicit-any: 'off' */
export function addFilter(
- columns: Column[],
+ columns: SheetColumn[],
columnId: string,
operatorKey: string,
value: any, // We cast to any to not cause type errors in the input components
arrayValues: string[] = []
) {
const operator = operatorKey ? operators[operatorKey] : null;
- const column = columns.find((c) => c.id === columnId) as Column;
+ const column = columns.find((c) => c.id === columnId) as SheetColumn;
if (!column || !operator) return;
if (column.array) {
queries.addFilter({ column, operator, value: arrayValues });
@@ -135,7 +135,7 @@ const operatorsDefault = new Map<
ValidOperators,
{
query: (attr: string, input: string | number | string[]) => string;
- types: ColumnType[];
+ types: SheetColumnType[];
hideInput?: boolean;
}
>([
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte
index e097213a1..ab482f31b 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte
@@ -20,11 +20,12 @@
import { addNotification } from '$lib/stores/notifications';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { isSmallViewport } from '$lib/stores/viewport';
- import { base } from '$app/paths';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import type { Models } from '@appwrite.io/console';
- import EmptySheet from './emptySheet.svelte';
+ import EmptySheet from './layout/emptySheet.svelte';
import CreateRecord from './createRecord.svelte';
+ import { goto } from '$app/navigation';
+ import { base } from '$app/paths';
export let data: PageData;
@@ -135,7 +136,7 @@
{#if hasAttributes && hasValidAttributes}
{#if data.documents.total}
-
+
{:else if $hasPageQueries}
@@ -159,10 +160,30 @@
{:else}
- (showRecordsCreateSheet = true)} />
+ {
+ showRecordsCreateSheet = true;
+ }
+ }
+ }} />
{/if}
{:else}
- (showRecordsCreateSheet = true)} />
+ {
+ await goto(
+ `${base}/project-${page.params.region}-${page.params.project}/databases/database-${page.params.database}/collection-${page.params.collection}/attributes`
+ );
+ }
+ }
+ }} />
{/if}
{/key}
@@ -186,6 +207,4 @@
}} />
{/if}
-{#if showRecordsCreateSheet}
-
-{/if}
+
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.ts
index 2f22ca60f..a8a40b4c1 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.ts
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.ts
@@ -8,7 +8,8 @@ import { queries, queryParamToMap } from '$lib/components/filters';
export const load: PageLoad = async ({ params, depends, url, route }) => {
depends(Dependencies.DOCUMENTS);
const page = getPage(url);
- const limit = getLimit(url, route, 18 /*PAGE_LIMIT*/);
+ // TODO: apply pagination
+ const limit = getLimit(url, route, 96 /*PAGE_LIMIT*/);
const view = getView(url, route, View.Grid);
const offset = pageToOffset(page, limit);
const query = getQuery(url);
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte
index e94163b7b..211b1dcad 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/+page.svelte
@@ -1,7 +1,4 @@
-
-
- Attributes
+
+
+
{#if $canWriteCollections}
{/if}
+
+
{#if $attributes.length}
-
-
- Key
- Type
- Default value
-
-
- {#each $attributes as attribute, index}
- {@const option = attributeOptions.find((option) => option.type === attribute.type)}
-
-
-
- {#if isRelationship(attribute)}
-
- {:else if 'format' in attribute && attribute.format}
- {@const icon = attributeFormatIcon[attribute?.format]}
-
- {:else}
-
- {/if}
-
-
- {attribute.key}
- {#if isString(attribute) && attribute.encrypt}
-
-
- Encrypted
-
+
+
+
+ Column name
+ Indexed
+ Default value
+
+
+
+ {#each $attributes as attribute, index}
+ {@const option = attributeOptions.find(
+ (option) => option.type === attribute.type
+ )}
+
+
+
+ {#if isRelationship(attribute)}
+
+ {:else if 'format' in attribute && attribute.format}
+ {@const icon = attributeFormatIcon[attribute?.format]}
+
+ {:else}
+
+ {/if}
+
+
+ {attribute.key}
+ {#if isString(attribute) && attribute.encrypt}
+
+
+ Encrypted
+
+ {/if}
+
+ {#if attribute.status !== 'available'}
+
+ {#if attribute.error}
+ {
+ e.preventDefault();
+ error = attribute.error;
+ showFailed = true;
+ }}>Details
+ {/if}
+ {:else if attribute.required}
+
{/if}
- {#if attribute.status !== 'available'}
-
- {#if attribute.error}
- {
- e.preventDefault();
- error = attribute.error;
- showFailed = true;
- }}>Details
- {/if}
- {:else if attribute.required}
-
- {/if}
-
-
-
- {#if 'format' in attribute && attribute.format}
- {attribute.format}
- {:else}
-
- {attribute.type}
- {#if isRelationship(attribute)}
-
- with {attribute?.key}
-
- {/if}
-
- {/if}
-
- {attribute.array ? '[]' : ''}
-
-
-
- {attribute?.default !== null && attribute?.default !== undefined
- ? attribute?.default
- : '-'}
-
-
- {#if $isCsvImportInProgress}
-
-
-
-
-
- {:else}
-
-
-
-
-
- {
- toggle(event);
- showEdit = true;
- selectedAttribute = attribute;
- showDropdown[index] = false;
- }}>
- Update
-
- {#if !isRelationship(attribute)}
+
+
+ {@const isIndexed = $indexes.some((index) =>
+ index.attributes.includes(attribute.key)
+ )}
+
+
+
+ {@const _default =
+ attribute?.default !== null && attribute?.default !== undefined
+ ? attribute?.default
+ : null}
+
+ {#if _default === null}
+
+ {:else}
+ {_default}
+ {/if}
+
+
+ {#if $isCsvImportInProgress}
+
+
+
+
+
+ {:else}
+
+
+
+
+
+
{
toggle(event);
+ showEdit = true;
selectedAttribute = attribute;
- showCreateIndex = true;
showDropdown[index] = false;
}}>
- Create index
+ Update
- {/if}
- {#if attribute.status !== 'processing'}
- {
- toggle(event);
- showDelete = true;
- showDropdown[index] = false;
- selectedAttribute = attribute;
- trackEvent(Click.DatabaseAttributeDelete);
- }}>
- Delete
-
- {/if}
-
-
- {/if}
-
-
- {/each}
-
+ {#if !isRelationship(attribute)}
+
{
+ toggle(event);
+ selectedAttribute = attribute;
+ showCreateIndex = true;
+ showDropdown[index] = false;
+ }}>
+ Create index
+
+ {/if}
+ {#if attribute.status !== 'processing'}
+
{
+ toggle(event);
+ showDelete = true;
+ showDropdown[index] = false;
+ selectedAttribute = attribute;
+ trackEvent(Click.DatabaseAttributeDelete);
+ }}>
+ Delete
+
+ {/if}
+
+
+ {/if}
+
+
+ {/each}
+
+
+
+
+ {$attributes.length} columns
+
+
+
+
+
{:else}
-
-
- Documentation
- {#if $canWriteCollections}
-
-
- Create attribute
-
-
- {/if}
-
-
+
+
+
{/if}
-
+
{#if showCreate}
@@ -255,8 +273,17 @@
{/if}
{#if showEdit}
-
+ await editAttribute.submit()
+ }}>
+
+
{/if}
+
{#if showCreateIndex}
{/if}
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/createAttributeDropdown.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/createAttributeDropdown.svelte
index 201ef960f..06a15f7ce 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/createAttributeDropdown.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/createAttributeDropdown.svelte
@@ -6,8 +6,8 @@
import CsvDisabled from '../csvDisabled.svelte';
import { isCsvImportInProgress } from '../store';
- export let selectedOption: Option['name'] = null;
export let showCreate = false;
+ export let selectedOption: Option['name'] = null;
{#if $isCsvImportInProgress}
@@ -20,9 +20,9 @@
{:else}
-
+
- Create attribute
+ Create column
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/edit.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/edit.svelte
index 9a1b9b3d0..9de4c8943 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/edit.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/attributes/edit.svelte
@@ -43,7 +43,7 @@
}
}) as Option;
- async function submit() {
+ export async function submit() {
try {
await option.update(databaseId, collectionId, selectedAttribute, originalKey);
await invalidate(Dependencies.COLLECTION);
@@ -58,6 +58,7 @@
type: 'success',
message: `Attribute ${selectedAttribute.key} has been updated`
});
+
showEdit = false;
trackEvent(Submit.AttributeUpdate);
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/create/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/create/+page.svelte
deleted file mode 100644
index 4390fc590..000000000
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/create/+page.svelte
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
- Create document
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/createRecord.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/createRecord.svelte
index f082fb3f0..025f0a7ff 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/createRecord.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/createRecord.svelte
@@ -1,7 +1,5 @@
-
-
-
- Create document
+
+ create()
+ }}>
+
+
-
+
+
+ Choose which permission scopes to grant your application. It is best practice to
+ allow only the permissions you need to meet your project goals.
+
+ {#if collection.documentSecurity}
+
+ Document security is enabled
+ Users will be able to access this document if they have been granted
+ either document or collection permissions .
+
+
+ {:else}
+
+ Document security is disabled
+ If you want to assign document permissions, navigate to Collection settings and
+ enable document security. Otherwise, only collection permissions will be used.
+
+ {/if}
-
-
-
-
+
+
-
-
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/emptySheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/emptySheet.svelte
deleted file mode 100644
index 03a1a5332..000000000
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/emptySheet.svelte
+++ /dev/null
@@ -1,173 +0,0 @@
-
-
-
-
-
- {#each staticColumns as column (column.id)}
- {#if column.isAction}
-
- {}}>
-
-
-
- {:else}
-
- {column.title}
-
- {/if}
- {/each}
-
-
-
-
-
-
- You have no records yet
-
-
- dispatch('record')}>
-
- Create record
-
-
-
- dispatch('random')}>
- Generate random data
-
-
- Yet to be added
-
-
-
-
-
-
-
-
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte
index f9258a35b..bd33d7299 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte
@@ -1,5 +1,4 @@
-
-
- Indexes
+
+
{#if $canWriteCollections}
(showCreateIndex = true)}>
@@ -69,116 +72,119 @@
{/if}
+
+
{#if data.collection?.attributes?.length}
{#if data.collection.indexes.length}
-
-
- Key
- Type
- Attributes
- Orders
- Lengths
-
-
- {#each data.collection.indexes as index}
-
-
-
- {index.key}
- {#if index.status !== 'available'}
-
- {#if index.error}
- {
- e.preventDefault();
- error = index.error;
- showFailed = true;
- }}>Details
+
+
+
+ Key
+ Type
+ Attributes
+ Orders
+ Lengths
+
+
+ {#each data.collection.indexes as index}
+
+
+
+ {index.key}
+ {#if index.status !== 'available'}
+
+ {#if index.error}
+ {
+ e.preventDefault();
+ error = index.error;
+ showFailed = true;
+ }}>Details
+ {/if}
{/if}
- {/if}
-
-
- {index.type}
-
- {index.attributes}
-
-
- {index.orders}
-
-
- {index.lengths}
-
-
-
-
-
-
-
- {
- selectedIndex = index;
- showOverview = true;
- }}>Overview
- {
- selectedIndex = index;
- showDelete = true;
- trackEvent(Click.DatabaseIndexDelete);
- }}>Delete
-
-
-
-
- {/each}
-
+
+
+
{index.type}
+
+ {index.attributes}
+
+
+ {index.orders}
+
+
+ {index.lengths}
+
+
+
+
+
+
+
+ {
+ selectedIndex = index;
+ showOverview = true;
+ }}>Overview
+ {
+ selectedIndex = index;
+ showDelete = true;
+ trackEvent(Click.DatabaseIndexDelete);
+ }}>Delete
+
+
+
+
+ {/each}
+
+
{:else}
-
(showCreateIndex = true)} />
+ (showCreateIndex = true),
+ disabled: !$collection?.attributes?.length
+ }
+ }} />
{/if}
{:else}
-
-
- Documentation
- {#if $canWriteCollections}
-
-
- Create attribute
-
-
- {/if}
-
-
+
+ {
+ await goto(
+ `${base}/project-${page.params.region}-${page.params.project}/databases/database-${page.params.database}/collection-${page.params.collection}/attributes`
+ );
+ }
+ }
+ }} />
{/if}
-
+
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/emptySheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/emptySheet.svelte
new file mode 100644
index 000000000..7cf96f59b
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/emptySheet.svelte
@@ -0,0 +1,241 @@
+
+
+
+
+
+ {#each spreadsheetColumns as column (column.id)}
+
+ {#if column.isAction}
+
+
+
+ {:else}
+ {column.title}
+ {/if}
+
+ {/each}
+
+
+
+
+
+
+ {title ?? `You have no ${mode} yet`}
+
+
+
+
+ {cta?.primary?.text ?? `Create ${mode}`}
+
+
+ {#if mode === 'records'}
+
+
+ {cta?.random?.text ?? `Generate random data`}
+
+ Yet to be added
+
+ {/if}
+
+
+
+
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/sidesheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/sidesheet.svelte
new file mode 100644
index 000000000..058a7bac4
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/sidesheet.svelte
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+ {@render children()}
+
+
+
+
+
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/spreadsheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/spreadsheet.svelte
new file mode 100644
index 000000000..34d70515e
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/layout/spreadsheet.svelte
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte
index 071003b73..3d55795e8 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte
@@ -31,9 +31,7 @@
FloatingActionBar,
Icon,
InteractiveText,
- Typography,
- Sheet,
- Divider
+ Typography
} from '@appwrite.io/pink-svelte';
import { toLocaleDateTime } from '$lib/helpers/date';
import DualTimeView from '$lib/components/dualTimeView.svelte';
@@ -58,30 +56,23 @@
import { type Action } from './sheetOptions.svelte';
import EditAttribute from './attributes/edit.svelte';
import { isSmallViewport } from '$lib/stores/viewport';
+ import SideSheet from './layout/sidesheet.svelte';
+ import SpreadsheetContainer from './layout/spreadsheet.svelte';
export let data: PageData;
+ export let showRecordsCreateSheet: boolean;
const databaseId = page.params.database;
const collectionId = page.params.collection;
let displayNames = {};
let showRelationships = false;
- let selectedRelationship: Models.AttributeRelationship = null;
let relationshipData: Partial[];
-
- let spreadsheetHeight = '75vh';
- let spreadsheetWrapper: HTMLDivElement;
+ let selectedRelationship: Models.AttributeRelationship = null;
$: documents = data.documents;
- function resizeSheet() {
- if (!spreadsheetWrapper) return;
- const rect = spreadsheetWrapper.getBoundingClientRect();
- spreadsheetHeight = window.innerHeight - rect.top + 'px';
- }
-
onMount(async () => {
- resizeSheet();
displayNames = preferences.getDisplayNames();
});
@@ -316,7 +307,7 @@
if (type === 'update') {
$databaseSheetOptions.show = true;
$databaseSheetOptions.isEdit = true;
- $databaseSheetOptions.title = 'update column';
+ $databaseSheetOptions.title = 'Update column';
}
if (type === 'column-left' || type === 'column-right') {
@@ -339,13 +330,7 @@
: emptyCellsLimit - data.documents.documents.length;
-
-
-
+
- {}}>
+ (showRecordsCreateSheet = true)}>
@@ -553,7 +541,7 @@
{/if}
-
+
@@ -624,49 +612,19 @@
-
-
-
-
-
- {$databaseSheetOptions.title}
-
-
-
-
-
-
-
-
-
-
-
-
-
+ $databaseSheetOptions.submitAction()
+ }}>
+
+