import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Button, Grid, Item, Menu, MenuTrigger, mergeProps, Paragraph, Select, Space, Tag, tasty, Text, Title, Panel, CloseIcon, } from '@cube-dev/ui-kit';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { formatDistance } from 'date-fns';
import { ArrowDownOutlined, ArrowUpOutlined, ClearOutlined, FilterOutlined, LeftOutlined, LoadingOutlined, MoreOutlined, RightOutlined, } from '@ant-design/icons';
import { ListDropTargetDelegate, ListKeyboardDelegate, useDraggableCollection, useDraggableItem, useDropIndicator, useDroppableCollection, useFocusRing, useListBox, useOption, } from 'react-aria';
import { useDraggableCollectionState, useDroppableCollectionState, useListState, } from 'react-stately';
import { PREDEFINED_GRANULARITIES } from './values';
import { formatCurrency, formatNumber } from './utils/formatters';
import { useDeepMemo, useIntervalEffect } from './hooks';
import { OutdatedLabel } from './components/OutdatedLabel';
import { CopyButton } from './components/CopyButton';
import { ListMemberButton } from './components/ListMemberButton';
import { useQueryBuilderContext } from './context';
import { formatDateByGranularity } from './utils/format-date-by-granularity';
import { MemberBadge } from './components/Badge';
import { MemberLabel } from './components/MemberLabel';
import { areQueriesRelated } from './utils/query-helpers';
import { ORDER_LABEL_BY_TYPE } from './utils/labels';
const StyledTag = tasty(Tag, {
    styles: {
        position: 'static',
    },
});
const StyledCopyButton = tasty(CopyButton, {
    dontShowToast: true,
    styles: {
        radius: 0,
        placeSelf: 'stretch',
        height: 'auto',
    },
});
const TableContainer = tasty({
    qa: 'ResultsTableContainer',
    styles: {
        styledScrollbar: true,
        maxWidth: '100%',
        overflow: 'auto',
    },
});
const TableFooter = tasty(Space, {
    qa: 'ResultsTableFooter',
    styles: {
        fill: '#white',
        padding: '1x',
        width: '100%',
        placeContent: 'center space-between',
        height: '5x',
        border: 'top',
    },
});
const OptionsButtonElement = tasty(ListMemberButton, {
    'aria-label': 'Options',
    icon: _jsx(MoreOutlined, {}),
    styles: {
        color: '#dark',
        gridColumns: 'auto',
        placeContent: 'center',
        padding: 0,
        width: '3.5x',
        height: '4x',
        margin: '-.5x -.5x -.5x .5x',
        ButtonIcon: { fontSize: '20px' },
    },
});
const DisclaimerContainer = tasty({
    styles: {
        display: 'grid',
        gridColumns: 'auto',
        placeContent: 'center',
        placeItems: 'center',
        gap: '2x',
        height: 'min 20x',
        padding: '1x',
    },
});
function getOrderIcon(direction) {
    if (direction === 'asc') {
        return _jsx(ArrowDownOutlined, {});
    }
    else if (direction === 'desc') {
        return _jsx(ArrowUpOutlined, {});
    }
    else {
        return null;
    }
}
function getPaginationOptionLabel({ page, perPage, total }) {
    const firstItem = (page - 1) * perPage + 1;
    const lastItem = Math.min(total, page * perPage);
    return `${firstItem}...${lastItem}`;
}
function renderValue(value, fallback) {
    if (value === undefined || Number.isNaN(value)) {
        if (fallback) {
            return _jsx(StyledTag, { children: fallback });
        }
        else {
            return _jsx(StyledTag, { children: "UNDEFINED" });
        }
    }
    return typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}') ? (_jsx(StyledTag, { children: value.replaceAll(/[{}]+/g, '') })) : fallback ? (value || _jsx(StyledTag, { children: fallback })) : (value);
}
function Pagination(props) {
    const { page, perPage = 100, total, onChange } = props;
    const numberOfPages = Math.ceil(total / perPage);
    const onSelectionChange = useCallback((val) => {
        onChange(Number(val));
    }, [onChange]);
    return (_jsxs(Space, { gap: ".5x", "aria-label": "Pagination", children: [_jsx(Button, { "aria-label": "Previous page", isDisabled: page === 1, size: "small", type: "outline", icon: _jsx(LeftOutlined, {}), onPress: () => onChange(page - 1) }), _jsx(Select, { "aria-label": "Select page", size: "small", selectedKey: String(page), width: "min 15x", onSelectionChange: onSelectionChange, children: [...Array(numberOfPages)].map((a, i) => {
                    return (_jsx(Select.Item, { textValue: String(i + 1), children: getPaginationOptionLabel({ page: i + 1, perPage, total }) }, i + 1));
                }) }), _jsx(Button, { "aria-label": "Next page", isDisabled: page === numberOfPages, size: "small", type: "outline", icon: _jsx(RightOutlined, {}), onPress: () => onChange(page + 1) })] }));
}
function OptionsButton(props) {
    const { name, member, type, order, onAddFilter, onOrderChange, onMemberRemove, ...otherProps } = props;
    const onAction = useCallback((key) => {
        switch (key) {
            case 'none':
            case 'asc':
            case 'desc':
                onOrderChange?.(key === 'none' ? undefined : key);
                break;
            case 'remove':
                onMemberRemove(name);
                break;
            case 'filter':
                onAddFilter?.(name);
                break;
        }
    }, [onOrderChange, onMemberRemove, onAddFilter, name]);
    const disabledKeys = type === 'boolean' ? ['filter'] : [];
    const onMemberRemoveLocal = useCallback(() => onMemberRemove(name), [onMemberRemove, name]);
    if (!onAddFilter && !onOrderChange) {
        return (_jsx(OptionsButtonElement, { icon: _jsx(CloseIcon, {}), "data-member": member, ...otherProps, onPress: onMemberRemoveLocal }));
    }
    return (_jsxs(MenuTrigger, { children: [_jsx(OptionsButtonElement, { "data-member": member, ...otherProps }), _jsx(Menu, { disabledKeys: disabledKeys, onAction: onAction, children: [
                    ...(onOrderChange
                        ? [
                            _jsxs(Menu.Section, { title: "Sorting", children: [_jsx(Menu.Item, { icon: _jsx(ClearOutlined, { style: { fontSize: 16 } }), children: "Do not sort" }, "none"), _jsxs(Menu.Item, { icon: _jsx(ArrowDownOutlined, { style: { fontSize: 16 } }), textValue: "Sort ASC", children: ["Sort ", _jsx(Text.Strong, { children: ORDER_LABEL_BY_TYPE[type]?.[0] || 'ASC' })] }, "asc"), _jsxs(Menu.Item, { icon: _jsx(ArrowUpOutlined, { style: { fontSize: 16 } }), textValue: "Sort DESC", children: ["Sort ", _jsx(Text.Strong, { children: ORDER_LABEL_BY_TYPE[type]?.[1] || 'DESC' })] }, "desc")] }, "sorting"),
                        ]
                        : []),
                    _jsxs(Menu.Section, { title: "Actions", children: [onAddFilter && (_jsx(Menu.Item, { icon: _jsx(FilterOutlined, { style: { fontSize: 16 } }), children: "Add filter" }, "filter")), _jsx(Menu.Item, { icon: _jsx(CloseIcon, { color: "#danger-text" }), textValue: "Remove member", children: _jsx(Text, { color: "#danger-text", children: "Remove member" }) }, "remove")] }, "actions"),
                ] })] }));
}
const CELL_STYLES = {
    display: 'grid',
    flow: 'column',
    gridColumns: '1fr auto',
    color: {
        '': '#dark',
        inactive: '#dark.5',
    },
    preset: 't3',
    fill: '#white',
    textOverflow: 'ellipsis',
    overflow: 'hidden',
    whiteSpace: 'nowrap',
    placeSelf: 'stretch',
    width: 'min 140px',
    transition: 'color .2s ease-in-out',
};
const GridTable = tasty(Grid, {
    styles: {
        position: 'relative',
        minWidth: 'min-content',
        fill: {
            '': '#dark-04.8',
            inactive: '#dark-04.4',
        },
        gap: '1bw',
        placeContent: 'stretch',
        border: 'bottom',
        Row: {
            display: 'contents',
        },
        CellValue: {
            textOverflow: 'ellipsis',
            overflow: 'hidden',
            whiteSpace: 'nowrap',
            padding: '1x',
        },
        Cell: {
            ...CELL_STYLES,
            cursor: {
                '': 'pointer',
                inactive: 'default',
            },
        },
        NumberCell: {
            ...CELL_STYLES,
            placeContent: 'end',
            cursor: {
                '': 'pointer',
                inactive: 'default',
            },
        },
        SelectedCell: {
            ...CELL_STYLES,
            shadow: '0 0 0 1bw #purple.5, 0 0 0 (1ow - 1bw) #purple.5 inset',
            zIndex: 1,
        },
        SelectedNumberCell: {
            ...CELL_STYLES,
            placeContent: 'end',
            shadow: '0 0 0 1bw #purple.5, 0 0 0 (1ow - 1bw) #purple.5 inset',
            zIndex: 1,
        },
    },
});
const ColumnHeader = tasty({
    styles: {
        position: 'sticky',
        top: 0,
        display: 'grid',
        gridColumns: 'max-content max-content',
        placeContent: 'center space-between',
        placeItems: 'center',
        color: '#dark',
        preset: 't3m',
        padding: '1x',
        fill: {
            '': '#missing-active',
            '[data-member="measure"]': '#measure-active',
            '[data-member="dimension"]': '#dimension-active',
            '[data-member="timeDimension"]': '#time-dimension-active',
        },
        cursor: {
            '': 'default',
            movable: 'move',
        },
        zIndex: 2,
    },
});
const EMPTY_DATA = [];
const ReorderableMemberListElement = tasty({
    as: 'ul',
    styles: {
        display: 'contents',
        flow: 'row',
        padding: 0,
        margin: 0,
    },
});
function ReorderableMemberList(props) {
    let { onMove, ...itemProps } = props;
    let state = useListState(props);
    let ref = useRef(null);
    let { listBoxProps } = useListBox({
        ...itemProps,
        // Prevent dragging from changing selection.
        shouldSelectOnPressUp: true,
    }, state, ref);
    const onReorder = (e) => {
        const originalKeys = [...(itemProps.items || [])].map((item) => item.id);
        const { target, keys: movableKeys } = e;
        const { dropPosition, key: targetKey } = target;
        const movableKey = [...movableKeys][0];
        const movableIndex = originalKeys.indexOf(movableKey);
        const targetIndex = originalKeys.indexOf(targetKey);
        // reorder keys
        const newKeys = movableIndex !== targetIndex
            ? originalKeys.reduce((arr, key, i) => {
                // if key is the same as the one we are moving, skip it
                if (i === movableIndex) {
                    return arr;
                }
                // if key is the same as the target, add the movable key
                if (i === targetIndex) {
                    if (dropPosition === 'before') {
                        arr.push(movableKey);
                        arr.push(key);
                    }
                    else if (dropPosition === 'after') {
                        arr.push(key);
                        arr.push(movableKey);
                    }
                    else {
                        arr.push(key);
                    }
                }
                else {
                    arr.push(key);
                }
                return arr;
            }, [])
            : originalKeys;
        onMove(newKeys);
    };
    // Setup drag state for the collection.
    let dragState = useDraggableCollectionState({
        // Pass through events from props.
        ...itemProps,
        // Collection and selection manager come from list state.
        collection: state.collection,
        selectionManager: state.selectionManager,
        // Provide data for each dragged item. This function could
        // also be provided by the user of the component.
        getItems: (keys) => {
            return [...keys].map((key) => {
                let item = state.collection.getItem(key);
                return {
                    'text/plain': item?.textValue || '',
                };
            });
        },
        getAllowedDropOperations: () => ['move'],
    });
    useDraggableCollection(props, dragState, ref);
    let dropState = useDroppableCollectionState({
        ...itemProps,
        onReorder,
        collection: state.collection,
        selectionManager: state.selectionManager,
    });
    let { collectionProps } = useDroppableCollection({
        ...itemProps,
        // Provide drop targets for keyboard and pointer-based drag and drop.
        keyboardDelegate: new ListKeyboardDelegate(state.collection, state.disabledKeys, ref),
        dropTargetDelegate: new ListDropTargetDelegate(state.collection, ref),
        onReorder,
    }, dropState, ref);
    return (_jsx(ReorderableMemberListElement, { ...mergeProps(listBoxProps, collectionProps), ref: ref, children: [...state.collection].map((item) => (_jsx(ReorderableMember, { item: item, state: state, dragState: dragState, dropState: dropState }, item.key))) }));
}
const ReorderableMemberElement = tasty({
    as: 'div',
    styles: {
        position: 'sticky',
        top: 0,
        display: 'block',
        shadow: {
            '': '0',
            focused: '1bw solid #focus inset',
        },
    },
});
function ReorderableMember({ item, state, dragState, dropState }) {
    // Setup listbox option as normal. See useListBox docs for details.
    let ref = useRef(null);
    let { optionProps } = useOption({ key: item.key }, state, ref);
    let { isFocusVisible, focusProps } = useFocusRing();
    // Register the item as a drag source.
    let { dragProps } = useDraggableItem({
        key: item.key,
    }, dragState);
    return (_jsx(_Fragment, { children: _jsxs(ReorderableMemberElement, { ...mergeProps(optionProps, dragProps, focusProps), ref: ref, mods: {
                focused: isFocusVisible,
            }, children: [_jsx(DropIndicator, { position: "before", target: { type: 'item', key: item.key, dropPosition: 'before' }, dropState: dropState }), item.rendered, state.collection.getKeyAfter(item.key) == null && (_jsx(DropIndicator, { position: "after", target: { type: 'item', key: item.key, dropPosition: 'after' }, dropState: dropState }))] }) }));
}
const DropIndicatorElement = tasty({
    styles: {
        zIndex: 10,
        position: 'absolute',
        pointerEvents: 'none',
        opacity: {
            '': 0,
            dropTarget: 1,
        },
        fill: '#purple',
        width: '.5x',
        top: 0,
        bottom: 0,
        left: {
            '': 'auto',
            before: '-2px',
        },
        right: {
            '': 'auto',
            after: '-2px',
        },
    },
});
function DropIndicator(props) {
    const { position, target } = props;
    let ref = useRef(null);
    let { dropIndicatorProps, isHidden, isDropTarget } = useDropIndicator({ target }, props.dropState, ref);
    if (isHidden) {
        return null;
    }
    return (_jsx(DropIndicatorElement, { ref: ref, role: "option", ...dropIndicatorProps, mods: {
            'drop-target': isDropTarget,
            after: position === 'after',
            before: position === 'before',
        } }));
}
export function QueryBuilderResults({ forceMinHeight }) {
    const { isLoading, isResultOutdated, query, members, measures: measuresUpdater, dimensions: dimensionsUpdater, filters: filtersUpdater, executedQuery, resultSet, order, cubes, error, usedCubes, updateQuery, grouping, totalRows, memberViewType, meta, } = useQueryBuilderContext();
    const isCompact = usedCubes.length === 1;
    const [selectedCell, setSelectedCell] = useState(null);
    const dataRef = useRef(EMPTY_DATA);
    const tableRef = useRef(null);
    const [page, setPage] = useState(1);
    // @ts-ignore
    if (resultSet?.loadResponse?.results[0].data) {
        // @ts-ignore
        dataRef.current = resultSet?.loadResponse?.results[0].data;
    }
    const queryRelated = executedQuery && areQueriesRelated(query, executedQuery);
    if (executedQuery && !queryRelated) {
        dataRef.current = undefined;
    }
    let data = dataRef.current;
    const measures = query?.measures || [];
    const dimensions = query?.dimensions || [];
    const timeDimensions = query?.timeDimensions?.filter((member) => !!member.granularity) || [];
    const totalColumns = measures.length + dimensions.length + grouping.getAll().length;
    const isColumnsSelected = !!totalColumns;
    // scroll table to the top when page is changed
    useEffect(() => {
        if (tableRef.current) {
            tableRef.current.scrollTop = 0;
        }
        if (selectedCell) {
            setSelectedCell(null);
        }
    }, [page]);
    // reset pagination when data is changed
    useEffect(() => {
        setPage(1);
    }, [dataRef.current]);
    useEffect(() => {
        setSelectedCell(null);
    }, [isLoading]);
    if (!data) {
        data = EMPTY_DATA;
    }
    function formatCellData(dimensionName, value, granularity) {
        if (value === null) {
            return ['{{NULL}}', 'unknown'];
        }
        if (value === undefined) {
            return ['–', 'unknown'];
        }
        const cubeName = dimensionName.split('.')[0];
        const cube = cubes.find((cube) => cube.name === cubeName);
        if (!cube) {
            return [value, 'unknown'];
        }
        let member = [...cube.dimensions, ...cube.measures].find((member) => member.name === dimensionName);
        if (!member) {
            return [value, 'unknown'];
        }
        const type = typeof value !== 'string' ? typeof value : member.type;
        switch (type) {
            case 'number':
                // @ts-ignore
                switch (member.format) {
                    case 'currency':
                        return [
                            formatCurrency(typeof value === 'string' ? parseFloat(value) : value),
                            'number',
                        ];
                    case 'percent':
                        return [
                            `${formatNumber((typeof value === 'string' ? parseFloat(value) : value) * 100)}%`,
                            'percent',
                        ];
                    default:
                        return [formatNumber(typeof value === 'string' ? parseFloat(value) : value), 'number'];
                }
            case 'time':
                try {
                    if (granularity) {
                        return [formatDateByGranularity(new Date(value), granularity), 'time'];
                    }
                    else {
                        return [formatDateByGranularity(new Date(value), 'second'), 'time'];
                    }
                }
                catch (e) {
                    return [value, 'unknown'];
                }
            case 'boolean':
                return [value && value !== '0' && value !== 'false' ? '{{TRUE}}' : '{{FALSE}}', 'boolean'];
            default:
                return [String(value) || '{{EMPTY STRING}}', 'string'];
        }
    }
    const onTableClick = useCallback((e) => {
        if (isLoading) {
            return;
        }
        const { row, name } = e.nativeEvent.target.parentNode.dataset;
        if (row != null && name != null) {
            const newSelectedCell = [Number(row), name];
            if (JSON.stringify(newSelectedCell) !== JSON.stringify(selectedCell)) {
                setSelectedCell([Number(row), name]);
            }
            else {
                setSelectedCell(null);
            }
        }
        else {
            setSelectedCell(null);
        }
    }, [selectedCell, isLoading]);
    const tableData = useMemo(() => {
        return (_jsx(_Fragment, { children: data?.slice((page - 1) * 100, (page - 1) * 100 + 100).map((row, rowId) => {
                return (_jsxs("div", { "data-element": "Row", "data-qa": `QueryBuilderResult-row_${rowId}`, children: [dimensions.map((dimension) => {
                            const isSelected = selectedCell && selectedCell[0] === rowId && selectedCell[1] === dimension;
                            const [value, type] = formatCellData(dimension, row[dimension]);
                            const copyButton = isSelected &&
                                value !== '–' &&
                                (typeof value !== 'string' || !value.startsWith('{{')) ? (_jsx(StyledCopyButton, { value: String(value) })) : null;
                            const renderedValue = renderValue(value);
                            return (_jsxs("div", { "data-row": rowId, "data-name": dimension, "data-element": `${isSelected ? 'Selected' : ''}${type === 'number' || type === 'percent' ? 'Number' : ''}Cell`, children: [_jsx("div", { "data-element": "CellValue", children: renderedValue }), copyButton] }, dimension));
                        }), timeDimensions.map((timeDimension) => {
                            const isSelected = selectedCell &&
                                selectedCell[0] === rowId &&
                                selectedCell[1] === timeDimension.dimension;
                            const rawValue = row[timeDimension.dimension + '.' + timeDimension.granularity];
                            let value = rawValue ? String(rawValue) : undefined;
                            try {
                                value =
                                    value != null
                                        ? formatDateByGranularity(new Date(value), timeDimension.granularity)
                                        : '–';
                            }
                            catch (e) { }
                            const copyButton = isSelected && value !== '–' ? _jsx(StyledCopyButton, { value: value }) : null;
                            const renderedValue = renderValue(value, 'NULL');
                            return (_jsxs("div", { "data-row": rowId, "data-name": timeDimension.dimension, "data-element": `${isSelected ? 'Selected' : ''}Cell`, children: [_jsx("div", { "data-element": "CellValue", children: renderedValue }), copyButton] }, `time-dimension.${timeDimension.dimension}`));
                        }), measures.map((measure) => {
                            const isSelected = selectedCell && selectedCell[0] === rowId && selectedCell[1] === measure;
                            const [value, type] = formatCellData(measure, row[measure]);
                            const copyButton = isSelected && value !== '–' ? _jsx(StyledCopyButton, { value: String(value) }) : null;
                            const renderedValue = renderValue(value);
                            return (_jsxs("div", { "data-row": rowId, "data-name": measure, "data-element": `${isSelected ? 'Selected' : ''}${type === 'number' || type === 'percent' ? 'Number' : ''}Cell`, children: [_jsx("div", { "data-element": "CellValue", children: renderedValue }), copyButton] }, measure));
                        })] }, rowId));
            }) }));
    }, [
        isLoading,
        JSON.stringify(measures),
        JSON.stringify(dimensions),
        JSON.stringify(timeDimensions),
        page,
        selectedCell,
        data,
        meta,
    ]);
    function addFilter(name) {
        filtersUpdater.add({ member: name, operator: 'set' });
    }
    const dimensionColumns = useDeepMemo(() => {
        if (!dimensions.length) {
            return null;
        }
        const items = dimensions.map((dimension) => {
            const member = members.dimensions[dimension];
            const cubeName = dimension.split('.')[0];
            const cube = cubes.find((cube) => cube.name === cubeName);
            return {
                id: dimension,
                textValue: dimension,
                rendered: (_jsxs(ColumnHeader, { "data-member": member ? 'dimension' : undefined, mods: { movable: dimensions.length > 1 }, children: [_jsx(MemberLabel, { isMissing: !member, name: dimension, memberName: member?.name, cubeName: cube?.name, memberTitle: member?.shortTitle, cubeTitle: cube?.title, isCompact: isCompact, memberViewType: memberViewType, memberType: "dimension", type: member?.type, children: getOrderIcon(order.get(dimension)) }), _jsx(OptionsButton, { name: dimension, member: "dimension", order: order.get(dimension), type: members.dimensions[dimension]?.type || 'string', onAddFilter: member ? addFilter : undefined, onOrderChange: member
                                ? (ord) => {
                                    if (ord) {
                                        order.set(dimension, ord);
                                    }
                                    else {
                                        order.remove(dimension);
                                    }
                                }
                                : undefined, onMemberRemove: (name) => dimensionsUpdater?.remove(name) })] }, dimension)),
            };
        });
        if (dimensions.length === 1) {
            return items[0].rendered;
        }
        return (_jsx(ReorderableMemberList, { "aria-label": "Dimensions", selectionBehavior: "replace", items: items, onMove: (newKeys) => {
                updateQuery({
                    dimensions: newKeys,
                });
            }, children: (item) => _jsx(Item, { textValue: item.textValue, children: item.rendered }) }));
    }, [dimensions, JSON.stringify(query.order), meta, memberViewType, isCompact]);
    const measuresColumns = useDeepMemo(() => {
        if (!measures.length) {
            return null;
        }
        const items = measures.map((measure) => {
            const member = members.measures[measure];
            const cubeName = measure.split('.')[0];
            const cube = cubes.find((cube) => cube.name === cubeName);
            return {
                id: measure,
                textValue: measure,
                rendered: (_jsxs(ColumnHeader, { "data-member": member ? 'measure' : undefined, mods: { movable: measures.length > 1 }, children: [_jsx(MemberLabel, { isMissing: !member, name: measure, memberName: member?.name, cubeName: cube?.name, memberTitle: member?.shortTitle, cubeTitle: cube?.title, isCompact: isCompact, memberViewType: memberViewType, memberType: "measure", type: member?.type ?? 'number', children: getOrderIcon(order.get(measure)) }), _jsx(OptionsButton, { name: measure, member: "measure", order: order.get(measure), type: members.measures[measure]?.type || 'string', onAddFilter: member ? addFilter : undefined, onOrderChange: member
                                ? (ord) => {
                                    if (ord) {
                                        order.set(measure, ord);
                                    }
                                    else {
                                        order.remove(measure);
                                    }
                                }
                                : undefined, onMemberRemove: (name) => measuresUpdater?.remove(name) })] }, measure)),
            };
        });
        if (measures.length === 1) {
            return items[0].rendered;
        }
        return (_jsx(ReorderableMemberList, { "aria-label": "Measures", selectionBehavior: "replace", items: items, onMove: (newKeys) => {
                updateQuery({
                    measures: newKeys,
                });
            }, children: (item) => _jsx(Item, { textValue: item.textValue, children: item.rendered }) }));
    }, [measures, JSON.stringify(query.order), meta, memberViewType, isCompact]);
    const timeDimensionsColumns = useDeepMemo(() => {
        if (!timeDimensions.length) {
            return null;
        }
        const items = timeDimensions.map((timeDimension) => {
            const member = members.dimensions[timeDimension.dimension];
            const ordering = order.get(timeDimension.dimension);
            const availableGranularities = [
                ...((member && 'granularities' in member && member?.granularities?.map((g) => g.name)) ||
                    []),
                ...PREDEFINED_GRANULARITIES,
            ];
            const cubeName = timeDimension.dimension.split('.')[0];
            const cube = cubes.find((cube) => cube.name === cubeName);
            const granularity = timeDimension.granularity &&
                member &&
                'granularities' in member &&
                member?.granularities?.find((g) => g.name === timeDimension.granularity);
            return {
                id: timeDimension.dimension,
                textValue: timeDimension.dimension,
                rendered: (_jsxs(ColumnHeader, { "data-member": member ? 'timeDimension' : undefined, mods: { movable: timeDimensions.length > 1 }, children: [_jsxs(MemberLabel, { isMissing: !member, name: timeDimension.dimension, memberName: member?.name, cubeName: cube?.name, memberTitle: member?.shortTitle, cubeTitle: cube?.title, isCompact: isCompact, memberViewType: memberViewType, memberType: "timeDimension", type: member?.type ?? 'time', children: [granularity ? (_jsx(MemberBadge, { isSpecial: true, isMissing: !availableGranularities.includes(timeDimension.granularity) || !member, type: "timeDimension", children: memberViewType === 'title'
                                        ? granularity.title
                                        : (timeDimension.granularity ?? timeDimension.granularity) })) : undefined, getOrderIcon(ordering)] }), _jsx(OptionsButton, { name: timeDimension.dimension, member: "timeDimension", order: ordering, type: "time", onAddFilter: member ? addFilter : undefined, onOrderChange: member
                                ? (ord) => {
                                    if (ord) {
                                        order.set(timeDimension.dimension, ord);
                                    }
                                    else {
                                        order.remove(timeDimension.dimension);
                                    }
                                }
                                : undefined, onMemberRemove: (name) => grouping.remove(name) })] }, `time-dimension.${timeDimension.dimension}`)),
            };
        });
        if (timeDimensions.length === 1) {
            return items[0].rendered;
        }
        return (_jsx(ReorderableMemberList, { "aria-label": "Time dimensions", selectionBehavior: "replace", items: items, onMove: (newKeys) => {
                grouping.reorder(newKeys);
            }, children: (item) => _jsx(Item, { textValue: item.textValue, children: item.rendered }) }));
    }, [timeDimensions, JSON.stringify(query.order), meta, memberViewType, isCompact]);
    const timestamp = useMemo(() => {
        return new Date();
    }, [tableData]);
    const [timeDistance, setTimeDistance] = useState(formatDistance(timestamp, new Date(), { addSuffix: true }));
    useIntervalEffect(() => {
        setTimeDistance(formatDistance(timestamp, new Date(), { addSuffix: true }));
    }, 60 * 1000);
    const noResultsDisclaimer = (_jsxs(DisclaimerContainer, { children: [_jsx(Title, { level: 4, gridArea: false, children: "No results available" }), _jsx(Paragraph, { children: "Compose and run a query to see the results." })] }));
    return (_jsxs(Panel, { qa: "QueryBuilderResults", flow: "column", gridRows: "minmax(0, 1fr) min-content", overflow: "clip", height: forceMinHeight ? 'min 31x' : 'initial', children: [isColumnsSelected ? (_jsx(Panel, { gridRows: "minmax(0, 1fr)", children: _jsxs(TableContainer, { ref: tableRef, onClick: onTableClick, onTouchStart: onTableClick, children: [_jsxs(GridTable, { columns: `repeat(${totalColumns}, auto)`, mods: { inactive: !!(isLoading || error) }, children: [dimensionColumns, timeDimensionsColumns, measuresColumns, tableData] }), !executedQuery ? noResultsDisclaimer : null] }) })) : (noResultsDisclaimer), _jsxs(TableFooter, { children: [_jsxs(Space, { children: [isLoading ? _jsx(LoadingOutlined, {}) : isResultOutdated ? _jsx(OutdatedLabel, {}) : undefined, executedQuery && !isLoading && isColumnsSelected && queryRelated && (_jsxs(Space, { gap: ".75x", children: [_jsx(Text, { preset: "t3m", children: data.length
                                            ? `${data.length} result${data.length > 1 ? 's' : ''}${totalRows
                                                ? totalRows === data.length
                                                    ? ' in total'
                                                    : ` out of ${totalRows} in total`
                                                : ''}`
                                            : 'No results' }), _jsxs(Text, { preset: "t3", children: ["received ", timeDistance] })] }))] }), _jsx(Space, { children: data.length > 100 ? (_jsx(Pagination, { page: page, total: data.length, onChange: setPage })) : null })] })] }));
}
//# sourceMappingURL=QueryBuilderResults.js.map