<commit_before>import * as React from "react"
import { computed, observable, action } from "mobx"
import { observer } from "mobx-react"
import classnames from "classnames"

import { IconDefinition } from "@fortawesome/fontawesome-svg-core"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons/faInfoCircle"
import { faSortAmountDownAlt } from "@fortawesome/free-solid-svg-icons/faSortAmountDownAlt"
import { faSortAmountUp } from "@fortawesome/free-solid-svg-icons/faSortAmountUp"
import { faSortAlphaDown } from "@fortawesome/free-solid-svg-icons/faSortAlphaDown"
import { faSortAlphaUpAlt } from "@fortawesome/free-solid-svg-icons/faSortAlphaUpAlt"

import { ChartConfig } from "./ChartConfig"
import { capitalize, some, defaultTo, orderBy } from "./Util"
import { Tippy } from "./Tippy"
import {
    DataTableTransform,
    DataTableRow,
    TargetYearMode,
    SortOrder,
    ColumnKey,
    isSingleValue,
    DataTableDimension,
    DataTableColumn,
    DimensionValue,
    isRangeValue,
    RangeValueKey,
    SingleValueKey,
    Value
} from "./DataTableTransform"

export interface DataTableProps {
    chart: ChartConfig
}

export interface DataTableState {
    sort: DataTableSortState
}

const ENTITY_DIM_INDEX = -1

export type DimensionIndex = number

export interface DataTableSortState {
    dimIndex: DimensionIndex
    columnKey: ColumnKey | undefined
    order: SortOrder
}

const DEFAULT_SORT_STATE: DataTableSortState = {
    dimIndex: ENTITY_DIM_INDEX,
    columnKey: undefined,
    order: SortOrder.asc
}

const columnNameByType: Record<ColumnKey, string> = {
    single: "Value",
    start: "Start",
    end: "End",
    delta: "Change",
    deltaRatio: "Change (%)"
}

function inverseSortOrder(order: SortOrder): SortOrder {
    return order === SortOrder.asc ? SortOrder.desc : SortOrder.asc
}

@observer
export class DataTable extends React.Component<DataTableProps> {
    @observable private storedState: DataTableState = {
        sort: DEFAULT_SORT_STATE
    }

    @computed get tableState(): DataTableState {
        return {
            sort: this.sortState
        }
    }

    @computed get sortState(): DataTableSortState {
        let { dimIndex, columnKey, order } = {
            ...DEFAULT_SORT_STATE,
            ...this.storedState.sort
        }

        // If not sorted by entity, then make sure the index of the chosen column exists
        if (dimIndex !== ENTITY_DIM_INDEX) {
            dimIndex = Math.min(dimIndex, this.transform.dimensions.length - 1)
            const availableColumns = this.transform.dimensionsWithValues[
                dimIndex
            ].columns.map(sub => sub.key)
            if (
                columnKey === undefined ||
                !availableColumns.includes(columnKey)
            ) {
                columnKey = availableColumns[0]
            }
        }

        return {
            dimIndex,
            columnKey,
            order
        }
    }

    @computed get entityType() {
        return this.props.chart.entityType
    }

    @computed get transform() {
        return new DataTableTransform(this.props.chart)
    }

    @computed get sortValueMapper(): (
        row: DataTableRow
    ) => number | string | undefined {
        const { dimIndex, columnKey, order } = this.tableState.sort<commit_msg>Fix: sorting by a dimension that isn't loaded crashes the page<commit_after>import * as React from "react"
import { computed, observable, action } from "mobx"
import { observer } from "mobx-react"
import classnames from "classnames"

import { IconDefinition } from "@fortawesome/fontawesome-svg-core"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons/faInfoCircle"
import { faSortAmountDownAlt } from "@fortawesome/free-solid-svg-icons/faSortAmountDownAlt"
import { faSortAmountUp } from "@fortawesome/free-solid-svg-icons/faSortAmountUp"
import { faSortAlphaDown } from "@fortawesome/free-solid-svg-icons/faSortAlphaDown"
import { faSortAlphaUpAlt } from "@fortawesome/free-solid-svg-icons/faSortAlphaUpAlt"

import { ChartConfig } from "./ChartConfig"
import { capitalize, some, defaultTo, orderBy } from "./Util"
import { Tippy } from "./Tippy"
import {
    DataTableTransform,
    DataTableRow,
    TargetYearMode,
    SortOrder,
    ColumnKey,
    isSingleValue,
    DataTableDimension,
    DataTableColumn,
    DimensionValue,
    isRangeValue,
    RangeValueKey,
    SingleValueKey,
    Value
} from "./DataTableTransform"

export interface DataTableProps {
    chart: ChartConfig
}

export interface DataTableState {
    sort: DataTableSortState
}

const ENTITY_DIM_INDEX = -1

export type DimensionIndex = number

export interface DataTableSortState {
    dimIndex: DimensionIndex
    columnKey: ColumnKey | undefined
    order: SortOrder
}

const DEFAULT_SORT_STATE: DataTableSortState = {
    dimIndex: ENTITY_DIM_INDEX,
    columnKey: undefined,
    order: SortOrder.asc
}

const columnNameByType: Record<ColumnKey, string> = {
    single: "Value",
    start: "Start",
    end: "End",
    delta: "Change",
    deltaRatio: "Change (%)"
}

function inverseSortOrder(order: SortOrder): SortOrder {
    return order === SortOrder.asc ? SortOrder.desc : SortOrder.asc
}

@observer
export class DataTable extends React.Component<DataTableProps> {
    @observable private storedState: DataTableState = {
        sort: DEFAULT_SORT_STATE
    }

    @computed get tableState(): DataTableState {
        return {
            sort: this.sortState
        }
    }

    @computed get sortState(): DataTableSortState {
        let { dimIndex, columnKey, order } = {
            ...DEFAULT_SORT_STATE,
            ...this.storedState.sort
        }

        // If not sorted by entity, then make sure the index of the chosen column exists
        dimIndex = Math.min(dimIndex, this.transform.dimensions.length - 1)
        if (dimIndex !== ENTITY_DIM_INDEX) {
            const availableColumns = this.transform.dimensionsWithValues[
                dimIndex
            ].columns.map(sub => sub.key)
            if (
                columnKey === undefined ||
                !availableColumns.includes(columnKey)
            ) {
                columnKey = availableColumns[0]
            }
        }

        return {
            dimIndex,
            columnKey,
            order
        }
    }

    @computed get entityType() {
        return this.props.chart.entityType
    }

    @computed get transform() {
        return new DataTableTransform(this.props.chart)
    }

    @computed get sortValueMapper(): (
        row: DataTableRow
    ) => number | string | undefined {
        const { dimIndex, columnKey, order } = this.tableState.sort
{'fraction_non_alphanumeric': 0.09460849125899809, 'fraction_numerical': 0.0008814455707360071, 'mean_word_length': 2.8182837913628718, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5962267', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1948, 'n_words': 465}