Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Commit

Permalink
feat: Flesh out the detail page a bit more
Browse files Browse the repository at this point in the history
  • Loading branch information
gashcrumb committed May 3, 2019
1 parent 776821e commit d115f98
Show file tree
Hide file tree
Showing 12 changed files with 708 additions and 159 deletions.
47 changes: 47 additions & 0 deletions app/ui-react/packages/api/src/WithActivities.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Activity, IntegrationDeployment } from '@syndesis/models';
import * as React from 'react';
import { SyndesisFetch } from './SyndesisFetch';

export interface IIntegrationDeploymentResponse {
items: IntegrationDeployment[];
totalCount: number;
}

export interface IActivitiesAndDeploymentsChildrenProps {
activities: Activity[];
deployments: IntegrationDeployment[];
fetchDeployments: () => Promise<void>;
fetchActivities: () => Promise<void>;
}

export interface IWithActivitiesProps {
integrationId: string;
children(props: IActivitiesAndDeploymentsChildrenProps): any;
}

export class WithActivities extends React.Component<IWithActivitiesProps> {
public render() {
return (
<SyndesisFetch<IIntegrationDeploymentResponse>
url={`/integrations/${this.props.integrationId}/deployments`}
defaultValue={{ items: [], totalCount: 0 }}
>
{({ read: fetchDeployments, response: deployments }) => (
<SyndesisFetch<Activity[]>
url={`/activity/integrations/${this.props.integrationId}`}
defaultValue={[]}
>
{({ read: fetchActivities, response: activities }) => {
return this.props.children({
activities: activities.data,
deployments: deployments.data.items,
fetchActivities,
fetchDeployments,
});
}}
</SyndesisFetch>
)}
</SyndesisFetch>
);
}
}
93 changes: 93 additions & 0 deletions app/ui-react/packages/api/src/WithMonitoredIntegration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
IIntegrationOverviewWithDraft,
IntegrationMonitoring,
IntegrationWithMonitoring,
} from '@syndesis/models';
import * as React from 'react';
import { IFetchState } from './Fetch';
import { ServerEventsContext } from './ServerEventsContext';
import { SyndesisFetch } from './SyndesisFetch';
import { WithChangeListener } from './WithChangeListener';
import { WithIntegration } from './WithIntegration';
import { IChangeEvent } from './WithServerEvents';

export interface IWithMonitoredIntegrationProps {
integrationId: string;
disableUpdates?: boolean;
children(props: IFetchState<IntegrationWithMonitoring>): any;
}

/**
* A component that fetches the integration with the specified identifier.
* @see [integrationId]{@link IWithIntegrationProps#integrationId}
*/
export class WithMonitoredIntegration extends React.Component<
IWithMonitoredIntegrationProps
> {
public constructor(props: IWithMonitoredIntegrationProps) {
super(props);
this.changeFilter = this.changeFilter.bind(this);
}
public changeFilter(change: IChangeEvent) {
return (
change.kind.startsWith('integration') &&
change.id.startsWith(this.props.integrationId)
);
}
public getMonitoredIntegration(
integration: IIntegrationOverviewWithDraft,
response: IFetchState<IntegrationMonitoring[]>
) {
return {
integration,
monitoring: response.data.find(
(o: IntegrationMonitoring) => o.integrationId === integration.id
),
};
}
public render() {
return (
<WithIntegration
integrationId={this.props.integrationId}
disableUpdates={this.props.disableUpdates}
>
{({ data: integration, ...props }) => (
<SyndesisFetch<IntegrationMonitoring[]>
url={'/monitoring/integrations'}
defaultValue={[]}
>
{({ read, response }) => {
if (this.props.disableUpdates) {
const data = this.getMonitoredIntegration(
integration,
response
);
return this.props.children({ ...props, data });
}
return (
<ServerEventsContext.Consumer>
{({ registerChangeListener, unregisterChangeListener }) => (
<WithChangeListener
read={read}
registerChangeListener={registerChangeListener}
unregisterChangeListener={unregisterChangeListener}
filter={this.changeFilter}
>
{() => {
const data = this.getMonitoredIntegration(
integration,
response
);
return this.props.children({ ...props, data });
}}
</WithChangeListener>
)}
</ServerEventsContext.Consumer>
);
}}
</SyndesisFetch>
)}
</WithIntegration>
);
}
}
2 changes: 2 additions & 0 deletions app/ui-react/packages/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './Fetch';
export * from './ServerEventsContext';
export * from './Stream';
export * from './WithIntegrationHelpers';
export * from './WithActivities';
export * from './WithApiConnectors';
export * from './WithApiVersion';
export * from './WithEnvironments';
Expand All @@ -17,6 +18,7 @@ export * from './WithExtensions';
export * from './WithIntegration';
export * from './WithIntegrations';
export * from './WithIntegrationTags';
export * from './WithMonitoredIntegration';
export * from './WithMonitoredIntegrations';
export * from './WithIntegrationsMetrics';
export * from './WithConnections';
Expand Down
23 changes: 23 additions & 0 deletions app/ui-react/packages/models/src/extra.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,29 @@ import {
*
*/

// this is for the logging backend
export interface Activity {
logts?: string;
at: number;
pod: string;
ver: string;
status: string;
failed: boolean;
steps?: ActivityStep[];
metadata?: any;
}

export interface ActivityStep extends Step {
name: string;
isFailed: boolean;
at: number;
duration?: number;
failure?: string;
messages?: string[];
output?: string;
events?: any;
}

export interface IApiVersion {
version: string;
'commit-id': string;
Expand Down
41 changes: 33 additions & 8 deletions app/ui-react/packages/ui/src/Integration/IntegrationDetailInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ import * as React from 'react';
import { IntegrationDetailEditableName } from './IntegrationDetailEditableName';

import './IntegrationDetailInfo.css';
import { IntegrationStatusDetail } from './IntegrationStatusDetail';
import { IntegrationState } from './models';

export interface IIntegrationDetailInfoProps {
name?: string;
version?: number;
currentState: IntegrationState;
targetState: IntegrationState;
monitoringValue?: string;
monitoringCurrentStep?: number;
monitoringTotalSteps?: number;
monitoringLogUrl?: string;
i18nProgressPending: string;
i18nProgressStarting: string;
i18nProgressStopping: string;
i18nLogUrlText: string;
}

export class IntegrationDetailInfo extends React.PureComponent<
Expand All @@ -16,14 +28,27 @@ export class IntegrationDetailInfo extends React.PureComponent<
return (
<div className="integration-detail-info">
<IntegrationDetailEditableName name={this.props.name} />
{this.props.version ? (
<>
<span className="pficon pficon-ok" />
&nbsp;Published version {this.props.version}
</>
) : (
'Stopped'
)}
<>
{this.props.currentState === 'Pending' && (
<IntegrationStatusDetail
targetState={this.props.targetState}
value={this.props.monitoringValue}
currentStep={this.props.monitoringCurrentStep}
totalSteps={this.props.monitoringTotalSteps}
logUrl={this.props.monitoringLogUrl}
i18nProgressPending={this.props.i18nProgressPending}
i18nProgressStarting={this.props.i18nProgressStarting}
i18nProgressStopping={this.props.i18nProgressStopping}
i18nLogUrlText={this.props.i18nLogUrlText}
/>
)}
{this.props.currentState === 'Published' && this.props.version && (
<>
<span className="pficon pficon-ok" />
&nbsp;Published version {this.props.version}
</>
)}
</>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { canActivate, canDeactivate } from '@syndesis/api';
import {
IntegrationMonitoring,
IntegrationWithMonitoring,
} from '@syndesis/models';
import {
IMenuActions,
IntegrationDetailBreadcrumb,
IntegrationDetailInfo,
} from '@syndesis/ui';
import * as React from 'react';
import { Translation } from 'react-i18next';
import resolvers from '../../resolvers';
import { IntegrationDetailNavBar } from '../shared';

export interface IIntegrationDetailHeaderProps {
data: IntegrationWithMonitoring;
startAction: IMenuActions;
stopAction: IMenuActions;
deleteAction: IMenuActions;
ciCdAction: IMenuActions;
editAction: IMenuActions;
exportAction: IMenuActions;
getPodLogUrl: (
monitoring: IntegrationMonitoring | undefined
) => string | undefined;
}

export const IntegrationDetailHeader: React.FunctionComponent<
IIntegrationDetailHeaderProps
> = (props: IIntegrationDetailHeaderProps) => {
const breadcrumbMenuActions: IMenuActions[] = [];
if (canActivate(props.data.integration)) {
breadcrumbMenuActions.push(props.startAction);
}
if (canDeactivate(props.data.integration)) {
breadcrumbMenuActions.push(props.stopAction);
}
breadcrumbMenuActions.push(props.deleteAction);
breadcrumbMenuActions.push(props.ciCdAction);

return (
<Translation ns={['integrations', 'shared']}>
{t => (
<>
<IntegrationDetailBreadcrumb
editHref={props.editAction.href}
editLabel={props.editAction.label}
exportAction={props.exportAction.onClick}
exportHref={props.exportAction.href}
exportLabel={props.exportAction.label}
homeHref={resolvers.dashboard.root()}
i18nHome={t('shared:Home')}
i18nIntegrations={t('shared:Integrations')}
i18nPageTitle={t('integrations:detail:pageTitle')}
integrationId={props.data.integration.id}
integrationsHref={resolvers.integrations.list()}
menuActions={breadcrumbMenuActions}
/>

<IntegrationDetailInfo
name={props.data.integration.name}
version={props.data.integration.version}
currentState={props.data.integration.currentState!}
targetState={props.data.integration.targetState!}
monitoringValue={
props.data.monitoring &&
t('integrations:' + props.data.monitoring.detailedState.value)
}
monitoringCurrentStep={
props.data.monitoring &&
props.data.monitoring.detailedState.currentStep
}
monitoringTotalSteps={
props.data.monitoring &&
props.data.monitoring.detailedState.totalSteps
}
monitoringLogUrl={props.getPodLogUrl(props.data.monitoring)}
i18nProgressPending={t('shared:Pending')}
i18nProgressStarting={t('integrations:progressStarting')}
i18nProgressStopping={t('integrations:progressStopping')}
i18nLogUrlText={t('shared:viewLogs')}
/>
<IntegrationDetailNavBar integration={props.data.integration} />
</>
)}
</Translation>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './Integrations';
export * from './IntegrationCreatorBreadcrumbs';
export * from './IntegrationDetailHeader';
export * from './IntegrationDetailSteps';
export * from './IntegrationEditorBreadcrumbs';
export * from './IntegrationEditorSidebar';
Expand Down
Loading

0 comments on commit d115f98

Please sign in to comment.