Skip to content

Commit

Permalink
Merge pull request #46 from kaishuu0123/feat/re-36-search-keyword-for…
Browse files Browse the repository at this point in the history
…-backlogs-and-kanban

refs RE-36: Search tickets on master backlog and Kanban page
  • Loading branch information
kaishuu0123 authored Dec 12, 2019
2 parents 7f104f3 + da7ab82 commit 4aee55c
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 28 deletions.
19 changes: 17 additions & 2 deletions app/javascript/components/backlogs/BacklogsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
:emptyInsertThreshold="40"
:data-sprint-id="null"
@end="dragEnd">
<StoryListItem :story="story" v-for="story in stories" :key="story.id" :data-story-id="story.id" />
<StoryListItem :story="story" v-for="story in searchStoryByKeyword(stories)" :key="story.id" :data-story-id="story.id" />
<li v-if="stories.length == 0" class="list-group-item rb-alert-primary px-3 py-2">
<div class="d-flex align-items-center">
<i class="fas fa-info-circle mr-1"></i> {{ $t('message.storyDoesNotExists') }}
Expand All @@ -39,7 +39,8 @@ export default {
name: 'BacklogsCard',
props: {
projectId: String,
stories: Array
stories: Array,
searchKeyword: String,
},
components: {
StoryListItem,
Expand Down Expand Up @@ -83,6 +84,20 @@ export default {
storyId, storyId
})
},
searchStoryByKeyword(stories) {
return stories.filter(story => {
return this.searchKeyword.toLowerCase()
.split(/\s+/)
.map(query => {
return (
story.ticket_number_with_ticket_prefix.toLowerCase().indexOf(query) > -1
|| story.title.toLowerCase().indexOf(query) > -1
|| story.tags.some(tag => tag.name.toLowerCase().indexOf(query) > -1)
)
})
.every(result => result === true)
});
},
...mapActions([
'createSprint',
'updateStoryByDrag'
Expand Down
19 changes: 17 additions & 2 deletions app/javascript/components/backlogs/SprintCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
:emptyInsertThreshold="40"
:data-sprint-id="sprint.id"
@end="dragEnd">
<StoryListItem v-for="story in sprint.stories" :key="story.id" :story="story" :data-story-id="story.id" />
<StoryListItem v-for="story in searchStoryByKeyword(sprint.stories)" :key="story.id" :story="story" :data-story-id="story.id" />
<li v-if="sprint.stories.length == 0" class="list-group-item rb-alert-primary px-3 py-2">
<div class="d-flex align-items-center">
<i class="fas fa-info-circle mr-1"></i> {{ $t('message.storyDoesNotExistsInSprint') }}
Expand Down Expand Up @@ -109,7 +109,8 @@ export default {
},
props: {
sprint: Object,
projectId: String
projectId: String,
searchKeyword: String,
},
mounted () {
this.dirtySprint = this.sprint
Expand Down Expand Up @@ -205,6 +206,20 @@ export default {
storyId: storyId
})
},
searchStoryByKeyword(stories) {
return stories.filter(story => {
return this.searchKeyword.toLowerCase()
.split(/\s+/)
.map(query => {
return (
story.ticket_number_with_ticket_prefix.toLowerCase().indexOf(query) > -1
|| story.title.toLowerCase().indexOf(query) > -1
|| (story.tags && story.tags.some(tag => tag.name.toLowerCase().indexOf(query) > -1))
)
})
.every(result => result === true)
});
},
...mapActions({
updateSprint: 'updateSprint',
updateStoryByDrag: 'updateStoryByDrag',
Expand Down
6 changes: 4 additions & 2 deletions app/javascript/i18n/globals.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"horizontal": "Horizontal",
"task": "Task",
"tag": "Tags",
"unassigned": "Unassigned"
"unassigned": "Unassigned",
"search": "Search by keyword"
},
"ticket": {
"title": "Title",
Expand Down Expand Up @@ -138,7 +139,8 @@
"horizontal": "水平",
"task": "タスク",
"tag": "タグ",
"unassigned": "未アサイン"
"unassigned": "未アサイン",
"search": "キーワード検索"
},
"ticket": {
"title": "タイトル",
Expand Down
40 changes: 26 additions & 14 deletions app/javascript/pages/BacklogsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,38 @@
<div class="d-flex w-100 align-items-center justify-content-between mb-2">
<h1 class="h4 mb-0 text-gray-700">{{ $t('title.masterBacklogs')}}</h1>
<div class="d-flex align-items-center">
<span class="h6 mb-0 mr-2">{{ $t('title.layout') }}: </span>
<b-form-radio-group
id="layout-radios"
v-model="layout"
:options="layoutOptions"
buttons
button-variant="outline-secondary"
size="sm"
name="radio-btn-outline"
></b-form-radio-group>
<div class="d-flex align-items-center mr-2">
<b-form-input
id="searchInput"
v-model="searchKeyword"
type="text"
size="sm"
:placeholder="$t('title.search')"
></b-form-input>
</div>
<div class="d-flex align-items-center">
<span class="h6 mb-0 mr-2">{{ $t('title.layout') }}: </span>
<b-form-radio-group
id="layout-radios"
v-model="layout"
:options="layoutOptions"
buttons
button-variant="outline-secondary"
size="sm"
name="radio-btn-outline"
></b-form-radio-group>
</div>
</div>
</div>
</div>

<div class="row" v-if="layout === 'HORIZONTAL'">
<div class="row flex-row flex-sm-nowrap w-100 rb-overflow-x" >
<div class="col-6">
<BacklogsCard :stories='storiesInBacklogs' :projectId='projectId' />
<BacklogsCard :stories='storiesInBacklogs' :projectId='projectId' :searchKeyword="searchKeyword" />
</div>
<div v-for="sprint in sprints" :key="sprint.id" class="col-6">
<SprintCard class="mb-3" :sprint="sprint" :projectId="projectId" />
<SprintCard class="mb-3" :sprint="sprint" :projectId="projectId" :searchKeyword="searchKeyword" />
</div>
<div v-if="sprints.length <= 0" class="col-6">
<div class="rb-alert-primary mt-2 p-3 border rounded rb-border-dotted">
Expand All @@ -42,15 +53,15 @@
</div>
<div class="row" v-else>
<div v-if="sprints.length > 0" class="col-6">
<SprintCard class="mb-3" v-for="sprint in sprints" :key="sprint.id" :sprint="sprint" :projectId="projectId" />
<SprintCard class="mb-3" v-for="sprint in sprints" :key="sprint.id" :sprint="sprint" :projectId="projectId" :searchKeyword="searchKeyword" />
</div>
<div v-else class="col-6">
<div class="w-100 rb-alert-primary mt-2 p-3 border rounded rb-border-dotted">
<p class="m-0"><i class="fas fa-info-circle mr-1"></i> {{ $t('message.sprintDoesNotExists')}} </p>
</div>
</div>
<div class="col-6">
<BacklogsCard :stories='storiesInBacklogs' :projectId='projectId' />
<BacklogsCard :stories='storiesInBacklogs' :projectId='projectId' :searchKeyword="searchKeyword" />
</div>
</div>

Expand Down Expand Up @@ -78,6 +89,7 @@ export default {
projectId: null,
newStory: false,
layout: 'DEFAULT',
searchKeyword: '',
layoutOptions: [
{
text: this.$t('title.default'),
Expand Down
53 changes: 45 additions & 8 deletions app/javascript/pages/KanbanPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,28 @@
loader="dots"></loading>

<div class="row mb-2 bg-light sticky-top">
<nav class="navbar px-1 py-0 navbar-light">
<nav class="navbar navbar-expand-md px-1 py-0 navbar-light w-100">
<a class="navbar-brand text-gray-700" href="#">{{ sprintTitle }}</a>
<ul class="navbar-nav">
<li class="nav-item">
<a :href="`/projects/${projectId}`" class="nav-link"><i class="fas fa-angle-double-left"></i> {{ $t('action.backToBacklogs') }}</a>
</li>
</ul>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="fas fa-bars"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a :href="`/projects/${projectId}`" class="nav-link"><i class="fas fa-angle-double-left"></i> {{ $t('action.backToBacklogs') }}</a>
</li>
</ul>
<div>
<b-form-input
id="searchInput"
v-model="searchKeyword"
type="text"
size="sm"
:placeholder="$t('title.search')"
></b-form-input>
</div>
</div>
</nav>
</div>
<div class="row">
Expand All @@ -27,7 +42,7 @@
</th>
</tr>
</thead>
<tbody v-for="story in stories" :key="story.id">
<tbody v-for="story in searchStoryAndTaskByKeyword(stories)" :key="story.id">
<tr>
<td :colspan="statusesLength" class="border-bottom-0">
<div class="d-flex align-items-center">
Expand Down Expand Up @@ -128,7 +143,8 @@ export default {
projectId: null,
sprintId: null,
sprintTitle: null,
newTask: false
newTask: false,
searchKeyword: ''
}
},
mounted() {
Expand Down Expand Up @@ -255,6 +271,27 @@ export default {
color: this.idealTextColor(color)
}
},
searchStoryAndTaskByKeyword(stories) {
return stories.filter(story => {
return this.searchKeyword.toLowerCase()
.split(/\s+/)
.map(query => {
return (
story.ticket_number_with_ticket_prefix.toLowerCase().indexOf(query) > -1
|| story.title.toLowerCase().indexOf(query) > -1
|| (story.tags && story.tags.some(tag => tag.name.toLowerCase().indexOf(query) > -1))
|| story.tasks.some((task) => {
return (
task.ticket_number_with_ticket_prefix.toLowerCase().indexOf(query) > -1
|| task.title.toLowerCase().indexOf(query) > -1
|| (task.assignee && task.assignee.username.toLowerCase().indexOf(query) > -1)
)
})
)
})
.every(result => result === true)
});
},
...mapMutations({
setSprintId: 'SET_SPRINT_ID',
setProjectId: 'SET_PROJECT_ID'
Expand Down

0 comments on commit 4aee55c

Please sign in to comment.