overview card updates

This commit is contained in:
Peter Clement 2022-07-14 08:39:39 +01:00
parent f980d55af3
commit 545f3d62b7
5 changed files with 134 additions and 83 deletions

View File

@ -148,28 +148,6 @@ export function getTemplateParams(
}
}
/**
* Generates a new user group ID
* @returns {string} The new user group ID which info can be stored under.
*/
exports.generateUserGroupID = () => {
return `${DocumentTypes.GROUP}${SEPARATOR}${newid()}`
}
/**
* Gets parameters for retrieving groups.
*/
exports.getUserGroupsParams = (groupId: any, otherProps = {}) => {
if (!groupId) {
groupId = ""
}
return {
...otherProps,
startkey: `${DocumentTypes.GROUP}${SEPARATOR}${groupId}`,
endkey: `${DocumentTypes.GROUP}${SEPARATOR}${groupId}${UNICODE_MAX}`,
}
}
/**
* Generates a new role ID.
* @returns {string} The new role ID which the role doc can be stored under.

View File

@ -23,10 +23,13 @@
let assignmentModal
let appGroups = []
let appUsers = []
let prevSearch = undefined,
search = undefined
let pageInfo = createPaginationStore()
$: page = $pageInfo.page
$: fetchUsers(page)
$: console.log(page)
$: fetchUsers(page, search)
$: isProPlan = $auth.user?.license.plan.type === Constants.PlanType.FREE
@ -43,19 +46,6 @@
})
})
$: filteredUsers =
$users.data?.filter(x => {
return !Object.keys(x.roles).find(y => {
return extractAppId(y) === extractAppId(app.appId)
})
}) || []
$: filteredGroups = $groups.filter(element => {
return !element.apps.find(y => {
return y.appId === app.appId
})
})
function extractAppId(id) {
const split = id?.split("_") || []
return split.length ? split[split.length - 1] : null
@ -99,10 +89,16 @@
groups.actions.save(group)
}
async function fetchUsers(page) {
async function fetchUsers(page, search) {
if ($pageInfo.loading) {
return
}
// need to remove the page if they've started searching
if (search && !prevSearch) {
pageInfo.reset()
page = undefined
}
prevSearch = search
try {
pageInfo.loading()
await users.search({ page, appId: app.appId })
@ -136,7 +132,7 @@
>
</div>
</div>
{#if isProPlan}
{#if isProPlan && appGroups.length}
<List title="User Groups">
{#each appGroups as group}
<ListItem
@ -154,31 +150,33 @@
{/each}
</List>
{/if}
<List title="Users">
{#each appUsers as user}
<ListItem title={user.email} avatar>
<RoleSelect
on:change={e => updateUserRole(e.detail, user)}
autoWidth
quiet
value={user.roles[
Object.keys(user.roles).find(
x => extractAppId(x) === extractAppId(app.appId)
)
]}
/>
</ListItem>
{/each}
</List>
<div class="pagination">
<Pagination
page={$pageInfo.pageNumber}
hasPrevPage={$pageInfo.loading ? false : $pageInfo.hasPrevPage}
hasNextPage={$pageInfo.loading ? false : $pageInfo.hasNextPage}
goToPrevPage={pageInfo.prevPage}
goToNextPage={pageInfo.nextPage}
/>
</div>
{#if appUsers.length}
<List title="Users">
{#each appUsers as user}
<ListItem title={user.email} avatar>
<RoleSelect
on:change={e => updateUserRole(e.detail, user)}
autoWidth
quiet
value={user.roles[
Object.keys(user.roles).find(
x => extractAppId(x) === extractAppId(app.appId)
)
]}
/>
</ListItem>
{/each}
</List>
<div class="pagination">
<Pagination
page={$pageInfo.pageNumber}
hasPrevPage={$pageInfo.loading ? false : $pageInfo.hasPrevPage}
hasNextPage={$pageInfo.loading ? false : $pageInfo.hasNextPage}
goToPrevPage={pageInfo.prevPage}
goToNextPage={pageInfo.nextPage}
/>
</div>
{/if}
{:else}
<div class="align">
<Layout gap="S">
@ -200,11 +198,7 @@
</div>
<Modal bind:this={assignmentModal}>
<AssignmentModal
userData={filteredUsers.length ? filteredUsers : $users.data}
groups={isProPlan ? filteredGroups : []}
{addData}
/>
<AssignmentModal {app} {appUsers} {addData} />
</Modal>
<style>

View File

@ -1,16 +1,54 @@
<script>
import { ModalContent, PickerDropdown, ActionButton } from "@budibase/bbui"
import {
ModalContent,
PickerDropdown,
ActionButton,
notifications,
} from "@budibase/bbui"
import { roles } from "stores/backend"
import { groups, users } from "stores/portal"
import { RoleUtils } from "@budibase/frontend-core"
import { createPaginationStore } from "helpers/pagination"
export let app
export let addData
export let userData = []
export let groups = []
export let appUsers = []
let prevSearch = undefined,
search = undefined
let pageInfo = createPaginationStore()
$: page = $pageInfo.page
$: fetchUsers(page, search)
async function fetchUsers(page, search) {
if ($pageInfo.loading) {
return
}
// need to remove the page if they've started searching
if (search && !prevSearch) {
pageInfo.reset()
page = undefined
}
prevSearch = search
try {
pageInfo.loading()
await users.search({ page, search })
pageInfo.fetched($users.hasNextPage, $users.nextPage)
} catch (error) {
notifications.error("Error getting user list")
}
}
$: filteredGroups = $groups.filter(element => {
return !element.apps.find(y => {
return y.appId === app.appId
})
})
$: optionSections = {
...(groups.length && {
...(filteredGroups.length && {
groups: {
data: groups,
data: filteredGroups,
getLabel: group => group.name,
getValue: group => group._id,
getIcon: group => group.icon,
@ -18,7 +56,7 @@
},
}),
users: {
data: userData,
data: $users.data.filter(u => !appUsers.find(x => x._id === u._id)),
getLabel: user => user.email,
getValue: user => user._id,
getIcon: user => user.icon,

View File

@ -1,16 +1,17 @@
<script>
import DashCard from "components/common/DashCard.svelte"
import { AppStatus } from "constants"
import { Icon, Heading, Link, Avatar, Layout } from "@budibase/bbui"
import { Icon, Heading, Link, Avatar, Layout, Body } from "@budibase/bbui"
import { store } from "builderStore"
import clientPackage from "@budibase/client/package.json"
import { processStringSync } from "@budibase/string-templates"
import { users, auth } from "stores/portal"
import { createEventDispatcher } from "svelte"
import { createEventDispatcher, onMount } from "svelte"
export let app
export let deployments
export let navigateTab
const dispatch = createEventDispatcher()
const unpublishApp = () => {
@ -18,7 +19,7 @@
}
let appEditor, appEditorPromise
$: console.log($users.data)
$: updateAvailable = clientPackage.version !== $store.version
$: isPublished = app && app?.status === AppStatus.DEPLOYED
$: appEditorId = !app?.updatedBy ? $auth.user._id : app?.updatedBy
@ -37,6 +38,10 @@
return initials == "" ? user.email[0] : initials
}
onMount(async () => {
await users.search({ page: undefined, appId: app.appId })
})
</script>
<div class="overview-tab">
@ -132,6 +137,37 @@
{/if}
</div>
</DashCard>
<DashCard
title={"Access"}
showIcon={true}
action={() => {
navigateTab("Access")
}}
dataCy={"access"}
>
<div class="last-edited-content">
{#if $users?.data?.length}
<Layout noPadding gap="S">
<div class="users-tab">
{#each $users?.data as user}
<Avatar size="M" initials={getInitials(user)} />
{/each}
</div>
<div class="users-text">
{$users?.data.length} users have access to this app
</div>
</Layout>
{:else}
<Layout noPadding gap="S">
<Body>No users</Body>
<div class="users-text">
No users have been assigned to this app
</div>
</Layout>
{/if}
</div>
</DashCard>
</div>
{#if false}
<div class="bottom">
@ -186,6 +222,14 @@
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
}
.users-tab {
display: flex;
gap: var(--spacing-m);
}
.users-text {
color: var(--spectrum-global-color-gray-600);
}
.overview-tab .bottom,
.automation-metrics {
display: grid;

View File

@ -1,7 +1,3 @@
const {
generateUserGroupID,
getUserGroupsParams,
} = require("@budibase/backend-core/db")
const { Configs } = require("../../../constants")
const email = require("../../../utilities/email")
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
@ -11,13 +7,14 @@ const {
CacheKeys,
bustCache,
} = require("@budibase/backend-core/cache")
const { groups } = require("@budibase/pro")
exports.save = async function (ctx: any) {
const db = getGlobalDB()
// Config does not exist yet
if (!ctx.request.body._id) {
ctx.request.body._id = generateUserGroupID(ctx.request.body.name)
ctx.request.body._id = groups.generateUserGroupID(ctx.request.body.name)
}
try {
@ -34,7 +31,7 @@ exports.save = async function (ctx: any) {
exports.fetch = async function (ctx: any) {
const db = getGlobalDB()
const response = await db.allDocs(
getUserGroupsParams(null, {
groups.getUserGroupsParams(null, {
include_docs: true,
})
)