Skip to content

Commit

Permalink
Merge pull request #490 from appwrite/filtering
Browse files Browse the repository at this point in the history
Filtering
  • Loading branch information
christyjacob4 authored Aug 9, 2023
2 parents 87a4ef3 + dd44289 commit 35a74b2
Show file tree
Hide file tree
Showing 13 changed files with 484 additions and 45 deletions.
8 changes: 5 additions & 3 deletions src/lib/commandCenter/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const groups = [
'teams',
'security',
'buckets',
'files'
'files',
'misc'
] as const;

export type CommandGroup = (typeof groups)[number];
Expand Down Expand Up @@ -278,8 +279,9 @@ export const commandGroupRanks = derived(groupRanksMap, ($groupRankTransformatio
databases: 3,
users: 2,
teams: 1,
navigation: -1,
help: -2
navigation: -10,
help: -20,
misc: -30
} as CommandGroupRanks;

const transformations = Array.from($groupRankTransformations.values());
Expand Down
14 changes: 12 additions & 2 deletions src/lib/components/drop.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,26 @@
event.target === element ||
element.contains(event.target as Node) ||
event.target === tooltip ||
tooltip.contains(event.target as Node)
tooltip.contains(event.target as Node) ||
// Avoid deleted elements triggering blur
!document.body.contains(event.target as Node)
)
) {
show = false;
dispatch('blur');
}
};
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape' && show) {
event.preventDefault();
show = false;
dispatch('blur');
}
};
</script>

<svelte:window on:click={onBlur} />
<svelte:window on:click={onBlur} on:keydown={onKeyDown} />

<div class:drop-wrapper={!noStyle} class:u-cross-child-start={childStart} bind:this={element}>
<slot />
Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/viewSelector.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
export let hideView = false;
export let hideColumns = false;
export let allowNoColumns = false;
export let showColsTextMobile = false;
let showSelectColumns = false;
Expand Down Expand Up @@ -84,7 +85,7 @@
class="icon-view-boards u-opacity-50"
aria-hidden="true"
aria-label="columns" />
<span class="text is-only-desktop">Columns</span>
<span class="text {showColsTextMobile ? '' : 'is-only-desktop'}">Columns</span>
<span class="inline-tag">{selectedColumnsNumber}</span>
</Button>
<svelte:fragment slot="list">
Expand Down
10 changes: 6 additions & 4 deletions src/lib/elements/forms/inputNumber.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { FormItem, Helper, Label } from '.';
import NullCheckbox from './nullCheckbox.svelte';
export let label: string;
export let label: string | undefined = undefined;
export let optionalText: string | undefined = undefined;
export let showLabel = true;
export let id: string;
Expand Down Expand Up @@ -65,9 +65,11 @@
</script>

<FormItem>
<Label {required} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{#if label}
<Label {required} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{/if}

<div class="input-text-wrapper">
<input
Expand Down
10 changes: 6 additions & 4 deletions src/lib/elements/forms/inputSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { FormItem, Helper, Label } from '.';
export let id: string;
export let label: string;
export let label: string | undefined = undefined;
export let optionalText: string | undefined = undefined;
export let showLabel = true;
export let value: string | number | boolean;
Expand Down Expand Up @@ -45,9 +45,11 @@
</script>

<FormItem>
<Label {required} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{#if label}
<Label {required} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{/if}

<div class="select">
<select
Expand Down
10 changes: 6 additions & 4 deletions src/lib/elements/forms/inputText.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import NullCheckbox from './nullCheckbox.svelte';
import TextCounter from './textCounter.svelte';
export let label: string;
export let label: string = undefined;
export let optionalText: string | undefined = undefined;
export let showLabel = true;
export let id: string;
Expand Down Expand Up @@ -67,9 +67,11 @@
</script>

<FormItem>
<Label {required} {tooltip} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{#if label}
<Label {required} {tooltip} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{/if}

<div class="input-text-wrapper">
<input
Expand Down
22 changes: 21 additions & 1 deletion src/routes/console/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import Header from '$lib/layout/header.svelte';
import SideNavigation from '$lib/layout/navigation.svelte';
import Shell from '$lib/layout/shell.svelte';
import { feedback } from '$lib/stores/feedback';
import { app, feedback } from '$lib/stores/app';
import { log } from '$lib/stores/logs';
import { newOrgModal } from '$lib/stores/organization';
import { wizard } from '$lib/stores/wizard';
Expand All @@ -21,6 +21,7 @@
import { AIPanel, OrganizationsPanel, ProjectsPanel } from '$lib/commandCenter/panels';
import { orgSearcher, projectsSearcher } from '$lib/commandCenter/searchers';
import { addSubPanel } from '$lib/commandCenter/subPanels';
import { addNotification } from '$lib/stores/notifications';
import { openMigrationWizard } from './(migration-wizard)';
$: $registerCommands([
Expand Down Expand Up @@ -105,6 +106,25 @@
},
group: 'help',
icon: 'discord'
},
{
label: 'Toggle theme',
callback: () => {
if ($app.theme === 'auto') {
$app.theme = 'light';
} else if ($app.theme === 'light') {
$app.theme = 'dark';
} else {
$app.theme = 'auto';
}
addNotification({
title: 'Theme changed',
message: `Theme changed to ${$app.theme}`,
type: 'success'
});
},
group: 'misc',
icon: 'switch-horizontal'
}
]);
let isOpen = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<script lang="ts">
import { Button, InputNumber } from '$lib/elements/forms';
import InputSelect from '$lib/elements/forms/inputSelect.svelte';
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';
const dispatch = createEventDispatcher<{
clear: void;
apply: { applied: number };
}>();
let columnId: string | null = null;
$: column = $columns.find((c) => c.id === columnId) as Column;
dispatch('apply', { applied: $tags.length });
const operators: Record<string, Operator> = {
'starts with': {
toQuery: Query.startsWith,
toTag: (attribute, input) => `**${attribute}** starts with **${input}**`,
types: ['string']
},
'ends with': {
toQuery: Query.endsWith,
toTag: (attribute, input) => `**${attribute}** ends with **${input}**`,
types: ['string']
},
'greater than': {
toQuery: (attr, input) => Query.greaterThan(attr, Number(input)),
toTag: (attribute, input) => `**${attribute}** greater than **${input}**`,
types: ['integer', 'double']
},
'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']
},
'less than': {
toQuery: Query.lessThan,
toTag: (attribute, input) => `**${attribute}** less than **${input}**`,
types: ['integer', 'double']
},
'less than or equal to': {
toQuery: Query.lessThanEqual,
toTag: (attribute, input) => `**${attribute}** less than or equal to **${input}**`,
types: ['integer', 'double']
},
equal: {
toQuery: Query.equal,
toTag: (attribute, input) => `**${attribute}** equal to **${input}**`,
types: ['string', 'integer', 'double']
},
'not null': {
toQuery: Query.isNotNull,
toTag: (attribute) => `**${attribute}** is not null`,
types: ['string', 'integer', 'double', 'boolean', 'datetime', 'relationship'],
hideInput: true
},
null: {
toQuery: Query.isNull,
toTag: (attribute) => `**${attribute}** is null`,
types: ['string', 'integer', 'double', 'boolean', 'datetime', 'relationship'],
hideInput: true
}
};
$: operatorsForColumn = Object.entries(operators)
.filter(([_, v]) => v.types.includes(column?.type))
.map(([k]) => ({
label: k,
value: k
}));
let operatorKey: string | null = null;
$: operator = operatorKey ? operators[operatorKey] : null;
$: {
columnId;
operatorKey = null;
}
// We cast to any to not cause type errors in the input components
let value: any = null;
$: {
columnId;
value = null;
}
// 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;
}
}
function tagFormat(node: HTMLElement) {
node.innerHTML = node.innerHTML.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>');
}
$: isDisabled = (function getDisabled() {
return !operator || (!operator?.hideInput && !value);
})();
</script>

<div>
<form on:submit|preventDefault={addFilter}>
<div class="selects u-flex u-gap-12 u-margin-block-start-16">
<InputSelect
id="column"
options={$columns.map((c) => ({
label: c.title,
value: c.id
}))}
placeholder="Select column"
bind:value={columnId} />
<InputSelect
id="operator"
disabled={!column}
options={operatorsForColumn}
placeholder="Select operator"
bind:value={operatorKey} />
</div>
{#if column && operator && !operator?.hideInput}
<div class="u-margin-block-start-16">
{#if column.type === 'integer' || column.type === 'double'}
<InputNumber id="value" bind:value placeholder="Enter value" />
{:else}
<InputText id="value" bind:value placeholder="Enter value" />
{/if}
</div>
{/if}
<Button text disabled={isDisabled} class="u-margin-block-start-12" submit>
<i class="icon-plus" />
Add filter
</Button>
</form>

<ul class="u-flex u-flex-wrap u-cross-center u-gap-8 u-margin-block-start-16 tags">
{#each $tags as tag (tag)}
<button
class="tag"
on:click={() => {
queries.removeFilter(tag);
}}>
<span class="text" use:tagFormat>
{tag}
</span>
<i class="icon-x" />
</button>
{/each}
</ul>
</div>

<style lang="scss">
.dropped {
border-radius: 0.5rem;
box-shadow: 0px 16px 32px 0px rgba(55, 59, 77, 0.04);
padding: 1rem;
margin-top: 0.5rem;
width: 37.5rem;
}
.selects {
:global(> *) {
flex: 1;
}
}
.tags {
:global(b) {
font-weight: bold;
}
}
hr {
height: 1px;
width: calc(100% + 2rem);
background-color: hsl(var(--color-border));
margin-block-start: 1rem;
margin-inline: -1rem;
}
</style>
Loading

0 comments on commit 35a74b2

Please sign in to comment.