mirror of https://github.com/Budibase/budibase.git
committed by
GitHub
14 changed files with 336 additions and 26 deletions
@ -0,0 +1,54 @@ |
|||
<script> |
|||
import { isActive, url, goto } from "@roxi/routify" |
|||
import { onMount } from "svelte" |
|||
import { |
|||
ActionMenu, |
|||
Checkbox, |
|||
Body, |
|||
MenuItem, |
|||
Icon, |
|||
Heading, |
|||
Avatar, |
|||
Search, |
|||
Layout, |
|||
ProgressCircle, |
|||
SideNavigation as Navigation, |
|||
SideNavigationItem as Item, |
|||
} from "@budibase/bbui" |
|||
import api from "builderStore/api" |
|||
import { organisation, admin } from "stores/portal" |
|||
|
|||
const MESSAGES = { |
|||
apps: "Create your first app", |
|||
smtp: "Set up email", |
|||
adminUser: "Create your first user", |
|||
} |
|||
</script> |
|||
|
|||
<ActionMenu> |
|||
<div slot="control" class="icon"> |
|||
<ProgressCircle size="S" value={$admin.onboardingProgress} /> |
|||
</div> |
|||
<MenuItem disabled> |
|||
<header class="item"> |
|||
<Heading size="XXS">Get Started Checklist</Heading> |
|||
<ProgressCircle size="S" value={$admin.onboardingProgress} /> |
|||
</header> |
|||
</MenuItem> |
|||
{#each Object.keys($admin.checklist) as checklistItem, idx} |
|||
<MenuItem> |
|||
<div class="item"> |
|||
<span>{idx + 1}. {MESSAGES[checklistItem]}</span> |
|||
<Checkbox value={!!$admin.checklist[checklistItem]} /> |
|||
</div> |
|||
</MenuItem> |
|||
{/each} |
|||
</ActionMenu> |
|||
|
|||
<style> |
|||
.item { |
|||
display: grid; |
|||
align-items: center; |
|||
grid-template-columns: 200px 20px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,29 @@ |
|||
<script> |
|||
import { onMount } from "svelte" |
|||
import { goto } from "@roxi/routify" |
|||
import { |
|||
SideNavigation as Navigation, |
|||
SideNavigationItem as Item, |
|||
} from "@budibase/bbui" |
|||
import { admin } from "stores/portal" |
|||
import LoginForm from "components/login/LoginForm.svelte" |
|||
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte" |
|||
import LogoutButton from "components/start/LogoutButton.svelte" |
|||
import Logo from "/assets/budibase-logo.svg" |
|||
import api from "builderStore/api" |
|||
|
|||
let checklist |
|||
|
|||
onMount(async () => { |
|||
await admin.init() |
|||
if (!$admin?.checklist?.adminUser) { |
|||
$goto("./admin") |
|||
} else { |
|||
$goto("./portal") |
|||
} |
|||
}) |
|||
</script> |
|||
|
|||
{#if $admin.checklist} |
|||
<slot /> |
|||
{/if} |
|||
@ -0,0 +1,69 @@ |
|||
<script> |
|||
import { |
|||
Button, |
|||
Heading, |
|||
Label, |
|||
notifications, |
|||
Layout, |
|||
Input, |
|||
Body, |
|||
} from "@budibase/bbui" |
|||
import { goto } from "@roxi/routify" |
|||
import { onMount } from "svelte" |
|||
import api from "builderStore/api" |
|||
|
|||
let adminUser = {} |
|||
|
|||
async function save() { |
|||
try { |
|||
// Save the admin user |
|||
const response = await api.post(`/api/admin/users/init`, adminUser) |
|||
|
|||
const json = await response.json() |
|||
if (response.status !== 200) throw new Error(json.message) |
|||
notifications.success(`Admin user created.`) |
|||
$goto("../portal") |
|||
} catch (err) { |
|||
notifications.error(`Failed to create admin user.`) |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<section> |
|||
<div class="container"> |
|||
<header> |
|||
<Heading size="M">Create an admin user</Heading> |
|||
<Body size="S">The admin user has access to everything in budibase.</Body> |
|||
</header> |
|||
<div class="config-form"> |
|||
<Layout gap="S"> |
|||
<Input label="email" bind:value={adminUser.email} /> |
|||
<Input |
|||
label="password" |
|||
type="password" |
|||
bind:value={adminUser.password} |
|||
/> |
|||
<Button cta on:click={save}>Create super admin user</Button> |
|||
</Layout> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
|||
<style> |
|||
section { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100%; |
|||
} |
|||
|
|||
header { |
|||
text-align: center; |
|||
width: 80%; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.config-form { |
|||
margin-bottom: 42px; |
|||
} |
|||
</style> |
|||
@ -1,7 +1,36 @@ |
|||
import { writable } from "svelte/store" |
|||
import api from "builderStore/api" |
|||
|
|||
const INITIAL_ADMIN_STATE = { |
|||
oauth: [], |
|||
export function createAdminStore() { |
|||
const { subscribe, set } = writable({}) |
|||
|
|||
async function init() { |
|||
try { |
|||
const response = await api.get("/api/admin/configs/checklist") |
|||
const json = await response.json() |
|||
|
|||
const onboardingSteps = Object.keys(json) |
|||
|
|||
const stepsComplete = onboardingSteps.reduce( |
|||
(score, step) => score + Number(!!json[step]), |
|||
0 |
|||
) |
|||
|
|||
set({ |
|||
checklist: json, |
|||
onboardingProgress: (stepsComplete / onboardingSteps.length) * 100, |
|||
}) |
|||
} catch (err) { |
|||
set({ |
|||
checklist: null, |
|||
}) |
|||
} |
|||
} |
|||
|
|||
return { |
|||
subscribe, |
|||
init, |
|||
} |
|||
} |
|||
|
|||
export const admin = writable({ ...INITIAL_ADMIN_STATE }) |
|||
export const admin = createAdminStore() |
|||
|
|||
@ -0,0 +1,38 @@ |
|||
const setup = require("./utilities") |
|||
|
|||
// mock the email system
|
|||
const sendMailMock = jest.fn() |
|||
jest.mock("nodemailer") |
|||
const nodemailer = require("nodemailer") |
|||
nodemailer.createTransport.mockReturnValue({ |
|||
verify: jest.fn() |
|||
}) |
|||
|
|||
describe("/api/admin/configs/checklist", () => { |
|||
let request = setup.getRequest() |
|||
let config = setup.getConfig() |
|||
|
|||
beforeAll(async () => { |
|||
await config.init() |
|||
}) |
|||
|
|||
afterAll(setup.afterAll) |
|||
|
|||
it("should return the correct checklist status based on the state of the budibase installation", async () => { |
|||
// initially configure settings
|
|||
await config.saveAdminUser() |
|||
await config.saveSmtpConfig() |
|||
|
|||
const res = await request |
|||
.get(`/api/admin/configs/checklist`) |
|||
.set(config.defaultHeaders()) |
|||
.expect("Content-Type", /json/) |
|||
.expect(200) |
|||
|
|||
const checklist = res.body |
|||
|
|||
expect(checklist.apps).toBe(0) |
|||
expect(checklist.smtp).toBe(true) |
|||
expect(checklist.adminUser).toBe(true) |
|||
}) |
|||
}) |
|||
Loading…
Reference in new issue