Skip to content

Commit

Permalink
Refactor providers table and add bulk deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
stnguyen90 committed Dec 14, 2023
1 parent 62c8dff commit f3c7f46
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 76 deletions.
1 change: 1 addition & 0 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export enum Dependencies {
COLLECTIONS = 'dependency:collections',
RUNTIMES = 'dependency:runtimes',
CONSOLE_VARIABLES = 'dependency:console_variables',
MESSAGING_PROVIDERS = 'dependency:messaging_providers',
MESSAGING_PROVIDER = 'dependency:messaging_provider'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,26 @@
<script lang="ts">
import { page } from '$app/stores';
import {
TableHeader,
TableBody,
TableRowLink,
TableCellHead,
TableCellText,
TableCell,
TableCellHeadCheck,
TableScroll,
TableCellCheck
} from '$lib/elements/table';
import { Button } from '$lib/elements/forms';
import {
Empty,
EmptySearch,
SearchQuery,
PaginationWithLimit,
Heading,
Id,
ViewSelector
} from '$lib/components';
import { Container } from '$lib/layout';
import { base } from '$app/paths';
import type { PageData } from './$types';
import { columns } from './store';
import { Pill } from '$lib/elements';
import Provider from '../provider.svelte';
import ProviderType from '../providerType.svelte';
import Filters from '$lib/components/filters/filters.svelte';
import CreateProviderDropdown from './createProviderDropdown.svelte';
import Table from './table.svelte';
export let data: PageData;
let showCreateDropdownMobile = false;
let showCreateDropdownDesktop = false;
let showCreateDropdownEmpty = false;
let selected: string[] = [];
const project = $page.params.project;
</script>

<Container>
Expand Down Expand Up @@ -79,61 +61,7 @@
</div>
</div>
{#if data.providers.total}
<TableScroll>
<TableHeader>
<TableCellHeadCheck
bind:selected
pageItemsIds={data.providers.providers.map((d) => d.$id)} />
{#each $columns as column}
{#if column.show}
<TableCellHead width={column.width}>{column.title}</TableCellHead>
{/if}
{/each}
</TableHeader>
<TableBody>
{#each data.providers.providers as provider (provider.$id)}
<TableRowLink
href={`${base}/console/project-${project}/messaging/providers/provider-${provider.$id}`}>
<TableCellCheck bind:selectedIds={selected} id={provider.$id} />
{#each $columns as column}
{#if column.show}
{#if column.id === '$id'}
{#key $columns}
<TableCell title={column.title} width={column.width}>
<Id value={provider.$id}>{provider.$id}</Id>
</TableCell>
{/key}
{:else if column.id === 'provider'}
<TableCellText title={column.title} width={column.width}>
<Provider provider={provider.provider} size="s" />
</TableCellText>
{:else if column.id === 'type'}
<TableCellText title={column.title} width={column.width}>
<ProviderType type={provider.type} size="s" />
</TableCellText>
{:else if column.id === 'enabled'}
<TableCellText title={column.title} width={column.width}>
<Pill success={provider.enabled}>
{#if provider.enabled}
<span class="icon-check-circle" aria-hidden="true"
></span>
{/if}
<span class="text u-trim">
{provider.enabled ? 'enabled' : 'disabled'}
</span>
</Pill>
</TableCellText>
{:else}
<TableCellText title={column.title} width={column.width}>
{provider[column.id]}
</TableCellText>
{/if}
{/if}
{/each}
</TableRowLink>
{/each}
</TableBody>
</TableScroll>
<Table {data} />

<PaginationWithLimit
name="Providers"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
getView,
pageToOffset
} from '$lib/helpers/load';
import { PAGE_LIMIT } from '$lib/constants';
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import { providersById, type Provider } from '../store';
import { queries, queryParamToMap } from '$lib/components/filters/store';

Expand All @@ -20,7 +20,9 @@ let data: { providers: Provider[]; total: number } = {
total: providers.length
};

export const load = async ({ url, route }) => {
export const load = async ({ depends, url, route }) => {
depends(Dependencies.MESSAGING_PROVIDERS);

const page = getPage(url);
const search = getSearch(url);
const view = getView(url, route, View.Grid);
Expand Down
170 changes: 170 additions & 0 deletions src/routes/console/project-[project]/messaging/providers/table.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<script lang="ts">
import { base } from '$app/paths';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { FloatingActionBar, Id, Modal } from '$lib/components';
import { Button } from '$lib/elements/forms';
import {
TableBody,
TableCell,
TableCellCheck,
TableCellHead,
TableCellHeadCheck,
TableCellText,
TableHeader,
TableRowLink,
TableScroll
} from '$lib/elements/table';
import { addNotification } from '$lib/stores/notifications';
import type { PageData } from './$types';
import { columns } from './store';
import { project } from '$routes/console/project-[project]/store';
import Provider from '../provider.svelte';
import ProviderType from '../providerType.svelte';
import { Pill } from '$lib/elements';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { sdk } from '$lib/stores/sdk';
export let data: PageData;
let selectedIds: string[] = [];
let showDelete = false;
let deleting = false;
async function handleDelete() {
showDelete = false;
function deleteProvider(providerId: string) {
return sdk.forProject.client.call(
'DELETE',
new URL(
`${sdk.forProject.client.config.endpoint}/messaging/providers/${providerId}`
),
{
'X-Appwrite-Project': sdk.forProject.client.config.project,
'content-type': 'application/json',
'X-Appwrite-Mode': 'admin'
}
);
}
const promises = selectedIds.map((id) => deleteProvider(id));
try {
await Promise.all(promises);
trackEvent(Submit.MessagingProviderDelete, {
total: selectedIds.length
});
addNotification({
type: 'success',
message: `${selectedIds.length} provider${
selectedIds.length > 1 ? 's' : ''
} deleted`
});
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
trackError(error, Submit.MessagingProviderDelete);
} finally {
invalidate(Dependencies.MESSAGING_PROVIDERS);
selectedIds = [];
showDelete = false;
}
}
</script>

<TableScroll>
<TableHeader>
<TableCellHeadCheck
bind:selected={selectedIds}
pageItemsIds={data.providers.providers.map((d) => d.$id)} />
{#each $columns as column}
{#if column.show}
<TableCellHead width={column.width}>{column.title}</TableCellHead>
{/if}
{/each}
</TableHeader>
<TableBody>
{#each data.providers.providers as provider (provider.$id)}
<TableRowLink
href={`${base}/console/project-${$project.$id}/messaging/providers/provider-${provider.$id}`}>
<TableCellCheck bind:selectedIds id={provider.$id} />
{#each $columns as column}
{#if column.show}
{#if column.id === '$id'}
{#key $columns}
<TableCell title={column.title} width={column.width}>
<Id value={provider.$id}>{provider.$id}</Id>
</TableCell>
{/key}
{:else if column.id === 'provider'}
<TableCellText title={column.title} width={column.width}>
<Provider provider={provider.provider} size="s" />
</TableCellText>
{:else if column.id === 'type'}
<TableCellText title={column.title} width={column.width}>
<ProviderType type={provider.type} size="s" />
</TableCellText>
{:else if column.id === 'enabled'}
<TableCellText title={column.title} width={column.width}>
<Pill success={provider.enabled}>
{#if provider.enabled}
<span class="icon-check-circle" aria-hidden="true"></span>
{/if}
<span class="text u-trim">
{provider.enabled ? 'enabled' : 'disabled'}
</span>
</Pill>
</TableCellText>
{:else}
<TableCellText title={column.title} width={column.width}>
{provider[column.id]}
</TableCellText>
{/if}
{/if}
{/each}
</TableRowLink>
{/each}
</TableBody>
</TableScroll>

<FloatingActionBar show={selectedIds.length > 0}>
<div class="u-flex u-cross-center u-main-space-between actions">
<div class="u-flex u-cross-center u-gap-8">
<span class="indicator body-text-2 u-bold">{selectedIds.length}</span>
<p>
<span class="is-only-desktop">
{selectedIds.length > 1 ? 'providers' : 'provider'}
</span>
selected
</p>
</div>

<div class="u-flex u-cross-center u-gap-8">
<Button text on:click={() => (selectedIds = [])}>Cancel</Button>
<Button secondary on:click={() => (showDelete = true)}>
<p>Delete</p>
</Button>
</div>
</div>
</FloatingActionBar>

<Modal
title="Delete providers"
icon="exclamation"
state="warning"
bind:show={showDelete}
onSubmit={handleDelete}
headerDivider={false}
closable={!deleting}>
<p class="text" data-private>
Are you sure you want to delete <b>{selectedIds.length}</b>
{selectedIds.length > 1 ? 'providers' : 'provider'}?
</p>
<svelte:fragment slot="footer">
<Button text on:click={() => (showDelete = false)} disabled={deleting}>Cancel</Button>
<Button secondary submit disabled={deleting}>Delete</Button>
</svelte:fragment>
</Modal>

0 comments on commit f3c7f46

Please sign in to comment.