"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TransactionsTable = TransactionsTable;
var _eui = require("@elastic/eui");
var _i18n = require("@kbn/i18n");
var _i18nReact = require("@kbn/i18n-react");
var _lodash = require("lodash");
var _react = _interopRequireWildcard(require("react"));
var _reactRouterDom = require("react-router-dom");
var _uuid = require("uuid");
var _document_type = require("../../../../common/document_type");
var _latency_aggregation_types = require("../../../../common/latency_aggregation_types");
var _use_apm_service_context = require("../../../context/apm_service/use_apm_service_context");
var _use_apm_params = require("../../../hooks/use_apm_params");
var _use_apm_router = require("../../../hooks/use_apm_router");
var _use_breakpoints = require("../../../hooks/use_breakpoints");
var _use_fetcher = require("../../../hooks/use_fetcher");
var _use_preferred_data_source_and_bucket_size = require("../../../hooks/use_preferred_data_source_and_bucket_size");
var _transaction_overview_link = require("../links/apm/transaction_overview_link");
var _url_helpers = require("../links/url_helpers");
var _overview_table_container = require("../overview_table_container");
var _get_comparison_options = require("../time_comparison/get_comparison_options");
var _get_columns = require("./get_columns");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

const INITIAL_STATE = {
  requestId: '',
  mainStatisticsData: {
    transactionGroups: [],
    maxTransactionGroupsExceeded: false,
    transactionOverflowCount: 0,
    transactionGroupsTotalItems: 0,
    hasActiveAlerts: false
  }
};
const DEFAULT_SORT = {
  direction: 'desc',
  field: 'impact'
};
function TransactionsTable({
  fixedHeight = false,
  hideViewTransactionsLink = false,
  hideTitle = false,
  isSingleColumn = true,
  numberOfTransactionsPerPage = 5,
  showPerPageOptions = true,
  showMaxTransactionGroupsExceededWarning = false,
  environment,
  kuery,
  start,
  end,
  saveTableOptionsToUrl = false
}) {
  var _preferred$source;
  const history = (0, _reactRouterDom.useHistory)();
  const {
    link
  } = (0, _use_apm_router.useApmRouter)();
  const {
    query,
    query: {
      comparisonEnabled,
      offset,
      latencyAggregationType: latencyAggregationTypeFromQuery,
      page: urlPage = 0,
      pageSize: urlPageSize = numberOfTransactionsPerPage,
      sortField: urlSortField = 'impact',
      sortDirection: urlSortDirection = 'desc'
    }
  } = (0, _use_apm_params.useAnyOfApmParams)('/services/{serviceName}/transactions', '/services/{serviceName}/overview', '/mobile-services/{serviceName}/transactions', '/mobile-services/{serviceName}/overview');
  const latencyAggregationType = (0, _latency_aggregation_types.getLatencyAggregationType)(latencyAggregationTypeFromQuery);
  const [tableOptions, setTableOptions] = (0, _react.useState)({
    page: {
      index: urlPage,
      size: urlPageSize
    },
    sort: {
      field: urlSortField,
      direction: urlSortDirection
    }
  });

  // SparkPlots should be hidden if we're in two-column view and size XL (1200px)
  const {
    isXl
  } = (0, _use_breakpoints.useBreakpoints)();
  const shouldShowSparkPlots = isSingleColumn || !isXl;
  const {
    page,
    sort
  } = tableOptions;
  const {
    direction,
    field
  } = sort;
  const {
    index,
    size
  } = page;
  const {
    transactionType,
    serviceName
  } = (0, _use_apm_service_context.useApmServiceContext)();
  const preferred = (0, _use_preferred_data_source_and_bucket_size.usePreferredDataSourceAndBucketSize)({
    start,
    end,
    kuery,
    numBuckets: 20,
    type: _document_type.ApmDocumentType.TransactionMetric
  });
  const shouldUseDurationSummary = latencyAggregationType === 'avg' && (preferred === null || preferred === void 0 ? void 0 : (_preferred$source = preferred.source) === null || _preferred$source === void 0 ? void 0 : _preferred$source.hasDurationSummaryField);
  const {
    data = INITIAL_STATE,
    status
  } = (0, _use_fetcher.useFetcher)(callApmApi => {
    if (!latencyAggregationType || !transactionType || !preferred) {
      return Promise.resolve(undefined);
    }
    return callApmApi('GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics', {
      params: {
        path: {
          serviceName
        },
        query: {
          environment,
          kuery,
          start,
          end,
          transactionType,
          useDurationSummary: !!shouldUseDurationSummary,
          latencyAggregationType: latencyAggregationType,
          documentType: preferred.source.documentType,
          rollupInterval: preferred.source.rollupInterval
        }
      }
    }).then(response => {
      const currentPageTransactionGroups = (0, _lodash.orderBy)(response.transactionGroups, [field], [direction]).slice(index * size, (index + 1) * size);
      return {
        // Everytime the main statistics is refetched, updates the requestId making the detailed API to be refetched.
        requestId: (0, _uuid.v4)(),
        mainStatisticsData: {
          ...response,
          transactionGroups: currentPageTransactionGroups,
          transactionGroupsTotalItems: response.transactionGroups.length
        }
      };
    });
  },
  // eslint-disable-next-line react-hooks/exhaustive-deps
  [environment, kuery, serviceName, start, end, transactionType, latencyAggregationType, index, size, direction, field,
  // not used, but needed to trigger an update when offset is changed either manually by user or when time range is changed
  offset,
  // not used, but needed to trigger an update when comparison feature is disabled/enabled by user
  comparisonEnabled, preferred]);
  const {
    requestId,
    mainStatisticsData: {
      transactionGroups,
      maxTransactionGroupsExceeded,
      transactionOverflowCount,
      transactionGroupsTotalItems,
      hasActiveAlerts
    }
  } = data;
  const {
    data: transactionGroupDetailedStatistics,
    status: transactionGroupDetailedStatisticsStatus
  } = (0, _use_fetcher.useFetcher)(callApmApi => {
    if (transactionGroupsTotalItems && start && end && transactionType && latencyAggregationType && preferred) {
      return callApmApi('GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics', {
        params: {
          path: {
            serviceName
          },
          query: {
            environment,
            kuery,
            start,
            end,
            bucketSizeInSeconds: preferred.bucketSizeInSeconds,
            transactionType,
            documentType: preferred.source.documentType,
            rollupInterval: preferred.source.rollupInterval,
            useDurationSummary: !!shouldUseDurationSummary,
            latencyAggregationType: latencyAggregationType,
            transactionNames: JSON.stringify(transactionGroups.map(({
              name
            }) => name).sort()),
            offset: comparisonEnabled && (0, _get_comparison_options.isTimeComparison)(offset) ? offset : undefined
          }
        }
      });
    }
  },
  // only fetches detailed statistics when requestId is invalidated by main statistics api call
  // eslint-disable-next-line react-hooks/exhaustive-deps
  [requestId], {
    preservePreviousData: false
  });
  const columns = (0, _get_columns.getColumns)({
    serviceName,
    latencyAggregationType: latencyAggregationType,
    transactionGroupDetailedStatisticsLoading: (0, _use_fetcher.isPending)(transactionGroupDetailedStatisticsStatus),
    transactionGroupDetailedStatistics,
    comparisonEnabled,
    shouldShowSparkPlots,
    offset,
    transactionOverflowCount,
    showAlertsColumn: hasActiveAlerts,
    link,
    query
  });
  const pagination = (0, _react.useMemo)(() => ({
    pageIndex: index,
    pageSize: size,
    totalItemCount: transactionGroupsTotalItems,
    showPerPageOptions
  }), [index, size, transactionGroupsTotalItems, showPerPageOptions]);
  const sorting = (0, _react.useMemo)(() => ({
    sort: {
      field,
      direction
    }
  }), [field, direction]);
  return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
    direction: "column",
    gutterSize: "s",
    "data-test-subj": "transactionsGroupTable"
  }, !hideTitle && /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
    justifyContent: "spaceBetween",
    responsive: false
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiTitle, {
    size: "xs"
  }, /*#__PURE__*/_react.default.createElement("h2", null, _i18n.i18n.translate('xpack.apm.transactionsTable.title', {
    defaultMessage: 'Transactions'
  })))), !hideViewTransactionsLink && /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_transaction_overview_link.TransactionOverviewLink, {
    serviceName: serviceName,
    latencyAggregationType: latencyAggregationType,
    transactionType: transactionType
  }, _i18n.i18n.translate('xpack.apm.transactionsTable.linkText', {
    defaultMessage: 'View transactions'
  }))))), showMaxTransactionGroupsExceededWarning && maxTransactionGroupsExceeded && /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiCallOut, {
    title: _i18n.i18n.translate('xpack.apm.transactionsCallout.cardinalityWarning.title', {
      defaultMessage: 'Number of transaction groups exceed the allowed maximum(1,000) that are displayed.'
    }),
    color: "warning",
    iconType: "warning"
  }, /*#__PURE__*/_react.default.createElement("p", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
    id: "xpack.apm.transactionsCallout.transactionGroupLimit.exceeded",
    defaultMessage: "The maximum number of transaction groups displayed in Kibana has been reached. Try narrowing down results by using the query bar."
  })))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_overview_table_container.OverviewTableContainer, {
    fixedHeight: fixedHeight,
    isEmptyAndNotInitiated: transactionGroupsTotalItems === 0 && status === _use_fetcher.FETCH_STATUS.NOT_INITIATED
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiBasicTable, {
    loading: status === _use_fetcher.FETCH_STATUS.LOADING,
    noItemsMessage: status === _use_fetcher.FETCH_STATUS.LOADING ? _i18n.i18n.translate('xpack.apm.transactionsTable.loading', {
      defaultMessage: 'Loading...'
    }) : _i18n.i18n.translate('xpack.apm.transactionsTable.noResults', {
      defaultMessage: 'No transactions found'
    }),
    error: status === _use_fetcher.FETCH_STATUS.FAILURE ? _i18n.i18n.translate('xpack.apm.transactionsTable.errorMessage', {
      defaultMessage: 'Failed to fetch'
    }) : '',
    items: transactionGroups,
    columns: columns,
    pagination: pagination,
    sorting: sorting,
    onChange: newTableOptions => {
      var _newTableOptions$page, _newTableOptions$page2, _newTableOptions$page3, _newTableOptions$page4;
      setTableOptions({
        page: {
          index: (_newTableOptions$page = (_newTableOptions$page2 = newTableOptions.page) === null || _newTableOptions$page2 === void 0 ? void 0 : _newTableOptions$page2.index) !== null && _newTableOptions$page !== void 0 ? _newTableOptions$page : 0,
          size: (_newTableOptions$page3 = (_newTableOptions$page4 = newTableOptions.page) === null || _newTableOptions$page4 === void 0 ? void 0 : _newTableOptions$page4.size) !== null && _newTableOptions$page3 !== void 0 ? _newTableOptions$page3 : numberOfTransactionsPerPage
        },
        sort: newTableOptions.sort ? {
          field: newTableOptions.sort.field,
          direction: newTableOptions.sort.direction
        } : DEFAULT_SORT
      });
      if (saveTableOptionsToUrl) {
        var _newTableOptions$page5, _newTableOptions$page6, _newTableOptions$sort, _newTableOptions$sort2;
        history.push({
          ...history.location,
          search: (0, _url_helpers.fromQuery)({
            ...(0, _url_helpers.toQuery)(history.location.search),
            page: (_newTableOptions$page5 = newTableOptions.page) === null || _newTableOptions$page5 === void 0 ? void 0 : _newTableOptions$page5.index,
            pageSize: (_newTableOptions$page6 = newTableOptions.page) === null || _newTableOptions$page6 === void 0 ? void 0 : _newTableOptions$page6.size,
            sortField: (_newTableOptions$sort = newTableOptions.sort) === null || _newTableOptions$sort === void 0 ? void 0 : _newTableOptions$sort.field,
            sortDirection: (_newTableOptions$sort2 = newTableOptions.sort) === null || _newTableOptions$sort2 === void 0 ? void 0 : _newTableOptions$sort2.direction
          })
        });
      }
    }
  })))));
}