Skip to content

Optimize team member ux #34593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,7 @@ teams = Teams
code = Code
lower_members = members
lower_repositories = repositories
all_teams = All Teams
create_new_team = New Team
create_team = Create Team
org_desc = Description
Expand Down
6 changes: 6 additions & 0 deletions routers/web/org/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,13 @@ func Members(ctx *context.Context) {
ctx.ServerError("GetMembers", err)
return
}
teams, err := organization.FindOrgTeams(ctx, org.ID)
if err != nil {
ctx.ServerError("GetOrgTeams", err)
return
}
ctx.Data["Page"] = pager
ctx.Data["Teams"] = teams
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH if you have "all teams" here, then the "pager" doesn't make sense any more.

ctx.Data["Members"] = members
ctx.Data["MembersIsPublicMember"] = membersIsPublic
ctx.Data["MembersIsUserOrgOwner"] = organization.IsUserOrgOwner(ctx, members, org.ID)
Expand Down
45 changes: 45 additions & 0 deletions templates/org/member/members.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
<div class="ui container">
{{template "base/alert" .}}

{{if .IsOrganizationOwner}}
<div class="flex-text-block tw-justify-end tw-gap-x-1 tw-gap-y-2 tw-mb-4">
<button class="ui primary button show-modal" data-modal="#add-member-to-team-modal"
>
{{svg "octicon-plus"}}
{{ctx.Locale.Tr "org.teams.add_team_member"}}
</button>
</div>
<div class="divider"></div>
{{end}}

<div class="flex-list">
{{range .Members}}
{{$isPublic := index $.MembersIsPublicMember .ID}}
Expand Down Expand Up @@ -87,4 +98,38 @@
{{template "base/modal_actions_confirm" .}}
</div>

<div class="ui small modal" id="add-member-to-team-modal">
<div class="header">{{ctx.Locale.Tr "org.teams.add_team_member"}}</div>
<div class="content">
<form class="ui form ignore-dirty" method="post" data-action-base-link="{{$.OrgLink}}">
{{.CsrfTokenHtml}}
<div class="required field">
<label>{{ctx.Locale.Tr "org.teams"}}</label>
<div class="ui dropdown selection search team_add_member_team_search">
<input name="team" type="hidden">
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="text"></div>
<div class="menu">
{{range .Teams}}
<div class="item" data-value="{{.LowerName}}">{{.Name}}</div>
{{end}}
</div>
</div>
</div>
<div class="required field">
<label>{{ctx.Locale.Tr "org.members"}}</label>
<div id="search-user-box" class="ui search">
<div class="ui input">
<input class="prompt" name="uname" placeholder="{{ctx.Locale.Tr "search.user_kind"}}" autocomplete="off" required>
</div>
</div>
</div>
<div class="actions">
<button class="ui cancel button">{{ctx.Locale.Tr "cancel"}}</button>
<button type="submit" class="ui primary button">{{ctx.Locale.Tr "save"}}</button>
</div>
</form>
</div>
</div>

{{template "base/footer" .}}
13 changes: 13 additions & 0 deletions templates/org/team/members.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
{{template "org/header" .}}
<div class="ui container">
{{template "base/alert" .}}
{{if or .IsOrganizationOwner .IsOrganizationMember}}
<div class="flex-text-block tw-justify-end tw-gap-x-1 tw-gap-y-2 tw-mb-4">
{{if .IsOrganizationOwner}}
<a class="ui primary button" href="{{.OrgLink}}/teams/new">{{svg "octicon-plus"}} {{ctx.Locale.Tr "org.create_new_team"}}</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why members list page should show "add new team"? I guess it should show "add new member" instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like above, there is no mistake. It is indeed about adding a new team. My original intention is to provide a more eye-catching and convenient operation entry on the secondary page.

{{end}}
{{if .IsOrganizationMember}}
<a class="ui primary button" href="{{.OrgLink}}/teams">{{svg "octicon-people"}} {{ctx.Locale.Tr "org.all_teams"}}</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the "all teams" link already in the navbar?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My original intention was to provide a more eye-catching entry on the secondary page.

{{end}}
</div>
{{end}}
{{if and .IsOrganizationOwner .IsOrganizationMember}}
<div class="divider"></div>
{{end}}
<div class="ui stackable grid">
{{template "org/team/sidebar" .}}
<div class="ui ten wide column">
Expand Down
14 changes: 14 additions & 0 deletions web_src/js/features/org-team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import {fomanticQuery} from '../modules/fomantic/base.ts';

const {appSubUrl} = window.config;

function initOrgTeamAddMember() {
const modal = document.querySelector('#add-member-to-team-modal');
if (!modal) return;
const elDropdown = modal.querySelector('.team_add_member_team_search');
const form = elDropdown.closest('form');
const baseUrl = form.getAttribute('data-action-base-link');
const teamInput = form.querySelector<HTMLInputElement>('input[name=team]');
const onChangeTeam = function() {
form.setAttribute('action', `${baseUrl}/teams/${teamInput.value}/action/add`);
};
fomanticQuery(elDropdown).dropdown('setting', 'onChange', onChangeTeam);
}

function initOrgTeamSettings() {
// on the page "page-content organization new team"
const pageContent = document.querySelector('.page-content.organization.new.team');
Expand Down Expand Up @@ -39,6 +52,7 @@ function initOrgTeamSearchRepoBox() {

export function initOrgTeam() {
if (!document.querySelector('.page-content.organization')) return;
initOrgTeamAddMember();
initOrgTeamSettings();
initOrgTeamSearchRepoBox();
}