| // 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. |
| |
| define([ |
| 'app', |
| 'api', |
| 'react', |
| 'addons/documents/index-results/stores', |
| 'addons/documents/index-results/actions', |
| 'addons/components/react-components.react', |
| 'addons/documents/resources', |
| |
| 'plugins/prettify' |
| ], |
| |
| function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) { |
| var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; |
| var store = Stores.indexResultsStore; |
| var BulkActionComponent = Components.BulkActionComponent; |
| |
| var NoResultScreen = React.createClass({ |
| render: function () { |
| return ( |
| <div className="watermark-logo"> |
| <h3>{this.props.text}</h3> |
| </div> |
| ); |
| } |
| }); |
| |
| var TableRow = React.createClass({ |
| propTypes: { |
| docIdentifier: React.PropTypes.string.isRequired, |
| docChecked: React.PropTypes.func.isRequired, |
| isSelected: React.PropTypes.bool.isRequired, |
| index: React.PropTypes.number.isRequired, |
| data: React.PropTypes.object.isRequired |
| }, |
| |
| onChange: function (e) { |
| this.props.docChecked(this.props.docIdentifier, this.props.data, e); |
| }, |
| |
| getInitialState: function () { |
| return { |
| checked: this.props.isSelected |
| }; |
| }, |
| |
| getRowContents: function (element, rownumber) { |
| var row = this.props.schema.map(function (k, i) { |
| var el = element.content; |
| var key = 'tableview-data-cell-' + rownumber + k + i + el[k]; |
| var stringified = typeof el[k] === 'object' ? JSON.stringify(el[k]) : el[k]; |
| var className = k === '_id' ? 'tableview-data-cell-id' : null; |
| |
| return ( |
| <td className={className} key={key} title={stringified}> |
| {k === '_id' ? this.maybeGetUrl(element.url, stringified) : stringified} |
| </td> |
| ); |
| }.bind(this)); |
| |
| return row; |
| }, |
| |
| maybeGetUrl: function (url, stringified) { |
| if (!url) { |
| return stringified; |
| } |
| |
| return ( |
| <a href={url}> |
| {stringified} |
| </a> |
| ); |
| }, |
| |
| maybeGetCheckboxCell: function (i) { |
| if (!this.props.data.isDeletable) { |
| return <td className="tableview-checkbox-cell" key={"tableview-checkbox-cell-" + i}></td>; |
| } |
| |
| return ( |
| <td className="tableview-checkbox-cell" key={"tableview-checkbox-cell-" + i}> |
| <input |
| id={"checkbox-" + this.props.docIdentifier} |
| checked={this.props.isSelected} |
| type="checkbox" |
| onChange={this.onChange} /> |
| </td> |
| ); |
| }, |
| |
| render: function () { |
| var i = this.props.index; |
| |
| return ( |
| <tr key={"tableview-content-row-" + i}> |
| {this.maybeGetCheckboxCell(i)} |
| {this.getRowContents(this.props.data, i)} |
| </tr> |
| ); |
| } |
| }); |
| |
| var TableView = React.createClass({ |
| getContentRows: function () { |
| var data = this.props.data.results; |
| var schema = this.props.data.schema; |
| |
| var res = data.map(function (el, i) { |
| |
| return ( |
| <TableRow |
| key={"tableview-row-component-" + i} |
| isListDeletable={this.props.isListDeletable} |
| index={i} |
| data={el} |
| docId={el.id} |
| docIdentifier={el.id || "tableview-row-component-" + i} |
| docChecked={this.props.docChecked} |
| isSelected={this.props.isSelected(el.id)} |
| schema={schema} /> |
| ); |
| }.bind(this)); |
| |
| return res; |
| }, |
| |
| getHeader: function () { |
| var row = this.props.data.schema.map(function (el, i) { |
| return <th key={"header-el-" + i} title={el}>{el}</th>; |
| }); |
| |
| var box = null; |
| |
| if (this.props.isListDeletable) { |
| box = (<th className="tableview-header-el-checkbox" key="tableview-header-el-checkbox"></th>); |
| } |
| |
| return ( |
| <tr key="tableview-content-row-header"> |
| {box} |
| {row} |
| </tr> |
| ); |
| }, |
| |
| render: function () { |
| var header = this.getHeader(); |
| var contentRows = this.getContentRows(); |
| |
| return ( |
| <table className="table table-striped table-view-docs"> |
| <thead> |
| {header} |
| </thead> |
| <tbody> |
| {contentRows} |
| </tbody> |
| </table> |
| ); |
| } |
| }); |
| |
| |
| var ResultsScreen = React.createClass({ |
| |
| onDoubleClick: function (id, doc) { |
| FauxtonAPI.navigate(doc.url); |
| }, |
| |
| getUrlFragment: function (url) { |
| if (!this.props.isEditable) { |
| return null; |
| } |
| |
| return ( |
| <a href={url}> |
| <i className="fonticon-pencil"></i> |
| </a>); |
| }, |
| |
| getDocumentList: function () { |
| var noop = function () {}; |
| var data = this.props.results.results; |
| |
| return _.map(data, function (doc, i) { |
| return ( |
| <Components.Document |
| key={doc.id + i} |
| doc={doc} |
| onDoubleClick={this.props.isEditable ? this.onDoubleClick : noop} |
| keylabel={doc.keylabel} |
| docContent={doc.content} |
| checked={this.props.isSelected(doc.id)} |
| header={doc.header} |
| docChecked={this.props.docChecked} |
| isDeletable={doc.isDeletable} |
| docIdentifier={doc.id} > |
| {doc.url ? this.getUrlFragment('#' + doc.url) : doc.url} |
| </Components.Document> |
| ); |
| }, this); |
| }, |
| |
| getDocumentStyleView: function (loadLines) { |
| var classNames = 'view'; |
| |
| if (this.props.isListDeletable) { |
| classNames += ' show-select'; |
| } |
| |
| return ( |
| <div className={classNames}> |
| {loadLines} |
| |
| |
| <div id="doc-list"> |
| <ReactCSSTransitionGroup transitionName="slow-fade"> |
| {this.getDocumentList()} |
| </ReactCSSTransitionGroup> |
| </div> |
| </div> |
| ); |
| }, |
| |
| getTableStyleView: function (loadLines) { |
| return ( |
| <div> |
| <TableView |
| docChecked={this.props.docChecked} |
| isSelected={this.props.isSelected} |
| isListDeletable={this.props.isListDeletable} |
| data={this.props.results} /> |
| </div> |
| ); |
| }, |
| |
| render: function () { |
| |
| var loadLines = null; |
| var isTableView = this.props.isTableView; |
| |
| if (this.props.isLoading) { |
| loadLines = <Components.LoadLines />; |
| } |
| |
| var mainView = isTableView ? this.getTableStyleView(loadLines) : this.getDocumentStyleView(loadLines); |
| return ( |
| <div className="document-result-screen"> |
| {this.props.isListDeletable ? <BulkActionComponent |
| removeItem={this.props.removeItem} |
| isChecked={this.props.allDocumentsSelected} |
| hasSelectedItem={this.props.hasSelectedItem} |
| selectAll={this.selectAllDocs} |
| toggleSelect={this.toggleSelectAll} |
| title="Select all docs that can be..." /> : null} |
| {mainView} |
| </div> |
| ); |
| }, |
| |
| selectAllDocs: function () { |
| Actions.selectAllDocuments(); |
| }, |
| |
| toggleSelectAll: function () { |
| Actions.toggleAllDocuments(); |
| }, |
| |
| componentDidMount: function () { |
| prettyPrint(); |
| }, |
| |
| componentDidUpdate: function () { |
| prettyPrint(); |
| }, |
| |
| }); |
| |
| |
| |
| var ViewResultListController = React.createClass({ |
| getStoreState: function () { |
| return { |
| hasResults: store.hasResults(), |
| results: store.getResults(), |
| selectedItems: store.getSelectedItems(), |
| isLoading: store.isLoading(), |
| isEditable: store.isEditable(), |
| textEmptyIndex: store.getTextEmptyIndex(), |
| isTableView: store.getIsTableView(), |
| |
| canDeselectAll: store.canDeselectAll(), |
| canSelectAll: store.canSelectAll(), |
| allDocumentsSelected: store.areAllDocumentsSelected(), |
| hasSelectedItem: !!store.getSelectedItemsLength() |
| }; |
| }, |
| |
| isSelected: function (id) { |
| return !!this.state.selectedItems[id]; |
| }, |
| |
| removeItem: function () { |
| Actions.deleteSelected(); |
| }, |
| |
| getInitialState: function () { |
| return this.getStoreState(); |
| }, |
| |
| componentDidMount: function () { |
| store.on('change', this.onChange, this); |
| }, |
| |
| componentWillUnmount: function () { |
| store.off('change', this.onChange); |
| }, |
| |
| onChange: function () { |
| this.setState(this.getStoreState()); |
| }, |
| |
| docChecked: function (id) { |
| Actions.selectDoc(id); |
| }, |
| |
| render: function () { |
| var view = <NoResultScreen text={this.state.textEmptyIndex}/>; |
| |
| if (this.state.hasResults) { |
| view = <ResultsScreen |
| removeItem={this.removeItem} |
| hasSelectedItem={this.state.hasSelectedItem} |
| allDocumentsSelected={this.state.allDocumentsSelected} |
| canSelectAll={this.state.canSelectAll} |
| isSelected={this.isSelected} |
| isEditable={this.state.isEditable} |
| isListDeletable={this.state.results.hasDeletableDoc} |
| docChecked={this.docChecked} |
| isLoading={this.state.isLoading} |
| results={this.state.results} |
| isTableView={this.state.isTableView} />; |
| } |
| |
| return ( |
| view |
| ); |
| } |
| }); |
| |
| var Views = { |
| List: ViewResultListController, |
| ResultsScreen: ResultsScreen |
| }; |
| |
| return Views; |
| }); |