Frontend work and basic API work for app update support.
This commit is contained in:
parent
fd518548fd
commit
bd197bee9e
|
@ -0,0 +1,40 @@
|
||||||
|
<script>
|
||||||
|
import { ModalContent, Toggle, Input, Layout, Dropzone } from "@budibase/bbui"
|
||||||
|
|
||||||
|
export let app
|
||||||
|
|
||||||
|
$: disabled = (encrypted && !password) || !file
|
||||||
|
let encrypted = false,
|
||||||
|
password
|
||||||
|
let file
|
||||||
|
|
||||||
|
function updateApp() {
|
||||||
|
console.log("confirm")
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ModalContent
|
||||||
|
title={`Update ${app.name}`}
|
||||||
|
confirmText="Update"
|
||||||
|
onConfirm={updateApp}
|
||||||
|
bind:disabled
|
||||||
|
>
|
||||||
|
<Layout noPadding gap="XS">
|
||||||
|
<Dropzone
|
||||||
|
gallery={false}
|
||||||
|
label="App export"
|
||||||
|
on:change={e => {
|
||||||
|
file = e.detail?.[0]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Toggle text="Encrypted" bind:value={encrypted} />
|
||||||
|
{#if encrypted}
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
label="Password"
|
||||||
|
placeholder="Type here..."
|
||||||
|
bind:value={password}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</Layout>
|
||||||
|
</ModalContent>
|
|
@ -32,9 +32,9 @@
|
||||||
active={$isActive("./embed")}
|
active={$isActive("./embed")}
|
||||||
/>
|
/>
|
||||||
<SideNavItem
|
<SideNavItem
|
||||||
text="Export"
|
text="Export/Import"
|
||||||
url={$url("./export")}
|
url={$url("./exportImport")}
|
||||||
active={$isActive("./export")}
|
active={$isActive("./exportImport")}
|
||||||
/>
|
/>
|
||||||
<SideNavItem
|
<SideNavItem
|
||||||
text="Name and URL"
|
text="Name and URL"
|
||||||
|
|
|
@ -11,31 +11,39 @@
|
||||||
import { apps } from "stores/portal"
|
import { apps } from "stores/portal"
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import ExportAppModal from "components/start/ExportAppModal.svelte"
|
import ExportAppModal from "components/start/ExportAppModal.svelte"
|
||||||
|
import ImportAppModal from "components/start/ImportAppModal.svelte"
|
||||||
|
|
||||||
$: filteredApps = $apps.filter(app => app.devId == $store.appId)
|
$: filteredApps = $apps.filter(app => app.devId == $store.appId)
|
||||||
$: app = filteredApps.length ? filteredApps[0] : {}
|
$: app = filteredApps.length ? filteredApps[0] : {}
|
||||||
$: appDeployed = app?.status === AppStatus.DEPLOYED
|
$: appDeployed = app?.status === AppStatus.DEPLOYED
|
||||||
|
|
||||||
let exportModal
|
let exportModal, importModal
|
||||||
let exportPublishedVersion = false
|
let exportPublishedVersion = false
|
||||||
|
|
||||||
const exportApp = opts => {
|
const exportApp = opts => {
|
||||||
exportPublishedVersion = !!opts?.published
|
exportPublishedVersion = !!opts?.published
|
||||||
exportModal.show()
|
exportModal.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importApp = () => {
|
||||||
|
importModal.show()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Modal bind:this={exportModal} padding={false}>
|
<Modal bind:this={exportModal} padding={false}>
|
||||||
<ExportAppModal {app} published={exportPublishedVersion} />
|
<ExportAppModal {app} published={exportPublishedVersion} />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<Modal bind:this={importModal} padding={false}>
|
||||||
|
<ImportAppModal {app} />
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
<Heading>Export your app</Heading>
|
<Heading>Export your app</Heading>
|
||||||
<Body>Export your latest edited or published app</Body>
|
<Body>Export your latest edited or published app</Body>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Divider />
|
<div class="body">
|
||||||
<div class="export-body">
|
|
||||||
<ActionButton secondary on:click={() => exportApp({ published: false })}>
|
<ActionButton secondary on:click={() => exportApp({ published: false })}>
|
||||||
Export latest edited app
|
Export latest edited app
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
@ -47,10 +55,20 @@
|
||||||
Export latest published app
|
Export latest published app
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
|
<Divider />
|
||||||
|
<Layout gap="XS" noPadding>
|
||||||
|
<Heading>Import your app</Heading>
|
||||||
|
<Body>Import an export to update this app</Body>
|
||||||
|
</Layout>
|
||||||
|
<div class="body">
|
||||||
|
<ActionButton secondary on:click={() => importApp()}>
|
||||||
|
Import app
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.export-body {
|
.body {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacing-l);
|
gap: var(--spacing-l);
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ CREATE TABLE Persons (
|
||||||
Address varchar(255),
|
Address varchar(255),
|
||||||
City varchar(255) DEFAULT 'Belfast',
|
City varchar(255) DEFAULT 'Belfast',
|
||||||
Age INTEGER DEFAULT 20 NOT NULL,
|
Age INTEGER DEFAULT 20 NOT NULL,
|
||||||
|
Year INTEGER,
|
||||||
Type person_job
|
Type person_job
|
||||||
);
|
);
|
||||||
CREATE TABLE Tasks (
|
CREATE TABLE Tasks (
|
||||||
|
@ -49,9 +50,10 @@ CREATE TABLE CompositeTable (
|
||||||
Name varchar(255),
|
Name varchar(255),
|
||||||
PRIMARY KEY (KeyPartOne, KeyPartTwo)
|
PRIMARY KEY (KeyPartOne, KeyPartTwo)
|
||||||
);
|
);
|
||||||
INSERT INTO Persons (FirstName, LastName, Address, City, Type) VALUES ('Mike', 'Hughes', '123 Fake Street', 'Belfast', 'qa');
|
INSERT INTO Persons (FirstName, LastName, Address, City, Type, Year) VALUES ('Mike', 'Hughes', '123 Fake Street', 'Belfast', 'qa', 1999);
|
||||||
INSERT INTO Persons (FirstName, LastName, Address, City, Type) VALUES ('John', 'Smith', '64 Updown Road', 'Dublin', 'programmer');
|
INSERT INTO Persons (FirstName, LastName, Address, City, Type, Year) VALUES ('John', 'Smith', '64 Updown Road', 'Dublin', 'programmer', 1996);
|
||||||
INSERT INTO Persons (FirstName, LastName, Address, City, Type, Age) VALUES ('Foo', 'Bar', 'Foo Street', 'Bartown', 'support', 0);
|
INSERT INTO Persons (FirstName, LastName, Address, City, Type, Age, Year) VALUES ('Foo', 'Bar', 'Foo Street', 'Bartown', 'support', 0, 1993);
|
||||||
|
INSERT INTO Persons (FirstName, LastName, Address, City, Type) VALUES ('Jonny', 'Muffin', 'Muffin Street', 'Cork', 'support');
|
||||||
INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (1, 2, 'assembling', TRUE);
|
INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (1, 2, 'assembling', TRUE);
|
||||||
INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (2, 1, 'processing', FALSE);
|
INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (2, 1, 'processing', FALSE);
|
||||||
INSERT INTO Products (ProductName) VALUES ('Computers');
|
INSERT INTO Products (ProductName) VALUES ('Computers');
|
||||||
|
|
|
@ -575,6 +575,8 @@ export async function sync(ctx: UserCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateWithExport(ctx: UserCtx) {}
|
||||||
|
|
||||||
export async function updateAppPackage(appPackage: any, appId: any) {
|
export async function updateAppPackage(appPackage: any, appId: any) {
|
||||||
return context.doInAppContext(appId, async () => {
|
return context.doInAppContext(appId, async () => {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
|
|
|
@ -58,5 +58,10 @@ router
|
||||||
authorized(permissions.GLOBAL_BUILDER),
|
authorized(permissions.GLOBAL_BUILDER),
|
||||||
controller.destroy
|
controller.destroy
|
||||||
)
|
)
|
||||||
|
.post(
|
||||||
|
"/api/applications/:appId/update",
|
||||||
|
authorized(permissions.BUILDER),
|
||||||
|
controller.updateWithExport
|
||||||
|
)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
Loading…
Reference in New Issue