mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: created menu component, add download source + output
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
export { default as Filters } from './filters.svelte';
|
||||
export { default as TagList } from './tagList.svelte';
|
||||
export { default as FilterMenu } from './menu.svelte';
|
||||
export { default as FilterSubMenu } from './subMenu.svelte';
|
||||
export { default as CustomFilters } from './customFilters.svelte';
|
||||
export { default as QuickFilters } from './quickFilters.svelte';
|
||||
export { default as ParsedTagList } from './parsedTagList.svelte';
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { afterNavigate } from '$app/navigation';
|
||||
import MenuItem from '$lib/components/filters/subMenu.svelte';
|
||||
import { queryParamToMap } from '$lib/components/filters/store';
|
||||
import type { Column } from '$lib/helpers/types';
|
||||
import { type Writable } from 'svelte/store';
|
||||
import Menu from '$lib/components/filters/menu.svelte';
|
||||
import { CustomFilters } from '$lib/components/filters';
|
||||
import { addFilterAndApply, buildFilterCol } from './quickFilters';
|
||||
import { setFiltersOnNavigate } from './setFilters';
|
||||
import { parsedTags, setFiltersOnNavigate } from './setFilters';
|
||||
import Menu from '../menu/menu.svelte';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { Icon } from '@appwrite.io/pink-svelte';
|
||||
import { IconFilterLine } from '@appwrite.io/pink-icons-svelte';
|
||||
import QuickfiltersSubMenu from './quickfiltersSubMenu.svelte';
|
||||
|
||||
export let columns: Writable<Column[]>;
|
||||
export let analyticsSource: string;
|
||||
@@ -27,39 +30,52 @@
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
{#each filterCols as filter}
|
||||
{#if filter.options}
|
||||
<MenuItem
|
||||
{filter}
|
||||
variant={filter?.array ? 'checkbox' : 'radio'}
|
||||
on:add={(e) => {
|
||||
addFilterAndApply(
|
||||
filter.id,
|
||||
filter.title,
|
||||
filter.operator,
|
||||
e.detail.value,
|
||||
filter?.array
|
||||
? (filter.options
|
||||
.filter((opt) => opt.checked)
|
||||
.map((opt) => opt.value) ?? [])
|
||||
: [],
|
||||
$columns,
|
||||
analyticsSource
|
||||
);
|
||||
}}
|
||||
on:clear={() => {
|
||||
addFilterAndApply(
|
||||
filter.id,
|
||||
filter.title,
|
||||
filter.operator,
|
||||
null,
|
||||
[],
|
||||
$columns,
|
||||
analyticsSource
|
||||
);
|
||||
}} />
|
||||
{/if}
|
||||
{/each}
|
||||
{#if $parsedTags?.length}
|
||||
<Button secondary badge={`${$parsedTags?.length}`}>
|
||||
<Icon icon={IconFilterLine} slot="start" size="s" />
|
||||
Filters
|
||||
</Button>
|
||||
{:else}
|
||||
<Button secondary>
|
||||
<Icon icon={IconFilterLine} slot="start" size="s" />
|
||||
Filters
|
||||
</Button>
|
||||
{/if}
|
||||
<svelte:fragment slot="menu">
|
||||
{#each filterCols as filter}
|
||||
{#if filter.options}
|
||||
<QuickfiltersSubMenu
|
||||
{filter}
|
||||
variant={filter?.array ? 'checkbox' : 'radio'}
|
||||
on:add={(e) => {
|
||||
addFilterAndApply(
|
||||
filter.id,
|
||||
filter.title,
|
||||
filter.operator,
|
||||
e.detail.value,
|
||||
filter?.array
|
||||
? (filter.options
|
||||
.filter((opt) => opt.checked)
|
||||
.map((opt) => opt.value) ?? [])
|
||||
: [],
|
||||
$columns,
|
||||
analyticsSource
|
||||
);
|
||||
}}
|
||||
on:clear={() => {
|
||||
addFilterAndApply(
|
||||
filter.id,
|
||||
filter.title,
|
||||
filter.operator,
|
||||
null,
|
||||
[],
|
||||
$columns,
|
||||
analyticsSource
|
||||
);
|
||||
}} />
|
||||
{/if}
|
||||
{/each}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="end">
|
||||
<CustomFilters {columns} />
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
</script>
|
||||
|
||||
<div use:melt={$subTrigger}>
|
||||
<ActionMenu.Root>
|
||||
<ActionMenu.Root noPadding>
|
||||
<ActionMenu.Item.Button trailingIcon={IconChevronRight}
|
||||
>{filter.title}</ActionMenu.Item.Button>
|
||||
</ActionMenu.Root>
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Menu } from './menu.svelte';
|
||||
export { default as SubMenu } from './subMenu.svelte';
|
||||
@@ -1,9 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { Card, Icon } from '@appwrite.io/pink-svelte';
|
||||
import { IconFilterLine } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card } from '@appwrite.io/pink-svelte';
|
||||
import { createMenubar, melt } from '@melt-ui/svelte';
|
||||
import { parsedTags } from './setFilters';
|
||||
|
||||
const {
|
||||
elements: { menubar },
|
||||
@@ -11,30 +8,31 @@
|
||||
} = createMenubar();
|
||||
|
||||
const {
|
||||
elements: { trigger: trigger, menu: menu, separator: separator }
|
||||
elements: { trigger: trigger, menu: menu, separator: separator },
|
||||
states: { open }
|
||||
} = createMenu();
|
||||
|
||||
function toggle() {
|
||||
open.update((state) => !state);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:melt={$menubar}>
|
||||
<div use:melt={$trigger}>
|
||||
{#if $parsedTags?.length}
|
||||
<Button secondary badge={`${$parsedTags?.length}`}>
|
||||
<Icon icon={IconFilterLine} slot="start" size="s" />
|
||||
Filters
|
||||
</Button>
|
||||
{:else}
|
||||
<Button secondary>
|
||||
<Icon icon={IconFilterLine} slot="start" size="s" />
|
||||
Filters
|
||||
</Button>
|
||||
{/if}
|
||||
<slot {toggle} />
|
||||
</div>
|
||||
|
||||
<div class="menu" use:melt={$menu}>
|
||||
<Card.Base padding="xxxs">
|
||||
<slot />
|
||||
<div class="separator" use:melt={$separator} />
|
||||
<slot name="end" />
|
||||
{#if $$slots.start}
|
||||
<slot name="start" />
|
||||
<div class="separator" use:melt={$separator} />
|
||||
{/if}
|
||||
<slot name="menu" {toggle} />
|
||||
{#if $$slots.end}
|
||||
<div class="separator" use:melt={$separator} />
|
||||
<slot name="end" />
|
||||
{/if}
|
||||
</Card.Base>
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,6 +40,7 @@
|
||||
<style>
|
||||
.menu {
|
||||
min-width: 244px;
|
||||
width: max-content;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<script lang="ts">
|
||||
import { Card } from '@appwrite.io/pink-svelte';
|
||||
import { createMenubar, melt } from '@melt-ui/svelte';
|
||||
|
||||
const {
|
||||
builders: { createMenu }
|
||||
} = createMenubar();
|
||||
|
||||
const {
|
||||
elements: { separator: separator },
|
||||
builders: { createSubmenu: createSubmenu }
|
||||
} = createMenu();
|
||||
|
||||
const {
|
||||
elements: { subMenu: subMenu, subTrigger: subTrigger }
|
||||
} = createSubmenu();
|
||||
</script>
|
||||
|
||||
<div use:melt={$subTrigger}>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<div class="subMenu" use:melt={$subMenu}>
|
||||
<Card.Base padding="xxxs">
|
||||
{#if $$slots.start}
|
||||
<slot name="start" />
|
||||
<div class="separator" use:melt={$separator} />
|
||||
{/if}
|
||||
<slot name="menu" />
|
||||
{#if $$slots.end}
|
||||
<div class="separator" use:melt={$separator} />
|
||||
<slot name="end" />
|
||||
{/if}
|
||||
</Card.Base>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.subMenu {
|
||||
min-width: 244px;
|
||||
margin-inline: -4px;
|
||||
margin-block: -4px;
|
||||
}
|
||||
</style>
|
||||
+47
-30
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { Menu } from '$lib/components/menu';
|
||||
import SubMenu from '$lib/components/menu/subMenu.svelte';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { DeploymentDownloadType, type Models } from '@appwrite.io/console';
|
||||
@@ -11,7 +13,7 @@
|
||||
IconTrash,
|
||||
IconXCircle
|
||||
} from '@appwrite.io/pink-icons-svelte';
|
||||
import { ActionMenu, Icon, Popover } from '@appwrite.io/pink-svelte';
|
||||
import { ActionMenu, Icon } from '@appwrite.io/pink-svelte';
|
||||
|
||||
export let selectedDeployment: Models.Deployment;
|
||||
export let deployment: Models.Deployment;
|
||||
@@ -22,28 +24,31 @@
|
||||
export let activeDeployment: string;
|
||||
export let inCard = false;
|
||||
|
||||
function getDownload(deploymentId: string) {
|
||||
function getOutputDownload(deploymentId: string) {
|
||||
return (
|
||||
sdk.forProject.sites.getDeploymentDownload($page.params.site, deploymentId).toString() +
|
||||
'&mode=admin',
|
||||
DeploymentDownloadType.Source
|
||||
sdk.forProject.sites.getDeploymentDownload(
|
||||
$page.params.site,
|
||||
deploymentId.toString(),
|
||||
DeploymentDownloadType.Output
|
||||
) + '&mode=admin'
|
||||
);
|
||||
}
|
||||
function getSourceDownload(deploymentId: string) {
|
||||
return (
|
||||
sdk.forProject.sites.getDeploymentDownload(
|
||||
$page.params.site,
|
||||
deploymentId.toString(),
|
||||
DeploymentDownloadType.Source
|
||||
) + '&mode=admin'
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Popover padding="none" placement="bottom-end" let:toggle>
|
||||
<Button
|
||||
text={!inCard}
|
||||
secondary={inCard}
|
||||
icon
|
||||
size="s"
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
toggle(e);
|
||||
}}>
|
||||
<Menu>
|
||||
<Button text={!inCard} secondary={inCard} icon size="s">
|
||||
<Icon size="s" icon={IconDotsHorizontal} />
|
||||
</Button>
|
||||
<svelte:fragment slot="tooltip" let:toggle>
|
||||
<svelte:fragment slot="menu" let:toggle>
|
||||
<ActionMenu.Root>
|
||||
{#if !inCard}
|
||||
<ActionMenu.Item.Button
|
||||
@@ -52,7 +57,7 @@
|
||||
e.preventDefault();
|
||||
selectedDeployment = deployment;
|
||||
showRedeploy = true;
|
||||
toggle(e);
|
||||
toggle();
|
||||
}}>
|
||||
Redeploy
|
||||
</ActionMenu.Item.Button>
|
||||
@@ -64,21 +69,35 @@
|
||||
e.preventDefault();
|
||||
selectedDeployment = deployment;
|
||||
showActivate = true;
|
||||
toggle(e);
|
||||
toggle();
|
||||
}}>
|
||||
Activate
|
||||
</ActionMenu.Item.Button>
|
||||
{/if}
|
||||
{#if deployment?.status === 'ready' || deployment?.status === 'failed'}
|
||||
<ActionMenu.Item.Anchor
|
||||
href={getDownload(deployment.$id)}
|
||||
external
|
||||
leadingIcon={IconDownload}
|
||||
on:click={(e) => {
|
||||
toggle(e);
|
||||
}}>
|
||||
Download
|
||||
</ActionMenu.Item.Anchor>
|
||||
<SubMenu>
|
||||
<ActionMenu.Root noPadding>
|
||||
<ActionMenu.Item.Button leadingIcon={IconDownload}>
|
||||
Download
|
||||
</ActionMenu.Item.Button>
|
||||
</ActionMenu.Root>
|
||||
<svelte:fragment slot="menu">
|
||||
<ActionMenu.Root noPadding>
|
||||
<ActionMenu.Item.Anchor
|
||||
on:click={toggle}
|
||||
href={getSourceDownload(deployment.$id)}
|
||||
external>
|
||||
Download source
|
||||
</ActionMenu.Item.Anchor>
|
||||
<ActionMenu.Item.Anchor
|
||||
on:click={toggle}
|
||||
href={getOutputDownload(deployment.$id)}
|
||||
external>
|
||||
Download output
|
||||
</ActionMenu.Item.Anchor>
|
||||
</ActionMenu.Root>
|
||||
</svelte:fragment>
|
||||
</SubMenu>
|
||||
{/if}
|
||||
|
||||
{#if deployment?.status === 'processing' || deployment?.status === 'building' || deployment.status === 'waiting'}
|
||||
@@ -89,7 +108,6 @@
|
||||
e.preventDefault();
|
||||
selectedDeployment = deployment;
|
||||
showCancel = true;
|
||||
toggle(e);
|
||||
}}>
|
||||
Cancel
|
||||
</ActionMenu.Item.Button>
|
||||
@@ -102,11 +120,10 @@
|
||||
e.preventDefault();
|
||||
selectedDeployment = deployment;
|
||||
showDelete = true;
|
||||
toggle(e);
|
||||
}}>
|
||||
Delete
|
||||
</ActionMenu.Item.Button>
|
||||
{/if}
|
||||
</ActionMenu.Root>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
</Menu>
|
||||
|
||||
Reference in New Issue
Block a user