<commit_before>import React, { useContext, useEffect, useState } from "react";
import { AnalysesContext } from "../../contexts/AnalysesContext";
import { Button, Icon, Popconfirm, Table } from "antd";
import {
  dateColumnFormat,
  nameColumnFormat
} from "../ant.design/table-renderers";
import {
  fetchAllPipelinesStates,
  fetchAllPipelinesTypes
} from "../../apis/analysis/analysis";
import { AnalysisState } from "./AnalysisState";
import { getI18N } from "../../utilities/i18n-utilties";
import { getHumanizedDuration } from "../../utilities/date-utilities.js";
import { getTextSearchProps } from "../ant.design/table-search-props";
import { blue6 } from "../../styles/colors";
import { SPACE_MD } from "../../styles/spacing";

/**
 * Displays the Analyses Table for both user and admin pages.
 * @returns {*}
 * @constructor
 */
export function AnalysesTable() {
  const CAN_MANAGE = window.PAGE.canManage;
  const {
    loading,
    total,
    pageSize,
    analyses,
    handleTableChange,
    deleteAnalyses
  } = useContext(AnalysesContext);

  const [selected, setSelected] = useState([]);
  const [pipelineStates, setPipelineStates] = useState([]);
  const [pipelineTypes, setPipelineTypes] = useState([]);
  const [deleting, setDeleting] = useState(false);

  useEffect(() => {
    Promise.all([fetchAllPipelinesStates(), fetchAllPipelinesTypes()]).then(
      ([states, types]) => {
        setPipelineStates(states);
        setPipelineTypes(types);
      }
    );
  }, []);

  const columns = [
    {
      ...nameColumnFormat({
        url: `${window.TL.BASE_URL}analysis/`,
        width: 300
      }),
      title: getI18N("analyses.analysis-name"),
      key: "name",
      ...getTextSearchProps("name")
    },
    {
      title: getI18N("analyses.state"),
      key: "state",
      dataIndex: "state",
      filterMultiple: true,
      filters: pipelineStates,
      width: 150,
      filterIcon(filtered) {
        return (
          <Icon
            type="filter"
            theme="filled"
            style={{ color: filtered ? blue6 : undefined }}
            className="t-state"
          />
        );
      },
      render(state) {
        return <AnalysisState state={state} />;
      }
    },
    {
      title: getI18N("analyses.type"),
      key: "type",
      width: 250,
      dataIndex: "type",
      filterMultiple: true,
      filterIcon(filtered) {
        return (
          <Icon
            type="filter"
            theme="filled"
            style={{ color: filtered ? blue6 : undefined }}
            className="t-type"
          />
        );
      },
      filters: pipelineTypes
    },
    {
      title: getI18N("analyses.submitter"),
      width: 200,
      key: "submitter",
      sorter: true,
      dataIndex: "submitter"
    },
    {
      ...dateColumnFormat(),
      title: "Created Date",
      dataIndex: "createdDate",
      key: "createdDate"
    },
    {
      title: getI18N("analysis.duration"),
      key: "duration",
      width: 150,
      dataIndex: "duration",
      render(timestamp) {
        return getHumanizedDuration({ date: timestamp });
      }
    },
    {
      title: "",
      key: "download",
      fixed: "right",
      render(text, record) {
        return (
          <Button
            shape="circle-outline"
            disabled={record.state.value !== "COMPLETED"}
            href={`${window.TL.BASE_URL}ajax/analyses/download/${record.id}`}
            download
            icon="download"
          />
        );
      }
    }
  ];

  let rowSelection;
  if (CAN_MANAGE) {
    rowSelection = {
      selectedRowKeys: selected,
      onChange: selectedRowKeys => setSelected(selectedRowKeys),
      getCheckboxProps: record => ({ name: record.name })
    };
  }

  return (
    <div>
      <div style={{ marginBottom: SPACE_MD }}>
        <Popconfirm
          placement="bottomRight"
          title={getI18N("analyses.delete-confirm").replace(
            "[COUNT]",
            selected.length
          )}
          onVisibleChange={visible => setDeleting(visible)}
          onConfirm={() =>
            deleteAnalyses(selected).then(() => setDeleting(false))
          }
        >
          <Button
            loading={deleting}
            disabled={!selected.length}
            onClick={() => setDeleting(true)}
          >
            {getI18N("analyses.delete")}
          </Button>
        </Popconfirm>
      </div>
      <Table
        rowSelection={rowSelection}
        scroll={{ x: "max-content" }}
        rowKey={record => record.id}
        loading={loading}
        pagination={{ total, pageSize }}
        columns={columns}
        dataSource={analyses}
        onChange={handleTableChange}
      />
    </div>
  );
}<commit_msg>Fixed issue with older selection being still selected.<commit_after>import React, { useContext, useEffect, useState } from "react";
import { AnalysesContext } from "../../contexts/AnalysesContext";
import { Button, Icon, Popconfirm, Table } from "antd";
import {
  dateColumnFormat,
  nameColumnFormat
} from "../ant.design/table-renderers";
import {
  fetchAllPipelinesStates,
  fetchAllPipelinesTypes
} from "../../apis/analysis/analysis";
import { AnalysisState } from "./AnalysisState";
import { getI18N } from "../../utilities/i18n-utilties";
import { getHumanizedDuration } from "../../utilities/date-utilities.js";
import { getTextSearchProps } from "../ant.design/table-search-props";
import { blue6 } from "../../styles/colors";
import { SPACE_MD } from "../../styles/spacing";

/**
 * Displays the Analyses Table for both user and admin pages.
 * @returns {*}
 * @constructor
 */
export function AnalysesTable() {
  const CAN_MANAGE = window.PAGE.canManage;
  const {
    loading,
    total,
    pageSize,
    analyses,
    handleTableChange,
    deleteAnalyses
  } = useContext(AnalysesContext);

  const [selected, setSelected] = useState([]);
  const [pipelineStates, setPipelineStates] = useState([]);
  const [pipelineTypes, setPipelineTypes] = useState([]);
  const [deleting, setDeleting] = useState(false);

  useEffect(() => {
    Promise.all([fetchAllPipelinesStates(), fetchAllPipelinesTypes()]).then(
      ([states, types]) => {
        setPipelineStates(states);
        setPipelineTypes(types);
      }
    );
  }, []);

  const columns = [
    {
      ...nameColumnFormat({
        url: `${window.TL.BASE_URL}analysis/`,
        width: 300
      }),
      title: getI18N("analyses.analysis-name"),
      key: "name",
      ...getTextSearchProps("name")
    },
    {
      title: getI18N("analyses.state"),
      key: "state",
      dataIndex: "state",
      filterMultiple: true,
      filters: pipelineStates,
      width: 150,
      filterIcon(filtered) {
        return (
          <Icon
            type="filter"
            theme="filled"
            style={{ color: filtered ? blue6 : undefined }}
            className="t-state"
          />
        );
      },
      render(state) {
        return <AnalysisState state={state} />;
      }
    },
    {
      title: getI18N("analyses.type"),
      key: "type",
      width: 250,
      dataIndex: "type",
      filterMultiple: true,
      filterIcon(filtered) {
        return (
          <Icon
            type="filter"
            theme="filled"
            style={{ color: filtered ? blue6 : undefined }}
            className="t-type"
          />
        );
      },
      filters: pipelineTypes
    },
    {
      title: getI18N("analyses.submitter"),
      width: 200,
      key: "submitter",
      sorter: true,
      dataIndex: "submitter"
    },
    {
      ...dateColumnFormat(),
      title: "Created Date",
      dataIndex: "createdDate",
      key: "createdDate"
    },
    {
      title: getI18N("analysis.duration"),
      key: "duration",
      width: 150,
      dataIndex: "duration",
      render(timestamp) {
        return getHumanizedDuration({ date: timestamp });
      }
    },
    {
      title: "",
      key: "download",
      fixed: "right",
      render(text, record) {
        return (
          <Button
            shape="circle-outline"
            disabled={record.state.value !== "COMPLETED"}
            href={`${window.TL.BASE_URL}ajax/analyses/download/${record.id}`}
            download
            icon="download"
          />
        );
      }
    }
  ];

  let rowSelection;
  if (CAN_MANAGE) {
    rowSelection = {
      selectedRowKeys: selected,
      onChange: selectedRowKeys => setSelected(selectedRowKeys),
      getCheckboxProps: record => ({ name: record.name })
    };
  }

  return (
    <div>
      <div style={{ marginBottom: SPACE_MD }}>
        <Popconfirm
          placement="bottomRight"
          title={getI18N("analyses.delete-confirm").replace(
            "[COUNT]",
            selected.length
          )}
          onVisibleChange={visible => setDeleting(visible)}
          onConfirm={() => deleteAnalyses(selected).then(() => setSelected([]))}
        >
          <Button
            loading={deleting}
            disabled={!selected.length}
            onClick={() => setDeleting(true)}
          >
            {getI18N("analyses.delete")}
          </Button>
        </Popconfirm>
      </div>
      <Table
        rowSelection={rowSelection}
        scroll={{ x: "max-content" }}
        rowKey={record => record.id}
        loading={loading}
        pagination={{ total, pageSize }}
        columns={columns}
        dataSource={analyses}
        onChange={handleTableChange}
      />
    </div>
  );
}
{'fraction_non_alphanumeric': 0.14550236717517095, 'fraction_numerical': 0.007574960547080484, 'mean_word_length': 2.110602094240838, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6988998', 'n_tokens_mistral': 2811, 'n_tokens_neox': 2741, 'n_words': 533}