Merge pull request #7981 from Budibase/feature/group-app-add

Add apps to a group from within groups interface
This commit is contained in:
Michael Drury 2022-09-26 19:18:44 +01:00 committed by GitHub
commit 190c54fb86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 108 additions and 12 deletions

View File

@ -36,6 +36,7 @@ exports.getDevelopmentAppID = appId => {
const rest = split.join(APP_PREFIX)
return `${APP_DEV_PREFIX}${rest}`
}
exports.getDevAppID = exports.getDevelopmentAppID
/**
* Convert a development app ID to a deployed app ID.

View File

@ -56,7 +56,7 @@
{
title: "Plugins",
href: "/builder/portal/manage/plugins",
badge: "Beta",
badge: "New",
},
{

View File

@ -25,6 +25,7 @@
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import CreateEditGroupModal from "./_components/CreateEditGroupModal.svelte"
import GroupIcon from "./_components/GroupIcon.svelte"
import AppAddModal from "./_components/AppAddModal.svelte"
export let groupId
@ -34,8 +35,7 @@
let prevSearch = undefined
let pageInfo = createPaginationStore()
let loaded = false
let editModal
let deleteModal
let editModal, deleteModal, appAddModal
$: page = $pageInfo.page
$: fetchUsers(page, searchTerm)
@ -182,7 +182,14 @@
</Layout>
<Layout noPadding gap="S">
<Heading size="S">Apps</Heading>
<div class="header">
<Heading size="S">Apps</Heading>
<div>
<Button on:click={appAddModal.show()} icon="ExperienceAdd" cta>
Add app
</Button>
</div>
</div>
<List>
{#if groupApps.length}
{#each groupApps as app}
@ -203,6 +210,18 @@
{getRoleLabel(app.appId)}
</StatusLight>
</div>
<Icon
on:click={e => {
groups.actions.removeApp(
groupId,
apps.getProdAppID(app.appId)
)
e.stopPropagation()
}}
hoverable
size="S"
name="Close"
/>
</ListItem>
{/each}
{:else}
@ -216,6 +235,11 @@
<Modal bind:this={editModal}>
<CreateEditGroupModal {group} {saveGroup} />
</Modal>
<Modal bind:this={appAddModal}>
<AppAddModal {group} />
</Modal>
<ConfirmDialog
bind:this={deleteModal}
title="Delete user group"

View File

@ -0,0 +1,53 @@
<script>
import { Body, ModalContent, Select } from "@budibase/bbui"
import { apps, groups } from "stores/portal"
import { roles } from "stores/backend"
import RoleSelect from "components/common/RoleSelect.svelte"
export let group
$: appOptions = $apps.map(app => ({
label: app.name,
value: app,
}))
$: prodAppId = selectedApp ? apps.getProdAppID(selectedApp.appId) : ""
$: confirmDisabled =
(!selectingRole && !selectedApp) || (selectingRole && !selectedRoleId)
let selectedApp, selectedRoleId
let selectingRole = false
async function appSelected() {
if (!selectingRole) {
selectingRole = true
await roles.fetchByAppId(prodAppId)
// return false to stop closing modal
return false
} else {
await groups.actions.addApp(group._id, prodAppId, selectedRoleId)
}
}
</script>
<ModalContent
onConfirm={appSelected}
size="M"
title="Add app to group"
confirmText={selectingRole ? "Confirm" : "Next"}
showSecondaryButton={selectingRole}
secondaryButtonText="Back"
secondaryAction={() => (selectingRole = false)}
disabled={confirmDisabled}
>
{#if !selectingRole}
<Body
>Select an app to assign roles for members of <i>"{group.name}"</i></Body
>
<Select bind:value={selectedApp} options={appOptions} />
{:else}
<Body
>Select the role that all members of "<i>{group.name}</i>" will have for
<i>"{selectedApp.name}"</i></Body
>
<RoleSelect allowPublic={false} bind:value={selectedRoleId} />
{/if}
</ModalContent>

View File

@ -5,16 +5,24 @@ import { RoleUtils } from "@budibase/frontend-core"
export function createRolesStore() {
const { subscribe, update, set } = writable([])
function setRoles(roles) {
set(
roles.sort((a, b) => {
const priorityA = RoleUtils.getRolePriority(a._id)
const priorityB = RoleUtils.getRolePriority(b._id)
return priorityA > priorityB ? -1 : 1
})
)
}
const actions = {
fetch: async () => {
const roles = await API.getRoles()
set(
roles.sort((a, b) => {
const priorityA = RoleUtils.getRolePriority(a._id)
const priorityB = RoleUtils.getRolePriority(b._id)
return priorityA > priorityB ? -1 : 1
})
)
setRoles(roles)
},
fetchByAppId: async appId => {
const { roles } = await API.getRolesForApp(appId)
setRoles(roles)
},
delete: async role => {
await API.deleteRole({

View File

@ -29,4 +29,13 @@ export const buildRoleEndpoints = API => ({
url: "/api/roles",
})
},
/**
* Gets a list of roles within a specified app.
*/
getRolesForApp: async appId => {
return await API.get({
url: `/api/global/roles/${appId}`,
})
},
})

View File

@ -2,6 +2,7 @@ const { getAllRoles } = require("@budibase/backend-core/roles")
const {
getAllApps,
getProdAppID,
getDevAppID,
DocumentType,
} = require("@budibase/backend-core/db")
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
@ -34,7 +35,7 @@ exports.fetch = async ctx => {
exports.find = async ctx => {
const appId = ctx.params.appId
await doInAppContext(appId, async () => {
await doInAppContext(getDevAppID(appId), async () => {
const db = getAppDB()
const app = await db.get(DocumentType.APP_METADATA)
ctx.body = {