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) { |
---|
54 | const headerStyle = { |
---|
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 |
---|
72 | className="header" |
---|
73 | style={headerStyle} |
---|
74 | > </span> |
---|
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 }} |
---|
165 | rowHeight={150} |
---|
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; |
---|