summaryrefslogtreecommitdiffstats
path: root/sdnr/wt-odlux/odlux/apps/helpApp/src
diff options
context:
space:
mode:
authorRavi Pendurty <ravi.pendurty@highstreet-technologies.com>2023-12-07 22:45:28 +0530
committerRavi Pendurty <ravi.pendurty@highstreet-technologies.com>2023-12-07 22:46:39 +0530
commitdfd91573b7567e1dab482f17111ab8f809553d99 (patch)
tree8368580d1b1add9cfef5e8354ccf1080f27109b0 /sdnr/wt-odlux/odlux/apps/helpApp/src
parentbf8d701f85d02a140a1290d288adc7f437c1cc90 (diff)
Create wt-odlux directory
Include odlux apps, helpserver and readthedocs Issue-ID: CCSDK-3970 Change-Id: I1aee1327e7da12e8f658185b9a985a5204ad6065 Signed-off-by: Ravi Pendurty <ravi.pendurty@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt-odlux/odlux/apps/helpApp/src')
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/actions/helpActions.ts78
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/assets/icons/helpAppIcon.svg27
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/components/helpStatus.tsx83
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/components/markdown.tsx77
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/components/tocEntry.tsx85
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts76
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/index.html29
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/models/tocNode.ts42
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/plugin.tsx91
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/services/helpService.ts65
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/utilities/path.ts79
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpApplication.tsx84
-rw-r--r--sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpTocApp.tsx55
13 files changed, 871 insertions, 0 deletions
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/actions/helpActions.ts b/sdnr/wt-odlux/odlux/apps/helpApp/src/actions/helpActions.ts
new file mode 100644
index 000000000..3cebfd61d
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/actions/helpActions.ts
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../../../../framework/src/flux/action';
+import { Dispatch } from '../../../../framework/src/flux/store';
+
+import { TocTreeNode } from '../models/tocNode';
+import helpService from '../services/helpService';
+
+export class LoadTocAction extends Action {
+ constructor() {
+ super();
+
+ }
+}
+
+export class TocLoadedAction extends Action {
+ constructor(public toc?: TocTreeNode[], error?: string) {
+ super();
+
+ }
+}
+
+export const requestTocAsyncAction = async (dispatch: Dispatch) => {
+ dispatch(new LoadTocAction);
+ try {
+ const toc = await helpService.getTableOfContents();
+ if (toc) {
+ dispatch(new TocLoadedAction(toc));
+ } else {
+ dispatch(new TocLoadedAction(undefined, "Could not load TOC."));
+ }
+ } catch (err) {
+ dispatch(new TocLoadedAction(undefined, err));
+ }
+}
+
+export class LoadDocumentAction extends Action {
+ constructor() {
+ super();
+
+ }
+}
+
+export class DocumentLoadedAction extends Action {
+ constructor(public document?: string, public documentPath?: string, error?: string) {
+ super();
+
+ }
+}
+
+export const requestDocumentAsyncActionCreator = (path: string) => async (dispatch: Dispatch) => {
+ dispatch(new LoadDocumentAction);
+ try {
+ const doc = await helpService.getDocument(path);
+ if (doc) {
+ dispatch(new DocumentLoadedAction(doc, path));
+ } else {
+ dispatch(new DocumentLoadedAction(undefined, undefined, "Could not load document."));
+ }
+ } catch (err) {
+ dispatch(new DocumentLoadedAction(undefined, undefined, err));
+ }
+} \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/assets/icons/helpAppIcon.svg b/sdnr/wt-odlux/odlux/apps/helpApp/src/assets/icons/helpAppIcon.svg
new file mode 100644
index 000000000..298eaa162
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/assets/icons/helpAppIcon.svg
@@ -0,0 +1,27 @@
+<!-- highstreet technologies GmbH colour scheme
+ Grey #565656
+ LBlue #36A9E1
+ DBlue #246DA2
+ Green #003F2C / #006C4B
+ Yellw #C8D400
+ Red #D81036
+-->
+
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="310 250 400 400">
+
+<g transform="translate(0,1024) scale(0.1,-0.1)">
+
+<path fill="#565656" d="M4926 7634 c-126 -17 -209 -38 -318 -79 -79 -31 -195 -89 -208 -104
+-10 -12 -69 -51 -77 -51 -4 0 -42 -28 -83 -63 -227 -190 -375 -475 -375 -722
+0 -81 3 -95 30 -143 111 -201 365 -252 514 -103 46 46 88 124 121 226 28 87
+109 255 153 315 67 95 172 168 275 192 86 20 268 21 346 2 113 -28 152 -50
+240 -137 64 -63 88 -95 104 -137 49 -125 52 -225 12 -332 -38 -102 -132 -209
+-360 -409 -153 -134 -329 -309 -375 -374 -97 -136 -148 -274 -166 -448 -19
+-192 12 -305 104 -379 64 -50 141 -72 228 -65 82 7 125 24 177 71 49 45 73
+100 105 241 59 258 63 263 528 687 218 198 295 284 374 419 134 230 138 543 9
+803 -101 202 -252 349 -474 461 -246 124 -573 172 -884 129z"/>
+
+<path fill="#36A9E1" d="M 5098 4587 C 4582 4587 4582 3845 5098 3845 C 5614 3847 5614 4585 5098 4587 Z"/>
+
+</g>
+</svg>
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/components/helpStatus.tsx b/sdnr/wt-odlux/odlux/apps/helpApp/src/components/helpStatus.tsx
new file mode 100644
index 000000000..985b404a7
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/components/helpStatus.tsx
@@ -0,0 +1,83 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import React from 'react';
+import { withRouter, RouteComponentProps } from 'react-router';
+
+import { Theme } from '@mui/material/styles';
+import { WithStyles } from '@mui/styles';
+import withStyles from '@mui/styles/withStyles';
+import createStyles from '@mui/styles/createStyles';
+import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; // select app icon
+
+import Typography from '@mui/material/Typography';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
+
+import { connect, Connect } from '../../../../framework/src/flux/connect';
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
+
+const styles = (theme: Theme) => createStyles({
+ icon: {
+ marginLeft: 8,
+ marginRight: 8
+ },
+ disabled: {
+ color: theme.palette.grey[400]
+ },
+ link: {
+ cursor: "pointer",
+ '&:hover': {
+ textDecoration: "underline"
+ }
+ }
+});
+
+const mapProps = (state: IApplicationStoreState) => ({
+ appId: state.framework.applicationState.appId,
+ toc: state.help.toc
+});
+
+
+type HelpStatusComponentProps = & RouteComponentProps & WithStyles<typeof styles> & Connect<typeof mapProps>;
+
+class HelpStatusComponent extends React.Component<HelpStatusComponentProps> {
+ render() {
+ const { classes, history, toc, appId } = this.props;
+ const rootNode = toc && toc.find(t => t.id === "sdnr");
+ const helpNode = appId
+ ? rootNode && rootNode.nodes && rootNode.nodes.find(n => n.id === appId || n.id === appId + "App")
+ : rootNode;
+ return helpNode
+ ? (
+ <Typography variant="body1" color="inherit" className={classes.link} onClick={(event) => { event.stopPropagation(); history.push(`/help/${helpNode.uri}`) }} >
+ <FontAwesomeIcon className={classes.icon} icon={faQuestionCircle} />
+ Help
+ </Typography>
+ )
+ : (
+ <Typography variant="body1" className={classes.disabled}>
+ <FontAwesomeIcon className={classes.icon} icon={faQuestionCircle} />
+ Help
+ </Typography>
+ );
+ };
+
+}
+
+export const HelpStatus = withRouter(withStyles(styles)(connect(mapProps)(HelpStatusComponent) as any) as any);
+export default HelpStatus; \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/components/markdown.tsx b/sdnr/wt-odlux/odlux/apps/helpApp/src/components/markdown.tsx
new file mode 100644
index 000000000..a7137836e
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/components/markdown.tsx
@@ -0,0 +1,77 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+
+import * as marked from 'marked';
+import * as hljs from 'highlight.js';
+
+type MarkdownComponentProps = {
+ text: string;
+ className?: string;
+ markedOptions?: marked.MarkedOptions;
+ style?: React.CSSProperties
+}
+
+const defaultRenderer = new marked.Renderer();
+defaultRenderer.link = (href, title, text) => (
+ `<a target="_blank" rel="noopener noreferrer" href="${ href }" title="${ title }">${ text }</a>`
+);
+
+
+class MarkdownComponent extends React.Component<MarkdownComponentProps> {
+ constructor(props: MarkdownComponentProps) {
+ super(props);
+
+ const markedOptions: marked.MarkedOptions = {
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: true,
+ smartLists: true,
+ smartypants: false,
+ langPrefix: 'hljs ',
+ ...(this.props.markedOptions || {}),
+ highlight: (code, lang) => {
+ if (!!(lang && hljs.getLanguage(lang))) {
+ return hljs.highlight(lang, code).value;
+ }
+ return code;
+ }
+ };
+
+ marked.setOptions(markedOptions);
+ }
+ render() {
+ const { text, className, style } = this.props;
+
+
+ const html = (marked(text || '', { renderer: this.props.markedOptions && this.props.markedOptions.renderer || defaultRenderer }));
+
+ return (
+ <div
+ dangerouslySetInnerHTML={ { __html: html } }
+ className={ className }
+ style={ style }
+ />
+ );
+ }
+}
+
+export const Markdown = MarkdownComponent;
+
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/components/tocEntry.tsx b/sdnr/wt-odlux/odlux/apps/helpApp/src/components/tocEntry.tsx
new file mode 100644
index 000000000..295b3caf9
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/components/tocEntry.tsx
@@ -0,0 +1,85 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import * as React from "react"
+import { TocTreeNode } from "../models/tocNode"
+import { Typography, Link, Theme } from "@mui/material";
+
+import makeStyles from '@mui/styles/makeStyles';
+import createStyles from '@mui/styles/createStyles';
+
+const useStyles = makeStyles((theme: Theme) =>
+ createStyles({
+ link: {
+ color: "blue",
+ },
+ sublink: {
+ margin: theme.spacing(1),
+ color: "blue",
+ },
+ container: {
+ display: "flex",
+ flexDirection: "row",
+ flexWrap: "wrap",
+ }
+ }),
+);
+
+type tocEntryProps = {
+ label: string,
+ overviewUri: string,
+ nodes?: TocTreeNode[],
+ loadDocument(uri: string): any
+}
+
+const TocEntry: React.FunctionComponent<tocEntryProps> = (props) => {
+ const classes = useStyles();
+ const areNodesEmpty = !props.nodes || props.nodes.length === 0
+
+ const navigate = (event: React.SyntheticEvent, uri: string) => {
+ event.preventDefault();
+ event.stopPropagation();
+ props.loadDocument(uri);
+ }
+
+ return (<div>
+ {
+ areNodesEmpty ? <Typography variant="h6">
+ <Link underline="hover" onClick={(event: any) => navigate(event, props.overviewUri)} className={classes.link}> {props.label}</Link>
+ </Typography> :
+ <>
+ <Typography variant="h6">
+ {props.label}
+ </Typography>
+ <div className={classes.container}>
+ <Typography variant="body1">
+ <Link underline="hover" onClick={(event: any) => navigate(event, props.overviewUri)} className={classes.sublink}>Overview</Link>
+ </Typography>
+ {props.nodes !== undefined && props.nodes.map((item, index) =>
+ <Typography variant="body1" key={index + 'x' + item.id}>
+ <Link underline="hover" onClick={(event: any) => navigate(event, item.uri)} className={classes.sublink}>{item.label}</Link>
+ </Typography>
+ )}
+ </div>
+ </>
+ }
+ </div >)
+}
+
+
+export default TocEntry; \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts b/sdnr/wt-odlux/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts
new file mode 100644
index 000000000..29e07959a
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts
@@ -0,0 +1,76 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+// main state handler
+
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
+import { IActionHandler } from '../../../../framework/src/flux/action';
+
+import { LoadTocAction, TocLoadedAction, LoadDocumentAction, DocumentLoadedAction } from '../actions/helpActions';
+import { TocTreeNode } from '../models/tocNode';
+
+export interface IHelpAppStoreState {
+ busy: boolean;
+ toc: TocTreeNode[] | undefined;
+ content: string | undefined;
+ currentPath: string | undefined;
+}
+
+declare module '../../../../framework/src/store/applicationStore' {
+ interface IApplicationStoreState {
+ help: IHelpAppStoreState
+ }
+}
+
+const helpAppStoreStatcurrentPatheInit: IHelpAppStoreState = {
+ busy: false,
+ toc: undefined,
+ content: undefined,
+ currentPath: undefined
+};
+
+export const helpAppRootHandler: IActionHandler<IHelpAppStoreState> = (state = helpAppStoreStatcurrentPatheInit, action) => {
+ if (action instanceof LoadTocAction) {
+ state = {
+ ...state,
+ busy: true
+ };
+ } else if (action instanceof TocLoadedAction) {
+ state = {
+ ...state,
+ busy: false,
+ toc: action.toc
+ };
+ } else if (action instanceof LoadDocumentAction) {
+ state = {
+ ...state,
+ busy: true
+ };
+ } else if (action instanceof DocumentLoadedAction) {
+ state = {
+ ...state,
+ busy: false,
+ content: action.document,
+ currentPath: action.documentPath
+ };
+ }
+
+ return state;
+}
+
+
+export default helpAppRootHandler;
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/index.html b/sdnr/wt-odlux/odlux/apps/helpApp/src/index.html
new file mode 100644
index 000000000..2344708c8
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <!-- <link rel="stylesheet" href="./vendor.css"> -->
+ <title>Minimal App</title>
+</head>
+
+<body>
+ <div id="app"></div>
+ <script type="text/javascript" src="./require.js"></script>
+ <script type="text/javascript" src="./config.js"></script>
+ <script>
+ // run the application
+ require(["app", "helpApp"], function (app, helpApp) {
+ //connectApp.register();
+ //faultApp.register();
+ //configurationApp.register();
+ //maintenanceApp.register();
+ helpApp.register();
+ app("./app.tsx").runApplication();
+ });
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/models/tocNode.ts b/sdnr/wt-odlux/odlux/apps/helpApp/src/models/tocNode.ts
new file mode 100644
index 000000000..dbefeec77
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/models/tocNode.ts
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export type VersionInfo = {
+ label: string,
+ path: string,
+ date: string
+}
+
+export type TocNode = {
+ label: string;
+ versions: {
+ [versionKey: string]: VersionInfo,
+ current: VersionInfo
+ };
+ nodes?: TocNodeCollection;
+}
+
+export type TocNodeCollection = { [tocNodeKey: string]: TocNode };
+
+
+export type TocTreeNode = {
+ id: string;
+ label: string;
+ uri: string;
+ nodes?: TocTreeNode[];
+ disabled?: boolean;
+}
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/plugin.tsx b/sdnr/wt-odlux/odlux/apps/helpApp/src/plugin.tsx
new file mode 100644
index 000000000..5d860e530
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/plugin.tsx
@@ -0,0 +1,91 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+// app configuration and main entry point for the app
+
+import React from "react";
+import { withRouter, RouteComponentProps, Route, Switch, Redirect } from 'react-router-dom';
+
+import applicationManager from '../../../framework/src/services/applicationManager';
+import { IApplicationStoreState } from "../../../framework/src/store/applicationStore";
+import { connect, Connect, IDispatcher } from '../../../framework/src/flux/connect';
+
+import { requestTocAsyncAction, requestDocumentAsyncActionCreator } from "./actions/helpActions";
+import { helpAppRootHandler } from './handlers/helpAppRootHandler';
+
+import { HelpApplication } from './views/helpApplication';
+import { HelpStatus } from "./components/helpStatus";
+
+import '!style-loader!css-loader!highlight.js/styles/default.css';
+import HelpTocApp from "./views/helpTocApp";
+
+const appIcon = require('./assets/icons/helpAppIcon.svg'); // select app icon
+
+const mapProps = (state: IApplicationStoreState) => ({
+
+});
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ requestDocument: (path: string) => {
+ dispatcher.dispatch(requestDocumentAsyncActionCreator(path));
+ }
+});
+
+let currentHelpPath: string | undefined = undefined;
+
+const HelpApplicationRouteAdapter = connect(mapProps, mapDispatch)((props: RouteComponentProps<{ '0'?: string }> & Connect<typeof mapProps, typeof mapDispatch>) => {
+
+ if (currentHelpPath !== props.match.params["0"]) {
+ // route parameter has changed
+ currentHelpPath = props.match.params["0"] || undefined;
+ // Hint: This timeout is need, since it is not recommended to change the state while rendering is in progress !
+ window.setTimeout(() => {
+ if (currentHelpPath) {
+ props.requestDocument(currentHelpPath);
+ }
+ });
+ }
+
+ return (
+ <HelpApplication />
+ )
+});
+
+const App = withRouter((props: RouteComponentProps) => (
+ <Switch>
+ <Route exact path={`${props.match.path}/`} component={HelpTocApp} />
+ <Route path={`${props.match.path}/*`} component={HelpApplicationRouteAdapter} />
+ <Route path={`${props.match.path}`} component={HelpTocApp} />
+ </Switch>
+));
+
+export async function register() {
+ const applicationApi = applicationManager.registerApplication({
+ name: "help",
+ icon: appIcon,
+ rootComponent: App,
+ rootActionHandler: helpAppRootHandler,
+ statusBarElement: HelpStatus,
+ menuEntry: "Help",
+ //subMenuEntry: SubMenuEntry
+ });
+
+ // start the initial toc request after the application store is initialized
+ const store = await applicationApi.applicationStoreInitialized;
+ store.dispatch(requestTocAsyncAction);
+
+} \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/services/helpService.ts b/sdnr/wt-odlux/odlux/apps/helpApp/src/services/helpService.ts
new file mode 100644
index 000000000..728f243a0
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/services/helpService.ts
@@ -0,0 +1,65 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { requestRest } from '../../../../framework/src/services/restService';
+import { TocTreeNode, TocNodeCollection } from '../models/tocNode';
+
+class HelpService {
+
+ private tocNodeCollection: TocTreeNode[] | null = null;
+ private documents: { [path: string]: string | null } = {};
+
+ public async getDocument(path: string): Promise<string | null> {
+ // check if the result is allready in the cache
+ if (this.documents[path]) return Promise.resolve(this.documents[path]);
+
+ // request the document
+ const result = await requestRest<string>(`/help/${path}`.replace(/\/{2,}/i, '/'));
+ if (result) {
+ this.documents[path] = result;
+ }
+ return this.documents[path] || null;
+ }
+
+ public async getTableOfContents(): Promise<TocTreeNode[] | null> {
+ // check if the result is allready in the cache
+ if (this.tocNodeCollection) return Promise.resolve(this.tocNodeCollection);
+
+ // request the table of contents
+ const result = await requestRest<TocNodeCollection>('/help/?meta', undefined, false);
+ if (result !== null) {
+ const mapNodesCollection = (col: TocNodeCollection): TocTreeNode[] => {
+ return Object.keys(col).reduce<TocTreeNode[]>((acc, key) => {
+ const current = col[key];
+ acc.push({
+ id: key,
+ label: current.label,
+ uri: current.versions.current.path,
+ nodes: current.nodes && mapNodesCollection(current.nodes) || undefined
+ });
+ return acc;
+ }, []);
+ }
+
+ this.tocNodeCollection = result && mapNodesCollection(result) || null;
+ }
+ return this.tocNodeCollection || null;
+ }
+}
+
+export const helpService = new HelpService();
+export default helpService; \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/utilities/path.ts b/sdnr/wt-odlux/odlux/apps/helpApp/src/utilities/path.ts
new file mode 100644
index 000000000..412bdfb1e
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/utilities/path.ts
@@ -0,0 +1,79 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export const resolvePath = (...paths: string[]): string => {
+ function resolve(pathA: string, pathB: string) {
+ // ‘a’ => ['a']
+ // 'a/b' => ['a', 'b']
+ // '/a/b' => ['', 'a', 'b']
+ // '/a/b/' => ['', 'a', 'b', '']
+ const pathBParts = pathB.split('/');
+ if (pathBParts[0] === '') {
+ return pathBParts.join('/');
+ }
+ const pathAParts = pathA.split('/');
+ const aLastIndex = pathAParts.length - 1;
+ if (pathAParts[aLastIndex] !== '') {
+ pathAParts[aLastIndex] = '';
+ }
+
+ let part: string;
+ let i = 0;
+ while (typeof (part = pathBParts[i]) === 'string') {
+ switch (part) {
+ case '..':
+ pathAParts.pop();
+ pathAParts.pop();
+ pathAParts.push('');
+ break;
+ case '.':
+ pathAParts.pop();
+ pathAParts.push('');
+ break;
+ default:
+ pathAParts.pop();
+ pathAParts.push(part);
+ pathAParts.push('');
+ break;
+ }
+ i++;
+ }
+ if (pathBParts[pathBParts.length - 1] !== '') pathAParts.pop();
+ return pathAParts.join('/');
+ }
+
+ let i = 0;
+ let path: string;
+ let r = location.pathname;
+
+ const urlRegex = /^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i;
+ const multiSlashReg = /\/\/+/g;
+
+ while (typeof (path = paths[i]) === 'string') {
+ debugger;
+ const matches = path && path.match(urlRegex);
+ if (matches || !i) {
+ r = path;
+ } else {
+ path = path.replace(multiSlashReg, '/');
+ r = resolve(r, path);
+ }
+ i++;
+ }
+
+ return r;
+}; \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpApplication.tsx b/sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpApplication.tsx
new file mode 100644
index 000000000..5940517b4
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpApplication.tsx
@@ -0,0 +1,84 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import React from 'react';
+import * as marked from 'marked';
+
+import { resolvePath } from '../utilities/path';
+
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
+import { connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { Markdown } from "../components/markdown";
+
+import '!style-loader!css-loader!github-markdown-css/github-markdown.css'
+
+const mapProps = (state: IApplicationStoreState) => ({
+ content: state.help.content,
+ currentPath: state.help.currentPath
+});
+
+const containerStyle = {
+ overflow: "auto",
+ height: "100%",
+ width: "100%"
+};
+
+const styles = {
+ maxWidth: "960px",
+ margin: "1.5em auto",
+
+};
+
+type HelpApplicationComponentProps = Connect<typeof mapProps>;
+
+class HelpApplicationComponent extends React.Component<HelpApplicationComponentProps> {
+
+ /**
+ * Initializes a new instance.
+ */
+ constructor(props: HelpApplicationComponentProps) {
+ super(props);
+
+ this.renderer = new marked.Renderer();
+
+ this.renderer.link = (href: string, title: string, text: string) => {
+ // check if href is rel or abs
+ const absUrlMatch = href.trim().match(/^https?:\/\//i);
+ return `<a href="${absUrlMatch ? href : resolvePath('#/help/', this.props.currentPath || '/', href)}" title="${title}" >${text}</a>`
+ };
+
+ this.renderer.image = (href: string, title: string) => {
+ return `<img src="${resolvePath('/help/', this.props.currentPath || '/', href)}" alt="${title}" />`
+ };
+
+ }
+
+ render(): JSX.Element {
+ return this.props.content ? (
+ <div style={containerStyle}>
+ <Markdown text={this.props.content} markedOptions={{ renderer: this.renderer }} className="markdown-body"
+ style={styles} />
+ </div>
+ ) : (<h2>Loading ...</h2>)
+ }
+
+ private renderer: marked.Renderer;
+}
+
+export const HelpApplication = connect(mapProps)(HelpApplicationComponent);
+export default HelpApplication; \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpTocApp.tsx b/sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpTocApp.tsx
new file mode 100644
index 000000000..6a6a89123
--- /dev/null
+++ b/sdnr/wt-odlux/odlux/apps/helpApp/src/views/helpTocApp.tsx
@@ -0,0 +1,55 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import React from 'react'
+import {connect, Connect, IDispatcher } from "../../../../framework/src/flux/connect";
+
+import { NavigateToApplication } from "../../../../framework/src/actions/navigationActions";
+import { FunctionComponent } from "react";
+import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
+import TocEntry from "../components/tocEntry";
+import { Typography } from "@mui/material";
+
+const mapProps = (state: IApplicationStoreState) => ({
+ helpToc: state.help.toc,
+})
+
+const mapDisp = (dispatcher: IDispatcher) => ({
+ requestDocument: (uri: string) => dispatcher.dispatch(new NavigateToApplication("help", uri))
+});
+
+const HelpTocComponent: FunctionComponent<Connect<typeof mapProps, typeof mapDisp>> = (props) => {
+
+ return (
+ <div>
+ <Typography aria-label="help" style={{ marginBottom: '30px' }} variant="h5">
+ Help &amp; FAQ
+ </Typography>
+ <Typography style={{ marginBottom: '30px' }} variant="body1">
+ On our Help site, you can find general information about SDN-R, detailed information about our applications, frequently asked questions and a list of used abbreviations.
+ </Typography>
+ {
+ props.helpToc && props.helpToc.map((item, index) => <TocEntry key={index} overviewUri={item.uri} nodes={item.nodes} label={item.label} loadDocument={props.requestDocument} />)
+ }
+ </div>
+ )
+}
+
+export const HelpTocApp = connect(mapProps, mapDisp)(HelpTocComponent)
+
+export default HelpTocApp; \ No newline at end of file