Переглянути джерело

fix: #603 - Dashboards that have fieldsets without entities are hidden (#609)

James Read 1 рік тому
батько
коміт
433456986d

+ 26 - 0
integration-tests/configs/dashboardsWithBasicFieldsets/config.yaml

@@ -0,0 +1,26 @@
+logLevel: debug
+
+actions:
+  - title: Ping
+
+  - title: Action 1
+  - title: Action 2
+
+  - title: Action 3
+  - title: Action 4
+
+dashboards:
+  - title: Test
+    contents:
+      # Uncomment to see the dashboard with the "Ping" action only
+      - title: Ping
+      - title: Fieldset 1
+        type: fieldset
+        contents:
+          - title: Action 1
+          - title: Action 2
+      - title: Fieldset 2
+        type: fieldset
+        contents:
+          - title: Action 3
+          - title: Action 4

+ 56 - 2
integration-tests/lib/elements.js

@@ -3,8 +3,12 @@ import fs from 'fs'
 import { expect } from 'chai'
 import { Condition } from 'selenium-webdriver'
 
-export async function getActionButtons (webdriver) {
-  return await webdriver.findElement(By.id('contentActions')).findElements(By.tagName('button'))
+export async function getActionButtons (dashboardTitle = null) {
+  if (dashboardTitle == null) { 
+    return await webdriver.findElement(By.id('contentActions')).findElements(By.tagName('button'))
+  } else {
+    return await webdriver.findElements(By.css('section[title="' + dashboardTitle + '"] button'))
+  }
 }
 
 export function takeScreenshotOnFailure (test, webdriver) {
@@ -41,6 +45,56 @@ export async function getRootAndWait() {
   }))
 }
 
+export async function closeSidebar() {
+  await webdriver.findElement(By.id('sidebar-toggler-button')).click()
+
+  const sidebar = await webdriver.findElement(By.id('mainnav'))
+
+  const neededLeft = '-250px' // Assuming sidebar is closed at this position
+
+  let lastLeft = ''
+
+  await webdriver.wait(new Condition('wait for sidebar to close', async function() {
+    const left = await sidebar.getCssValue('left')
+
+    if (left !== lastLeft) {
+      lastLeft = left
+      console.log('Sidebar left changed to: ', left)
+      return false
+    } else {
+      console.log('Sidebar closed, left is: *' + left, left === neededLeft ? ' (as expected)' : '')
+      return left === neededLeft
+    }
+  }), 10000); // Wait up to 10 seconds for the sidebar to close
+}
+
+export async function openSidebar() {
+  await webdriver.findElement(By.id('sidebar-toggler-button')).click()
+
+  const sidebar = await webdriver.findElement(By.id('mainnav'))
+
+  let lastLeft = 0
+
+  await webdriver.wait(new Condition('wait for sidebar to open', async function() {
+    const left = await sidebar.getCssValue('left')
+
+    if (left !== lastLeft) {
+      lastLeft = left
+      console.log('Sidebar left changed to: ', left)
+      return false
+    } else {
+      console.log('Sidebar opened, left is: ', left)
+      return true
+    }
+  }));
+}
+
+export async function getNavigationLinks() {
+  const navigationLinks = await webdriver.findElements(By.css('#navigation-links a'))
+
+  return navigationLinks
+}
+
 export async function requireExecutionDialogStatus (webdriver, expected) {
   // It seems that webdriver will not give us text if domStatus is hidden (which it will be until complete)
   await webdriver.executeScript('window.executionDialog.domExecutionDetails.hidden = false')

+ 50 - 0
integration-tests/test/dashboardsWithBasicFieldsets.js

@@ -0,0 +1,50 @@
+import { describe, it, before, after } from 'mocha'
+import { expect } from 'chai'
+import { By, until, Condition } from 'selenium-webdriver'
+//import * as waitOn from 'wait-on'
+import {
+  getRootAndWait,
+  getActionButtons,
+  openSidebar,
+  getNavigationLinks,
+  takeScreenshotOnFailure,
+} from '../lib/elements.js'
+
+describe('config: dashboards with basic fieldsets', function () {
+  before(async function () {
+    await runner.start('dashboardsWithBasicFieldsets')
+  })
+
+  after(async () => {
+    await runner.stop()
+  })
+
+  afterEach(function () {
+    takeScreenshotOnFailure(this.currentTest, webdriver);
+  });
+
+  it('Dashboards with basic fieldsets', async function () {
+    await getRootAndWait()
+
+    const title = await webdriver.getTitle()
+    expect(title).to.be.equal("OliveTin » Test")
+
+    const navigationLinks = await getNavigationLinks()
+    expect(navigationLinks.length).to.be.equal(2, 'Expected the nav to only have 2 links')
+
+    const firstLink = await navigationLinks[0]
+
+    expect(await firstLink.getAttribute('id')).to.be.equal('showActions', 'Expected the first link to be the actions link')
+    expect(await firstLink.isDisplayed()).to.be.false
+    
+    const secondLink = await navigationLinks[1]
+    expect(await secondLink.getAttribute('href')).to.be.equal('http://localhost:1337/Test', 'Expected the second link to be the test dashboard with basic fieldsets link')
+
+    const actionButtons = await getActionButtons('Test')
+    expect(actionButtons).to.have.length(5, 'Expected 5 action buttons')
+
+    const fieldsets = await webdriver.findElements(By.css('section[title="Test"] fieldset'))
+    expect(fieldsets).to.have.length(3, 'Expected 3 fieldsets in the Test dashboard')
+
+  })
+})

+ 6 - 6
integration-tests/test/emptyDashboardsAreHidden.js

@@ -4,6 +4,8 @@ import { By, until, Condition } from 'selenium-webdriver'
 //import * as waitOn from 'wait-on'
 import {
   getRootAndWait,
+  openSidebar,
+  getNavigationLinks,
   takeScreenshotOnFailure,
 } from '../lib/elements.js'
 
@@ -26,17 +28,15 @@ describe('config: empty dashboards are hidden', function () {
     const title = await webdriver.getTitle()
     expect(title).to.be.equal("OliveTin")
 
-    await webdriver.findElement(By.id('sidebar-toggler-button')).click()
-
-    const navigationLinks = await webdriver.findElements(By.css('#navigation-links a'))
-
-    console.log('navigationLinks', navigationLinks)
+    await openSidebar()
 
+    const navigationLinks = await getNavigationLinks()
     expect(navigationLinks).to.not.be.empty
     expect(navigationLinks.length).to.be.equal(1, 'Expected the nav to only have 1 link')
-
+    
     const firstLinkId = await navigationLinks[0].getAttribute('id')
 
     expect(firstLinkId).to.be.equal('showActions', 'Expected the first link to be the actions link')
+
   })
 })

+ 1 - 1
integration-tests/test/general.mjs

@@ -56,7 +56,7 @@ describe('config: general', function () {
   it('Default buttons are rendered', async function() {
     await getRootAndWait()
 
-    const buttons = await getActionButtons(webdriver)
+    const buttons = await getActionButtons()
 
     expect(buttons).to.have.length(8)
   })

+ 1 - 1
integration-tests/test/multipleDropdowns.js

@@ -24,7 +24,7 @@ describe('config: multipleDropdowns', function () {
   it('Multiple dropdowns are possible', async function() {
     await getRootAndWait()
 
-    const buttons = await getActionButtons(webdriver)
+    const buttons = await getActionButtons()
 
     let button = null
     for (const b of buttons) {

+ 51 - 0
integration-tests/test/onlyDashboards.mjs

@@ -0,0 +1,51 @@
+import { describe, it, before, after } from 'mocha'
+import { assert } from 'chai'
+import { By } from 'selenium-webdriver'
+import {
+  getRootAndWait,
+  getActionButtons,
+  getNavigationLinks,
+  openSidebar,
+  closeSidebar,
+  takeScreenshotOnFailure,
+} from '../lib/elements.js'
+
+describe('config: onlyDashboards', function () {
+  before(async function () {
+    await runner.start('onlyDashboards')
+  })
+
+  after(async () => {
+    await runner.stop()
+  })
+
+  afterEach(function () {
+    takeScreenshotOnFailure(this.currentTest, webdriver);
+  });
+
+  it('When there are only dashboards, actions are hidden', async function () {
+    await getRootAndWait()
+
+    await openSidebar()
+
+    const navLinks = await getNavigationLinks()
+
+    const actionsLink = navLinks[0];
+    assert.isNotNull(actionsLink, 'Actions link should not be null')
+    assert.equal(await actionsLink.getAttribute('title'), 'Actions', 'Actions link should have the title "Actions"')
+    assert.isFalse(await actionsLink.isDisplayed(), 'Actions link should not be displayed when there are only dashboards')
+
+    const firstDashboardLink = await webdriver.findElement(By.css('li[title="My Dashboard"]'), 'The first dashboard link should be present')
+    assert.isNotNull(firstDashboardLink, 'First dashboard link should not be null')
+    assert.isTrue(await firstDashboardLink.isDisplayed(), 'First dashboard link should be displayed')
+    
+    const actionButtons = await getActionButtons()
+
+    assert.isArray(actionButtons, 'Action buttons should be an array')
+    assert.lengthOf(actionButtons, 0, 'Action buttons should be empty when everything is added to the dashboard')
+
+    const actionButtonsOnDashboard = await getActionButtons('MyDashboard')
+    assert.isArray(actionButtonsOnDashboard, 'Action buttons on dashboard should be an array')
+    assert.lengthOf(actionButtonsOnDashboard, 3, 'Action buttons on dashboard should have 3 buttons')
+  })
+})

+ 4 - 2
service/internal/grpcapi/grpcApiDashboard.go

@@ -60,8 +60,10 @@ func getDashboardComponentContents(dashboard *config.DashboardComponent, rr *Das
 }
 
 func buildDashboardComponentSimple(subitem *config.DashboardComponent, rr *DashboardRenderRequest) *apiv1.DashboardComponent {
-	if !slices.Contains(rr.AllowedActionTitles, subitem.Title) {
-		return nil
+	if subitem.Type == "" || subitem.Type == "link" {
+		if !slices.Contains(rr.AllowedActionTitles, subitem.Title) {
+			return nil
+		}
 	}
 
 	newitem := &apiv1.DashboardComponent{