Update handling of basic and admin edges
This commit is contained in:
parent
2099ee8baf
commit
354b5041c7
|
@ -20,7 +20,7 @@
|
|||
export let target
|
||||
|
||||
const flow = useSvelteFlow()
|
||||
const { updateRole, selectedNodes } = getContext("flow")
|
||||
const { deleteEdge, selectedNodes } = getContext("flow")
|
||||
|
||||
let iconHovered = false
|
||||
let edgeHovered = false
|
||||
|
@ -53,13 +53,6 @@
|
|||
return classes
|
||||
}
|
||||
|
||||
const deleteEdge = async () => {
|
||||
flow.deleteElements({
|
||||
edges: [{ id }],
|
||||
})
|
||||
await updateRole(target)
|
||||
}
|
||||
|
||||
const onEdgeMouseOver = () => {
|
||||
edgeHovered = true
|
||||
}
|
||||
|
@ -92,7 +85,7 @@
|
|||
style:transform="translate(-50%, -50%) translate({labelX}px,{labelY}px)"
|
||||
class="edge-label nodrag nopan"
|
||||
class:active
|
||||
on:click={deleteEdge}
|
||||
on:click={() => deleteEdge(id)}
|
||||
on:mouseover={() => (iconHovered = true)}
|
||||
on:mouseout={() => (iconHovered = false)}
|
||||
>
|
||||
|
|
|
@ -31,26 +31,33 @@
|
|||
$: handleExternalRoleChanges($roles)
|
||||
|
||||
// Converts a role doc into a node structure
|
||||
const roleToNode = role => ({
|
||||
id: role._id,
|
||||
sourcePosition: Position.Right,
|
||||
targetPosition: Position.Left,
|
||||
type: "role",
|
||||
position: { x: 0, y: 0 },
|
||||
data: {
|
||||
...role.uiMetadata,
|
||||
custom: !role._id.match(/[A-Z]+/),
|
||||
},
|
||||
})
|
||||
const roleToNode = role => {
|
||||
const custom = !role._id.match(/[A-Z]+/)
|
||||
|
||||
return {
|
||||
id: role._id,
|
||||
sourcePosition: Position.Right,
|
||||
targetPosition: Position.Left,
|
||||
type: "role",
|
||||
position: { x: 0, y: 0 },
|
||||
data: {
|
||||
...role.uiMetadata,
|
||||
custom,
|
||||
},
|
||||
deletable: custom,
|
||||
draggable: custom,
|
||||
connectable: custom,
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a node structure back into a role doc
|
||||
const nodeToRole = node => {
|
||||
const role = $roles.find(x => x._id === node.id)
|
||||
// const inherits = $edges.filter(x => x.target === node.id).map(x => x.source)
|
||||
const inherits = $edges.filter(x => x.target === node.id).map(x => x.source)
|
||||
// TODO save inherits array
|
||||
return {
|
||||
...role,
|
||||
// inherits,
|
||||
inherits,
|
||||
uiMetadata: {
|
||||
displayName: node.data.displayName,
|
||||
color: node.data.color,
|
||||
|
@ -63,7 +70,11 @@
|
|||
const rolesToLayout = roles => {
|
||||
let nodes = []
|
||||
let edges = []
|
||||
for (let role of roles.filter(role => role._id !== Roles.PUBLIC)) {
|
||||
|
||||
// Remove some builtins
|
||||
const ignoredRoles = [Roles.PUBLIC, Roles.POWER]
|
||||
roles = roles.filter(role => !ignoredRoles.includes(role._id))
|
||||
for (let role of roles) {
|
||||
// Add node for this role
|
||||
nodes.push(roleToNode(role))
|
||||
|
||||
|
@ -138,7 +149,6 @@
|
|||
description: "Custom role",
|
||||
},
|
||||
permissionId: "write",
|
||||
inherits: Roles.BASIC,
|
||||
})
|
||||
await tick()
|
||||
selectNode(roleId)
|
||||
|
@ -148,7 +158,7 @@
|
|||
const updateRole = async (roleId, metadata) => {
|
||||
// Don't update builtins
|
||||
const node = $nodes.find(x => x.id === roleId)
|
||||
if (!node || !node.data.custom) {
|
||||
if (!node) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -170,6 +180,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
const deleteEdge = async edgeId => {
|
||||
const edge = $edges.find(x => x.id === edgeId)
|
||||
if (!edge) {
|
||||
return
|
||||
}
|
||||
edges.set($edges.filter(x => x.id !== edgeId))
|
||||
await updateRole(edge.target)
|
||||
}
|
||||
|
||||
// Saves a new connection
|
||||
const onConnect = async connection => {
|
||||
await updateRole(connection.target)
|
||||
|
@ -183,6 +202,7 @@
|
|||
createRole,
|
||||
updateRole,
|
||||
deleteRole,
|
||||
deleteEdge,
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
export let data
|
||||
export let id
|
||||
export let selected
|
||||
export let isConnectable
|
||||
|
||||
const { dragging, updateRole, deleteRole } = getContext("flow")
|
||||
|
||||
|
@ -30,7 +31,7 @@
|
|||
$: nameError = validateName(tempDisplayName, $roles)
|
||||
$: descriptionError = validateDescription(tempDescription)
|
||||
$: invalid = nameError || descriptionError
|
||||
$: targetClasses = `target${$dragging ? "" : " hidden"}`
|
||||
$: targetClasses = `target${!$dragging ? " hidden" : ""}`
|
||||
|
||||
const validateName = (name, roles) => {
|
||||
if (!name?.length) {
|
||||
|
@ -91,15 +92,13 @@
|
|||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if id !== Roles.BASIC}
|
||||
{#if isConnectable}
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
class={targetClasses}
|
||||
isConnectable={$dragging}
|
||||
/>
|
||||
{/if}
|
||||
{#if id !== Roles.ADMIN}
|
||||
<Handle type="source" position={Position.Right} />
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@ export const dagreLayout = ({ nodes, edges }) => {
|
|||
dagreGraph.setDefaultEdgeLabel(() => ({}))
|
||||
dagreGraph.setGraph({
|
||||
rankdir: "LR",
|
||||
ranksep: GridResolution * 8,
|
||||
ranksep: GridResolution * 4,
|
||||
nodesep: GridResolution * 2,
|
||||
})
|
||||
nodes.forEach(node => {
|
||||
|
@ -19,6 +19,26 @@ export const dagreLayout = ({ nodes, edges }) => {
|
|||
edges.forEach(edge => {
|
||||
dagreGraph.setEdge(edge.source, edge.target)
|
||||
})
|
||||
|
||||
// Add ephemeral edges for basic and admin so that we can position them properly
|
||||
|
||||
for (let node of nodes) {
|
||||
if (
|
||||
!edges.some(x => x.target === node.id) &&
|
||||
node.id !== Roles.BASIC &&
|
||||
node.id !== Roles.ADMIN
|
||||
) {
|
||||
dagreGraph.setEdge(Roles.BASIC, node.id)
|
||||
}
|
||||
if (
|
||||
!edges.some(x => x.source === node.id) &&
|
||||
node.id !== Roles.BASIC &&
|
||||
node.id !== Roles.ADMIN
|
||||
) {
|
||||
dagreGraph.setEdge(node.id, Roles.ADMIN)
|
||||
}
|
||||
}
|
||||
|
||||
dagre.layout(dagreGraph)
|
||||
nodes.forEach(node => {
|
||||
const pos = dagreGraph.node(node.id)
|
||||
|
@ -34,32 +54,14 @@ export const dagreLayout = ({ nodes, edges }) => {
|
|||
|
||||
// Adds additional edges as needed to the flow structure to ensure compatibility with BB role logic
|
||||
const sanitiseLayout = ({ nodes, edges }) => {
|
||||
let additions = []
|
||||
|
||||
for (let node of nodes) {
|
||||
// If a node does not inherit anything, let it inherit basic
|
||||
if (!edges.some(x => x.target === node.id) && node.id !== Roles.BASIC) {
|
||||
additions.push({
|
||||
id: Helpers.uuid(),
|
||||
source: Roles.BASIC,
|
||||
target: node.id,
|
||||
animated: true,
|
||||
})
|
||||
}
|
||||
|
||||
// If a node is not inherited by anything, let it be inherited by admin
|
||||
if (!edges.some(x => x.source === node.id) && node.id !== Roles.ADMIN) {
|
||||
additions.push({
|
||||
id: Helpers.uuid(),
|
||||
source: node.id,
|
||||
target: Roles.ADMIN,
|
||||
})
|
||||
}
|
||||
}
|
||||
// Remove any inheritance of basic and admin since this is implied
|
||||
edges = edges.filter(
|
||||
edge => edge.source !== Roles.BASIC && edge.target !== Roles.ADMIN
|
||||
)
|
||||
|
||||
return {
|
||||
nodes,
|
||||
edges: [...edges, ...additions],
|
||||
edges,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue