Commit 577b6f4c authored by Justin Ho's avatar Justin Ho

Add FilteredSearchBar for search and sort

- Use Vue component to avoid needing to refresh the page
- Allow search (free text) and sort
- Only show for Jira issues
parent 02f27285
......@@ -12,8 +12,10 @@ import {
import { __ } from '~/locale';
import initManualOrdering from '~/manual_ordering';
import Issuable from './issuable.vue';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import {
sortOrderMap,
availableSortOptionsJira,
RELATIVE_POSITION,
PAGE_SIZE,
PAGE_SIZE_MANUAL,
......@@ -29,6 +31,7 @@ export default {
GlPagination,
GlSkeletonLoading,
Issuable,
FilteredSearchBar,
},
props: {
canBulkEdit: {
......@@ -50,14 +53,25 @@ export default {
type: String,
required: true,
},
projectPath: {
type: String,
required: false,
default: '',
},
sortKey: {
type: String,
required: false,
default: '',
},
type: {
type: String,
required: false,
default: '',
},
},
data() {
return {
availableSortOptionsJira,
filters: {},
isBulkEditing: false,
issuables: [],
......@@ -141,6 +155,22 @@ export default {
nextPage: this.paginationNext,
};
},
isJira() {
return this.type === 'jira';
},
initialFilterValue() {
const value = [];
const { search } = this.getQueryObject();
if (search) {
value.push(search);
}
return value;
},
initialSortBy() {
const { sort } = this.getQueryObject();
return sort || 'created_desc';
},
},
watch: {
selection() {
......@@ -262,11 +292,51 @@ export default {
this.filters = filters;
},
refetchIssuables() {
const ignored = ['utf8', 'state'];
const params = omit(this.filters, ignored);
historyPushState(setUrlParams(params, window.location.href, true));
this.fetchIssuables();
},
handleFilter(filters) {
let search = null;
filters.forEach(filter => {
if (typeof filter === 'string') {
search = filter;
}
});
this.filters.search = search;
this.page = 1;
this.refetchIssuables();
},
handleSort(sort) {
this.filters.sort = sort;
this.page = 1;
this.refetchIssuables();
},
},
};
</script>
<template>
<div>
<filtered-search-bar
v-if="isJira"
:namespace="projectPath"
:search-input-placeholder="__('Search Jira issues')"
:tokens="[]"
:sort-options="availableSortOptionsJira"
:initial-filter-value="initialFilterValue"
:initial-sort-by="initialSortBy"
class="row-content-block"
@onFilter="handleFilter"
@onSort="handleSort"
/>
<ul v-if="loading" class="content-list">
<li v-for="n in $options.LOADING_LIST_ITEMS_LENGTH" :key="n" class="issue gl-px-5! gl-py-5!">
<gl-skeleton-loading />
......@@ -309,4 +379,5 @@ export default {
:primary-button-link="emptyState.primaryLink"
:primary-button-text="emptyState.primaryText"
/>
</div>
</template>
import { __ } from '~/locale';
// Maps sort order as it appears in the URL query to API `order_by` and `sort` params.
const PRIORITY = 'priority';
const ASC = 'asc';
......@@ -31,3 +33,22 @@ export const sortOrderMap = {
weight_desc: { order_by: WEIGHT, sort: DESC },
weight: { order_by: WEIGHT, sort: ASC },
};
export const availableSortOptionsJira = [
{
id: 1,
title: __('Created date'),
sortDirection: {
descending: 'created_desc',
ascending: 'created_asc',
},
},
{
id: 2,
title: __('Last updated'),
sortDirection: {
descending: 'updated_desc',
ascending: 'updated_asc',
},
},
];
......@@ -3,4 +3,6 @@
.js-issuables-list{ data: { endpoint: expose_path(project_integrations_jira_issues_path(@project, format: :json)),
'can-bulk-edit': false,
'empty-svg-path': image_path('illustrations/issues.svg'),
'sort-key': @sort } }
'sort-key': @sort,
type: 'jira',
project_path: @project.full_path, } }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment