Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add app list and details page views to navigation history (#7776) #7937

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {delay, filter, map, mergeMap, repeat, retryWhen} from 'rxjs/operators';
import {DataLoader, EmptyState, ErrorNotification, ObservableQuery, Page, Paginate, Revision, Timestamp} from '../../../shared/components';
import {AppContext, ContextApis} from '../../../shared/context';
import * as appModels from '../../../shared/models';
import {AppDetailsPreferences, AppsDetailsViewType, services} from '../../../shared/services';
import {AppDetailsPreferences, AppsDetailsViewKey, AppsDetailsViewType, services} from '../../../shared/services';

import {ApplicationConditions} from '../application-conditions/application-conditions';
import {ApplicationDeploymentHistory} from '../application-deployment-history/application-deployment-history';
Expand Down Expand Up @@ -100,6 +100,21 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{nam
services.viewPreferences.updatePreferences({appDetails: {...pref, groupNodes: !pref.groupNodes}});
}

private getPageTitle(view: string) {
const {Tree, Pods, Network, List} = AppsDetailsViewKey;
switch (view) {
case Tree:
return 'Application Details Tree';
case Network:
return 'Application Details Network';
case Pods:
return 'Application Details Pods';
case List:
return 'Application Details List';
}
keithchong marked this conversation as resolved.
Show resolved Hide resolved
return '';
}

public render() {
return (
<ObservableQuery>
Expand Down Expand Up @@ -194,47 +209,49 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{nam
part + ' '
)
);

const {Tree, Pods, Network, List} = AppsDetailsViewKey;
return (
<div className='application-details'>
<Page
title='Application Details'
title={this.props.match.params.name + ' - ' + this.getPageTitle(pref.view)}
useTitleOnly={true}
topBarTitle={this.getPageTitle(pref.view)}
toolbar={{
breadcrumbs: [{title: 'Applications', path: '/applications'}, {title: this.props.match.params.name}],
actionMenu: {items: this.getApplicationActionMenu(application, true)},
tools: (
<React.Fragment key='app-list-tools'>
<div className='application-details__view-type'>
<i
className={classNames('fa fa-sitemap', {selected: pref.view === 'tree'})}
className={classNames('fa fa-sitemap', {selected: pref.view === Tree})}
title='Tree'
onClick={() => {
this.appContext.apis.navigation.goto('.', {view: 'tree'}, {replace: true});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: 'tree'}});
this.appContext.apis.navigation.goto('.', {view: Tree});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: Tree}});
}}
/>
<i
className={classNames('fa fa-th', {selected: pref.view === 'pods'})}
className={classNames('fa fa-th', {selected: pref.view === Pods})}
title='Pods'
onClick={() => {
this.appContext.apis.navigation.goto('.', {view: 'pods'}, {replace: true});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: 'pods'}});
this.appContext.apis.navigation.goto('.', {view: Pods});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: Pods}});
}}
/>
<i
className={classNames('fa fa-network-wired', {selected: pref.view === 'network'})}
className={classNames('fa fa-network-wired', {selected: pref.view === Network})}
title='Network'
onClick={() => {
this.appContext.apis.navigation.goto('.', {view: 'network'}, {replace: true});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: 'network'}});
this.appContext.apis.navigation.goto('.', {view: Network});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: Network}});
}}
/>
<i
className={classNames('fa fa-th-list', {selected: pref.view === 'list'})}
className={classNames('fa fa-th-list', {selected: pref.view === List})}
title='List'
onClick={() => {
this.appContext.apis.navigation.goto('.', {view: 'list'}, {replace: true});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: 'list'}});
this.appContext.apis.navigation.goto('.', {view: List});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: List}});
}}
keithchong marked this conversation as resolved.
Show resolved Hide resolved
/>
</div>
Expand Down Expand Up @@ -575,7 +592,7 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{nam

private onAppDeleted() {
this.appContext.apis.notifications.show({type: NotificationType.Success, content: `Application '${this.props.match.params.name}' was deleted`});
this.appContext.apis.navigation.goto('/applications', {}, {replace: true});
this.appContext.apis.navigation.goto('/applications', {view: 'tiles'});
}

private async updateApp(app: appModels.Application, query: {validate?: boolean}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {bufferTime, delay, filter, map, mergeMap, repeat, retryWhen} from 'rxjs/
import {AddAuthToToolbar, ClusterCtx, DataLoader, EmptyState, ObservableQuery, Page, Paginate, Query, Spinner} from '../../../shared/components';
import {Consumer, Context, ContextApis} from '../../../shared/context';
import * as models from '../../../shared/models';
import {AppsListPreferences, AppsListViewType, HealthStatusBarPreferences, services} from '../../../shared/services';
import {AppsListViewKey, AppsListPreferences, AppsListViewType, HealthStatusBarPreferences, services} from '../../../shared/services';
import {ApplicationCreatePanel} from '../application-create-panel/application-create-panel';
import {ApplicationSyncPanel} from '../application-sync-panel/application-sync-panel';
import {ApplicationsSyncPanel} from '../applications-sync-panel/applications-sync-panel';
Expand Down Expand Up @@ -124,6 +124,8 @@ const ViewPref = ({children}: {children: (pref: AppsListPreferences & {page: num
}
if (params.get('view') != null) {
viewPref.view = params.get('view') as AppsListViewType;
} else {
viewPref.view = 'tiles' as AppsListViewType;
}
if (params.get('labels') != null) {
viewPref.labelsFilter = params
Expand Down Expand Up @@ -287,6 +289,7 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
const clusters = React.useMemo(() => services.clusters.list(), []);
const [isAppCreatePending, setAppCreatePending] = React.useState(false);
const loaderRef = React.useRef<DataLoader>();
const {List, Summary, Tiles} = AppsListViewKey;

function refreshApp(appName: string) {
// app refreshing might be done too quickly so that UI might miss it due to event batching
Expand Down Expand Up @@ -318,14 +321,31 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
);
}

function getPageTitle(view: string) {
switch (view) {
case List:
return 'Applications List';
case Tiles:
return 'Applications Tiles';
case Summary:
return 'Applications Summary';
}
return '';
keithchong marked this conversation as resolved.
Show resolved Hide resolved
}

return (
<ClusterCtx.Provider value={clusters}>
<KeybindingProvider>
<Consumer>
{ctx => (
<Page title='Applications' toolbar={{breadcrumbs: [{title: 'Applications', path: '/applications'}]}} hideAuth={true}>
<ViewPref>
{pref => (
<ViewPref>
{pref => (
<Page
key={pref.view}
title={getPageTitle(pref.view)}
useTitleOnly={true}
toolbar={{breadcrumbs: [{title: 'Applications', path: '/applications'}]}}
hideAuth={true}>
<DataLoader
input={pref.projectsFilter?.join(',')}
ref={loaderRef}
Expand Down Expand Up @@ -367,27 +387,27 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
</Tooltip>
<div className='applications-list__view-type' style={{marginLeft: 'auto'}}>
<i
className={classNames('fa fa-th', {selected: pref.view === 'tiles'}, 'menu_icon')}
className={classNames('fa fa-th', {selected: pref.view === Tiles}, 'menu_icon')}
title='Tiles'
onClick={() => {
ctx.navigation.goto('.', {view: 'tiles'}, {replace: true});
services.viewPreferences.updatePreferences({appList: {...pref, view: 'tiles'}});
ctx.navigation.goto('.', {view: Tiles});
services.viewPreferences.updatePreferences({appList: {...pref, view: Tiles}});
}}
/>
<i
className={classNames('fa fa-th-list', {selected: pref.view === 'list'}, 'menu_icon')}
className={classNames('fa fa-th-list', {selected: pref.view === List}, 'menu_icon')}
title='List'
onClick={() => {
ctx.navigation.goto('.', {view: 'list'}, {replace: true});
services.viewPreferences.updatePreferences({appList: {...pref, view: 'list'}});
ctx.navigation.goto('.', {view: List});
services.viewPreferences.updatePreferences({appList: {...pref, view: List}});
}}
/>
<i
className={classNames('fa fa-chart-pie', {selected: pref.view === 'summary'}, 'menu_icon')}
className={classNames('fa fa-chart-pie', {selected: pref.view === Summary}, 'menu_icon')}
title='Summary'
onClick={() => {
ctx.navigation.goto('.', {view: 'summary'}, {replace: true});
services.viewPreferences.updatePreferences({appList: {...pref, view: 'summary'}});
ctx.navigation.goto('.', {view: Summary});
services.viewPreferences.updatePreferences({appList: {...pref, view: Summary}});
}}
/>
</div>
Expand Down Expand Up @@ -557,9 +577,9 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
);
}}
</DataLoader>
)}
</ViewPref>
</Page>
</Page>
)}
</ViewPref>
)}
</Consumer>
</KeybindingProvider>
Expand Down
Loading