Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor filters to be generic #609

Merged
merged 3 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import InputText from '$lib/elements/forms/inputText.svelte';
import { Query } from '@appwrite.io/console';
import { createEventDispatcher } from 'svelte';
import { columns } from '../store';
import { tags, type Column, type Operator, queries } from './store';
import { tags, type Operator, queries } from './store';
import type { Column } from '$lib/helpers/types';
import type { Writable } from 'svelte/store';

export let columns: Writable<Column[]>;

const dispatch = createEventDispatcher<{
clear: void;
Expand All @@ -31,22 +34,22 @@
'greater than': {
toQuery: (attr, input) => Query.greaterThan(attr, Number(input)),
toTag: (attribute, input) => `**${attribute}** greater than **${input}**`,
types: ['integer', 'double']
types: ['integer', 'double', 'datetime']
},
'greater than or equal to': {
toQuery: (attr, input) => Query.greaterThanEqual(attr, Number(input)),
toTag: (attribute, input) => `**${attribute}** greater than or equal to **${input}**`,
types: ['integer', 'double']
types: ['integer', 'double', 'datetime']
},
'less than': {
toQuery: Query.lessThan,
toTag: (attribute, input) => `**${attribute}** less than **${input}**`,
types: ['integer', 'double']
types: ['integer', 'double', 'datetime']
},
'less than or equal to': {
toQuery: Query.lessThanEqual,
toTag: (attribute, input) => `**${attribute}** less than or equal to **${input}**`,
types: ['integer', 'double']
types: ['integer', 'double', 'datetime']
},
equal: {
toQuery: Query.equal,
Expand Down Expand Up @@ -97,19 +100,17 @@

// This Map is keyed by tags, and has a query as the value
function addFilter() {
if (column && operator) {
queries.addFilter({ column, operator, value });
value = null;
}
if (!column || !operator) return;

queries.addFilter({ column, operator, value: value ?? '' });
value = null;
}

function tagFormat(node: HTMLElement) {
node.innerHTML = node.innerHTML.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>');
}

$: isDisabled = (function getDisabled() {
return !operator || (!operator?.hideInput && !value);
})();
$: isDisabled = !operator;
</script>

<div>
Expand All @@ -134,6 +135,16 @@
<div class="u-margin-block-start-8">
{#if column.type === 'integer' || column.type === 'double'}
<InputNumber id="value" bind:value placeholder="Enter value" />
{:else if column.type === 'boolean'}
<InputSelect
id="value"
placeholder="Select a value"
required={true}
options={[
{ label: 'True', value: true },
{ label: 'False', value: false }
].filter(Boolean)}
bind:value />
{:else}
<InputText id="value" bind:value placeholder="Enter value" />
{/if}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
import { beforeNavigate } from '$app/navigation';
import { Drop, Modal } from '$lib/components';
import { Button } from '$lib/elements/forms';
import type { Column } from '$lib/helpers/types';
import type { Writable } from 'svelte/store';
import Content from './content.svelte';
import { queries, queriesAreDirty, tags } from './store';
import { queries, queriesAreDirty, queryParamToMap, tags } from './store';

export let query = '[]';
export let columns: Writable<Column[]>;

const parsedQueries = queryParamToMap(query);
queries.set(parsedQueries);

// We need to separate them so we don't trigger Drop's handlers
let showFiltersDesktop = false;
Expand Down Expand Up @@ -33,6 +41,7 @@
<div class="dropped card">
<p>Apply filter rules to refine the table view</p>
<Content
{columns}
on:apply={(e) => (applied = e.detail.applied)}
on:clear={() => (applied = 0)} />
<hr />
Expand Down Expand Up @@ -61,7 +70,10 @@
description="Apply filter rules to refine the table view"
bind:show={showFiltersMobile}
size="big">
<Content on:apply={(e) => (applied = e.detail.applied)} on:clear={() => (applied = 0)} />
<Content
{columns}
on:apply={(e) => (applied = e.detail.applied)}
on:clear={() => (applied = 0)} />
<svelte:fragment slot="footer">
<Button text on:click={queries.clearAll}>Clear all</Button>
<Button on:click={queries.apply} disabled={!$queriesAreDirty}>Apply</Button
Expand Down
1 change: 1 addition & 0 deletions src/lib/components/filters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as filters } from './filters.svelte';
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { goto } from '$app/navigation';

import { derived, get, writable, type Writable } from 'svelte/store';
import type { columns } from '../store';
import { derived, get, writable } from 'svelte/store';
import { page } from '$app/stores';
import deepEqual from 'deep-equal';

const columnTypes = ['string', 'integer', 'double', 'boolean', 'datetime', 'relationship'] as const;
type ColumnType = (typeof columnTypes)[number];

type StoreValues<Store> = Store extends Writable<infer T> ? T : never;
export type Column = Omit<StoreValues<typeof columns>[number], 'type'> & {
type: ColumnType;
};
import type { Column, ColumnType } from '$lib/helpers/types';

export type Operator = {
toTag: (attribute: string, input?: string | number) => string;
Expand Down
10 changes: 1 addition & 9 deletions src/lib/components/viewSelector.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
<script context="module" lang="ts">
export type Column = {
id: string;
title: string;
show: boolean;
width?: number;
};
</script>

<script lang="ts">
import { Button, InputChoice } from '$lib/elements/forms';
import { DropList } from '.';
Expand All @@ -16,6 +7,7 @@
import { onMount } from 'svelte';
import { View } from '$lib/helpers/load';
import { tooltip } from '$lib/actions/tooltip';
import type { Column } from '$lib/helpers/types';

export let columns: Writable<Column[]>;
export let view: View;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/helpers/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export function getSearch(url: URL): string | undefined {
return url.searchParams.get('search') ?? undefined;
}

export function getQuery(url: URL): string | undefined {
return url.searchParams.get('query') ?? undefined;
}

type TabElement = { href: string; title: string; hasChildren?: boolean };

export function isTabSelected(
Expand Down
10 changes: 10 additions & 0 deletions src/lib/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ export function isHTMLInputElement(el: unknown): el is HTMLInputElement {

// eslint-disable-next-line @typescript-eslint/ban-types
export type Prettify<T> = T & {};

const columnTypes = ['string', 'integer', 'double', 'boolean', 'datetime', 'relationship'] as const;
export type ColumnType = (typeof columnTypes)[number];
export type Column = {
id: string;
title: string;
type: ColumnType;
show: boolean;
width?: number;
};
2 changes: 1 addition & 1 deletion src/lib/layout/gridHeader.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { Heading, ViewSelector } from '$lib/components';
import type { View } from '$lib/helpers/load';
import type { Column } from '$lib/components/viewSelector.svelte';
import type { Column } from '$lib/helpers/types';
import type { Writable } from 'svelte/store';

export let title: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import type { Column } from '$lib/helpers/types';
import { writable } from 'svelte/store';

export type Column = {
id: string;
title: string;
show: boolean;
width?: number;
};

export const columns = writable<Column[]>([
{ id: '$id', title: 'Database ID', show: true, width: 150 },
{ id: 'name', title: 'Name', show: true, width: 120 },
{ id: '$createdAt', title: 'Created', show: true, width: 120 },
{ id: '$updatedAt', title: 'Updated', show: true, width: 120 }
{ id: '$id', title: 'Database ID', type: 'string', show: true, width: 150 },
{ id: 'name', title: 'Name', type: 'string', show: true, width: 120 },
{ id: '$createdAt', title: 'Created', type: 'string', show: true, width: 120 },
{ id: '$updatedAt', title: 'Updated', type: 'string', show: true, width: 120 }
]);
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<script lang="ts">
import { page } from '$app/stores';
import { Empty, EmptySearch, Heading, PaginationWithLimit } from '$lib/components';
import Filters from '$lib/components/filters/filters.svelte';
import { hasPageQueries, queries } from '$lib/components/filters/store';
import ViewSelector from '$lib/components/viewSelector.svelte';
import { Button } from '$lib/elements/forms';
import type { ColumnType } from '$lib/helpers/types';
import { Container } from '$lib/layout';
import { preferences } from '$lib/stores/preferences';
import { wizard } from '$lib/stores/wizard';
import type { PageData } from './$types';
import Filters from './(filters)/filters.svelte';
import { hasPageQueries, queries } from './(filters)/store';
import CreateAttributeDropdown from './attributes/createAttributeDropdown.svelte';
import type { Option } from './attributes/store';
import CreateAttribute from './createAttribute.svelte';
Expand All @@ -27,7 +28,7 @@
$collection.attributes.map((attribute) => ({
id: attribute.key,
title: attribute.key,
type: attribute.type,
type: attribute.type as ColumnType,
show: selected?.includes(attribute.key) ?? true
}))
);
Expand All @@ -54,7 +55,7 @@
</Button>
</div>

<Filters />
<Filters query={data.query} {columns} />

<div class="u-flex u-main-end u-gap-16">
<ViewSelector
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import { getLimit, getPage, getView, pageToOffset, View } from '$lib/helpers/load';
import { getLimit, getPage, getQuery, getView, pageToOffset, View } from '$lib/helpers/load';
import { sdk } from '$lib/stores/sdk';
import { Query } from '@appwrite.io/console';
import type { PageLoad } from './$types';

import { queries, queryParamToMap } from './(filters)/store';
import { queries, queryParamToMap } from '$lib/components/filters/store';

export const load: PageLoad = async ({ params, depends, url, route }) => {
depends(Dependencies.DOCUMENTS);
const page = getPage(url);
const limit = getLimit(url, route, PAGE_LIMIT);
const view = getView(url, route, View.Grid);
const offset = pageToOffset(page, limit);
const query = getQuery(url);

const paramQueries = url.searchParams.get('query');
const parsedQueries = queryParamToMap(paramQueries || '[]');
Expand All @@ -21,6 +21,7 @@ export const load: PageLoad = async ({ params, depends, url, route }) => {
offset,
limit,
view,
query,
documents: await sdk.forProject.databases.listDocuments(
params.database,
params.collection,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { page } from '$app/stores';
import type { Column } from '$lib/helpers/types';
import type { Models } from '@appwrite.io/console';
import { derived, writable } from 'svelte/store';

Expand All @@ -16,14 +17,6 @@ export type Attributes =
type Collection = Omit<Models.Collection, 'attributes'> & {
attributes: Array<Attributes>;
};
export type Column = {
id: string;
title: string;
show: boolean;
type?: string;
twoWay?: string;
width?: number;
};

export const collection = derived(page, ($page) => $page.data.collection as Collection);
export const attributes = derived(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import RelationshipsModal from './relationshipsModal.svelte';
import { attributes, collection, columns } from './store';
import { clickOnEnter } from '$lib/helpers/a11y';
import type { ColumnType } from '$lib/helpers/types';

export let data: PageData;

Expand Down Expand Up @@ -89,7 +90,7 @@
$collection.attributes.map((attribute) => ({
id: attribute.key,
title: attribute.key,
type: attribute.type,
type: attribute.type as ColumnType,
show: selected?.includes(attribute.key) ?? true
}))
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { page } from '$app/stores';
import type { Column } from '$lib/components/viewSelector.svelte';
import type { Column } from '$lib/helpers/types';
import type { Models } from '@appwrite.io/console';
import { derived, writable } from 'svelte/store';

export const database = derived(page, ($page) => $page.data.database as Models.Database);
export const showCreate = writable(false);

export const columns = writable<Column[]>([
{ id: '$id', title: 'Collection ID', show: true, width: 150 },
{ id: 'name', title: 'Name', show: true, width: 120 },
{ id: '$createdAt', title: 'Created', show: true, width: 120 },
{ id: '$updatedAt', title: 'Updated', show: true, width: 120 }
{ id: '$id', title: 'Collection ID', type: 'string', show: true, width: 150 },
{ id: 'name', title: 'Name', type: 'string', show: true, width: 120 },
{ id: '$createdAt', title: 'Created', type: 'datetime', show: true, width: 120 },
{ id: '$updatedAt', title: 'Updated', type: 'datetime', show: true, width: 120 }
]);
10 changes: 5 additions & 5 deletions src/routes/console/project-[project]/databases/store.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Column } from '$lib/components/viewSelector.svelte';
import type { Column } from '$lib/helpers/types';
import { writable } from 'svelte/store';

export const columns = writable<Column[]>([
{ id: '$id', title: 'Database ID', show: true, width: 150 },
{ id: 'name', title: 'Name', show: true, width: 120 },
{ id: '$createdAt', title: 'Created', show: true, width: 120 },
{ id: '$updatedAt', title: 'Updated', show: true, width: 120 }
{ id: '$id', title: 'Database ID', type: 'string', show: true, width: 150 },
{ id: 'name', title: 'Name', type: 'string', show: true, width: 120 },
{ id: '$createdAt', title: 'Created', type: 'datetime', show: true, width: 120 },
{ id: '$updatedAt', title: 'Updated', type: 'datetime', show: true, width: 120 }
]);