Update home screen UI to work better on mobile and make spacing more consistent

This commit is contained in:
Andrew Kingston 2021-12-15 15:54:33 +00:00
parent 5da5acc27b
commit 07b2a411a4
5 changed files with 148 additions and 150 deletions

View File

@ -63,6 +63,9 @@
.gap-L { .gap-L {
grid-gap: var(--spectrum-alias-grid-gutter-medium); grid-gap: var(--spectrum-alias-grid-gutter-medium);
} }
.gap-XL {
grid-gap: var(--spectrum-alias-grid-gutter-large);
}
.horizontal.gap-S :global(*) + :global(*) { .horizontal.gap-S :global(*) + :global(*) {
margin-left: var(--spectrum-alias-grid-gutter-xsmall); margin-left: var(--spectrum-alias-grid-gutter-xsmall);
} }

View File

@ -13,3 +13,9 @@
> >
<slot /> <slot />
</p> </p>
<style>
p {
font-weight: 600;
}
</style>

View File

@ -62,12 +62,8 @@
</StatusLight> </StatusLight>
</div> </div>
<div> <div>
<Button <Button disabled={app.lockedOther} on:click={() => editApp(app)} secondary
disabled={app.lockedOther} >Open</Button
on:click={() => editApp(app)}
size="S"
quiet
secondary>Open</Button
> >
<ActionMenu align="right"> <ActionMenu align="right">
<Icon hoverable slot="control" name="More" /> <Icon hoverable slot="control" name="More" />
@ -91,7 +87,7 @@
<MenuItem on:click={() => updateApp(app)} icon="Edit">Edit</MenuItem> <MenuItem on:click={() => updateApp(app)} icon="Edit">Edit</MenuItem>
<MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem> <MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem>
{/if} {/if}
<MenuItem on:click={() => editIcon(app)} icon="Brush">Edit Icon</MenuItem> <MenuItem on:click={() => editIcon(app)} icon="Brush">Edit icon</MenuItem>
</ActionMenu> </ActionMenu>
</div> </div>

View File

@ -4,10 +4,11 @@
export let app export let app
let modal let modal
$: selectedIcon = app?.icon?.name $: selectedIcon = app?.icon?.name || "Apps"
$: selectedColor = app?.icon?.color $: selectedColor = app?.icon?.color
let iconsList = [ let iconsList = [
"Apps",
"Actions", "Actions",
"ConversionFunnel", "ConversionFunnel",
"App", "App",
@ -31,7 +32,6 @@
"GraphDonut", "GraphDonut",
"GraphBarHorizontal", "GraphBarHorizontal",
"Demographic", "Demographic",
"Apps",
] ]
export const show = () => { export const show = () => {
modal.show() modal.show()
@ -68,13 +68,13 @@
> >
<div class="scrollable-icons"> <div class="scrollable-icons">
<div class="title-spacing"> <div class="title-spacing">
<Label>Select an Icon</Label> <Label>Select an icon</Label>
</div> </div>
<div class="grid"> <div class="grid">
{#each iconsList as item} {#each iconsList as item}
<div <div
class="icon-item" class="icon-item"
style="color: {item === selectedIcon ? selectedColor : ''}" class:selected={item === selectedIcon}
on:click={() => (selectedIcon = item)} on:click={() => (selectedIcon = item)}
> >
<Icon name={item} /> <Icon name={item} />
@ -84,7 +84,7 @@
</div> </div>
<div class="color-selection"> <div class="color-selection">
<div> <div>
<Label>Select a Color</Label> <Label>Select a color</Label>
</div> </div>
<div class="color-selection-item"> <div class="color-selection-item">
<ColorPicker <ColorPicker
@ -124,4 +124,7 @@
.icon-item { .icon-item {
cursor: pointer; cursor: pointer;
} }
.icon-item.selected {
color: var(--spectrum-global-color-blue-600);
}
</style> </style>

View File

@ -43,6 +43,7 @@
let cloud = $admin.cloud let cloud = $admin.cloud
let appName = "" let appName = ""
let creatingFromTemplate = false let creatingFromTemplate = false
$: enrichedApps = enrichApps($apps, $auth.user, sortBy) $: enrichedApps = enrichApps($apps, $auth.user, sortBy)
$: filteredApps = enrichedApps.filter(app => $: filteredApps = enrichedApps.filter(app =>
app?.name?.toLowerCase().includes(searchTerm.toLowerCase()) app?.name?.toLowerCase().includes(searchTerm.toLowerCase())
@ -280,99 +281,104 @@
</script> </script>
<Page wide> <Page wide>
<Layout noPadding> <Layout noPadding gap="XL">
<div class="title"> <div class="title">
<Heading size="S">Welcome to Budibase</Heading> <Layout noPadding gap="XS">
<Heading size="M">Welcome to Budibase</Heading>
<Body size="S">
Manage your apps and get a head start with templates
</Body>
</Layout>
<ButtonGroup> <div class="buttons">
{#if cloud} <!--{#if cloud}-->
<Button secondary on:click={initiateAppsExport}>Export apps</Button> <Button icon="Export" quiet secondary on:click={initiateAppsExport}>
{/if} Export apps
<Button icon="Import" quiet secondary on:click={initiateAppImport} </Button>
>Import app</Button <!--{/if}-->
> <Button icon="Import" quiet secondary on:click={initiateAppImport}>
<Button icon="Add" cta on:click={initiateAppCreation}>Create app</Button Import app
> </Button>
</ButtonGroup> <Button icon="Add" cta on:click={initiateAppCreation}>
Create app
</Button>
</div>
</div> </div>
<div class="title-text"> <Layout noPadding gap="S">
<Body size="S">Manage your apps and get a head start with templates</Body> <Detail size="L">Quick start templates</Detail>
</div> <div class="grid">
<Detail>Quick Start Templates</Detail> {#each $templates as item}
<div class="grid"> <div
{#each $templates as item} on:click={() => {
<div template = item
on:click={() => { creationModal.show()
template = item creatingApp = true
creationModal.show() }}
creatingApp = true class="template-card"
}} >
class="template-card" <div class="card-body">
> <div style="color: {item.background}" class="iconAlign">
<div class="card-body"> <svg
<div style="color: {item.background}" class="iconAlign"> width="26px"
<svg height="26px"
width="26px" class="spectrum-Icon"
height="26px" style="color:{item.background};"
class="spectrum-Icon" focusable="false"
style="color:{item.background};" >
focusable="false" <use xlink:href="#spectrum-icon-18-{item.icon}" />
> </svg>
<use xlink:href="#spectrum-icon-18-{item.icon}" /> </div>
</svg> <div class="iconAlign">
</div> <Body weight="900" size="S">{item.name}</Body>
<div class="iconAlign"> <div style="font-size: 10px;">
<Body weight="900" size="S">{item.name}</Body> <Body size="S">{item.category.toUpperCase()}</Body>
<div style="font-size: 10px;"> </div>
<Body size="S">{item.category.toUpperCase()}</Body>
</div> </div>
</div> </div>
</div> </div>
</div>
{/each}
</div>
{#if loaded && enrichedApps.length}
<div class="title">
<Detail>My Apps</Detail>
</div>
<div class="filter">
<div class="select">
<Select
quiet
autoWidth
bind:value={sortBy}
placeholder={null}
options={[
{ label: "Sort by name", value: "name" },
{ label: "Sort by recently updated", value: "updated" },
{ label: "Sort by status", value: "status" },
]}
/>
<div class="desktop-search">
<Search quiet placeholder="Search" bind:value={searchTerm} />
</div>
</div>
</div>
<div class="mobile-search">
<Search placeholder="Search" bind:value={searchTerm} />
</div>
<div class="appTable">
{#each filteredApps as app (app.appId)}
<AppRow
{releaseLock}
{editIcon}
{app}
{unpublishApp}
{viewApp}
{editApp}
{exportApp}
{deleteApp}
{updateApp}
/>
{/each} {/each}
</div> </div>
</Layout>
{#if loaded && enrichedApps.length}
<Layout noPadding gap="S">
<div class="title">
<Detail size="L">My apps</Detail>
<div class="filter">
<Select
quiet
autoWidth
bind:value={sortBy}
placeholder={null}
options={[
{ label: "Sort by name", value: "name" },
{ label: "Sort by recently updated", value: "updated" },
{ label: "Sort by status", value: "status" },
]}
/>
<Search placeholder="Search" bind:value={searchTerm} />
</div>
</div>
<div class="appTable">
{#each filteredApps as app (app.appId)}
<AppRow
{releaseLock}
{editIcon}
{app}
{unpublishApp}
{viewApp}
{editApp}
{exportApp}
{deleteApp}
{updateApp}
/>
{/each}
</div>
</Layout>
{/if} {/if}
{#if !enrichedApps.length && !creatingApp && loaded} {#if !enrichedApps.length && !creatingApp && loaded}
<div class="empty-wrapper"> <div class="empty-wrapper">
<Modal inline> <Modal inline>
@ -380,6 +386,7 @@
</Modal> </Modal>
</div> </div>
{/if} {/if}
{#if creatingFromTemplate} {#if creatingFromTemplate}
<div class="empty-wrapper"> <div class="empty-wrapper">
<p>Creating your Budibase app from your selected template...</p> <p>Creating your Budibase app from your selected template...</p>
@ -427,68 +434,61 @@
<ChooseIconModal app={selectedApp} bind:this={iconModal} /> <ChooseIconModal app={selectedApp} bind:this={iconModal} />
<style> <style>
.title, .title {
.filter {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
gap: 5px; gap: var(--spacing-xl);
flex-wrap: wrap;
} }
.buttons {
@media only screen and (max-width: 560px) { display: flex;
.title { flex-direction: row;
flex-direction: column; justify-content: flex-start;
align-items: flex-start; align-items: center;
} gap: var(--spacing-xl);
.grid { flex-wrap: wrap;
grid-template-columns: repeat(2, 1fr); }
@media (max-width: 640px) {
.buttons {
flex-direction: row-reverse;
justify-content: flex-end;
} }
} }
.iconAlign { .filter {
padding: 0 0 0 var(--spacing-m); display: flex;
display: inline-block; flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: var(--spacing-xl);
}
.grid {
display: grid;
grid-gap: var(--spacing-xl);
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
} }
.template-card { .template-card {
height: 80px; height: 80px;
width: 270px;
border-radius: var(--border-radius-s); border-radius: var(--border-radius-s);
margin-bottom: var(--spacing-m);
border: 1px solid var(--spectrum-global-color-gray-300); border: 1px solid var(--spectrum-global-color-gray-300);
cursor: pointer; cursor: pointer;
display: flex; display: flex;
} }
.title-text { .template-card:hover {
margin-top: calc(var(--spacing-xl) * -1); background: var(--spectrum-alias-background-color-tertiary);
} }
.card-body { .card-body {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 12px; padding: 12px;
} }
.iconAlign {
.grid { padding: 0 0 0 var(--spacing-m);
display: grid; display: inline-block;
grid-gap: 5px;
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
}
@media (min-width: 200px) {
}
.select {
display: grid;
grid-template-columns: auto auto;
grid-gap: 30px;
}
.filter :global(.spectrum-ActionGroup) {
flex-wrap: nowrap;
}
.mobile-search {
display: none;
} }
.appTable { .appTable {
@ -511,6 +511,12 @@
.appTable :global(> div) { .appTable :global(> div) {
border-bottom: var(--border-light); border-bottom: var(--border-light);
} }
@media (max-width: 640px) {
.appTable {
grid-template-columns: 1fr auto;
}
}
.empty-wrapper { .empty-wrapper {
flex: 1 1 auto; flex: 1 1 auto;
height: 100%; height: 100%;
@ -519,20 +525,4 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
@media (max-width: 640px) {
.appTable {
grid-template-columns: 1fr auto;
}
.desktop-search {
display: none;
}
.mobile-search {
display: block;
}
}
.template-card:hover {
background: var(--spectrum-alias-background-color-tertiary);
}
</style> </style>