4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 import _includes
from 'lodash/includes'
22 import React
from 'react'
23 import ReactDOM
from 'react-dom'
24 import messages
from './messages'
25 import ClassNames
from 'classnames'
26 import UploadDropZone
from '../libraries/CatalogPackageManagerUploadDropZone'
27 import PureRenderMixin
from 'react-addons-pure-render-mixin'
28 import DropTarget
from './DropTarget'
29 import DropZonePanel
from './DropZonePanel'
30 import CatalogItems
from './CatalogItems'
31 import CatalogFilter
from './CatalogFilter'
32 import CatalogPanelTray
from './CatalogPanelTray'
33 import CatalogPanelToolbar
from './CatalogPanelToolbar'
34 import CatalogPackageManager
from './CatalogPackageManager'
35 import CatalogItemsActions
from '../actions/CatalogItemsActions'
36 import CatalogPanelTrayActions
from '../actions/CatalogPanelTrayActions'
37 import ComposerAppActions
from '../actions/ComposerAppActions'
38 import ComposerAppStore
from '../stores/ComposerAppStore'
39 import CatalogPanelStore
from '../stores/CatalogPanelStore'
40 import LoadingIndicator
from './LoadingIndicator'
41 import SelectionManager
from '../libraries/SelectionManager'
43 import '../styles/CatalogPanel.scss'
45 const createDropZone = function (action
, clickable
, dropTarget
) {
46 const dropZone
= new UploadDropZone(ReactDOM
.findDOMNode(dropTarget
), [clickable
], action
);
47 dropZone
.on('dragover', this.onDragOver
);
48 dropZone
.on('dragend', this.onDragEnd
);
49 dropZone
.on('addedfile', this.onFileAdded
);
53 const uiTransientState
= {
56 isDraggingFiles
: false,
60 const CatalogPanel
= React
.createClass({
61 mixins
: [PureRenderMixin
],
63 return CatalogPanelStore
.getState();
67 componentWillMount() {
70 CatalogPanelStore
.listen(this.onChange
);
71 document
.body
.addEventListener('dragover', this.onDragOver
);
72 document
.body
.addEventListener('dragend', this.onDragEnd
);
73 window
.addEventListener('dragend', this.onDragEnd
);
75 componentDidUpdate() {
77 componentWillUnmount() {
78 CatalogPanelStore
.unlisten(this.onChange
);
79 document
.body
.removeEventListener('dragover', this.onDragOver
);
80 document
.body
.removeEventListener('dragend', this.onDragEnd
);
81 window
.removeEventListener('dragend', this.onDragEnd
);
85 const onDropCatalogItem
= e
=> {
87 clearTimeout(uiTransientState
.timeoutId
);
88 uiTransientState
.isDragging
= false;
89 uiTransientState
.isDrop
= true;
90 const item
= JSON
.parse(e
.dataTransfer
.getData('text')).item
;
91 CatalogItemsActions
.exportSelectedCatalogItems(item
);
92 CatalogPanelTrayActions
.open();
95 const onDropUpdatePackage
= e
=> {
97 clearTimeout(uiTransientState
.timeoutId
);
98 uiTransientState
.isDragging
= false;
99 uiTransientState
.isDrop
= true;
100 CatalogPanelTrayActions
.open();
103 const onDropOnboardPackage
= e
=> {
105 clearTimeout(uiTransientState
.timeoutId
);
106 uiTransientState
.isDragging
= false;
107 uiTransientState
.isDrop
= true;
108 CatalogPanelTrayActions
.open();
111 const isDraggingItem
= uiTransientState
.isDragging
&& !uiTransientState
.isDraggingFiles
;
112 const isDraggingFiles
= uiTransientState
.isDragging
&& uiTransientState
.isDraggingFiles
;
113 const updateDropZone
= createDropZone
.bind(this, UploadDropZone
.ACTIONS
.update
, '.action-update-catalog-package');
114 const onboardDropZone
= createDropZone
.bind(this, UploadDropZone
.ACTIONS
.onboard
, '.action-onboard-catalog-package');
115 const className
= ClassNames('CatalogPanel', {'-is-tray-open': this.state
.isTrayOpen
});
116 const hasNoCatalogs
= this.props
.hasNoCatalogs
;
117 const isLoading
= this.props
.isLoading
;
119 <div className
={className
} data
-resizable
="right" data
-resizable
-handle
-offset
="0 6" style
={{width
: this.props
.layout
.left
}}>
120 <CatalogPanelToolbar
/>
121 <div className
="CatalogPanelBody">
125 <div className
="LoaderWrapper">
131 return messages
.catalogWelcome
;
135 <CatalogFilter filterByType
={this.props
.filterByType
} />
136 <CatalogItems filterByType
={this.props
.filterByType
} />
141 <CatalogPanelTray show
={this.state
.isTrayOpen
}>
142 <DropZonePanel show
={isDraggingItem
} title
="Drop catalog item to export.">
143 <DropTarget className
="action-export-catalog-items" onDrop
={onDropCatalogItem
}>
144 <span
>Export catalog item
.</span
>
147 <DropZonePanel show
={isDraggingFiles
}>
148 <DropTarget className
="action-onboard-catalog-package" dropZone
={onboardDropZone
} onDrop
={onDropOnboardPackage
}>
149 <span
>On
-board
new catalog
package.</span
>
151 <DropTarget className
="action-update-catalog-package" dropZone
={updateDropZone
} onDrop
={onDropUpdatePackage
}>
152 <span
>Update existing catalog
package.</span
>
155 <CatalogPackageManager
/>
162 this.setState(state
);
165 // NOTE do not call preventDefault here - see DropTarget
166 if (!uiTransientState
.isDragging
) {
167 uiTransientState
.isDrop
= false;
168 uiTransientState
.isDragging
= true;
169 uiTransientState
.wasTrayOpen
= this.state
.isTrayOpen
;
170 uiTransientState
.isDraggingFiles
= _includes(e
.dataTransfer
.types
, 'Files');
171 const dragState
= ComposerAppStore
.getState().drag
|| {};
172 if (uiTransientState
.isDraggingFiles
|| (dragState
.type
=== 'catalog-item')) {
173 CatalogPanelTrayActions
.open();
176 e
.dataTransfer
.dropEffect
= 'none';
177 // the drag-end event does not fire on drag events that originate
178 // outside of the browser, e.g. dragging files from desktop, so
179 // we use this debounced callback to simulate a drag-end event
180 clearTimeout(uiTransientState
.timeoutId
);
181 uiTransientState
.timeoutId
= setTimeout(() => {
186 clearTimeout(uiTransientState
.timeoutId
);
187 if (uiTransientState
.isDragging
) {
188 uiTransientState
.isDragging
= false;
189 if (uiTransientState
.isDrop
|| uiTransientState
.wasTrayOpen
) {
190 CatalogPanelTrayActions
.open();
192 CatalogPanelTrayActions
.close();
197 CatalogPanelTrayActions
.open();
201 export default CatalogPanel
;