1
0
Fork 0
mirror of synced 2024-07-09 08:16:34 +12:00

Merge branch 'develop' into correct-nginx-cors-changes

This commit is contained in:
Andrew Kingston 2023-09-25 19:51:17 +01:00 committed by GitHub
commit 00c0ee0efa
10 changed files with 330 additions and 18 deletions

View file

@ -1,5 +1,5 @@
{
"version": "2.10.12-alpha.11",
"version": "2.10.12-alpha.13",
"npmClient": "yarn",
"packages": [
"packages/*"

View file

@ -14,13 +14,14 @@
import GridManageAccessButton from "components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte"
import GridRelationshipButton from "components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte"
import GridEditColumnModal from "components/backend/DataTable/modals/grid/GridEditColumnModal.svelte"
import GridUsersTableButton from "components/backend/DataTable/modals/grid/GridUsersTableButton.svelte"
const userSchemaOverrides = {
firstName: { displayName: "First name", disabled: true },
lastName: { displayName: "Last name", disabled: true },
email: { displayName: "Email", disabled: true },
roleId: { displayName: "Role", disabled: true },
status: { displayName: "Status", disabled: true },
firstName: { displayName: "First name" },
lastName: { displayName: "Last name" },
email: { displayName: "Email" },
roleId: { displayName: "Role" },
status: { displayName: "Status" },
}
$: id = $tables.selected?._id
@ -59,22 +60,22 @@
datasource={gridDatasource}
canAddRows={!isUsersTable}
canDeleteRows={!isUsersTable}
canEditRows={!isUsersTable}
canEditColumns={!isUsersTable}
schemaOverrides={isUsersTable ? userSchemaOverrides : null}
showAvatars={false}
on:updatedatasource={handleGridTableUpdate}
>
<svelte:fragment slot="filter">
{#if isUsersTable}
<GridUsersTableButton />
{/if}
<GridFilterButton />
</svelte:fragment>
<svelte:fragment slot="edit-column">
<GridEditColumnModal />
</svelte:fragment>
<svelte:fragment slot="add-column">
<GridAddColumnModal />
</svelte:fragment>
<svelte:fragment slot="controls">
<GridCreateViewButton />
{#if !isUsersTable}
<GridCreateViewButton />
{/if}
<GridManageAccessButton />
{#if relationshipsEnabled}
<GridRelationshipButton />
@ -84,7 +85,6 @@
{:else}
<GridImportButton />
{/if}
<GridExportButton />
{#if isUsersTable}
<GridEditUserModal />
@ -92,6 +92,12 @@
<GridCreateEditRowModal />
{/if}
</svelte:fragment>
<svelte:fragment slot="edit-column">
<GridEditColumnModal />
</svelte:fragment>
<svelte:fragment slot="add-column">
<GridAddColumnModal />
</svelte:fragment>
</Grid>
</div>

View file

@ -0,0 +1,54 @@
<script>
import { ActionButton, Popover, Heading, Body, Button } from "@budibase/bbui"
import { store } from "builderStore"
let anchor
let open = false
const openSidePanel = () => {
store.update(state => ({
...state,
builderSidePanel: true,
}))
open = false
}
</script>
<div bind:this={anchor}>
<ActionButton on:click={() => (open = true)} icon="Help" quiet>
Why can't I edit this table?
</ActionButton>
</div>
<Popover bind:open {anchor} align="left">
<div class="content">
<Heading size="XS">The app users table is read only</Heading>
<Body size="S">
You can continue to view the users that have access to your application.
</Body>
<Body size="S">
Manage and invite more application users using the user side panel in the
top right of your screen.
</Body>
<div class="button">
<Button cta on:click={openSidePanel}>Open users panel</Button>
</div>
</div>
</Popover>
<style>
.content {
width: 300px;
padding: var(--spacing-l);
display: flex;
flex-direction: column;
gap: var(--spacing-l);
}
.content :global(.spectrum-Heading) {
font-weight: 400;
}
.button {
display: flex;
justify-content: flex-end;
}
</style>

View file

@ -180,7 +180,7 @@
<div class="hierarchy-items-container">
<NavItem
icon="UserGroup"
text="Users"
text="App users"
selected={$isActive("./table/:tableId") &&
$tables.selected?._id === TableNames.USERS}
on:click={() => selectTable(TableNames.USERS)}

View file

@ -101,7 +101,7 @@
justify-content: flex-start;
align-items: center;
border-bottom: var(--border-light);
padding: 0 24px;
padding: 0 var(--spacing-l);
gap: 24px;
position: relative;
}

View file

@ -0,0 +1,15 @@
<script>
import { params, redirect } from "@roxi/routify"
import { apps } from "stores/portal"
$: app = $apps.find(app => app.appId === $params.appId)
$: {
if (!app) {
$redirect("../")
}
}
</script>
{#if app}
<slot />
{/if}

View file

@ -0,0 +1,79 @@
<script>
import { params, goto } from "@roxi/routify"
import { apps, auth, sideBarCollapsed } from "stores/portal"
import { ActionButton } from "@budibase/bbui"
import { sdk } from "@budibase/shared-core"
$: app = $apps.find(app => app.appId === $params.appId)
$: iframeUrl = getIframeURL(app)
$: isBuilder = sdk.users.isBuilder($auth.user, app?.devId)
const getIframeURL = app => {
if (app.status === "published") {
return `/app${app.url}`
}
return `/${app.devId}`
}
</script>
<div class="container">
<div class="header">
{#if $sideBarCollapsed}
<ActionButton
quiet
icon="Rail"
on:click={() => sideBarCollapsed.set(false)}
>
Menu
</ActionButton>
{:else}
<ActionButton
quiet
icon="RailRightOpen"
on:click={() => sideBarCollapsed.set(true)}
>
Collapse
</ActionButton>
{/if}
{#if isBuilder}
<ActionButton
quiet
icon="Edit"
on:click={() => $goto(`../../app/${app.devId}`)}
>
Edit
</ActionButton>
{/if}
<ActionButton
quiet
icon="LinkOut"
on:click={() => window.open(iframeUrl, "_blank")}
>
Fullscreen
</ActionButton>
</div>
<iframe src={iframeUrl} title={app.name} />
</div>
<style>
.container {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
padding: 0 var(--spacing-l) var(--spacing-l) var(--spacing-l);
}
.header {
display: flex;
justify-content: flex-start;
align-items: center;
gap: var(--spacing-xs);
flex: 0 0 50px;
}
iframe {
flex: 1 1 auto;
border-radius: var(--spacing-s);
border: 1px solid var(--spectrum-global-color-gray-300);
}
</style>

View file

@ -0,0 +1,140 @@
<script>
import { Icon, Body } from "@budibase/bbui"
import { apps, sideBarCollapsed } from "stores/portal"
import { params, goto } from "@roxi/routify"
import { tick } from "svelte"
import NavItem from "components/common/NavItem.svelte"
let searchInput
let searchString
let searching = false
$: filteredApps = $apps.filter(app => {
return (
!searchString ||
app.name.toLowerCase().includes(searchString.toLowerCase())
)
})
const startSearching = async () => {
searching = true
searchString = ""
await tick()
searchInput.focus()
}
const stopSearching = () => {
searching = false
searchString = ""
}
</script>
<div class="side-bar" class:collapsed={$sideBarCollapsed}>
<div class="side-bar-controls">
{#if searching}
<input
bind:this={searchInput}
bind:value={searchString}
placeholder="Search for apps"
/>
{:else}
<Body size="S">Apps</Body>
<Icon name="Search" size="S" hoverable on:click={startSearching} />
{/if}
<div class="rotational" class:rotated={searching}>
<Icon
name="Add"
hoverable
on:click={searching ? stopSearching : () => $goto("./create")}
/>
</div>
</div>
<div class="side-bar-nav">
<NavItem
icon="WebPages"
text="All apps"
on:click={() => $goto("./")}
selected={!$params.appId}
/>
{#each filteredApps as app}
<NavItem
text={app.name}
icon={app.icon?.name || "Apps"}
iconColor={app.icon?.color}
selected={$params.appId === app.appId}
on:click={() => $goto(`./${app.appId}`)}
/>
{/each}
</div>
</div>
<style>
.side-bar {
flex: 0 0 260px;
display: flex;
flex-direction: column;
align-items: stretch;
border-right: var(--border-light);
background: var(--spectrum-global-color-gray-100);
overflow: hidden;
transition: margin-left 300ms ease-out;
}
.side-bar.collapsed {
margin-left: -262px;
}
@media (max-width: 640px) {
.side-bar {
margin-left: -262px;
}
}
.side-bar-controls {
flex: 0 0 50px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: var(--spacing-l);
padding: 0 var(--spacing-l);
}
.side-bar-controls :global(.spectrum-Body),
.side-bar-controls input {
flex: 1 1 auto;
}
.side-bar-controls :global(.spectrum-Icon) {
color: var(--spectrum-global-color-gray-700);
}
input {
outline: none;
border: none;
max-width: none;
flex: 1 1 auto;
color: var(--spectrum-global-color-gray-800);
font-size: 14px;
padding: 0;
transition: border 130ms ease-out;
font-family: var(--font-sans);
background: inherit;
}
input::placeholder {
color: var(--spectrum-global-color-gray-700);
transition: color 130ms ease-out;
}
input:hover::placeholder {
color: var(--spectrum-global-color-gray-800);
}
.side-bar-nav {
flex: 1 1 auto;
overflow: auto;
overflow-x: hidden;
}
div.rotational {
transition: transform 130ms ease-out;
}
div.rotational.rotated {
transform: rotate(45deg);
}
</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}
<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>

View file

@ -1,3 +1,5 @@
import { writable } from "svelte/store"
export { organisation } from "./organisation"
export { users } from "./users"
export { admin } from "./admin"
@ -14,3 +16,5 @@ export { environment } from "./environment"
export { menu } from "./menu"
export { auditLogs } from "./auditLogs"
export { features } from "./features"
export const sideBarCollapsed = writable(false)