Skip to content

Commit

Permalink
Merge pull request buildbot#8076 from p12tic/www-sidebar-groups
Browse files Browse the repository at this point in the history
www: Several improvements to sidebar menu group expand behavior
  • Loading branch information
p12tic authored Oct 4, 2024
2 parents ee16c7c + a9879bc commit 4571779
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 64 deletions.
1 change: 1 addition & 0 deletions master/docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ errorCb
et
eventPathPatterns
executables
expander
explorable
extensibility
facto
Expand Down
1 change: 1 addition & 0 deletions newsfragments/www-sidebar-groups-icon.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed sidebar group expander to use different icon for expanded groups.
1 change: 1 addition & 0 deletions newsfragments/www-sidebar-menu-expand-configurable.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a way to configure sidebar menu group expand behavior in web frontend.
36 changes: 14 additions & 22 deletions www/base/src/components/PageWithSidebar/PageWithSidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@ $gl-sidebar-width: 600px;
background: var(--bb-sidebar-footer-background-color);
}
li.current {
a, button {
.bb-sidebar-item {
background: var(--bb-sidebar-button-current-background-color);
}
a:hover,
button:hover {
.bb-sidebar-button:hover {
background: var(--bb-sidebar-button-hover-background-color);
}
}
a:hover,
button:hover {
.bb-sidebar-button:hover {
background: var(--bb-sidebar-button-hover-background-color);
}
ul .sidebar-title {
Expand Down Expand Up @@ -61,8 +59,7 @@ $gl-sidebar-width: 600px;
display: block;
margin: 13px 0;
}
.sidebar-list a:hover span,
.sidebar-list button:hover span{
.sidebar-list .bb-sidebar-button:hover span{
border-left: 3px solid #e99d1a;
text-indent: 22px;
}
Expand Down Expand Up @@ -123,8 +120,7 @@ $gl-sidebar-width: 600px;
text-align: left;
}

li a,
li button {
li .bb-sidebar-item {
color: var(--bb-sidebar-header-text-color);
display: block;
text-decoration: none;
Expand All @@ -135,7 +131,7 @@ $gl-sidebar-width: 600px;
}
li.sidebar-main {
height: 51px;
a, button {
.bb-sidebar-item {
font-size: 18px;
line-height: 50px;
}
Expand All @@ -157,7 +153,7 @@ $gl-sidebar-width: 600px;
}
li.sidebar-list {
height: 40px;
a, button {
.bb-sidebar-item {
padding: 0;
text-indent: 25px;
font-size: 15px;
Expand All @@ -168,7 +164,7 @@ $gl-sidebar-width: 600px;
}
}
&.current {
a, button {
.bb-sidebar-item {
color: var(--bb-sidebar-button-current-text-color);
border-left: 3px solid var(--bb-sidebar-stripe-current-color);
text-indent: 22px;
Expand All @@ -177,8 +173,7 @@ $gl-sidebar-width: 600px;
text-indent: 25px;
}
}
a:hover,
button:hover {
.bb-sidebar-button:hover {
color: var(--bb-sidebar-button-hover-text-color);
border-left: 3px solid var(--bb-sidebar-stripe-hover-color);
text-indent: 22px;
Expand All @@ -192,19 +187,18 @@ $gl-sidebar-width: 600px;
width: 50px;
}
}
a:hover .menu-icon,
button:hover .menu-icon {
.bb-sidebar-button:hover .menu-icon {
text-indent: 25px;
}
&.subitem {
transition: height $gl-sidebar-transition-time ease-out 0s;
a, button {
.bb-sidebar-item {
padding-left:20px;
transition: line-height $gl-sidebar-transition-time ease-out 0s, color $gl-sidebar-transition-time ease-out 0s, background $gl-sidebar-transition-time ease-out 0s;;
}
&:not(.active) {
height: 0px;
a, button {
.bb-sidebar-item {
line-height: 0px;
color: rgba(255, 0, 0, 0.0);
}
Expand All @@ -229,14 +223,12 @@ $gl-sidebar-width: 600px;
border: 0;
}

div a,
div button {
div .bb-sidebar-item {
color: #b2bfdc;
font-size: 12px;
line-height: 43px;
}
div a:hover,
div button:hover {
div .bb-sidebar-button:hover {
color: #ffffff;
text-decoration: none;
}
Expand Down
61 changes: 49 additions & 12 deletions www/base/src/components/PageWithSidebar/PageWithSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@

import './PageWithSidebar.scss';
import {observer} from "mobx-react";
import {FaAngleRight, FaBars, FaThumbtack} from "react-icons/fa";
import {FaAngleDown, FaAngleRight, FaBars, FaThumbtack} from "react-icons/fa";
import {buildbotGetSettings, buildbotSetupPlugin} from "buildbot-plugin-support";
import {
getBestMatchingSettingsGroupRoute,
GlobalMenuSettings
} from "../../plugins/GlobalMenuSettings";
import {SidebarStore} from "../../stores/SidebarStore";
import {Link, useLocation} from "react-router-dom";

const SIDEBAR_GROUPS_EXPAND_ON_CLICK = 'Expand on click';
const SIDEBAR_GROUPS_EXPAND_ALWAYS = 'Always expand';

type PageWithSidebarProps = {
menuSettings: GlobalMenuSettings,
sidebarStore: SidebarStore,
Expand Down Expand Up @@ -52,29 +56,45 @@ export const PageWithSidebar = observer(({menuSettings, sidebarStore, children}:

const matchingGroupRoute = getBestMatchingSettingsGroupRoute(useLocation().pathname, groups);

const groupExpandBehavior = buildbotGetSettings().getChoiceComboSetting("Home.sidebar_menu_groups_expand_behavior");

const groupElements = groups.map((group, groupIndex) => {
if (group.subGroups.length > 0) {
const isActiveGroup = sidebarStore.activeGroup === group.name ||
groupExpandBehavior === SIDEBAR_GROUPS_EXPAND_ALWAYS;
const subGroups = group.subGroups.map(subGroup => {
const subClassName = "sidebar-list subitem" +
(sidebarStore.activeGroup === group.name ? " active": "") +
(isActiveGroup ? " active": "") +
(subGroup.route === matchingGroupRoute ? " current": "");

return (
<li key={`group-${subGroup.name}`} className={subClassName}>
{subGroup.route === null
? <span>{subGroup.caption}</span>
: <Link to={subGroup.route} onClick={() => sidebarStore.hide()}>{subGroup.caption}</Link>
? <span className="bb-sidebar-item">{subGroup.caption}</span>
: <Link className="bb-sidebar-item bb-sidebar-button" to={subGroup.route}
onClick={() => sidebarStore.hide()}>{subGroup.caption}</Link>
}
</li>
)
});

return [
<li key={`group-${group.name}`} className="sidebar-list">
<button onClick={() => {sidebarStore.toggleGroup(group.name); }}>
<FaAngleRight/>{group.caption}
const groupEl = groupExpandBehavior === SIDEBAR_GROUPS_EXPAND_ALWAYS ?
(
<span className="bb-sidebar-item">
<FaAngleDown/>{group.caption}
<span className="menu-icon">{group.icon}</span>
</span>
) : (
<button className="bb-sidebar-item bb-sidebar-button"
onClick={() => {sidebarStore.toggleGroup(group.name); }}>
{isActiveGroup ? <FaAngleDown/> : <FaAngleRight/>}{group.caption}
<span className="menu-icon">{group.icon}</span>
</button>
);

return [
<li key={`group-${group.name}`} className="sidebar-list">
{groupEl}
</li>,
...subGroups
];
Expand All @@ -91,10 +111,12 @@ export const PageWithSidebar = observer(({menuSettings, sidebarStore, children}:
elements.push(
<li key={`group-${group.name}`} className={groupClassName}>
{group.route === null
? <button onClick={() => sidebarStore.toggleGroup(group.name)}>{group.caption}
? <button className="bb-sidebar-item bb-sidebar-button"
onClick={() => sidebarStore.toggleGroup(group.name)}>{group.caption}
<span className="menu-icon">{group.icon}</span>
</button>
: <Link to={group.route} onClick={() => sidebarStore.toggleGroup(group.name)}>{group.caption}
: <Link className="bb-sidebar-item bb-sidebar-button" to={group.route}
onClick={() => sidebarStore.toggleGroup(group.name)}>{group.caption}
<span className="menu-icon">{group.icon}</span>
</Link>
}
Expand All @@ -106,7 +128,7 @@ export const PageWithSidebar = observer(({menuSettings, sidebarStore, children}:
const footerElements = footerItems.map((footerItem, index) => {
return (
<div key={index} className="col-xs-4">
<Link to={footerItem.route}>{footerItem.caption}</Link>
<Link className="bb-sidebar-item bb-sidebar-button" to={footerItem.route}>{footerItem.caption}</Link>
</div>
);
});
Expand All @@ -116,7 +138,9 @@ export const PageWithSidebar = observer(({menuSettings, sidebarStore, children}:
<div onMouseEnter={() => sidebarStore.enter()} onMouseLeave={() => sidebarStore.leave()}
onClick={() => sidebarStore.show()} className="sidebar">
<ul>
<li key="sidebar-main" className="sidebar-main"><Link to="/">{appTitle}{sidebarIcon}</Link></li>
<li key="sidebar-main" className="sidebar-main">
<Link className="bb-sidebar-item" to="/">{appTitle}{sidebarIcon}</Link>
</li>
<li key="sidebar-title" className="sidebar-title"><span>NAVIGATION</span></li>
{groupElements}
</ul>
Expand All @@ -130,3 +154,16 @@ export const PageWithSidebar = observer(({menuSettings, sidebarStore, children}:
</div>
);
});

buildbotSetupPlugin((reg) => {
reg.registerSettingGroup({
name: 'Home',
caption: null,
items: [{
type: 'choice_combo',
name: 'sidebar_menu_groups_expand_behavior',
caption: 'Sidebar menu groups expansion behavior',
choices: [SIDEBAR_GROUPS_EXPAND_ON_CLICK, SIDEBAR_GROUPS_EXPAND_ALWAYS],
defaultValue: SIDEBAR_GROUPS_EXPAND_ON_CLICK
}]});
});
32 changes: 12 additions & 20 deletions www/base/src/plugins/GlobalSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,12 @@

import {action, makeObservable, observable} from "mobx";
import {Config} from "buildbot-ui";
import {ISettings, registerBuildbotSettingsSingleton} from "buildbot-plugin-support";

export type SettingValue = string | number | boolean;
export type SettingType = "string" | "integer" | "float" | "boolean" | "choice_combo";

export type SettingItemConfig = {
name: string;
type: SettingType;
caption: string;
defaultValue: SettingValue;
choices?: string[]; // only when type == "choice_combo"
}

export type SettingGroupConfig = {
name: string;
caption: string;
items: SettingItemConfig[];
}
import {
ISettings,
SettingGroupConfig,
SettingValue,
registerBuildbotSettingsSingleton
} from "buildbot-plugin-support";

export type SettingItem = {
name: string;
Expand All @@ -48,7 +36,7 @@ export type SettingItem = {

export type SettingGroup = {
name: string;
caption: string;
caption: string | null;
items: {[name: string]: SettingItem};
}

Expand Down Expand Up @@ -259,7 +247,8 @@ export class GlobalSettings implements ISettings {
/** Adds a new setting group and its setting items.
Items of a single group may be added via multiple calls to this function. If group caption
is different between the calls, it is unspecified which value will be used.
is different between the calls, it is unspecified which value will be used. Group captions
having value null are ignored.
This function may only be called during import time. New options should not be added once
the app is running.
Expand All @@ -271,6 +260,9 @@ export class GlobalSettings implements ISettings {

if (config.name in this.groups) {
const group = this.groups[config.name];
if (group.caption === null) {
group.caption = config.caption;
}
for (const item of config.items) {
if (item.name in group.items) {
console.error(`Duplicate group item ${config.name}.${item.name}`);
Expand Down
3 changes: 2 additions & 1 deletion www/base/src/views/SettingsView/Fields/FieldBoolean.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
*/

import {observer} from "mobx-react";
import {SettingItem, SettingValue} from "../../../plugins/GlobalSettings";
import {SettingValue} from "buildbot-plugin-support";;
import {SettingItem} from "../../../plugins/GlobalSettings";

type FieldBooleanProps = {
item: SettingItem;
Expand Down
3 changes: 2 additions & 1 deletion www/base/src/views/SettingsView/Fields/FieldChoiceCombo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

import {observer} from "mobx-react";
import {Form} from "react-bootstrap";
import {SettingItem, SettingValue} from "../../../plugins/GlobalSettings";
import {SettingValue} from "buildbot-plugin-support";;
import {SettingItem} from "../../../plugins/GlobalSettings";

type FieldChoiceCombo = {
item: SettingItem;
Expand Down
3 changes: 2 additions & 1 deletion www/base/src/views/SettingsView/Fields/FieldFloat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
*/

import {observer} from "mobx-react";
import {SettingItem, SettingValue} from "../../../plugins/GlobalSettings";
import {SettingValue} from "buildbot-plugin-support";;
import {SettingItem} from "../../../plugins/GlobalSettings";

type FieldFloatProps = {
item: SettingItem;
Expand Down
3 changes: 2 additions & 1 deletion www/base/src/views/SettingsView/Fields/FieldInteger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
*/

import {observer} from "mobx-react";
import {SettingItem, SettingValue} from "../../../plugins/GlobalSettings";
import {SettingValue} from "buildbot-plugin-support";;
import {SettingItem} from "../../../plugins/GlobalSettings";

type FieldIntegerProps = {
item: SettingItem;
Expand Down
3 changes: 2 additions & 1 deletion www/base/src/views/SettingsView/Fields/FieldString.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
*/

import {observer} from "mobx-react";
import {SettingItem, SettingValue} from "../../../plugins/GlobalSettings";
import {SettingValue} from "buildbot-plugin-support";;
import {SettingItem} from "../../../plugins/GlobalSettings";

type FieldStringProps = {
item: SettingItem;
Expand Down
6 changes: 3 additions & 3 deletions www/base/src/views/SettingsView/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import './SettingsView.scss';
import {observer} from "mobx-react";
import {Card} from "react-bootstrap";
import {FaSlidersH} from "react-icons/fa";
import {buildbotSetupPlugin} from "buildbot-plugin-support";
import {buildbotSetupPlugin, SettingValue} from "buildbot-plugin-support";
import {
GlobalSettings,
globalSettings,
SettingGroup,
SettingItem, SettingValue
SettingItem
} from "../../plugins/GlobalSettings";
import {FieldBoolean} from "./Fields/FieldBoolean";
import {FieldChoiceCombo} from "./Fields/FieldChoiceCombo";
Expand Down Expand Up @@ -94,7 +94,7 @@ export const SettingsView = observer(() => {
return (
<Card key={group.name}>
<Card.Header>
<Card.Title>{group.caption}</Card.Title>
<Card.Title>{group.caption ?? "(null - please report a bug)"}</Card.Title>
</Card.Header>
<Card.Body>
<form data-bb-test-id={`settings-group-${group.name}`}
Expand Down
Loading

0 comments on commit 4571779

Please sign in to comment.