Merge branch '437-sorting-collections' into 'master'

Resolve "Sorting Collections"

Closes #437

See merge request les/gancio!55
This commit is contained in:
les 2024-08-19 10:14:14 +00:00
commit d773db650f
5 changed files with 61 additions and 10 deletions

View file

@ -146,7 +146,9 @@ v-container
)
template(v-slot:item.pin='{ item }')
v-switch.float-right(:input-value='item.isTop' @change="togglePinCollection(item)" inset hide-details)
template(v-slot:item.actions='{ item }')
template(v-slot:item.actions='{ item, index }')
v-btn(v-if='index>0' icon color='warn' @click.stop='moveUp(item)')
v-icon(v-text='mdiChevronUp')
v-btn(@click='editCollection(item)' color='primary' icon)
v-icon(v-text='mdiPencil')
v-btn(@click='removeCollection(item)' color='error' icon)
@ -160,13 +162,13 @@ import debounce from 'lodash/debounce'
import isEqual from 'lodash/isEqual'
import sortBy from 'lodash/sortBy'
import { mdiPencil, mdiChevronLeft, mdiChevronRight, mdiMagnify, mdiPlus, mdiTagMultiple, mdiMapMarker, mdiDeleteForever,
import { mdiPencil, mdiChevronLeft, mdiChevronRight, mdiMagnify, mdiPlus, mdiTagMultiple, mdiMapMarker, mdiDeleteForever, mdiChevronUp,
mdiCloseCircle, mdiChevronDown, mdiWeb, mdiInformation, mdiNotEqualVariant, mdiEqualBox } from '@mdi/js'
export default {
data({ $store }) {
return {
mdiPencil, mdiChevronRight, mdiChevronLeft, mdiMagnify, mdiPlus, mdiTagMultiple, mdiMapMarker, mdiDeleteForever,
mdiPencil, mdiChevronRight, mdiChevronLeft, mdiMagnify, mdiPlus, mdiTagMultiple, mdiMapMarker, mdiDeleteForever, mdiChevronUp,
mdiCloseCircle, mdiChevronDown, mdiWeb, mdiInformation, mdiEqualBox, mdiNotEqualVariant,
loading: false,
dialog: false,
@ -278,13 +280,22 @@ export default {
this.$fetch()
this.loading = false
},
async moveUp (collection) {
try {
await this.$axios.$put(`/collection/moveup/${collection.sortIndex}`)
this.$fetch()
} catch (e) {
const err = get(e, 'response.data.errors[0].message', e)
this.$root.$message(this.$t(err), { color: 'error' })
}
},
async togglePinCollection (collection) {
try {
await this.$axios.$put(`/collection/toggle/${collection.id}`)
collection.isTop = !collection.isTop
} catch (e) {
const err = get(e, 'response.data.errors[0].message', e)
this.$root.$message(this.$t(err), { color: 'error' })
this.$root.$message(this.$t(err), { color: 'error' })
}
},
async editFilter(filter) {

View file

@ -13,12 +13,12 @@ const collectionController = {
const pin = req.query.pin
let collections
if (withFilters) {
collections = await Collection.findAll({ include: [ Filter ] })
collections = await Collection.findAll({ include: [ Filter ], order: [['sortIndex', 'asc']] })
} else {
if (pin) {
collections = await Collection.findAll({ where: { isTop: true }})
collections = await Collection.findAll({ where: { isTop: true }, order: [['sortIndex','asc']]})
} else {
collections = await Collection.findAll()
collections = await Collection.findAll({ order: [['sortIndex', 'asc']]})
}
}
@ -26,7 +26,22 @@ const collectionController = {
},
async _getVisible () {
return Collection.findAll({ attributes: ['name', 'id'], where: { isTop: true }, raw: true })
return Collection.findAll({ attributes: ['name', 'id'], where: { isTop: true }, raw: true, order: [['sortIndex', 'asc']] })
},
async moveUp (req, res) {
const sortIndex = Number(req.params.sort_index)
try {
const collections = await Collection.findAll({ where: { sortIndex: { [Op.lte]: sortIndex } }, limit: 2, order:[['sortIndex', 'desc']] })
if (collections.length !== 2) { return res.sendStatus(404) }
const tmpSortIndex = collections[0].sortIndex
await collections[0].update({ sortIndex: collections[1].sortIndex })
await collections[1].update({ sortIndex: tmpSortIndex })
res.sendStatus(200)
} catch (e) {
log.error(e)
res.sendStatus(404)
}
},
async togglePin (req, res) {
@ -213,6 +228,7 @@ const collectionController = {
log.info(`Create collection: ${req.body.name}`)
try {
const collection = await Collection.create(collectionDetail)
await collection.update({ sortIndex: collection.id })
res.json(collection)
} catch (e) {
log.error(`Create collection failed ${e}`)
@ -286,8 +302,6 @@ const collectionController = {
}
},
}
module.exports = collectionController

View file

@ -233,6 +233,7 @@ module.exports = () => {
api.post('/collections', isAdmin, collectionController.add)
api.delete('/collection/:id', isAdmin, collectionController.remove)
api.put('/collection/toggle/:id', isAdmin, collectionController.togglePin)
api.put('/collection/moveup/:sort_index', isAdmin, collectionController.moveUp)
api.get('/filter/:collection_id', isAdmin, collectionController.getFilters)
api.post('/filter', isAdmin, collectionController.addFilter)
api.put('/filter/:id', isAdmin, collectionController.updateFilter)

View file

@ -16,5 +16,8 @@ module.exports = (sequelize, DataTypes) =>
},
isTop: { // is this collection shown in top navbar in home page?
type: DataTypes.BOOLEAN
},
sortIndex: {
type: DataTypes.INTEGER,
}
}, { timestamps: false })

View file

@ -0,0 +1,22 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up (queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction()
try {
await queryInterface.addColumn('collections', 'sortIndex', { type: Sequelize.INTEGER })
await queryInterface.sequelize.query('UPDATE collections set sortIndex=id')
return transaction.commit()
} catch (e) {
if (transaction) {
await transaction.rollback()
}
return Promise.reject(e)
}
},
async down (queryInterface, Sequelize) {
return queryInterface.removeColumn('collections', 'sortIndex')
}
}