229 lines
6.2 KiB
JavaScript
229 lines
6.2 KiB
JavaScript
export default function table() {
|
|
return {
|
|
collapsedGroups: [],
|
|
|
|
isLoading: false,
|
|
|
|
selectedRecords: [],
|
|
|
|
shouldCheckUniqueSelection: true,
|
|
|
|
lastCheckedRecord: null,
|
|
|
|
init: function () {
|
|
this.$wire.$on('deselectAllTableRecords', () =>
|
|
this.deselectAllRecords(),
|
|
)
|
|
|
|
this.$watch('selectedRecords', () => {
|
|
if (!this.shouldCheckUniqueSelection) {
|
|
this.shouldCheckUniqueSelection = true
|
|
|
|
return
|
|
}
|
|
|
|
this.selectedRecords = [...new Set(this.selectedRecords)]
|
|
|
|
this.shouldCheckUniqueSelection = false
|
|
})
|
|
|
|
this.$nextTick(() => this.watchForCheckboxClicks())
|
|
|
|
Livewire.hook('element.init', ({ component }) => {
|
|
if (component.id === this.$wire.id) {
|
|
this.watchForCheckboxClicks()
|
|
}
|
|
})
|
|
},
|
|
|
|
mountAction: function (name, record = null) {
|
|
this.$wire.set('selectedTableRecords', this.selectedRecords, false)
|
|
this.$wire.mountTableAction(name, record)
|
|
},
|
|
|
|
mountBulkAction: function (name) {
|
|
this.$wire.set('selectedTableRecords', this.selectedRecords, false)
|
|
this.$wire.mountTableBulkAction(name)
|
|
},
|
|
|
|
toggleSelectRecordsOnPage: function () {
|
|
const keys = this.getRecordsOnPage()
|
|
|
|
if (this.areRecordsSelected(keys)) {
|
|
this.deselectRecords(keys)
|
|
|
|
return
|
|
}
|
|
|
|
this.selectRecords(keys)
|
|
},
|
|
|
|
toggleSelectRecordsInGroup: async function (group) {
|
|
this.isLoading = true
|
|
|
|
if (this.areRecordsSelected(this.getRecordsInGroupOnPage(group))) {
|
|
this.deselectRecords(
|
|
await this.$wire.getGroupedSelectableTableRecordKeys(group),
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
this.selectRecords(
|
|
await this.$wire.getGroupedSelectableTableRecordKeys(group),
|
|
)
|
|
|
|
this.isLoading = false
|
|
},
|
|
|
|
getRecordsInGroupOnPage: function (group) {
|
|
const keys = []
|
|
|
|
for (let checkbox of this.$root?.getElementsByClassName(
|
|
'fi-ta-record-checkbox',
|
|
) ?? []) {
|
|
if (checkbox.dataset.group !== group) {
|
|
continue
|
|
}
|
|
|
|
keys.push(checkbox.value)
|
|
}
|
|
|
|
return keys
|
|
},
|
|
|
|
getRecordsOnPage: function () {
|
|
const keys = []
|
|
|
|
for (let checkbox of this.$root?.getElementsByClassName(
|
|
'fi-ta-record-checkbox',
|
|
) ?? []) {
|
|
keys.push(checkbox.value)
|
|
}
|
|
|
|
return keys
|
|
},
|
|
|
|
selectRecords: function (keys) {
|
|
for (let key of keys) {
|
|
if (this.isRecordSelected(key)) {
|
|
continue
|
|
}
|
|
|
|
this.selectedRecords.push(key)
|
|
}
|
|
},
|
|
|
|
deselectRecords: function (keys) {
|
|
for (let key of keys) {
|
|
let index = this.selectedRecords.indexOf(key)
|
|
|
|
if (index === -1) {
|
|
continue
|
|
}
|
|
|
|
this.selectedRecords.splice(index, 1)
|
|
}
|
|
},
|
|
|
|
selectAllRecords: async function () {
|
|
this.isLoading = true
|
|
|
|
this.selectedRecords =
|
|
await this.$wire.getAllSelectableTableRecordKeys()
|
|
|
|
this.isLoading = false
|
|
},
|
|
|
|
deselectAllRecords: function () {
|
|
this.selectedRecords = []
|
|
},
|
|
|
|
isRecordSelected: function (key) {
|
|
return this.selectedRecords.includes(key)
|
|
},
|
|
|
|
areRecordsSelected: function (keys) {
|
|
return keys.every((key) => this.isRecordSelected(key))
|
|
},
|
|
|
|
toggleCollapseGroup: function (group) {
|
|
if (this.isGroupCollapsed(group)) {
|
|
this.collapsedGroups.splice(
|
|
this.collapsedGroups.indexOf(group),
|
|
1,
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
this.collapsedGroups.push(group)
|
|
},
|
|
|
|
isGroupCollapsed: function (group) {
|
|
return this.collapsedGroups.includes(group)
|
|
},
|
|
|
|
resetCollapsedGroups: function () {
|
|
this.collapsedGroups = []
|
|
},
|
|
|
|
watchForCheckboxClicks: function () {
|
|
let checkboxes =
|
|
this.$root?.getElementsByClassName('fi-ta-record-checkbox') ??
|
|
[]
|
|
|
|
for (let checkbox of checkboxes) {
|
|
// Remove existing listener to avoid duplicates
|
|
checkbox.removeEventListener('click', this.handleCheckboxClick)
|
|
|
|
checkbox.addEventListener('click', (event) =>
|
|
this.handleCheckboxClick(event, checkbox),
|
|
)
|
|
}
|
|
},
|
|
|
|
handleCheckboxClick: function (event, checkbox) {
|
|
if (!this.lastChecked) {
|
|
this.lastChecked = checkbox
|
|
|
|
return
|
|
}
|
|
|
|
if (event.shiftKey) {
|
|
let checkboxes = Array.from(
|
|
this.$root?.getElementsByClassName(
|
|
'fi-ta-record-checkbox',
|
|
) ?? [],
|
|
)
|
|
|
|
if (!checkboxes.includes(this.lastChecked)) {
|
|
this.lastChecked = checkbox
|
|
|
|
return
|
|
}
|
|
|
|
let start = checkboxes.indexOf(this.lastChecked)
|
|
let end = checkboxes.indexOf(checkbox)
|
|
|
|
let range = [start, end].sort((a, b) => a - b)
|
|
let values = []
|
|
|
|
for (let i = range[0]; i <= range[1]; i++) {
|
|
checkboxes[i].checked = checkbox.checked
|
|
|
|
values.push(checkboxes[i].value)
|
|
}
|
|
|
|
if (checkbox.checked) {
|
|
this.selectRecords(values)
|
|
} else {
|
|
this.deselectRecords(values)
|
|
}
|
|
}
|
|
|
|
this.lastChecked = checkbox
|
|
},
|
|
}
|
|
}
|