Add sidebar for portal and use it for automation history. Fix multiple overflow and scrolling issues

This commit is contained in:
Andrew Kingston 2022-12-21 09:47:17 +00:00
parent df1e1b0c3f
commit 285f11eca5
8 changed files with 179 additions and 169 deletions

View File

@ -56,5 +56,6 @@
--spectrum-semantic-positive-icon-color: #2d9d78; --spectrum-semantic-positive-icon-color: #2d9d78;
--spectrum-semantic-negative-icon-color: #e34850; --spectrum-semantic-negative-icon-color: #e34850;
min-width: 100px; min-width: 100px;
margin: 0;
} }
</style> </style>

View File

@ -1,15 +1,52 @@
<script> <script>
import { setContext } from "svelte"
import clickOutside from "../Actions/click_outside"
export let wide = false export let wide = false
export let narrow = false export let narrow = false
export let noPadding = false export let noPadding = false
let sidePanelVisble = false
setContext("side-panel", {
open: () => (sidePanelVisble = true),
close: () => (sidePanelVisble = false),
})
</script> </script>
<div class:wide class:noPadding class:narrow> <div class="page">
<slot /> <div class="main">
<div class="content" class:wide class:noPadding class:narrow>
<slot />
</div>
</div>
<div
id="side-panel"
class:visible={sidePanelVisble}
use:clickOutside={() => {
sidePanelVisble = false
}}
>
<slot name="side-panel" />
</div>
</div> </div>
<style> <style>
div { .page {
position: relative;
}
.page,
.main {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
flex: 1 1 auto;
}
.main {
overflow: auto;
}
.content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
@ -17,15 +54,31 @@
max-width: 1080px; max-width: 1080px;
margin: 0 auto; margin: 0 auto;
flex: 1 1 auto; flex: 1 1 auto;
padding-bottom: 50px; padding: 50px;
z-index: 1;
} }
.wide { .wide {
max-width: none; max-width: none;
} }
.narrow { .narrow {
max-width: 840px; max-width: 840px;
margin: 0; }
#side-panel {
position: absolute;
right: 0;
top: 0;
padding: 24px;
background: var(--background);
border-left: var(--border-light);
width: 320px;
overflow: auto;
overflow-x: hidden;
transform: translateX(100%);
transition: transform 130ms ease-out;
height: calc(100% - 48px);
z-index: 2;
}
#side-panel.visible {
transform: translateX(0);
} }
</style> </style>

View File

@ -87,7 +87,7 @@
"shortid": "2.2.15", "shortid": "2.2.15",
"svelte-dnd-action": "^0.9.8", "svelte-dnd-action": "^0.9.8",
"svelte-loading-spinners": "^0.1.1", "svelte-loading-spinners": "^0.1.1",
"svelte-portal": "0.1.0", "svelte-portal": "1.0.0",
"uuid": "8.3.1", "uuid": "8.3.1",
"yup": "0.29.2" "yup": "0.29.2"
}, },

View File

@ -304,7 +304,6 @@
justify-content: center; justify-content: center;
align-items: stretch; align-items: stretch;
overflow: auto; overflow: auto;
padding: 50px 50px 0 50px;
} }
@media (max-width: 640px) { @media (max-width: 640px) {

View File

@ -177,68 +177,63 @@
</script> </script>
{#if loaded} {#if loaded}
<Page narrow> <Layout noPadding>
<Layout noPadding> <Layout noPadding gap="XS">
<Layout noPadding gap="XS"> <Heading>Usage</Heading>
<Heading>Usage</Heading>
<Body>
<div>Get information about your current usage within Budibase</div>
</Body>
</Layout>
<Divider />
<Body> <Body>
To upgrade your plan and usage limits visit your <div>Get information about your current usage within Budibase</div>
<Link size="L" on:click={goToAccountPortal}>account</Link>.
</Body> </Body>
<DashCard </Layout>
description="YOUR CURRENT PLAN" <Divider />
title={planTitle()} <Body>
{primaryActionText} To upgrade your plan and usage limits visit your
primaryAction={accountPortalAccess ? goToAccountPortal : undefined} <Link size="L" on:click={goToAccountPortal}>account</Link>.
{textRows} </Body>
> <DashCard
<div class="content"> description="YOUR CURRENT PLAN"
title={planTitle()}
{primaryActionText}
primaryAction={accountPortalAccess ? goToAccountPortal : undefined}
{textRows}
>
<div class="content">
<div class="column">
<Layout noPadding>
{#each staticUsage as usage}
<div class="usage">
<Usage {usage} warnWhenFull={WARN_USAGE.includes(usage.name)} />
</div>
{/each}
</Layout>
</div>
{#if monthlyUsage.length}
<div class="column"> <div class="column">
<Layout noPadding> <Layout noPadding gap="M">
{#each staticUsage as usage} <Layout gap="XS" noPadding>
<div class="usage"> <Heading size="S">Monthly limits</Heading>
<div class="detail">
<TooltipWrapper tooltip={new Date(quotaReset)}>
<Detail size="M">
Resets in {daysRemainingInMonth} days
</Detail>
</TooltipWrapper>
</div>
</Layout>
<Layout noPadding gap="M">
{#each monthlyUsage as usage}
<Usage <Usage
{usage} {usage}
warnWhenFull={WARN_USAGE.includes(usage.name)} warnWhenFull={WARN_USAGE.includes(usage.name)}
/> />
</div> {/each}
{/each} </Layout>
</Layout> </Layout>
</div> </div>
{/if}
{#if monthlyUsage.length} </div>
<div class="column"> </DashCard>
<Layout noPadding gap="M"> </Layout>
<Layout gap="XS" noPadding>
<Heading size="S">Monthly limits</Heading>
<div class="detail">
<TooltipWrapper tooltip={new Date(quotaReset)}>
<Detail size="M">
Resets in {daysRemainingInMonth} days
</Detail>
</TooltipWrapper>
</div>
</Layout>
<Layout noPadding gap="M">
{#each monthlyUsage as usage}
<Usage
{usage}
warnWhenFull={WARN_USAGE.includes(usage.name)}
/>
{/each}
</Layout>
</Layout>
</div>
{/if}
</div>
</DashCard>
</Layout>
</Page>
{/if} {/if}
<style> <style>

View File

@ -1,5 +1,12 @@
<script> <script>
import { Layout, Icon, ActionButton, InlineAlert } from "@budibase/bbui" import {
Layout,
Body,
Button,
InlineAlert,
Heading,
Icon,
} from "@budibase/bbui"
import StatusRenderer from "./StatusRenderer.svelte" import StatusRenderer from "./StatusRenderer.svelte"
import DateTimeRenderer from "components/common/renderers/DateTimeRenderer.svelte" import DateTimeRenderer from "components/common/renderers/DateTimeRenderer.svelte"
import TestDisplay from "components/automation/AutomationBuilder/TestDisplay.svelte" import TestDisplay from "components/automation/AutomationBuilder/TestDisplay.svelte"
@ -17,90 +24,59 @@
</script> </script>
{#if history} {#if history}
<div class="body"> <Layout noPadding>
<div class="top"> <div class="controls">
<div class="controls"> <StatusRenderer value={history.status} />
<StatusRenderer value={history.status} /> <Icon hoverable name="Close" on:click={close} />
<ActionButton noPadding size="S" icon="Close" quiet on:click={close} />
</div>
</div> </div>
<Layout paddingY="XL" paddingX="XL" gap="S"> <Layout noPadding gap="XS">
<div class="icon"> <Heading>{history.automationName}</Heading>
<Icon name="Clock" /> <DateTimeRenderer value={history.createdAt} />
<DateTimeRenderer value={history.createdAt} />
</div>
<div class="icon">
<Icon name="JourneyVoyager" />
<div>{history.automationName}</div>
</div>
{#if history.status === STOPPED_ERROR}
<div class="cron-error">
<InlineAlert
type="error"
header="CRON automation disabled"
message="Fix the error and re-publish your app to re-activate."
/>
</div>
{/if}
<div>
{#if exists}
<ActionButton
icon="Edit"
fullWidth={false}
on:click={() =>
$goto(`../../../app/${appId}/automate/${history.automationId}`)}
>Edit automation</ActionButton
>
{/if}
</div>
</Layout> </Layout>
<div class="bottom"> {#if history.status === STOPPED_ERROR}
{#key history} <div class="cron-error">
<InlineAlert
type="error"
header="CRON automation disabled"
message="Fix the error and re-publish your app to re-activate."
/>
</div>
{/if}
{#if exists}
<div>
<Button
secondary
on:click={() => {
$goto(`../../../../app/${appId}/automate/${history.automationId}`)
}}
>
Edit automation
</Button>
</div>
{/if}
{#key history}
<div class="history">
<TestDisplay testResults={history} width="100%" /> <TestDisplay testResults={history} width="100%" />
{/key} </div>
</div> {/key}
</div> </Layout>
{:else} {:else}
<div>No details found</div> <Body>No details found</Body>
{/if} {/if}
<style> <style>
.body {
right: 0;
background-color: var(--background);
border-left: var(--border-light);
width: 420px;
height: calc(100vh - 240px);
position: fixed;
overflow: auto;
}
.top {
padding: var(--spacing-m) 0 var(--spacing-m) 0;
border-bottom: var(--border-light);
}
.bottom {
border-top: var(--border-light);
padding-top: calc(var(--spacing-xl) * 2);
padding-bottom: calc(var(--spacing-xl) * 2);
}
.icon {
display: flex;
gap: var(--spacing-m);
}
.controls { .controls {
padding: 0 var(--spacing-l) 0 var(--spacing-l); display: flex;
display: grid;
grid-template-columns: 1fr auto;
gap: var(--spacing-s); gap: var(--spacing-s);
justify-content: space-between;
align-items: center;
} }
.cron-error { .cron-error {
display: flex; display: flex;
width: 100%; width: 100%;
justify-content: center; justify-content: center;
} }
.history {
margin: 0 -30px;
}
</style> </style>

View File

@ -14,14 +14,16 @@
import HistoryDetailsPanel from "./_components/HistoryDetailsPanel.svelte" import HistoryDetailsPanel from "./_components/HistoryDetailsPanel.svelte"
import { automationStore } from "builderStore" import { automationStore } from "builderStore"
import { createPaginationStore } from "helpers/pagination" import { createPaginationStore } from "helpers/pagination"
import { onMount } from "svelte" import { getContext, onDestroy, onMount } from "svelte"
import dayjs from "dayjs" import dayjs from "dayjs"
import { auth, licensing, admin, overview } from "stores/portal" import { auth, licensing, admin, overview } from "stores/portal"
import { Constants } from "@budibase/frontend-core" import { Constants } from "@budibase/frontend-core"
import Portal from "svelte-portal"
const ERROR = "error", const ERROR = "error",
SUCCESS = "success", SUCCESS = "success",
STOPPED = "stopped" STOPPED = "stopped"
const sidePanel = getContext("side-panel")
let pageInfo = createPaginationStore() let pageInfo = createPaginationStore()
let runHistory = null let runHistory = null
@ -109,7 +111,7 @@
function viewDetails({ detail }) { function viewDetails({ detail }) {
selectedHistory = detail selectedHistory = detail
showPanel = true sidePanel.open()
} }
onMount(async () => { onMount(async () => {
@ -130,6 +132,10 @@
automationOptions.push({ value: automation._id, label: automation.name }) automationOptions.push({ value: automation._id, label: automation.name })
} }
}) })
onDestroy(() => {
sidePanel.close()
})
</script> </script>
<Layout noPadding> <Layout noPadding>
@ -209,15 +215,15 @@
{/if} {/if}
</Layout> </Layout>
<div class="panel" class:panelShow={showPanel}> {#if selectedHistory}
<HistoryDetailsPanel <Portal target="#side-panel">
appId={app.devId} <HistoryDetailsPanel
bind:history={selectedHistory} appId={app.devId}
close={() => { bind:history={selectedHistory}
showPanel = false close={sidePanel.close}
}} />
/> </Portal>
</div> {/if}
<style> <style>
.search { .search {
@ -226,39 +232,19 @@
width: 100%; width: 100%;
align-items: flex-end; align-items: flex-end;
} }
.select { .select {
flex-basis: 150px; flex-basis: 150px;
} }
.pagination { .pagination {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-end; justify-content: flex-end;
margin-top: var(--spacing-xl); margin-top: var(--spacing-xl);
} }
.panel {
display: none;
margin-top: calc(-1 * var(--spectrum-alias-grid-gutter-medium));
}
.panelShow {
display: block;
}
.panelOpen {
grid-template-columns: auto 420px;
}
.pro-upgrade { .pro-upgrade {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
flex: 1; flex: 1;
} }
.pro-copy {
margin-right: var(--spacing-l);
}
</style> </style>

View File

@ -5813,10 +5813,10 @@ svelte-loading-spinners@^0.1.1:
resolved "https://registry.yarnpkg.com/svelte-loading-spinners/-/svelte-loading-spinners-0.1.7.tgz#3fa6fa0ef67ab635773bf20b07d0b071debbadaa" resolved "https://registry.yarnpkg.com/svelte-loading-spinners/-/svelte-loading-spinners-0.1.7.tgz#3fa6fa0ef67ab635773bf20b07d0b071debbadaa"
integrity sha512-EKCId1DjVL2RSUVJJsvtNcqQHox03XIgh4xh/4p7r6ST7d8mut6INY9/LqK4A17PFU64+3quZmqiSfOlf480CA== integrity sha512-EKCId1DjVL2RSUVJJsvtNcqQHox03XIgh4xh/4p7r6ST7d8mut6INY9/LqK4A17PFU64+3quZmqiSfOlf480CA==
svelte-portal@0.1.0: svelte-portal@1.0.0:
version "0.1.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-0.1.0.tgz#cc2821cc84b05ed5814e0218dcdfcbebc53c1742" resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
integrity sha512-kef+ksXVKun224mRxat+DdO4C+cGHla+fEcZfnBAvoZocwiaceOfhf5azHYOPXSSB1igWVFTEOF3CDENPnuWxg== integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
svelte@^3.48.0: svelte@^3.48.0:
version "3.49.0" version "3.49.0"