123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- /* eslint-disable no-restricted-syntax */ /* eslint-disable guard-for-in */
- <template>
- <div>
- <div class="row">
- <div align="center" class="col">
- <float-label
- class="mb-3"
- label="Search"
- style="width: 50%; float: center;"
- >
- <input
- v-model="searchItem"
- class="form-control uniInput mt-3"
- placeholder="Search"
- />
- </float-label>
- </div>
- </div>
-
- <div class="d-flex justify-content-between">
- <div class="p-2" v-if="!hideSearch"></div>
- <div class="p-2" v-if="title">
- <h2>{{ title }}</h2>
- </div>
- <div class="p-2">
- <div class="d-flex flex-row">
- <div class="p2" v-if="showColumnChooser">
- <div
- class="btn-white-border cursor-pointer"
- data-toggle="modal"
- data-target="#myModal"
- >
- Column Chooser
- </div>
- <div class="col-md-12">
- <div id="myModal" class="modal fade" role="dialog">
- <div class="modal-dialog modal-lg" style="width: 500px;">
- <!-- Modal content-->
- <div class="modal-content">
- <div class="modal-header">
- <h5>Column Chooser</h5>
- <button type="button" class="close" data-dismiss="modal">
- ×
- </button>
- </div>
- <div style="margin-bottom: 50px;">
- <ListViewControl
- :items="allColumn"
- @checkItem="checkItem"
- />
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="p2" v-if="selectedItems.length > 0">
- <div
- class="btn-white-border cursor-pointer"
- @click="onClearSelected()"
- >
- Clear Selected
- </div>
- </div>
- <div class="p2" v-if="showNew">
- <div class="btn-white-border cursor-pointer" @click="onNew()">
- New
- </div>
- </div>
- </div>
- </div>
- </div>
- <div style="height: 5px;"></div>
- <div v-if="items && items.length > 0" class="table-responsive">
- <table
- id="table"
- class="table table-striped"
- :class="{
- 'table table-hover': 1 === 1,
- 'table-sm': compact,
- 'table-bordered': bordered,
- }"
- >
- <thead>
- <tr class="dnd-moved">
- <th v-for="(column, c) in Columns" :key="c">
- <div
- @click="sortBy(column)"
- @mouseover="hover = c"
- @mouseleave="hover = -1"
- :class="{ active: hover === c }"
- >
- <div class="d-flex bd-highlight">
- <div
- v-if="displayHeaders.length === 0"
- class="p-2 w-100 bd-highlight"
- >
- {{ column | toProper }}
- </div>
- <div v-else class="p-2 w-100 bd-highlight">
- {{
- displayHeaders[c] !== ''
- ? displayHeaders[c]
- : column | toProper
- }}
- </div>
- <div class="p-2 flex-shrink-1 bd-highlight">
- <img
- src="../../../public/img/sort-up.png"
- height="8px;"
- v-if="sortKey === column && reverse"
- />
- <img
- src="../../../public/img/sort-down.png"
- height="8px;"
- v-if="sortKey === column && !reverse"
- />
- </div>
- </div>
- </div>
- </th>
- <th v-if="showCustomAction"></th>
- <th v-if="editable"></th>
- <th v-if="deleteable"></th>
- </tr>
- </thead>
-
- <tbody>
- <tr
- v-for="(item, i) in DisplayItems"
- :key="i"
- @click="onRowClick(item, i)"
- :class="{ selected: isSelected(i), 'cursor-pointer': allowSelect }"
- >
- <td v-for="(column, c) in Columns" :key="c">
- <div v-if="displayFormats.length === 0">
- {{
- isObject(item[column]) ? item[column].display : item[column]
- }}
- </div>
- <div
- v-else-if="
- displayFormats.length > 0 && displayFormats[c] === 'date'
- "
- >
- <div v-if="item[column] !== '0001-01-01T00:00:00'">
- {{
- isObject(item[column])
- ? item[column].display
- : item[column] | toDate
- }}
- </div>
- </div>
- <div
- style="padding-left: 10px; white-space: nowrap;"
- v-else-if="
- displayFormats.length > 0 && displayFormats[c] === 'money'
- "
- >
- {{
- isObject(item[column])
- ? item[column].display
- : item[column] | toCurrency
- }}
- </div>
- <div
- v-else-if="
- displayFormats.length > 0 && displayFormats[c] === 'image'
- "
- >
- <img
- :src="item[column]"
- style="height: 100px; width: 100px; object-fit: cover;"
- />
- </div>
- <div v-else>
- {{
- isObject(item[column]) ? item[column].display : item[column]
- }}
- </div>
- </td>
- <td v-if="showCustomAction" class="my-width">
- <button
- type="button"
- class="btn my-btn"
- @click="onCustomClick(item)"
- >
- <p v-if="CustomActionHeading !== 'Publish'">
- {{ CustomActionHeading }}
- </p>
- <img
- v-else
- src="../../../public/img/icons/Upload.png"
- height="25"
- width="25"
- />
- </button>
- </td>
-
- <td v-if="editable" class="my-width">
- <a @click="onEdit(item)" class="p-3">
- <img
- src="../../../public/img/icons/Edit.png"
- height="25"
- width="25"
- />
- </a>
- <!-- <button type="button" class="btn my-btn" @click="onEdit(item)">Edit</button> -->
- </td>
- <td v-if="deleteable" class="my-width">
- <a @click="onDelete(item)" class="p-3">
- <img
- src="../../../public/img/icons/delete.png"
- height="25"
- width="25"
- />
- </a>
- <!-- <button type="button" class="btn my-btn"
- @click="onDelete(item)">Delete</button> -->
- </td>
- </tr>
- </tbody>
- </table>
- <div class="d-flex justify-content-between" v-if="showPager">
- <div class="p-1">
- {{
- currentPage +
- ' / ' +
- PageCount +
- (!hideItemCount ? ' - (' + FilteredItems.length + ' items)' : '')
- }}
- </div>
- <div class="p-1">
- <BasePagination
- :currentPage="currentPage"
- :pageCount="PageCount"
- @nextPage="pageChangeHandle('next')"
- @previousPage="pageChangeHandle('previous')"
- @loadPage="pageChangeHandle"
- />
- </div>
- <div class="p-2">
- <div class="d-flex flex-row">
- <div>
- <select
- class="form-control"
- v-model="visibleItemsPerPageCount"
- @change="onChangeItemsPerPage()"
- >
- <option v-for="(item, i) in itemsPerPageList" :key="i">
- {{ item }}
- </option>
- </select>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div v-else>
- <Alert :text="'No items found ^-^'" :type="'INFO'" />
- </div>
- </div>
- </template>
-
- <script>
- /* eslint-disable */
- import _ from 'lodash'
- import ItemsPerPageList from '../../assets/staticData/itemsPerPage'
- import BasePagination from './basePagination.vue'
- import Alert from './alert.vue'
- import ListViewControl from './listViewControl.vue'
-
- export default {
- components: {
- BasePagination,
- Alert,
- ListViewControl,
- },
- mounted() {
- try {
- // to assign initial value to itemsPerPage
- if (this.itemsPerPageList && this.itemsPerPageList.length > 0) {
- const [startItem] = this.itemsPerPageList
- this.visibleItemsPerPageCount = startItem
- }
- } catch (error) {
- throw error
- }
- this.getInitColumn()
- },
- props: {
- compact: {
- default: false,
- },
- allowSelect: {
- default: true,
- },
- allowMultipleSelect: {
- default: false,
- },
- hideSearch: {
- default: false,
- },
- showNew: {
- default: true,
- },
- items: undefined,
- editable: {
- default: false,
- },
- deleteable: {
- default: false,
- },
- columnCount: {
- default: 6,
- },
- showPager: {
- default: true,
- },
- title: {
- default: undefined,
- },
- hideItemCount: {
- default: false,
- },
- currentPage: {
- default: 1,
- },
- bordered: {
- default: false,
- },
- striped: {
- default: true,
- },
- showColumnChooser: {
- default: true,
- },
- displayColumns: {
- type: Array,
- default: () => [],
- },
- displayFormats: {
- type: Array,
- default: () => [],
- },
- displayHeaders: {
- type: Array,
- default: () => [],
- },
- showCustomAction: {
- default: false,
- },
- CustomActionHeading: {
- default: '',
- },
- CustomActionCondition: {
- default: '',
- },
- },
- data() {
- return {
- hover: -1,
- selectedItems: [],
- showControl: false,
- sortKey: 'id',
- reverse: false,
- searchItem: '',
- visibleItemsPerPageCount: 20,
- itemsPerPageList: ItemsPerPageList,
- visibleColumn: [],
- allColumn: [],
- }
- },
- methods: {
- checkItem(column, show) {
- const list = []
- for (const i in this.allColumn) {
- const item = this.allColumn[i]
- if (item && item.column === column) {
- item.show = show
- }
- list.push(item)
- }
- this.allColumn = list
- },
- getInitColumn() {
- const list = []
- const listAll = []
- if (this.items) {
- for (const i in Object.keys(this.items)) {
- const item = this.items[i]
- for (const o in Object.keys(item)) {
- if (
- !listAll.includes(Object.keys(item)[o]) &&
- !Array.isArray(Object.values(item)[o])
- ) {
- const columnName = Object.keys(item)[o]
- if (!listAll.some((x) => x.column === columnName)) {
- listAll.push({
- column: columnName,
- show:
- _.filter(listAll, (x) => x.show).length < this.columnCount,
- })
- }
- }
- }
- }
- }
- this.allColumn = listAll
- },
- onClearSelected() {
- this.selectedItems = []
- this.$emit('onClearSelected')
- },
- isSelected(i) {
- const ind = this.getActualIndex(i)
- return _.some(this.selectedItems, (x) => x === ind)
- },
- onNew() {
- this.$emit('onNew')
- },
- isObject(item) {
- return !!item && item.constructor === Object
- },
- isDate(item) {
- return !!item && item.constructor === Date
- },
- isDecimal(item) {
- if (!!item && item.constructor === Number && item.indexOf('.') > 0) {
- return true
- }
- return false
- },
- isImage(item) {
- return (
- !!item &&
- item.constructor === String &&
- item.length > 9 &&
- item.substring(0, 9) === 'data:image'
- )
- },
- onEdit(item) {
- this.$emit('onEdit', item)
- },
- onDelete(item) {
- this.$emit('onDelete', item)
- },
- onCustomClick(item) {
- this.$emit('onCustomClick', item)
- },
- onRowClick(item, i) {
- const ind = this.getActualIndex(i)
- if (_.some(this.selectedItems, (x) => x === ind)) {
- this.selectedItems = this.selectedItems.filter((x) => x !== ind)
- } else {
- if (!this.allowMultipleSelect) {
- this.selectedItems = []
- }
- this.selectedItems.push(item)
- }
- this.$emit('onRowClick', this.selectedItems)
- },
- getActualIndex(index) {
- return (this.currentPage - 1) * this.visibleItemsPerPageCount + index
- },
- changeColumn(title, checked) {
- if (checked) {
- this.myColumns.push(title)
- } else {
- const ind = this.myColumns.indexOf(title)
- if (ind > -1) {
- this.myColumns.splice(ind, 1)
- }
- }
- },
- onControlVisibilityChange() {
- this.showControl = !this.showControl
- },
- sortBy(sortKey) {
- this.reverse = this.sortKey === sortKey ? !this.reverse : false
- this.sortKey = sortKey
- },
- async pageChangeHandle(value) {
- console.log(value)
- switch (value) {
- case 'next':
- this.currentPage += 1
- break
- case 'previous':
- this.currentPage -= 1
- break
- default:
- this.currentPage = value
- }
- },
- onChangeItemsPerPage() {
- if (this.currentPage !== 1) {
- this.currentPage = 1
- }
- },
- inArray(array, value) {
- const lenght = array.length
- for (let i = 0; i < lenght; i++) {
- if (array[i] === value) return true
- }
- return false
- },
- },
- computed: {
- ListWidth() {
- if (this.showControl) {
- return 'col-md-9'
- }
- return 'col-md-12'
- },
- SortDirection() {
- return this.reverse ? 'desc' : 'asc'
- },
- PageCount() {
- return this.visibleItemsPerPageCount !== 0
- ? Math.ceil(this.FilteredItems.length / this.visibleItemsPerPageCount)
- : 1
- },
- Columns() {
- const listColumns = []
- if (!this.allColumn || this.allColumn.length === 0) {
- this.getInitColumn()
- }
- if (this.displayColumns.length > 0) {
- for (let i = 0; i < this.displayColumns.length; i++) {
- listColumns.push(this.displayColumns[i])
- }
- } else {
- const list = _.filter(this.allColumn, (x) => x.show)
- for (const i in list) {
- const item = list[i]
- if (item) {
- listColumns.push(item.column)
- }
- }
- }
- return listColumns
- },
- AllColumns() {
- const list = []
- if (this.items) {
- }
- return list
- },
- FilteredItems() {
- const list = _.filter(this.items, (item) =>
- Object.values(item).some(
- (i) =>
- JSON.stringify(i)
- .toLowerCase()
- .indexOf(this.searchItem.toLowerCase()) > -1,
- ),
- )
- return _.orderBy(list, this.sortKey, this.SortDirection)
- },
- DisplayItems() {
- const list = this.FilteredItems
- const startSlice = (this.currentPage - 1) * this.visibleItemsPerPageCount
- let endSlice = this.currentPage * this.visibleItemsPerPageCount
- if (endSlice > list.length) {
- endSlice = list.length
- }
- return list.slice(startSlice, endSlice)
- },
-
- GetAllColumn() {},
- },
- }
- </script>
- <style scoped>
- th[draggable] a,
- th[draggable] {
- cursor: move;
- }
- th[draggable] a:hover,
- th[draggable] a {
- display: block;
- text-decoration: none;
- color: #333333;
- }
- .table-striped > tbody > tr:nth-child(2n + 1) > td,
- .table-striped > tbody > tr:nth-child(2n + 1) > th {
- background-color: rgba(225, 225, 225, 0.8);
- }
- .active {
- background-color: rgba(255, 255, 255, 0.5);
- cursor: pointer;
- }
- .table > tbody > tr > td {
- vertical-align: middle;
- }
- .my-width {
- width: 20px;
- }
- .drag {
- background-color: rgba(0, 255, 0, 0.35);
- opacity: 0.25;
- }
- .dnd-drag {
- opacity: 0.25;
- }
- .over {
- background-color: rgba(0, 0, 255, 0.35);
- }
- .my-border {
- border: solid 3px silver;
- }
- .selected {
- background-color: rgba(96, 203, 235, 0.5);
- border: white 2px double;
- }
- .selected:hover {
- background-color: rgba(96, 203, 235, 0.85);
- }
- .btn-width {
- width: 125px;
- }
- .table-title {
- padding: 5px;
- border: rgba(200, 200, 200, 0.66) double 2px;
- border-radius: 5px;
- background-color: rgba(96, 203, 235, 0.25);
- }
- .table-title:hover {
- background-color: rgba(96, 203, 235, 0.4);
- }
- .table-header {
- background-color: rgba(200, 200, 200, 0.66);
- }
- .my-table {
- border: rgba(150, 150, 150, 0.75) 3px double;
- }
- </style>
|