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

Improve desktop menu #103

Merged
merged 1 commit into from
Jun 15, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 3 additions & 4 deletions cmd/electron/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,10 @@ func main() {
}
}()

// Check if a new version is available and create the menu. For the menu we need the sync flag, to write the
// selected context back to the Kubeconfig file, the result from the version check and the Kubernetes client and
// logger.
// Check if a new version is available and create the menu. For the menu we need the result from the version check
// and the Kubernetes client and logger.
updateAvailable := checkVersion(version.Version, log)
menuOptions, err := getMenuOptions(*syncFlag, updateAvailable, client, log)
menuOptions, err := getMenuOptions(updateAvailable, client, log)
if err != nil {
log.WithError(err).Fatalf("Could not create menu")
}
Expand Down
46 changes: 36 additions & 10 deletions cmd/electron/menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,11 @@ func openBrowser(url string) {

// createClusterMenuItem creates a new menu item for a given context from the Kubeconfig file.
// When the cluster is selected an "cluster" event will be send to the frontend via SSE.
func createClusterMenuItem(cluster string, sync bool, client *kube.Client, log *logrus.Logger) astilectron.MenuItemOptions {
func createClusterMenuItem(cluster string, log *logrus.Logger) astilectron.MenuItemOptions {
return astilectron.MenuItemOptions{
Label: astikit.StrPtr(cluster),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Debugf("Menu item '%s' has been clicked", cluster)
if sync {
err := client.ChangeContext(cluster)
if err != nil {
log.WithError(err).Errorf("Could not save selected context")
}
}
messageChannel <- Message{Event: "cluster", Data: cluster}
return
},
Expand Down Expand Up @@ -133,7 +127,7 @@ func createFileMenu(updateAvailable bool, log *logrus.Logger) *astilectron.MenuI
}

// getMenuOptions returns the menu for the Electron app.
func getMenuOptions(sync bool, updateAvailable bool, client *kube.Client, log *logrus.Logger) ([]*astilectron.MenuItemOptions, error) {
func getMenuOptions(updateAvailable bool, client *kube.Client, log *logrus.Logger) ([]*astilectron.MenuItemOptions, error) {
fileMenu := createFileMenu(updateAvailable, log)

// Load all clusters from the Kubeconfig file and sort the clusters alphabetical. Then iterate over the clusters and
Expand All @@ -151,7 +145,7 @@ func getMenuOptions(sync bool, updateAvailable bool, client *kube.Client, log *l

var clusterSubMenu []*astilectron.MenuItemOptions
for _, context := range contexts {
item := createClusterMenuItem(context, sync, client, log)
item := createClusterMenuItem(context, log)
clusterSubMenu = append(clusterSubMenu, &item)
}

Expand Down Expand Up @@ -246,6 +240,22 @@ func getMenuOptions(sync bool, updateAvailable bool, client *kube.Client, log *l
{
Label: astikit.StrPtr("Discovery and Load Balancing"),
SubMenu: []*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Endpoints"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Debugf("Menu item 'Endpoint' has been clicked")
messageChannel <- Message{Event: "navigation", Data: "/resources/discovery-and-loadbalancing/endpoints"}
return
},
},
{
Label: astikit.StrPtr("Horizontal Pod Autoscalers"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Debugf("Menu item 'Horizontal Pod Autoscalers' has been clicked")
messageChannel <- Message{Event: "navigation", Data: "/resources/discovery-and-loadbalancing/horizontalpodautoscalers"}
return
},
},
{
Label: astikit.StrPtr("Ingresses"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
Expand All @@ -254,6 +264,14 @@ func getMenuOptions(sync bool, updateAvailable bool, client *kube.Client, log *l
return
},
},
{
Label: astikit.StrPtr("Network Policies"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Debugf("Menu item 'Network Policies' has been clicked")
messageChannel <- Message{Event: "navigation", Data: "/resources/discovery-and-loadbalancing/networkpolicies"}
return
},
},
{
Label: astikit.StrPtr("Services"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
Expand Down Expand Up @@ -307,6 +325,14 @@ func getMenuOptions(sync bool, updateAvailable bool, client *kube.Client, log *l
return
},
},
{
Label: astikit.StrPtr("Storage Classes"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Debugf("Menu item 'Storage Classes' has been clicked")
messageChannel <- Message{Event: "navigation", Data: "/resources/config-and-storage/storageclasses"}
return
},
},
},
},
{
Expand All @@ -324,7 +350,7 @@ func getMenuOptions(sync bool, updateAvailable bool, client *kube.Client, log *l
Label: astikit.StrPtr("Cluster Role Bindings"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Debugf("Menu item 'Cluster Role Bindings' has been clicked")
messageChannel <- Message{Event: "navigation", Data: "/resources/rbac/clusterrolebinding"}
messageChannel <- Message{Event: "navigation", Data: "/resources/rbac/clusterrolebindings"}
return
},
},
Expand Down
54 changes: 35 additions & 19 deletions src/components/menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import {
IonToolbar,
isPlatform,
} from '@ionic/react';
import React, { memo } from 'react';
import React, { memo, useContext } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';

import { IAppSections } from '../../declarations';
import { IAppSections, IContext } from '../../declarations';
import { CUSTOM_URI_SCHEME, GOOGLE_REDIRECT_URI, OIDC_REDIRECT_URL, SERVER } from '../../utils/constants';
import { saveCluster } from '../../utils/storage';
import { AppContext } from '../../utils/context';
import Clusters from './Clusters';
import Sections from './Sections';

Expand All @@ -32,26 +32,42 @@ App.addListener('appUrlOpen', (data) => {
}
});

if (isPlatform('electron')) {
const eventSource = new EventSource(`${SERVER}/api/electron`);

eventSource.addEventListener('navigation', (event) => {
const msg = event as MessageEvent;
window.location.href = msg.data;
});

eventSource.addEventListener('cluster', (event) => {
const msg = event as MessageEvent;
saveCluster(msg.data);
window.location.href = '/';
});
}

interface IMenuProps extends RouteComponentProps {
sections: IAppSections;
}

const Menu: React.FunctionComponent<IMenuProps> = ({ sections }: IMenuProps) => {
const Menu: React.FunctionComponent<IMenuProps> = ({ sections, history, location }: IMenuProps) => {
const context = useContext<IContext>(AppContext);

if (isPlatform('electron')) {
const eventSource = new EventSource(`${SERVER}/api/electron`);

eventSource.addEventListener('navigation', async (event) => {
const msg = event as MessageEvent;
history.push(msg.data);
});

eventSource.addEventListener('cluster', async (event) => {
const path = location.pathname;
const msg = event as MessageEvent;

// This must be the same as the changeCluster function in the Clusters.tsx file.
await context.changeCluster(msg.data);

if (path.startsWith('/resources')) {
const parts = path.split('/');
if (parts.length > 4) {
history.push(parts.slice(0, 4).join('/'));
}
} else if (path.startsWith('/customresources')) {
const parts = path.split('/');
if (parts.length > 5) {
history.push(parts.slice(0, 5).join('/'));
}
}
});
}

return (
<IonMenu contentId="main" type="overlay">
<IonHeader>
Expand Down