Code review updates
This commit is contained in:
parent
346c5426eb
commit
3a0d1460b6
|
@ -40,6 +40,10 @@
|
||||||
padding-left: var(--spacing-xl);
|
padding-left: var(--spacing-xl);
|
||||||
padding-right: var(--spacing-xl);
|
padding-right: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
.paddingX-XXL {
|
||||||
|
padding-left: calc(var(--spacing-xl) * 2);
|
||||||
|
padding-right: calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
.paddingY-S {
|
.paddingY-S {
|
||||||
padding-top: var(--spacing-s);
|
padding-top: var(--spacing-s);
|
||||||
padding-bottom: var(--spacing-s);
|
padding-bottom: var(--spacing-s);
|
||||||
|
@ -56,6 +60,10 @@
|
||||||
padding-top: var(--spacing-xl);
|
padding-top: var(--spacing-xl);
|
||||||
padding-bottom: var(--spacing-xl);
|
padding-bottom: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
.paddingY-XXL {
|
||||||
|
padding-top: calc(var(--spacing-xl) * 2);
|
||||||
|
padding-bottom: calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
.gap-XXS {
|
.gap-XXS {
|
||||||
grid-gap: var(--spacing-xs);
|
grid-gap: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
export let wide = false
|
export let wide = false
|
||||||
export let maxWidth = "80ch"
|
export let maxWidth = "80ch"
|
||||||
|
export let noPadding = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style="--max-width: {maxWidth}" class:wide>
|
<div style="--max-width: {maxWidth}" class:wide class:noPadding>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -23,4 +24,9 @@
|
||||||
max-width: none;
|
max-width: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noPadding {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
$: lockedByHeading =
|
$: lockedByHeading =
|
||||||
lockedBy && lockedByYou ? "Locked by you" : `Locked by ${lockIdentifer}`
|
lockedBy && lockedByYou ? "Locked by you" : `Locked by ${lockIdentifer}`
|
||||||
|
|
||||||
$: lockExpiry = getExpiryDuration(app)
|
|
||||||
|
|
||||||
const getExpiryDuration = app => {
|
const getExpiryDuration = app => {
|
||||||
if (!app?.lockedBy?.lockedAt) {
|
if (!app?.lockedBy?.lockedAt) {
|
||||||
return -1
|
return -1
|
||||||
|
@ -86,12 +84,12 @@
|
||||||
between your team.
|
between your team.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{#if lockedByYou && lockExpiry > 0}
|
{#if lockedByYou && getExpiryDuration(app) > 0}
|
||||||
<span class="lock-expiry-body">
|
<span class="lock-expiry-body">
|
||||||
{processStringSync(
|
{processStringSync(
|
||||||
"This lock will expire in {{ duration time 'millisecond' }} from now",
|
"This lock will expire in {{ duration time 'millisecond' }} from now",
|
||||||
{
|
{
|
||||||
time: lockExpiry,
|
time: getExpiryDuration(app),
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -10,20 +10,13 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="dash-card" data-cy={dataCy}>
|
<div class="dash-card" data-cy={dataCy}>
|
||||||
<div
|
<div class="dash-card-header" class:active={actionDefined} on:click={action}>
|
||||||
class={actionDefined ? "dash-card-header active" : "dash-card-header"}
|
|
||||||
on:click={() => {
|
|
||||||
if (actionDefined) {
|
|
||||||
action()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span class="dash-card-title">
|
<span class="dash-card-title">
|
||||||
<Detail size="M">{title}</Detail>
|
<Detail size="M">{title}</Detail>
|
||||||
</span>
|
</span>
|
||||||
<span class="dash-card-action">
|
<span class="dash-card-action">
|
||||||
{#if actionDefined}
|
{#if actionDefined}
|
||||||
<Icon name={actionIcon ? actionIcon : "ChevronRight"} />
|
<Icon name={actionIcon || "ChevronRight"} />
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,7 +29,6 @@
|
||||||
.dash-card {
|
.dash-card {
|
||||||
background: var(--spectrum-alias-background-color-primary);
|
background: var(--spectrum-alias-background-color-primary);
|
||||||
border-radius: var(--border-radius-s);
|
border-radius: var(--border-radius-s);
|
||||||
border: 1px solid var(--spectrum-global-color-gray-300);
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@
|
||||||
|
|
||||||
.mobile-toggle,
|
.mobile-toggle,
|
||||||
.user-dropdown {
|
.user-dropdown {
|
||||||
flex: 1 1 0;
|
flex: 0 1 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reduce BBUI page padding */
|
/* Reduce BBUI page padding */
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
notifications,
|
notifications,
|
||||||
Body,
|
Body,
|
||||||
Search,
|
Search,
|
||||||
Divider,
|
|
||||||
Helpers,
|
Helpers,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
|
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
|
||||||
|
@ -66,6 +65,9 @@
|
||||||
app?.name?.toLowerCase().includes(searchTerm.toLowerCase())
|
app?.name?.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$: lockedApps = filteredApps.filter(app => app?.lockedYou || app?.lockedOther)
|
||||||
|
$: unlocked = lockedApps?.length == 0
|
||||||
|
|
||||||
const enrichApps = (apps, user, sortBy) => {
|
const enrichApps = (apps, user, sortBy) => {
|
||||||
const enrichedApps = apps.map(app => ({
|
const enrichedApps = apps.map(app => ({
|
||||||
...app,
|
...app,
|
||||||
|
@ -178,10 +180,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const previewApp = app => {
|
|
||||||
window.open(`/${app.devId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const appOverview = app => {
|
const appOverview = app => {
|
||||||
$goto(`../overview/${app.devId}`)
|
$goto(`../overview/${app.devId}`)
|
||||||
}
|
}
|
||||||
|
@ -348,7 +346,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if enrichedApps.length}
|
{#if enrichedApps.length}
|
||||||
<Layout noPadding gap="S">
|
<Layout noPadding gap="L">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<Button
|
<Button
|
||||||
|
@ -414,8 +412,8 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<Divider size="S" />
|
|
||||||
<div class="appTable">
|
<div class="appTable" class:unlocked>
|
||||||
{#each filteredApps as app (app.appId)}
|
{#each filteredApps as app (app.appId)}
|
||||||
<AppRow
|
<AppRow
|
||||||
{copyAppId}
|
{copyAppId}
|
||||||
|
@ -428,7 +426,6 @@
|
||||||
{exportApp}
|
{exportApp}
|
||||||
{deleteApp}
|
{deleteApp}
|
||||||
{updateApp}
|
{updateApp}
|
||||||
{previewApp}
|
|
||||||
{appOverview}
|
{appOverview}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -490,6 +487,9 @@
|
||||||
<ChooseIconModal app={selectedApp} bind:this={iconModal} />
|
<ChooseIconModal app={selectedApp} bind:this={iconModal} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.appTable {
|
||||||
|
border-top: var(--border-light);
|
||||||
|
}
|
||||||
.app-actions {
|
.app-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -533,6 +533,11 @@
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr auto;
|
grid-template-columns: 1fr 1fr 1fr 1fr auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.appTable.unlocked {
|
||||||
|
grid-template-columns: 1fr 1fr auto 1fr auto;
|
||||||
|
}
|
||||||
|
|
||||||
.appTable :global(> div) {
|
.appTable :global(> div) {
|
||||||
height: 70px;
|
height: 70px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { goto } from "@roxi/routify"
|
import { goto } from "@roxi/routify"
|
||||||
import { Layout, Page, notifications, Button } from "@budibase/bbui"
|
import { Layout, Page, notifications, ActionButton } from "@budibase/bbui"
|
||||||
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
|
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { templates } from "stores/portal"
|
import { templates } from "stores/portal"
|
||||||
|
@ -25,16 +25,15 @@
|
||||||
<Page wide>
|
<Page wide>
|
||||||
<Layout noPadding gap="XL">
|
<Layout noPadding gap="XL">
|
||||||
<span>
|
<span>
|
||||||
<Button
|
<ActionButton
|
||||||
quiet
|
|
||||||
secondary
|
secondary
|
||||||
icon={"ChevronLeft"}
|
icon={"ArrowLeft"}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
$goto("../")
|
$goto("../")
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Back
|
Back
|
||||||
</Button>
|
</ActionButton>
|
||||||
</span>
|
</span>
|
||||||
{#if loaded && $templates?.length}
|
{#if loaded && $templates?.length}
|
||||||
<TemplateDisplay templates={$templates} />
|
<TemplateDisplay templates={$templates} />
|
||||||
|
|
|
@ -4,12 +4,18 @@
|
||||||
Layout,
|
Layout,
|
||||||
Page,
|
Page,
|
||||||
Button,
|
Button,
|
||||||
|
ActionButton,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Heading,
|
Heading,
|
||||||
Tab,
|
Tab,
|
||||||
Tabs,
|
Tabs,
|
||||||
notifications,
|
notifications,
|
||||||
ProgressCircle,
|
ProgressCircle,
|
||||||
|
Input,
|
||||||
|
ActionMenu,
|
||||||
|
MenuItem,
|
||||||
|
Icon,
|
||||||
|
Helpers,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import OverviewTab from "../_components/OverviewTab.svelte"
|
import OverviewTab from "../_components/OverviewTab.svelte"
|
||||||
import SettingsTab from "../_components/SettingsTab.svelte"
|
import SettingsTab from "../_components/SettingsTab.svelte"
|
||||||
|
@ -20,12 +26,17 @@
|
||||||
import { AppStatus } from "constants"
|
import { AppStatus } from "constants"
|
||||||
import AppLockModal from "components/common/AppLockModal.svelte"
|
import AppLockModal from "components/common/AppLockModal.svelte"
|
||||||
import EditableIcon from "components/common/EditableIcon.svelte"
|
import EditableIcon from "components/common/EditableIcon.svelte"
|
||||||
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import { checkIncomingDeploymentStatus } from "components/deploy/utils"
|
import { checkIncomingDeploymentStatus } from "components/deploy/utils"
|
||||||
import { onDestroy, onMount } from "svelte"
|
import { onDestroy, onMount } from "svelte"
|
||||||
|
|
||||||
export let application
|
export let application
|
||||||
|
|
||||||
let promise = getPackage()
|
let promise = getPackage()
|
||||||
|
let loaded = false
|
||||||
|
let deletionModal
|
||||||
|
let unpublishModal
|
||||||
|
let appName = ""
|
||||||
|
|
||||||
// App
|
// App
|
||||||
$: filteredApps = $apps.filter(app => app.devId === application)
|
$: filteredApps = $apps.filter(app => app.devId === application)
|
||||||
|
@ -74,6 +85,7 @@
|
||||||
try {
|
try {
|
||||||
const pkg = await API.fetchAppPackage(application)
|
const pkg = await API.fetchAppPackage(application)
|
||||||
await store.actions.initialise(pkg)
|
await store.actions.initialise(pkg)
|
||||||
|
loaded = true
|
||||||
return pkg
|
return pkg
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error(`Error initialising app: ${error?.message}`)
|
notifications.error(`Error initialising app: ${error?.message}`)
|
||||||
|
@ -121,6 +133,58 @@
|
||||||
$goto(`../../../app/${app.devId}`)
|
$goto(`../../../app/${app.devId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const copyAppId = async app => {
|
||||||
|
await Helpers.copyToClipboard(app.prodId)
|
||||||
|
notifications.success("App ID copied to clipboard.")
|
||||||
|
}
|
||||||
|
|
||||||
|
const exportApp = app => {
|
||||||
|
const id = isPublished ? app.prodId : app.devId
|
||||||
|
const appName = encodeURIComponent(app.name)
|
||||||
|
window.location = `/api/backups/export?appId=${id}&appname=${appName}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const unpublishApp = app => {
|
||||||
|
selectedApp = app
|
||||||
|
unpublishModal.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmUnpublishApp = async () => {
|
||||||
|
if (!selectedApp) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
analytics.captureEvent(Events.APP.UNPUBLISHED, {
|
||||||
|
appId: selectedApp.appId,
|
||||||
|
})
|
||||||
|
await API.unpublishApp(selectedApp.prodId)
|
||||||
|
await apps.load()
|
||||||
|
notifications.success("App unpublished successfully")
|
||||||
|
} catch (err) {
|
||||||
|
notifications.error("Error unpublishing app")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteApp = app => {
|
||||||
|
selectedApp = app
|
||||||
|
deletionModal.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmDeleteApp = async () => {
|
||||||
|
if (!selectedApp) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await API.deleteApp(selectedApp?.devId)
|
||||||
|
backToAppList()
|
||||||
|
notifications.success("App deleted successfully")
|
||||||
|
} catch (err) {
|
||||||
|
notifications.error("Error deleting app")
|
||||||
|
}
|
||||||
|
selectedApp = null
|
||||||
|
appName = null
|
||||||
|
}
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
store.actions.reset()
|
store.actions.reset()
|
||||||
})
|
})
|
||||||
|
@ -130,6 +194,7 @@
|
||||||
if (!apps.length) {
|
if (!apps.length) {
|
||||||
await apps.load()
|
await apps.load()
|
||||||
}
|
}
|
||||||
|
await API.syncApp(application)
|
||||||
deployments = await fetchDeployments()
|
deployments = await fetchDeployments()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error initialising app overview")
|
notifications.error("Error initialising app overview")
|
||||||
|
@ -137,18 +202,24 @@
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Page wide>
|
<span class="overview-wrap">
|
||||||
<Layout noPadding gap="XL">
|
<Page wide noPadding>
|
||||||
<span>
|
|
||||||
<Button quiet secondary icon={"ChevronLeft"} on:click={backToAppList}>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</span>
|
|
||||||
{#await promise}
|
{#await promise}
|
||||||
|
<span class="page-header">
|
||||||
|
<ActionButton secondary icon={"ArrowLeft"} on:click={backToAppList}>
|
||||||
|
Back
|
||||||
|
</ActionButton>
|
||||||
|
</span>
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
<ProgressCircle size="XL" />
|
<ProgressCircle size="XL" />
|
||||||
</div>
|
</div>
|
||||||
{:then _}
|
{:then _}
|
||||||
|
<Layout paddingX="XXL" paddingY="XXL" gap="XL">
|
||||||
|
<span class="page-header" class:loaded>
|
||||||
|
<ActionButton secondary icon={"ArrowLeft"} on:click={backToAppList}>
|
||||||
|
Back
|
||||||
|
</ActionButton>
|
||||||
|
</span>
|
||||||
<div class="overview-header">
|
<div class="overview-header">
|
||||||
<div class="app-title">
|
<div class="app-title">
|
||||||
<div class="app-logo">
|
<div class="app-logo">
|
||||||
|
@ -173,6 +244,7 @@
|
||||||
<ButtonGroup gap="XS">
|
<ButtonGroup gap="XS">
|
||||||
<Button
|
<Button
|
||||||
size="M"
|
size="M"
|
||||||
|
quiet
|
||||||
secondary
|
secondary
|
||||||
icon="Globe"
|
icon="Globe"
|
||||||
disabled={!isPublished}
|
disabled={!isPublished}
|
||||||
|
@ -193,8 +265,34 @@
|
||||||
<span>Edit</span>
|
<span>Edit</span>
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
<ActionMenu align="right" dataCy="app-overview-menu-popover">
|
||||||
|
<span slot="control" class="app-overview-actions-icon">
|
||||||
|
<Icon hoverable name="More" />
|
||||||
|
</span>
|
||||||
|
<MenuItem on:click={() => exportApp(selectedApp)} icon="Download">
|
||||||
|
Export
|
||||||
|
</MenuItem>
|
||||||
|
{#if isPublished}
|
||||||
|
<MenuItem
|
||||||
|
on:click={() => unpublishApp(selectedApp)}
|
||||||
|
icon="GlobeRemove"
|
||||||
|
>
|
||||||
|
Unpublish
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem on:click={() => copyAppId(selectedApp)} icon="Copy">
|
||||||
|
Copy App ID
|
||||||
|
</MenuItem>
|
||||||
|
{/if}
|
||||||
|
{#if !isPublished}
|
||||||
|
<MenuItem on:click={() => deleteApp(selectedApp)} icon="Delete">
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
|
{/if}
|
||||||
|
</ActionMenu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Layout>
|
||||||
|
<div class="tab-wrap">
|
||||||
<Tabs
|
<Tabs
|
||||||
selected={selectedTab}
|
selected={selectedTab}
|
||||||
noPadding
|
noPadding
|
||||||
|
@ -221,11 +319,38 @@
|
||||||
<SettingsTab app={selectedApp} />
|
<SettingsTab app={selectedApp} />
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
<ConfirmDialog
|
||||||
|
bind:this={deletionModal}
|
||||||
|
title="Confirm deletion"
|
||||||
|
okText="Delete app"
|
||||||
|
onOk={confirmDeleteApp}
|
||||||
|
onCancel={() => (appName = null)}
|
||||||
|
disabled={appName !== selectedApp?.name}
|
||||||
|
>
|
||||||
|
Are you sure you want to delete the app <b>{selectedApp?.name}</b>?
|
||||||
|
|
||||||
|
<p>Please enter the app name below to confirm.</p>
|
||||||
|
<Input
|
||||||
|
bind:value={appName}
|
||||||
|
data-cy="delete-app-confirmation"
|
||||||
|
placeholder={selectedApp?.name}
|
||||||
|
/>
|
||||||
|
</ConfirmDialog>
|
||||||
|
<ConfirmDialog
|
||||||
|
bind:this={unpublishModal}
|
||||||
|
title="Confirm unpublish"
|
||||||
|
okText="Unpublish app"
|
||||||
|
onOk={confirmUnpublishApp}
|
||||||
|
dataCy={"unpublish-modal"}
|
||||||
|
>
|
||||||
|
Are you sure you want to unpublish the app <b>{selectedApp?.name}</b>?
|
||||||
|
</ConfirmDialog>
|
||||||
{:catch error}
|
{:catch error}
|
||||||
<p>Something went wrong: {error.message}</p>
|
<p>Something went wrong: {error.message}</p>
|
||||||
{/await}
|
{/await}
|
||||||
</Layout>
|
</Page>
|
||||||
</Page>
|
</span>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.app-url {
|
.app-url {
|
||||||
|
@ -234,11 +359,35 @@
|
||||||
.loading {
|
.loading {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
.overview-header {
|
.overview-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-header.loaded {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overview-wrap :global(> div > .container),
|
||||||
|
.tab-wrap :global(.spectrum-Tabs) {
|
||||||
|
background-color: var(--background);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
.overview-header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--spacing-l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.overview-wrap :global(.content > *) {
|
||||||
|
padding: calc(var(--spacing-xl) * 1.5) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
.app-title {
|
.app-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacing-m);
|
gap: var(--spacing-m);
|
||||||
|
@ -252,4 +401,13 @@
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
margin-bottom: var(--spacing-s);
|
margin-bottom: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
.tab-wrap :global(.spectrum-Tabs) {
|
||||||
|
padding-left: calc(var(--spacing-xl) * 2);
|
||||||
|
padding-right: calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
padding-left: calc(var(--spacing-xl) * 2);
|
||||||
|
padding-right: calc(var(--spacing-xl) * 2);
|
||||||
|
padding-top: calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
<script>
|
<script>
|
||||||
import DashCard from "components/common/DashCard.svelte"
|
import DashCard from "components/common/DashCard.svelte"
|
||||||
import { AppStatus } from "constants"
|
import { AppStatus } from "constants"
|
||||||
import { Icon, Heading, Link, Avatar, notifications } from "@budibase/bbui"
|
import {
|
||||||
|
Icon,
|
||||||
|
Heading,
|
||||||
|
Link,
|
||||||
|
Avatar,
|
||||||
|
notifications,
|
||||||
|
Layout,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import clientPackage from "@budibase/client/package.json"
|
import clientPackage from "@budibase/client/package.json"
|
||||||
import { processStringSync } from "@budibase/string-templates"
|
import { processStringSync } from "@budibase/string-templates"
|
||||||
|
@ -41,6 +48,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="overview-tab">
|
<div class="overview-tab">
|
||||||
|
<Layout paddingX="XXL" paddingY="XXL">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<DashCard title={"App Status"} dataCy={"app-status"}>
|
<DashCard title={"App Status"} dataCy={"app-status"}>
|
||||||
<div class="status-content">
|
<div class="status-content">
|
||||||
|
@ -92,7 +100,8 @@
|
||||||
{processStringSync(
|
{processStringSync(
|
||||||
"Last edited {{ duration time 'millisecond' }} ago",
|
"Last edited {{ duration time 'millisecond' }} ago",
|
||||||
{
|
{
|
||||||
time: new Date().getTime() - new Date(app?.updatedAt).getTime(),
|
time:
|
||||||
|
new Date().getTime() - new Date(app?.updatedAt).getTime(),
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -111,7 +120,8 @@
|
||||||
<Heading size="XS">{$store.version}</Heading>
|
<Heading size="XS">{$store.version}</Heading>
|
||||||
{#if updateAvailable}
|
{#if updateAvailable}
|
||||||
<p class="version-status">
|
<p class="version-status">
|
||||||
New version <strong>{clientPackage.version}</strong> is available -
|
New version <strong>{clientPackage.version}</strong> is available
|
||||||
|
-
|
||||||
<Link
|
<Link
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (typeof navigateTab === "function") {
|
if (typeof navigateTab === "function") {
|
||||||
|
@ -167,6 +177,7 @@
|
||||||
</DashCard>
|
</DashCard>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
</Layout>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -180,6 +191,23 @@
|
||||||
grid-gap: var(--spacing-xl);
|
grid-gap: var(--spacing-xl);
|
||||||
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
.overview-tab .top {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: var(--spacing-xl);
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.overview-tab .top {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: var(--spacing-xl);
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.overview-tab .bottom,
|
.overview-tab .bottom,
|
||||||
.automation-metrics {
|
.automation-metrics {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
|
|
||||||
<div class="settings-tab">
|
<div class="settings-tab">
|
||||||
<Page wide={false}>
|
<Page wide={false}>
|
||||||
<Layout gap="XL" noPadding>
|
<Layout gap="XL" paddingY="XXL" paddingX="">
|
||||||
<span class="details-section">
|
<span class="details-section">
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
<Heading size="S">Name and Url</Heading>
|
<Heading size="S">Name and URL</Heading>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Body>
|
<Body>
|
||||||
<div class="app-details">
|
<div class="app-details">
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
</Layout>
|
</Layout>
|
||||||
</span>
|
</span>
|
||||||
<span class="version-section">
|
<span class="version-section">
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" paddingY="XXL" paddingX="">
|
||||||
<Heading size="S">App Version</Heading>
|
<Heading size="S">App version</Heading>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Body>
|
<Body>
|
||||||
{#if updateAvailable}
|
{#if updateAvailable}
|
||||||
|
@ -76,28 +76,26 @@
|
||||||
<strong>{$store.version}</strong>. You're running the latest!
|
<strong>{$store.version}</strong>. You're running the latest!
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
<p>
|
|
||||||
Updates can contain new features, performance improvements and bug
|
Updates can contain new features, performance improvements and bug
|
||||||
fixes.
|
fixes.
|
||||||
</p>
|
|
||||||
<div class="page-action">
|
<div class="page-action">
|
||||||
<Button cta on:click={versionModal.show()}>Update App</Button>
|
<Button cta on:click={versionModal.show()}>Update app</Button>
|
||||||
</div>
|
</div>
|
||||||
</Body>
|
</Body>
|
||||||
</Layout>
|
</Layout>
|
||||||
</span>
|
</span>
|
||||||
<span class="selfhost-section">
|
<span class="selfhost-section">
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" paddingY="XXL" paddingX="">
|
||||||
<Heading size="S">Self-host Budibase</Heading>
|
<Heading size="S">Self-host Budibase</Heading>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Body>
|
<Body>
|
||||||
<p>
|
Self-host Budibase for free to get unlimited apps and more - and it
|
||||||
Self-host Budibase for free to get unlimited apps and more - and
|
only takes a few minutes!
|
||||||
it only takes a few minutes!
|
|
||||||
</p>
|
|
||||||
<div class="page-action">
|
<div class="page-action">
|
||||||
<Button
|
<Button
|
||||||
cta
|
secondary
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
window.open(selfHostPath, "_blank")
|
window.open(selfHostPath, "_blank")
|
||||||
}}>Self-host Budibase</Button
|
}}>Self-host Budibase</Button
|
||||||
|
|
Loading…
Reference in New Issue