Skip to content
This repository has been archived by the owner on Jul 22, 2022. It is now read-only.

Search stories by tags and content #259

Open
wants to merge 1 commit into
base: master
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
17 changes: 17 additions & 0 deletions app/assets/javascripts/fulcrum.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
_.mixin({
queryParams: function(queryString) {
var params = {};
var queries;
var temp;

queries = queryString.split('&');

for (var i = 0, l = queries.length; i < l; i++) {
temp = queries[i].split('=');
params[temp[0]] = decodeURIComponent(temp[1].replace(/\+/g, ' '));
}

return params;
}
});

$(function() {
$('#add_story').click(function() {
window.projectView.newStory();
Expand Down
24 changes: 24 additions & 0 deletions app/assets/javascripts/models/story.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ Fulcrum.Story = Backbone.Model.extend({

},

matchesSearch: function(params) {
var matchesTags = true;
var matchesText = true;

if (params.tags) {
var myTags = this.labels();

matchesTags = _.every(params.tags.split(','), function(tag) {
return _.contains(myTags, tag);
})
}

if (params.text) {
var description = this.get('description');
var title = this.get('title');
var text = params.text.toLowerCase();

matchesText = (description && description.toLowerCase().indexOf(text) > -1) ||
(title && title.toLowerCase().indexOf(text) > -1);
}

return matchesTags && matchesText;
},

changeState: function(model, new_value) {
if (new_value == "started" && !this.get('owned_by_id')) {
model.set({owned_by_id: model.collection.project.current_user.id}, true);
Expand Down
14 changes: 14 additions & 0 deletions app/assets/javascripts/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
if (typeof Fulcrum == 'undefined') {
Fulcrum = {};
}

Fulcrum.Router = Backbone.Router.extend({

routes: {
'search?:params': 'search',
'': 'home'
}

});

Fulcrum.appRouter = new Fulcrum.Router();
1 change: 1 addition & 0 deletions app/assets/javascripts/templates/search.jst.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input type="text" placeholder="Search...">
4 changes: 3 additions & 1 deletion app/assets/javascripts/templates/story.jst.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
</span>
</div>
<div class="story-title">
<% if (story.get('labels')) { %><span class="tags"><%= story.escape('labels') %></span><% } %>
<% _.each(story.labels(), function(label) { %>
<a class="tag" href="#search?tags=<%= label %>"><%= label %></a>
<% }); %>
<%= story.escape('title') %>
<% if (story.owned_by()) { %>
<abbr class="initials" title="<%= story.owned_by().escape('name') %>">
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/views/project_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Fulcrum.ProjectView = Backbone.View.extend({
if (_.isUndefined(column) || !_.isString(column)) {
column = story.column;
}

var view = new Fulcrum.StoryView({model: story}).render();
this.appendViewToColumn(view, column);
view.setFocus();
Expand Down
62 changes: 62 additions & 0 deletions app/assets/javascripts/views/search_view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
if (typeof Fulcrum == 'undefined') {
Fulcrum = {};
}

Fulcrum.SearchView = Backbone.View.extend({

TAGS_REGEX: /tags:([a-z,]*)/i,

template: JST['templates/search'],

events: {
'change input': 'search'
},

initialize: function() {
var that = this;

Fulcrum.appRouter.on('route:search', function(params) {
params = _.queryParams(params);
var search = '';

if (params.tags) {
search = 'tags:' + params.tags + ' ';
}

if (params.text) {
search += params.text;
}

that.input.val(search);
});
},

render: function() {
this.$el.html(this.template);
this.input = this.$el.find('input');

return this;
},

search: function() {
var params = this.input.val();
var tags = this.TAGS_REGEX.exec(params);
var options = {};

if (tags) {
options.tags = tags[1];
params = params.replace(tags[0], '');
}

if (params) {
options.text = params.trim();
}

if (params || tags) {
Fulcrum.appRouter.navigate('search?' + $.param(options), {trigger: true});
} else {
Fulcrum.appRouter.navigate('/', {trigger: true});
}
}

});
33 changes: 28 additions & 5 deletions app/assets/javascripts/views/story_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Fulcrum.StoryView = Fulcrum.FormView.extend({
initialize: function() {
_.bindAll(this, "render", "highlight", "moveColumn", "setClassName",
"transition", "estimate", "disableForm", "renderNotes",
"renderNotesCollection", "addEmptyNote");
"renderNotesCollection", "addEmptyNote", 'searchFromRoute');

// Rerender on any relevant change to the views story
this.model.bind("change", this.render);
Expand All @@ -37,6 +37,8 @@ Fulcrum.StoryView = Fulcrum.FormView.extend({
// remove itself from the page when destroy() gets called.
this.model.view = this;

Fulcrum.appRouter.on('all', this.searchFromRoute);

if (this.model.id) {
this.id = this.el.id = this.model.id;
this.$el.attr('id', 'story-' + this.id);
Expand All @@ -58,9 +60,27 @@ Fulcrum.StoryView = Fulcrum.FormView.extend({
"click input.estimate": "estimate",
"click #destroy": "clear",
"click #edit-description": "editDescription",
"click .tag": 'tagClicked',
"sortupdate": "sortUpdate"
},

searchFromRoute: function(route, params) {
if (route !== 'route:search') {
return this.$el.show();
}

var matched = this.model.matchesSearch(_.queryParams(params));
this.$el.toggle(matched);

if (matched) {
$(this.model.column).parent().show();
}
},

tagClicked: function(event) {
event.stopPropagation();
},

// Triggered whenever a story is dropped to a new position
sortUpdate: function(ev, ui) {

Expand Down Expand Up @@ -334,8 +354,6 @@ Fulcrum.StoryView = Fulcrum.FormView.extend({
})
);



this.$el.append(
this.makeFormControl(function(div) {
$(div).append(this.label("description", "Description"));
Expand All @@ -361,13 +379,18 @@ Fulcrum.StoryView = Fulcrum.FormView.extend({
);

this.initTags();

this.renderNotes();

} else {
this.$el.removeClass('editing');
this.$el.html(this.template({story: this.model, view: this}));
}

var route = Backbone.history.getFragment().split('?');

if (route[0] === 'search') {
this.searchFromRoute('route:search', route[1]);
}

this.hoverBox();
return this;
},
Expand Down
13 changes: 11 additions & 2 deletions app/assets/stylesheets/screen.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,18 @@ ul#primary-nav li.secondary ul li {
margin: 0;
padding: 10px 1em;

#right-side {
float: right;
}

#search {
display: inline-block;
margin-right: 15px;
}

div.velocity {
display: inline-block;
font-size: 1.6em;
float: right;
position: relative;

div.velocity_override_container {
Expand Down Expand Up @@ -490,7 +499,7 @@ a.button:hover {
color: white;
text-shadow: $darkgrey 0 1px 0;
}
.tags{
.tag{
color:$sky-blue-3;
font-size:84%;
}
Expand Down
12 changes: 11 additions & 1 deletion app/views/projects/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ $(function() {
new Fulcrum.ColumnVisibilityButtonView({columnView: chillyBinColumn, elementId: 'chilly_bin'}).render().el
);

new Fulcrum.SearchView({
el: $('#search')
}).render();

// FIXME Move to view
// Connect up drag and drop behaviour
$('#backlog').sortable('option', 'connectWith', '#chilly_bin,#in_progress');
Expand Down Expand Up @@ -68,11 +72,17 @@ $(function() {
image: '<%= image_path('dialog-warning.png') %>'
});
<% end %>

Backbone.history.start();
});
</script>

<% content_for :title_bar do %>
<div id="velocity" class="velocity"></div>
<div id="right-side">
<div id="search"></div>
<div id="velocity" class="velocity"></div>
</div>

<%= render :partial => 'projects/nav',
:locals => {:project => @project, :show_column_toggles => true} %>
| <a id="add_story" href="#"><%= t('add story') %></a>
Expand Down
1 change: 1 addition & 0 deletions config/locales/el.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ el:
accepted: γίνουν αποδεκτές
rejected: απορριφθούν
delivered: παραδοθούν
search: Αναζήτηση ...

author unknown: "αγνωστος"
add story: "νέα ιστορία"
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ en:
points: "Points"
saving: "Saving ..."
expand: "Expand"
search: "Search..."

author unknown: "Author Unknown"
add story: "Add story"
Expand Down
1 change: 1 addition & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ es:
back: "Atras"
import: "Importa"
export: "Exporta"
search: "Busca..."

author unknown: "Autor desconocido"

Expand Down
1 change: 1 addition & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ja:
points: "ポイント"
saving: "保存中…"
expand: "広げる"
search: "検索..."

author unknown: "作者不明"
add story: "ストーリー追加"
Expand Down
1 change: 1 addition & 0 deletions config/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ nl:
points: "Punten"
saving: "Opslaan ..."
expand: "Uitvouwen"
search: "Zoeken ..."

author unknown: "Auteur Onbekend"
add story: "Voeg verhaal toe"
Expand Down
1 change: 1 addition & 0 deletions config/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pt-BR:
points: "Pontos"
saving: "Salvando ..."
expand: "Expandir"
search: "Pesquisa..."

author unknown: "Autor Desconhecido"
add story: "Adicionar história"
Expand Down