UNPKG

graft-react

Version:

react admin and helper components for graft-db

425 lines (424 loc) 22.5 kB
"use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; return { next: verb(0), "throw": verb(1), "return": verb(2) }; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var React = require("react"); var react_dom_1 = require("react-dom"); var graft_db_1 = require("graft-db"); var debounce = require("lodash.debounce"); var List_1 = require("react-md/lib/Lists/List"); var ListItem_1 = require("react-md/lib/Lists/ListItem"); var Buttons_1 = require("react-md/lib/Buttons"); var Toolbars_1 = require("react-md/lib/Toolbars"); var Autocompletes_1 = require("react-md/lib/Autocompletes"); var Avatars_1 = require("react-md/lib/Avatars"); var FontIcons_1 = require("react-md/lib/FontIcons"); var utils_1 = require("../utils"); var modal_1 = require("../modal"); var react_dnd_1 = require("react-dnd"); var WithClient_1 = require("./WithClient"); var Router_1 = require("./Router"); var edgeItemDragSource = { beginDrag: function (props) { var id = props.id, index = props.index; return { id: id, index: index }; }, endDrag: function (props, monitor, _component) { var onDoneReordering = props.onDoneReordering; if (!monitor.didDrop()) { onDoneReordering(false); return; } onDoneReordering(true); } }; var edgeItemTarget = { hover: function (props, monitor, component) { var dragIndex = monitor.getItem().index; var hoverIndex = props.index; if (dragIndex === hoverIndex) { return; } var hoverBoundingRect = react_dom_1.findDOMNode(component).getBoundingClientRect(); var hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; var clientOffset = monitor.getClientOffset(); var hoverClientY = clientOffset.y - hoverBoundingRect.top; if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { return; } if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { return; } var onReorder = props.onReorder; onReorder(dragIndex, hoverIndex); monitor.getItem().index = hoverIndex; } }; var EdgeItem = (function (_super) { __extends(EdgeItem, _super); function EdgeItem() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.remove = function (e) { e.preventDefault(); e.stopPropagation(); var _a = _this.props, id = _a.id, onRemove = _a.onRemove; onRemove(id); }; return _this; } EdgeItem.prototype.render = function () { var _a = this.props, id = _a.id, name = _a.name, onClick = _a.onClick, isDragging = _a.isDragging, dragSource = _a.dragSource, dropTarget = _a.dropTarget; var icon = dragSource(React.createElement("div", null, React.createElement(Avatars_1.default, { icon: React.createElement(FontIcons_1.default, null, "link") }))); var opacity = isDragging ? 0 : 1; var border = isDragging ? '5px dashed #eee' : 0; return dropTarget(React.createElement("div", { style: { border: border } }, React.createElement(ListItem_1.default, { leftAvatar: icon, key: id, primaryText: name, rightIcon: React.createElement(FontIcons_1.default, { onClick: this.remove }, "delete"), onClick: onClick, style: { opacity: opacity } }))); }; return EdgeItem; }(React.Component)); EdgeItem = __decorate([ react_dnd_1.DropTarget('edge', edgeItemTarget, function (connect) { return ({ dropTarget: connect.dropTarget() }); }), react_dnd_1.DragSource('edge', edgeItemDragSource, function (connect, monitor) { return ({ dragSource: connect.dragSource(), isDragging: monitor.isDragging() }); }) ], EdgeItem); exports.EdgeItem = EdgeItem; var EdgeProperty = (function (_super) { __extends(EdgeProperty, _super); function EdgeProperty() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var _this = _super.apply(this, args) || this; _this.save = debounce(function () { return __awaiter(_this, void 0, void 0, function () { var _this = this; var client, _a, object, property, _b, add, remove, orderedValues, values_1, e_1; return __generator(this, function (_c) { switch (_c.label) { case 0: client = this.context.client; _a = this.props, object = _a.object, property = _a.property; _b = this.state, add = _b.add, remove = _b.remove, orderedValues = _b.orderedValues; if (!add && !remove && !orderedValues) { return [2 /*return*/]; } if (!orderedValues && add && add.length === 0 && remove && remove.length === 0) { return [2 /*return*/]; } _c.label = 1; case 1: _c.trys.push([1, 3, , 4]); values_1 = this.getValues(); return [4 /*yield*/, client.update(function (b) { return __awaiter(_this, void 0, void 0, function () { var i, v, _i, add_1, v, _a, remove_1, id; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!orderedValues) return [3 /*break*/, 4]; i = 0; _b.label = 1; case 1: if (!(i < orderedValues.length)) return [3 /*break*/, 4]; v = orderedValues[i]; return [4 /*yield*/, b.set(v.id, { kind: graft_db_1.Kind.Value, owner: object.id, property: property.id, type: graft_db_1.ValueType.Object, key: v.objectValue.id, edge: property.edge, pos: i, })]; case 2: b = _b.sent(); _b.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: if (!add) return [3 /*break*/, 8]; _i = 0, add_1 = add; _b.label = 5; case 5: if (!(_i < add_1.length)) return [3 /*break*/, 8]; v = add_1[_i]; if (remove && remove.indexOf(v.id) > -1) { return [3 /*break*/, 7]; } return [4 /*yield*/, b.set(v.id, { kind: graft_db_1.Kind.Value, owner: object.id, property: property.id, type: graft_db_1.ValueType.Object, key: v.objectValue.id, edge: property.edge, pos: values_1.length - 1, })]; case 6: b = _b.sent(); _b.label = 7; case 7: _i++; return [3 /*break*/, 5]; case 8: if (!remove) return [3 /*break*/, 12]; _a = 0, remove_1 = remove; _b.label = 9; case 9: if (!(_a < remove_1.length)) return [3 /*break*/, 12]; id = remove_1[_a]; return [4 /*yield*/, b.delete(id)]; case 10: b = _b.sent(); _b.label = 11; case 11: _a++; return [3 /*break*/, 9]; case 12: return [2 /*return*/, b]; } }); }); })]; case 2: _c.sent(); this.setState({ add: [], remove: [], orderedValues: null }); return [3 /*break*/, 4]; case 3: e_1 = _c.sent(); console.error('failed to save EdgeProperty', e_1); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }, 750); _this.onChangeSearch = function (searchValue) { _this.setState({ searchValue: searchValue }); }; _this.showSearch = function () { _this.setState({ searching: true, searchValue: '' }); }; _this.resetSearch = function () { _this.setState({ searching: false, searchValue: '' }); }; _this.onSelectExisting = function (_, idx, matches) { var o = matches[idx]; if (o) { _this.add(o.id); } else { _this.resetSearch(); } }; _this.add = function (id) { var client = _this.context.client; var values = _this.getValues(); var v = { objectValue: { id: id }, id: client.generateId(), pos: values.length - 1 }; var add = [v].concat(_this.state.add || []); _this.setState({ add: add }, _this.save); }; _this.onRemove = function (id) { var remove = [id].concat(_this.state.remove); _this.setState({ remove: remove }, _this.save); }; _this.createAndLink = function () { return __awaiter(_this, void 0, void 0, function () { var _this = this; var client, _a, object, property, types, allowedTypes, type, _b, id; return __generator(this, function (_c) { switch (_c.label) { case 0: client = this.context.client; _a = this.props, object = _a.object, property = _a.property, types = _a.types; allowedTypes = types.filter(function (t) { return property.edgeTypes.indexOf(t.id) > -1; }); if (allowedTypes.length === 0) { throw new Error('no allowed types'); } if (!(allowedTypes.length > 1)) return [3 /*break*/, 2]; return [4 /*yield*/, modal_1.pickType(allowedTypes)]; case 1: _b = _c.sent(); return [3 /*break*/, 3]; case 2: _b = allowedTypes[0].id; _c.label = 3; case 3: type = _b; id = client.generateId(); return [4 /*yield*/, client.update(function (b) { return __awaiter(_this, void 0, void 0, function () { var values; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, b.set(id, { kind: graft_db_1.Kind.Object, type: type })]; case 1: b = _a.sent(); values = this.getValues(); return [4 /*yield*/, b.set(client.generateId(), { kind: graft_db_1.Kind.Value, owner: object.id, property: property.id, type: graft_db_1.ValueType.Object, key: id, edge: property.edge, pos: values.length - 1, })]; case 2: b = _a.sent(); return [2 /*return*/, b]; } }); }); })]; case 4: _c.sent(); return [2 /*return*/]; } }); }); }; _this.onReorder = function (fromIndex, toIndex) { var values = _this.getValues(); var vs = values.slice(); vs.splice(toIndex, 0, vs.splice(fromIndex, 1)[0]); var orderedValues = vs.map(function (v, idx) { return (__assign({}, v, { pos: idx })); }); _this.setState({ orderedValues: orderedValues }); }; _this.onDoneReordering = function (droppedInList) { if (!droppedInList) { _this.setState({ orderedValues: null }); } else { _this.save(); } }; _this.state = { orderedValues: null, searchValue: '', searching: false, add: [], remove: [] }; return _this; } EdgeProperty.prototype.getValues = function () { var _a = this.state, add = _a.add, remove = _a.remove, orderedValues = _a.orderedValues; if (orderedValues) { return orderedValues; } var values = this.props.values; var vs = (add || []).concat(values); if (remove && remove.length > 0) { vs = vs.filter(function (v) { return remove.indexOf(v.id) === -1; }); } return vs.sort(function (a, b) { return a.pos > b.pos ? 1 : b.pos > a.pos ? -1 : 0; }); }; EdgeProperty.prototype.render = function () { var _this = this; var navigator = this.context.navigator; var _a = this.props, property = _a.property, objects = _a.objects, types = _a.types; var _b = this.state, searching = _b.searching, searchValue = _b.searchValue; var values = this.getValues(); var items = values.map(function (v, idx) { var id = v.objectValue.id; var o = utils_1.find(objects, function (o) { return o.id === id; }); return (React.createElement(EdgeItem, { key: id, id: v.id, index: idx, name: o.name, onRemove: _this.onRemove, onReorder: _this.onReorder, onDoneReordering: _this.onDoneReordering, onClick: function () { return navigator.navigate('object', { id: id }); } })); }).filter(function (item) { return !!item; }); var nav = React.createElement(Buttons_1.default, { icon: true, disabled: true }, utils_1.propertyIconName(graft_db_1.PropertyType.Edge)); var children; var actions; var title; if (searching) { var selectedObjectIds_1 = values.map(function (v) { return v.objectValue.id; }); var filteredObjects = objects.filter(function (o) { if (property.edgeTypes && property.edgeTypes.length > 0) { if (!o.type) { return false; } if (property.edgeTypes.indexOf(o.type.id) === -1) { return false; } } if (selectedObjectIds_1.indexOf(o.id) > -1) { return false; } return true; }).map(function (_a) { var id = _a.id, name = _a.name; return ({ id: id, name: name }); }); var edgeNames = property.edgeTypes ? property.edgeTypes.map(function (id) { var t = utils_1.find(types, function (t) { return t.id === id; }); return t ? t.name : ''; }).join(',') : 'object'; children = React.createElement(Autocompletes_1.default, { block: true, id: 'search', placeholder: "Search for " + edgeNames + "...", paddedBlock: false, data: filteredObjects, dataLabel: 'name', dataValue: 'id', value: searchValue, onAutocomplete: this.onSelectExisting, onChange: this.onChangeSearch, onBlur: this.resetSearch, className: 'md-title--toolbar', inputClassName: 'md-text-field--toolbar' }); actions = React.createElement(Buttons_1.default, { onClick: this.resetSearch, icon: true }, "close"); } else { actions = [ React.createElement(Buttons_1.default, { key: 'search', onClick: this.showSearch, icon: true }, "search"), React.createElement(Buttons_1.default, { key: 'create', onClick: this.createAndLink, icon: true }, "add"), ]; title = property.name; } actions.push(React.createElement(Buttons_1.default, { icon: true, tooltipLabel: property.hint, tooltipPosition: 'left' }, "help")); return (React.createElement("div", { className: 'md-cell md-cell--12 md-cell--top' }, React.createElement(Toolbars_1.default, { singleColor: true, themed: true, nav: nav, title: title, actions: actions, children: children, className: 'property-toolbar' }), React.createElement(List_1.default, null, items))); }; return EdgeProperty; }(React.Component)); EdgeProperty.contextTypes = __assign({}, WithClient_1.clientContextTypes, Router_1.navigatorContextTypes); exports.EdgeProperty = EdgeProperty;