UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

210 lines (182 loc) 6.83 kB
// (C) 2019-2020 GoodData Corporation import get = require("lodash/get"); import set = require("lodash/set"); import includes = require("lodash/includes"); import every = require("lodash/every"); import isEmpty = require("lodash/isEmpty"); import omitBy = require("lodash/omitBy"); import isNil = require("lodash/isNil"); import { AFM } from "@gooddata/typings"; import { DataLayer } from "@gooddata/gooddata-js"; import { SORT_DIR_ASC, SORT_DIR_DESC } from "../constants/sort"; import { IBucket, IBucketItem, IExtendedReferencePoint, IVisualizationProperties, } from "../interfaces/Visualization"; import { getFirstAttribute, getFirstValidMeasure } from "./bucketHelper"; import { VisualizationTypes } from "../../constants/visualizationTypes"; import * as SortsHelper from "../../helpers/sorts"; export function getMeasureSortItems(identifier: string, direction: AFM.SortDirection): AFM.SortItem[] { return [ { measureSortItem: { direction, locators: [ { measureLocatorItem: { measureIdentifier: identifier, }, }, ], }, }, ]; } function getDefaultTableSort(afm: AFM.IAfm): AFM.SortItem[] { const attribute: AFM.IAttribute = get(afm, "attributes.0"); if (!attribute) { return SortsHelper.getFirstMeasureSort(afm); } return [SortsHelper.getAttributeSortItem(attribute.localIdentifier, SORT_DIR_ASC)]; } function getDefaultGeoPushpinSort(afm: AFM.IAfm): AFM.SortItem[] { return SortsHelper.getDefaultAttributeGeoPushpinSort(afm); } export function getDefaultPivotTableSort(afm: AFM.IAfm): AFM.SortItem[] { const attribute: AFM.IAttribute = get(afm, "attributes.0"); if (!attribute) { return []; } return []; } function sanitizeSorts(afm: AFM.IAfm, sorts: AFM.SortItem[]): AFM.SortItem[] { if (isEmpty(sorts)) { return []; } return sorts.filter((sortItem: AFM.SortItem) => DataLayer.ResultSpecUtils.isSortValid(afm, sortItem)); } // Consider disolving this function into individual components export function createSorts( type: string, afm: AFM.IAfm, resultSpec: AFM.IResultSpec, visualizationProperties: IVisualizationProperties, canSortStackTotalValue: boolean = false, enableSortingByTotalGroup: boolean = false, ): AFM.SortItem[] { const sortItems = get(visualizationProperties, "sortItems", []) as AFM.SortItem[]; const sanitizedSortItems: AFM.SortItem[] = sanitizeSorts(afm, sortItems); // reuse sorts only for Table // This does not apply to PivotTable, it doesn't use this function at all if (type === VisualizationTypes.TABLE && !isEmpty(sanitizedSortItems)) { return sanitizedSortItems; } switch (type) { case VisualizationTypes.TABLE: return getDefaultTableSort(afm); case VisualizationTypes.COLUMN: case VisualizationTypes.LINE: return []; case VisualizationTypes.BAR: return SortsHelper.getDefaultBarChartSort( afm, resultSpec, canSortStackTotalValue, enableSortingByTotalGroup, ); case VisualizationTypes.TREEMAP: return SortsHelper.getDefaultTreemapSort(afm, resultSpec); case VisualizationTypes.PUSHPIN: return getDefaultGeoPushpinSort(afm); case VisualizationTypes.HEATMAP: return SortsHelper.getDefaultHeatmapSort(resultSpec); } return []; } export function getBucketItemIdentifiers(referencePoint: IExtendedReferencePoint): string[] { const buckets: IBucket[] = get(referencePoint, "buckets", []); return buckets.reduce((localIdentifiers: string[], bucket: IBucket): string[] => { const items: IBucketItem[] = get(bucket, "items", []); return localIdentifiers.concat(items.map((item: IBucketItem): string => item.localIdentifier)); }, []); } export function getSortIdentifiers(item: AFM.SortItem): string[] { if (AFM.isMeasureSortItem(item)) { return get(item, "measureSortItem.locators", []).map((locator: AFM.LocatorItem) => { if (get(locator, "measureLocatorItem")) { return get(locator, "measureLocatorItem.measureIdentifier"); } else { return get(locator, "attributeLocatorItem.attributeIdentifier"); } }); } if (AFM.isAttributeSortItem(item)) { const attribute = get(item, "attributeSortItem.attributeIdentifier"); if (attribute) { return [attribute]; } } return []; } function isSortItemValid(item: AFM.SortItem, identifiers: string[]) { const sortIdentifiers = getSortIdentifiers(item); return every(sortIdentifiers, id => includes(identifiers, id)); } export function removeSort(referencePoint: Readonly<IExtendedReferencePoint>) { if (referencePoint.properties) { const properties = omitBy( { ...referencePoint.properties, sortItems: null, }, isNil, ); return { ...referencePoint, properties, }; } return referencePoint; } export function removeInvalidSort(referencePoint: Readonly<IExtendedReferencePoint>) { if (referencePoint.properties) { const identifiers = getBucketItemIdentifiers(referencePoint); let sortItems = referencePoint.properties.sortItems || []; sortItems = sortItems.filter((item: AFM.SortItem) => { return isSortItemValid(item, identifiers); }); return { ...referencePoint, properties: { ...referencePoint.properties, sortItems, }, }; } return referencePoint; } export function setSortItems(referencePoint: IExtendedReferencePoint) { const buckets = referencePoint.buckets; const sortItems = get(referencePoint, ["properties", "sortItems"], []); if (sortItems.length > 0) { return referencePoint; } const firstMeasure = getFirstValidMeasure(buckets); const firstAttribute = getFirstAttribute(buckets); if (firstMeasure !== null && firstAttribute == null) { set( referencePoint, ["properties", "sortItems"], getMeasureSortItems(firstMeasure.localIdentifier, SORT_DIR_DESC), ); } else if (firstAttribute !== null) { set( referencePoint, ["properties", "sortItems"], [SortsHelper.getAttributeSortItem(firstAttribute.localIdentifier, SORT_DIR_ASC)], ); } return referencePoint; }