Skip to content
Snippets Groups Projects
ChangeHostAdmin.js 6.06 KiB
Newer Older
import React, {
  useState,
  useEffect,
  useCallback,
  useMemo,
  useContext
} from "react";
import AccessControl from "../../auth/AccessControl";
import {
  SimpleAccordion,
  ConfirmationDialog,
  useAPIMethod
} from "@ess-ics/ce-ui-common";
import {
  Button,
  Typography,
  Grid,
  Tooltip,
  CircularProgress,
  Alert,
  Autocomplete
} from "@mui/material";
import { useTypingTimer } from "../../common/SearchBoxFilter/TypingTimer";
import { transformHostQuery } from "../../common/Helper";

export default function ChangeHostAdmin({
  ioc,
  getIOC,
  resetTab,
  buttonDisabled
}) {
  const initHost = useMemo(
    () => ({
      csEntryHost: {
        fqdn: ioc.activeDeployment.host.fqdn,
        id: ioc.activeDeployment.host.csEntryId
      }
    }),
    [ioc?.activeDeployment?.host]
  );
  const [host, setHost] = useState(initHost);

  const client = useContext(apiContext);

  const {
    value: hosts,
    wrapper: getHosts,
    loading: loadingHosts
  } = useAPIMethod({
    fcn: client.apis.Hosts.listHosts,
    call: false
  });

  const [query, onHostKeyUp] = useTypingTimer({ interval: 500 });

  const noModification = useCallback(
    () => !host || host.csEntryHost.id === ioc.activeDeployment.host.csEntryId,
    [host, ioc]
  );

  // for the dialog
  const [error, setError] = useState();
  const [open, setOpen] = useState(false);

  const {
    value: updatedIoc,
    wrapper: updateHost,
    error: updateHostError
  } = useAPIMethod({
    fcn: client.apis.IOCs.updateActiveDeploymentHost,
    call: false
  });

  useEffect(() => {
    if (updateHostError) {
      setError(updateHostError?.message);
    }
  }, [updateHostError, setError]);

  useEffect(() => {
    if (updatedIoc) {
      getIOC();
      resetTab();
    }
  }, [updatedIoc, getIOC, resetTab]);

  useEffect(() => {
    getHosts({ query: transformHostQuery(`${query}`) });
  }, [query, getHosts]);
  const onClose = useCallback(() => {
    setOpen(false);
    setHost(initHost);
  }, [setOpen, initHost]);
  const onConfirm = useCallback(() => {
    updateHost(
      {
        ioc_id: ioc.id
      },
      {
        requestBody: {
          hostCSEntryId: host.csEntryHost.id
        }
      }
    );
  }, [updateHost, ioc, host?.csEntryHost?.id]);

  let disabledButtonTitle = "";
  if (buttonDisabled || ioc.operationInProgress) {
    disabledButtonTitle =
      "There is an ongoing operation, you cannot 'undeploy' the IOC right now";
  } else {
    if (!ioc.activeDeployment) {
      disabledButtonTitle = "IOC has no active deployment";
    }
  }

  return (
    <>
      <AccessControl
        allowedRoles={["DeploymentToolAdmin"]}
        renderNoAccess={() => <></>}
      >
        <ConfirmationDialog
          title="Modifying deployment host"
          description={
            <>
              <Typography component="span">
                Are you sure want to modify deployment host of
                <Typography
                  component="span"
                  fontFamily="monospace"
                  {" "}
                  {ioc.namingName}
                </Typography>{" "}
                ?
              </Typography>
            </>
          }
          confirmText="Modify Host"
          cancelText="Cancel"
          open={open}
          onClose={onClose}
          onConfirm={onConfirm}
        />
        <SimpleAccordion
          summary="Change deployment host"
          defaultExpanded
        >
          <Grid
            container
            spacing={1}
          >
            {error ? (
                <Alert severity="error">{error}</Alert>
            ) : (
              <></>
            )}
            <Grid
              item
              xs={12}
            >
              <Autocomplete
                autoHighlight
                id="host"
                options={query ? hosts?.csEntryHosts ?? [] : []}
                loading={loadingHosts}
                clearOnBlur={false}
                value={host}
                getOptionLabel={(option) => {
                  return option?.csEntryHost?.fqdn ?? "";
                }}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    label="host"
                    variant="outlined"
                    required
                    InputProps={{
                      ...params.InputProps,
                      endAdornment: (
                        <React.Fragment>
                          {loadingHosts ? (
                            <CircularProgress
                              color="inherit"
                              size={20}
                            />
                          ) : null}
                          {params.InputProps.endAdornment}
                        </React.Fragment>
                      )
                    }}
                  />
                )}
                onChange={(event, value, reason) => {
                  setHost(value);
                }}
                onInputChange={(event, value, reason) => {
                  event && onHostKeyUp(event.nativeEvent);
                }}
                autoSelect
                filterOptions={(options, state) => options}
              />
            </Grid>
            <Grid
              item
              xs={12}
            >
              <Tooltip title={disabledButtonTitle}>
                <span>
                  <Button
                    color="primary"
                    variant="contained"
                    onClick={() => setOpen(true)}
                    disabled={
                      buttonDisabled ||
                      ioc.operationInProgress ||
                      !ioc.activeDeployment ||
                      noModification()
                    }
                  >
                    CHANGE HOST
                  </Button>
                </span>
              </Tooltip>
          </Grid>
        </SimpleAccordion>
      </AccessControl>
    </>
  );
}