POC of new portal
This commit is contained in:
parent
b370b89a07
commit
e93e7ed885
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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}
|
||||
<slot />
|
||||
<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>
|
||||
|
|
Loading…
Reference in New Issue