app/javascript/vue/tasks/observation_matrices/new/components/rows/copyRows.vue
<template>
<div>
<modal-component
v-if="showModal"
:container-style="{
width: '500px',
'overflow-y': 'scroll',
'max-height': '60vh'
}"
@close="closeModal"
>
<template #header>
<h3>Copy rows from matrix</h3>
</template>
<template #body>
<spinner-component
v-if="isLoading"
legend="Loading..."
/>
<select
class="full_width margin-medium-bottom"
v-model="matrixSelected"
>
<option :value="undefined">Select a observation matrix</option>
<option
v-for="item in observationMatrices"
:key="item.id"
:value="item"
>
{{ item.name }}
</option>
</select>
<div
v-if="matrixSelected"
class="flex-separate margin-small-bottom"
>
<div>
<button
@click="addRows"
:disabled="!rowsSelected.length"
class="button normal-input button-submit"
>
Add rows
</button>
</div>
<div v-if="matrixSelected">
<button
class="button normal-input button-default"
@click="selectAll"
>
Select all
</button>
<button
class="button normal-input button-default"
@click="unselectAll"
>
Unselect all
</button>
</div>
</div>
<ul class="no_bullets">
<li
v-for="item in rows"
:key="item.observation_object.id"
>
<label>
<input
type="checkbox"
:value="item"
v-model="rowsSelected"
:disabled="alreadyExist(item)"
/>
<span
class="disabled"
v-if="alreadyExist(item)"
>
<span v-html="item.observation_object.object_tag" /> ({{
item.observation_object.base_class
}}) <span>(Already added)</span></span
>
<span v-else>
<span v-html="item.observation_object.object_tag" /> ({{
item.observation_object.base_class
}})
</span>
</label>
</li>
</ul>
</template>
<template #footer>
<div class="flex-separate">
<div>
<button
@click="addRows"
:disabled="!rowsSelected.length"
class="button normal-input button-submit"
>
Add rows
</button>
</div>
<div v-if="matrixSelected">
<button
class="button normal-input button-default"
@click="selectAll"
>
Select all
</button>
<button
class="button normal-input button-default"
@click="unselectAll"
>
Unselect all
</button>
</div>
</div>
</template>
</modal-component>
</div>
</template>
<script>
import ModalComponent from '@/components/ui/Modal'
import SpinnerComponent from '@/components/ui/VSpinner'
import getPagination from '@/helpers/getPagination'
import { ActionNames } from '../../store/actions/actions'
import { GetterNames } from '../../store/getters/getters'
import { GetMatrixObservationRows } from '../../request/resources'
import { ObservationMatrix, ObservationMatrixRowItem } from '@/routes/endpoints'
import ObservationTypes from '../../const/types.js'
export default {
components: {
ModalComponent,
SpinnerComponent
},
props: {
matrixId: {
type: [String, Number],
required: true
}
},
computed: {
existingRows() {
return this.$store.getters[GetterNames.GetMatrixRows]
}
},
data() {
return {
types: ObservationTypes.Row,
isLoading: false,
matrixSelected: undefined,
rowsSelected: [],
rows: [],
showModal: true,
observationMatrices: [],
pagination: undefined
}
},
watch: {
showModal: {
handler(newVal) {
if (newVal) {
this.isLoading = true
ObservationMatrix.where({ per: 500 }).then((response) => {
response.body.splice(
response.body.findIndex((item) => this.matrixId === item.id),
1
)
this.observationMatrices = response.body
this.isLoading = false
})
}
},
immediate: true
},
matrixSelected(newVal) {
if (newVal) {
this.loadRows()
} else {
this.rows = []
}
}
},
mounted() {
document.addEventListener('turbolinks:load', () => {
window.removeEventListener('scroll', this.checkScroll)
})
this.$el
.querySelector('.modal-container')
.addEventListener('scroll', this.checkScroll)
},
methods: {
loadRows(page = undefined) {
this.isLoading = true
GetMatrixObservationRows(this.matrixSelected.id, {
per: 500,
page: page,
extend: ['observation_object']
}).then((response) => {
this.rows = this.rows.concat(response.body)
this.pagination = getPagination(response)
this.isLoading = false
})
},
addRows() {
const index = this.existingRows.length
const data = this.rowsSelected.map((item) => ({
observation_matrix_id: this.matrixId,
observation_object_id: item.observation_object.id,
observation_object_type: item.observation_object.base_class,
position: item.position + index,
type: this.types[item.observation_object.base_class]
}))
data.sort((a, b) => a - b)
const promises = data.map((row) =>
ObservationMatrixRowItem.create({ observation_matrix_row_item: row })
)
Promise.all(promises).then(() => {
this.$store.dispatch(ActionNames.GetMatrixObservationRows)
this.rowsSelected = []
TW.workbench.alert.create(
'Rows was successfully added to matrix.',
'notice'
)
this.closeModal()
})
},
alreadyExist(item) {
return this.existingRows.find(
(row) => item.observation_object.id === row.observation_object.id
)
},
closeModal() {
this.showModal = false
this.$emit('close')
},
selectAll() {
this.rowsSelected = this.rows.filter((item) => !this.alreadyExist(item))
},
unselectAll() {
this.rowsSelected = []
},
checkScroll(event) {
const scrollPosition = event.target.clientHeight + event.target.scrollTop
const listHeght = event.target.scrollHeight
const bottomOfTable = scrollPosition >= listHeght
if (bottomOfTable && !this.isLoading) {
if (this.pagination.nextPage) {
this.loadRows(this.pagination.nextPage)
}
}
}
}
}
</script>