Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom sort #1404

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
212 changes: 169 additions & 43 deletions lib/nav/page-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@
}

.page-list-header {
@include type-list-header();

height: auto;
justify-content: start;
padding: 0;

&:hover {
background-color: transparent;
}

&-site {
flex: 0 0 $site-column;
}
Expand Down Expand Up @@ -111,13 +121,19 @@
}

&-collaborators {
cursor: default;
display: none;
flex: 0 0 $collaborators-column;

@media screen and (min-width: $all-columns-sidebar) {
display: inline;
}
}

& > .ui-button__content {
font-weight: normal;
justify-content: start;
}
}
}

Expand Down Expand Up @@ -152,10 +168,20 @@
</div>
<div class="page-list-headers">
<span v-if="multipleSitesSelected" class="page-list-header page-list-header-site">Site</span>
<span class="page-list-header page-list-header-title">Title</span>
<span class="page-list-header page-list-header-byline">Byline</span>
<span class="page-list-header page-list-header-status">Status</span>
<span class="page-list-header page-list-header-collaborators">Collaborators</span>
<ui-button
v-for="header in headerTitles"
:key="header.key"
buttonType="button"
:class="[`page-list-header page-list-header-${header.key}`]"
disableRipple
:icon="sortBy === header.sortField ? sortIcon : null"
iconPosition="right"
size="small"
type="secondary"
@click="header.key !== 'collaborators' && sortByField(header.sortField)"
>
{{ header.title }}
</ui-button>
</div>
<div class="page-list-readout">
<page-list-item
Expand Down Expand Up @@ -185,7 +211,9 @@
import statusSelector from './status-selector.vue';
import pageListItem from './page-list-item.vue';

const DEFAULT_QUERY_SIZE = 50;
const DEFAULT_QUERY_SIZE = 50,
SORT_DESC = 'desc',
SORT_ASC = 'asc';

/**
* get data for all sites, and format it into something we can use
Expand Down Expand Up @@ -216,21 +244,30 @@
* @param {string} username
* @return {object}
*/
function buildQuery({ siteFilter, queryText, queryUser, offset, statusFilter, isMyPages, username }) { // eslint-disable-line
function buildQuery({ siteFilter, queryText, queryUser, offset, statusFilter, isMyPages, username, sortBy, sortOrder }) { // eslint-disable-line
let query = {
index: 'pages',
body: {
size: DEFAULT_QUERY_SIZE,
from: offset,
sort: {
updateTime: {
order: 'desc'
}
[sortBy]: { order: sortOrder }
},
query: {}
}
};

// Status sorting is handled differently,
// we have to deal with boolean properties
if (sortBy === 'status') {
query.body.sort = {
published: { order: sortOrder },
publishTime: { order: sortOrder },
scheduled: { order: sortOrder },
scheduledTime: { order: sortOrder }
};
}

_.set(query, 'body.query.bool.must', []);

// filter for only "My Pages", and filter users
Expand Down Expand Up @@ -359,7 +396,26 @@
sites: getInitialSites.call(this),
pages: [],
selectedStatus: _.get(this.$store, 'state.url.status', 'all'),
isPopoverOpen: false
isPopoverOpen: false,
sortBy: 'title.raw',
sortOrder: 'desc',
fxisco marked this conversation as resolved.
Show resolved Hide resolved
headerTitles: [{
title: 'Title',
key: 'title',
sortField: 'title.raw'
}, {
title: 'Byline',
key: 'byline',
sortField: 'authors.raw'
}, {
title: 'Status',
key: 'status',
sortField: 'status'
}, {
title: 'Collaborators',
key: 'collaborators',
sortField: 'users'
}]
};
},
computed: {
Expand Down Expand Up @@ -388,15 +444,34 @@
const user = this.query.match(/user:(\S+)/i);

return user ? user[1] : '';
},
sortIcon() {
return this.sortOrder === SORT_DESC ? 'arrow_downward' : 'arrow_upward';
}
},
methods: {
/**
* Sets the isPopoverOpen prop to true
* when the popover is opened
* @returns {void}
*/
onPopoverOpen() {
this.isPopoverOpen = true;
},
/**
* Sets the isPopoverOpen prop to false
* when the popover is closed
* @returns {void}
*/
onPopoverClose() {
this.isPopoverOpen = false;
},
/**
* Sets the selected site in the state
* and refetches the pages
* @param {String} slug
* @returns {void}
*/
selectSite(slug) {
const site = _.find(this.sites, (s) => s.slug === slug);

Expand All @@ -405,12 +480,23 @@
this.offset = 0;
this.fetchPages();
},
/**
* Sets the selected sites is there are multiple selected
fxisco marked this conversation as resolved.
Show resolved Hide resolved
* @param {String[]} allSites
* @returns {void}
*/
selectMultipleSites(allSites) {
this.sites = _.map(this.sites, (site) => {
site.selected = allSites;
return site;
});
},
/**
* Sets the selected site in the state
* and refetches the pages
* @param {String} slug
* @returns {void}
*/
setSingleSite(slug) {
// loop through all sites, making sure that only one is selected
_.each(this.sites, (site) => {
Expand All @@ -430,54 +516,94 @@
this.offset = 0;
this.fetchPages();
}, 300),
/**
* Sets the selected status in the state
* and refetches the pages
* @param {String} status
* @returns {void}
*/
selectStatus(status) {
this.selectedStatus = status;

this.$store.commit('FILTER_PAGELIST_STATUS', this.selectedStatus);
this.offset = 0;
this.fetchPages();
},
/**
* Sets the built query in the state
* and refetches the pages
* @param {Object} query
* @returns {void}
*/
setQuery(query) {
this.query = query;
this.offset = 0;
this.fetchPages();
},
/**
* Sets the sort order and sort field in the state
* and refetches the pages
* @param {String} field
* @returns {void}
*/
sortByField(field) {
this.sortOrder = this.sortBy === field ? this.toggleSortOrder(this.sortOrder) : SORT_ASC;
this.sortBy = field;
this.offset = 0;

this.fetchPages();
},
/**
* Toggles the sort order between ascending and descending
* @param {String} order
* @returns {String}
*/
toggleSortOrder(order) {
return order === SORT_DESC ? SORT_ASC : SORT_DESC;
},
/**
* Makes a query to ES to fetch for all pages
* @returns {Promise}
*/
fetchPages() {
const siteFilter = _.map(this.selectedSites, (site) => site.slug),
queryText = this.queryText,
queryUser = this.queryUser,
offset = this.offset,
const {
isMyPages,
offset,
queryText,
queryUser,
selectedSites,
selectedStatus: statusFilter,
sortBy,
sortOrder
} = this,
siteFilter = _.map(selectedSites, (site) => site.slug),
prefix = _.get(this.$store, 'state.site.prefix'),
isMyPages = this.isMyPages,
username = _.get(this.$store, 'state.user.username'),
statusFilter = this.selectedStatus,
query = buildQuery({ siteFilter, queryText, queryUser, offset, statusFilter, isMyPages, username });

return postJSON(prefix + searchRoute, query).then((res) => {
const hits = _.get(res, 'hits.hits') || [],
total = _.get(res, 'hits.total'),
pages = _.map(hits, (hit) => Object.assign({}, hit._source, { uri: hit._id }));

if (offset === 0) {
this.pages = pages;
} else {
this.pages = this.pages.concat(pages);
}

this.offset = offset + pages.length;
this.total = total; // update the total for this particular query
// (it's used to hide the "load more" button)

// set the url hash
if (_.get(this.$store, 'state.ui.currentDrawer')) {
this.$store.dispatch('setHash', { menu: {
tab: isMyPages ? 'my-pages' : 'all-pages',
sites: siteFilter.join(','),
status: statusFilter,
query: this.query
}});
}
});
query = buildQuery({ siteFilter, queryText, queryUser, offset, statusFilter, isMyPages, username, sortBy, sortOrder });

return postJSON(prefix + searchRoute, query)
.then((res) => {
const hits = _.get(res, 'hits.hits') || [],
total = _.get(res, 'hits.total'),
pages = _.map(hits, (hit) => Object.assign({}, hit._source, { uri: hit._id }));

this.pages = offset === 0 ? pages : this.pages.concat(pages);

this.offset = offset + pages.length;
this.total = total; // update the total for this particular query
// (it's used to hide the "load more" button)

// set the url hash
if (_.get(this.$store, 'state.ui.currentDrawer')) {
this.$store.dispatch('setHash', { menu: {
tab: isMyPages ? 'my-pages' : 'all-pages',
sites: siteFilter.join(','),
status: statusFilter,
query: this.query
}});
}
})
.catch((e) => console.error(e));
}
},
mounted() {
Expand Down
Loading