blob: 92cdfdc927a197097f4711e0b84b6c94bd7e859d [file] [log] [blame]
// 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;
});