diff --git a/src/App.vue b/src/App.vue index 7ed4c2d..3e3f778 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,9 +1,18 @@ diff --git a/src/main.js b/src/main.js index 953122c..b4059db 100644 --- a/src/main.js +++ b/src/main.js @@ -9,10 +9,10 @@ import 'bootstrap/dist/js/bootstrap.min.js'; // fontawesome import { library } from '@fortawesome/fontawesome-svg-core'; -import { faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown } from '@fortawesome/free-solid-svg-icons'; +import { faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown, faTh, faList } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; -library.add(faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown); +library.add(faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown, faTh, faList); Vue.component('font-awesome-icon', FontAwesomeIcon); diff --git a/src/mixins/data-container.js b/src/mixins/data-container.js new file mode 100644 index 0000000..b50760d --- /dev/null +++ b/src/mixins/data-container.js @@ -0,0 +1,39 @@ +import * as R from 'ramda'; + +export default { + props: ['columns', 'items', 'keyName'], + data: (self) => ({ + sortBy: self.keyName, + ascend: true, + filters: R.fromPairs(self.columns.map(column => [column, ''])) + }), + computed: { + internalItems() { + const filtered = this.items.filter(item => this.columns + .map(column => { + const field = item[column] + ''; + const filter = this.filters[column]; + return field.includes(filter); + }).reduce((acc, nxt) => acc && nxt, true) + ); + const sortByOrd = R.sortBy(R.prop(this.sortBy)); + const sorted = sortByOrd(filtered, [this.sortBy]); + return this.ascend ? sorted : R.reverse(sorted); + } + }, + methods: { + getSortIcon(column) { + if (column !== this.sortBy) return 'sort'; + if (this.ascend) return 'sort-up'; + return 'sort-down'; + }, + toggleSort(column) { + if (column === this.sortBy) + this.ascend = !this.ascend; + this.sortBy = column; + }, + setFilter(column, filter) { + this.filters[column] = filter; + } + } +}; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 280edb9..5afc522 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -7,6 +7,7 @@ export default new Vuex.Store({ state: { events: ['35c3', 'camp19', '36c3'], activeEvent: '36c3', + layout: 'cards', loadedItems: [ { uid: 1, description: 'sleeping bag', box: 7, image: 41 }, { uid: 2, description: 'tent', box: 7, image: 23 }, @@ -14,16 +15,27 @@ export default new Vuex.Store({ { uid: 4, description: 'power supply black', box: 5, image: 62 }, { uid: 5, description: 'pullover yellow "pesthörnchen"', box: 5, image: 84 }, { uid: 6, description: '"blue black second skin"', box: 6, image: 72 }, - { uid: 7, description: '"the bike blog" bottle orange', box: 6, image: 71 } + { uid: 7, description: '"the bike blog" bottle orange', box: 6, image: 71 }, + { uid: 8, description: 'tshirt guad3c', box: 6, image: 26 }, + { uid: 9, description: 'power supply dell', box: 6, image: 74 }, + { uid: 10, description: 'blanket green blue', box: 6, image: 25 }, + { uid: 11, description: 'cap "ega"', box: 6, image: 71 }, + { uid: 12, description: 'water bottle blue "sistema"', box: 3, image: 12 }, + { uid: 13, description: 'sun hat black', box: 5, image: 1 }, + { uid: 14, description: 'toy truck', box: 6, image: 51 } ] }, mutations: { changeEvent(state, event) { state.activeEvent = event; + }, + setLayout(state, layout) { + state.layout = layout; } }, actions: { changeEvent({ commit }, event) { + // todo: load items from server // todo: load items from server commit('changeEvent', event); }