github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/pages/auth/users/user/policies.jsx (about)

     1  import React, {useEffect} from "react";
     2  import {useOutletContext} from "react-router-dom";
     3  import {UserHeaderWithContext} from "./userHeaderWithContext";
     4  import {
     5      ActionGroup,
     6      ActionsBar,
     7      DataTable,
     8      FormattedDate,
     9      Loading,
    10      AlertError,
    11      RefreshButton
    12  } from "../../../../lib/components/controls";
    13  import Button from "react-bootstrap/Button";
    14  import {useAPIWithPagination} from "../../../../lib/hooks/api";
    15  import {auth} from "../../../../lib/api";
    16  import {Paginator} from "../../../../lib/components/pagination";
    17  import {useState} from "react";
    18  import {AttachModal} from "../../../../lib/components/auth/forms";
    19  import {ConfirmationButton} from "../../../../lib/components/modals";
    20  import {Link} from "../../../../lib/components/nav";
    21  import {useRouter} from "../../../../lib/hooks/router";
    22  
    23  
    24  const UserPoliciesList = ({ userId, after, onPaginate }) => {
    25      const [refresh, setRefresh] = useState(false);
    26      const [showAddModal, setShowAddModal] = useState(false);
    27      const [attachError, setAttachError] = useState(null);
    28  
    29      const {results, loading, error, nextPage} = useAPIWithPagination(() => {
    30          return auth.listUserPolicies(userId, false, after);
    31      }, [userId, after, refresh]);
    32  
    33      let content;
    34      if (loading) content = <Loading/>;
    35      else if (error) content=  <AlertError error={error}/>;
    36      else content = (
    37              <>
    38                  {attachError && <AlertError error={attachError}/>}
    39                  <DataTable
    40                      keyFn={policy => policy.id}
    41                      rowFn={policy => [
    42                          <Link href={{pathname: '/auth/policies/:policyId', params: {policyId: policy.id}}}>{policy.id}</Link>,
    43                          <FormattedDate dateValue={policy.creation_date}/>
    44                      ]}
    45                      headers={['Policy ID', 'Created At']}
    46                      actions={[{
    47                          key: 'Detach',
    48                          buttonFn: policy => <ConfirmationButton
    49                              size="sm"
    50                              variant="outline-danger"
    51                              modalVariant="danger"
    52                              msg={<span>Are you sure you{'\''}d like to detach policy <strong>{policy.id}</strong>?</span>}
    53                              onConfirm={() => {
    54                                  auth.detachPolicyFromUser(userId, policy.id)
    55                                      .catch(error => alert(error))
    56                                      .then(() => { setRefresh(!refresh) })
    57                              }}>
    58                              Detach
    59                          </ConfirmationButton>
    60                      }]}
    61                      results={results}
    62                      emptyState={'No policies found'}
    63                  />
    64  
    65                  <Paginator onPaginate={onPaginate} after={after} nextPage={nextPage}/>
    66  
    67  
    68                  {showAddModal && <AttachModal
    69                      show={showAddModal}
    70                      emptyState={'No policies found'}
    71                      filterPlaceholder={'Find Policy...'}
    72                      modalTitle={'Attach Policies'}
    73                      addText={'Attach Policies'}
    74                      searchFn={prefix => auth.listPolicies(prefix, "", 5).then(res => res.results)}
    75                      onHide={() => setShowAddModal(false)}
    76                      onAttach={(selected) => {
    77                          Promise.all(selected.map(policy => auth.attachPolicyToUser(userId, policy.id)))
    78                              .then(() => { setRefresh(!refresh); setAttachError(null) })
    79                              .catch(error => { setAttachError(error) })
    80                              .finally(() => { setShowAddModal(false) });
    81                      }}/>
    82                  }
    83              </>
    84          )
    85  
    86      return (
    87          <>
    88              <UserHeaderWithContext userId={userId} page={'policies'}/>
    89  
    90              <ActionsBar>
    91                  <ActionGroup orientation="left">
    92                      <Button variant="success" onClick={() => setShowAddModal(true)}>Attach Policy</Button>
    93                  </ActionGroup>
    94  
    95                  <ActionGroup orientation="right">
    96                      <RefreshButton onClick={() => setRefresh(!refresh)}/>
    97                  </ActionGroup>
    98              </ActionsBar>
    99  
   100              <div className="mt-2">
   101                  {content}
   102              </div>
   103          </>
   104      );
   105  }
   106  
   107  const UserPoliciesContainer = () => {
   108      const router = useRouter();
   109      const { after } = router.query;
   110      const { userId } = router.params;
   111      return (!userId) ? <></> : <UserPoliciesList
   112          userId={userId}
   113          after={(after) ? after : ""}
   114          onPaginate={after => router.push({pathname: '/auth/users/:userId/policies', params: {userId}, query: {after}})}
   115      />;
   116  };
   117  
   118  const UserPoliciesPage = () => {
   119      const {setActiveTab} = useOutletContext();
   120      useEffect(() => setActiveTab("users"), [setActiveTab]);
   121      return <UserPoliciesContainer/>;
   122  };
   123  
   124  export default UserPoliciesPage;