1
0
Fork 0
mirror of synced 2024-07-04 22:11:23 +12:00

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. * Generates a new role ID.
* @returns {string} The new role ID which the role doc can be stored under. * @returns {string} The new role ID which the role doc can be stored under.

View file

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

View file

@ -1,16 +1,54 @@
<script> <script>
import { ModalContent, PickerDropdown, ActionButton } from "@budibase/bbui" import {
ModalContent,
PickerDropdown,
ActionButton,
notifications,
} from "@budibase/bbui"
import { roles } from "stores/backend" import { roles } from "stores/backend"
import { groups, users } from "stores/portal"
import { RoleUtils } from "@budibase/frontend-core" import { RoleUtils } from "@budibase/frontend-core"
import { createPaginationStore } from "helpers/pagination"
export let app
export let addData export let addData
export let userData = [] export let appUsers = []
export let groups = []
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 = { $: optionSections = {
...(groups.length && { ...(filteredGroups.length && {
groups: { groups: {
data: groups, data: filteredGroups,
getLabel: group => group.name, getLabel: group => group.name,
getValue: group => group._id, getValue: group => group._id,
getIcon: group => group.icon, getIcon: group => group.icon,
@ -18,7 +56,7 @@
}, },
}), }),
users: { users: {
data: userData, data: $users.data.filter(u => !appUsers.find(x => x._id === u._id)),
getLabel: user => user.email, getLabel: user => user.email,
getValue: user => user._id, getValue: user => user._id,
getIcon: user => user.icon, getIcon: user => user.icon,

View file

@ -1,16 +1,17 @@
<script> <script>
import DashCard from "components/common/DashCard.svelte" import DashCard from "components/common/DashCard.svelte"
import { AppStatus } from "constants" 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 { store } from "builderStore"
import clientPackage from "@budibase/client/package.json" import clientPackage from "@budibase/client/package.json"
import { processStringSync } from "@budibase/string-templates" import { processStringSync } from "@budibase/string-templates"
import { users, auth } from "stores/portal" import { users, auth } from "stores/portal"
import { createEventDispatcher } from "svelte" import { createEventDispatcher, onMount } from "svelte"
export let app export let app
export let deployments export let deployments
export let navigateTab export let navigateTab
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const unpublishApp = () => { const unpublishApp = () => {
@ -18,7 +19,7 @@
} }
let appEditor, appEditorPromise let appEditor, appEditorPromise
$: console.log($users.data)
$: updateAvailable = clientPackage.version !== $store.version $: updateAvailable = clientPackage.version !== $store.version
$: isPublished = app && app?.status === AppStatus.DEPLOYED $: isPublished = app && app?.status === AppStatus.DEPLOYED
$: appEditorId = !app?.updatedBy ? $auth.user._id : app?.updatedBy $: appEditorId = !app?.updatedBy ? $auth.user._id : app?.updatedBy
@ -37,6 +38,10 @@
return initials == "" ? user.email[0] : initials return initials == "" ? user.email[0] : initials
} }
onMount(async () => {
await users.search({ page: undefined, appId: app.appId })
})
</script> </script>
<div class="overview-tab"> <div class="overview-tab">
@ -132,6 +137,37 @@
{/if} {/if}
</div> </div>
</DashCard> </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> </div>
{#if false} {#if false}
<div class="bottom"> <div class="bottom">
@ -186,6 +222,14 @@
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); 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, .overview-tab .bottom,
.automation-metrics { .automation-metrics {
display: grid; display: grid;

View file

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