Update app overview version and name/url screens

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,20 +14,12 @@
} from "@budibase/bbui"
import Spinner from "components/common/Spinner.svelte"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
import AppLimitModal from "components/portal/licensing/AppLimitModal.svelte"
import { store, automationStore } from "builderStore"
import { API } from "api"
import { onMount } from "svelte"
import {
apps,
auth,
admin,
templates,
licensing,
groups,
} from "stores/portal"
import { apps, auth, admin, licensing } from "stores/portal"
import { goto } from "@roxi/routify"
import AppRow from "components/start/AppRow.svelte"
import { AppStatus } from "constants"
@ -35,9 +27,7 @@
let sortBy = "name"
let template
let selectedApp
let creationModal
let updatingModal
let appLimitModal
let creatingApp = false
let searchTerm = ""
@ -348,10 +338,6 @@
<CreateAppModal {template} />
</Modal>
<Modal bind:this={updatingModal} padding={false} width="600px">
<UpdateAppModal app={selectedApp} />
</Modal>
<AppLimitModal bind:this={appLimitModal} />
<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">
<EditableIcon
{app}
autoSave
size="XL"
name={app?.icon?.name || "Apps"}
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-600: hsl(var(--hue), var(--sat), 60%);
--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%);
--modal-background: var(--spectrum-global-color-gray-50);