Skip to content
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

Scoped label display improvements #23164

Closed
wants to merge 12 commits into from
Closed
13 changes: 9 additions & 4 deletions models/issues/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,22 @@ func (l *Label) UseLightTextColor() bool {
}

// Return scope substring of label name, or empty string if none exists
func (l *Label) ExclusiveScope() string {
if !l.Exclusive {
return ""
}
func (l *Label) Scope() string {
lastIndex := strings.LastIndex(l.Name, "/")
if lastIndex == -1 || lastIndex == 0 || lastIndex == len(l.Name)-1 {
return ""
}
return l.Name[:lastIndex]
}

// Return scope for exclusive labels, or empty string if none exists
func (l *Label) ExclusiveScope() string {
if !l.Exclusive {
return ""
}
return l.Scope()
}

// NewLabel creates a new label
func NewLabel(ctx context.Context, l *Label) error {
color, err := label.NormalizeColor(l.Color)
Expand Down
6 changes: 2 additions & 4 deletions modules/templates/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ func RenderIssueTitle(ctx context.Context, text, urlPrefix string, metas map[str

// RenderLabel renders a label
func RenderLabel(ctx context.Context, label *issues_model.Label) string {
labelScope := label.ExclusiveScope()
labelScope := label.Scope()

textColor := "#111"
if label.UseLightTextColor() {
Expand All @@ -834,7 +834,7 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) string {
// Make scope and item background colors slightly darker and lighter respectively.
// More contrast needed with higher luminance, empirically tweaked.
luminance := (0.299*r + 0.587*g + 0.114*b) / 255
contrast := 0.01 + luminance*0.06
contrast := 0.01 + luminance*0.03
// Ensure we add the same amount of contrast also near 0 and 1.
darken := contrast + math.Max(luminance+contrast-1.0, 0.0)
lighten := contrast + math.Max(contrast-luminance, 0.0)
Expand All @@ -859,12 +859,10 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) string {

return fmt.Sprintf("<span class='ui label scope-parent' title='%s'>"+
"<div class='ui label scope-left' style='color: %s !important; background-color: %s !important'>%s</div>"+
"<div class='ui label scope-middle' style='background: linear-gradient(-80deg, %s 48%%, %s 52%% 0%%);'>&nbsp;</div>"+
delvh marked this conversation as resolved.
Show resolved Hide resolved
"<div class='ui label scope-right' style='color: %s !important; background-color: %s !important''>%s</div>"+
"</span>",
description,
textColor, scopeColor, scopeText,
itemColor, scopeColor,
textColor, itemColor, itemText)
}

Expand Down
45 changes: 45 additions & 0 deletions templates/repo/issue/labels/labels_selector_field.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-label dropdown">
<a class="text gt-df gt-ac muted">
<strong>{{.locale.Tr "repo.issues.new.labels"}}</strong>
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
{{svg "octicon-gear" 16 "gt-ml-2"}}
{{end}}
</a>
<div class="filter menu" {{if .Issue}}data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/labels"{{else}}data-id="#label_ids"{{end}}>
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_labels_title"}}</div>
{{if or .Labels .OrgLabels}}
<div class="ui icon search input">
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_labels"}}">
delvh marked this conversation as resolved.
Show resolved Hide resolved
</div>
{{end}}
<a class="no-select item" href="#">{{.locale.Tr "repo.issues.new.clear_labels"}}</a>
{{if or .Labels .OrgLabels}}
{{$previousScope := "_no_scope"}}
{{range .Labels}}
{{$scope := .Scope}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousScope "_no_scope") (ne $previousScope $scope)}}
<div class="ui divider"></div>
{{end}}
{{$previousScope = $scope}}
lafriks marked this conversation as resolved.
Show resolved Hide resolved
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context .}}
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}</a>
{{end}}
<div class="ui divider"></div>
{{$previousScope := "_no_scope"}}
{{range .OrgLabels}}
{{$scope := .Scope}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousScope "_no_scope") (ne $previousScope $scope)}}
<div class="ui divider"></div>
{{end}}
{{$previousScope = $scope}}
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context .}}
delvh marked this conversation as resolved.
Show resolved Hide resolved
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}</a>
{{end}}
{{else}}
<div class="header" style="text-transform: none;font-size:14px;">{{.locale.Tr "repo.issues.new.no_items"}}</div>
{{end}}
</div>
</div>
20 changes: 10 additions & 10 deletions templates/repo/issue/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@
</div>
<span class="info">{{.locale.Tr "repo.issues.filter_label_exclude" | Safe}}</span>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_label_no_select"}}</a>
{{$previousExclusiveScope := "_no_scope"}}
{{$previousScope := "_no_scope"}}
{{range .Labels}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
{{$scope := .Scope}}
{{if and (ne $previousScope "_no_scope") (ne $previousScope $scope)}}
<div class="ui divider"></div>
{{end}}
{{$previousExclusiveScope = $exclusiveScope}}
<a class="item label-filter-item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.QueryString}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}" data-label-id="{{.ID}}">{{if .IsExcluded}}{{svg "octicon-circle-slash"}}{{else if .IsSelected}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}}</a>
{{$previousScope = $scope}}
<a class="item label-filter-item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.QueryString}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}" data-label-id="{{.ID}}">{{if .IsExcluded}}{{svg "octicon-circle-slash"}}{{else if .IsSelected}}{{if .ExclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}}</a>
delvh marked this conversation as resolved.
Show resolved Hide resolved
{{end}}
</div>
</div>
Expand Down Expand Up @@ -224,15 +224,15 @@
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
</span>
<div class="menu">
{{$previousExclusiveScope := "_no_scope"}}
{{$previousScope := "_no_scope"}}
{{range .Labels}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
{{$scope := .Scope}}
{{if and (ne $previousScope "_no_scope") (ne $previousScope $scope)}}
<div class="ui divider"></div>
{{end}}
{{$previousExclusiveScope = $exclusiveScope}}
{{$previousScope = $scope}}
<div class="item issue-action" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels">
{{if contain $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}}
{{if contain $.SelLabelIDs .ID}}{{if .ExclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}}
delvh marked this conversation as resolved.
Show resolved Hide resolved
</div>
{{end}}
</div>
Expand Down
45 changes: 1 addition & 44 deletions templates/repo/issue/new_form.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -36,50 +36,7 @@
{{template "repo/issue/branch_selector_field" .}}

<input id="label_ids" name="label_ids" type="hidden" value="{{.label_ids}}">
brechtvl marked this conversation as resolved.
Show resolved Hide resolved
<div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating jump select-label dropdown">
<span class="text">
<strong>{{.locale.Tr "repo.issues.new.labels"}}</strong>
{{if .HasIssuesOrPullsWritePermission}}
{{svg "octicon-gear"}}
{{end}}
</span>
<div class="filter menu" data-id="#label_ids">
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_labels_title"}}</div>
{{if or .Labels .OrgLabels}}
<div class="ui icon search input">
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_labels"}}">
</div>
{{end}}
<div class="no-select item">{{.locale.Tr "repo.issues.new.clear_labels"}}</div>
{{if or .Labels .OrgLabels}}
{{$previousExclusiveScope := "_no_scope"}}
{{range .Labels}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
<div class="ui divider"></div>
{{end}}
{{$previousExclusiveScope = $exclusiveScope}}
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context .}}
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}</a>
{{end}}

<div class="ui divider"></div>
{{$previousExclusiveScope := "_no_scope"}}
{{range .OrgLabels}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
<div class="ui divider"></div>
{{end}}
{{$previousExclusiveScope = $exclusiveScope}}
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context .}}
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}</a>
{{end}}
{{else}}
<div class="header" style="text-transform: none;font-size:14px;">{{.locale.Tr "repo.issues.new.no_items"}}</div>
{{end}}
</div>
</div>
{{template "repo/issue/labels/labels_selector_field" .}}
{{template "repo/issue/labels/labels_sidebar" dict "root" $}}

<div class="ui divider"></div>
Expand Down
44 changes: 1 addition & 43 deletions templates/repo/issue/view_content/sidebar.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -106,49 +106,7 @@
<div class="ui divider"></div>
{{end}}

<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-label dropdown">
<a class="text gt-df gt-ac muted">
<strong>{{.locale.Tr "repo.issues.new.labels"}}</strong>
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
{{svg "octicon-gear" 16 "gt-ml-2"}}
{{end}}
</a>
<div class="filter menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/labels">
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_labels_title"}}</div>
{{if or .Labels .OrgLabels}}
<div class="ui icon search input">
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_labels"}}">
</div>
{{end}}
<a class="no-select item" href="#">{{.locale.Tr "repo.issues.new.clear_labels"}}</a>
{{if or .Labels .OrgLabels}}
{{$previousExclusiveScope := "_no_scope"}}
{{range .Labels}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
<div class="ui divider"></div>
{{end}}
{{$previousExclusiveScope = $exclusiveScope}}
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context .}}
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}</a>
{{end}}
<div class="ui divider"></div>
{{$previousExclusiveScope := "_no_scope"}}
{{range .OrgLabels}}
{{$exclusiveScope := .ExclusiveScope}}
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
<div class="ui divider"></div>
{{end}}
{{$previousExclusiveScope = $exclusiveScope}}
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span>&nbsp;&nbsp;{{RenderLabel $.Context .}}
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}</a>
{{end}}
{{else}}
<div class="header" style="text-transform: none;font-size:14px;">{{.locale.Tr "repo.issues.new.no_items"}}</div>
{{end}}
</div>
</div>
{{template "repo/issue/labels/labels_selector_field" .}}
{{template "repo/issue/labels/labels_sidebar" dict "root" $}}

<div class="ui divider"></div>
Expand Down
15 changes: 2 additions & 13 deletions web_src/less/_repository.less
Original file line number Diff line number Diff line change
Expand Up @@ -2838,11 +2838,11 @@

.labels-list .label {
margin: 2px 0;
display: inline-block !important;
display: inline-flex !important;
line-height: 1.3em; // there is a `font-size: 1.25em` for inside emoji, so here the line-height needs to be larger slightly
}

// Scoped labels with different colors on left and right, and slanted divider in the middle
// Scoped labels with different colors on left and right
.scope-parent {
background: none !important;
padding: 0 !important;
Expand All @@ -2851,23 +2851,12 @@
.ui.label.scope-left {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
padding-right: 0;
margin-right: 0;
}

.ui.label.scope-middle {
width: 12px;
border-radius: 0;
padding-left: 0;
padding-right: 0;
margin-left: 0;
margin-right: 0;
}

.ui.label.scope-right {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
padding-left: 0;
margin-left: 0;
}

Expand Down