@@ -30,6 +30,7 @@ import Router from '../issues/router'; | |||
import WorkspaceListView from '../issues/workspace-list-view'; | |||
import WorkspaceHeaderView from '../issues/workspace-header-view'; | |||
import FacetsView from './../issues/facets-view'; | |||
import HeaderView from './../issues/HeaderView'; | |||
const App = new Marionette.Application(); | |||
const init = function () { | |||
@@ -73,6 +74,11 @@ const init = function () { | |||
}); | |||
this.layout.facetsRegion.show(this.facetsView); | |||
this.headerView = new HeaderView({ | |||
app: this | |||
}); | |||
this.layout.filtersRegion.show(this.headerView); | |||
key.setScope('list'); | |||
App.router = new Router({ app: App }); | |||
Backbone.history.start(); |
@@ -0,0 +1,61 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import Marionette from 'backbone.marionette'; | |||
import Template from './templates/facets/issues-my-issues-facet.hbs'; | |||
export default Marionette.ItemView.extend({ | |||
template: Template, | |||
className: 'issues-header-inner', | |||
events: { | |||
'change [name="issues-page-my"]': 'onMyIssuesChange' | |||
}, | |||
initialize () { | |||
this.listenTo(this.options.app.state, 'change:query', this.render); | |||
}, | |||
onMyIssuesChange () { | |||
const mode = this.$('[name="issues-page-my"]:checked').val(); | |||
if (mode === 'my') { | |||
this.options.app.state.updateFilter({ | |||
assigned_to_me: 'true', | |||
assignees: null, | |||
assigned: null | |||
}); | |||
} else { | |||
this.options.app.state.updateFilter({ | |||
assigned_to_me: null, | |||
assignees: null, | |||
assigned: null | |||
}); | |||
} | |||
}, | |||
serializeData () { | |||
const me = !!this.options.app.state.get('query').assigned_to_me; | |||
return { | |||
...Marionette.ItemView.prototype.serializeData.apply(this, arguments), | |||
me, | |||
isContext: this.options.app.state.get('isContext'), | |||
user: window.SS.user | |||
}; | |||
} | |||
}); | |||
@@ -29,6 +29,7 @@ import Router from './router'; | |||
import WorkspaceListView from './workspace-list-view'; | |||
import WorkspaceHeaderView from './workspace-header-view'; | |||
import FacetsView from './facets-view'; | |||
import HeaderView from './HeaderView'; | |||
const App = new Marionette.Application(); | |||
const init = function () { | |||
@@ -63,6 +64,11 @@ const init = function () { | |||
}); | |||
this.layout.facetsRegion.show(this.facetsView); | |||
this.headerView = new HeaderView({ | |||
app: this | |||
}); | |||
this.layout.filtersRegion.show(this.headerView); | |||
key.setScope('list'); | |||
App.router = new Router({ app: App }); | |||
Backbone.history.start(); |
@@ -26,14 +26,6 @@ import ComponentViewer from './component-viewer/main'; | |||
const FACET_DATA_FIELDS = ['components', 'users', 'rules', 'languages']; | |||
export default Controller.extend({ | |||
_facetsFromServer () { | |||
const facets = Controller.prototype._facetsFromServer.apply(this, arguments) || []; | |||
if (facets.indexOf('assignees') !== -1) { | |||
facets.push('assigned_to_me'); | |||
} | |||
return facets; | |||
}, | |||
_issuesParameters () { | |||
return { | |||
p: this.options.app.state.get('page'), | |||
@@ -45,15 +37,6 @@ export default Controller.extend({ | |||
}; | |||
}, | |||
_myIssuesFromResponse (r) { | |||
const myIssuesData = _.findWhere(r.facets, { property: 'assigned_to_me' }); | |||
if ((myIssuesData != null) && _.isArray(myIssuesData.values) && myIssuesData.values.length > 0) { | |||
return this.options.app.state.set({ myIssues: myIssuesData.values[0].count }, { silent: true }); | |||
} else { | |||
return this.options.app.state.unset('myIssues', { silent: true }); | |||
} | |||
}, | |||
fetchList (firstPage) { | |||
const that = this; | |||
if (firstPage == null) { | |||
@@ -65,6 +48,9 @@ export default Controller.extend({ | |||
} | |||
const data = this._issuesParameters(); | |||
_.extend(data, this.options.app.state.get('query')); | |||
if (this.options.app.state.get('query').assigned_to_me) { | |||
_.extend(data, { assignees: '__me__' }); | |||
} | |||
if (this.options.app.state.get('isContext')) { | |||
_.extend(data, this.options.app.state.get('contextQuery')); | |||
} | |||
@@ -80,10 +66,7 @@ export default Controller.extend({ | |||
that.options.app.facets[field] = r[field]; | |||
}); | |||
that.options.app.facets.reset(that._allFacets()); | |||
that.options.app.facets.add(_.reject(r.facets, function (f) { | |||
return f.property === 'assigned_to_me'; | |||
}), { merge: true }); | |||
that._myIssuesFromResponse(r); | |||
that.options.app.facets.add(r.facets, { merge: true }); | |||
that.enableFacets(that._enabledFacets()); | |||
if (firstPage) { | |||
that.options.app.state.set({ | |||
@@ -117,9 +100,6 @@ export default Controller.extend({ | |||
requestFacet (id) { | |||
const that = this; | |||
if (id === 'assignees') { | |||
return this.requestAssigneeFacet(); | |||
} | |||
const facet = this.options.app.facets.get(id); | |||
const data = _.extend({ facets: id, ps: 1, additionalFields: '_all' }, this.options.app.state.get('query')); | |||
if (this.options.app.state.get('isContext')) { | |||
@@ -136,26 +116,6 @@ export default Controller.extend({ | |||
}); | |||
}, | |||
requestAssigneeFacet () { | |||
const that = this; | |||
const facet = this.options.app.facets.get('assignees'); | |||
const data = _.extend({ facets: 'assignees,assigned_to_me', ps: 1, additionalFields: '_all' }, | |||
this.options.app.state.get('query')); | |||
if (this.options.app.state.get('isContext')) { | |||
_.extend(data, this.options.app.state.get('contextQuery')); | |||
} | |||
return $.get(window.baseUrl + '/api/issues/search', data, function (r) { | |||
FACET_DATA_FIELDS.forEach(function (field) { | |||
that.options.app.facets[field] = that._mergeCollections(that.options.app.facets[field], r[field]); | |||
}); | |||
const facetData = _.findWhere(r.facets, { property: 'assignees' }); | |||
that._myIssuesFromResponse(r); | |||
if (facetData != null) { | |||
return facet.set(facetData); | |||
} | |||
}); | |||
}, | |||
newSearch () { | |||
this.options.app.state.unset('filter'); | |||
return this.options.app.state.setQuery({ resolved: 'false' }); |
@@ -56,12 +56,14 @@ export default CustomValuesFacet.extend({ | |||
const value = checked ? 'false' : null; | |||
return this.options.app.state.updateFilter({ | |||
assigned: value, | |||
assignees: null | |||
assignees: null, | |||
assigned_to_me: null | |||
}); | |||
} else { | |||
return this.options.app.state.updateFilter({ | |||
assigned: null, | |||
assignees: this.getValue() | |||
assignees: this.getValue(), | |||
assigned_to_me: null | |||
}); | |||
} | |||
}, | |||
@@ -110,13 +112,8 @@ export default CustomValuesFacet.extend({ | |||
}); | |||
}, | |||
getNumberOfMyIssues () { | |||
return this.options.app.state.get('myIssues'); | |||
}, | |||
serializeData () { | |||
return _.extend(CustomValuesFacet.prototype.serializeData.apply(this, arguments), { | |||
myIssues: this.getNumberOfMyIssues(), | |||
values: this.sortValues(this.getValuesWithLabels()) | |||
}); | |||
} |
@@ -17,6 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import $ from 'jquery'; | |||
import _ from 'underscore'; | |||
import BaseFacet from './base-facet'; | |||
import Template from '../templates/facets/issues-mode-facet.hbs'; | |||
@@ -24,13 +25,11 @@ import Template from '../templates/facets/issues-mode-facet.hbs'; | |||
export default BaseFacet.extend({ | |||
template: Template, | |||
events: { | |||
'change [name="issues-page-mode"]': 'onModeChange' | |||
}, | |||
onModeChange () { | |||
const mode = this.$('[name="issues-page-mode"]:checked').val(); | |||
this.options.app.state.updateFilter({ facetMode: mode }); | |||
toggleFacet (e) { | |||
const isCount = $(e.currentTarget).is('[data-value="count"]'); | |||
return this.options.app.state.updateFilter({ | |||
facetMode: isCount ? 'count' : 'effort' | |||
}); | |||
}, | |||
serializeData () { |
@@ -21,12 +21,13 @@ import $ from 'jquery'; | |||
import _ from 'underscore'; | |||
import Marionette from 'backbone.marionette'; | |||
import Template from './templates/issues-layout.hbs'; | |||
import './styles.css'; | |||
export default Marionette.LayoutView.extend({ | |||
template: Template, | |||
regions: { | |||
filtersRegion: '.search-navigator-filters', | |||
filtersRegion: '.issues-header', | |||
facetsRegion: '.search-navigator-facets', | |||
workspaceHeaderRegion: '.search-navigator-workspace-header', | |||
workspaceListRegion: '.search-navigator-workspace-list', | |||
@@ -34,9 +35,6 @@ export default Marionette.LayoutView.extend({ | |||
}, | |||
onRender () { | |||
if (this.options.app.state.get('isContext')) { | |||
this.$(this.filtersRegion.el).addClass('hidden'); | |||
} | |||
this.$('.search-navigator').addClass('sticky'); | |||
const top = this.$('.search-navigator').offset().top; | |||
this.$('.search-navigator-workspace-header').css({ top }); |
@@ -0,0 +1,16 @@ | |||
.issues-header-inner { | |||
padding: 32px 10px 15px; | |||
background-color: #f3f3f3; | |||
text-align: center; | |||
} | |||
.issues-header-inner:empty { | |||
display: none; | |||
} | |||
.issues-header-order { | |||
display: inline-block; | |||
vertical-align: top; | |||
margin-right: 20px; | |||
font-size: 12px; | |||
} |
@@ -1,16 +1,6 @@ | |||
{{> "_issues-facet-header"}} | |||
<div class="search-navigator-facet-list"> | |||
{{#notNull myIssues}} | |||
<a class="facet search-navigator-facet js-facet" data-value="__me__" title="{{t "me"}}"> | |||
<span class="facet-name">{{t "me"}}</span> | |||
<span class="facet-stat"> | |||
{{formatFacetValue myIssues state.facetMode}} | |||
</span> | |||
</a> | |||
<hr> | |||
{{/notNull}} | |||
{{#each values}} | |||
{{#eq val ""}} | |||
{{! unassigned }} |
@@ -1,14 +1,15 @@ | |||
<div class="issues-facet-mode"> | |||
<ul class="radio-toggle"> | |||
<li> | |||
<input type="radio" name="issues-page-mode" value="count" id="issues-page-mode-count" | |||
{{#eq mode 'count'}}checked{{/eq}}> | |||
<label for="issues-page-mode-count">{{t 'issues.facet.mode.issues'}}</label> | |||
</li> | |||
<li> | |||
<input type="radio" name="issues-page-mode" value="effort" id="issues-page-mode-effort" | |||
{{#eq mode 'effort'}}checked{{/eq}}> | |||
<label for="issues-page-mode-effort">{{t 'issues.facet.mode.effort'}}</label> | |||
</li> | |||
</ul> | |||
<div class="search-navigator-facet-header"> | |||
{{t 'issues.facet.mode'}} | |||
</div> | |||
<div class="search-navigator-facet-list"> | |||
<a class="facet search-navigator-facet search-navigator-facet-half js-facet {{#eq mode 'count'}}active{{/eq}}" | |||
data-value="count"> | |||
<span class="facet-name">{{t 'issues.facet.mode.issues'}}</span> | |||
</a> | |||
<a class="facet search-navigator-facet search-navigator-facet-half js-facet {{#eq mode 'effort'}}active{{/eq}}" | |||
data-value="effort"> | |||
<span class="facet-name">{{t 'issues.facet.mode.effort'}}</span> | |||
</a> | |||
</div> |
@@ -0,0 +1,12 @@ | |||
{{#if user}} | |||
<ul class="radio-toggle"> | |||
<li> | |||
<input type="radio" name="issues-page-my" value="my" id="issues-page-my-my" {{#if me}}checked{{/if}}> | |||
<label for="issues-page-my-my">My Issues</label> | |||
</li> | |||
<li> | |||
<input type="radio" name="issues-page-my" value="all" id="issues-page-my-all" {{#unless me}}checked{{/unless}}> | |||
<label for="issues-page-my-all">All</label> | |||
</li> | |||
</ul> | |||
{{/if}} |
@@ -1,8 +1,6 @@ | |||
<div class="issues search-navigator"> | |||
<div class="search-navigator-side"> | |||
<div class="search-navigator-filters"> | |||
<h1 class="page-title">{{t "issues"}}</h1> | |||
</div> | |||
<div class="issues-header"></div> | |||
<div class="search-navigator-facets"></div> | |||
</div> | |||
@@ -773,6 +773,7 @@ issues.facet.createdAt.last_month=Last month | |||
issues.facet.createdAt.last_year=Last year | |||
issues.facet.authors=Author | |||
issues.facet.issues=Issue Key | |||
issues.facet.mode=Display Mode | |||
issues.facet.mode.issues=Issues | |||
issues.facet.mode.effort=Effort | |||