Updates to upgrade page to change config based on offlineMode value
This commit is contained in:
parent
efe53bb217
commit
1ba3665ed4
|
@ -10,6 +10,8 @@
|
||||||
Label,
|
Label,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
notifications,
|
notifications,
|
||||||
|
CopyInput,
|
||||||
|
File
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { auth, admin } from "stores/portal"
|
import { auth, admin } from "stores/portal"
|
||||||
import { redirect } from "@roxi/routify"
|
import { redirect } from "@roxi/routify"
|
||||||
|
@ -21,44 +23,122 @@
|
||||||
$: license = $auth.user.license
|
$: license = $auth.user.license
|
||||||
$: upgradeUrl = `${$admin.accountPortalUrl}/portal/upgrade`
|
$: upgradeUrl = `${$admin.accountPortalUrl}/portal/upgrade`
|
||||||
|
|
||||||
|
// LICENSE KEY
|
||||||
$: activateDisabled = !licenseKey || licenseKeyDisabled
|
$: activateDisabled = !licenseKey || licenseKeyDisabled
|
||||||
|
|
||||||
let licenseInfo
|
|
||||||
|
|
||||||
let licenseKeyDisabled = false
|
let licenseKeyDisabled = false
|
||||||
let licenseKeyType = "text"
|
let licenseKeyType = "text"
|
||||||
let licenseKey = ""
|
let licenseKey = ""
|
||||||
let deleteLicenseKeyModal
|
let deleteLicenseKeyModal
|
||||||
|
|
||||||
|
// OFFLINE LICENSE
|
||||||
|
let installationIdentifier = undefined
|
||||||
|
let offlineLicense = undefined
|
||||||
|
const offlineLicenseExtensions = [
|
||||||
|
".txt",
|
||||||
|
]
|
||||||
|
|
||||||
// Make sure page can't be visited directly in cloud
|
// Make sure page can't be visited directly in cloud
|
||||||
$: {
|
$: {
|
||||||
if ($admin.cloud) {
|
if ($admin.cloud) {
|
||||||
$redirect("../../portal")
|
$redirect("../../portal")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log({ offlineLicense })
|
||||||
}
|
}
|
||||||
|
|
||||||
const activate = async () => {
|
// LICENSE KEY
|
||||||
|
|
||||||
|
const getLicenseKey = async () => {
|
||||||
try {
|
try {
|
||||||
await API.activateLicenseKey({ licenseKey })
|
licenseKey = await API.getLicenseKey()
|
||||||
await auth.getSelf()
|
if (licenseKey) {
|
||||||
await setLicenseInfo()
|
licenseKey = "**********************************************"
|
||||||
notifications.success("Successfully activated")
|
licenseKeyType = "password"
|
||||||
|
licenseKeyDisabled = true
|
||||||
|
activateDisabled = true
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
notifications.error(e.message)
|
console.error(e)
|
||||||
|
notifications.error("Error retrieving license key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const destroy = async () => {
|
const activateLicenseKey = async () => {
|
||||||
|
try {
|
||||||
|
await API.activateLicenseKey({ licenseKey })
|
||||||
|
await auth.getSelf()
|
||||||
|
await getLicenseKey()
|
||||||
|
notifications.success("Successfully activated")
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
notifications.error("Error activating license key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteLicenseKey = async () => {
|
||||||
try {
|
try {
|
||||||
await API.deleteLicenseKey({ licenseKey })
|
await API.deleteLicenseKey({ licenseKey })
|
||||||
await auth.getSelf()
|
await auth.getSelf()
|
||||||
await setLicenseInfo()
|
await getLicenseKey()
|
||||||
// reset the form
|
// reset the form
|
||||||
licenseKey = ""
|
licenseKey = ""
|
||||||
licenseKeyDisabled = false
|
licenseKeyDisabled = false
|
||||||
notifications.success("Successfully deleted")
|
notifications.success("Offline license removed")
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
notifications.error(e.message)
|
console.error(e)
|
||||||
|
notifications.error("Error deleting license key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFLINE LICENSE
|
||||||
|
|
||||||
|
const getOfflineLicense = async () => {
|
||||||
|
try {
|
||||||
|
const license = await API.getOfflineLicense()
|
||||||
|
if (license) {
|
||||||
|
offlineLicense = {
|
||||||
|
name: "license"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offlineLicense = undefined
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
notifications.error("Error loading offline license")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function activateOfflineLicense(offlineLicense) {
|
||||||
|
try {
|
||||||
|
await API.activateOfflineLicense({ offlineLicense })
|
||||||
|
await auth.getSelf()
|
||||||
|
await getOfflineLicense()
|
||||||
|
notifications.success("Successfully activated")
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
notifications.error("Error activating offline license")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteOfflineLicense() {
|
||||||
|
try {
|
||||||
|
await API.deleteOfflineLicense()
|
||||||
|
await auth.getSelf()
|
||||||
|
await getOfflineLicense()
|
||||||
|
notifications.success("Successfully removed ofline license")
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
notifications.error("Error upload offline license")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onOfflineLicenseChange(event) {
|
||||||
|
if (event.detail) {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsText(event.detail)
|
||||||
|
reader.onload = () => activateOfflineLicense(reader.result)
|
||||||
|
} else {
|
||||||
|
await deleteOfflineLicense()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,29 +153,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// deactivate the license key field if there is a license key set
|
|
||||||
$: {
|
|
||||||
if (licenseInfo?.licenseKey) {
|
|
||||||
licenseKey = "**********************************************"
|
|
||||||
licenseKeyType = "password"
|
|
||||||
licenseKeyDisabled = true
|
|
||||||
activateDisabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const setLicenseInfo = async () => {
|
|
||||||
licenseInfo = await API.getLicenseInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await setLicenseInfo()
|
if ($admin.offlineMode) {
|
||||||
|
await getOfflineLicense()
|
||||||
|
} else {
|
||||||
|
await getLicenseKey()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $auth.isAdmin}
|
{#if $auth.isAdmin}
|
||||||
<DeleteLicenseKeyModal
|
<DeleteLicenseKeyModal
|
||||||
bind:this={deleteLicenseKeyModal}
|
bind:this={deleteLicenseKeyModal}
|
||||||
onConfirm={destroy}
|
onConfirm={deleteLicenseKey}
|
||||||
/>
|
/>
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
|
@ -112,38 +182,73 @@
|
||||||
</Body>
|
</Body>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Layout gap="XS" noPadding>
|
{#if $admin.offlineMode}
|
||||||
<Heading size="S">Activate</Heading>
|
<Layout gap="XS" noPadding>
|
||||||
<Body size="S">Enter your license key below to activate your plan</Body>
|
<Heading size="XS">Installation identifier</Heading>
|
||||||
</Layout>
|
<Body size="S">Share this with support@budibase.com to obtain your offline license</Body>
|
||||||
<Layout noPadding>
|
</Layout>
|
||||||
<div class="fields">
|
<Layout noPadding>
|
||||||
<div class="field">
|
<div class="fields">
|
||||||
<Label size="L">License key</Label>
|
<div class="field">
|
||||||
<Input
|
<CopyInput value={installationIdentifier} />
|
||||||
thin
|
</div>
|
||||||
bind:value={licenseKey}
|
</div>
|
||||||
type={licenseKeyType}
|
</Layout>
|
||||||
disabled={licenseKeyDisabled}
|
<Divider />
|
||||||
|
<Layout gap="XS" noPadding>
|
||||||
|
<Heading size="XS">License</Heading>
|
||||||
|
<Body size="S">Upload your license to activate your plan</Body>
|
||||||
|
</Layout>
|
||||||
|
<Layout noPadding>
|
||||||
|
<div>
|
||||||
|
<File
|
||||||
|
title="Upload license"
|
||||||
|
extensions={offlineLicenseExtensions}
|
||||||
|
value={offlineLicense}
|
||||||
|
on:change={onOfflineLicenseChange}
|
||||||
|
allowClear={true}
|
||||||
|
disabled={!!offlineLicense}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
<ButtonGroup gap="M">
|
{:else}
|
||||||
<Button cta on:click={activate} disabled={activateDisabled}>
|
<Layout gap="XS" noPadding>
|
||||||
Activate
|
<Heading size="XS">Activate</Heading>
|
||||||
</Button>
|
<Body size="S">Enter your license key below to activate your plan</Body>
|
||||||
{#if licenseInfo?.licenseKey}
|
</Layout>
|
||||||
<Button warning on:click={() => deleteLicenseKeyModal.show()}>
|
<Layout noPadding>
|
||||||
Delete
|
<div class="fields">
|
||||||
|
<div class="field">
|
||||||
|
<Label size="L">License key</Label>
|
||||||
|
<Input
|
||||||
|
thin
|
||||||
|
bind:value={licenseKey}
|
||||||
|
type={licenseKeyType}
|
||||||
|
disabled={licenseKeyDisabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ButtonGroup gap="M">
|
||||||
|
<Button cta on:click={activateLicenseKey} disabled={activateDisabled}>
|
||||||
|
Activate
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{#if licenseKey}
|
||||||
</ButtonGroup>
|
<Button warning on:click={() => deleteLicenseKeyModal.show()}>
|
||||||
</Layout>
|
Delete
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
</ButtonGroup>
|
||||||
|
</Layout>
|
||||||
|
{/if}
|
||||||
<Divider />
|
<Divider />
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
<Heading size="S">Plan</Heading>
|
<Heading size="XS">Plan</Heading>
|
||||||
<Layout noPadding gap="XXS">
|
<Layout noPadding gap="S">
|
||||||
<Body size="S">You are currently on the {license.plan.type} plan</Body>
|
<Body size="S">You are currently on the {license.plan.type} plan</Body>
|
||||||
|
<div>
|
||||||
|
<Body size="S">If you purchase or update your plan on the account</Body>
|
||||||
|
<Body size="S">portal, click the refresh button to sync those changes</Body>
|
||||||
|
</div>
|
||||||
<Body size="XS">
|
<Body size="XS">
|
||||||
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
|
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
|
||||||
time:
|
time:
|
||||||
|
|
|
@ -17,6 +17,7 @@ export const DEFAULT_CONFIG = {
|
||||||
adminUser: { checked: false },
|
adminUser: { checked: false },
|
||||||
sso: { checked: false },
|
sso: { checked: false },
|
||||||
},
|
},
|
||||||
|
offlineMode: false
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAdminStore() {
|
export function createAdminStore() {
|
||||||
|
|
|
@ -1,32 +1,56 @@
|
||||||
export const buildLicensingEndpoints = API => ({
|
export const buildLicensingEndpoints = API => ({
|
||||||
/**
|
|
||||||
* Activates a self hosted license key
|
// LICENSE KEY
|
||||||
*/
|
|
||||||
activateLicenseKey: async data => {
|
activateLicenseKey: async data => {
|
||||||
return API.post({
|
return API.post({
|
||||||
url: `/api/global/license/activate`,
|
url: `/api/global/license/key`,
|
||||||
body: data,
|
body: data,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a self hosted license key
|
|
||||||
*/
|
|
||||||
deleteLicenseKey: async () => {
|
deleteLicenseKey: async () => {
|
||||||
return API.delete({
|
return API.delete({
|
||||||
url: `/api/global/license/info`,
|
url: `/api/global/license/key`,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getLicenseKey: async () => {
|
||||||
|
try {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/global/license/key",
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
if (e.status !== 404) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
// OFFLINE LICENSE
|
||||||
* Get the license info - metadata about the license including the
|
|
||||||
* obfuscated license key.
|
activateOfflineLicense: async ({ offlineLicense }) => {
|
||||||
*/
|
return API.post({
|
||||||
getLicenseInfo: async () => {
|
url: "/api/global/license/offline",
|
||||||
return API.get({
|
body: {
|
||||||
url: "/api/global/license/info",
|
offlineLicense
|
||||||
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
deleteOfflineLicense: async () => {
|
||||||
|
return API.delete({
|
||||||
|
url: "/api/global/license/offline",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getOfflineLicense: async () => {
|
||||||
|
try {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/global/license/offline",
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
if (e.status !== 404) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes the license cache
|
* Refreshes the license cache
|
||||||
|
@ -36,7 +60,6 @@ export const buildLicensingEndpoints = API => ({
|
||||||
url: "/api/global/license/refresh",
|
url: "/api/global/license/refresh",
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the usage information for the tenant
|
* Retrieve the usage information for the tenant
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue