update: layout fixes

This commit is contained in:
Darshan
2025-08-14 12:51:37 +05:30
parent 39a758fb10
commit 3aefacf44f
12 changed files with 175 additions and 151 deletions
+2 -1
View File
@@ -6,6 +6,7 @@
import { IconViewBoards } from '@appwrite.io/pink-icons-svelte';
import ViewToggle from './viewToggle.svelte';
import ColumnSelector from './columnSelector.svelte';
import { isSmallViewport } from '$lib/stores/viewport';
export let onlyIcon = false;
export let ui: 'legacy' | 'new' = 'legacy';
@@ -25,7 +26,7 @@
size="s"
icon={onlyIcon}
variant="secondary"
class={onlyIcon ? 'width-fix' : undefined}
class={onlyIcon && !$isSmallViewport ? 'width-fix' : undefined}
disabled={!$columns.length && showAnyway}
badge={selectedColumnsNumber.toString()}
on:click={toggle}>
+2 -2
View File
@@ -20,8 +20,8 @@
$isSmallViewport ? 'var(--font-size-m)' : 'var(--font-size-xxxl)'
);
const currentFontSize = $derived(collapsed ? 'var(--font-size-l)' : expandedSize);
// const currentFontSize = $derived(collapsed ? 'var(--font-size-l)' : 'var(--font-size-xxxl)');
// const currentFontSize = $derived(collapsed ? 'var(--font-size-l)' : expandedSize);
const currentFontSize = $derived(collapsed ? 'var(--font-size-l)' : 'var(--font-size-xxxl)');
const currentLineHeight = $derived(collapsed ? '130%' : '140%');
const currentLetterSpacing = $derived(collapsed ? '0' : '-0.144px');
+16 -2
View File
@@ -4,11 +4,11 @@
// TODO: needs better props
export let expanded = false;
export let expandHeightButton = false;
export let slotSpacing = false;
export let overlapCover = false;
export let paddingInlineEnd = true;
export let databasesScreen = false;
export let expandHeightButton = false;
export let size: 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl' = null;
$: style = size
@@ -45,6 +45,11 @@
padding-inline-end: 0 !important;
margin-block: var(--base-8) !important;
@media (min-width: 1440px) {
margin-inline: 0 !important;
padding-inline: 53px !important;
}
&.expandHeightButton {
margin-inline-end: unset;
margin-inline-start: 2.75rem;
@@ -81,25 +86,34 @@
&.databasesScreen {
@media (min-width: 1440px) {
min-width: 1070px;
max-width: 1144px;
/*max-width: 1144px;*/
}
@media (min-width: 1728px) {
min-width: 1070px;
padding-inline: 196px !important;
}
}
@media (min-width: 360px) {
margin-inline: 1rem;
}
@media (min-width: 1024px) {
margin-inline: auto;
max-width: calc(944px - 11rem);
}
@media (min-width: 1280px) {
margin-inline: auto;
max-width: 1000px;
}
@media (min-width: 1440px) {
margin-inline: auto;
max-width: 1144px;
}
@media (min-width: 1728px) {
margin-inline: auto;
max-width: 1200px;
+9 -2
View File
@@ -31,12 +31,12 @@
</script>
<div
class:animate
class:expanded
class:collapsed={animate && collapsed}
class:animate
class="top-cover-console"
style:block-size={animatedBlocksize}
style:margin-top={marginTop}
style:block-size={animatedBlocksize}
style:padding-block-start={headerPaddingTop}
style:padding-block-end={headerPaddingBottom}>
<div
@@ -91,18 +91,22 @@
@media (min-width: 360px) {
margin-inline: 1rem;
}
@media (min-width: 1024px) {
margin-inline: auto;
max-width: calc(944px - 11rem);
}
@media (min-width: 1280px) {
margin-inline: auto;
max-width: 1000px;
}
@media (min-width: 1440px) {
margin-inline: auto;
max-width: 1144px;
}
@media (min-width: 1728px) {
margin-inline: auto;
max-width: 1200px;
@@ -119,5 +123,8 @@
.expanded-slot {
margin-inline: 3rem !important;
@media (max-width: 768px) {
margin-inline: 0 !important;
}
}
</style>
+10 -3
View File
@@ -16,8 +16,10 @@
const currentYear = new Date().getFullYear();
// for spreadsheet ui
const hideFooter = $derived(page.route.id?.includes('table-[table]'));
const hideFooter = $derived.by(() => {
const endings = ['table-[table]', 'table-[table]/columns', 'table-[table]/indexes'];
return endings.some((end) => page.route.id?.endsWith(end));
});
</script>
<footer class:hide={hideFooter}>
@@ -175,10 +177,15 @@
:global(main:has(.sub-navigation)) footer {
@media (min-width: 1024px) {
margin-inline-start: -1.5rem;
margin-inline-end: 2rem;
margin-inline-start: -1.5rem;
}
}
:global(main:has(.wide-screen-wrapper)) footer {
margin-inline-start: 2rem !important;
}
.extra-margin {
margin-block-start: var(--space-2, 4px);
}
+1 -9
View File
@@ -239,21 +239,13 @@
}
@media (max-width: 768px) {
.main-content {
.main-content:not(:has(.wide-screen-wrapper)) {
width: 100%;
position: fixed;
}
}
}
:global(main:has(.wide-screen-wrapper)) {
@media (min-width: 1728px) {
.main-content {
padding-left: 255px;
}
}
}
.overlay {
position: fixed;
width: 100vw;
@@ -1,6 +1,5 @@
<script lang="ts">
import { Button } from '$lib/elements/forms';
import { Container } from '$lib/layout';
import {
ActionMenu,
Badge,
@@ -117,6 +116,17 @@
enum: IconViewList
};
const emptyCellsLimit = $derived($isSmallViewport ? 16 : 18);
const emptyCellsCount = $derived(
updatedColumnsForSheet.length >= emptyCellsLimit
? 0
: emptyCellsLimit - updatedColumnsForSheet.length
);
onMount(() => {
columnsOrder = preferences.getColumnOrder(tableId);
});
function getColumnStatusBadge(status: string): ComponentProps<Badge>['type'] {
switch (status) {
case 'processing':
@@ -130,16 +140,17 @@
}
}
const emptyCellsLimit = $derived($isSmallViewport ? 14 : 17);
const emptyCellsCount = $derived(
updatedColumnsForSheet.length >= emptyCellsLimit
? 0
: emptyCellsLimit - updatedColumnsForSheet.length
);
onMount(() => {
columnsOrder = preferences.getColumnOrder(tableId);
});
function getMinMaxSizeForColumn(column: Columns): string | undefined {
if (column.type === 'string' && !column['format'] && column.key !== '$id') {
const stringColumn = column as Models.ColumnString;
return `Size: ${stringColumn.size}`;
} else if (column.type === 'integer' || column.type === 'double') {
const numbersColumn = column as Models.ColumnInteger | Models.ColumnFloat;
return `Min: ${numbersColumn.min}, Max: ${numbersColumn.max}`;
} else {
return undefined;
}
}
onDestroy(() => ($showCreateAttributeSheet.show = false));
@@ -151,22 +162,6 @@
});
</script>
<Container expanded style="background: var(--bgcolor-neutral-primary)">
<Layout.Stack direction="row" justifyContent="flex-end">
{#if updatedColumnsForSheet}
<Button
size="s"
secondary
disabled={$isCsvImportInProgress}
on:click={() => ($showCreateAttributeSheet.show = true)}
event="create_attribute">
<Icon icon={IconPlus} slot="start" size="s" />
Create column
</Button>
{/if}
</Layout.Stack>
</Container>
<div class="databases-spreadsheet">
<SpreadsheetContainer bind:this={spreadsheetContainer}>
<Spreadsheet.Root
@@ -176,8 +171,8 @@
emptyCells={emptyCellsCount}
bind:selectedRows={selectedColumns}
columns={[
{ id: 'key', width: { min: 200 } },
{ id: 'size', width: { min: 200 } },
// more size until we decide if we want a new column!
{ id: 'key', width: { min: $isSmallViewport ? 250 : 200 } },
{ id: 'indexed', width: { min: 150 } },
{ id: 'default', width: { min: 200 } },
{ id: 'actions', width: 40, isAction: true }
@@ -185,7 +180,6 @@
bottomActionClick={() => ($showCreateAttributeSheet.show = true)}>
<svelte:fragment slot="header" let:root>
<Spreadsheet.Header.Cell column="key" {root}>Column name</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="size" {root}>Size</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="indexed" {root}>Indexed</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="default" {root}
>Default value</Spreadsheet.Header.Cell>
@@ -199,71 +193,72 @@
column['system'] || column.type === 'relationship' ? 'disabled' : true}
<Spreadsheet.Row.Base {root} select={isSelectable} id={column.key}>
<Spreadsheet.Cell column="key" {root} isEditable={false}>
<Layout.Stack direction="row" alignItems="center">
{#if isRelationship(column)}
<Icon
size="s"
icon={column?.twoWay
? IconSwitchHorizontal
: IconArrowSmRight} />
{:else if 'format' in column && column.format}
{@const icon = columnFormatIcon[column?.format]}
<Icon {icon} size="s" />
{:else if column.key === '$id'}
<Icon icon={IconFingerPrint} size="s" />
{:else}
<Icon icon={option.icon} size="s" />
{/if}
<Layout.Stack direction="row" justifyContent="space-between">
<Layout.Stack direction="row" alignItems="center" inline>
{#if isRelationship(column)}
<Icon
size="s"
icon={column?.twoWay
? IconSwitchHorizontal
: IconArrowSmRight} />
{:else if 'format' in column && column.format}
{@const icon = columnFormatIcon[column?.format]}
<Icon {icon} size="s" />
{:else if column.key === '$id'}
<Icon icon={IconFingerPrint} size="s" />
{:else}
<Icon icon={option.icon} size="s" />
{/if}
<Layout.Stack direction="row" alignItems="center" gap="s">
<Layout.Stack inline direction="row" alignItems="center" gap="xxs">
<span class="text u-trim-1" data-private>
{#if column.key === '$id' || column.key === '$sequence' || column.key === '$createdAt' || column.key === '$updatedAt'}
{column['name']}
{:else}
{column.key} {column.array ? '[]' : undefined}
<Layout.Stack direction="row" alignItems="center" gap="s">
<Layout.Stack
inline
direction="row"
alignItems="center"
gap="xxs">
<span class="text u-trim-1" data-private>
{#if column.key === '$id' || column.key === '$sequence' || column.key === '$createdAt' || column.key === '$updatedAt'}
{column['name']}
{:else}
{column.key} {column.array ? '[]' : undefined}
{/if}
</span>
{#if isString(column) && column.encrypt}
<Tooltip>
<Icon
size="s"
icon={IconLockClosed}
color="--fgcolor-neutral-tertiary" />
<div slot="tooltip">Encrypted</div>
</Tooltip>
{/if}
</span>
{#if isString(column) && column.encrypt}
<Tooltip>
<Icon
size="s"
icon={IconLockClosed}
color="--fgcolor-neutral-tertiary" />
<div slot="tooltip">Encrypted</div>
</Tooltip>
</Layout.Stack>
{#if column.status !== 'available'}
<Badge
size="s"
variant="secondary"
content={column.status}
type={getColumnStatusBadge(column.status)} />
{#if column.error}
<Link.Button
variant="muted"
on:click={(e) => {
e.preventDefault();
error = column.error;
showFailed = true;
}}>Details</Link.Button>
{/if}
{:else if column.required}
<Badge size="xs" variant="secondary" content="required" />
{/if}
</Layout.Stack>
{#if column.status !== 'available'}
<Badge
size="s"
variant="secondary"
content={column.status}
type={getColumnStatusBadge(column.status)} />
{#if column.error}
<Link.Button
variant="muted"
on:click={(e) => {
e.preventDefault();
error = column.error;
showFailed = true;
}}>Details</Link.Button>
{/if}
{:else if column.required}
<Badge size="xs" variant="secondary" content="required" />
{/if}
</Layout.Stack>
{@const minMaxSize = getMinMaxSizeForColumn(column)}
{#if minMaxSize}
<Badge size="xs" content={minMaxSize} variant="secondary" />
{/if}
</Layout.Stack>
</Spreadsheet.Cell>
<Spreadsheet.Cell column="size" {root} isEditable={false}>
{#if column.type === 'string'}
{column.size /* or length */}
{:else if column.type === 'integer' || column.type === 'double'}
Min: {column.min} Max: {column.max}
{:else}
-
{/if}
</Spreadsheet.Cell>
<Spreadsheet.Cell column="indexed" {root} isEditable={false}>
{@const isIndexed = $indexes.some((index) =>
index.columns.includes(column.key)
@@ -59,37 +59,55 @@
const link = $derived(
`${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}`
);
const nonSheetPages = $derived.by(() => {
const endings = ['table-[table]', 'table-[table]/columns', 'table-[table]/indexes'];
const isSpreadsheetPage = endings.some((end) => page.route.id?.endsWith(end));
return !isSpreadsheetPage;
});
</script>
<Cover expanded collapsed={!$expandTabs} blocksize={$expandTabs ? '152px' : '90px'} animate={true}>
<svelte:fragment slot="header">
<Layout.Stack direction="row" alignContent="center" alignItems="center" inline>
<AnimatedTitle href={link} collapsed={!$expandTabs}>
{$table?.name}
</AnimatedTitle>
<div class:nonSheetPages>
<Cover animate expanded collapsed={!$expandTabs} blocksize={$expandTabs ? '152px' : '90px'}>
<svelte:fragment slot="header">
<Layout.Stack direction="row" alignContent="center" alignItems="center" inline>
<AnimatedTitle href={link} collapsed={!$expandTabs}>
{$table?.name}
</AnimatedTitle>
{#key $table?.$id}
<Id value={$table?.$id} tooltipPlacement={$expandTabs ? undefined : 'right'}
>{$table?.$id}</Id>
{/key}
</Layout.Stack>
</svelte:fragment>
{#key $table?.$id}
<Id value={$table?.$id} tooltipPlacement={$expandTabs ? undefined : 'right'}
>{$table?.$id}</Id>
{/key}
</Layout.Stack>
</svelte:fragment>
<div class="tabs-container" class:collapsed={!$expandTabs}>
<Tabs>
{#each tabs as tab}
<Tab
href={tab.href}
selected={isTabSelected(tab, page.url.pathname, path, tabs)}
event={tab.event}>
{tab.title}
</Tab>
{/each}
</Tabs>
</div>
</Cover>
<div class="tabs-container" class:collapsed={!$expandTabs}>
<Tabs>
{#each tabs as tab}
<Tab
href={tab.href}
selected={isTabSelected(tab, page.url.pathname, path, tabs)}
event={tab.event}>
{tab.title}
</Tab>
{/each}
</Tabs>
</div>
</Cover>
</div>
<style lang="scss">
.nonSheetPages :global(.cover-container) {
@media (min-width: 1440px) {
padding-inline: 7px !important;
}
@media (min-width: 1728px) {
padding-inline: 10.25rem !important;
}
}
.tabs-container {
opacity: 1;
transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1);
@@ -94,21 +94,6 @@
});
</script>
<Container expanded style="background: var(--bgcolor-neutral-primary)">
<Layout.Stack direction="row" justifyContent="flex-end">
{#if $canWriteTables}
<Button
secondary
event="create_index"
disabled={!$table?.columns?.length}
on:click={() => (showCreateIndex = true)}>
<Icon icon={IconPlus} slot="start" size="s" />
Create index
</Button>
{/if}
</Layout.Stack>
</Container>
<div class="databases-spreadsheet">
{#if data.table?.columns?.length}
{#if data.table.indexes.length}
@@ -310,8 +310,12 @@
height: 79.1vh !important;
}
@media (max-width: 768px) {
height: 70vh;
@media (max-width: 1024px) {
height: 76vh;
}
@media (min-width: 1024px) {
height: 80.35vh;
}
}
@@ -9,7 +9,7 @@
import UpdateStatus from './updateStatus.svelte';
</script>
<div class="wide-screen-wrapper databases-spreadsheet">
<div class="wide-screen-wrapper databases-spreadsheet" style:padding-bottom="1rem">
<Container expanded slotSpacing databasesScreen>
{#if $table}
<UpdateStatus />
@@ -76,6 +76,7 @@
import { pageToOffset } from '$lib/helpers/load';
import { debounce } from '$lib/helpers/debounce';
import { hash } from '$lib/helpers/string';
import { abbreviateNumber } from '$lib/helpers/numbers';
export let data: PageData;
export let showRecordsCreateSheet: {
@@ -905,7 +906,7 @@
<span style:white-space="nowrap">
{selectedRows.length
? `${selectedRows.length} row${selectedRows.length === 1 ? '' : 's'} selected`
: `${$rows.total} row${$rows.total === 1 ? '' : 's'}`}
: `${abbreviateNumber($rows.total)} row${$rows.total === 1 ? '' : 's'}`}
</span>
</Typography.Text>