Merge commit
This commit is contained in:
parent
0dda7afee7
commit
e8f28113da
|
@ -7,9 +7,15 @@
|
|||
Body,
|
||||
Button,
|
||||
ActionButton,
|
||||
Icon,
|
||||
Link,
|
||||
Modal,
|
||||
StatusLight,
|
||||
} from "@budibase/bbui"
|
||||
import RevertModal from "components/deploy/RevertModal.svelte"
|
||||
import VersionModal from "components/deploy/VersionModal.svelte"
|
||||
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
|
||||
|
||||
import { processStringSync } from "@budibase/string-templates"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
import analytics, { Events, EventSource } from "analytics"
|
||||
|
@ -21,16 +27,22 @@
|
|||
import { store } from "builderStore"
|
||||
import TourWrap from "components/portal/onboarding/TourWrap.svelte"
|
||||
import { TOUR_STEP_KEYS } from "components/portal/onboarding/tours.js"
|
||||
import { url, goto } from "@roxi/routify"
|
||||
|
||||
export let application
|
||||
|
||||
let publishPopover
|
||||
let publishPopoverAnchor
|
||||
let unpublishModal
|
||||
let updateAppModal
|
||||
let revertModal
|
||||
let versionModal
|
||||
|
||||
$: filteredApps = $apps.filter(
|
||||
app => app.devId === application && app.status === "published"
|
||||
)
|
||||
let appActionPopover
|
||||
let appActionPopoverOpen = false
|
||||
let appActionPopoverAnchor
|
||||
|
||||
let publishing
|
||||
|
||||
$: filteredApps = $apps.filter(app => app.devId === application)
|
||||
$: selectedApp = filteredApps?.length ? filteredApps[0] : null
|
||||
|
||||
$: deployments = []
|
||||
|
@ -38,7 +50,30 @@
|
|||
.filter(deployment => deployment.status === "SUCCESS")
|
||||
.sort((a, b) => a.updatedAt > b.updatedAt)
|
||||
|
||||
$: isPublished = selectedApp && latestDeployments?.length > 0
|
||||
$: isPublished =
|
||||
selectedApp?.status === "published" && latestDeployments?.length > 0
|
||||
|
||||
$: updateAvailable =
|
||||
$store.upgradableVersion &&
|
||||
$store.version &&
|
||||
$store.upgradableVersion !== $store.version
|
||||
|
||||
const initialiseApp = async () => {
|
||||
console.log("AppActions :: Reinitialise")
|
||||
const applicationPkg = await API.fetchAppPackage($store.devId)
|
||||
await store.actions.initialise(applicationPkg)
|
||||
}
|
||||
|
||||
const updateDeploymentString = () => {
|
||||
return deployments?.length
|
||||
? processStringSync("Published {{ duration time 'millisecond' }} ago", {
|
||||
time:
|
||||
new Date().getTime() - new Date(deployments[0].updatedAt).getTime(),
|
||||
})
|
||||
: ""
|
||||
}
|
||||
|
||||
$: deploymentString = updateDeploymentString(deployments)
|
||||
|
||||
const reviewPendingDeployments = (deployments, newDeployments) => {
|
||||
if (deployments.length > 0) {
|
||||
|
@ -77,11 +112,35 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function publishApp() {
|
||||
try {
|
||||
publishing = true
|
||||
|
||||
let published = await API.publishAppChanges($store.appId)
|
||||
|
||||
notifications.send("App published", {
|
||||
type: "success",
|
||||
icon: "GlobeCheck",
|
||||
})
|
||||
|
||||
await completePublish()
|
||||
} catch (error) {
|
||||
analytics.captureException(error)
|
||||
notifications.error("Error publishing app")
|
||||
}
|
||||
publishing = false
|
||||
}
|
||||
|
||||
const unpublishApp = () => {
|
||||
publishPopover.hide()
|
||||
appActionPopover.hide()
|
||||
unpublishModal.show()
|
||||
}
|
||||
|
||||
const revertApp = () => {
|
||||
appActionPopover.hide()
|
||||
revertModal.show()
|
||||
}
|
||||
|
||||
const confirmUnpublishApp = async () => {
|
||||
if (!application || !isPublished) {
|
||||
//confirm the app has loaded.
|
||||
|
@ -90,7 +149,10 @@
|
|||
try {
|
||||
await API.unpublishApp(selectedApp.prodId)
|
||||
await apps.load()
|
||||
notifications.success("App unpublished successfully")
|
||||
notifications.send("App unpublished", {
|
||||
type: "success",
|
||||
icon: "GlobeStrike",
|
||||
})
|
||||
} catch (err) {
|
||||
notifications.error("Error unpublishing app")
|
||||
}
|
||||
|
@ -116,81 +178,25 @@
|
|||
{#if $store.hasLock}
|
||||
<div class="action-top-nav">
|
||||
<div class="action-buttons">
|
||||
<div class="version">
|
||||
<VersionModal />
|
||||
</div>
|
||||
<RevertModal />
|
||||
|
||||
{#if isPublished}
|
||||
<div class="publish-popover">
|
||||
<div bind:this={publishPopoverAnchor}>
|
||||
<ActionButton
|
||||
quiet
|
||||
icon="Globe"
|
||||
size="M"
|
||||
tooltip="Your published app"
|
||||
on:click={publishPopover.show()}
|
||||
/>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
{#if updateAvailable}
|
||||
<div class="app-action-button version" on:click={versionModal.show}>
|
||||
<div class="app-action">
|
||||
<StatusLight notice />
|
||||
Update
|
||||
</div>
|
||||
<Popover
|
||||
bind:this={publishPopover}
|
||||
align="right"
|
||||
disabled={!isPublished}
|
||||
anchor={publishPopoverAnchor}
|
||||
offset={10}
|
||||
>
|
||||
<div class="popover-content">
|
||||
<Layout noPadding gap="M">
|
||||
<Heading size="XS">Your published app</Heading>
|
||||
<Body size="S">
|
||||
<span class="publish-popover-message">
|
||||
{processStringSync(
|
||||
"Last published {{ duration time 'millisecond' }} ago",
|
||||
{
|
||||
time:
|
||||
new Date().getTime() -
|
||||
new Date(latestDeployments[0].updatedAt).getTime(),
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
</Body>
|
||||
<div class="buttons">
|
||||
<Button
|
||||
warning={true}
|
||||
icon="GlobeStrike"
|
||||
disabled={!isPublished}
|
||||
on:click={unpublishApp}
|
||||
>
|
||||
Unpublish
|
||||
</Button>
|
||||
<Button cta on:click={viewApp}>View app</Button>
|
||||
</div>
|
||||
</Layout>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !isPublished}
|
||||
<ActionButton
|
||||
quiet
|
||||
icon="GlobeStrike"
|
||||
size="M"
|
||||
tooltip="Your app has not been published yet"
|
||||
disabled
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<TourWrap
|
||||
tourStepKey={$store.onboarding
|
||||
? TOUR_STEP_KEYS.BUILDER_USER_MANAGEMENT
|
||||
: TOUR_STEP_KEYS.FEATURE_USER_MANAGEMENT}
|
||||
>
|
||||
<span id="builder-app-users-button">
|
||||
<ActionButton
|
||||
quiet
|
||||
icon="UserGroup"
|
||||
size="M"
|
||||
<div class="app-action-button users">
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="app-action"
|
||||
id="builder-app-users-button"
|
||||
on:click={() => {
|
||||
store.update(state => {
|
||||
state.builderSidePanel = true
|
||||
|
@ -198,13 +204,124 @@
|
|||
})
|
||||
}}
|
||||
>
|
||||
<Icon name={"UserGroup"} />
|
||||
Users
|
||||
</ActionButton>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</TourWrap>
|
||||
|
||||
<div class="app-action-button preview">
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="app-action" on:click={previewApp}>
|
||||
<Icon name={"PlayCircle"} />
|
||||
|
||||
Preview
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-action-button publish app-action-popover">
|
||||
<div bind:this={appActionPopoverAnchor}>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="app-action"
|
||||
on:click={() => {
|
||||
appActionPopover.show()
|
||||
}}
|
||||
>
|
||||
<Icon name={isPublished ? "GlobeCheck" : "GlobeStrike"} />
|
||||
<TourWrap tourStepKey={TOUR_STEP_KEYS.BUILDER_APP_PUBLISH}>
|
||||
<span class="publish-open" id="builder-app-publish-button">
|
||||
Publish
|
||||
<Icon
|
||||
name={appActionPopoverOpen ? "ChevronUp" : "ChevronDown"}
|
||||
size="M"
|
||||
/>
|
||||
</span>
|
||||
</TourWrap>
|
||||
</div>
|
||||
</div>
|
||||
<Popover
|
||||
bind:this={appActionPopover}
|
||||
align="right"
|
||||
disabled={!isPublished}
|
||||
anchor={appActionPopoverAnchor}
|
||||
offset={10}
|
||||
on:close={() => {
|
||||
appActionPopoverOpen = false
|
||||
}}
|
||||
on:open={() => {
|
||||
appActionPopoverOpen = true
|
||||
}}
|
||||
>
|
||||
<div class="app-action-popover-content">
|
||||
<Layout noPadding gap="M">
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<Body size="M">
|
||||
<span
|
||||
class="app-link"
|
||||
on:click={() => {
|
||||
if (isPublished) {
|
||||
viewApp()
|
||||
} else {
|
||||
appActionPopover.hide()
|
||||
updateAppModal.show()
|
||||
}
|
||||
}}
|
||||
>
|
||||
{selectedApp ? `${selectedApp?.url}` : ""}
|
||||
{#if isPublished}
|
||||
<Icon size="S" name="LinkOut" />
|
||||
{:else}
|
||||
<Icon size="S" name="Edit" />
|
||||
{/if}
|
||||
</span>
|
||||
</Body>
|
||||
|
||||
<Body size="S">
|
||||
<span class="publish-popover-status">
|
||||
{#if isPublished}
|
||||
<span class="status-text">{deploymentString}</span>
|
||||
<span class="unpublish-link">
|
||||
<Link quiet on:click={unpublishApp}>Unpublish</Link>
|
||||
</span>
|
||||
<span class="revert-link">
|
||||
<Link quiet secondary on:click={revertApp}>Revert</Link>
|
||||
</span>
|
||||
{:else}
|
||||
<span class="status-text unpublished">Not published</span>
|
||||
{/if}
|
||||
</span>
|
||||
</Body>
|
||||
<div class="action-buttons">
|
||||
{#if $store.hasLock}
|
||||
<Button
|
||||
secondary
|
||||
icon="Code"
|
||||
on:click={() => {
|
||||
$goto("./settings/embed")
|
||||
appActionPopover.hide()
|
||||
}}
|
||||
>
|
||||
Embed
|
||||
</Button>
|
||||
<Button
|
||||
cta
|
||||
on:click={publishApp}
|
||||
id={"builder-app-publish-button"}
|
||||
disabled={publishing}
|
||||
>
|
||||
Publish
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</Layout>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modals -->
|
||||
<ConfirmDialog
|
||||
bind:this={unpublishModal}
|
||||
title="Confirm unpublish"
|
||||
|
@ -213,45 +330,99 @@
|
|||
>
|
||||
Are you sure you want to unpublish the app <b>{selectedApp?.name}</b>?
|
||||
</ConfirmDialog>
|
||||
|
||||
<Modal bind:this={updateAppModal} padding={false} width="600px">
|
||||
<UpdateAppModal
|
||||
app={selectedApp}
|
||||
onUpdateComplete={async () => {
|
||||
await initialiseApp()
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<RevertModal bind:this={revertModal} />
|
||||
<VersionModal hideIcon bind:this={versionModal} />
|
||||
{/if}
|
||||
|
||||
<div class="buttons">
|
||||
<Button on:click={previewApp} secondary>Preview</Button>
|
||||
{#if $store.hasLock}
|
||||
<DeployModal onOk={completePublish} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* .banner-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
} */
|
||||
.popover-content {
|
||||
.app-action-popover-content {
|
||||
padding: var(--spacing-xl);
|
||||
}
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: var(--spacing-l);
|
||||
|
||||
.app-action-popover-content :global(.icon svg.spectrum-Icon) {
|
||||
height: 0.8em;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
/* gap: var(--spacing-s); */
|
||||
}
|
||||
.version {
|
||||
margin-right: var(--spacing-s);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.action-top-nav {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
.app-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
cursor: pointer;
|
||||
}
|
||||
.app-action-popover-content .status-text {
|
||||
color: #1ca872;
|
||||
border-right: 1px solid var(--spectrum-global-color-gray-500);
|
||||
padding-right: var(--spacing-m);
|
||||
}
|
||||
.app-action-popover-content .status-text.unpublished {
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
border-right: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
.app-action-popover-content .action-buttons {
|
||||
gap: var(--spacing-m);
|
||||
}
|
||||
.app-action-popover-content
|
||||
.publish-popover-status
|
||||
.unpublish-link
|
||||
:global(.spectrum-Link) {
|
||||
color: #ee4331;
|
||||
}
|
||||
.publish-popover-status {
|
||||
display: flex;
|
||||
gap: var(--spacing-m);
|
||||
}
|
||||
.app-action-popover .publish-open {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
}
|
||||
|
||||
.app-action-button {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0px var(--spacing-l);
|
||||
/* border-left: var(--border-light); */
|
||||
}
|
||||
|
||||
.app-action-button:hover {
|
||||
background-color: var(--spectrum-global-color-gray-200);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.app-action-button.publish {
|
||||
border-left: var(--border-light);
|
||||
}
|
||||
|
||||
.app-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue