/* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ const React = require('react') const Pydio = require('pydio') const {Responsive, WidthProvider} = require('react-grid-layout'); const {PydioContextConsumer} = Pydio.requireLib('boot') import Store from './Store' import GridBuilder from './GridBuilder' /** * Automatic layout for presenting draggable cards to users. Used for user and admin dashboard. */ const CardsGrid = React.createClass({ /** * Save layouts in the users preference. * * @param {object} allLayouts Responsive layouts passed for saving */ saveFullLayouts:function(allLayouts){ const savedPref = this.props.store.getUserPreference('Layout'); // Compare JSON versions to avoid saving unnecessary changes if(savedPref && this.previousLayout  && this.previousLayout == JSON.stringify(allLayouts)){ return; } this.previousLayout = JSON.stringify(allLayouts); this.props.store.saveUserPreference('Layout', allLayouts); }, onLayoutChange: function(currentLayout, allLayouts){ if(this._blockLayoutSave) return; this.saveFullLayouts(allLayouts); }, componentWillUnmount: function(){ this.props.store.stopObserving("cards", this._storeObserver); }, componentWillReceiveProps: function(nextProps){ if(this.props && nextProps.editMode !== this.props.editMode){ Object.keys(this.refs).forEach(function(k){ this.refs[k].toggleEditMode(nextProps.editMode); }.bind(this)); } }, shouldComponentUpdate: function(nextProps, nextState){ return this._forceUpdate || false; }, getInitialState:function(){ this._storeObserver = function(e){ this._forceUpdate = true; this.setState({ cards: this.props.store.getCards() }, ()=>{this._forceUpdate = false}); }.bind(this); this.props.store.observe("cards", this._storeObserver); return {cards: this.props.store.getCards()} }, removeCard: function(itemKey){ this.props.removeCard(itemKey); }, buildCards: function(cards){ let index = 0; let layouts = {lg:[], md:[], sm:[], xs:[], xxs:[]}; let items = []; let additionalNamespaces = []; const rand = Math.random(); const savedLayouts = this.props.store.getUserPreference('Layout'); const buildLayout = function(classObject, itemKey, item, x, y){ let layout = classObject.getGridLayout(x, y); layout['handle'] = 'h4'; if(item['gridHandle']){ layout['handle'] = item['gridHandle']; } layout['i'] = itemKey; return layout; } cards.map(function(item){ var parts = item.componentClass.split("."); var classNS = parts[0]; var className = parts[1]; var classObject; if(global[classNS] && global[classNS][className]){ classObject = global[classNS][className]; }else{ if(!global[classNS]) { additionalNamespaces.push(classNS); } return; } var props = {...item.props}; var itemKey = props['key'] = item['id'] || 'item_' + index; props.ref=itemKey; props.pydio=this.props.pydio; props.onCloseAction = function(){ this.removeCard(itemKey); }.bind(this); props.preferencesProvider = this.props.store; var defaultX = 0, defaultY = 0; if(item.defaultPosition){ defaultX = item.defaultPosition.x; defaultY = item.defaultPosition.y; } const defaultLayout = buildLayout(classObject, itemKey, item, defaultX, defaultY); for(var breakpoint in layouts){ if(!layouts.hasOwnProperty(breakpoint))continue; var breakLayout = layouts[breakpoint]; // Find corresponding element in preference var existing; if(savedLayouts && savedLayouts[breakpoint]){ savedLayouts[breakpoint].map(function(gridData){ if(gridData['i'] == itemKey && gridData['h'] == defaultLayout['h']){ existing = gridData; } }); } if(existing) { breakLayout.push(existing); }else if(item.defaultLayouts && item.defaultLayouts[breakpoint]){ let crtLayout = buildLayout(classObject, itemKey, item, item.defaultLayouts[breakpoint].x, item.defaultLayouts[breakpoint].y); breakLayout.push(crtLayout); }else{ breakLayout.push(defaultLayout); } } index++; items.push(React.createElement(classObject, props)); }.bind(this)); if(additionalNamespaces.length){ this._blockLayoutSave = true; ResourcesManager.loadClassesAndApply(additionalNamespaces, function(){ this.setState({additionalNamespacesLoaded:additionalNamespaces}, function(){ this._blockLayoutSave = false; }.bind(this)); }.bind(this)); } return {cards: items, layouts: layouts}; }, render: function(){ const {cards, layouts} = this.buildCards(this.state.cards); const ResponsiveGridLayout = WidthProvider(Responsive); return ( {cards} ); } }); let DynamicGrid = React.createClass({ propTypes: { storeNamespace : React.PropTypes.string.isRequired, builderNamespaces: React.PropTypes.array, defaultCards : React.PropTypes.array, pydio : React.PropTypes.instanceOf(Pydio), disableDrag : React.PropTypes.bool }, removeCard:function(cardId){ this.state.store.removeCard(cardId); }, addCard:function(cardDefinition){ this.state.store.addCard(cardDefinition); }, resetCardsAndLayout:function(){ this.state.store.saveUserPreference('Layout', null); this.state.store.setCards(this.props.defaultCards); }, getInitialState: function(){ const store = new Store(this.props.storeNamespace, this.props.defaultCards, this.props.pydio); return{ editMode: false, store : store }; }, toggleEditMode:function(){ this.setState({editMode:!this.state.editMode}); }, render: function(){ const monitorWidgetEditing = function(status){ this.setState({widgetEditing:status}); }.bind(this); let builder; if(this.props.builderNamespaces && this.state.editMode){ builder = ( {return this.props.getMessage(id, ns)}} />); } const propStyle = this.props.style || {}; const rglStyle = this.props.rglStyle || {}; return (
{builder}
); } }); DynamicGrid = PydioContextConsumer(DynamicGrid) export {DynamicGrid as default}