summaryrefslogtreecommitdiffstats
path: root/src/generic-components/componentManager
diff options
context:
space:
mode:
authorARULNA <arul.nambi@amdocs.com>2017-06-02 16:27:25 -0400
committerARULNA <arul.nambi@amdocs.com>2017-06-02 16:33:14 -0400
commitca007e933bcd9f63aa77801656ed9dd4142c432c (patch)
treece97ed9df8c4fe48a524f0dc1365ad28acef7c46 /src/generic-components/componentManager
parent42b788b852f0604748828e9e325e4a0f01152c75 (diff)
Initial coomit for AAI-UI(sparky-fe)
Change-Id: I9f8482824a52bac431c100939899e760c0fa4fdb Signed-off-by: ARULNA <arul.nambi@amdocs.com>
Diffstat (limited to 'src/generic-components/componentManager')
-rw-r--r--src/generic-components/componentManager/ComponentManager.jsx311
-rw-r--r--src/generic-components/componentManager/ComponentManagerConstants.js33
-rw-r--r--src/generic-components/componentManager/ComponentManagerContainer.jsx115
3 files changed, 459 insertions, 0 deletions
diff --git a/src/generic-components/componentManager/ComponentManager.jsx b/src/generic-components/componentManager/ComponentManager.jsx
new file mode 100644
index 0000000..c1e95a4
--- /dev/null
+++ b/src/generic-components/componentManager/ComponentManager.jsx
@@ -0,0 +1,311 @@
+/*
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+import React, {Component} from 'react';
+
+import ComponentManagerContainer from
+ 'generic-components/componentManager/ComponentManagerContainer.jsx';
+import {
+ MIN_PANEL_WIDTH,
+ MIN_PANEL_HEIGHT,
+ MAX_PANEL_WIDTH,
+ EDIT_ICON,
+ LAYOUT_STATIC
+} from 'generic-components/componentManager/ComponentManagerConstants.js';
+
+var widthProvider = require('react-grid-layout').WidthProvider;
+var ReactGridLayout = require('react-grid-layout');
+ReactGridLayout = widthProvider(ReactGridLayout);
+
+export default class ComponentManager extends Component {
+ constructor(props) {
+ super(props);
+
+ if (props.layoutType === LAYOUT_STATIC &&
+ Object.keys(props.layoutFormat).length > 0) {
+ this.state = {
+ layout: props.layoutFormat.layout,
+ panels: props.layoutFormat.panels,
+ containers: props.layoutFormat.containers
+ };
+ } else {
+ this.state = {
+ layout: [],
+ panels: [],
+ containers: []
+ };
+ }
+ this.onLayoutChange = this.onLayoutChange.bind(this);
+ }
+
+ createContainer(
+ containerId, xPos, yPos, width, height, staticLayout = false) {
+ if (staticLayout) {
+ return {
+ id: containerId,
+ properties: {
+ x: xPos,
+ y: yPos,
+ w: width,
+ h: height,
+ isDraggable: false,
+ isResizable: false
+ }
+ };
+ } else {
+ return {
+ id: containerId,
+ properties: {
+ x: xPos,
+ y: yPos,
+ w: width,
+ h: height,
+ minW: MIN_PANEL_WIDTH,
+ maxW: MAX_PANEL_WIDTH,
+ minH: MIN_PANEL_HEIGHT
+ }
+ };
+ }
+ }
+
+ createPanel(id, title, panelSource, panelProps, actionList) {
+ return {
+ id: id,
+ title: title,
+ source: panelSource,
+ props: panelProps,
+ actions: actionList
+ };
+ }
+
+ addNewComponent(compProps, containingContainerId) {
+ let containerId = containingContainerId;
+ let actionsList = [];
+
+ if (typeof containerId === 'undefined' || containerId === null) {
+ // new component being added isn't associated with a
+ // container yet, so create one
+ containerId = 'container:' + (new Date).getTime();
+ let updatedContainerProps = [];
+ this.state.containers.forEach((containerProps) => {
+ updatedContainerProps.push(containerProps);
+ });
+ updatedContainerProps.push(
+ this.createContainer(containerId, 0, Infinity, 12, 2));
+ this.setState({containers: updatedContainerProps});
+
+ actionsList = [
+ {
+ type: 'close', id: containerId, callback: () => {
+ this.removeExistingComponent(containerId);
+ }
+ }
+ ];
+ } else {
+ // we are updating a static container with a new panel, add the edit
+ // action so it can be updated moving forward
+ actionsList = [
+ {
+ type: 'custom',
+ id: containingContainerId,
+ icon: EDIT_ICON,
+ callback: () => {
+ this.props.addPanelCallback(containingContainerId);
+ }
+ }
+ ];
+ }
+
+ let updatedPanelProps = [];
+ this.state.panels.forEach((panelProp) => {
+ if (panelProp.id !== containingContainerId) {
+ // add all existing panels except the one with a
+ // matching id (this is an edit scenario, will replace
+ // with new panel below
+ updatedPanelProps.push(panelProp);
+ }
+ });
+ updatedPanelProps.push(
+ this.createPanel(
+ containerId,
+ compProps.title,
+ compProps.visualizationSource,
+ compProps.visualizationProps,
+ actionsList));
+ this.setState({panels: updatedPanelProps});
+ }
+
+ removeExistingComponent(id) {
+ let updatedPanelProps = this.state.panels.filter((panelProp) => {
+ return id !== panelProp.id;
+ });
+ this.setState({panels: updatedPanelProps});
+
+ let updatedContainerProps = this.state.containers.filter(
+ (containerProp) => {
+ return id !== containerProp.id;
+ });
+ this.setState({containers: updatedContainerProps});
+ }
+
+ getLayoutProperties() {
+ return {
+ layout: this.state.layout,
+ containers: this.state.containers,
+ panels: this.state.panels
+ };
+ }
+
+ setLayoutProperties(layoutProperties) {
+ this.setState({
+ layout: layoutProperties.layout,
+ containers: layoutProperties.containers,
+ panels: layoutProperties.panels
+ });
+ }
+
+ fetchMatchingPanel(containerId) {
+ let actionsList = [];
+ let matchingPanel = (
+ <ComponentManagerContainer
+ showHeader={this.props.showHeader}
+ showTitle={this.props.showTitle}
+ showBorder={this.props.showBorder}
+ actions={actionsList}>
+ {'Please select a visualization'}
+ </ComponentManagerContainer>
+ );
+ this.state.panels.forEach((panel) => {
+ if (panel.id === containerId) {
+ let GeneratedComponent =
+ this.props.componentPropertiesProvider[panel.source].component.class;
+ let visProps = panel.props;
+ matchingPanel = (
+ <ComponentManagerContainer
+ showHeader={this.props.showHeader}
+ showTitle={this.props.showTitle}
+ showBorder={this.props.showBorder}
+ title={panel.title}
+ actions={panel.actions}>
+ <GeneratedComponent {...visProps}/>
+ </ComponentManagerContainer>
+ );
+ }
+ });
+ return matchingPanel;
+ }
+
+ preparedContainers() {
+ let containersToRender = [];
+
+ this.state.containers.forEach((container) => {
+ let matchingPanel = this.fetchMatchingPanel(container.id);
+
+ containersToRender.push(<div key={container.id}
+ data-grid={{...(container.properties)}}>
+ {matchingPanel}
+ </div>);
+ });
+
+ return containersToRender;
+ }
+
+ onLayoutChange(layout) {
+ this.setState({layout: layout});
+ this.props.onLayoutChange(layout);
+ }
+
+ buildStaticContainers(layoutFormat) {
+ let staticContainers = [];
+ let nextRowIndex = 0;
+
+ layoutFormat.layout.forEach((row) => {
+ let nextColIndex = 0;
+ let currentTallestContainer = 0;
+
+ row.forEach((col) => {
+ let containerId = 'container:' + nextRowIndex + '-' + nextColIndex;
+ let xPos = nextColIndex;
+ let yPos = nextRowIndex;
+ let width = 12 * col.width;
+ let height = col.height;
+
+ nextColIndex = nextColIndex + width;
+ currentTallestContainer = Math.max(currentTallestContainer, col.height);
+
+ staticContainers.push(
+ this.createContainer(
+ containerId,
+ xPos,
+ yPos,
+ width,
+ height,
+ true
+ )
+ );
+ });
+
+ nextRowIndex = currentTallestContainer;
+ });
+
+ return staticContainers;
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.layoutFormat !== this.props.layoutFormat) {
+ // layout format being passed in are the containers, panels and layout
+ // for the newly view
+ this.setState({
+ layout: nextProps.layoutFormat.layout,
+ panels: nextProps.layoutFormat.panels,
+ containers: nextProps.layoutFormat.containers
+ });
+ }
+ }
+
+ render() {
+
+ return (
+ <div className='component-manager'>
+ <ReactGridLayout
+ className='content app-components'
+ {...this.props}
+ onLayoutChange={this.onLayoutChange}
+ layout={this.state.layout}>
+ {this.preparedContainers()}
+ </ReactGridLayout>
+ </div>
+ );
+ }
+}
+ComponentManager.defaultProps = {
+ cols: 12,
+ rewHeight: 100,
+ onLayoutChange: function () {
+ },
+ showHeader: true,
+ showTitle: true,
+ showBorder: true
+};
diff --git a/src/generic-components/componentManager/ComponentManagerConstants.js b/src/generic-components/componentManager/ComponentManagerConstants.js
new file mode 100644
index 0000000..d7679f9
--- /dev/null
+++ b/src/generic-components/componentManager/ComponentManagerConstants.js
@@ -0,0 +1,33 @@
+/*
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+export const MIN_PANEL_WIDTH = 1;
+export const MIN_PANEL_HEIGHT = 1;
+export const MAX_PANEL_WIDTH = 12;
+
+export const EDIT_ICON = 'fa-pencil';
+
+export const LAYOUT_STATIC = 'static';
+export const LAYOUT_DYNAMIC = 'dynamic';
diff --git a/src/generic-components/componentManager/ComponentManagerContainer.jsx b/src/generic-components/componentManager/ComponentManagerContainer.jsx
new file mode 100644
index 0000000..0bf10f1
--- /dev/null
+++ b/src/generic-components/componentManager/ComponentManagerContainer.jsx
@@ -0,0 +1,115 @@
+/*
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+import React, {Component, PropTypes} from 'react';
+import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
+import Button from 'react-bootstrap/lib/Button';
+
+import i18n from 'utils/i18n/i18n';
+
+const ICON_CLASS_CLOSE = 'fa fa-times';
+
+export default class ComponentManagerContainer extends Component {
+
+ static propType = {
+ id: PropTypes.string,
+ title: PropTypes.string,
+ actions: PropTypes.array,
+ showHeader: PropTypes.bool,
+ showTitle: PropTypes.bool,
+ showBorder: PropTypes.bool,
+ };
+
+ static defaultProps = {
+ id: '',
+ title: 'Some Title',
+ actions: [],
+ showHeader: true,
+ showTitle: true,
+ showBorder: true
+ };
+
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ let {
+ title,
+ actions,
+ children,
+ showHeader,
+ showTitle,
+ showBorder
+ } = this.props;
+ let buttons = [];
+ actions.forEach((action) => {
+ switch (action.type) {
+ case 'close':
+ buttons.push(
+ <Button
+ type='submit'
+ key={action.type}
+ className='close-button'
+ onClick={ () => {
+ action.callback(action.id);
+ }}>
+ <i className={ICON_CLASS_CLOSE} aria-hidden='true'></i>
+ </Button>
+ );
+ break;
+ case 'custom':
+ buttons.push(
+ <Button
+ type='submit'
+ key={action.type}
+ className='custom-button'
+ onClick={action.callback}>
+ <i className={'fa ' + action.icon} aria-hidden='true'></i>
+ </Button>
+ );
+ break;
+ }
+ });
+
+ let containerClass = showBorder
+ ? 'titled-container titled-container-boarders'
+ : 'titled-container';
+ let headerClass = showHeader ? 'titled-container-header' : 'hidden';
+ let titleClass = showTitle ? '' : 'hidden';
+
+ return (
+ <div className={containerClass}>
+ <ButtonGroup>{buttons}</ButtonGroup>
+ <div className={headerClass}>
+ <span className={titleClass}>{i18n(title)}</span>
+ </div>
+ <div className='contents'>
+ {children}
+ </div>
+ </div>
+ );
+ }
+}