Update app overview version and name/url screens

This commit is contained in:
Andrew Kingston 2022-12-20 08:48:20 +00:00
parent cc86fa7aa9
commit b5e3505f55
10 changed files with 219 additions and 234 deletions

View File

@ -21,6 +21,7 @@
label { label {
padding: 0; padding: 0;
white-space: nowrap; white-space: nowrap;
color: var(--spectrum-global-color-gray-600);
} }
.muted { .muted {

View File

@ -1,48 +1,46 @@
<script> <script>
import { Icon } from "@budibase/bbui" import { Icon, Modal } from "@budibase/bbui"
import ChooseIconModal from "components/start/ChooseIconModal.svelte" import ChooseIconModal from "components/start/ChooseIconModal.svelte"
export let name export let name
export let size export let size = "M"
export let app export let app
export let color export let color
export let autoSave = false
let iconModal let modal
</script> </script>
<div class="editable-icon"> <div class="editable-icon">
<div <div class="hover" on:click={modal.show}>
class="edit-hover" <Icon name="Edit" {size} color="var(--spectrum-global-color-gray-600)" />
on:click={() => {
iconModal.show()
}}
>
<Icon name={"Edit"} size={"L"} />
</div> </div>
<div class="app-icon"> <div class="normal">
<Icon {name} {size} {color} /> <Icon {name} {size} {color} />
</div> </div>
</div> </div>
<ChooseIconModal {app} bind:this={iconModal} />
<Modal bind:this={modal}>
<ChooseIconModal {name} {color} {app} {autoSave} on:change />
</Modal>
<style> <style>
.editable-icon:hover .app-icon {
opacity: 0;
}
.editable-icon { .editable-icon {
position: relative; position: relative;
display: flex;
justify-content: flex-start;
} }
.editable-icon:hover .edit-hover { .normal {
opacity: 1; display: block;
} }
.edit-hover { .hover {
color: var(--spectrum-global-color-gray-600); display: none;
cursor: pointer; cursor: pointer;
z-index: 100; }
width: 100%; .editable-icon:hover .normal {
height: 100%; display: none;
position: absolute; }
opacity: 0; .editable-icon:hover .hover {
/* transition: opacity var(--spectrum-global-animation-duration-100) ease; */ display: block;
} }
</style> </style>

View File

@ -1,18 +1,20 @@
<script> <script>
import { import {
ModalContent, ModalContent,
Modal,
Icon, Icon,
ColorPicker, ColorPicker,
Label, Label,
notifications, notifications,
} from "@budibase/bbui" } from "@budibase/bbui"
import { apps } from "stores/portal" import { apps } from "stores/portal"
import { createEventDispatcher } from "svelte"
export let app export let app
let modal export let name
$: selectedIcon = app?.icon?.name || "Apps" export let color
$: selectedColor = app?.icon?.color export let autoSave = false
const dispatch = createEventDispatcher()
let iconsList = [ let iconsList = [
"Apps", "Apps",
@ -40,30 +42,15 @@
"GraphBarHorizontal", "GraphBarHorizontal",
"Demographic", "Demographic",
] ]
export const show = () => {
modal.show()
}
export const hide = () => {
modal.hide()
}
const onCancel = () => {
selectedIcon = ""
selectedColor = ""
hide()
}
const changeColor = val => {
selectedColor = val
}
const save = async () => { const save = async () => {
if (!autoSave) {
dispatch("change", { color, name })
return
}
try { try {
await apps.update(app.instance._id, { await apps.update(app.instance._id, {
icon: { icon: { name, color },
name: selectedIcon,
color: selectedColor,
},
}) })
} catch (error) { } catch (error) {
notifications.error("Error updating app") notifications.error("Error updating app")
@ -71,12 +58,7 @@
} }
</script> </script>
<Modal bind:this={modal} on:hide={onCancel}> <ModalContent title="Edit Icon" confirmText="Save" onConfirm={save}>
<ModalContent
title={"Edit Icon"}
confirmText={"Save"}
onConfirm={() => save()}
>
<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>
@ -85,8 +67,8 @@
{#each iconsList as item} {#each iconsList as item}
<div <div
class="icon-item" class="icon-item"
class:selected={item === selectedIcon} class:selected={item === name}
on:click={() => (selectedIcon = item)} on:click={() => (name = item)}
> >
<Icon name={item} /> <Icon name={item} />
</div> </div>
@ -98,14 +80,10 @@
<Label>Select a color</Label> <Label>Select a color</Label>
</div> </div>
<div class="color-selection-item"> <div class="color-selection-item">
<ColorPicker <ColorPicker bind:value={color} on:change={e => (color = e.detail)} />
bind:value={selectedColor}
on:change={e => changeColor(e.detail)}
/>
</div> </div>
</div> </div>
</ModalContent> </ModalContent>
</Modal>
<style> <style>
.scrollable-icons { .scrollable-icons {

View File

@ -1,22 +1,29 @@
<script> <script>
import { writable, get as svelteGet } from "svelte/store" import { writable, get as svelteGet } from "svelte/store"
import { notifications, Input, ModalContent, Body } from "@budibase/bbui" import {
notifications,
Input,
ModalContent,
Layout,
Label,
} from "@budibase/bbui"
import { apps } from "stores/portal" import { apps } from "stores/portal"
import { onMount } from "svelte" import { onMount } from "svelte"
import { createValidationStore } from "helpers/validation/yup" import { createValidationStore } from "helpers/validation/yup"
import * as appValidation from "helpers/validation/yup/app" import * as appValidation from "helpers/validation/yup/app"
import EditableIcon from "../common/EditableIcon.svelte"
export let app export let app
const values = writable({ name: "", url: null }) const values = writable({
const validation = createValidationStore() name: app.name,
$: validation.check($values) url: app.url,
iconName: app.icon?.name,
onMount(async () => { iconColor: app.icon?.color,
$values.name = app.name
$values.url = app.url
setupValidation()
}) })
const validation = createValidationStore()
$: validation.check($values)
const setupValidation = async () => { const setupValidation = async () => {
const applications = svelteGet(apps) const applications = svelteGet(apps)
@ -28,14 +35,14 @@
async function updateApp() { async function updateApp() {
try { try {
// Update App await apps.update(app.instance._id, {
const body = { name: $values.name?.trim(),
name: $values.name.trim(), url: $values.url?.trim(),
} icon: {
if ($values.url) { name: $values.iconName,
body.url = $values.url.trim() color: $values.iconColor,
} },
await apps.update(app.instance._id, body) })
} catch (error) { } catch (error) {
console.error(error) console.error(error)
notifications.error("Error updating app") notifications.error("Error updating app")
@ -68,15 +75,22 @@
let resolvedUrl = resolveAppUrl(null, appName) let resolvedUrl = resolveAppUrl(null, appName)
tidyUrl(resolvedUrl) tidyUrl(resolvedUrl)
} }
const updateIcon = e => {
const { name, color } = e.detail
$values.iconColor = color
$values.iconName = name
}
onMount(setupValidation)
</script> </script>
<ModalContent <ModalContent
title={"Edit app"} title="Edit name and URL"
confirmText={"Save"} confirmText="Save"
onConfirm={updateApp} onConfirm={updateApp}
disabled={!$validation.valid} disabled={!$validation.valid}
> >
<Body size="S">Update the name of your app.</Body>
<Input <Input
bind:value={$values.name} bind:value={$values.name}
error={$validation.touched.name && $validation.errors.name} error={$validation.touched.name && $validation.errors.name}
@ -84,6 +98,16 @@
on:change={nameToUrl($values.name)} on:change={nameToUrl($values.name)}
label="Name" label="Name"
/> />
<Layout noPadding gap="XS">
<Label>Icon</Label>
<EditableIcon
{app}
size="XL"
name={$values.iconName}
color={$values.iconColor}
on:change={updateIcon}
/>
</Layout>
<Input <Input
bind:value={$values.url} bind:value={$values.url}
error={$validation.touched.url && $validation.errors.url} error={$validation.touched.url && $validation.errors.url}

View File

@ -14,20 +14,12 @@
} from "@budibase/bbui" } from "@budibase/bbui"
import Spinner from "components/common/Spinner.svelte" import Spinner from "components/common/Spinner.svelte"
import CreateAppModal from "components/start/CreateAppModal.svelte" import CreateAppModal from "components/start/CreateAppModal.svelte"
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
import AppLimitModal from "components/portal/licensing/AppLimitModal.svelte" import AppLimitModal from "components/portal/licensing/AppLimitModal.svelte"
import { store, automationStore } from "builderStore" import { store, automationStore } from "builderStore"
import { API } from "api" import { API } from "api"
import { onMount } from "svelte" import { onMount } from "svelte"
import { import { apps, auth, admin, licensing } from "stores/portal"
apps,
auth,
admin,
templates,
licensing,
groups,
} from "stores/portal"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import AppRow from "components/start/AppRow.svelte" import AppRow from "components/start/AppRow.svelte"
import { AppStatus } from "constants" import { AppStatus } from "constants"
@ -35,9 +27,7 @@
let sortBy = "name" let sortBy = "name"
let template let template
let selectedApp
let creationModal let creationModal
let updatingModal
let appLimitModal let appLimitModal
let creatingApp = false let creatingApp = false
let searchTerm = "" let searchTerm = ""
@ -348,10 +338,6 @@
<CreateAppModal {template} /> <CreateAppModal {template} />
</Modal> </Modal>
<Modal bind:this={updatingModal} padding={false} width="600px">
<UpdateAppModal app={selectedApp} />
</Modal>
<AppLimitModal bind:this={appLimitModal} /> <AppLimitModal bind:this={appLimitModal} />
<style> <style>

View File

@ -1,116 +0,0 @@
<script>
import {
Layout,
Divider,
Heading,
Body,
Page,
Button,
Modal,
} from "@budibase/bbui"
import { store } from "builderStore"
import clientPackage from "@budibase/client/package.json"
import VersionModal from "components/deploy/VersionModal.svelte"
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
import { AppStatus } from "constants"
export let app
let versionModal
let updatingModal
$: updateAvailable = clientPackage.version !== $store.version
$: appUrl = `${window.origin}/app${app?.url}`
$: appDeployed = app?.status === AppStatus.DEPLOYED
</script>
<div class="settings-tab">
<Page wide={false}>
<Layout gap="XL" paddingY="XXL" paddingX="">
<span class="details-section">
<Layout gap="XS" noPadding>
<Heading size="S">Name and URL</Heading>
<Divider />
<Body>
<div class="app-details">
<div class="app-name">
<div class="name-title detail-title">Name</div>
<div class="name">{app?.name}</div>
</div>
<div class="app-url">
<div class="url-title detail-title">Url Path</div>
<div class="url">{appUrl}</div>
</div>
</div>
<div class="page-action">
<Button
cta
secondary
on:click={() => {
updatingModal.show()
}}
disabled={appDeployed}
>
Edit
</Button>
</div>
</Body>
</Layout>
</span>
<span class="version-section">
<Layout gap="XS" noPadding>
<Heading size="S">App version</Heading>
<Divider />
<Body>
{#if updateAvailable}
<Body>
The app is currently using version
<strong>{$store.version}</strong>
but version <strong>{clientPackage.version}</strong> is
available.
<br />
Updates can contain new features, performance improvements and bug
fixes.
</Body>
<div class="page-action">
<Button cta on:click={versionModal.show()}>Update app</Button>
</div>
{:else}
<div class="version-status">
The app is currently using version
<strong>{$store.version}</strong>. You're running the latest!
</div>
<div class="page-action">
<Button secondary on:click={versionModal.show()}>
Revert app
</Button>
</div>
{/if}
</Body>
</Layout>
</span>
</Layout>
<VersionModal bind:this={versionModal} hideIcon={true} />
<Modal bind:this={updatingModal} padding={false} width="600px">
<UpdateAppModal {app} />
</Modal>
</Page>
</div>
<style>
.page-action {
padding-top: var(--spacing-xl);
}
.app-details {
display: flex;
flex-direction: column;
gap: var(--spacing-m);
}
.detail-title {
color: var(--spectrum-global-color-gray-600);
font-size: var(
--spectrum-alias-font-size-default,
var(--spectrum-global-dimension-font-size-100)
);
}
</style>

View File

@ -124,6 +124,7 @@
<div slot="icon"> <div slot="icon">
<EditableIcon <EditableIcon
{app} {app}
autoSave
size="XL" size="XL"
name={app?.icon?.name || "Apps"} name={app?.icon?.name || "Apps"}
color={app?.icon?.color} color={app?.icon?.color}

View File

@ -0,0 +1,73 @@
<script>
import {
Layout,
Divider,
Heading,
Body,
Button,
Label,
Modal,
Icon,
} from "@budibase/bbui"
import { AppStatus } from "constants"
import { overview } from "stores/portal"
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
let updatingModal
$: app = $overview.selectedApp
$: appUrl = `${window.origin}/app${app?.url}`
$: appDeployed = app?.status === AppStatus.DEPLOYED
</script>
<Layout noPadding>
<Layout gap="XS" noPadding>
<Heading>Name and URL</Heading>
<Body>Edit your app's name and URL</Body>
</Layout>
<Divider />
<Layout noPadding gap="XXS">
<Label size="L">Name</Label>
<Body>{app?.name}</Body>
</Layout>
<Layout noPadding gap="XS">
<Label size="L">Icon</Label>
<div class="icon">
<Icon
size="L"
name={app?.icon?.name || "Apps"}
color={app?.icon?.color}
/>
</div>
</Layout>
<Layout noPadding gap="XXS">
<Label size="L">URL</Label>
<Body>{appUrl}</Body>
</Layout>
<div>
<Button
cta
on:click={() => {
updatingModal.show()
}}
disabled={appDeployed}
>
Edit
</Button>
</div>
</Layout>
<Modal bind:this={updatingModal} padding={false} width="600px">
<UpdateAppModal app={$overview.selectedApp} />
</Modal>
<style>
.icon {
display: flex;
justify-content: flex-start;
}
</style>

View File

@ -0,0 +1,40 @@
<script>
import { Layout, Heading, Body, Divider, Button } from "@budibase/bbui"
import { store } from "builderStore"
import clientPackage from "@budibase/client/package.json"
import VersionModal from "components/deploy/VersionModal.svelte"
let versionModal
$: updateAvailable = clientPackage.version !== $store.version
</script>
<Layout noPadding>
<Layout gap="XS" noPadding>
<Heading>Version</Heading>
<Body>See the current version of your app and check for updates</Body>
</Layout>
<Divider />
{#if updateAvailable}
<Body>
The app is currently using version <strong>{$store.version}</strong>
but version <strong>{clientPackage.version}</strong> is available.
<br />
Updates can contain new features, performance improvements and bug fixes.
</Body>
<div>
<Button cta on:click={versionModal.show}>Update app</Button>
</div>
{:else}
<Body>
The app is currently using version <strong>{$store.version}</strong>.
<br />
You're running the latest!
</Body>
<div>
<Button secondary on:click={versionModal.show}>Revert app</Button>
</div>
{/if}
</Layout>
<VersionModal bind:this={versionModal} hideIcon={true} />

View File

@ -10,7 +10,7 @@
--spectrum-global-color-gray-500: hsl(var(--hue), var(--sat), 40%); --spectrum-global-color-gray-500: hsl(var(--hue), var(--sat), 40%);
--spectrum-global-color-gray-600: hsl(var(--hue), var(--sat), 60%); --spectrum-global-color-gray-600: hsl(var(--hue), var(--sat), 60%);
--spectrum-global-color-gray-700: hsl(var(--hue), var(--sat), 70%); --spectrum-global-color-gray-700: hsl(var(--hue), var(--sat), 70%);
--spectrum-global-color-gray-800: hsl(var(--hue), var(--sat), 80%); --spectrum-global-color-gray-800: hsl(var(--hue), var(--sat), 85%);
--spectrum-global-color-gray-900: hsl(var(--hue), var(--sat), 95%); --spectrum-global-color-gray-900: hsl(var(--hue), var(--sat), 95%);
--modal-background: var(--spectrum-global-color-gray-50); --modal-background: var(--spectrum-global-color-gray-50);