[881] | 1 | "use strict"; |
---|
| 2 | import React from 'react'; |
---|
| 3 | import { WidthProvider, Responsive} from 'react-grid-layout'; |
---|
| 4 | import _ from 'lodash'; |
---|
| 5 | |
---|
| 6 | const ResponsiveReactGridLayout = WidthProvider(Responsive); |
---|
| 7 | |
---|
| 8 | /** |
---|
| 9 | * Component holding all widgets of Framsticks-JS. It bases on 'react-grid-layout' |
---|
| 10 | * component, making it possible to create mini-windows within website. |
---|
| 11 | */ |
---|
| 12 | class WidgetsContainer extends React.Component { |
---|
| 13 | /** |
---|
| 14 | * Creates instance of WidgetsContainer. It starts in the beginning with no |
---|
| 15 | * items. To add items you need to explicitly call object method addItem |
---|
| 16 | * with React.Component. |
---|
| 17 | * @param {any} props Basic props for React Components |
---|
| 18 | */ |
---|
| 19 | constructor(props) { |
---|
| 20 | super(props); |
---|
| 21 | |
---|
| 22 | this.state = { |
---|
| 23 | items: [], |
---|
| 24 | widgetCounter: 0, |
---|
| 25 | }; |
---|
| 26 | this.props = props; |
---|
| 27 | //this.onAddItem = this.onAddItem.bind(this); |
---|
| 28 | this.onBreakpointChange = this.onBreakpointChange.bind(this); |
---|
| 29 | this.onLayoutChange = this.onLayoutChange.bind(this); |
---|
| 30 | } |
---|
| 31 | |
---|
| 32 | /** |
---|
| 33 | * Initializes references. |
---|
| 34 | */ |
---|
| 35 | componentDidMount() { |
---|
| 36 | this.props.onRef(this); |
---|
| 37 | } |
---|
| 38 | |
---|
| 39 | /** |
---|
| 40 | * Unmounts references |
---|
| 41 | */ |
---|
| 42 | componentWillUnmount() { |
---|
| 43 | this.props.onRef(void 0); |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | /** |
---|
| 47 | * Creates widgets in Framsticks-JS. It is strictly internal method for |
---|
| 48 | * this Component and should not be called outside. It is used in |
---|
| 49 | * render() function. It holds default styles for widgets windows. |
---|
| 50 | * @param {React.Component} el widget to be added to board |
---|
| 51 | * @returns {JSX.Element} new widget |
---|
| 52 | */ |
---|
| 53 | createElement(el) { |
---|
[911] | 54 | const headerStyle = { |
---|
[881] | 55 | right: "2px", |
---|
| 56 | marginRight: "10px", |
---|
| 57 | top: 0, |
---|
| 58 | cursor: "pointer", |
---|
| 59 | }; |
---|
| 60 | const content = el.content ? el.content : "none"; |
---|
| 61 | let gridStyle = { |
---|
| 62 | backgroundColor: '#AAAAAA', |
---|
| 63 | display: 'table', |
---|
| 64 | padding: 0, |
---|
| 65 | boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)" |
---|
| 66 | }; |
---|
| 67 | return ( |
---|
| 68 | <div key={el.i} data-grid={el} style={gridStyle}> |
---|
| 69 | {/* <span className="text" style={gridStyle}>{el.content}</span> */} |
---|
| 70 | <div style={{display: 'table-row', textAlign: 'right'}}> |
---|
| 71 | <span |
---|
[911] | 72 | className="header" |
---|
| 73 | style={headerStyle} |
---|
| 74 | > </span> |
---|
[881] | 75 | </div> |
---|
| 76 | <div style={{display: 'table-row', height: '100%'}}> |
---|
| 77 | {content} |
---|
| 78 | </div> |
---|
| 79 | </div> |
---|
| 80 | ); |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | /** |
---|
| 84 | * Adds new React.Component to Framsticks-JS board. This method should |
---|
| 85 | * be used externally instead of createElement to add new element. It |
---|
| 86 | * holds and remembers newly added components. |
---|
| 87 | * @param {React.Component} item new widget to be added to board |
---|
| 88 | * @param {string} name name of used component, useful for remembering layout |
---|
| 89 | * @param {number} x OX position of widget |
---|
| 90 | * @param {number} y OY position of widget |
---|
| 91 | * @param {number} w width of widget |
---|
| 92 | * @param {number} h height of widget |
---|
| 93 | * @example <caption>Example of using addItem with GenoChecker widget</caption> |
---|
| 94 | * this.widgetscontainer.addItem(<GenoChecker />); |
---|
| 95 | */ |
---|
| 96 | addItem(item, name, x=0, y=Infinity, w=2, h=2) { |
---|
| 97 | this.setState({ |
---|
| 98 | items: this.state.items.concat({ |
---|
| 99 | i: ""+this.state.widgetCounter+","+name, |
---|
| 100 | content: item, |
---|
| 101 | //x: (this.state.items.length) % (this.state.cols || 12), |
---|
| 102 | //y: Infinity, |
---|
| 103 | x: x, |
---|
| 104 | y: y, |
---|
| 105 | w: w, |
---|
| 106 | h: h |
---|
| 107 | }), |
---|
| 108 | widgetCounter: this.state.widgetCounter+1, |
---|
| 109 | }); |
---|
| 110 | } |
---|
| 111 | |
---|
| 112 | /** |
---|
| 113 | * Uses list of layout items to be distributed on site. |
---|
| 114 | * @param {any} layoutitems list of items. |
---|
| 115 | */ |
---|
| 116 | addMultipleItems(layoutitems) { |
---|
| 117 | this.setState({ |
---|
| 118 | items: layoutitems, |
---|
| 119 | widgetCounter: layoutitems.length |
---|
| 120 | }); |
---|
| 121 | } |
---|
| 122 | |
---|
| 123 | /** |
---|
| 124 | * Method implemented for responsive behaviour of 'react-grid-layout'. |
---|
| 125 | * @param {any} breakpoint new breakpoint for layout |
---|
| 126 | * @param {any} cols new number of columns in grid |
---|
| 127 | */ |
---|
| 128 | onBreakpointChange(breakpoint, cols) { |
---|
| 129 | this.setState({ |
---|
| 130 | breakpoint: breakpoint, |
---|
| 131 | cols: cols |
---|
| 132 | }); |
---|
| 133 | } |
---|
| 134 | |
---|
| 135 | /** |
---|
| 136 | * Event running on change of 'react-grid-layout' Component. |
---|
| 137 | * @param {any} layout layout which should be selected next |
---|
| 138 | */ |
---|
| 139 | onLayoutChange(layout) { |
---|
| 140 | if (this.props.onLayoutChange) this.props.onLayoutChange(layout); |
---|
| 141 | //this.props.onLayoutChange(layout); |
---|
| 142 | this.setState({layout: layout}); |
---|
| 143 | } |
---|
| 144 | |
---|
| 145 | /** |
---|
| 146 | * This events run on removing i-th item in 'react-grid-layout'. |
---|
| 147 | * @param {number} i id of item to be removed |
---|
| 148 | */ |
---|
| 149 | onRemoveItem(i) { |
---|
| 150 | this.setState({items: _.reject(this.state.items, {i:i})}); |
---|
| 151 | } |
---|
| 152 | |
---|
| 153 | /** |
---|
| 154 | * WidgetsContainer render method. |
---|
| 155 | * @returns {JSX.Element} WidgetsContainer |
---|
| 156 | */ |
---|
| 157 | render() { |
---|
| 158 | return ( |
---|
| 159 | <div> |
---|
| 160 | <ResponsiveReactGridLayout |
---|
| 161 | layout={this.state.layout} |
---|
| 162 | onLayoutChange={this.onLayoutChange} |
---|
| 163 | onBreakpointChange={this.onBreakpointChange} |
---|
| 164 | cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }} |
---|
[911] | 165 | rowHeight={150} |
---|
[881] | 166 | className="layout" |
---|
| 167 | {...this.props} |
---|
| 168 | > |
---|
| 169 | {_.map(this.state.items, el=>this.createElement(el))} |
---|
| 170 | </ResponsiveReactGridLayout> |
---|
| 171 | </div> |
---|
| 172 | ); |
---|
| 173 | } |
---|
| 174 | } |
---|
| 175 | |
---|
| 176 | export default WidgetsContainer; |
---|