Untitled

 avatar
unknown
javascript
10 days ago
15 kB
6
Indexable
/**
 * App.js Layout Start Here
 */
import { CompositeFilterDescriptor, orderBy, SortDescriptor } from "@progress/kendo-data-query";
import { filter } from "@progress/kendo-data-query/dist/npm/transducers";
import { getter } from "@progress/kendo-react-common";
import {
  getSelectedState,
  Grid,
  GridColumn,
  GridNoRecords,
  GridSortChangeEvent,
} from "@progress/kendo-react-grid";
import moment from "moment";
import React, { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router";
import Loading from "../../control-components/loader/loader";
import apiHelper from "../../helper/api-helper";
import { showError } from "../../util/utility";
import { displayDateFromUtcDate } from "../../util/utility.js";
import EditedHistory from "./view-edited-history";
import { API_ENDPOINTS } from "src/services/api-endpoints";

// Const Vars
const DATA_ITEM_KEY = "id";
const SELECTED_FIELD = "selected";
export const ACTION_ID = {
  submitted: 1,
  edited: 2,
  trashed: 3,
  locked: 4,
  unLocked: 5,
  signed: 6,
  signatureRemoved: 7,
  printed: 8,
  sealed: 9,
  restored: 10,
  rating: 11,
  linked: 13,
  linkedDeleted: 14,
  docApproved: 15,
  docDisApproved: 16,
  postEditReview: 17,
  linkedQuestionnaire: 18,
  questionnaireRemoved: 19,
  documentSignByClient: 20,
  documentSignByParent: 21,
  billingStatusUpdated: 22,
  billingCommentAdded: 23,
  billingCommentUpdated: 24,
  serviceSupervisorAssigned: 26,
  serviceUpdated: 27,
  posUpdated: 28,
  dxUpdated: 29,
  serviceSiteUpdated: 30,
  serviceDateUpdated: 31,
  unitsReturned: 33,
  unitsRestored: 34,
  payrollStatusUpdated: 35,
};

const idGetter = getter(DATA_ITEM_KEY);
const filterOperators = {
  text: [
    {
      text: "grid.filterContainsOperator",
      operator: "contains",
    },
  ],
};

const DocumentHistoryList = () => {
  // States
  const [loading, setLoading] = useState(false);
  const [sort, setSort] = useState<SortDescriptor[]>([]);
  const [page, setPage] = useState(0);
  const [pageSize, setPageSize] = useState(10);
  const [selectedState, setSelectedState] = useState({});
  const [historyList, setHistoryList] = useState<any[]>([]);
  const location = useLocation();
  const navigate = useNavigate();
  const [showDocHistoryChanges, setShowDocHistoryChanges] = useState(false);
  const [state, setState] = React.useState({
    oldVersion: null,
    latestVersion: null,
    documentId: null,
    documentName: null,
    documentTemplateId: null
  });

  /* ============================= useEffect functions ============================= */

  useEffect(() => {
    getDocumentHistory();
  }, []);

  /* ============================= useCallbacks ============================= */

  const onSelectionChange = React.useCallback(
    (event) => {
      const newSelectedState = getSelectedState({
        event,
        selectedState: selectedState,
        dataItemKey: DATA_ITEM_KEY,
      });
      setSelectedState(newSelectedState);
    },
    [selectedState]
  );

  const onHeaderSelectionChange = React.useCallback((event) => {
    const checkboxElement = event.syntheticEvent.target;
    const checked = checkboxElement.checked;
    const newSelectedState = {};
    event.dataItems.forEach((item) => {
      newSelectedState[idGetter(item)] = checked;
    });
    setSelectedState(newSelectedState);
  }, []);

  /* ============================= private functions ============================= */

  function getDocumentHistory() {
    setLoading(true);
    apiHelper
      .queryGetRequestWithEncryption(
        API_ENDPOINTS.DOCUMENT_HISTORY,
        location.state?.id
      )
      .then((result) => {
        setHistoryList(result.resultData);
      })
      .catch((err) => {
        showError(err, "History Document");
      })
      .finally(() => {
        setLoading(false);
      });
  }

  function getClassName(actionId) {
    switch (actionId) {
      case ACTION_ID.submitted:
        return "fa fa-notes-medical fa-lg";
      case ACTION_ID.edited:
        return "fa fa-edit fa-lg";
      case ACTION_ID.trashed:
        return "d-flex fa fa-trash fa-lg";
      case ACTION_ID.locked:
        return "d-inline-flex fa fa-lock fa-lg";
      case ACTION_ID.unLocked:
        return "fa fa-unlock fa-lg";
      case ACTION_ID.signed:
        return "fa fa-signature fa-lg";
      case ACTION_ID.signatureRemoved:
        return "fa fa-signature fa-lg";
      case ACTION_ID.restored:
        return "fa fa-rotate-left pr-2";
      case ACTION_ID.rating:
        return "fa fa-star pr-2";
      case ACTION_ID.printed:
        return "fa fa-print pr-2";
      case ACTION_ID.linked:
        return "fa fa-link pr-2";
      case ACTION_ID.sealed:
        return "fa-solid fa-stamp pr-2";
      case ACTION_ID.linkedDeleted:
        return "d-flex fa fa-trash fa-lg";
      case ACTION_ID.docApproved:
        return "fa fa-check-square fa-lg";
      case ACTION_ID.docDisApproved:
        return "fa fa-ban fa-lg";
      case ACTION_ID.postEditReview:
        return "fa-solid fa-file-pen fa-lg ";
      case ACTION_ID.linkedQuestionnaire:
        return "fa fa-file-text fa-lg";
      case ACTION_ID.questionnaireRemoved:
        return "d-flex fa fa-trash fa-lg";
      case ACTION_ID.documentSignByClient:
        return "fa fa-signature fa-lg";
      case ACTION_ID.documentSignByParent:
        return "fa fa-signature fa-lg";
      case ACTION_ID.billingStatusUpdated:
        return "fa fa-usd fa-lg";
      case ACTION_ID.billingCommentAdded:
        return "fa fa-comment fa-lg";
      case ACTION_ID.billingCommentUpdated:
        return "fa fa-comments fa-lg";
      case ACTION_ID.serviceSupervisorAssigned:
        return "fa fa-exchange fa-lg"
      case ACTION_ID.serviceUpdated:
        return "fa fa-edit fa-lg";
      case ACTION_ID.posUpdated:
        return "fa fa-edit fa-lg";
      case ACTION_ID.dxUpdated:
        return "fa fa-diagnoses fa-lg";
      case ACTION_ID.serviceSiteUpdated:
        return "fa fa-globe fa-lg";
      case ACTION_ID.serviceDateUpdated:
        return "fa fa-calendar fa-lg";
      case ACTION_ID.unitsReturned:
        return "fa fa-circle-xmark fa-lg";
      case ACTION_ID.unitsRestored:
        return "fa fa-rotate-left fa-lg";
      case ACTION_ID.payrollStatusUpdated:
        return "fas fa-receipt fa-lg";
    }

    return "";
  }

  /* ============================= event functions ============================= */

  function onActionClick(action) {
    if (action.actionId == ACTION_ID.edited || action.actionId == ACTION_ID.posUpdated) {
      setState({
        ...state,
        oldVersion: JSON.parse(action.oldVersion),
        latestVersion: JSON.parse(action.latestVersion),
        documentId: location.state?.id,
        documentName: location.state?.documentName,
        documentTemplateId: action.documentTemplateId,
      });
      setShowDocHistoryChanges(true);
    }
  }

  function onBack() {
    // navigate(APP_ROUTES.DOCUMENT_LIST);
    navigate(-1);
  }

  function onPageChange(event) {
    let skip = event.page.skip;
    let take = event.page.take;
    setPage(skip);
    setPageSize(take);
  }

  function onDataStateChange(event) {
    setPage(event.dataState.skip);
    setPageSize(event.dataState.take);
    setSort(event.dataState.sort);
  }
  const handleClose = () => {
    setShowDocHistoryChanges(false);
  };
  return (
    <div className="grid-table filter-grid cursor-default blueThemeTable">
      <button
        type="button"
        value="BACK"
        onClick={onBack}
        className="border-0 bg-transparent arrow-rotate mb-3 history-title m-0 p-0 d-flex align-items-center"
      >
        <i className="fa-solid fa-arrow-left mr-2"></i>
        Document History
      </button>
      <div className="list-unstyled pl-0 details-info ms-4 row mb-3">
        <div className="col-md-4 d-flex">
          <p className=" mb-0  px-0 f-16 fw-600">Client:</p>
          <p className=" mb-0  px-0 f-14 ml-2">
            {location.state?.documentName.clientNameDoc}
          </p>
        </div>
        <div className="col-md-4 d-flex justify-content-center md-justify-content-start">
          <p className=" mb-0  px-0 f-16 fw-600">Service Date:</p>
          <p className=" mb-0  px-0 f-14 ml-2">
            {moment(location.state?.documentName.serviceDateStr).format(
              "M/D/YYYY"
            )}
          </p>
        </div>
        <div className="col-md-4 d-flex justify-content-end md-justify-content-start">
          <p className=" mb-0  px-0 f-16 fw-600">Doc Status:</p>
          <p className=" mb-0  px-0 f-14 ml-2">
            {location.state?.documentName?.docStatus}
          </p>
        </div>
      </div>
      <Grid
        data={orderBy(historyList.slice(page, pageSize + page), sort).map(
          (item) => ({
            ...item,
            [SELECTED_FIELD]: selectedState[idGetter(item)],
          })
        )}
        style={{
          height: historyList.length > 0 ? "100%" : "250px",
        }}
        dataItemKey={DATA_ITEM_KEY}
        skip={page}
        take={pageSize}
        total={historyList.length}
        onPageChange={onPageChange}
        sort={sort}
        sortable={true}
        onSortChange={(e: GridSortChangeEvent) => {
          setSort(e?.sort);
        }}
        // filter={filter}

        filterOperators={filterOperators}
        onDataStateChange={onDataStateChange}
        onSelectionChange={onSelectionChange}
        onHeaderSelectionChange={onHeaderSelectionChange}
        className="pagination-row-cus"
        pageable={{
          pageSizes: [10, 20, 30],
        }}
      >
        <GridNoRecords>
          {loading ? <Loading /> : "No data found"}
        </GridNoRecords>

        <GridColumn
          title=""
          width={150}
          className="w-5 cursor-default"
          cell={(props) => {
            let actionId = props.dataItem.actionId;
            return (
              <td className="cursor-default">
                <i className={getClassName(actionId)} />
              </td>
            );
          }}
        />

        <GridColumn
          className="w-20 cursor-default"
          title="Action"
          width={300}
          cell={(props) => {
            const action = props.dataItem;

            return <td className="w-20 cursor-default">{action.actionName.trim()}</td>;
          }}
        />

        <GridColumn
          width={250}
          title="By"
          className="cursor-default"
          cell={(props) => {
            const updatedByStr = props.dataItem.editedByParentName ? props.dataItem.editedByParentName + ' (Parent/Guardian)' :
              props.dataItem.editedByClientName ? props.dataItem.editedByClientName + ' (Client)' :
                props.dataItem.staffName + ''
            return <td className="cursor-default">{updatedByStr}</td>;
          }}
        />

        <GridColumn
          title="Date"
          className="cursor-default"
          width={200}
          cell={(props) => {
            let field = moment
              .utc(props.dataItem.utcDateCreated)
              .local()
              .format("M/D/YYYY");
            return <td className="cursor-default">{field}</td>;
          }}
        />
        <GridColumn
          title="Time"
          width={200}
          cell={(props) => {
            let field = moment
              .utc(props.dataItem.utcDateCreated)
              .local()
              .format("hh:mm A");
            return <td className="cursor-default">{field}</td>;
          }}
        />
        <GridColumn
          title="Additional Info"
          cell={(props) => {
            const action = props.dataItem;
            let oldVersion = props.dataItem.oldVersion;
            let actionId = props.dataItem.actionId;
            let parsedInfo = JSON.parse(oldVersion)
            if (action.actionId == ACTION_ID.edited || action.actionId == ACTION_ID.posUpdated) {
              return (<td className="text-theme w-20" onClick={() => onActionClick(action)}>View</td>);
            }
            else if (action.actionId === ACTION_ID.signed || action.actionId === ACTION_ID.documentSignByClient || action.actionId === ACTION_ID.documentSignByParent) {
              var imgUrl = 'data:image/jpeg;base64,' + action.signature;
              return (<td><img src={imgUrl} style={{ height: "75px", width: "200px" }} /></td>)
            }
            else {
              return (<td style={{ cursor: "pointer" }}>
                {
                  actionId == ACTION_ID.billingStatusUpdated &&
                  <>
                    {"Changed from " + parsedInfo?.oldBillingStatus + " to " + parsedInfo?.newBillingStatus}
                  </>

                }
                {
                  actionId == ACTION_ID.serviceUpdated &&
                  <>
                    {"Changed from " + parsedInfo?.oldServiceName + " to " + parsedInfo?.newServiceName}
                  </>
                }
                {
                  actionId == ACTION_ID.dxUpdated &&
                  <>
                    {"Changed from " + parsedInfo?.oldDxName + " to " + parsedInfo?.newDxName}
                  </>
                }
                {
                  actionId == ACTION_ID.serviceSiteUpdated &&
                  <>
                    {"Changed from " + parsedInfo?.oldServiceSiteName + " to " + parsedInfo?.newServiceSiteName}
                  </>
                }
                {
                  actionId == ACTION_ID.serviceDateUpdated &&
                  <>
                    {"Changed from " + parsedInfo?.oldServiceDate + " to " + parsedInfo?.newServiceDate}
                  </>
                }
                {
                  actionId == ACTION_ID.payrollStatusUpdated &&
                  <>
                    {"Changed from " + parsedInfo?.oldPayrollStatus + " to " + parsedInfo?.newPayrollStatus}
                  </>
                }
              </td>);
            }
          }} />
      </Grid>
      {showDocHistoryChanges && (
        <EditedHistory
          onClose={handleClose}
          stateData={state}
        />
      )}
    </div>

  );
};

export default DocumentHistoryList;
Editor is loading...
Leave a Comment