"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.densityValues = exports.DataTable = void 0;
var _Checkbox2 = _interopRequireDefault(require("@mui/material/Checkbox"));
var _materialReactTable = require("material-react-table");
var _react = require("react");
var _Box = require("../Box.cjs");
var _MenuButton = require("../Buttons/MenuButton.cjs");
var _MenuItem = require("../Buttons/MenuItem.cjs");
var _i18n = require("../i18n.generated/i18n.cjs");
var _index = require("../icons.generated/index.cjs");
var _OdysseyDesignTokensContext = require("../OdysseyDesignTokensContext.cjs");
var _DataFilters = require("./DataFilters.cjs");
var _DataTablePagination = require("./DataTablePagination.cjs");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/*!
 * Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
 * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
 *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 */

const densityValues = exports.densityValues = ["comfortable", "spacious", "compact"];
const reorderDataRowsLocally = ({
  currentData,
  rowId,
  newIndex
}) => {
  const updatedData = [...currentData];
  const rowIndex = updatedData.findIndex(row => row.id === rowId);
  if (rowIndex !== -1) {
    const [removedRow] = updatedData.splice(rowIndex, 1);
    updatedData.splice(newIndex, 0, removedRow);
  }
  return updatedData;
};
const DataTable = ({
  columns,
  data: dataProp,
  getRowId,
  page: pageProp = 1,
  initialDensity = densityValues[0],
  resultsPerPage: resultsPerPageProp = 20,
  fetchDataFn,
  reorderDataFn,
  totalRows,
  hasSearchSubmitButton,
  searchDelayTime,
  paginationType = "paged",
  onRowSelectionChange,
  rowActionButtons,
  rowActionMenuItems,
  hasChangeableDensity,
  hasColumnResizing,
  hasColumnVisibility,
  hasFilters,
  hasPagination,
  hasRowReordering,
  hasRowSelection,
  hasSearch,
  hasSorting
}) => {
  const odysseyDesignTokens = (0, _OdysseyDesignTokensContext.useOdysseyDesignTokens)();
  const {
    t
  } = (0, _i18n.useTranslation)();
  const [draggingRow, setDraggingRow] = (0, _react.useState)();
  const [showSkeletons, setShowSkeletons] = (0, _react.useState)(true);
  const [data, setData] = (0, _react.useState)(dataProp);
  const [page, setPage] = (0, _react.useState)(pageProp);
  const [resultsPerPage, setResultsPerPage] = (0, _react.useState)(resultsPerPageProp);
  const [rowSelection, setRowSelection] = (0, _react.useState)({});
  const [sorting, setSorting] = (0, _react.useState)([]);
  const [density, setDensity] = (0, _react.useState)(initialDensity);
  const initialColumnVisibility = (0, _react.useMemo)(() => {
    return columns.reduce((acc, column) => {
      acc[column.accessorKey] = true;
      return acc;
    }, {});
  }, [columns]);
  const [columnVisibility, setColumnVisibility] = (0, _react.useState)(initialColumnVisibility);
  const [globalFilter, setGlobalFilter] = (0, _react.useState)("");
  const [filters, setFilters] = (0, _react.useState)();
  (0, _react.useEffect)(() => {
    setShowSkeletons(false);
  }, [data]);
  (0, _react.useEffect)(() => {
    onRowSelectionChange?.(rowSelection);
  }, [rowSelection, onRowSelectionChange]);
  const refreshData = (0, _react.useCallback)(async () => {
    setShowSkeletons(true);
    try {
      const newData = fetchDataFn({
        page: page,
        resultsPerPage: resultsPerPage,
        sort: sorting,
        search: globalFilter,
        filters: filters
      });
      setData(newData instanceof Promise ? await newData : newData);
      setShowSkeletons(false);
    } catch (error) {
      console.error(error);
      setShowSkeletons(false);
    }
  }, [page, resultsPerPage, sorting, globalFilter, filters, fetchDataFn]);
  (0, _react.useEffect)(() => {
    refreshData();
  }, [refreshData, page, resultsPerPage, sorting, globalFilter, filters]);
  const handleSortingChange = (0, _react.useCallback)(updater => {
    setSorting(prevSorting => updater instanceof Function ? updater(prevSorting) : sorting);
  }, [sorting]);
  const handleColumnVisibility = (0, _react.useCallback)(columnId => {
    setColumnVisibility(prevVisibility => ({
      ...prevVisibility,
      [columnId]: !columnVisibility[columnId]
    }));
  }, [columnVisibility]);
  const handleSearch = (0, _react.useCallback)(value => {
    setGlobalFilter(value);
  }, []);
  const handleFilters = (0, _react.useCallback)(updatedFilters => {
    setFilters(updatedFilters);
  }, []);
  const handleRowSelectionChange = (0, _react.useCallback)(updater => {
    setRowSelection(prevRowSelection => updater instanceof Function ? updater(prevRowSelection) : rowSelection);
  }, [rowSelection]);
  const updateRowOrder = (0, _react.useCallback)(({
    rowId,
    newIndex
  }) => {
    if (newIndex < 0) {
      return;
    }
    if (totalRows && newIndex > totalRows) {
      return;
    }
    const newData = reorderDataRowsLocally({
      currentData: data,
      rowId,
      newIndex
    });
    setData(newData);
    reorderDataFn?.({
      rowId,
      newIndex
    });
    refreshData();
  }, [data, totalRows, reorderDataFn, refreshData]);
  const rowVirtualizerInstanceRef = (0, _react.useRef)(null);
  const setHoveredRow = (0, _react.useCallback)((table, id) => {
    if (id) {
      const nextRow = table.getRow(id);
      if (nextRow) {
        table.setHoveredRow(nextRow);
      }
    }
  }, []);
  const resetDraggingAndHoveredRow = (0, _react.useCallback)(table => {
    setDraggingRow(null);
    table.setHoveredRow(null);
  }, [setDraggingRow]);
  const handleDragHandleKeyDown = (0, _react.useCallback)(({
    table,
    row,
    event
  }) => {
    const {
      hoveredRow
    } = table.getState();
    const {
      key
    } = event;
    const isSpaceKey = key === " ";
    const isEnterKey = key === "Enter";
    const isEscapeKey = key === "Escape";
    const isArrowDown = key === "ArrowDown";
    const isArrowUp = key === "ArrowUp";
    const isSpaceOrEnter = isSpaceKey || isEnterKey;
    const zeroIndexedPageNumber = page - 1;
    const currentIndex = row.index + zeroIndexedPageNumber * resultsPerPage;
    if (isEscapeKey) {
      resetDraggingAndHoveredRow(table);
      return;
    }
    if (isSpaceOrEnter) {
      event.preventDefault();
      event.stopPropagation();
    }
    if (draggingRow) {
      if (typeof hoveredRow?.index === "number") {
        const {
          index
        } = hoveredRow;
        if (isSpaceOrEnter) {
          const pageRelativeIndex = index + zeroIndexedPageNumber * resultsPerPage;
          if (pageRelativeIndex !== currentIndex) {
            updateRowOrder({
              rowId: row.id,
              newIndex: pageRelativeIndex
            });
            setTimeout(() => {
              resetDraggingAndHoveredRow(table);
            }, odysseyDesignTokens.TransitionDurationMainAsNumber);
            return;
          }
        }
        if (isArrowDown || isArrowUp) {
          const nextIndex = isArrowDown ? index + 1 : index - 1;
          setHoveredRow(table, data[nextIndex]?.id);
        }
      } else {
        if (isArrowDown || isArrowUp) {
          const nextIndex = isArrowDown ? row.index + 1 : row.index - 1;
          setHoveredRow(table, data[nextIndex]?.id);
        }
      }
    } else {
      if (isSpaceOrEnter) {
        setDraggingRow(row);
      }
    }
  }, [data, draggingRow, odysseyDesignTokens.TransitionDurationMainAsNumber, page, resetDraggingAndHoveredRow, resultsPerPage, setHoveredRow, updateRowOrder]);
  const handleDragHandleOnDragEnd = (0, _react.useCallback)(table => {
    const cols = table.getAllColumns();
    cols[0].toggleVisibility();
    const {
      draggingRow,
      hoveredRow
    } = table.getState();
    if (draggingRow) {
      updateRowOrder({
        newIndex: hoveredRow.index,
        rowId: draggingRow.id
      });
    }
    setDraggingRow(null);
  }, [updateRowOrder]);
  const handleDragHandleOnDragCapture = (0, _react.useCallback)(table => {
    if (!draggingRow && table.getState().draggingRow?.id) {
      setDraggingRow(table.getState().draggingRow);
    }
  }, [draggingRow]);
  const tableState = (0, _react.useMemo)(() => ({
    density,
    sorting,
    globalFilter,
    columnVisibility,
    rowSelection,
    showSkeletons
  }), [density, sorting, globalFilter, columnVisibility, rowSelection, showSkeletons]);
  const table = (0, _materialReactTable.useMaterialReactTable)({
    columns: columns,
    data: data,
    state: tableState,
    rowVirtualizerInstanceRef: rowVirtualizerInstanceRef,
    rowVirtualizerOptions: {
      overscan: 4
    },
    enableRowVirtualization: paginationType === "loadMore" || resultsPerPage > 50,
    enableColumnResizing: hasColumnResizing,
    enableDensityToggle: false,
    enableFullScreenToggle: false,
    enablePagination: false,
    enableRowSelection: hasRowSelection,
    enableFilters: false,
    enableHiding: false,
    enableRowOrdering: hasRowReordering,
    enableRowDragging: hasRowReordering,
    enableSorting: hasSorting,
    selectAllMode: "all",
    enableColumnActions: false,
    layoutMode: "grid-no-grow",
    displayColumnDefOptions: {
      "mrt-row-actions": {
        muiTableBodyCellProps: {
          align: "right",
          sx: {
            overflow: "visible",
            width: "unset"
          }
        },
        muiTableHeadCellProps: {
          align: "right",
          sx: {
            width: "unset"
          }
        }
      },
      "mrt-row-drag": {
        header: "",
        muiTableBodyCellProps: {
          sx: {
            minWidth: 0,
            width: "auto"
          }
        },
        muiTableHeadCellProps: {
          sx: {
            minWidth: 0,
            width: "auto"
          }
        }
      }
    },
    enableGlobalFilter: false,
    manualFiltering: true,
    manualSorting: true,
    getRowId: getRowId,
    icons: {
      ArrowDownwardIcon: _index.ArrowDownIcon,
      DragHandleIcon: _index.DragIndicatorIcon,
      SyncAltIcon: _index.ArrowUnsortedIcon
    },
    onSortingChange: handleSortingChange,
    onRowSelectionChange: handleRowSelectionChange,
    enableRowActions: hasRowReordering === true || rowActionButtons || rowActionMenuItems ? true : false,
    positionActionsColumn: "last",
    muiTableHeadCellProps: ({
      column
    }) => ({
      className: sorting.find(item => item.id === column.id) ? "isSorted" : "isUnsorted"
    }),
    muiTableBodyRowProps: ({
      table,
      row
    }) => ({
      className: draggingRow?.id === row.id && table.getState().hoveredRow?.id !== row.id ? "isDragging" : table.getState().hoveredRow?.id === row.id && draggingRow?.id !== row.id ? "isDragTarget" : draggingRow?.id === row.id && table.getState().hoveredRow?.id === row.id ? "isDragging isDragTarget" : undefined
    }),
    muiRowDragHandleProps: ({
      table,
      row
    }) => ({
      title: t("table.draghandle.tooltip"),
      "aria-label": t("table.draghandle.arialabel"),
      onKeyDown: event => handleDragHandleKeyDown({
        table,
        row,
        event
      }),
      onBlur: () => {
        resetDraggingAndHoveredRow(table);
      },
      onDragEnd: () => handleDragHandleOnDragEnd(table),
      onDragCapture: () => handleDragHandleOnDragCapture(table),
      sx: {
        padding: odysseyDesignTokens.Spacing1,
        borderRadius: odysseyDesignTokens.BorderRadiusMain,
        "&:focus-visible": {
          boxShadow: `0 0 0 2px ${odysseyDesignTokens.HueNeutralWhite}, 0 0 0 4px ${odysseyDesignTokens.PalettePrimaryMain}`,
          outline: "2px solid transparent",
          outlineOffset: "1px"
        }
      }
    }),
    renderRowActions: ({
      row
    }) => {
      const currentIndex = row.index + (page - 1) * resultsPerPage;
      return (0, _jsxRuntime.jsxs)(_Box.Box, {
        sx: {
          display: "flex"
        },
        children: [rowActionButtons?.(row.original), (rowActionMenuItems || hasRowReordering) && (0, _jsxRuntime.jsxs)(_MenuButton.MenuButton, {
          ariaLabel: t("table.moreactions.arialabel"),
          buttonVariant: "floating",
          endIcon: (0, _jsxRuntime.jsx)(_index.MoreIcon, {}),
          menuAlignment: "right",
          size: "small",
          children: [rowActionMenuItems && (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
            children: [rowActionMenuItems(row.original), (0, _jsxRuntime.jsx)("hr", {})]
          }), (0, _jsxRuntime.jsxs)(_MenuItem.MenuItem, {
            isDisabled: currentIndex <= 0,
            onClick: () => updateRowOrder({
              rowId: row.id,
              newIndex: 0
            }),
            children: [(0, _jsxRuntime.jsx)(_index.ArrowTopIcon, {}), " Bring to front"]
          }), (0, _jsxRuntime.jsxs)(_MenuItem.MenuItem, {
            isDisabled: currentIndex <= 0,
            onClick: () => updateRowOrder({
              rowId: row.id,
              newIndex: currentIndex <= 0 ? 0 : currentIndex - 1
            }),
            children: [(0, _jsxRuntime.jsx)(_index.ArrowUpIcon, {}), " Bring forward"]
          }), (0, _jsxRuntime.jsxs)(_MenuItem.MenuItem, {
            isDisabled: totalRows ? currentIndex >= totalRows - 1 : false,
            onClick: () => updateRowOrder({
              rowId: row.id,
              newIndex: currentIndex + 1
            }),
            children: [(0, _jsxRuntime.jsx)(_index.ArrowDownIcon, {}), " Send backward"]
          }), (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
            children: totalRows && (0, _jsxRuntime.jsxs)(_MenuItem.MenuItem, {
              isDisabled: currentIndex >= totalRows - 1,
              onClick: () => updateRowOrder({
                rowId: row.id,
                newIndex: totalRows
              }),
              children: [(0, _jsxRuntime.jsx)(_index.ArrowBottomIcon, {}), " Send to back"]
            })
          })]
        })]
      });
    }
  });
  const tableSettings = (0, _react.useMemo)(() => (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
    children: [hasChangeableDensity && (0, _jsxRuntime.jsx)(_MenuButton.MenuButton, {
      ariaLabel: "Table density",
      endIcon: (0, _jsxRuntime.jsx)(_index.ListIcon, {}),
      menuAlignment: "right",
      shouldCloseOnSelect: false,
      children: (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
        children: densityValues.map(value => (0, _jsxRuntime.jsx)(_MenuItem.MenuItem, {
          isSelected: density === value,
          onClick: () => setDensity(value),
          children: `${value.charAt(0).toUpperCase()}${value.slice(1)}`
        }, value))
      })
    }), hasColumnVisibility && (0, _jsxRuntime.jsx)(_MenuButton.MenuButton, {
      ariaLabel: "Show/hide columns",
      endIcon: (0, _jsxRuntime.jsx)(_index.ShowIcon, {}),
      menuAlignment: "right",
      shouldCloseOnSelect: false,
      children: (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
        children: columns.filter(column => column.enableHiding !== false).map(column => (0, _jsxRuntime.jsxs)(_MenuItem.MenuItem, {
          onClick: () => handleColumnVisibility(column.accessorKey),
          children: [(0, _jsxRuntime.jsx)(_Checkbox2.default, {
            checked: columnVisibility[column.accessorKey] !== false
          }), column.header]
        }, column.accessorKey))
      })
    })]
  }), [columnVisibility, columns, density, hasChangeableDensity, handleColumnVisibility, hasColumnVisibility]);
  return (0, _jsxRuntime.jsxs)(_Box.Box, {
    sx: {
      display: "flex",
      flexDirection: "column",
      gap: 4
    },
    children: [(0, _jsxRuntime.jsx)(_DataFilters.DataFilters, {
      additionalActions: tableSettings,
      filters: hasFilters ? columns.filter(column => column.enableColumnFilter !== false).map(column => {
        return {
          id: column.accessorKey,
          label: column.header,
          variant: column.filterVariant ?? "text",
          options: column.filterSelectOptions
        };
      }) : undefined,
      hasSearchSubmitButton: hasSearchSubmitButton,
      onChangeFilters: handleFilters,
      onChangeSearch: hasSearch ? handleSearch : undefined,
      searchDelayTime: searchDelayTime
    }), (0, _jsxRuntime.jsx)(_materialReactTable.MRT_TableContainer, {
      table: table
    }), hasPagination && (0, _jsxRuntime.jsx)(_DataTablePagination.DataTablePagination, {
      currentNumberOfResults: data.length,
      currentPage: page,
      isNextButtonDisabled: false,
      isPreviousButtonDisabled: page <= 1,
      onClickNext: () => {
        if (paginationType === "loadMore") {
          setResultsPerPage(resultsPerPage + resultsPerPageProp);
        } else {
          setPage(page + 1);
        }
      },
      onClickPrevious: () => setPage(page - 1),
      paginationType: paginationType
    })]
  });
};
const MemoizedDataTable = exports.DataTable = (0, _react.memo)(DataTable);
MemoizedDataTable.displayName = "DataTable";
//# sourceMappingURL=DataTable.cjs.map