Fixing issue #3915 so that when using the short hand URL for apps you will be redirected correctly if not logged in, allows all users to make use of it and updating the builder to send the user to the short form factor URL if not in cloud.

This commit is contained in:
mike12345567 2022-01-05 18:26:39 +00:00
parent 23ca7a9750
commit 24bebd82e9
4 changed files with 32 additions and 137 deletions

View File

@ -1,126 +0,0 @@
<script>
import {
Heading,
Icon,
Body,
Layout,
ActionMenu,
MenuItem,
StatusLight,
} from "@budibase/bbui"
import { gradient } from "actions"
import { processStringSync } from "@budibase/string-templates"
export let app
export let exportApp
export let viewApp
export let editApp
export let updateApp
export let deleteApp
export let unpublishApp
export let releaseLock
</script>
<div class="wrapper">
<Layout noPadding gap="XS" alignContent="start">
<div class="preview" use:gradient={{ seed: app.name }} />
<div class="title">
{#if app.lockedBy}
<Icon name="LockClosed" />
{/if}
<div class="name" on:click={() => editApp(app)}>
<Heading size="XS">
{app.name}
</Heading>
</div>
<ActionMenu align="right">
<Icon slot="control" name="More" hoverable />
{#if app.deployed}
<MenuItem on:click={() => viewApp(app)} icon="GlobeOutline">
View published app
</MenuItem>
{/if}
{#if app.lockedYou}
<MenuItem on:click={() => releaseLock(app)} icon="LockOpen">
Release lock
</MenuItem>
{/if}
<MenuItem on:click={() => exportApp(app)} icon="Download">
Export
</MenuItem>
{#if app.deployed}
<MenuItem on:click={() => unpublishApp(app)} icon="GlobeRemove">
Unpublish
</MenuItem>
{/if}
{#if !app.deployed}
<MenuItem on:click={() => updateApp(app)} icon="Edit">Edit</MenuItem>
<MenuItem on:click={() => deleteApp(app)} icon="Delete">
Delete
</MenuItem>
{/if}
</ActionMenu>
</div>
<div class="status">
<Body size="S">
{#if app.updatedAt}
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
time: new Date().getTime() - new Date(app.updatedAt).getTime(),
})}
{:else}
Never updated
{/if}
</Body>
<StatusLight active={app.deployed} neutral={!app.deployed}>
{#if app.deployed}Published{:else}Unpublished{/if}
</StatusLight>
</div>
</Layout>
</div>
<style>
.wrapper {
overflow: hidden;
}
.wrapper :global(.spectrum-StatusLight) {
padding: 0;
min-height: 0;
}
.preview {
height: 135px;
border-radius: var(--border-radius-s);
margin-bottom: var(--spacing-m);
}
.status {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.name {
flex: 1 1 auto;
}
.title {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
gap: var(--spacing-m);
}
.title :global(.spectrum-Icon) {
flex: 0 0 auto;
}
.title :global(h1) {
overflow: hidden;
text-overflow: ellipsis;
}
.title :global(h1:hover) {
color: var(--spectrum-global-color-blue-600);
cursor: pointer;
transition: color 130ms ease;
}
</style>

View File

@ -12,7 +12,7 @@
Modal,
} from "@budibase/bbui"
import { onMount } from "svelte"
import { apps, organisation, auth } from "stores/portal"
import { apps, organisation, auth, admin } from "stores/portal"
import { goto } from "@roxi/routify"
import { AppStatus } from "constants"
import { gradient } from "actions"
@ -34,12 +34,16 @@
const publishedAppsOnly = app => app.status === AppStatus.DEPLOYED
$: publishedApps = $apps.filter(publishedAppsOnly)
$: isCloud = $admin.cloud
$: userApps = $auth.user?.builder?.global
? publishedApps
: publishedApps.filter(app =>
Object.keys($auth.user?.roles).includes(app.prodId)
)
function getUrl(app) {
return !isCloud ? `/app/${encodeURIComponent(app.name)}` : `/${app.prodId}`
}
</script>
{#if $auth.user && loaded}
@ -93,7 +97,7 @@
<div class="group">
<Layout gap="S" noPadding>
{#each userApps as app, idx (app.appId)}
<a class="app" target="_blank" href={`/${app.prodId}`}>
<a class="app" target="_blank" href={getUrl(app)}>
<div class="preview" use:gradient={{ seed: app.name }} />
<div class="app-info">
<Heading size="XS">{app.name}</Heading>

View File

@ -47,6 +47,7 @@
$: filteredApps = enrichedApps.filter(app =>
app?.name?.toLowerCase().includes(searchTerm.toLowerCase())
)
$: isCloud = $admin.cloud
const enrichApps = (apps, user, sortBy) => {
const enrichedApps = apps.map(app => ({
@ -158,8 +159,13 @@
}
const viewApp = app => {
const id = app.deployed ? app.prodId : app.devId
window.open(`/${id}`, "_blank")
if (!isCloud && app.deployed) {
// special case to use the short form name if self hosted
window.open(`/app/${encodeURIComponent(app.name)}`)
} else {
const id = app.deployed ? app.prodId : app.devId
window.open(`/${id}`, "_blank")
}
}
const editApp = app => {

View File

@ -1,18 +1,29 @@
const { getAllApps } = require("@budibase/auth/db")
const {
getAllApps,
getDeployedAppID,
isProdAppID,
} = require("@budibase/auth/db")
const CouchDB = require("../../db")
const URL_REGEX_SLASH = /\/|\\/g
exports.getApps = async ctx => {
const apps = await getAllApps(CouchDB, { dev: true })
const apps = await getAllApps(CouchDB, { all: true })
const body = {}
for (let app of apps) {
let url = app.url || encodeURI(`${app.name}`)
url = `/${url.replace(URL_REGEX_SLASH, "")}`
body[url] = {
appId: app.appId,
name: app.name,
url,
const appId = app.appId,
isProd = isProdAppID(app.appId)
if (!body[url]) {
body[url] = {
appId: getDeployedAppID(appId),
name: app.name,
url,
deployed: isProd,
}
} else {
body[url].deployed = isProd || body[url].deployed
}
}
ctx.body = body