Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16,975 changes: 16,948 additions & 27 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/css/gravity.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/gravity.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"/js/gravity.js": "/js/gravity.js?id=2b068722e2a1f6b4c4c5",
"/css/gravity.css": "/css/gravity.css?id=f4312103778cfc5c63f0",
"/js/gravity.js": "/js/gravity.js?id=cd22fa9cf3d22ec78b78",
"/css/gravity.css": "/css/gravity.css?id=865176a63047b81aa599",
"/img/audio-large.svg": "/img/audio-large.svg?id=fca6a67c7ef06d00ef4a",
"/img/audio-small.svg": "/img/audio-small.svg?id=48f5a5c5ff1cfd2cb375",
"/img/document-large.svg": "/img/document-large.svg?id=5c7cacec26ee17c609d5",
Expand Down
79 changes: 60 additions & 19 deletions resources/js/ui/Table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@

<th v-for="(column, index) in displayable"
v-show="! hasSelections"
:class="{'sortable': isSortable(column), 'active': (sort.key === column), 'w-96': (column === 'url')}"
:class="{'sortable': isSortable(column), 'active': (sort.key === column), 'w-96': (column === 'url'), ['th-' + column]: true}"
:key="column[primaryKey] || index">
<a href="#" v-if="isSortable(column)" class="table__heading table__heading--link" @click.prevent="isSortable(column) && sortRecordsBy(column)" :aria-label="'Sort by ' + column_names[column] || column">
<span>{{ column_names[column] || column }}</span>
Expand All @@ -125,23 +125,21 @@
</span>
</th>

<th v-show="hasSelections" :colspan="displayable.length">
<span class="table__heading">
<th v-show="hasSelections" :colspan="hasActions ? displayable.length + 1 : displayable.length">
<span class="table__heading flex">
{{ this.selected.length }} record{{ this.selected.length > 1 ? 's' : '' }} selected
</span>
</th>

<th v-show="hasSelections" class="w-48">
<div class="bulk-actions">
<select name="bulk-actions" id="bulk-actions" class="field-select field-select--sm field-select--bordered" v-model="action" @change="showBulkActionConfirmation = true">
<option selected disabled :value="null">Bulk Actions</option>

<div class="ml-auto">
<select name="bulk-actions" id="bulk-actions" class="field-select field-select--sm field-select--bordered" v-model="action" @change="showBulkActionConfirmation = true">
<option selected disabled :value="null">Bulk Actions</option>

<option v-for="(action, index) in allowedBulkActions" :key="action.name" :value="index">{{ action.name }}</option>
</select>
</div>
<option v-for="(action, index) in allowedBulkActions" :key="action.name" :value="index">{{ action.name }}</option>
</select>
</div>
</span>
</th>

<th v-show="hasActions && ! hasSelections" class="w-48">&nbsp;</th>
<th v-show="hasActions && ! hasSelections" class="w-20 col-actions">&nbsp;</th>
</tr>
</thead>

Expand All @@ -160,16 +158,23 @@
</div>
</td>

<td v-for="column in displayable"
<td v-for="column in displayable" :class="'td-' + column"
:key="column">
<span class="column-label">{{ column_names[column] || column }}</span>

<slot :name="column" :record="record">
{{ record[column] }}
<component
v-if="column_types[column] && isComponentExist(column_types[column])"
:is="column_types[column]"
v-bind="column_props[column]"
:value="record[column]"
:record="record"
/>
<span v-else >{{ record[column] }}</span>
</slot>
</td>

<td class="table__actions w-20" v-if="hasActions">
<td class="'table__actions w-20 col-actions'" v-if="hasActions">
<slot name="actions" :record="record"></slot>
</td>
</tr>
Expand Down Expand Up @@ -236,7 +241,7 @@
<ui-modal v-if="action !== null" name="confirm-bulk-action" :title="'Confirm Bulk ' + this.allowedBulkActions[action].name" v-model="showBulkActionConfirmation">
<p>Are you sure you want to perform this action against <b>{{ this.selected.length }}</b> record{{this.selected.length > 1 ? 's' : '' }}?</p>

<template slot="footer">
<template v-slot:footer>
<ui-button @click.prevent="confirmBulkAction" :loading="working" class="ml-3" variant="primary">Confirm</ui-button>
<ui-button @click.prevent="cancelBulkAction" v-if="! working" variant="secondary">Cancel</ui-button>
</template>
Expand Down Expand Up @@ -266,7 +271,7 @@
},
bulk: {
type: Boolean,
default: false
default: true
},
refresh: {
type: Number|Boolean,
Expand All @@ -284,6 +289,10 @@
type: String,
default: 'id'
},
saveSortBy: {
type: Boolean,
default: true,
},
perPage: {
type: Number,
default: 10
Expand Down Expand Up @@ -356,6 +365,8 @@
working: false,
displayable: [],
column_names: [],
column_types: [],
column_props: [],
bulk_actions: [],
bulk_actions_exempt: [],
sortable: [],
Expand Down Expand Up @@ -397,6 +408,7 @@
},

hasBulkActions() {
console.log(this.bulk, this.selectable.length, this.allowedBulkActions.length)
if (! this.bulk) return false
if (! this.selectable.length > 0) return false
if (! this.allowedBulkActions.length > 0) return false
Expand Down Expand Up @@ -512,6 +524,8 @@
this.displayable = response.data.displayable
this.sortable = response.data.sortable
this.column_names = response.data.column_names
this.column_types = response.data.column_types
this.column_props = response.data.column_props
this.bulk_actions = response.data.bulk_actions
this.bulk_actions_exempt = response.data.bulk_actions_exempt
this.pagination.totalRecords = response.data.records.total
Expand All @@ -523,6 +537,8 @@
if (this.refresh && ! self._timer) {
this._timer = setTimeout(() => this.getRecords(), this.refresh)
}

this.$emit('loaded', this.records)
})
},

Expand Down Expand Up @@ -554,6 +570,26 @@
}

this.getRecords()

this.saveSortProperty()
},

saveSortProperty() {
if (this.saveSortBy) {
window.localStorage.setItem('ui-table-sort-' + this.id + '-' + this.endpoint + '-' + window.location.pathname, JSON.stringify(this.sort))
}
},

loadSortProperty() {
try {
let sort = window.localStorage.getItem('ui-table-sort-' + this.id + '-' + this.endpoint + '-' + window.location.pathname)
if (sort) {
sort = JSON.parse(sort)
this.sort = sort
}
} catch (error) {

}
},

changePage(page) {
Expand All @@ -580,10 +616,15 @@
bus().$on('refresh-datatable-' + this.id, (data) => {
this.getRecords()
})
},

isComponentExist(componentName) {
return componentName in this.$options.components
}
},

created() {
this.loadSortProperty()
this.getRecords()
this.listenForEvents()
},
Expand Down
34 changes: 32 additions & 2 deletions src/Http/Controllers/DataTableController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public function index(Request $request)
'displayable' => array_values($this->getDisplayableColumns()),
'sortable' => array_values($this->getSortable()),
'column_names' => $this->getCustomColumnNames(),
'column_types' => $this->getCustomColumnTypes(),
'column_props' => $this->getCustomColumnProps(),
'records' => $this->getRecords($request),
'bulk_actions' => $this->getBulkActions(),
'bulk_actions_exempt' => $this->getExemptFromBulkActions(),
Expand Down Expand Up @@ -100,6 +102,26 @@ protected function getCustomColumnNames()
return [];
}

/**
* Get the mapped custom column types.
*
* @return array
*/
protected function getCustomColumnTypes()
{
return [];
}

/**
* Get the mapped custom column props.
*
* @return array
*/
protected function getCustomColumnProps()
{
return [];
}

/**
* Get the filterable columns.
*
Expand Down Expand Up @@ -136,6 +158,14 @@ protected function getAllowedFilters()
});
}

/**
* Get the sortable columns for Spatie query builder (It's value is not same as getSortable() when it have object as value, eg. Spatie\QueryBuilder\Sorts\Sort)
*/
protected function getAllowedSorts()
{
return $this->getSortable();
}

/**
* Get the sortable columns.
*
Expand Down Expand Up @@ -198,7 +228,7 @@ protected function getRecords(Request $request)
->allowedIncludes($this->getRelationships())

// Allowed sortable columns (e.g. sort=name)
->allowedSorts($this->getSortable())
->allowedSorts($this->getAllowedSorts())

// Default sortable column
->defaultSort($this->getDefaultSort())
Expand All @@ -210,7 +240,7 @@ protected function getRecords(Request $request)
// - page (defaults to `PAGE_NUM`)
->paginate(
$request->query('perPage', self::PER_PAGE),
self::getDisplayableColumns(),
['*'], // fix issue where displayable columns cannot be configured properly when there is column which is not exist in the table (eg, column generated using aggregate function)
get_class($this),
$request->query('page', self::PAGE_NUM)
);
Expand Down