glass-app-manager
Version:
Informatica's Glass Framework CLI for bootstrapping
266 lines (237 loc) • 8.08 kB
JavaScript
import React, { Component } from "react";
import { Shell } from "@informatica/droplets-core";
import { NavLink, withRouter } from "react-router-dom";
import { Route, Switch, Redirect } from "react-router-dom";
import { GlassContext as Context } from "glass-core";
import Constants from "./lib/Constants";
class GlassRoutes extends Component {
consumerNavLinks = [];
consumerRoutes = [];
workspaceMap = {}; //holds workspaceName: workspaceConfig
/* Params workspaceName ,url, instanceId are mandatory to open asset workspace */
openWorkspace(workspaceName, url, instanceId, params) {
let workspaceObject = this.workspaceMap[workspaceName];
//If workspacename specified is incorrect
if (!workspaceObject) {
// throw error;
console.error(
`The workspace with Name:"${workspaceName}" is not registered.Please specify the correct name.`
);
}
if (workspaceObject.type === "asset") {
if (!url) {
//throw error
console.error(
`Please pass the URL to open asset workspace --${workspaceName}`
);
return;
}
if (
instanceId === undefined ||
instanceId === null ||
instanceId === ""
) {
//throw error
console.error(
`Please pass the instanceID to open asset workspace-- ${workspaceName}`
);
return;
}
let workspaceConfigWithParams = {
...workspaceObject,
...params,
...{ path: url }
};
this.updateState(workspaceConfigWithParams, instanceId);
} else if (workspaceObject.type === "fixed") {
url = url ? url : workspaceObject.path;
}
this.props.history.push(url);
}
updateState(workspaceConfigWithParams, instanceId) {
this.setState(prevState => {
let assetWKSKey = `${workspaceConfigWithParams.name}_${instanceId}`;
let temporaryWorkspaces = Object.assign(
{},
prevState.openedTemporaryWorkspaces
);
temporaryWorkspaces[assetWKSKey] = workspaceConfigWithParams;
return {
openedTemporaryWorkspaces: temporaryWorkspaces
};
});
}
constructor(props) {
super(props);
this.state = {
openedTemporaryWorkspaces: {}
};
let platformWorkspaces = React.Children.toArray(props.children);
this.preparePlatformRoutesAndNavLinks(platformWorkspaces);
//plugins supported by platform Configuration
let pluginsList = [];
if (window.GLASS_UI_CONFIG) {
pluginsList = window.GLASS_UI_CONFIG.plugins;
}
pluginsList.forEach(pluginObj => {
let pluginName = pluginObj;
// If the plugin is not enabled in platform, return
// if (!pluginObj[pluginName].enabled) {
// return;
// }
let pluginConfiguration = window.GLASS_UI_CONFIG[pluginName];
// if pluginConfiguration does not exists, return
//If plugin is not enabled from product side, return
if (
!pluginConfiguration ||
(pluginConfiguration && !pluginConfiguration.enabled)
) {
return;
}
//Is the Product bundle available ?
if (
!window.GLASS ||
!window.GLASS.product ||
!window.GLASS.product[pluginName]
) {
return;
}
let productWorkspacesList = pluginConfiguration.extensions.pages;
let consumerObj = this.prepareConsumerRoutesAndNavLinks(
productWorkspacesList,
pluginName
);
this.consumerNavLinks = this.consumerNavLinks.concat(consumerObj.navList);
this.consumerRoutes = this.consumerRoutes.concat(consumerObj.routeList);
});
}
getRouteJSX = config => {
let ComponentName = config.component;
return (
<Route
key={config.name}
path={config.path}
render={props => <ComponentName {...props} {...config} />}
/>
);
};
getNavLinkJSX = config => {
return (
<Shell.Nav.NavLink
key={config.name}
as={NavLink}
label={config.label}
icon={<img src={config.icon} alt="" />}
to={`${config.path}`}
/>
);
};
prepareConsumerRoutesAndNavLinks = (productWorkspacesList, productName) => {
let consumerNavLinks = [];
let consumerRoutes = [];
productWorkspacesList.forEach(componentName => {
let Comp = window.GLASS.product[productName][componentName];
// Is Component available in bundle
if (Comp) {
let configObj = { ...Comp.workspaceConfig };
configObj.component = Comp;
configObj.productName = productName;
let isWorkspaceValid = this.validateAndRegisterWorkspace(configObj);
if (isWorkspaceValid) {
if (configObj.type === "fixed") {
consumerNavLinks.push(this.getNavLinkJSX(configObj));
}
consumerRoutes.push(this.getRouteJSX(configObj));
if (configObj.isDefault) {
this.defaultRedirect = <Redirect from="/" to={`${configObj.path}`} />;
}
}
}
});
return {
navList: consumerNavLinks,
routeList: consumerRoutes
};
};
//workspaceName should start with the productName.
validateAndRegisterWorkspace = configObj => {
let workspaceName = configObj.name;
let productName = configObj.productName;
let path = configObj.path;
if (!workspaceName.startsWith(configObj.productName)) {
//throw error
console.error(
`Workspacename ${workspaceName} does not start with the productname ${
configObj.productName
}.Hence the workspace could not be registered.`
);
return false;
}
//If workspace path does not start with product name
if (!path.startsWith(`/${productName}`)) {
//throw error
console.error(
`Workspace path ${path} does not start with the productname /${
configObj.productName
}.Hence the workspace could not be registered.`
);
return false;
}
//Workspace already exists with the same name within the same product
if (this.workspaceMap[workspaceName]) {
//throw error
console.error(
`Workspacename ${workspaceName} already exists.Hence the workspace could not be registered.`
);
return false;
}
this.workspaceMap[workspaceName] = configObj;
return true;
};
preparePlatformRoutesAndNavLinks(list) {
let platformNavlinks = [];
let platformRoutesList = [];
list.forEach(child => {
let config = child.props;
config.productName = Constants.uniqueProductName;
let isWorkspaceValid = this.validateAndRegisterWorkspace(config);
//Proceed only if workspace is valid
if (isWorkspaceValid) {
if (config.type === "fixed") {
platformNavlinks.push(this.getNavLinkJSX(config));
}
platformRoutesList.push(this.getRouteJSX(config));
if (config.isDefault) {
this.defaultRedirect = <Redirect from="/" to={`${config.path}`} />;
}
}
});
this.platformNavLinks = platformNavlinks;
this.platformRoutesList = platformRoutesList;
}
render() {
return (
<React.Fragment>
<Shell.Nav>
{this.platformNavLinks}
{this.consumerNavLinks}
{Object.values(this.state.openedTemporaryWorkspaces).map(config =>
this.getNavLinkJSX(config)
)}
</Shell.Nav>
<Context.Provider
value={{ openWorkspace: this.openWorkspace.bind(this) }}
>
<Shell.Main>
<Switch>
{this.platformRoutesList}
{this.consumerRoutes}
{this.defaultRedirect}
</Switch>
</Shell.Main>
</Context.Provider>
</React.Fragment>
);
}
}
export default withRouter(GlassRoutes);