mirror of
https://github.com/immich-app/immich.git
synced 2026-01-15 14:33:16 -08:00
Compare commits
2 Commits
push-mmvrm
...
refactor/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c55564487e | ||
|
|
887033ced3 |
@@ -1,21 +0,0 @@
|
||||
<script lang="ts">
|
||||
import BottomInfo from '$lib/components/shared-components/side-bar/bottom-info.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { NavbarItem } from '@immich/ui';
|
||||
import { mdiAccountMultipleOutline, mdiBookshelf, mdiCog, mdiServer, mdiTrayFull } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
</script>
|
||||
|
||||
<div class="h-full flex flex-col justify-between gap-2">
|
||||
<div class="flex flex-col pt-8 pe-4 gap-1">
|
||||
<NavbarItem title={$t('users')} href={AppRoute.ADMIN_USERS} icon={mdiAccountMultipleOutline} />
|
||||
<NavbarItem title={$t('external_libraries')} href={AppRoute.ADMIN_LIBRARIES} icon={mdiBookshelf} />
|
||||
<NavbarItem title={$t('admin.queues')} href={AppRoute.ADMIN_QUEUES} icon={mdiTrayFull} />
|
||||
<NavbarItem title={$t('settings')} href={AppRoute.ADMIN_SETTINGS} icon={mdiCog} />
|
||||
<NavbarItem title={$t('server_stats')} href={AppRoute.ADMIN_STATS} icon={mdiServer} />
|
||||
</div>
|
||||
|
||||
<div class="mb-2 me-4">
|
||||
<BottomInfo />
|
||||
</div>
|
||||
</div>
|
||||
61
web/src/lib/components/BreadcrumbActionPage.svelte
Normal file
61
web/src/lib/components/BreadcrumbActionPage.svelte
Normal file
@@ -0,0 +1,61 @@
|
||||
<script lang="ts">
|
||||
import type { HeaderButtonActionItem } from '$lib/types';
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Button,
|
||||
Container,
|
||||
ContextMenuButton,
|
||||
HStack,
|
||||
MenuItemType,
|
||||
Scrollable,
|
||||
isMenuItemType,
|
||||
type BreadcrumbItem,
|
||||
} from '@immich/ui';
|
||||
import { mdiSlashForward } from '@mdi/js';
|
||||
import type { Snippet } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
type Props = {
|
||||
breadcrumbs?: BreadcrumbItem[];
|
||||
actions?: Array<HeaderButtonActionItem | MenuItemType>;
|
||||
children?: Snippet;
|
||||
};
|
||||
|
||||
let { breadcrumbs = [], actions = [], children }: Props = $props();
|
||||
|
||||
const enabledActions = $derived(
|
||||
actions
|
||||
.filter((action): action is HeaderButtonActionItem => !isMenuItemType(action))
|
||||
.filter((action) => action.$if?.() ?? true),
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="flex h-16 w-full justify-between items-center border-b py-2 px-4 md:px-2">
|
||||
<Breadcrumbs items={breadcrumbs} separator={mdiSlashForward} />
|
||||
|
||||
{#if enabledActions.length > 0}
|
||||
<div class="hidden md:block">
|
||||
<HStack gap={0}>
|
||||
{#each enabledActions as action, i (i)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="small"
|
||||
color={action.color ?? 'secondary'}
|
||||
leadingIcon={action.icon}
|
||||
onclick={() => action.onAction(action)}
|
||||
title={action.data?.title}
|
||||
>
|
||||
{action.title}
|
||||
</Button>
|
||||
{/each}
|
||||
</HStack>
|
||||
</div>
|
||||
|
||||
<ContextMenuButton aria-label={$t('open')} items={actions} class="md:hidden" />
|
||||
{/if}
|
||||
</div>
|
||||
<Scrollable class="grow">
|
||||
<Container class="p-2 pb-16" {children} />
|
||||
</Scrollable>
|
||||
</div>
|
||||
@@ -1,23 +1,12 @@
|
||||
<script lang="ts">
|
||||
import AdminSidebar from '$lib/components/AdminSidebar.svelte';
|
||||
import PageContent from '$lib/components/layouts/PageContent.svelte';
|
||||
import BreadcrumbActionPage from '$lib/components/BreadcrumbActionPage.svelte';
|
||||
import NavigationBar from '$lib/components/shared-components/navigation-bar/navigation-bar.svelte';
|
||||
import BottomInfo from '$lib/components/shared-components/side-bar/bottom-info.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { sidebarStore } from '$lib/stores/sidebar.svelte';
|
||||
import type { HeaderButtonActionItem } from '$lib/types';
|
||||
import {
|
||||
AppShell,
|
||||
AppShellHeader,
|
||||
AppShellSidebar,
|
||||
Breadcrumbs,
|
||||
Button,
|
||||
ContextMenuButton,
|
||||
HStack,
|
||||
MenuItemType,
|
||||
Scrollable,
|
||||
isMenuItemType,
|
||||
type BreadcrumbItem,
|
||||
} from '@immich/ui';
|
||||
import { mdiSlashForward } from '@mdi/js';
|
||||
import { AppShell, AppShellHeader, AppShellSidebar, MenuItemType, NavbarItem, type BreadcrumbItem } from '@immich/ui';
|
||||
import { mdiAccountMultipleOutline, mdiBookshelf, mdiCog, mdiServer, mdiTrayFull } from '@mdi/js';
|
||||
import type { Snippet } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@@ -27,52 +16,31 @@
|
||||
children?: Snippet;
|
||||
};
|
||||
|
||||
let { breadcrumbs, actions = [], children }: Props = $props();
|
||||
|
||||
const enabledActions = $derived(
|
||||
actions
|
||||
.filter((action): action is HeaderButtonActionItem => !isMenuItemType(action))
|
||||
.filter((action) => action.$if?.() ?? true),
|
||||
);
|
||||
let { breadcrumbs, actions, children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<AppShell>
|
||||
<AppShellHeader>
|
||||
<NavigationBar showUploadButton={false} noBorder />
|
||||
<NavigationBar noBorder />
|
||||
</AppShellHeader>
|
||||
<AppShellSidebar bind:open={sidebarStore.isOpen} class="border-none shadow-none">
|
||||
<AdminSidebar />
|
||||
<AppShellSidebar
|
||||
bind:open={sidebarStore.isOpen}
|
||||
class="border-none shadow-none h-full flex flex-col justify-between gap-2"
|
||||
>
|
||||
<div class="flex flex-col pt-8 pe-4 gap-1">
|
||||
<NavbarItem title={$t('users')} href={AppRoute.ADMIN_USERS} icon={mdiAccountMultipleOutline} />
|
||||
<NavbarItem title={$t('external_libraries')} href={AppRoute.ADMIN_LIBRARIES} icon={mdiBookshelf} />
|
||||
<NavbarItem title={$t('admin.queues')} href={AppRoute.ADMIN_QUEUES} icon={mdiTrayFull} />
|
||||
<NavbarItem title={$t('settings')} href={AppRoute.ADMIN_SETTINGS} icon={mdiCog} />
|
||||
<NavbarItem title={$t('server_stats')} href={AppRoute.ADMIN_STATS} icon={mdiServer} />
|
||||
</div>
|
||||
|
||||
<div class="mb-2 me-4">
|
||||
<BottomInfo />
|
||||
</div>
|
||||
</AppShellSidebar>
|
||||
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="flex h-16 w-full justify-between items-center border-b py-2 px-4 md:px-2">
|
||||
<Breadcrumbs items={breadcrumbs} separator={mdiSlashForward} />
|
||||
|
||||
{#if enabledActions.length > 0}
|
||||
<div class="hidden md:block">
|
||||
<HStack gap={0}>
|
||||
{#each enabledActions as action, i (i)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="small"
|
||||
color={action.color ?? 'secondary'}
|
||||
leadingIcon={action.icon}
|
||||
onclick={() => action.onAction(action)}
|
||||
title={action.data?.title}
|
||||
>
|
||||
{action.title}
|
||||
</Button>
|
||||
{/each}
|
||||
</HStack>
|
||||
</div>
|
||||
|
||||
<ContextMenuButton aria-label={$t('open')} items={actions} class="md:hidden" />
|
||||
{/if}
|
||||
</div>
|
||||
<Scrollable class="grow">
|
||||
<PageContent>
|
||||
{@render children?.()}
|
||||
</PageContent>
|
||||
</Scrollable>
|
||||
</div>
|
||||
<BreadcrumbActionPage {breadcrumbs} {actions}>
|
||||
{@render children?.()}
|
||||
</BreadcrumbActionPage>
|
||||
</AppShell>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Container } from '@immich/ui';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
children?: Snippet;
|
||||
};
|
||||
|
||||
const { children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<Container class="p-2 pb-16" {children} />
|
||||
@@ -14,13 +14,11 @@
|
||||
|
||||
interface Props {
|
||||
hideNavbar?: boolean;
|
||||
showUploadButton?: boolean;
|
||||
title?: string | undefined;
|
||||
description?: string | undefined;
|
||||
scrollbar?: boolean;
|
||||
use?: ActionArray;
|
||||
actions?: Array<HeaderButtonActionItem | MenuItemType>;
|
||||
header?: Snippet;
|
||||
sidebar?: Snippet;
|
||||
buttons?: Snippet;
|
||||
children?: Snippet;
|
||||
@@ -28,13 +26,11 @@
|
||||
|
||||
let {
|
||||
hideNavbar = false,
|
||||
showUploadButton = false,
|
||||
title = undefined,
|
||||
description = undefined,
|
||||
scrollbar = true,
|
||||
use = [],
|
||||
actions = [],
|
||||
header,
|
||||
sidebar,
|
||||
buttons,
|
||||
children,
|
||||
@@ -52,10 +48,8 @@
|
||||
|
||||
<header>
|
||||
{#if !hideNavbar}
|
||||
<NavigationBar {showUploadButton} onUploadClick={() => openFileUploadDialog()} />
|
||||
<NavigationBar onUploadClick={() => openFileUploadDialog()} />
|
||||
{/if}
|
||||
|
||||
{@render header?.()}
|
||||
</header>
|
||||
<div
|
||||
tabindex="-1"
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
import UserAvatar from '../user-avatar.svelte';
|
||||
import AccountInfoPanel from './account-info-panel.svelte';
|
||||
|
||||
interface Props {
|
||||
showUploadButton?: boolean;
|
||||
type Props = {
|
||||
onUploadClick?: () => void;
|
||||
// TODO: remove once this is only used in <AppShellHeader>
|
||||
noBorder?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
let { showUploadButton = true, onUploadClick, noBorder = false }: Props = $props();
|
||||
let { onUploadClick, noBorder = false }: Props = $props();
|
||||
|
||||
let shouldShowAccountInfoPanel = $state(false);
|
||||
let shouldShowNotificationPanel = $state(false);
|
||||
@@ -105,7 +104,7 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if !page.url.pathname.includes('/admin') && showUploadButton && onUploadClick}
|
||||
{#if !page.url.pathname.includes('/admin') && onUploadClick}
|
||||
<Button
|
||||
leadingIcon={mdiTrayArrowUp}
|
||||
onclick={onUploadClick}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<UserPageLayout hideNavbar={assetInteraction.selectionActive} showUploadButton scrollbar={false}>
|
||||
<UserPageLayout hideNavbar={assetInteraction.selectionActive} scrollbar={false}>
|
||||
<Timeline
|
||||
enableRouting={true}
|
||||
bind:timelineManager
|
||||
|
||||
Reference in New Issue
Block a user