<script> import { Button, ButtonGroup, ModalContent, Modal, notifications, ProgressCircle, } from "@budibase/bbui" import { auth, apps } from "stores/portal" import { processStringSync } from "@budibase/string-templates" import { API } from "api" export let app export let buttonSize = "M" let APP_DEV_LOCK_SECONDS = 600 //common area for this? let appLockModal let processing = false $: lockedBy = app?.lockedBy $: lockedByYou = $auth.user.email === lockedBy?.email $: lockIdentifer = `${ lockedBy && Object.prototype.hasOwnProperty.call(lockedBy, "firstName") ? lockedBy?.firstName : lockedBy?.email }` $: lockedByHeading = lockedBy && lockedByYou ? "Locked by you" : `Locked by ${lockIdentifer}` $: lockExpiry = getExpiryDuration(app) const getExpiryDuration = app => { if (!app?.lockedBy?.lockedAt) { return -1 } let expiry = new Date(app.lockedBy.lockedAt).getTime() + APP_DEV_LOCK_SECONDS * 1000 return expiry - new Date().getTime() } const releaseLock = async () => { processing = true if (app) { try { await API.releaseAppLock(app.devId) await apps.load() notifications.success("Lock released successfully") } catch (err) { notifications.error("Error releasing lock") } } else { notifications.error("No application is selected") } processing = false } </script> <div class="lock-status"> {#if lockedBy} <Button quiet secondary icon="LockClosed" size={buttonSize} on:click={() => { appLockModal.show() }} > <span class="lock-status-text"> {lockedByHeading} </span> </Button> {/if} </div> <Modal bind:this={appLockModal}> <ModalContent title={lockedByHeading} dataCy={"app-lock-modal"} showConfirmButton={false} showCancelButton={false} > <p> Apps are locked to prevent work from being lost from overlapping changes between your team. </p> {#if lockedByYou && lockExpiry > 0} {processStringSync( "This lock will expire in {{ duration time 'millisecond' }} from now", { time: lockExpiry, } )} {/if} <div class="lock-modal-actions"> <ButtonGroup> <Button secondary quiet={lockedBy && lockedByYou} disabled={processing} on:click={() => { appLockModal.hide() }} > <span class="cancel" >{lockedBy && !lockedByYou ? "Done" : "Cancel"}</span > </Button> {#if lockedByYou} <Button secondary disabled={processing} on:click={() => { releaseLock() appLockModal.hide() }} > {#if processing} <ProgressCircle overBackground={true} size="S" /> {:else} <span class="unlock">Release Lock</span> {/if} </Button> {/if} </ButtonGroup> </div> </ModalContent> </Modal> <style> .lock-modal-actions { display: flex; justify-content: flex-end; margin-top: var(--spacing-l); gap: var(--spacing-xl); } .lock-status { display: flex; gap: var(--spacing-s); } /* .lock-status :global(.spectrum-Button-label) { font-weight: 200; font-family: var(--font-sans); } */ </style>