github.com/argoproj/argo-cd/v3@v3.2.1/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx (about)

     1  import * as moment from 'moment';
     2  import * as React from 'react';
     3  import * as classNames from 'classnames';
     4  import * as models from '../../../shared/models';
     5  import './application-deployment-history.scss';
     6  import '../../../shared/components/editable-panel/editable-panel.scss';
     7  import {DataLoader} from 'argo-ui';
     8  import {Repo, Revision} from '../../../shared/components';
     9  import {services} from '../../../shared/services';
    10  import {ApplicationParameters} from '../application-parameters/application-parameters';
    11  import {RevisionMetadataRows} from './revision-metadata-rows';
    12  
    13  type props = {
    14      app: models.Application;
    15      info: models.RevisionHistory;
    16      index: number;
    17  };
    18  
    19  export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) => {
    20      const deployments = (app.status.history || []).slice().reverse();
    21      const recentDeployments = deployments.map((info, i) => {
    22          const nextDeployedAt = i === 0 ? null : deployments[i - 1].deployedAt;
    23          const runEnd = nextDeployedAt ? moment(nextDeployedAt) : moment();
    24          return {...info, nextDeployedAt, durationMs: runEnd.diff(moment(info.deployedAt)) / 1000};
    25      });
    26  
    27      const [showParameterDetails, setShowParameterDetails] = React.useState(Boolean);
    28      const [showSourceDetails, setShowSourceDetails] = React.useState([]);
    29      const updateMap = (i: number) => {
    30          if (i === null || i === undefined) {
    31              return;
    32          }
    33          if (showSourceDetails.includes(i)) {
    34              setShowSourceDetails(showSourceDetails.filter(item => item !== i));
    35          } else {
    36              setShowSourceDetails([...showSourceDetails, i]);
    37          }
    38      };
    39  
    40      const getCollapsedSection = (i: number, repoURL: string): React.ReactFragment => {
    41          return (
    42              <div
    43                  id={i ? `'hide-parameters-'${i}` : 'hide-parameters'}
    44                  key={i ? `'hide-parameters-'${i}` : 'hide-parameters'}
    45                  className='settings-overview__redirect-panel collapsible-section'
    46                  onClick={() => {
    47                      setShowParameterDetails(!showParameterDetails);
    48                      updateMap(i);
    49                  }}>
    50                  <div className='editable-panel__collapsible-button'>
    51                      <i className={`fa fa-angle-down filter__collapse editable-panel__collapsible-button__override`} />
    52                  </div>
    53  
    54                  <div style={{textAlign: 'center'}}>
    55                      <div className='settings-overview__redirect-panel__title'>{i != null ? 'Source ' + (i + 1) + ' Parameters' : 'Source Parameters'}</div>
    56                      <div className='settings-overview__redirect-panel__description'>URL: {repoURL}</div>
    57                  </div>
    58              </div>
    59          );
    60      };
    61  
    62      const getExpandedSection = (index?: number): React.ReactFragment => {
    63          return (
    64              <div id={index ? `'show-parameters-'${index}` : 'show-parameters'} className='editable-panel__collapsible-button' style={{zIndex: 1001}}>
    65                  <i
    66                      className={`fa fa-angle-up filter__collapse editable-panel__collapsible-button__override`}
    67                      onClick={() => {
    68                          setShowParameterDetails(!showParameterDetails);
    69                          updateMap(index);
    70                      }}
    71                  />
    72              </div>
    73          );
    74      };
    75  
    76      const getErrorSection = (err: React.ReactNode): React.ReactFragment => {
    77          return (
    78              <div style={{padding: '1.7em'}}>
    79                  <p style={{textAlign: 'center'}}>{err}</p>
    80              </div>
    81          );
    82      };
    83  
    84      return (
    85          <>
    86              {info.sources === undefined ? (
    87                  <React.Fragment>
    88                      <div>
    89                          <div className='row'>
    90                              <div className='columns small-3'>Revision:</div>
    91                              <div className='columns small-9'>
    92                                  <Revision repoUrl={info.source.repoURL} revision={info.revision} />
    93                              </div>
    94                          </div>
    95                      </div>
    96                      <RevisionMetadataRows
    97                          applicationName={app.metadata.name}
    98                          applicationNamespace={app.metadata.namespace}
    99                          source={{...recentDeployments[index].source, targetRevision: recentDeployments[index].revision}}
   100                          index={0}
   101                          versionId={recentDeployments[index].id}
   102                      />
   103  
   104                      {showParameterDetails ? (
   105                          <div id={`'history-expanded'`} key={`'history-expanded'`} className={classNames('white-box', 'collapsible-section')}>
   106                              {getExpandedSection()}
   107                              <DataLoader
   108                                  errorRenderer={err => {
   109                                      return getErrorSection(err);
   110                                  }}
   111                                  input={{...recentDeployments[index].source, targetRevision: recentDeployments[index].revision, appName: app.metadata.name}}
   112                                  load={src => services.repos.appDetails(src, src.appName, app.spec.project, 0, recentDeployments[index].id)}>
   113                                  {(details: models.RepoAppDetails) => (
   114                                      <div>
   115                                          <ApplicationParameters
   116                                              application={{
   117                                                  ...app,
   118                                                  spec: {...app.spec, source: recentDeployments[index].source}
   119                                              }}
   120                                              details={details}
   121                                              tempSource={{...recentDeployments[index].source, targetRevision: recentDeployments[index].revision}}
   122                                          />
   123                                      </div>
   124                                  )}
   125                              </DataLoader>
   126                          </div>
   127                      ) : (
   128                          getCollapsedSection(null, recentDeployments[index].source.repoURL)
   129                      )}
   130                  </React.Fragment>
   131              ) : (
   132                  info.sources.map((source, i) => (
   133                      <React.Fragment key={`${index}_${i}`}>
   134                          {i > 0 ? <div className='separator' /> : null}
   135                          <div>
   136                              <div className='row'>
   137                                  <div className='columns small-3'>Repo URL:</div>
   138                                  <div className='columns small-9'>
   139                                      <Repo url={source.repoURL} />
   140                                  </div>
   141                              </div>
   142                              <div className='row'>
   143                                  <div className='columns small-3'>Revision:</div>
   144                                  <div className='columns small-9'>
   145                                      <Revision repoUrl={source.repoURL} revision={info.revisions[i]} />
   146                                  </div>
   147                              </div>
   148                          </div>
   149                          <RevisionMetadataRows
   150                              applicationName={app.metadata.name}
   151                              applicationNamespace={app.metadata.namespace}
   152                              source={{...source, targetRevision: recentDeployments[index].revisions[i]}}
   153                              index={i}
   154                              versionId={recentDeployments[index].id}
   155                          />
   156                          {showSourceDetails.includes(i) ? (
   157                              <div id={`'history-expanded-'${i}`} key={`'history-expanded-'${i}`} className={classNames('white-box', 'collapsible-section')}>
   158                                  <div id={`'history-expanded-'${i}`} key={`'history-expanded-'${i}`} className='white-box__details'>
   159                                      {getExpandedSection(i)}
   160                                      <DataLoader
   161                                          errorRenderer={err => {
   162                                              return getErrorSection(err);
   163                                          }}
   164                                          input={{
   165                                              ...source,
   166                                              targetRevision: recentDeployments[index].revisions[i],
   167                                              index: i,
   168                                              versionId: recentDeployments[index].id,
   169                                              appName: app.metadata.name
   170                                          }}
   171                                          load={src => services.repos.appDetails(src, src.appName, app.spec.project, i, recentDeployments[index].id)}>
   172                                          {(details: models.RepoAppDetails) => (
   173                                              <React.Fragment>
   174                                                  <div id={'floating_title_' + i} className='editable-panel__sticky-title'>
   175                                                      <div style={{marginTop: '0px'}}>
   176                                                          <div>Source {i + 1} Parameters</div>
   177                                                          <div>Repo URL: {source.repoURL}</div>
   178                                                          <div>{source.path ? 'Path: ' + source.path : ''}</div>
   179                                                          <span>
   180                                                              Revision: <Revision repoUrl={''} revision={info.revisions[i]}></Revision>
   181                                                          </span>
   182                                                      </div>
   183                                                  </div>
   184                                                  <ApplicationParameters
   185                                                      application={{
   186                                                          ...app,
   187                                                          spec: {...app.spec, source}
   188                                                      }}
   189                                                      details={details}
   190                                                      tempSource={{...source, targetRevision: recentDeployments[index].revisions[i]}}
   191                                                  />
   192                                              </React.Fragment>
   193                                          )}
   194                                      </DataLoader>
   195                                  </div>
   196                              </div>
   197                          ) : (
   198                              getCollapsedSection(i, source.repoURL)
   199                          )}
   200                      </React.Fragment>
   201                  ))
   202              )}
   203          </>
   204      );
   205  };