File tree Expand file tree Collapse file tree 7 files changed +67
-7
lines changed Expand file tree Collapse file tree 7 files changed +67
-7
lines changed Original file line number Diff line number Diff line change @@ -1248,8 +1248,12 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
12481248
12491249 if opts .LabelIDs != nil {
12501250 for i , labelID := range opts .LabelIDs {
1251- sess .Join ("INNER" , fmt .Sprintf ("issue_label il%d" , i ),
1252- fmt .Sprintf ("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d" , i , labelID ))
1251+ if labelID > 0 {
1252+ sess .Join ("INNER" , fmt .Sprintf ("issue_label il%d" , i ),
1253+ fmt .Sprintf ("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d" , i , labelID ))
1254+ } else {
1255+ sess .Where ("issue.id not in (select issue_id from issue_label where label_id = ?)" , - labelID )
1256+ }
12531257 }
12541258 }
12551259}
Original file line number Diff line number Diff line change @@ -72,6 +72,7 @@ type Label struct {
7272 IsChecked bool `xorm:"-"`
7373 QueryString string `xorm:"-"`
7474 IsSelected bool `xorm:"-"`
75+ IsExcluded bool `xorm:"-"`
7576}
7677
7778// APIFormat converts a Label to the api.Label format
@@ -97,7 +98,10 @@ func (label *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64)
9798 for _ , s := range currentSelectedLabels {
9899 if s == label .ID {
99100 labelSelected = true
100- } else if s > 0 {
101+ } else if - s == label .ID {
102+ labelSelected = true
103+ label .IsExcluded = true
104+ } else if s != 0 {
101105 labelQuerySlice = append (labelQuerySlice , strconv .FormatInt (s , 10 ))
102106 }
103107 }
Original file line number Diff line number Diff line change @@ -802,6 +802,7 @@ issues.delete_branch_at = `deleted branch <b>%s</b> %s`
802802issues.open_tab = %d Open
803803issues.close_tab = %d Closed
804804issues.filter_label = Label
805+ issues.filter_label_exclude = `Use <code>alt</code> + <code>click/enter</code> to exclude labels`
805806issues.filter_label_no_select = All labels
806807issues.filter_milestone = Milestone
807808issues.filter_milestone_no_select = All milestones
Original file line number Diff line number Diff line change @@ -458,6 +458,8 @@ i.icon.centerlock{top:1.5em}
458458.repository .filter .menu .label .color {border-radius : 3px ;margin-left : 15px ;padding : 0 8px }
459459.repository .filter .menu .octicon {float : left;margin : 5px -7px 0 -5px ;width : 16px }
460460.repository .filter .menu .labels .octicon {margin : -2px -7px 0 -5px }
461+ .repository .filter .menu .labels .label-filter .menu .info {display : inline-block;padding : 9px 7px 7px 7px ;text-align : center;border-bottom : 1px solid # ccc ;font-size : 12px }
462+ .repository .filter .menu .labels .label-filter .menu .info code {border : 1px solid # ccc ;border-radius : 3px ;padding : 3px 2px 1px 2px ;font-size : 11px }
461463.repository .filter .menu .text {margin-left : .9em }
462464.repository .filter .menu .menu {max-height : 300px ;overflow-x : auto;right : 0 !important ;left : auto!important }
463465.repository .filter .menu .dropdown .item {margin : 1px ;padding-right : 0 }
Original file line number Diff line number Diff line change @@ -3278,8 +3278,39 @@ function initIssueList() {
32783278 } ,
32793279
32803280 fullTextSearch : true
3281- } )
3282- ;
3281+ } ) ;
3282+
3283+ $ ( ".menu a.label-filter-item" ) . each ( function ( ) {
3284+ $ ( this ) . click ( function ( e ) {
3285+ if ( e . altKey ) {
3286+ const href = $ ( this ) . attr ( "href" ) ;
3287+ const id = $ ( this ) . data ( "label-id" ) ;
3288+
3289+ const regStr = "labels=(-?[0-9]+%2c)*(" + id + ")(%2c-?[0-9]+)*&" ;
3290+ const newStr = "labels=$1-$2$3&" ;
3291+
3292+ window . location = href . replace ( new RegExp ( regStr ) , newStr ) ;
3293+ }
3294+ } ) ;
3295+ } ) ;
3296+
3297+ $ ( ".menu .ui.dropdown.label-filter" ) . keydown ( function ( e ) {
3298+ if ( e . altKey && e . keyCode == 13 ) {
3299+ const selectedItems = $ ( ".menu .ui.dropdown.label-filter .menu .item.selected" ) ;
3300+
3301+ if ( selectedItems . length > 0 ) {
3302+ const item = $ ( selectedItems [ 0 ] ) ;
3303+
3304+ const href = item . attr ( "href" ) ;
3305+ const id = item . data ( "label-id" ) ;
3306+
3307+ const regStr = "labels=(-?[0-9]+%2c)*(" + id + ")(%2c-?[0-9]+)*&" ;
3308+ const newStr = "labels=$1-$2$3&" ;
3309+
3310+ window . location = href . replace ( new RegExp ( regStr ) , newStr ) ;
3311+ }
3312+ }
3313+ } ) ;
32833314}
32843315function cancelCodeComment ( btn ) {
32853316 const form = $ ( btn ) . closest ( "form" ) ;
Original file line number Diff line number Diff line change 158158 margin : -2px -7px 0 -5px ;
159159 }
160160
161+ & .labels {
162+ .label-filter .menu .info {
163+ display : inline-block ;
164+ padding : 9px 7px 7px 7px ;
165+ text-align : center ;
166+ border-bottom : 1px solid #cccccc ;
167+ font-size : 12px ;
168+
169+ code {
170+ border : 1px solid #cccccc ;
171+ border-radius : 3px ;
172+ padding : 3px 2px 1px 2px ;
173+ font-size : 11px ;
174+ }
175+ }
176+ }
177+
161178 .text {
162179 margin-left : 0.9em ;
163180 }
Original file line number Diff line number Diff line change 4242 <div class="ten wide right aligned column">
4343 <div class="ui secondary filter stackable menu labels">
4444 <!-- Label -->
45- <div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item" style="margin-left: auto">
45+ <div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item label-filter " style="margin-left: auto">
4646 <span class="text">
4747 {{.i18n.Tr "repo.issues.filter_label"}}
4848 <i class="dropdown icon"></i>
4949 </span>
5050 <div class="menu">
51+ <span class="info">{{.i18n.Tr "repo.issues.filter_label_exclude" | Safe}}</span>
5152 <a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a>
5253 {{range .Labels}}
53- <a class="item has-emoji" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.QueryString}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}"><span class="octicon {{if .IsSelected}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
54+ <a class="item has-emoji label-filter-item " href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.QueryString}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" data-label-id="{{.ID}}" ><span class="octicon {{if .IsExcluded}}octicon-circle-slash{{else if .IsSelected}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
5455 {{end}}
5556 </div>
5657 </div>
You can’t perform that action at this time.
0 commit comments