POC of new portal

This commit is contained in:
Andrew Kingston 2023-08-04 08:38:05 +01:00
parent b370b89a07
commit e93e7ed885
4 changed files with 260 additions and 1 deletions

View File

@ -0,0 +1,72 @@
<script>
import { params, goto } from "@roxi/routify"
import { apps } from "stores/portal"
import { Icon } from "@budibase/bbui"
$: app = $apps.find(app => app.appId === $params.appId)
$: iframeUrl = getIframeURL(app)
$: preview = app?.status !== "published"
const getIframeURL = app => {
if (app.status === "published") {
return `/app${app.url}`
}
return `/${app.devId}`
}
</script>
<div class="container">
<div class="header">
<div class="icons">
<Icon name="RailRightOpen" size="S" />
</div>
<div class="text">
{#if preview}
This is a preview of your unpublished app
{/if}
</div>
<div class="icons">
<Icon
name="Edit"
hoverable
on:click={() => $goto(`../../app/${app.devId}`)}
size="S"
/>
<Icon
name="LinkOut"
hoverable
on:click={() => window.open(iframeUrl, "_blank")}
size="S"
/>
</div>
</div>
<iframe src={iframeUrl} />
</div>
<style>
.container {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: 10px;
padding: 10px 10px 10px 0;
}
.header {
flex: 0 0 32px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 8px;
}
.icons {
display: flex;
gap: 24px;
}
iframe {
flex: 1 1 auto;
border-radius: 8px;
border: none;
}
</style>

View File

@ -0,0 +1,131 @@
<script>
import { Icon } from "@budibase/bbui"
import PortalSideNavItem from "./PortalSideNavItem.svelte"
import { apps } from "stores/portal"
import { params, goto } from "@roxi/routify"
let searchString
$: filteredApps = $apps.filter(app => {
return (
!searchString ||
app.name.toLowerCase().includes(searchString.toLowerCase())
)
})
</script>
<div class="side-bar">
<div class="side-bar-controls">
<div class="search">
<input bind:value={searchString} placeholder="Search" />
<Icon name="Search" size="S" />
</div>
<div class="add-app" on:click={() => $goto("./create")}>
<Icon name="Add" />
</div>
</div>
<div class="side-bar-nav">
<PortalSideNavItem
icon="WebPages"
text="All apps"
url="./"
selected={!$params.appId}
/>
{#each filteredApps as app}
<PortalSideNavItem
icon={app.icon?.name || "Apps"}
iconColor={app.icon?.color}
text={app.name}
url={`./${app.appId}`}
selected={$params.appId === app.appId}
/>
{/each}
</div>
</div>
<style>
.side-bar {
--spacing: 10px;
--radius: 8px;
flex: 0 0 300px;
padding: var(--spacing);
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--spacing);
}
.side-bar-controls {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
gap: var(--spacing);
}
.search {
flex: 1 1 auto;
display: flex;
align-items: center;
justify-content: flex-start;
position: relative;
}
input {
outline: none;
max-width: none;
flex: 1 1 auto;
padding: 0 38px 0 var(--spacing);
color: var(--spectrum-global-color-gray-800);
font-size: 12px;
border: 1px solid transparent;
transition: border 130ms ease-out;
}
input::placeholder {
color: var(--spectrum-global-color-gray-700);
transition: color 130ms ease-out;
}
input:hover {
border: 1px solid var(--spectrum-global-color-gray-300);
}
input:hover::placeholder {
color: var(--spectrum-global-color-gray-800);
}
input:focus {
border: 1px solid var(--spectrum-global-color-blue-400);
}
.search :global(.spectrum-Icon) {
position: absolute;
right: 10px;
}
.add-app {
flex: 0 0 32px;
display: grid;
place-items: center;
transition: background 130ms ease-out;
}
.add-app:hover {
cursor: pointer;
background: var(--spectrum-global-color-gray-200);
}
.search input,
.add-app {
height: 32px;
}
.search input,
.add-app,
.side-bar-nav {
background: var(--spectrum-global-color-gray-100);
border-radius: var(--radius);
}
.side-bar-nav {
flex: 1 1 auto;
padding: var(--spacing);
display: flex;
flex-direction: column;
justify-items: flex-start;
align-items: stretch;
gap: 6px;
overflow: auto;
overflow-x: hidden;
}
</style>

View File

@ -0,0 +1,42 @@
<script>
import { Icon } from "@budibase/bbui"
import { goto } from "@roxi/routify"
export let icon = null
export let iconColor = null
export let text = ""
export let selected = false
export let url = null
</script>
<div class="container" on:click={() => $goto(url)} class:selected>
<Icon name={icon} color={iconColor} />
<div class="text">{text}</div>
</div>
<style>
.container {
padding: 8px 12px;
border-radius: var(--radius);
display: flex;
align-items: center;
justify-content: flex-start;
gap: var(--spacing);
transition: background 130ms ease-out;
}
.container:hover {
background: var(--spectrum-global-color-gray-200);
cursor: pointer;
}
.container.selected {
background: var(--spectrum-global-color-gray-300);
}
.container :global(.spectrum-Icon) {
color: var(--spectrm-global-color-gray-600);
}
.text {
flex: 1 1 auto;
font-size: 14px;
color: var(--spectrm-global-color-gray-900);
}
</style>

View File

@ -11,6 +11,7 @@
import { onMount } from "svelte"
import { redirect } from "@roxi/routify"
import { sdk } from "@budibase/shared-core"
import PortalSideBar from "./_components/PortalSideBar.svelte"
// Don't block loading if we've already hydrated state
let loaded = $apps.length != null
@ -44,5 +45,18 @@
</script>
{#if loaded}
<div class="page">
<PortalSideBar />
<slot />
</div>
{/if}
<style>
.page {
flex: 1 1 auto;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
}
</style>