Skip to content

Commit

Permalink
feat: misc UI/UX improvements (argoproj#11769)
Browse files Browse the repository at this point in the history

Signed-off-by: Alex Eftimie <[email protected]>
Co-authored-by: Remington Breeze <[email protected]>
  • Loading branch information
alexef and rbreeze authored Mar 17, 2023
1 parent 1cc1d4a commit d764cf7
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,11 @@
.columns {
white-space: normal;
}

.row {
line-height: 2;
padding-top: 15px;
padding-bottom: 15px;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export const ApplicationConditions = ({conditions}: {conditions: models.Applicat
<div className={`argo-table-list__row application-conditions__condition application-conditions__condition--${getConditionCategory(condition)}`} key={index}>
<div className='row'>
<div className='columns small-2'>{condition.type}</div>
<div className='columns small-7'>{condition.message}</div>
<div className='columns small-7' style={{whiteSpace: 'normal', lineHeight: 'normal'}}>
{condition.message}
</div>
<div className='columns small-3'>
<Timestamp date={condition.lastTransitionTime} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
this.setState({collapsedNodes: collapsedNodesList});
}
};
const appFullName = AppUtils.nodeKey({
group: 'argoproj.io',
kind: application.kind,
name: application.metadata.name,
namespace: application.metadata.namespace
});
return (
<div className='application-details'>
<Page
Expand Down Expand Up @@ -392,6 +398,7 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
<div className='application-details__status-panel'>
<ApplicationStatusPanel
application={application}
showDiff={() => this.selectNode(appFullName, 0, 'diff')}
showOperation={() => this.setOperationStatusVisible(true)}
showConditions={() => this.setConditionsStatusVisible(true)}
showMetadataInfo={revision => this.setState({...this.state, revision})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {DropDown} from 'argo-ui';
import * as classNames from 'classnames';
import * as React from 'react';

import * as models from '../../../shared/models';
Expand Down Expand Up @@ -26,13 +27,18 @@ export const ApplicationResourceList = ({
<div className='columns small-1 xxxlarge-2'>SYNC ORDER</div>
<div className='columns small-2 xxxlarge-2'>NAMESPACE</div>
<div className='columns small-2 xxxlarge-2'>CREATED AT</div>
<div className='columns small-1 xxxlarge-1'>STATUS</div>
<div className='columns small-2 xxxlarge-2'>STATUS</div>
</div>
</div>
{resources
.sort((first, second) => -createdOrNodeKey(first).localeCompare(createdOrNodeKey(second)))
.map(res => (
<div key={nodeKey(res)} className='argo-table-list__row' onClick={() => onNodeClick(nodeKey(res))}>
<div
key={nodeKey(res)}
className={classNames('argo-table-list__row', {
'application-resource-tree__node--orphaned': res.orphaned
})}
onClick={() => onNodeClick(nodeKey(res))}>
<div className='row'>
<div className='columns small-1 xxxlarge-1'>
<div className='application-details__resource-icon'>
Expand All @@ -59,7 +65,7 @@ export const ApplicationResourceList = ({
<div className='columns small-1 xxxlarge-2'>{res.syncWave || '-'}</div>
<div className='columns small-2 xxxlarge-2'>{res.namespace}</div>
<div className='columns small-2 xxxlarge-2'>{res.createdAt}</div>
<div className='columns small-1 xxxlarge-1'>
<div className='columns small-2 xxxlarge-2'>
{res.health && (
<React.Fragment>
<HealthStatusIcon state={res.health} /> {res.health.status} &nbsp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const ApplicationNodeInfo = (props: {
}
attributes.push({title: 'HOSTNAMES', value: hostNames});
} else if (props.node.kind === 'ReplicaSet') {
attributes.push({title: 'REPLICAS', value: `${props.live.spec?.replicas || 0}/${props.live.status?.readyReplicas || 0}/${props.live.spec?.replicas || 0}`});
attributes.push({title: 'REPLICAS', value: `${props.live.spec?.replicas || 0}/${props.live.status?.readyReplicas || 0}/${props.live.status?.replicas || 0}`});
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from 'react';
import Moment from 'react-moment';
import {Pod} from '../../../shared/models';
import {isYoungerThanXMinutes} from '../utils';

export const PodTooltip = (props: {pod: Pod}) => {
const pod = props.pod;

return (
<div>
<div className='row'>
<div className='columns small-12'>{pod.metadata.name}</div>
</div>
<div className='row'>
<div className='columns small-6'>Health:</div>
<div className='columns small-6'>{pod.health}</div>
</div>
{(pod.info || [])
.filter(i => i.name !== 'Node')
.map(i => (
<div className='row' key={i.name}>
<div className='columns small-6' style={{whiteSpace: 'nowrap'}}>
{i.name}:
</div>
<div className='columns small-6'>{i.value}</div>
</div>
))}
{pod.createdAt && (
<div className='row'>
<div className='columns small-6'>
<span>Created: </span>
</div>
<div className='columns small-6'>
<Moment fromNow={true} ago={true}>
{pod.createdAt}
</Moment>
<span> ago</span>
</div>
{isYoungerThanXMinutes(pod, 30) && (
<div className='columns small-12'>
<span>
<i className='fas fa-circle circle-icon' /> &nbsp;
<span>pod age less than 30min</span>
</span>
</div>
)}
</div>
)}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,7 @@ $pod-age-icon-clr: #ffce25;
}
}
}

.tippy-content {
text-align: left;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {ResourceLabel} from '../resource-label';
import {ComparisonStatusIcon, isYoungerThanXMinutes, HealthStatusIcon, nodeKey, PodHealthIcon, deletePodAction} from '../utils';

import './pod-view.scss';
import {PodTooltip} from './pod-tooltip';

interface PodViewProps {
tree: ApplicationTree;
Expand Down Expand Up @@ -163,29 +164,7 @@ export class PodView extends React.Component<PodViewProps> {
key={pod.uid}
anchor={() => (
<Tooltip
content={
<div>
{pod.metadata.name}
<div>Health: {pod.health}</div>
{pod.createdAt && (
<span>
<span>Created: </span>
<Moment fromNow={true} ago={true}>
{pod.createdAt}
</Moment>
<span> ago ({<Moment local={true}>{pod.createdAt}</Moment>})</span>
<div>
{isYoungerThanXMinutes(pod, 30) && (
<span>
<i className='fas fa-circle circle-icon' /> &nbsp;
<span>pod age less than 30min</span>
</span>
)}
</div>
</span>
)}
</div>
}
content={<PodTooltip pod={pod} />}
popperOptions={{
modifiers: {
preventOverflow: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

&--orphaned {
@include themify($themes) {
background-color: themed('light-argo-gray-2');
background-color: themed('light-argo-gray-2') !important;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ export function compareNodes(first: ResourceTreeNode, second: ResourceTreeNode)
}
return value.replace(/^Rev:/, '');
}
if (first.kind === 'ReplicaSet') {
return (
orphanedToInt(first.orphaned) - orphanedToInt(second.orphaned) ||
compareRevision(getRevision(second), getRevision(first)) ||
nodeKey(first).localeCompare(nodeKey(second)) ||
0
);
}
return (
orphanedToInt(first.orphaned) - orphanedToInt(second.orphaned) ||
nodeKey(first).localeCompare(nodeKey(second)) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import './application-status-panel.scss';

interface Props {
application: models.Application;
showDiff?: () => any;
showOperation?: () => any;
showConditions?: () => any;
showMetadataInfo?: (revision: string) => any;
Expand Down Expand Up @@ -44,7 +45,7 @@ const sectionHeader = (info: SectionInfo, hasMultipleSources: boolean, onClick?:
);
};

export const ApplicationStatusPanel = ({application, showOperation, showConditions, showMetadataInfo}: Props) => {
export const ApplicationStatusPanel = ({application, showDiff, showOperation, showConditions, showMetadataInfo}: Props) => {
const today = new Date();

let daysSinceLastSynchronized = 0;
Expand Down Expand Up @@ -91,7 +92,13 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio
{appOperationState && (
<div className={`application-status-panel__item-value application-status-panel__item-value--${appOperationState.phase}`}>
<div>
<ComparisonStatusIcon status={application.status.sync.status} label={true} />
{application.status.sync.status === models.SyncStatuses.OutOfSync ? (
<a onClick={() => showDiff && showDiff()}>
<ComparisonStatusIcon status={application.status.sync.status} label={true} />
</a>
) : (
<ComparisonStatusIcon status={application.status.sync.status} label={true} />
)}
</div>
<div className='application-status-panel__item-value__revision show-for-large'>{syncStatusMessage(application)}</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import {AutocompleteField, DropDownMenu, ErrorNotification, FormField, FormSelect, HelpIcon, NotificationType} from 'argo-ui';
import * as React from 'react';
import {FormApi, Text} from 'react-form';
import {Cluster, DataLoader, EditablePanel, EditablePanelItem, Expandable, MapInputField, NumberField, Repo, Revision, RevisionHelpIcon} from '../../../shared/components';
import {
ClipboardText,
Cluster,
DataLoader,
EditablePanel,
EditablePanelItem,
Expandable,
MapInputField,
NumberField,
Repo,
Revision,
RevisionHelpIcon
} from '../../../shared/components';
import {BadgePanel, Spinner} from '../../../shared/components';
import {Consumer, ContextApis} from '../../../shared/context';
import * as models from '../../../shared/models';
Expand Down Expand Up @@ -139,7 +151,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => {
},
{
title: 'NAMESPACE',
view: app.spec.destination.namespace,
view: <ClipboardText text={app.spec.destination.namespace} />,
edit: (formApi: FormApi) => <FormField formApi={formApi} field='spec.destination.namespace' component={Text} />
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,11 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
{title: 'Name', compare: (a, b) => a.metadata.name.localeCompare(b.metadata.name)},
{
title: 'Created At',
compare: (a, b) => a.metadata.creationTimestamp.localeCompare(b.metadata.creationTimestamp)
compare: (b, a) => a.metadata.creationTimestamp.localeCompare(b.metadata.creationTimestamp)
},
{
title: 'Synchronized',
compare: (a, b) =>
compare: (b, a) =>
a.status.operationState?.finishedAt?.localeCompare(b.status.operationState?.finishedAt)
}
]}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/shared/components/events-list/events-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const EventsList = (props: {events: models.Event[]}) => {
<div className={`argo-table-list__row events-list__event events-list__event--${event.type}`} key={event.metadata.uid}>
<div className='row'>
<div className='columns small-2 xxlarge-2'>{event.reason}</div>
<div className='columns small-4 xxlarge-5' style={{whiteSpace: 'normal'}}>
<div className='columns small-4 xxlarge-5' style={{whiteSpace: 'normal', lineHeight: 'normal'}}>
{event.message}
</div>
<div className='columns small-2 xxlarge-1'>{event.count}</div>
Expand Down
1 change: 1 addition & 0 deletions ui/src/app/shared/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ export interface ResourceStatus {
hook?: boolean;
requiresPruning?: boolean;
syncWave?: number;
orphaned?: boolean;
}

export interface ResourceRef {
Expand Down

0 comments on commit d764cf7

Please sign in to comment.