UX: switch group pages to horizontal nav (#31243)

This gets group pages on the same horizontal nav patterns as the user
profile pages. These pages need some more adjustments in general, but
this is a good start!

Before: 

![image](https://github.com/user-attachments/assets/2eaf5504-030f-4c91-a794-f66808fe0576)

![image](https://github.com/user-attachments/assets/5a726208-56ec-437c-8e53-c6edcd2ce772)


After:

![image](https://github.com/user-attachments/assets/f621c371-ac2c-4ab7-af18-d836bcec4c74)

![image](https://github.com/user-attachments/assets/c9eee57e-3e30-4ccb-82a2-29327dae5404)


Before: 

<img
src="https://github.com/user-attachments/assets/b58f1994-8ef8-4a67-9b37-bfee428c343b"
width="350" />

After:

<img
src="https://github.com/user-attachments/assets/013b1af6-ddb9-4a93-bcfe-37b2a9760d8b"
width="350" />
This commit is contained in:
Kris 2025-02-10 10:38:31 -05:00 committed by GitHub
parent db139534d2
commit 50136ee4e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 147 additions and 155 deletions

View File

@ -0,0 +1,52 @@
import Component from "@glimmer/component";
import { hash } from "@ember/helper";
import { LinkTo } from "@ember/routing";
import { service } from "@ember/service";
import HorizontalOverflowNav from "discourse/components/horizontal-overflow-nav";
import PluginOutlet from "discourse/components/plugin-outlet";
import icon from "discourse/helpers/d-icon";
import { i18n } from "discourse-i18n";
import GroupDropdown from "select-kit/components/group-dropdown";
export default class GroupNavigation extends Component {
@service site;
<template>
{{#if this.site.mobileView}}
<LinkTo @route="groups.index">
{{i18n "groups.index.all"}}
</LinkTo>
{{else}}
<GroupDropdown
@groups={{@group.extras.visible_group_names}}
@value={{@group.name}}
/>
{{/if}}
<HorizontalOverflowNav class="group-nav">
{{#each @tabs as |tab|}}
<li>
<LinkTo
@route={{tab.route}}
@model={{@group}}
title={{tab.message}}
class={{tab.name}}
>
{{#if tab.icon}}
{{icon tab.icon}}
{{/if}}
{{tab.message}}
{{#if tab.count}}
<span class="count">
({{tab.count}})
</span>
{{/if}}
</LinkTo>
</li>
{{/each}}
<PluginOutlet
@name="group-reports-nav-item"
@outletArgs={{hash group=@group}}
@connectorTagName="li"
/>
</HorizontalOverflowNav>
</template>
}

View File

@ -1,36 +0,0 @@
<MobileNav class="group-nav" @desktopClass="nav nav-pills">
{{#if this.site.mobileView}}
<li>
<LinkTo @route="groups.index">
{{i18n "groups.index.all"}}
</LinkTo>
</li>
{{else}}
<li>
<GroupDropdown
@groups={{this.group.extras.visible_group_names}}
@value={{this.group.name}}
/>
</li>
{{/if}}
{{#each this.tabs as |tab|}}
<li>
<LinkTo
@route={{tab.route}}
@model={{this.group}}
title={{tab.message}}
class={{tab.name}}
>
{{#if tab.icon}}{{d-icon tab.icon}}{{/if}}
{{tab.message}}
{{#if tab.count}}<span class="count">({{tab.count}})</span>{{/if}}
</LinkTo>
</li>
{{/each}}
<PluginOutlet
@name="group-reports-nav-item"
@outletArgs={{hash group=this.group}}
@connectorTagName="li"
/>
</MobileNav>

View File

@ -1,5 +0,0 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
@tagName("")
export default class GroupNavigation extends Component {}

View File

@ -50,7 +50,10 @@ export default class GroupController extends Controller {
count: userCount,
});
const defaultTabs = [membersTab, Tab.create({ name: "activity" })];
const defaultTabs = [
membersTab,
Tab.create({ name: "activity", icon: "bars-staggered" }),
];
if (canManageGroup && allowMembershipRequests) {
defaultTabs.push(
@ -68,6 +71,7 @@ export default class GroupController extends Controller {
Tab.create({
name: "messages",
i18nKey: "messages",
icon: "envelope",
})
);
}
@ -86,6 +90,7 @@ export default class GroupController extends Controller {
Tab.create({
name: "permissions",
i18nKey: "permissions.title",
icon: "id-card",
})
);

View File

@ -83,20 +83,16 @@
{{/if}}
</div>
<span>
<PluginOutlet
@name="group-details-after"
@connectorTagName="div"
@outletArgs={{hash model=this.model}}
/>
</span>
<PluginOutlet
@name="group-details-after"
@connectorTagName="div"
@outletArgs={{hash model=this.model}}
/>
</div>
{{#if this.model.bio_cooked}}
<hr />
<div class="group-bio">
<p>{{html-safe this.model.bio_cooked}}</p>
{{html-safe this.model.bio_cooked}}
</div>
{{/if}}
@ -104,15 +100,12 @@
<div class="user-content-wrapper">
<section class="user-primary-navigation">
<div class="container">
<GroupNavigation
@group={{this.model}}
@currentPath={{this.currentPath}}
@tabs={{this.tabs}}
/>
</div>
<GroupNavigation
@group={{this.model}}
@currentPath={{this.currentPath}}
@tabs={{this.tabs}}
/>
</section>
{{outlet}}
</div>
</div>

View File

@ -1,8 +1,5 @@
<section class="user-secondary-navigation">
<MobileNav
@desktopClass="action-list activity-list nav-stacked"
class="activity-nav"
>
<HorizontalOverflowNav class="activity-nav">
{{#if this.model.can_see_members}}
<GroupActivityFilter @filter="posts" @categoryId={{this.category_id}} />
<GroupActivityFilter @filter="topics" @categoryId={{this.category_id}} />
@ -14,7 +11,7 @@
/>
{{/if}}
<PluginOutlet @name="group-activity-bottom" @connectorTagName="li" />
</MobileNav>
</HorizontalOverflowNav>
</section>
<section class="user-content" id="user-content">
{{outlet}}

View File

@ -1,8 +1,5 @@
<section class="user-secondary-navigation">
<MobileNav
@desktopClass="action-list activity-list nav-stacked"
class="activity-nav"
>
<HorizontalOverflowNav class="activity-nav">
{{#each this.tabs as |tab|}}
<li>
<LinkTo @route={{tab.route}} @model={{this.model.name}}>
@ -10,7 +7,7 @@
</LinkTo>
</li>
{{/each}}
</MobileNav>
</HorizontalOverflowNav>
</section>
<section class="user-content" id="user-content">
{{outlet}}

View File

@ -1,5 +1,5 @@
<section class="user-secondary-navigation">
<MobileNav @desktopClass="nav-stacked action-list" class="messages-nav">
<HorizontalOverflowNav class="messages-nav">
<li>
<LinkTo @route="group.messages.inbox" @model={{this.model.name}}>
{{i18n "user.messages.inbox"}}
@ -10,7 +10,7 @@
{{i18n "user.messages.archive"}}
</LinkTo>
</li>
</MobileNav>
</HorizontalOverflowNav>
</section>
<section class="user-content" id="user-content">
{{outlet}}

View File

@ -10,9 +10,35 @@
.group-details-container {
background: var(--primary-very-low);
padding: 20px;
margin-bottom: 15px;
padding: 0.8em;
position: relative;
display: flex;
flex-direction: column;
gap: 0.5em;
margin-bottom: 1em;
}
.group-bio {
max-width: 80ch;
p:first-child {
margin-top: 0;
}
p:last-child {
margin-bottom: 0;
}
}
.group-info-details {
display: flex;
flex-direction: column;
align-items: start;
width: 100%;
}
.group-info-mention-name {
margin-bottom: 0.5em;
}
.group-delete-tooltip {
@ -30,6 +56,7 @@
flex-wrap: wrap;
width: 100%;
gap: 0.5em 0;
margin-bottom: 1em;
.bulk-select + input {
margin-left: 0.5em;
@ -98,10 +125,8 @@
.group-details-button {
display: flex;
flex-wrap: wrap;
button:not(:last-child) {
margin-right: 0.5em;
}
justify-content: end;
gap: 0.5em;
}
}

View File

@ -89,7 +89,6 @@
flex: 1 1 auto;
span {
width: 100%;
word-break: break-word;
line-height: var(--line-height-medium);
}

View File

@ -6,7 +6,7 @@
display: grid;
grid-template-columns: 1fr 5fr;
grid-template-rows: auto auto 1fr auto;
grid-gap: 20px;
grid-gap: 0 0.8em;
.user-primary-navigation {
grid-column-start: 1;
@ -14,34 +14,62 @@
grid-row-start: 1;
grid-row-end: 2;
.nav-pills {
flex-wrap: wrap;
.horizontal-overflow-nav {
border-block: 1px solid var(--primary-low);
}
.group-dropdown {
margin-right: 0.5em;
.mobile-view & {
.select-kit-header-wrapper {
font-size: var(--font-down-1);
}
}
}
}
.user-secondary-navigation {
grid-column-start: 1;
grid-column-end: 2;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 3;
border-bottom: 1px solid var(--primary-low);
font-size: var(--font-down-1);
}
.user-primary-navigation,
.user-secondary-navigation {
display: flex;
align-items: stretch;
li {
flex: 1 0 auto;
a {
width: 100%;
justify-content: center;
}
}
}
.solo-preference,
.user-content,
.spinner {
grid-row-start: 2;
grid-row-end: 4;
grid-row-start: 3;
grid-row-end: 5;
grid-column-start: 1;
grid-column-end: 3;
}
.user-content {
margin-top: 1em;
min-width: 100%;
}
.user-additional-controls + .user-content,
.user-secondary-navigation + .user-content {
grid-column-start: 2;
grid-column-start: 1;
grid-column-end: 3;
}
@ -64,6 +92,10 @@
.paginated-topics-list {
position: relative;
tbody {
border-top: none;
}
}
.show-mores {

View File

@ -6,6 +6,8 @@
.nav-pills {
overflow: auto;
min-width: 0;
margin: 0;
height: 100%;
position: relative;
// avoids auto-scroll on initial load if active nav item is overflowed

View File

@ -82,11 +82,5 @@
&.tag-drop {
color: var(--primary-high);
}
&.group-dropdown {
.select-kit-row {
font-weight: bold;
}
}
}
}

View File

@ -1,66 +1,3 @@
// Mobile styles for "/user" section
.user-content-wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto auto;
grid-gap: 16px;
padding-top: 1em;
.user-primary-navigation {
grid-column-start: 1;
grid-row-start: 1;
grid-column-end: 2;
min-width: 120px;
}
.user-secondary-navigation {
grid-column-start: 2;
grid-row-start: 1;
min-width: 120px;
}
.user-additional-controls + .user-content,
.user-secondary-navigation + .user-content {
grid-column-start: 1;
}
.user-additional-controls {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
}
.user-content,
.spinner {
grid-row-start: 3;
grid-column-start: 1;
}
// specific to messages
.user-messages {
grid-row-start: 2;
grid-column-start: 1;
grid-column-end: 3;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
+ .user-additional-controls {
grid-row-start: 2;
grid-column-start: 1;
}
}
.inboxes-controls {
display: flex;
}
.new-private-message {
grid-row-start: 1;
grid-column-start: 2;
}
}
.user-messages-page {
.paginated-topics-list {
margin-top: 0;