-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'v3-ui' into queryui-default
- Loading branch information
Showing
74 changed files
with
1,908 additions
and
718 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 0 additions & 15 deletions
15
packages/builder/src/components/backend/DataTable/buttons/EditRolesButton.svelte
This file was deleted.
Oops, something went wrong.
192 changes: 178 additions & 14 deletions
192
packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,195 @@ | ||
<script> | ||
import { ActionButton } from "@budibase/bbui" | ||
import { permissions } from "stores/builder" | ||
import ManageAccessModal from "../modals/ManageAccessModal.svelte" | ||
import { | ||
ActionButton, | ||
Input, | ||
Select, | ||
Label, | ||
List, | ||
ListItem, | ||
notifications, | ||
} from "@budibase/bbui" | ||
import { permissions as permissionsStore, roles } from "stores/builder" | ||
import DetailPopover from "components/common/DetailPopover.svelte" | ||
import EditRolesButton from "./EditRolesButton.svelte" | ||
import { PermissionSource } from "@budibase/types" | ||
import { capitalise } from "helpers" | ||
import InfoDisplay from "pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/InfoDisplay.svelte" | ||
import { Roles } from "constants/backend" | ||
export let resourceId | ||
let resourcePermissions | ||
const inheritedRoleId = "inherited" | ||
const builtins = [Roles.ADMIN, Roles.POWER, Roles.BASIC, Roles.PUBLIC] | ||
let permissions | ||
let showPopover = true | ||
let dependantsInfoMessage | ||
$: fetchPermissions(resourceId) | ||
$: loadDependantInfo(resourceId) | ||
$: roleMismatch = checkRoleMismatch(permissions) | ||
$: selectedRole = roleMismatch ? null : permissions?.[0]?.value | ||
$: readableRole = selectedRole | ||
? $roles.find(x => x._id === selectedRole)?.uiMetadata.displayName | ||
: null | ||
$: buttonLabel = readableRole ? `Access: ${readableRole}` : "Access" | ||
$: highlight = roleMismatch || selectedRole === Roles.PUBLIC | ||
$: builtInRoles = builtins.map(roleId => $roles.find(x => x._id === roleId)) | ||
$: customRoles = $roles | ||
.filter(x => !builtins.includes(x._id)) | ||
.slice() | ||
.toSorted((a, b) => { | ||
const aName = a.uiMetadata.displayName || a.name | ||
const bName = b.uiMetadata.displayName || b.name | ||
return aName < bName ? -1 : 1 | ||
}) | ||
const fetchPermissions = async id => { | ||
resourcePermissions = await permissions.forResourceDetailed(id) | ||
const res = await permissionsStore.forResourceDetailed(id) | ||
permissions = Object.entries(res?.permissions || {}).map(([perm, info]) => { | ||
let enriched = { | ||
permission: perm, | ||
value: | ||
info.permissionType === PermissionSource.INHERITED | ||
? inheritedRoleId | ||
: info.role, | ||
options: [...$roles], | ||
} | ||
if (info.inheritablePermission) { | ||
enriched.options.unshift({ | ||
_id: inheritedRoleId, | ||
name: `Inherit (${ | ||
$roles.find(x => x._id === info.inheritablePermission).name | ||
})`, | ||
}) | ||
} | ||
return enriched | ||
}) | ||
} | ||
const checkRoleMismatch = permissions => { | ||
if (!permissions || permissions.length < 2) { | ||
return false | ||
} | ||
return ( | ||
permissions[0].value !== permissions[1].value || | ||
permissions[0].value === inheritedRoleId | ||
) | ||
} | ||
const loadDependantInfo = async resourceId => { | ||
const dependantsInfo = await permissionsStore.getDependantsInfo(resourceId) | ||
const resourceByType = dependantsInfo?.resourceByType | ||
if (resourceByType) { | ||
const total = Object.values(resourceByType).reduce((p, c) => p + c, 0) | ||
let resourceDisplay = | ||
Object.keys(resourceByType).length === 1 && resourceByType.view | ||
? "view" | ||
: "resource" | ||
if (total === 1) { | ||
dependantsInfoMessage = `1 ${resourceDisplay} is inheriting this access` | ||
} else if (total > 1) { | ||
dependantsInfoMessage = `${total} ${resourceDisplay}s are inheriting this access` | ||
} else { | ||
dependantsInfoMessage = null | ||
} | ||
} else { | ||
dependantsInfoMessage = null | ||
} | ||
} | ||
const changePermission = async role => { | ||
try { | ||
await permissionsStore.save({ | ||
level: "read", | ||
role, | ||
resource: resourceId, | ||
}) | ||
await permissionsStore.save({ | ||
level: "write", | ||
role, | ||
resource: resourceId, | ||
}) | ||
await fetchPermissions(resourceId) | ||
notifications.success("Updated permissions") | ||
} catch (error) { | ||
console.error(error) | ||
notifications.error("Error updating permissions") | ||
} | ||
} | ||
</script> | ||
<DetailPopover title="Manage access" {showPopover}> | ||
<DetailPopover title="Select access role" {showPopover}> | ||
<svelte:fragment slot="anchor" let:open> | ||
<ActionButton icon="LockClosed" selected={open} quiet>Access</ActionButton> | ||
<ActionButton | ||
icon="LockClosed" | ||
selected={open || highlight} | ||
quiet | ||
accentColor={highlight ? "#ff0000" : null} | ||
> | ||
{buttonLabel} | ||
</ActionButton> | ||
</svelte:fragment> | ||
{#if resourcePermissions} | ||
<ManageAccessModal {resourceId} permissions={resourcePermissions} /> | ||
{#if roleMismatch} | ||
<div class="row"> | ||
<Label extraSmall grey>Level</Label> | ||
<Label extraSmall grey>Role</Label> | ||
{#each permissions as permission} | ||
<Input value={capitalise(permission.permission)} disabled /> | ||
<Select | ||
placeholder={false} | ||
value={permission.value} | ||
on:change={e => changePermission(e.detail)} | ||
disabled | ||
options={permission.options} | ||
getOptionLabel={x => x.name} | ||
getOptionValue={x => x._id} | ||
/> | ||
{/each} | ||
</div> | ||
<InfoDisplay | ||
error | ||
icon="Alert" | ||
body="Your previous configuration is shown above.<br/> Please choose a single role for read and write access." | ||
/> | ||
{/if} | ||
<List> | ||
{#each builtInRoles as role} | ||
<ListItem | ||
title={role.uiMetadata.displayName} | ||
subtitle={role.uiMetadata.description} | ||
hoverable | ||
selected={selectedRole === role._id} | ||
icon="StatusLight" | ||
iconColor={role.uiMetadata.color} | ||
on:click={() => changePermission(role._id)} | ||
/> | ||
{/each} | ||
{#each customRoles as role} | ||
<ListItem | ||
title={role.uiMetadata.displayName} | ||
subtitle={role.uiMetadata.description} | ||
hoverable | ||
selected={selectedRole === role._id} | ||
icon="StatusLight" | ||
iconColor={role.uiMetadata.color} | ||
on:click={() => changePermission(role._id)} | ||
/> | ||
{/each} | ||
</List> | ||
{#if dependantsInfoMessage} | ||
<InfoDisplay info body={dependantsInfoMessage} /> | ||
{/if} | ||
<EditRolesButton | ||
on:show={() => (showPopover = false)} | ||
on:hide={() => (showPopover = true)} | ||
/> | ||
</DetailPopover> | ||
<style> | ||
.row { | ||
display: grid; | ||
grid-template-columns: 1fr 1fr; | ||
grid-gap: var(--spacing-s); | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.