Skip to content

Commit

Permalink
handle empty topic states, mid-topic terminating segments and alter c…
Browse files Browse the repository at this point in the history
…ounter to also count terminating segments
  • Loading branch information
cstns committed Nov 27, 2024
1 parent 66295fb commit 16ec27d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 34 deletions.
45 changes: 40 additions & 5 deletions frontend/src/pages/team/UNS/Hierarchy/components/TopicSegment.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="segment-wrapper" :class="{open: isSegmentOpen}" data-el="segment-wrapper" :data-value="segment.name">
<div class="segment-wrapper" :class="{open: isSegmentOpen, empty: segment.isEmpty}" data-el="segment-wrapper" :data-value="segment.name">
<div class="segment flex" @click="toggleChildren">
<div class="diagram">
<span v-if="!isRoot" class="connector-elbow" />
Expand All @@ -8,7 +8,18 @@
<div class="content flex gap-1.5 items-center font-bold" :class="{'cursor-pointer': hasChildren, 'cursor-default': !hasChildren, 'pl-10': !isRoot}">
<ChevronRightIcon v-if="hasChildren" class="chevron ff-icon-sm" />
<p class="flex gap-2.5 items-end" :class="{'ml-2': !hasChildren}">
<span class="title">{{ segmentText }}</span>
<span class="title">
<span v-if="segment.isEmpty && !isRoot && !hasChildren" class="separator">/</span>

{{ segmentText }}
<span
v-if="segment.isEndOfTopic && segment.childrenCount"
class="separator cursor-help"
title="This topic is also able to receive events"
>
<ArchiveIcon class="ff-icon-sm" />
</span>
</span>
<span v-if="hasChildren" class="font-normal opacity-50 text-xs">{{ topicsCounterLabel }}</span>
<text-copier :text="segment.path" :show-text="false" class="ff-text-copier" />
</p>
Expand All @@ -17,7 +28,7 @@
<div v-if="hasChildren && isSegmentOpen" class="children" data-el="segment-children" :class="{ 'pl-10': isRoot}">
<topic-segment
v-for="(child, key) in childrenSegments"
:key="child.path"
:key="'-'+child.path"
:segment="children[child]"
:children="children[child].children"
:has-siblings="Object.keys(children).length > 1"
Expand All @@ -30,12 +41,13 @@
</template>

<script>
import { ArchiveIcon } from '@heroicons/vue/outline'
import { ChevronRightIcon } from '@heroicons/vue/solid'
import TextCopier from '../../../../../components/TextCopier.vue'
export default {
name: 'TopicSegment',
components: { TextCopier, ChevronRightIcon },
components: { TextCopier, ChevronRightIcon, ArchiveIcon },
props: {
segment: {
required: true,
Expand Down Expand Up @@ -80,7 +92,7 @@ export default {
return `(${this.segment.childrenCount} ${label})`
},
segmentText () {
return this.hasChildren ? `${this.segment.name}/` : this.segment.name
return this.segment.isEmpty ? '(empty)' : this.segment.name
},
shouldShowTrunk () {
return !this.isRoot && this.hasSiblings && this.isLastSibling
Expand Down Expand Up @@ -148,6 +160,12 @@ export default {
transition: ease .3s;
}
.title {
align-items: center;
display: flex;
gap: 3px;
}
.ff-text-copier {
display: none;
height: 17px;
Expand Down Expand Up @@ -181,5 +199,22 @@ export default {
}
}
}
&.empty > {
.segment {
.content {
.title {
color: $ff-grey-600;
font-size: 90%;
font-weight: 300;
.separator {
color: $ff-black;
font-weight: bold;
}
}
}
}
}
}
</style>
50 changes: 29 additions & 21 deletions frontend/src/pages/team/UNS/Hierarchy/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,35 +79,43 @@ export default {
hierarchy: {
get () {
const hierarchy = {}
this.topics.forEach(topic => {
const parts = topic.split('/')
let current = hierarchy
parts.forEach((part, index) => {
if (!current[part]) {
current[part] = {
name: part,
path: parts.slice(0, index + 1).join('/'),
open: false,
childrenCount: 0,
children: {}
const topics = this.topics
topics.sort()
.forEach(topic => {
const parts = topic.split('/')
let current = hierarchy
parts.forEach((part, index) => {
if (!current[part]) {
const isEmpty = part.length === 0
current[part] = {
name: part,
isEmpty,
path: parts.slice(0, index + 1).join('/'),
open: false,
childrenCount: 0,
children: {},
isEndOfTopic: index === parts.length - 1
}
}
}
current = current[part].children
current = current[part].children
})
})
})
function calculateChildrenCount (node) {
if (!node.children || Object.keys(node.children).length === 0) {
return 1 // Terminating segment; count as 1.
}
let count = 0
for (const childKey in node.children) {
const childNode = node.children[childKey]
count += calculateChildrenCount(childNode) // Only count terminating children.
count += calculateChildrenCount(childNode)
}
for (const childKey in node.children) {
if (node.children[childKey].isEndOfTopic) {
count++
}
}
node.childrenCount = count
return count
}
Expand Down
22 changes: 14 additions & 8 deletions test/e2e/frontend/cypress/tests-ee/uns/hierarchy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ describe('FlowForge - Unified Namespace Hierarchy', () => {
'foo/bar/baz',
'foo/thud',
'foo/flam/paz/daz',
'wibble/wabble/bork'
'wibble/wabble/bork',
'wibble/wabble/bork/spork'
]).as('getTopics')
cy.get('[data-nav="team-unified-namespace"]').click()

Expand All @@ -77,9 +78,11 @@ describe('FlowForge - Unified Namespace Hierarchy', () => {
cy.get('[data-el="segment-wrapper"]').should('have.length', 2)

cy.get('[data-el="segment-wrapper"][data-value="foo"]').contains('3 topics')
cy.get('[data-el="segment-wrapper"][data-value="foo"]').contains('foo/')
cy.get('[data-el="segment-wrapper"][data-value="wibble"]').contains('1 topic')
cy.get('[data-el="segment-wrapper"][data-value="wibble"]').contains('wibble/')
cy.get('[data-el="segment-wrapper"][data-value="foo"]').contains('foo')

// check that terminating topic segments are correctly included in the parent count
cy.get('[data-el="segment-wrapper"][data-value="wibble"]').contains('2 topics')
cy.get('[data-el="segment-wrapper"][data-value="wibble"]').contains('wibble')

cy.get('[data-el="segment-wrapper"][data-value="paz"]').should('not.exist')
cy.get('[data-el="segment-wrapper"][data-value="bar"]').should('not.exist')
Expand All @@ -89,18 +92,16 @@ describe('FlowForge - Unified Namespace Hierarchy', () => {
cy.get('[data-el="segment-wrapper"][data-value="foo"]').click()
cy.get('[data-el="segment-wrapper"][data-value="foo"]').within(() => {
cy.get('[data-el="segment-wrapper"][data-value="baz"]').should('not.exist')
cy.get('[data-el="segment-wrapper"][data-value="bar"]').contains('bar/')
cy.get('[data-el="segment-wrapper"][data-value="bar"]').contains('bar')
cy.get('[data-el="segment-wrapper"][data-value="bar"]').contains('1 topic')
cy.get('[data-el="segment-wrapper"][data-value="bar"]').click()
cy.get('[data-el="segment-wrapper"][data-value="baz"]').should('exist')
cy.get('[data-el="segment-wrapper"][data-value="baz"]').should('contain', 'baz')
cy.get('[data-el="segment-wrapper"][data-value="baz"]').should('not.contain', 'baz/')

cy.get('[data-el="segment-wrapper"][data-value="thud"]').should('not.contain', '1 topic')
cy.get('[data-el="segment-wrapper"][data-value="thud"]').should('not.contain', 'thud/')

cy.get('[data-el="segment-wrapper"][data-value="paz"]').should('not.exist')
cy.get('[data-el="segment-wrapper"][data-value="flam"]').contains('flam/')
cy.get('[data-el="segment-wrapper"][data-value="flam"]').contains('flam')
cy.get('[data-el="segment-wrapper"][data-value="flam"]').contains('1 topic')
cy.get('[data-el="segment-wrapper"][data-value="flam"]').click()
cy.get('[data-el="segment-wrapper"][data-value="paz"]').should('exist')
Expand All @@ -113,6 +114,11 @@ describe('FlowForge - Unified Namespace Hierarchy', () => {

cy.get('[data-el="segment-wrapper"][data-value="foo"] > .segment .content').click()
cy.get('[data-el="segment-wrapper"]').should('have.length', 2)

// check that terminating topic segments are marked with an svg icon
cy.get('[data-el="segment-wrapper"][data-value="wibble"]').click()
cy.get('[data-el="segment-wrapper"][data-value="wabble"]').click()
cy.get('[data-el="segment-wrapper"][data-value="bork"]').find('svg').should('exist')
})
})

Expand Down

0 comments on commit 16ec27d

Please sign in to comment.