<template>
    <div class="Scroll-Table">
        <my-input :props="{type: 'text', placeholder: 'Suche'}" @change="searchChanged" v-model="currentSearch"></my-input>
        <my-table :actions="actions" :columns="columns" :rows="rows"
          :currentOrderBy="currentOrderBy"
          :currentOrderDesc="currentOrderDesc"
          @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 'components/my-table';
import MyInput from 'components/my-input';

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

export default {
    name: "ScrollTable",
    directives: {
        ObserveVisibility
    },
    components: {
        MyTable,
        MyInput
    },
    props: {
        actions: {
            type: Array,
            default() {
                return [ ];
            }
        },
        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) {
            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();
                }, 20);
            }
        },
        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>