diff --git a/packages/bbui/src/Form/Core/InputDropdown.svelte b/packages/bbui/src/Form/Core/InputDropdown.svelte index c9ca70dff9..be43676bb9 100644 --- a/packages/bbui/src/Form/Core/InputDropdown.svelte +++ b/packages/bbui/src/Form/Core/InputDropdown.svelte @@ -5,6 +5,7 @@ import { fly } from "svelte/transition" import { createEventDispatcher } from "svelte" import clickOutside from "../../Actions/click_outside" + import StatusLight from "../../StatusLight/StatusLight.svelte" export let inputValue export let dropdownValue @@ -18,6 +19,8 @@ export let options = [] export let getOptionLabel = option => extractProperty(option, "label") export let getOptionValue = option => extractProperty(option, "value") + export let getOptionColour = option => extractProperty(option, "colour") + export let isOptionSelected = () => false const dispatch = createEventDispatcher() diff --git a/packages/bbui/src/Form/Core/Select.svelte b/packages/bbui/src/Form/Core/Select.svelte index 81d7ec8e6c..f549f58d0c 100644 --- a/packages/bbui/src/Form/Core/Select.svelte +++ b/packages/bbui/src/Form/Core/Select.svelte @@ -17,7 +17,6 @@ export let autoWidth = false export let autocomplete = false export let sort = false - const dispatch = createEventDispatcher() let open = false $: fieldText = getFieldText(value, options, placeholder) diff --git a/packages/bbui/src/IconPicker/IconPicker.svelte b/packages/bbui/src/IconPicker/IconPicker.svelte index 0b96cbe4c9..0e71be2c33 100644 --- a/packages/bbui/src/IconPicker/IconPicker.svelte +++ b/packages/bbui/src/IconPicker/IconPicker.svelte @@ -6,7 +6,7 @@ import Icon from "../Icon/Icon.svelte" import { createEventDispatcher } from "svelte" - export let value = "Anchor" + export let value export let size = "M" export let alignRight = false @@ -59,7 +59,7 @@ style={value ? `background: ${value};` : ""} class:placeholder={!value} > - + {#if open} diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 6a4373df92..21af5a16db 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -24,6 +24,7 @@ export { default as Toggle } from "./Form/Toggle.svelte" export { default as RadioGroup } from "./Form/RadioGroup.svelte" export { default as Checkbox } from "./Form/Checkbox.svelte" export { default as InputDropdown } from "./Form/InputDropdown.svelte" +export { default as PickerDropdown } from "./Form/PickerDropdown.svelte" export { default as DetailSummary } from "./DetailSummary/DetailSummary.svelte" export { default as Popover } from "./Popover/Popover.svelte" export { default as ProgressBar } from "./ProgressBar/ProgressBar.svelte" diff --git a/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte b/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte index 08610e0e23..9c6cd6241f 100644 --- a/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte +++ b/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte @@ -22,23 +22,15 @@ export let groupId let popoverAnchor let popover - $: group = $groups.find(x => x._id === groupId) let searchTerm = "" let selectedUsers = [] + $: group = $groups.find(x => x._id === groupId) $: filteredUsers = $users.filter( user => selectedUsers && user?.email?.toLowerCase().includes(searchTerm.toLowerCase()) ) - let app_list = [ - { - access: "ADMIN", - name: "test app", - icon: "Anchor", - color: "blue", - }, - ] - + $: console.log(group) async function addAll() { selectedUsers = [...selectedUsers, ...filteredUsers] group.users = selectedUsers @@ -138,9 +130,13 @@ - {#if app_list.length} - {#each app_list as app} - + {#if group?.apps} + {#each group.apps as app} +
diff --git a/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte b/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte index 5988601a2a..478608f2d4 100644 --- a/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte +++ b/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte @@ -45,7 +45,7 @@
- {parseInt(group.appCount) || 0} app{parseInt(group.appCount) === 1 + {parseInt(group?.apps?.length) || 0} app{parseInt(group?.apps?.length) === 1 ? "" : "s"}
diff --git a/packages/builder/src/pages/builder/portal/manage/groups/index.svelte b/packages/builder/src/pages/builder/portal/manage/groups/index.svelte index 2a8c1b973f..6841be9e61 100644 --- a/packages/builder/src/pages/builder/portal/manage/groups/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/groups/index.svelte @@ -21,6 +21,7 @@ icon: "", color: "", users: [], + apps: [], } let proPlan = true @@ -82,13 +83,15 @@ {/if}
-
- {#each $groups as group} -
- -
- {/each} -
+ {#if proPlan} +
+ {#each $groups as group} +
+ +
+ {/each} +
+ {/if} diff --git a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte index f095cf8a90..690ac71409 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte @@ -24,7 +24,8 @@ import { onMount } from "svelte" import { fetchData } from "helpers" - import { users, auth, groups } from "stores/portal" + import { users, auth, groups, apps } from "stores/portal" + import { roles } from "stores/backend" import { Constants } from "@budibase/frontend-core" import ForceResetPasswordModal from "./_components/ForceResetPasswordModal.svelte" @@ -38,19 +39,28 @@ let searchTerm = "" let popover let selectedGroups = [] - $: defaultRoleId = $userFetch?.data?.builder?.global ? "ADMIN" : "" - - // Merge the Apps list and the roles response to get something that makes sense for the table - $: allAppList = Object.keys($apps?.data).map(id => { - const roleId = $userFetch?.data?.roles?.[id] || defaultRoleId - const role = $apps?.data?.[id].roles.find(role => role._id === roleId) - return { - ...$apps?.data?.[id], - _id: id, - role: [role], - } - }) + let allAppList = [] + $: console.log($apps) + $: console.log($userFetch.data) + $: allAppList = $apps + .filter(x => { + if ($userFetch.data?.roles) { + return Object.keys($userFetch.data.roles).find(y => { + return x.appId === y + }) + } + }) + .map(app => { + let roles = Object.keys($userFetch.data.roles).filter(id => { + return id === app.appId + }) + return { + ...app, + roles, + } + }) + $: console.log(allAppList) // Used for searching through groups in the add group popover $: filteredGroups = $groups.filter( group => @@ -58,16 +68,13 @@ group?.name?.toLowerCase().includes(searchTerm.toLowerCase()) ) - $: appList = allAppList.filter(app => !!app.role[0]) - $: userGroups = $groups.filter(x => { - return x.users?.some(y => { + return x.users?.find(y => { return y._id === userId }) }) const userFetch = fetchData(`/api/global/users/${userId}`) - const apps = fetchData(`/api/global/roles`) async function deleteUser() { try { await users.delete(userId) @@ -166,6 +173,7 @@ onMount(async () => { try { await groups.actions.init() + await apps.load() } catch (error) { notifications.error("Error getting User groups") } @@ -243,9 +251,7 @@
User groups - Manage apps that this User group has been assigned to + Add or remove this user from user groups
- {#if appList.length} - {#each appList as app} - -
- -
- {getHighestRole(app.role).name} + {#if allAppList.length} + {#each allAppList as app} +
+ +
+ +
+ d +
-
- + +
{/each} {:else} diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte index 3ff1b3df0c..a475ea01c1 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte @@ -5,39 +5,33 @@ Label, ModalContent, Multiselect, - notifications, InputDropdown, } from "@budibase/bbui" - import { users, groups } from "stores/portal" - import analytics, { Events } from "analytics" + import { createEventDispatcher } from "svelte" + import { groups } from "stores/portal" import { Constants } from "@budibase/frontend-core" export let disabled export let showOnboardingTypeModal - const options = ["Email onboarding", "Basic onboarding"] - let selected = options[0] - let builder, admin - $: userData = [{ email: "", role: "", error: null }] + const dispatch = createEventDispatcher() + + $: userData = [{ email: "", role: "", groups: [], error: null }] - /* - async function createUserFlow() { - try { - const res = await users.invite({ email: "", builder, admin }) - notifications.success(res.message) - analytics.captureEvent(Events.USER.INVITE, { type: selected }) - } catch (error) { - notifications.error("Error inviting user") - } - } - */ function addNewInput() { userData = [...userData, { email: "", role: "" }] } + + function setValue(e) { + userData.groups = e.detail + } { + showOnboardingTypeModal() + dispatch("change", userData) + }} size="M" title="Add new user" confirmText="Add user" @@ -64,6 +58,7 @@ setValue(e)} label="User Groups" options={$groups} getOptionLabel={option => option.name} diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/ImportUsersModal.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/ImportUsersModal.svelte index 24db91500d..b9b4f91af8 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/_components/ImportUsersModal.svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/_components/ImportUsersModal.svelte @@ -1,8 +1,44 @@ Import your users email addrresses from a CSV -
-
- Upload -
+
+ +
@@ -49,4 +88,51 @@ justify-content: center; align-items: center; } + + .error { + color: var(--red); + } + + .dropzone { + text-align: center; + display: flex; + align-items: center; + flex-direction: column; + border-radius: 10px; + transition: all 0.3s; + } + .uploaded { + color: var(--blue); + } + + label { + font-family: var(--font-sans); + cursor: pointer; + font-weight: 600; + box-sizing: border-box; + overflow: hidden; + border-radius: var(--border-radius-s); + color: var(--ink); + padding: var(--spacing-m) var(--spacing-l); + transition: all 0.2s ease 0s; + display: inline-flex; + text-rendering: optimizeLegibility; + min-width: auto; + outline: none; + font-feature-settings: "case" 1, "rlig" 1, "calt" 0; + -webkit-box-align: center; + user-select: none; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 100%; + background-color: var(--grey-2); + font-size: var(--font-size-xs); + line-height: normal; + border: var(--border-transparent); + } + + input[type="file"] { + display: none; + } diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/OnboardingTypeModal.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/OnboardingTypeModal.svelte index 089721348e..7ec6d338d5 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/_components/OnboardingTypeModal.svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/_components/OnboardingTypeModal.svelte @@ -1,6 +1,7 @@
@@ -11,31 +80,44 @@ Assign users to your app and define their access here - +
- - - - - - + {#each appGroups as group} + + + + {/each} - - - - - - - - - + {#each appUsers as user} + + extractAppId(x) === extractAppId(app.appId) + ) + ]} + /> + + {/each}
+ + + +