Add table app list view

This commit is contained in:
Andrew Kingston 2021-05-07 13:13:51 +01:00
parent 93b4a3bd78
commit e6e47a6d03
5 changed files with 123 additions and 39 deletions

View File

@ -7,43 +7,28 @@
ActionMenu, ActionMenu,
MenuItem, MenuItem,
Link, Link,
notifications,
} from "@budibase/bbui" } from "@budibase/bbui"
import download from "downloadjs"
import { gradient } from "actions" import { gradient } from "actions"
import { url } from "@roxi/routify"
export let name export let app
export let _id export let exportApp
let appExportLoading = false let appExportLoading = false
async function exportApp() {
appExportLoading = true
try {
download(
`/api/backups/export?appId=${_id}&appname=${encodeURIComponent(name)}`
)
notifications.success("App export complete")
} catch (err) {
console.error(err)
notifications.error("App export failed")
} finally {
appExportLoading = false
}
}
</script> </script>
<Layout noPadding gap="XS"> <Layout noPadding gap="XS">
<div class="preview" use:gradient /> <div class="preview" use:gradient />
<div class="title"> <div class="title">
<Link href={`/builder/app/${_id}`}> <Link href={$url(`../../app/${app._id}`)}>
<Heading size="XS"> <Heading size="XS">
{name} {app.name}
</Heading> </Heading>
</Link> </Link>
<ActionMenu> <ActionMenu>
<Icon slot="control" name="More" hoverable /> <Icon slot="control" name="More" hoverable />
<MenuItem on:click={exportApp} icon="Download">Export</MenuItem> <MenuItem on:click={() => exportApp(app)} icon="Download">Export</MenuItem
>
</ActionMenu> </ActionMenu>
</div> </div>
<div class="status"> <div class="status">

View File

@ -1,16 +1,16 @@
<script> <script>
import AppCard from "./AppCard.svelte" import AppCard from "./AppCard.svelte"
import { apps } from "stores/portal" import { apps } from "stores/portal"
export let exportApp
</script> </script>
{#if $apps.length} {#if $apps.length}
<div class="appList"> <div class="appList">
{#each $apps as app} {#each $apps as app}
<AppCard {...app} /> <AppCard {exportApp} {app} />
{/each} {/each}
</div> </div>
{:else}
<div>No apps found.</div>
{/if} {/if}
<style> <style>

View File

@ -1,23 +1,105 @@
<script> <script>
import AppCard from "./AppCard.svelte"
import { apps } from "stores/portal" import { apps } from "stores/portal"
import { Table } from "@budibase/bbui" import { gradient } from "actions"
import {
Heading,
Button,
Icon,
ActionMenu,
MenuItem,
Link,
} from "@budibase/bbui"
import { goto, url } from "@roxi/routify"
export let exportApp
const openApp = app => {
$goto(`../../app/${app._id}`)
}
</script> </script>
{#if $apps.length} {#if $apps.length}
<div class="appList"> <div class="appTable">
{#each $apps as app} {#each $apps as app}
<AppCard {...app} /> <div class="title">
<div class="preview" use:gradient />
<Link href={$url(`../../app/${app._id}`)}>
<Heading size="XS">
{app.name}
</Heading>
</Link>
</div>
<div>
Edited {Math.round(Math.random() * 10 + 1)} months ago
</div>
<div>
{#if Math.random() < 0.33}
<div class="status status--open" />
Open
{:else if Math.random() < 0.33}
<div class="status status--locked-other" />
Locked by Will Wheaton
{:else}
<div class="status status--locked-you" />
Locked by you
{/if}
</div>
<div class="actions">
<Button on:click={() => openApp(app)} size="S" secondary>Open</Button>
<ActionMenu align="right">
<Icon hoverable slot="control" name="More" />
<MenuItem on:click={() => exportApp(app)} icon="Download">
Export
</MenuItem>
</ActionMenu>
</div>
{/each} {/each}
</div> </div>
{:else}
<div>No apps found.</div>
{/if} {/if}
<style> <style>
.appList { .appTable {
display: grid; display: grid;
grid-gap: 50px; grid-template-rows: auto;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); grid-template-columns: 1fr 1fr 1fr auto;
align-items: center;
}
.appTable > div {
border-bottom: var(--border-light);
height: 70px;
display: grid;
align-items: center;
gap: var(--spacing-xl);
grid-template-columns: auto 1fr;
}
.preview {
height: 40px;
width: 40px;
border-radius: var(--border-radius-s);
}
.title :global(a) {
text-decoration: none;
}
.title :global(h1:hover) {
color: var(--spectrum-global-color-blue-600);
cursor: pointer;
transition: color 130ms ease;
}
.status {
height: 10px;
width: 10px;
border-radius: 50%;
}
.status--locked-you {
background-color: var(--spectrum-global-color-orange-600);
}
.status--locked-other {
background-color: var(--spectrum-global-color-red-600);
}
.status--open {
background-color: var(--spectrum-global-color-green-600);
}
.actions {
padding-right: 10px;
} }
</style> </style>

View File

@ -13,6 +13,7 @@
import { onMount } from "svelte" import { onMount } from "svelte"
import Logo from "/assets/bb-logo.svg" import Logo from "/assets/bb-logo.svg"
import { capitalise } from "../../helpers" import { capitalise } from "../../helpers"
import { goto } from "@roxi/routify"
export let template export let template
@ -111,7 +112,7 @@
} }
const userResp = await api.post(`/api/users/metadata/self`, user) const userResp = await api.post(`/api/users/metadata/self`, user)
await userResp.json() await userResp.json()
window.location = `/builder/app/${appJson._id}` $goto(`/builder/app/${appJson._id}`)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
notifications.error(error) notifications.error(error)

View File

@ -9,6 +9,7 @@
Select, Select,
Modal, Modal,
Page, Page,
notifications,
} from "@budibase/bbui" } from "@budibase/bbui"
import AppGridView from "components/start/AppGridView.svelte" import AppGridView from "components/start/AppGridView.svelte"
import AppTableView from "components/start/AppTableView.svelte" import AppTableView from "components/start/AppTableView.svelte"
@ -17,12 +18,13 @@
import analytics from "analytics" import analytics from "analytics"
import { onMount } from "svelte" import { onMount } from "svelte"
import { apps } from "stores/portal" import { apps } from "stores/portal"
import download from "downloadjs"
let layout = "grid" let layout = "grid"
let modal let modal
let template let template
async function checkKeys() { const checkKeys = async () => {
const response = await api.get(`/api/keys/`) const response = await api.get(`/api/keys/`)
const keys = await response.json() const keys = await response.json()
if (keys.userId) { if (keys.userId) {
@ -30,11 +32,25 @@
} }
} }
function initiateAppImport() { const initiateAppImport = () => {
template = { fromFile: true } template = { fromFile: true }
modal.show() modal.show()
} }
const exportApp = app => {
try {
download(
`/api/backups/export?appId=${app._id}&appname=${encodeURIComponent(
app.name
)}`
)
notifications.success("App export complete")
} catch (err) {
console.error(err)
notifications.error("App export failed")
}
}
onMount(() => { onMount(() => {
checkKeys() checkKeys()
apps.load() apps.load()
@ -70,9 +86,9 @@
</ActionGroup> </ActionGroup>
</div> </div>
{#if layout === "grid"} {#if layout === "grid"}
<AppGridView /> <AppGridView {exportApp} />
{:else} {:else}
<AppTableView /> <AppTableView {exportApp} />
{/if} {/if}
</Layout> </Layout>
</Page> </Page>