<template>
    <div class="Scroll-Table">
        <my-input label="Suche:" type="text" @change="searchChanged" v-model="currentSearch"></my-input>
        <my-table :columns="columns" :rows="rows" @sort="sort"></my-table>
        <div v-if="loadingDelayed">loading...</div>
        <div style="padding-left: 30%; padding-bottom: 100px;">
            <span v-show="hasMore || reloadTriggered" v-if="!loadingDelayed" v-observe-visibility="visibilityChanged">...</span>
        </div>
    </div>
</template>

<script>
import MyTable from './my-table.vue';
import MyInput from './my-input.vue';

import { ObserveVisibility } from 'vue-observe-visibility/dist/vue-observe-visibility';

export default {
   name: "ScrollTable",
    directives: {
        ObserveVisibility
    },
    components: {
        MyTable,
        MyInput
    },
    props: {
       columns: {
           type: Array,
           default() {
                return [ ];
           }
       },
       newRows: {
           type: Array,
           default() {
                return [ ];
           }
       },
       offset: {
           type: Number,
           default: 0
       },
       limit: {
           type: Number,
           default: 10
       },
       orderBy: {
           type: String
       },
       orderDesc: {
           type: Boolean,
           default: false
       },
       search: {
           type: String
       },
       loading: {
           type: Boolean,
           default: false
       },
       hasMore: {
           type: Boolean,
           default: true
       },
       handler: {
           type: Function,
           default: () => {}
       }
    },
    watch: {
        newRows(rows) {
            rows.forEach(row => {
                this.rowsToPush.push(row);
            });
            this.currentOffset += rows.length;
            this.pushRows(); // for transition
        },
        loading(l) {
            if (!l) {
                // delay after loading for visibility observer
                setTimeout(() => {
                    this.loadingDelayed = false;
                }, 200);
            } else {
                this.loadingDelayed = true;
            }
        }
    },
    data() {
        return {
            rows: [ ],
            rowsToPush: [ ],
            currentOffset: this.offset,
            currentOrderBy: this.orderBy,
            currentOrderDesc: this.orderDesc,
            currentSearch: this.search,
            loadingDelayed: false,
            reloadTriggered: false
        }
    },
    methods: {
        visibilityChanged(isVisible, entry) {
            if (isVisible) {
                // infinite scrolling
                this.reloadTriggered = false;
                this.handler(this.currentOffset, this.limit, this.currentOrderBy, this.currentOrderDesc, this.currentSearch);
            }
        },
        pushRows() {
            let row = this.rowsToPush.shift();
            if (row) {
                this.rows.push(row);
                setTimeout(() => {
                    this.pushRows();
                }, 50);
            }
        },
        clear() {
            this.currentOffset = 0;
            this.rows = [];
            this.rowsToPush = [];
        },
        sort(e) {
            if (e.orderBy == this.currentOrderBy) {
                this.currentOrderDesc = !this.currentOrderDesc;
            } else {
                this.currentOrderDesc = false;
            }
            this.currentOrderBy = e.orderBy;
            this.reloadTriggered = true;
            this.clear();
        },
        searchChanged(e) {
            this.currentSearch = e;
            this.reloadTriggered = true;
            this.clear();
        }
    }
}

</script>