Source: media/data/GridData.js

import { GalleryDataInput } from "./input.js";
import { PromiseQueue } from "./PromiseQueue.js";
import { DataRequestProcessing } from "./utils.js";
import { GalleryMappingScheme } from "./utils.js";

export { GridData }

/**
 * Class representing *unfiltered* grid data.
 */
class GridData extends GalleryDataInput {
    /**
     * Create the grid data object.
     * @param {Object} galleryConfigDict - Gallery configuration dictionary.
     */
    constructor(galleryConfigDict) {
        super();
        this.dataItems = [];
        this.dataItemsHarmonized = [];
        this.galleryConfigDict = galleryConfigDict;
        this.gridDataQueue = new PromiseQueue();
    }

    /**
     * Return the number of items if already loaded in the past, i.e., via getItemsQuantity().
     */
    get dataItemAmount() {
        return this.adapter.totalItems
    }

    /**
     * Request the number of items, regardless of the service.
     * @returns Promise with number of items.
     */
    getItemsQuantity() {
        return this.adapter.requestItemsQuantity(this.galleryRemoteFilter.abstractFilter).then((quantity) => {
            if (typeof quantity === 'string')
                return Number(quantity)
            return quantity
        })
    }

    /**
     * Load items until the count is reached. No filtering is applied.
     * @param {Number} startIndex - Index where loading should start.
     * @param {Number} count - Number of items that should be loaded.
     * @param {Object} query - Custom query parameters for the request.
     * @param {Boolean} queueing - If true, load multiple requests synchronously via queue.
     * @returns Promise.
     */
    loadItems(startIndex, count, query = {}, queueing = true) {

        const _loadItems = (startIndex, count, query) => {
            const allItemsInCache = this.dataItems.length != 0 && !this.dataItems.slice(startIndex, startIndex + count).includes(undefined);
            if (allItemsInCache)
                return Promise.resolve();

            const sortByColumns = [GalleryMappingScheme.findPropertyKeyInMapping(this.galleryConfigDict['mapping'], ['dateTime'])[0], GalleryMappingScheme.findPropertyKeyInMapping(this.galleryConfigDict['mapping'], ['name'])[0]]
            const queryParams = {
                ...startIndex && { 'STARTINDEX': startIndex },
                ...isFinite(count) && { 'COUNT': count },
                'SORTBY': sortByColumns.filter(defined => defined).join(',')
            }
            const paramsFinal = Object.assign({}, queryParams, query);
            return this.adapter.requestData(this.galleryRemoteFilter.abstractFilter, paramsFinal).then(() => {
                const countItemsLoaded = this.adapter.requestedDataItems.length;
                const newDataItems = this.adapter.requestedDataItems;
                const newDataItemsHarmonized = DataRequestProcessing.harmonizeData(newDataItems, this.galleryConfigDict);
                const enrichedDataItemsHarmonized = DataRequestProcessing.includeSidebarData(newDataItems, newDataItemsHarmonized);
                this.dataItemsHarmonized = DataRequestProcessing.mergeData(this.dataItemsHarmonized, enrichedDataItemsHarmonized, startIndex, countItemsLoaded);
                DataRequestProcessing.resizeArray(this.dataItemsHarmonized, this.adapter.totalItems, undefined);
                this.dataItems = DataRequestProcessing.mergeData(this.dataItems, newDataItems, startIndex, countItemsLoaded);
                DataRequestProcessing.resizeArray(this.dataItems, this.adapter.totalItems, undefined);
                return Promise.resolve();
            })
        }
        if (queueing)
            return this.gridDataQueue.enqueue(() => _loadItems(startIndex, count, query));
        else
            return _loadItems(startIndex, count, query)

    }
}