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

Merge branch 'command-center-and-migrations' into filtering #497

Merged
merged 13 commits into from
Aug 9, 2023
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