diff options
author | herbert <herbert.eiselt@highstreet-technologies.com> | 2019-12-14 01:05:47 +0100 |
---|---|---|
committer | Herbert Eiselt <herbert.eiselt@highstreet-technologies.com> | 2019-12-16 12:52:11 +0000 |
commit | e6d0d67fdbe3fc70c996c8df33bd65d3b151dfad (patch) | |
tree | 0d2da7d1da74c6ebca6b53039741617d35f65d96 /sdnr/wt/odlux/apps/helpApp/src | |
parent | 6b98928b7b1b0ebc28d2ef286e8c932fca67c305 (diff) |
update odlux and featureaggregator
v2 update odlux and featureaggregator bundles
Issue-ID: SDNC-1008
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
Change-Id: I0018d7bfa3a0e6896c1b210b539a574af9808e22
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/odlux/apps/helpApp/src')
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/actions/helpActions.ts | 78 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/components/helpStatus.tsx | 80 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/components/markdown.tsx | 77 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/components/tocEntry.tsx | 82 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts | 75 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/index.html | 29 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/models/tocNode.ts | 42 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/plugin.tsx | 91 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts | 65 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/utilities/path.ts | 79 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/views/helpApplication.tsx | 70 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/helpApp/src/views/helpTocApp.tsx | 55 |
12 files changed, 823 insertions, 0 deletions
diff --git a/sdnr/wt/odlux/apps/helpApp/src/actions/helpActions.ts b/sdnr/wt/odlux/apps/helpApp/src/actions/helpActions.ts new file mode 100644 index 000000000..3cebfd61d --- /dev/null +++ b/sdnr/wt/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/apps/helpApp/src/components/helpStatus.tsx b/sdnr/wt/odlux/apps/helpApp/src/components/helpStatus.tsx new file mode 100644 index 000000000..140935715 --- /dev/null +++ b/sdnr/wt/odlux/apps/helpApp/src/components/helpStatus.tsx @@ -0,0 +1,80 @@ +/** + * ============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 { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles'; +import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; // select app icon + +import connect, { Connect } from '../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; + +import Typography from '@material-ui/core/Typography'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; +import { withRouter, RouteComponentProps } from 'react-router'; + +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/apps/helpApp/src/components/markdown.tsx b/sdnr/wt/odlux/apps/helpApp/src/components/markdown.tsx new file mode 100644 index 000000000..a7137836e --- /dev/null +++ b/sdnr/wt/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/apps/helpApp/src/components/tocEntry.tsx b/sdnr/wt/odlux/apps/helpApp/src/components/tocEntry.tsx new file mode 100644 index 000000000..fc7b8dff5 --- /dev/null +++ b/sdnr/wt/odlux/apps/helpApp/src/components/tocEntry.tsx @@ -0,0 +1,82 @@ +/** + * ============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, makeStyles, Theme, createStyles } from "@material-ui/core" + +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 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 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 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/apps/helpApp/src/handlers/helpAppRootHandler.ts b/sdnr/wt/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts new file mode 100644 index 000000000..cc6a98488 --- /dev/null +++ b/sdnr/wt/odlux/apps/helpApp/src/handlers/helpAppRootHandler.ts @@ -0,0 +1,75 @@ +/** + * ============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 { TocTreeNode } from 'models/tocNode'; +import { IActionHandler } from '../../../../framework/src/flux/action'; +import { LoadTocAction, TocLoadedAction, LoadDocumentAction, DocumentLoadedAction } from '../actions/helpActions'; + +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/apps/helpApp/src/index.html b/sdnr/wt/odlux/apps/helpApp/src/index.html new file mode 100644 index 000000000..2344708c8 --- /dev/null +++ b/sdnr/wt/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/apps/helpApp/src/models/tocNode.ts b/sdnr/wt/odlux/apps/helpApp/src/models/tocNode.ts new file mode 100644 index 000000000..dbefeec77 --- /dev/null +++ b/sdnr/wt/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/apps/helpApp/src/plugin.tsx b/sdnr/wt/odlux/apps/helpApp/src/plugin.tsx new file mode 100644 index 000000000..50a264b15 --- /dev/null +++ b/sdnr/wt/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 * as React from "react"; +import { withRouter, RouteComponentProps, Route, Switch, Redirect } from 'react-router-dom'; + +import { faFirstAid } from '@fortawesome/free-solid-svg-icons'; // select app icon + +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 mapProps = (state: IApplicationStoreState) => ({ + +}); + +const mapDisp = (dispatcher: IDispatcher) => ({ + requestDocument: (path: string) => { + dispatcher.dispatch(requestDocumentAsyncActionCreator(path)); + } +}); + +let currentHelpPath: string | undefined = undefined; + +const HelpApplicationRouteAdapter = connect(mapProps, mapDisp)((props: RouteComponentProps<{ '0'?: string }> & Connect<typeof mapProps, typeof mapDisp>) => { + + 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: faFirstAid, + rootComponent: App, + rootActionHandler: helpAppRootHandler, + statusBarElement: HelpStatus, + menuEntry: "Help", + //subMenuEntry: SubMenuEntry + }); + + // start the initial toc request after the application store is initalized + const store = await applicationApi.applicationStoreInitialized; + store.dispatch(requestTocAsyncAction); + +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts b/sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts new file mode 100644 index 000000000..c8b247832 --- /dev/null +++ b/sdnr/wt/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); + } + return this.tocNodeCollection || null; + } +} + +export const helpService = new HelpService(); +export default helpService;
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/helpApp/src/utilities/path.ts b/sdnr/wt/odlux/apps/helpApp/src/utilities/path.ts new file mode 100644 index 000000000..412bdfb1e --- /dev/null +++ b/sdnr/wt/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/apps/helpApp/src/views/helpApplication.tsx b/sdnr/wt/odlux/apps/helpApp/src/views/helpApplication.tsx new file mode 100644 index 000000000..b4de26d50 --- /dev/null +++ b/sdnr/wt/odlux/apps/helpApp/src/views/helpApplication.tsx @@ -0,0 +1,70 @@ +/** + * ============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 { 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 +}); + +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 ? ( + <Markdown text={this.props.content} markedOptions={{ renderer: this.renderer }} className="markdown-body" + style={{ maxWidth: "960px", margin: "1.5em auto" }} /> + ) : (<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/apps/helpApp/src/views/helpTocApp.tsx b/sdnr/wt/odlux/apps/helpApp/src/views/helpTocApp.tsx new file mode 100644 index 000000000..65d4609e2 --- /dev/null +++ b/sdnr/wt/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 connect, { Connect, IDispatcher } from "../../../../framework/src/flux/connect"; + +import { NavigateToApplication } from "../../../../framework/src/actions/navigationActions"; +import * as React from 'react' +import { FunctionComponent } from "react"; +import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; +import TocEntry from "../components/tocEntry"; +import { Typography } from "@material-ui/core"; + +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 style={{ marginBottom: '30px' }} variant="h5"> + Help & 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 |