export function RoleEdit()

in public/apps/configuration/panels/role-edit/role-edit.tsx [74:250]


export function RoleEdit(props: RoleEditDeps) {
  const [roleName, setRoleName] = React.useState('');
  const [roleClusterPermission, setRoleClusterPermission] = useState<ComboBoxOptions>([]);
  const [roleIndexPermission, setRoleIndexPermission] = useState<RoleIndexPermissionStateClass[]>(
    []
  );
  const [roleTenantPermission, setRoleTenantPermission] = useState<
    RoleTenantPermissionStateClass[]
  >([]);

  const [toasts, addToast, removeToast] = useToastState();

  const [isFormValid, setIsFormValid] = useState<boolean>(true);

  React.useEffect(() => {
    const action = props.action;
    if (action === 'edit' || action === 'duplicate') {
      const fetchData = async () => {
        try {
          const roleData = await getRoleDetail(props.coreStart.http, props.sourceRoleName);
          setRoleClusterPermission(roleData.cluster_permissions.map(stringToComboBoxOption));
          setRoleIndexPermission(buildIndexPermissionState(roleData.index_permissions));
          setRoleTenantPermission(buildTenantPermissionState(roleData.tenant_permissions));

          setRoleName(generateResourceName(action, props.sourceRoleName));
        } catch (e) {
          addToast(createUnknownErrorToast('fetchRole', 'load data'));
          console.error(e);
        }
      };

      fetchData();
    }
  }, [addToast, props.action, props.coreStart.http, props.sourceRoleName]);

  const [actionGroups, setActionGroups] = useState<string[]>([]);
  React.useEffect(() => {
    const fetchActionGroupNames = async () => {
      try {
        const actionGroupsObject = await fetchActionGroups(props.coreStart.http);
        setActionGroups(Object.keys(actionGroupsObject));
      } catch (e) {
        addToast(createUnknownErrorToast('actionGroup', 'load data'));
        console.error(e);
      }
    };

    fetchActionGroupNames();
  }, [addToast, props.coreStart.http]);

  const [tenantNames, setTenantNames] = React.useState<string[]>([]);
  React.useEffect(() => {
    const fetchTenantNames = async () => {
      try {
        setTenantNames(await fetchTenantNameList(props.coreStart.http));
      } catch (e) {
        addToast(createUnknownErrorToast('tenant', 'load data'));
        console.error(e);
      }
    };

    fetchTenantNames();
  }, [addToast, props.coreStart.http]);

  const updateRoleHandler = async () => {
    try {
      // Remove index/tenant permissions with empty patterns.
      const validIndexPermission = roleIndexPermission.filter(
        (v: RoleIndexPermissionStateClass) => !isEmpty(v.indexPatterns)
      );
      const validTenantPermission = roleTenantPermission.filter(
        (v: RoleTenantPermissionStateClass) => !isEmpty(v.tenantPatterns)
      );

      await updateRole(props.coreStart.http, roleName, {
        cluster_permissions: roleClusterPermission.map(comboBoxOptionToString),
        index_permissions: unbuildIndexPermissionState(validIndexPermission),
        tenant_permissions: unbuildTenantPermissionState(validTenantPermission),
      });

      setCrossPageToast(buildUrl(ResourceType.roles, Action.view, roleName), {
        id: 'updateRoleSucceeded',
        color: 'success',
        title: getSuccessToastMessage('Role', props.action, roleName),
      });
      // Redirect to role view
      window.location.href = buildHashUrl(ResourceType.roles, Action.view, roleName);
    } catch (e) {
      addToast(createUnknownErrorToast('updateRole', `${props.action} role`));
      console.error(e);
    }
  };

  const clusterWisePermissionOptions = [
    {
      label: 'Permission groups',
      options: actionGroups.map(stringToComboBoxOption),
    },
    {
      label: 'Cluster permissions',
      options: CLUSTER_PERMISSIONS.map(stringToComboBoxOption),
    },
    {
      label: 'Index permissions',
      options: INDEX_PERMISSIONS.map(stringToComboBoxOption),
    },
  ];

  const tenantOptions = tenantNames.map(stringToComboBoxOption);

  return (
    <>
      {props.buildBreadcrumbs(TITLE_TEXT_DICT[props.action])}
      <EuiPageHeader>
        <EuiText size="xs" color="subdued" className="panel-header-subtext">
          <EuiTitle size="m">
            <h1>{TITLE_TEXT_DICT[props.action]}</h1>
          </EuiTitle>
          Roles are the core way of controlling access to your cluster. Roles contain any
          combination of cluster-wide permission, index-specific permissions, document- and
          field-level security, and tenants. Once you&apos;ve created the role, you can map users to
          the roles so that users gain those permissions.{' '}
          <ExternalLink href={DocLinks.UsersAndRolesDoc} />
        </EuiText>
      </EuiPageHeader>
      <PanelWithHeader headerText="Name">
        <EuiForm>
          <NameRow
            headerText="Name"
            headerSubText="Specify a descriptive and unique role name. You cannot edit the name once the role is created."
            resourceName={roleName}
            resourceType="role"
            action={props.action}
            setNameState={setRoleName}
            setIsFormValid={setIsFormValid}
          />
        </EuiForm>
      </PanelWithHeader>
      <EuiSpacer size="m" />
      <ClusterPermissionPanel
        state={roleClusterPermission}
        setState={setRoleClusterPermission}
        optionUniverse={clusterWisePermissionOptions}
      />
      <EuiSpacer size="m" />
      <IndexPermissionPanel
        state={roleIndexPermission}
        setState={setRoleIndexPermission}
        optionUniverse={clusterWisePermissionOptions}
      />
      <EuiSpacer size="m" />
      <TenantPanel
        state={roleTenantPermission}
        setState={setRoleTenantPermission}
        optionUniverse={tenantOptions}
      />
      <EuiSpacer size="m" />
      <EuiFlexGroup justifyContent="flexEnd">
        <EuiFlexItem grow={false}>
          <EuiButton
            onClick={() => {
              window.location.href = buildHashUrl(ResourceType.roles);
            }}
          >
            Cancel
          </EuiButton>
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiButton fill onClick={updateRoleHandler} disabled={!isFormValid}>
            {props.action === 'edit' ? 'Update' : 'Create'}
          </EuiButton>
        </EuiFlexItem>
      </EuiFlexGroup>
      <EuiGlobalToastList toasts={toasts} toastLifeTimeMs={10000} dismissToast={removeToast} />
    </>
  );
}