@@ -74,21 +80,35 @@
{app.deployed ? "Published" : "Unpublished"}
- {#if isBuilder}
+
-
- Manage
-
-
- Edit
-
+ {#if isBuilder}
+
+
+ Edit
+
+
+
+
{
+ actionsOpen = true
+ }}
+ on:close={() => {
+ actionsOpen = false
+ }}
+ />
+
+ {:else}
+
+
View
+ {/if}
- {:else if app.deployed}
-
-
diff --git a/packages/builder/src/components/start/ExportAppModal.svelte b/packages/builder/src/components/start/ExportAppModal.svelte
index 734e4448a1..ec0cf42fe0 100644
--- a/packages/builder/src/components/start/ExportAppModal.svelte
+++ b/packages/builder/src/components/start/ExportAppModal.svelte
@@ -121,6 +121,7 @@
{
- const applications = svelteGet(apps)
+ const applications = svelteGet(appsStore).apps
appValidation.name(validation, {
apps: applications,
currentApp: {
@@ -62,7 +62,7 @@
async function updateApp() {
try {
- await apps.update(app.appId, {
+ await appsStore.save(app.appId, {
name: $values.name?.trim(),
url: $values.url?.trim(),
icon: {
diff --git a/packages/builder/src/global.css b/packages/builder/src/global.css
index bc1f55d9d3..adf4a47070 100644
--- a/packages/builder/src/global.css
+++ b/packages/builder/src/global.css
@@ -22,6 +22,7 @@ body {
--grey-7: var(--spectrum-global-color-gray-700);
--grey-8: var(--spectrum-global-color-gray-800);
--grey-9: var(--spectrum-global-color-gray-900);
+ --spectrum-global-color-yellow-1000: #d8b500;
color: var(--ink);
background-color: var(--background-alt);
diff --git a/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte b/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte
index 7c1cc583e1..d714bafc70 100644
--- a/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte
@@ -15,7 +15,14 @@
FancySelect,
} from "@budibase/bbui"
import { builderStore, appStore, roles } from "stores/builder"
- import { groups, licensing, apps, users, auth, admin } from "stores/portal"
+ import {
+ groups,
+ licensing,
+ appsStore,
+ users,
+ auth,
+ admin,
+ } from "stores/portal"
import {
fetchData,
Constants,
@@ -54,7 +61,7 @@
let inviteFailureResponse = ""
$: validEmail = emailValidator(email) === true
- $: prodAppId = apps.getProdAppID($appStore.appId)
+ $: prodAppId = appsStore.getProdAppID($appStore.appId)
$: promptInvite = showInvite(
filteredInvites,
filteredUsers,
diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte
index 45b10d3d9e..fd6a97560d 100644
--- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte
@@ -8,7 +8,7 @@
userStore,
deploymentStore,
} from "stores/builder"
- import { auth, apps } from "stores/portal"
+ import { auth, appsStore } from "stores/portal"
import { TENANT_FEATURE_FLAGS, isEnabled } from "helpers/featureFlags"
import {
Icon,
@@ -52,7 +52,7 @@
const pkg = await API.fetchAppPackage(application)
await initialise(pkg)
- await apps.load()
+ await appsStore.load()
await deploymentStore.load()
loaded = true
diff --git a/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
index da4f743f04..67befddcb9 100644
--- a/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
@@ -3,7 +3,7 @@
import { Page, Layout, AbsTooltip, TooltipPosition } from "@budibase/bbui"
import { url, isActive } from "@roxi/routify"
import DeleteModal from "components/deploy/DeleteModal.svelte"
- import { isOnlyUser } from "stores/builder"
+ import { isOnlyUser, appStore } from "stores/builder"
let deleteModal
@@ -67,7 +67,11 @@
diff --git a/packages/builder/src/pages/builder/portal/apps/_layout.svelte b/packages/builder/src/pages/builder/portal/apps/_layout.svelte
index 8810edca9c..00719dc6d5 100644
--- a/packages/builder/src/pages/builder/portal/apps/_layout.svelte
+++ b/packages/builder/src/pages/builder/portal/apps/_layout.svelte
@@ -2,7 +2,7 @@
import { notifications } from "@budibase/bbui"
import {
admin,
- apps,
+ appsStore,
templates,
licensing,
groups,
@@ -14,7 +14,7 @@
import PortalSideBar from "./_components/PortalSideBar.svelte"
// Don't block loading if we've already hydrated state
- let loaded = !!$apps?.length
+ let loaded = !!$appsStore.apps?.length
onMount(async () => {
try {
@@ -34,7 +34,10 @@
}
// Go to new app page if no apps exists
- if (!$apps.length && sdk.users.hasBuilderPermissions($auth.user)) {
+ if (
+ !$appsStore.apps.length &&
+ sdk.users.hasBuilderPermissions($auth.user)
+ ) {
$redirect("./onboarding")
}
} catch (error) {
@@ -46,7 +49,7 @@
{#if loaded}
- {#if $apps.length > 0}
+ {#if $appsStore.apps.length > 0}
{/if}
diff --git a/packages/builder/src/pages/builder/portal/apps/create.svelte b/packages/builder/src/pages/builder/portal/apps/create.svelte
index 1f2c579071..1248c41cf8 100644
--- a/packages/builder/src/pages/builder/portal/apps/create.svelte
+++ b/packages/builder/src/pages/builder/portal/apps/create.svelte
@@ -5,7 +5,7 @@
import CreateAppModal from "components/start/CreateAppModal.svelte"
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
import AppLimitModal from "components/portal/licensing/AppLimitModal.svelte"
- import { apps, templates, licensing } from "stores/portal"
+ import { appsStore, templates, licensing } from "stores/portal"
import { Breadcrumbs, Breadcrumb, Header } from "components/portal/page"
let template
@@ -35,7 +35,7 @@
}
-{#if !$apps.length}
+{#if !$appsStore.apps.length}
{:else}
diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte
index a1aa242a36..adea7600a6 100644
--- a/packages/builder/src/pages/builder/portal/apps/index.svelte
+++ b/packages/builder/src/pages/builder/portal/apps/index.svelte
@@ -19,13 +19,18 @@
import { automationStore, initialise } from "stores/builder"
import { API } from "api"
import { onMount } from "svelte"
- import { apps, auth, admin, licensing, environment } from "stores/portal"
+ import {
+ appsStore,
+ auth,
+ admin,
+ licensing,
+ environment,
+ enrichedApps,
+ } from "stores/portal"
import { goto } from "@roxi/routify"
import AppRow from "components/start/AppRow.svelte"
- import { AppStatus } from "constants"
import Logo from "assets/bb-space-man.svg"
- let sortBy = "name"
let template
let creationModal
let appLimitModal
@@ -33,56 +38,27 @@
let searchTerm = ""
let creatingFromTemplate = false
let automationErrors
- let accessFilterList = null
$: welcomeHeader = `Welcome ${$auth?.user?.firstName || "back"}`
- $: enrichedApps = enrichApps($apps, $auth.user, sortBy)
- $: filteredApps = enrichedApps.filter(
- app =>
- (searchTerm
- ? app?.name?.toLowerCase().includes(searchTerm.toLowerCase())
- : true) &&
- (accessFilterList !== null
- ? accessFilterList?.includes(
- `${app?.type}_${app?.tenantId}_${app?.appId}`
- )
- : true)
- )
- $: automationErrors = getAutomationErrors(enrichedApps)
+ $: filteredApps = filterApps($enrichedApps, searchTerm)
+ $: automationErrors = getAutomationErrors(filteredApps || [])
$: isOwner = $auth.accountPortalAccess && $admin.cloud
+ const filterApps = (apps, searchTerm) => {
+ return apps?.filter(app => {
+ const query = searchTerm?.trim()?.replace(/\s/g, "")
+ if (query) {
+ return app?.name?.toLowerCase().includes(query.toLowerCase())
+ } else {
+ return true
+ }
+ })
+ }
+
const usersLimitLockAction = $licensing?.errUserLimit
? () => accountLockedModal.show()
: null
- const enrichApps = (apps, user, sortBy) => {
- const enrichedApps = apps.map(app => ({
- ...app,
- deployed: app.status === AppStatus.DEPLOYED,
- lockedYou: app.lockedBy && app.lockedBy.email === user?.email,
- lockedOther: app.lockedBy && app.lockedBy.email !== user?.email,
- }))
-
- if (sortBy === "status") {
- return enrichedApps.sort((a, b) => {
- if (a.status === b.status) {
- return a.name?.toLowerCase() < b.name?.toLowerCase() ? -1 : 1
- }
- return a.status === AppStatus.DEPLOYED ? -1 : 1
- })
- } else if (sortBy === "updated") {
- return enrichedApps.sort((a, b) => {
- const aUpdated = a.updatedAt || "9999"
- const bUpdated = b.updatedAt || "9999"
- return aUpdated < bUpdated ? 1 : -1
- })
- } else {
- return enrichedApps.sort((a, b) => {
- return a.name?.toLowerCase() < b.name?.toLowerCase() ? -1 : 1
- })
- }
- }
-
const getAutomationErrors = apps => {
const automationErrors = {}
for (let app of apps) {
@@ -117,7 +93,7 @@
const initiateAppCreation = async () => {
if ($licensing?.usageMetrics?.apps >= 100) {
appLimitModal.show()
- } else if ($apps?.length) {
+ } else if ($appsStore.apps?.length) {
$goto("/builder/portal/apps/create")
} else {
template = null
@@ -136,7 +112,7 @@
const templateKey = template.key.split("/")[1]
let appName = templateKey.replace(/-/g, " ")
- const appsWithSameName = $apps.filter(app =>
+ const appsWithSameName = $appsStore.apps.filter(app =>
app.name?.startsWith(appName)
)
appName = `${appName} ${appsWithSameName.length + 1}`
@@ -217,7 +193,7 @@
: "View error"}
on:dismiss={async () => {
await automationStore.actions.clearLogErrors({ appId })
- await apps.load()
+ await appsStore.load()
}}
message={automationErrorMessage(appId)}
/>
@@ -233,7 +209,7 @@