Update apps list page and app rows to match new styles and behaviours
This commit is contained in:
parent
eb2fd47e44
commit
9d38fa938f
|
@ -87,7 +87,7 @@
|
|||
{#if lockedByYou && getExpiryDuration(app) > 0}
|
||||
<span class="lock-expiry-body">
|
||||
{processStringSync(
|
||||
"This lock will expire in {{ duration time 'millisecond' }} from now",
|
||||
"This lock will expire in {{ duration time 'millisecond' }} from now.",
|
||||
{
|
||||
time: getExpiryDuration(app),
|
||||
}
|
||||
|
@ -141,4 +141,8 @@
|
|||
gap: var(--spacing-s);
|
||||
max-width: 175px;
|
||||
}
|
||||
.lock-status-text {
|
||||
font-weight: 400;
|
||||
color: var(--spectrum-global-color-gray-800);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
<script>
|
||||
import { Heading, Button, Icon, ActionMenu, MenuItem } from "@budibase/bbui"
|
||||
import { Heading, Button, Icon } from "@budibase/bbui"
|
||||
import AppLockModal from "../common/AppLockModal.svelte"
|
||||
import { processStringSync } from "@budibase/string-templates"
|
||||
|
||||
export let app
|
||||
export let exportApp
|
||||
export let editApp
|
||||
export let updateApp
|
||||
export let deleteApp
|
||||
export let unpublishApp
|
||||
export let appOverview
|
||||
export let releaseLock
|
||||
export let editIcon
|
||||
export let copyAppId
|
||||
</script>
|
||||
|
||||
<div class="title" data-cy={`${app.devId}`}>
|
||||
|
@ -20,7 +13,7 @@
|
|||
<div class="app-icon" style="color: {app.icon?.color || ''}">
|
||||
<Icon size="XL" name={app.icon?.name || "Apps"} />
|
||||
</div>
|
||||
<div class="name" data-cy="app-name-link" on:click={() => appOverview(app)}>
|
||||
<div class="name" data-cy="app-name-link" on:click={() => editApp(app)}>
|
||||
<Heading size="XS">
|
||||
{app.name}
|
||||
</Heading>
|
||||
|
@ -37,7 +30,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
<div class="desktop">
|
||||
<AppLockModal {app} buttonSize="S" />
|
||||
<AppLockModal {app} buttonSize="M" />
|
||||
</div>
|
||||
<div class="desktop">
|
||||
<div class="app-status">
|
||||
|
@ -52,47 +45,27 @@
|
|||
</div>
|
||||
<div data-cy={`row_actions_${app.appId}`}>
|
||||
<div class="app-row-actions">
|
||||
<Button size="S" secondary newStyles on:click={() => appOverview(app)}>
|
||||
Manage
|
||||
</Button>
|
||||
<Button
|
||||
size="S"
|
||||
secondary
|
||||
quiet
|
||||
primary
|
||||
newStyles
|
||||
disabled={app.lockedOther}
|
||||
on:click={() => editApp(app)}
|
||||
>Edit
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button size="S" cta on:click={() => appOverview(app)}>View</Button>
|
||||
</div>
|
||||
<ActionMenu align="right" dataCy="app-row-actions-menu-popover">
|
||||
<span slot="control" class="app-row-actions-icon">
|
||||
<Icon hoverable name="More" />
|
||||
</span>
|
||||
{#if app.lockedYou}
|
||||
<MenuItem on:click={() => releaseLock(app)} icon="LockOpen">
|
||||
Release lock
|
||||
</MenuItem>
|
||||
{/if}
|
||||
<MenuItem on:click={() => exportApp(app)} icon="Download">Export</MenuItem>
|
||||
{#if app.deployed}
|
||||
<MenuItem on:click={() => unpublishApp(app)} icon="GlobeRemove">
|
||||
Unpublish
|
||||
</MenuItem>
|
||||
<MenuItem on:click={() => copyAppId(app)} icon="Copy">
|
||||
Copy App ID
|
||||
</MenuItem>
|
||||
{/if}
|
||||
{#if !app.deployed}
|
||||
<MenuItem on:click={() => updateApp(app)} icon="Edit">Edit</MenuItem>
|
||||
<MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem>
|
||||
{/if}
|
||||
<MenuItem on:click={() => editIcon(app)} icon="Brush">Edit icon</MenuItem>
|
||||
</ActionMenu>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.app-row-actions {
|
||||
grid-gap: var(--spacing-s);
|
||||
display: grid;
|
||||
grid-template-columns: 75px 75px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.app-status {
|
||||
display: grid;
|
||||
|
|
|
@ -3,20 +3,17 @@
|
|||
Heading,
|
||||
Layout,
|
||||
Button,
|
||||
Input,
|
||||
Select,
|
||||
Modal,
|
||||
Page,
|
||||
notifications,
|
||||
Body,
|
||||
Search,
|
||||
Helpers,
|
||||
} from "@budibase/bbui"
|
||||
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
|
||||
import Spinner from "components/common/Spinner.svelte"
|
||||
import CreateAppModal from "components/start/CreateAppModal.svelte"
|
||||
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
|
||||
import ChooseIconModal from "components/start/ChooseIconModal.svelte"
|
||||
import ExportAppModal from "components/start/ExportAppModal.svelte"
|
||||
|
||||
import { store, automationStore } from "builderStore"
|
||||
|
@ -25,10 +22,9 @@
|
|||
import { apps, auth, admin, templates } from "stores/portal"
|
||||
import download from "downloadjs"
|
||||
import { goto } from "@roxi/routify"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
import AppRow from "components/start/AppRow.svelte"
|
||||
import { AppStatus } from "constants"
|
||||
import analytics, { Events, EventSource } from "analytics"
|
||||
import analytics, { Events } from "analytics"
|
||||
import Logo from "assets/bb-space-man.svg"
|
||||
|
||||
let sortBy = "name"
|
||||
|
@ -36,15 +32,11 @@
|
|||
let selectedApp
|
||||
let creationModal
|
||||
let updatingModal
|
||||
let deletionModal
|
||||
let unpublishModal
|
||||
let exportModal
|
||||
let iconModal
|
||||
let creatingApp = false
|
||||
let loaded = $apps?.length || $templates?.length
|
||||
let searchTerm = ""
|
||||
let cloud = $admin.cloud
|
||||
let appName = ""
|
||||
let creatingFromTemplate = false
|
||||
|
||||
const resolveWelcomeMessage = (auth, apps) => {
|
||||
|
@ -170,18 +162,6 @@
|
|||
creatingApp = false
|
||||
}
|
||||
|
||||
const viewApp = app => {
|
||||
analytics.captureEvent(Events.APP.VIEW_PUBLISHED, {
|
||||
appId: app.appId,
|
||||
eventSource: EventSource.PORTAL,
|
||||
})
|
||||
if (app.url) {
|
||||
window.open(`/app${app.url}`)
|
||||
} else {
|
||||
window.open(`/${app.prodId}`)
|
||||
}
|
||||
}
|
||||
|
||||
const appOverview = app => {
|
||||
$goto(`../overview/${app.devId}`)
|
||||
}
|
||||
|
@ -196,79 +176,6 @@
|
|||
$goto(`../../app/${app.devId}`)
|
||||
}
|
||||
|
||||
const editIcon = app => {
|
||||
selectedApp = app
|
||||
iconModal.show()
|
||||
}
|
||||
|
||||
const exportApp = app => {
|
||||
exportModal.show()
|
||||
selectedApp = app
|
||||
}
|
||||
|
||||
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)
|
||||
await apps.load()
|
||||
// Get checklist, just in case that was the last app
|
||||
await admin.init()
|
||||
notifications.success("App deleted successfully")
|
||||
} catch (err) {
|
||||
notifications.error("Error deleting app")
|
||||
}
|
||||
selectedApp = null
|
||||
appName = null
|
||||
}
|
||||
|
||||
const updateApp = async app => {
|
||||
selectedApp = app
|
||||
updatingModal.show()
|
||||
}
|
||||
|
||||
const releaseLock = async app => {
|
||||
try {
|
||||
await API.releaseAppLock(app.devId)
|
||||
await apps.load()
|
||||
notifications.success("Lock released successfully")
|
||||
} catch (err) {
|
||||
notifications.error("Error releasing lock")
|
||||
}
|
||||
}
|
||||
|
||||
const copyAppId = async app => {
|
||||
await Helpers.copyToClipboard(app.prodId)
|
||||
notifications.success("App ID copied to clipboard.")
|
||||
}
|
||||
|
||||
function createAppFromTemplateUrl(templateKey) {
|
||||
// validate the template key just to make sure
|
||||
const templateParts = templateKey.split("/")
|
||||
|
@ -416,19 +323,7 @@
|
|||
|
||||
<div class="appTable" class:unlocked>
|
||||
{#each filteredApps as app (app.appId)}
|
||||
<AppRow
|
||||
{copyAppId}
|
||||
{releaseLock}
|
||||
{editIcon}
|
||||
{app}
|
||||
{unpublishApp}
|
||||
{viewApp}
|
||||
{editApp}
|
||||
{exportApp}
|
||||
{deleteApp}
|
||||
{updateApp}
|
||||
{appOverview}
|
||||
/>
|
||||
<AppRow {app} {editApp} {appOverview} />
|
||||
{/each}
|
||||
</div>
|
||||
</Layout>
|
||||
|
@ -462,35 +357,6 @@
|
|||
<ExportAppModal app={selectedApp} />
|
||||
</Modal>
|
||||
|
||||
<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>
|
||||
|
||||
<ChooseIconModal app={selectedApp} bind:this={iconModal} />
|
||||
|
||||
<style>
|
||||
.appTable {
|
||||
border-top: var(--border-light);
|
||||
|
@ -547,12 +413,9 @@
|
|||
height: 70px;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-gap: var(--spacing-xl);
|
||||
grid-template-columns: auto 1fr;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0 var(--spacing-s);
|
||||
}
|
||||
.appTable :global(> div) {
|
||||
border-bottom: var(--border-light);
|
||||
|
|
Loading…
Reference in New Issue