diff --git a/package-lock.json b/package-lock.json index 8e7ac21..878d597 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vue-datasource", - "version": "2.0.1", + "version": "2.0.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -348,9 +348,9 @@ "dev": true }, "axios": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.16.2.tgz", - "integrity": "sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.0.tgz", + "integrity": "sha1-fadHkW24A/dhZR1gkdcIeJuVPGo=", "requires": { "follow-redirects": "1.2.5", "is-buffer": "1.1.5" @@ -6019,7 +6019,8 @@ "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true }, "lodash._arraycopy": { "version": "3.0.0", diff --git a/package.json b/package.json index b37c6f8..387a311 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ ], "homepage": "https://github.com/coderdiaz/vue-datasource#readme", "dependencies": { + "axios": "^0.17.0", "vue": "^2.2.6" }, "devDependencies": { diff --git a/src/App.vue b/src/App.vue index 5b3ffac..6c8a7aa 100644 --- a/src/App.vue +++ b/src/App.vue @@ -23,11 +23,13 @@ export default { columns: [ { name: 'Id', - key: 'id' + key: 'id', + order: true }, { name: 'First Name', - key: 'first_name' + key: 'first_name', + order: true }, { name: 'Last Name', diff --git a/src/assets/icon-sort-asc.svg b/src/assets/icon-sort-asc.svg new file mode 100644 index 0000000..2775f9e --- /dev/null +++ b/src/assets/icon-sort-asc.svg @@ -0,0 +1,3 @@ +<?xml version="1.0" ?><svg id="Слой_1" style="enable-background:new 0 0 139 139;" version="1.1" viewBox="0 0 139 139" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css"> + .st0{fill:none;stroke:#000000;stroke-width:6;stroke-miterlimit:10;} +</style><line class="st0" id="XMLID_7_" x1="18" x2="121" y1="34.8" y2="34.8"/><line class="st0" id="XMLID_8_" x1="95.2" x2="18" y1="69.5" y2="69.5"/><line class="st0" id="XMLID_9_" x1="69.5" x2="18" y1="104.2" y2="104.2"/></svg> \ No newline at end of file diff --git a/src/assets/icon-sort-desc.svg b/src/assets/icon-sort-desc.svg new file mode 100644 index 0000000..56cde9c --- /dev/null +++ b/src/assets/icon-sort-desc.svg @@ -0,0 +1,3 @@ +<?xml version="1.0" ?><svg id="Слой_1" style="enable-background:new 0 0 139 139;" version="1.1" viewBox="0 0 139 139" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css"> + .st0{fill:none;stroke:#000000;stroke-width:6;stroke-miterlimit:10;} +</style><line class="st0" id="XMLID_7_" x1="18" x2="121" y1="104.2" y2="104.2"/><line class="st0" id="XMLID_8_" x1="95.2" x2="18" y1="69.5" y2="69.5"/><line class="st0" id="XMLID_9_" x1="69.5" x2="18" y1="34.8" y2="34.8"/></svg> \ No newline at end of file diff --git a/src/components/ClientDatasource.vue b/src/components/ClientDatasource.vue deleted file mode 100644 index d2e7e38..0000000 --- a/src/components/ClientDatasource.vue +++ /dev/null @@ -1,47 +0,0 @@ -<script> -import DatasourceUtils from '../utils/DatasourceUtils' -import Pagination from './Pagination.vue' -import { EventBus } from '../utils/EventBus' -export default { - name: 'ClientDatasource', - components: { - Pagination - }, - render (h) { - return (<div class="vue-client-datasource"></div>) - }, - data () { - return { - perpage: 10, - selected: null, // row and Object selected on click event - indexSelected: -1, // index row selected on click event - search: '' // word to search in the table - } - } -} -</script> -<style scoped> -.vue-datasource .panel-body { - padding: 0 -} - -.vue-datasource table { - margin-bottom: 0 -} - -.vue-datasource .panel-footer .btn-group-actions { - margin: 10px 0 -} - -.pr1 { - padding-right: 5px -} - -.pr2 { - padding-right: 10px; -} - -.mr1 { - margin-right: 5px; -} -</style> \ No newline at end of file diff --git a/src/components/ServerDatasource.vue b/src/components/ServerDatasource.vue index 7ca9c63..7171f5a 100644 --- a/src/components/ServerDatasource.vue +++ b/src/components/ServerDatasource.vue @@ -1,7 +1,9 @@ <script> -import DatasourceUtils from '../utils/DatasourceUtils' +import DatasourceUtils from '@/utils/DatasourceUtils' import Pagination from './Pagination' -import {EventBus} from '../utils/EventBus' +import {EventBus} from '@/utils/EventBus' +import IconAsc from '@/assets/icon-sort-asc.svg' +import IconDesc from '@/assets/icon-sort-desc.svg' export default { name: 'ServerDatasource', components: {Pagination}, @@ -124,7 +126,11 @@ export default { current_page: 1, selected: null, // row and Object selected on click event indexSelected: -1, // index row selected on click event - search: '' // word to search in the table, + search: '', // word to search in the table, + columnSortSelected: { // Object to set a column sort data + key: null, + order: true + } } }, computed: { @@ -134,8 +140,24 @@ export default { }) }, columnItems () { + let showArrows = (key) => { + if (this.columnSortSelected.key) { + return (this.shouldShowUpArrow(key)) ? <img class="arrow-active" src={IconAsc} width="15"/> + : <img class="arrow-active" src={IconDesc} width="15"/> + } else { + return <img src={IconDesc} width="15"/> + } + } + return this.columns.map((column, index) => { - return <th>{column.name}</th> + if (column.order) { + return <th class="vue-server-ordering" on-click={(e) => this.sortColumn(e, column.key)}> + {column.name} + <span class="vue-server-arrows">{showArrows(column.key)}</span> + </th> + } else { + return <th>{column.name}</th> + } }) }, columnObjects () { @@ -182,7 +204,10 @@ export default { this.indexSelected = -1 this.current_page = 1 this.$emit('searching', e.target.value) - } + }, + sortColumn: DatasourceUtils.sortColumn, + shouldShowUpArrow: DatasourceUtils.shouldShowUpArrow, + shouldShowDownArrow: DatasourceUtils.shouldShowDownArrow }, watch: { /** @@ -208,8 +233,29 @@ export default { position: relative; padding: 0; } + .vue-server-arrows { + position: absolute; + right: 5px; + top: 6px; + } table { margin-bottom: 0; + th { + position: relative; + + &.vue-server-ordering { + cursor: pointer; + + .vue-server-arrows { + img { + opacity: .3; + &.arrow-active { + opacity: 1; + } + } + } + } + } } .panel-footer { .btn-group-actions { diff --git a/src/utils/DatasourceUtils.js b/src/utils/DatasourceUtils.js index 3a480aa..22f49e8 100644 --- a/src/utils/DatasourceUtils.js +++ b/src/utils/DatasourceUtils.js @@ -82,6 +82,47 @@ export default { return temp }, + /** + * Function to $emit a sort event + * @param {Exception} e + * @param {String} key + * @return void + */ + sortColumn (e, key) { + if (this.columnSortSelected.key === key) { + this.columnSortSelected.order = !this.columnSortSelected.order + } else { + this.columnSortSelected.order = false + this.columnSortSelected.key = key + } + let sortType = (this.columnSortSelected.order) ? 'ASC' : 'DESC' + this.$emit('column-sort', { sort: this.columnSortSelected, type: sortType }) + }, + + /** + * Function to show up arrow + * @param {String} key + * @return Boolean + */ + shouldShowUpArrow (key) { + return (this.columnSortSelected.key === key) && (this.columnSortSelected.order === true) + }, + + /** + * Function to show down arrow + * @param {String} key + * @return Boolean + */ + shouldShowDownArrow (key) { + return (this.columnSortSelected.key === key) && (this.columnSortSelected.order === false) + }, + + /** + * Function to get a value rounded + * @param {Number} value + * @param {Number} precision + * @return Number + */ roundNumber (value, precision) { let multiplier = Math.pow(10, precision || 0) return Math.round(value * multiplier) / multiplier