Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
device.view.list.tsx 3.93 KiB
import { insertMarkTags } from "@helper/text";
import { useAppSelector } from "@hooks";
import DOMPurify from "dompurify";
import { RefObject, useCallback, useRef } from "react";
import { Col, OverlayTrigger, Row, Tooltip } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import { Device } from "../reducer/device.reducer";
import { useDeviceTableViewModel } from "../view_model/device.list.viewmodel";

const cropUUID = (uuid: string): string => {
  return (
    uuid.substring(0, 3) + "..." + uuid.substring(uuid.length - 3, uuid.length)
  );
};

export const DeviceList = ({
  searchRef,
}: {
  searchRef: RefObject<HTMLInputElement>;
}) => {
  const {
    devices,
    pnds,
    selected: selectedDevice,
  } = useAppSelector((state) => state.device);
  const { t } = useTranslation("common");
  const listRef = useRef<HTMLDivElement>(null);
  const { dispatchDevice } = useDeviceTableViewModel(searchRef, listRef);

  const handleItemClick = useCallback((device: Device) => {
    dispatchDevice(device);
  }, []);

  const getDeviceList = useCallback(() => {
    const search = searchRef?.current?.value;
    let filtered = devices;

    if (search) {
      filtered = devices.filter((device) => {
        const user = pnds.find((pnd) => pnd.id === device.pid);
        return (
          device.id?.includes(search) ||
          device.name?.includes(search) ||
          user?.name?.includes(search)
        );
      });
    }

    return filtered.map((device) => {
      const user = pnds.find((pnd) => pnd.id === device.pid);
      const username = user?.name || "";
      const deviceId = device.id!;
      const croppedId = cropUUID(deviceId);
      const devicename = device.name || "";
      const isSelected = selectedDevice?.device.id === deviceId;

      return (
        <div
          key={deviceId}
          className={`border-bottom border-primary p-2 transitions ${isSelected && "bg-gradient-fade py-2"} ${!isSelected && "text-disabled disabled-hover"}`}
          onClick={() => handleItemClick(device)}
        >
          <Row
            className="align-items-center clickable"
            onClick={() => handleItemClick(device)}
          >
            <Col xs={12} sm={5}>
              <span
                dangerouslySetInnerHTML={{
                  __html: search
                    ? insertMarkTags(devicename, search)
                    : DOMPurify.sanitize(devicename),
                }}
              />
            </Col>
            <Col xs={12} sm={3}>
              <OverlayTrigger
                overlay={<Tooltip id={deviceId}>{deviceId}</Tooltip>}
              >
                <span
                  className="text-gray-500"
                  dangerouslySetInnerHTML={{
                    __html: search
                      ? insertMarkTags(croppedId, search)
                      : DOMPurify.sanitize(croppedId),
                  }}
                />
              </OverlayTrigger>
            </Col>
            <Col xs={12} sm={4}>
              <span
                className="text-gray-500"
                dangerouslySetInnerHTML={{
                  __html: search
                    ? insertMarkTags(username, search)
                    : DOMPurify.sanitize(username),
                }}
              />
            </Col>
          </Row>
        </div>
      );
    });
  }, [devices, searchRef, pnds, selectedDevice, handleItemClick]);

  return (
    <div className="rounded border border-primary mt-2">
      <Row className="border-bottom border-primary px-2 py-2 mx-0">
        <Col xs={12} sm={5}>
          <span className="font-medium">{t("device.table.header.name")}</span>
        </Col>
        <Col xs={12} sm={3}>
          <span className="font-medium">{t("device.table.header.uuid")}</span>
        </Col>
        <Col xs={12} sm={4}>
          <span className="font-medium">{t("device.table.header.user")}</span>
        </Col>
      </Row>
      <div ref={listRef}>{getDeviceList()}</div>
    </div>
  );
};