function ToggleAsset()

in dialogflow-cx/vpc-sc-demo/frontend/src/AssetPollToggle.js [528:773]


function ToggleAsset(props) {
  const asset = props.dataModel.assetStatus[props.target];
  const [errorBoxOpen, setErrorBoxOpen] = React.useState(false);
  const [resourceName, setResourceName] = React.useState(null);

  const handleErrorBoxCancel = () => {
    setErrorBoxOpen(false);
  };

  function onSettled() {
    props.dataModel.terraformLocked.set(false);
    props.dataModel.invertAssetCollectionSwitches.set(false);
  }

  function queryFunction() {
    let destroy = asset.current === true ? true : false;
    props.dataModel.validAccessPolicy.set(true);
    if (
      props.isModuleSwitch &&
      props.dataModel.invertAssetCollectionSwitches.current &&
      !ResourceCollectionIsAllSame(props.target, props.dataModel)
    ) {
      destroy = !destroy;
    }

    let target;
    if (props.target === 'module.services' && destroy) {
      target = [
        props.target,
        'google_project_service.dialogflow',
        'google_project_service.cloudfunctions',
        'google_project_service.compute',
        'google_project_service.servicedirectory',
        'google_project_service.cloudbuild',
        'google_project_service.accesscontextmanager',
        'google_project_service.cloudbilling',
        'google_project_service.iam',
      ];
    } else if (props.target === 'module.service_directory') {
      target = [
        props.target,
        'module.service_perimeter.google_access_context_manager_service_perimeter.service_perimeter[0]',
      ];
    } else if (props.target === 'module.webhook_agent' && destroy) {
      target = [props.target, 'google_storage_bucket.bucket'];
    } else {
      target = [props.target];
    }

    props.dataModel.terraformLocked.set(true);
    return axios
      .post(
        '/update_target',
        {
          targets: target,
          destroy: destroy,
        },
        {
          params: {
            project_id: props.dataModel.projectData.project_id.current,
            bucket: getBucket(props.dataModel),
            region: props.dataModel.projectData.region.current,
            access_policy_title:
              props.dataModel.projectData.accessPolicyTitle.current,
            debug: false,
          },
        }
      )
      .then(res => res.data);
  }

  function onError() {
    setErrorBoxOpen(true);
  }

  function importFunction() {
    props.dataModel.terraformLocked.set(true);
    return axios
      .post(
        '/import',
        {
          resourceName: resourceName,
        },
        {
          params: {
            project_id: props.dataModel.projectData.project_id.current,
            bucket: getBucket(props.dataModel),
            access_policy_title:
              props.dataModel.projectData.accessPolicyTitle.current,
            region: props.dataModel.projectData.region.current,
            target: props.target,
          },
        }
      )
      .then(res => res.data);
  }

  function onSuccess(data) {
    props.dataModel.validAccessPolicy.set(true);
    props.dataModel.validProjectId.set(true);
    props.dataModel.projectIdColor.set('primary');
    if (data.status === 'BLOCKED') {
      if (
        (data.reason === 'TOKEN_EXPIRED') &
        props.dataModel.loggedIn.current &
        !props.dataModel.sessionExpiredModalOpen.current
      ) {
        handleTokenExpired(props.dataModel);
      }
    } else {
      for (const key in props.dataModel.assetStatus) {
        props.dataModel.assetStatus[key].set(data.resources.includes(key));
      }
    }
  }

  const update = useQuery('/update_target', queryFunction, {
    enabled: false,
    onSettled: onSettled,
    retry: 0,
    onError: onError,
    onSuccess: onSuccess,
  });

  function onImportSuccess() {
    update.refetch();
  }

  const tfImport = useQuery(['/import'], importFunction, {
    enabled: false,
    onSettled: onSettled,
    retry: 0,
    onSuccess: onImportSuccess,
  });

  const handleErrorBoxImport = () => {
    setErrorBoxOpen(false);
    tfImport.refetch();
  };

  function onChange() {
    update.refetch();
  }

  let visibility;
  if (
    !props.dataModel.validProjectId.current ||
    !props.dataModel.validAccessPolicy.current ||
    update.isFetching ||
    tfImport.isFetching ||
    typeof asset.current !== 'boolean' ||
    props.dataModel.terraformLocked.current ||
    asset.current === 'BLOCKED'
  ) {
    visibility = 'hidden';
  } else {
    visibility = 'visible';
  }

  if (
    (props.target ===
      'module.service_perimeter.google_access_context_manager_service_perimeter.service_perimeter[0]') &
    (props.dataModel.projectData.accessPolicyTitle.current === null ||
      typeof props.dataModel.projectData.accessPolicyTitle.current ===
        'undefined' ||
      props.dataModel.projectData.accessPolicyTitle.current === '')
  ) {
    visibility = 'hidden';
  }

  let checked = typeof asset.current === 'boolean' ? asset.current : false;
  if (
    props.isModuleSwitch &&
    props.dataModel.invertAssetCollectionSwitches.current &&
    !ResourceCollectionIsAllSame(props.target, props.dataModel)
  ) {
    checked = !checked;
  }
  const indicator = (
    <Switch
      onChange={onChange}
      checked={checked}
      color="primary"
      style={{visibility: visibility}}
      size={props.target === 'all' ? 'medium' : 'small'}
    />
  );

  let name;
  if (
    props.dataModel &&
    props.dataModel.projectData.project_id.current !== null &&
    props.dataModel.assetStatus[props.target].current === true
  ) {
    name = (
      <Link target="_blank" href={props.href} variant="body1">
        {props.name}
      </Link>
    );
  } else {
    name = <Typography variant="body2">{props.name}</Typography>;
  }

  const nameBox = (
    <Box
      sx={{pl: 1, mx: 0, my: 0.5, py: 1, width: PANEL_WIDTH, height: 30}}
      display="flex"
      alignItems="center"
      justifyContent="right"
    >
      {name}
    </Box>
  );

  return (
    <>
      <ErrorDialog
        open={errorBoxOpen}
        onClickCancel={handleErrorBoxCancel}
        onClickImport={handleErrorBoxImport}
        target={props.target}
        setResourceName={setResourceName}
        error={update.error}
        dataModel={props.dataModel}
      />
      <Grid
        container
        item
        direction="row"
        columnSpacing={3}
        justifyContent="flex-start"
        alignItems="center"
      >
        {props.includeNameBox ? <></> : nameBox}
        <Box
          sx={{width: 60, height: 30}}
          display="flex"
          alignItems="center"
          justifyContent="center"
        >
          {indicator}
        </Box>
      </Grid>
    </>
  );
}