scrivito_content_browser 0.30.0 → 0.40.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1629 @@
1
+ (function() {
2
+ var ExpandableFilterNodeMixin, FilterMixin, OptionFilterLabelRenderMixin, OptionFilterMixin, classSet, models, ui,
3
+ __hasProp = {}.hasOwnProperty,
4
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
+
6
+ if (typeof scrivito === "undefined" || scrivito === null) {
7
+ console.error("'scrivito' is undefined, the content browser will not be available");
8
+ $(function() {
9
+ if (typeof scrivito === "undefined" || scrivito === null) {
10
+ return console.log("possible reason: '//= require scrivito_sdk' is missing");
11
+ } else {
12
+ return console.log("possible reason: 'scrivito_sdk'/'scrivito_body_tags' is included after 'scrivito_content_browser'");
13
+ }
14
+ });
15
+ return;
16
+ }
17
+
18
+ scrivito.content_browser = (function() {
19
+ return {
20
+ filters: {},
21
+ components: {},
22
+ models: {},
23
+ _center: function(domElement) {
24
+ if (domElement) {
25
+ domElement = $(domElement);
26
+ return domElement.css({
27
+ marginLeft: -domElement.innerWidth() / 2,
28
+ marginTop: -domElement.innerHeight() / 2,
29
+ left: '50%'
30
+ });
31
+ }
32
+ },
33
+ _loadModal: function() {
34
+ this.overlay = $('<div></div>').addClass('editing-overlay show').appendTo($('body'));
35
+ this.modal = $('<div></div>').addClass('scrivito-content-browser show').attr('id', 'scrivito-content-browser').appendTo($('body'));
36
+ this._center(this.modal);
37
+ return $(window).resize((function(_this) {
38
+ return function() {
39
+ return _this._center(_this.modal);
40
+ };
41
+ })(this));
42
+ },
43
+ _buildFilter: function(filter_definition) {
44
+ return new models.Filter(filter_definition);
45
+ },
46
+ _startReact: function() {
47
+ var filter, filterConfig;
48
+ filterConfig = this.options.filters || this.filters;
49
+ filter = this._buildFilter(filterConfig);
50
+ return this._reactApp = React.render(React.createElement(ui.App, {
51
+ "initialFilter": filter,
52
+ "container": this
53
+ }), document.getElementById('scrivito-content-browser'));
54
+ },
55
+ close: function() {
56
+ this.overlay.remove();
57
+ return this.modal.remove();
58
+ },
59
+ open: function(options) {
60
+ if (options == null) {
61
+ options = {};
62
+ }
63
+ this.options = options;
64
+ this._loadModal();
65
+ this._startReact();
66
+ this._promise = $.Deferred();
67
+ return this._promise;
68
+ }
69
+ };
70
+ })();
71
+
72
+ ui = scrivito.content_browser.components;
73
+
74
+ models = scrivito.content_browser.models;
75
+
76
+ classSet = React.addons.classSet;
77
+
78
+ scrivito.register_public_api("content_browser", scrivito.content_browser);
79
+
80
+ ExpandableFilterNodeMixin = {
81
+ defaultExpansionState: function() {
82
+ return {
83
+ open: this.props.filter.isExpanded()
84
+ };
85
+ },
86
+ arrowHandleClick: function() {
87
+ return this.setState({
88
+ open: !this.state.open
89
+ });
90
+ },
91
+ renderArrowTag: function() {
92
+ return React.createElement("div", {
93
+ "className": "scrivito-content-browser-hierarchy-arrow",
94
+ "onClick": this.arrowHandleClick
95
+ });
96
+ },
97
+ openClassSetOptions: function() {
98
+ return {
99
+ 'open': this.state.open,
100
+ 'closed': !this.state.open
101
+ };
102
+ }
103
+ };
104
+
105
+ FilterMixin = {
106
+ renderSubFiltersList: function(subFilters, additionalClasses) {
107
+ var ulClassName;
108
+ ulClassName = "scrivito-content-browser-hierarchy-filter";
109
+ if (additionalClasses && additionalClasses.length > 0) {
110
+ ulClassName = ulClassName + " " + additionalClasses;
111
+ }
112
+ return React.createElement("ul", {
113
+ "className": ulClassName
114
+ }, subFilters);
115
+ }
116
+ };
117
+
118
+ OptionFilterLabelRenderMixin = {
119
+ renderHierarchyLabelTitle: function(title) {
120
+ return React.createElement("div", {
121
+ "className": "scrivito-content-browser-hierarchy-label"
122
+ }, React.createElement("span", null, title));
123
+ }
124
+ };
125
+
126
+ OptionFilterMixin = {
127
+ mixins: [OptionFilterLabelRenderMixin],
128
+ optionLabelToogleClick: function() {
129
+ return this.props.filter.toggleActive();
130
+ },
131
+ activeClassName: function() {
132
+ if (this.props.filter.isActive()) {
133
+ return "active";
134
+ } else {
135
+ return "";
136
+ }
137
+ },
138
+ renderOptionFilterTitle: function() {
139
+ return this.renderHierarchyLabelTitle(this.props.filter.title);
140
+ }
141
+ };
142
+
143
+ models.FilterNode = (function() {
144
+ function FilterNode(filter, name, filter_definition) {
145
+ this.filter = filter;
146
+ this.name = name;
147
+ this.title = filter_definition.title;
148
+ this.title || (this.title = this._fallbackTitle());
149
+ }
150
+
151
+ FilterNode.prototype._fallbackTitle = function() {
152
+ return this._capitalize(this.name.replace(/_/g, ' ').trim());
153
+ };
154
+
155
+ FilterNode.prototype._capitalize = function(string) {
156
+ return string.charAt(0).toUpperCase() + string.slice(1);
157
+ };
158
+
159
+ return FilterNode;
160
+
161
+ })();
162
+
163
+ models.Listenable = (function() {
164
+ function Listenable() {
165
+ this._callbacks = {};
166
+ }
167
+
168
+ Listenable.prototype.on = function(eventName, callback) {
169
+ var _base;
170
+ (_base = this._callbacks)[eventName] || (_base[eventName] = []);
171
+ return this._callbacks[eventName].push(callback);
172
+ };
173
+
174
+ Listenable.prototype.trigger = function() {
175
+ var callbacks, eventName, params;
176
+ eventName = arguments[0];
177
+ params = _.toArray(arguments).slice(1);
178
+ callbacks = this._callbacks[eventName];
179
+ if (callbacks) {
180
+ return _.each(callbacks, function(callback) {
181
+ return callback.apply(this, params);
182
+ });
183
+ }
184
+ };
185
+
186
+ Listenable.prototype.onChange = function(callback) {
187
+ return this.on('change', callback);
188
+ };
189
+
190
+ Listenable.prototype.changed = function() {
191
+ return this.trigger('change', this);
192
+ };
193
+
194
+ return Listenable;
195
+
196
+ })();
197
+
198
+ models.CheckboxFilter = (function(_super) {
199
+ __extends(CheckboxFilter, _super);
200
+
201
+ function CheckboxFilter(filter, name, filterDefinition) {
202
+ CheckboxFilter.__super__.constructor.call(this, filter, name, filterDefinition);
203
+ this.type = 'checkbox';
204
+ this.expanded = filterDefinition.expanded, this.field = filterDefinition.field, this.operator = filterDefinition.operator;
205
+ this.children = _.map(filterDefinition.options, (function(_this) {
206
+ return function(definition, name) {
207
+ return new models.CheckboxOption(_this.filter, name, definition);
208
+ };
209
+ })(this));
210
+ }
211
+
212
+ CheckboxFilter.prototype.isExpanded = function() {
213
+ return !!this.expanded;
214
+ };
215
+
216
+ CheckboxFilter.prototype.hasActiveChildren = function() {
217
+ return _.some(this.children, function(child) {
218
+ return child.isActive();
219
+ });
220
+ };
221
+
222
+ return CheckboxFilter;
223
+
224
+ })(models.FilterNode);
225
+
226
+ models.CheckboxOption = (function(_super) {
227
+ __extends(CheckboxOption, _super);
228
+
229
+ function CheckboxOption(filter, name, filterDefinition) {
230
+ CheckboxOption.__super__.constructor.call(this, filter, name, filterDefinition);
231
+ this.value = filterDefinition.value;
232
+ this.active = filterDefinition.selected;
233
+ }
234
+
235
+ CheckboxOption.prototype.toggleActive = function() {
236
+ this.active = !this.active;
237
+ return this.filter.changed();
238
+ };
239
+
240
+ CheckboxOption.prototype.isActive = function() {
241
+ return !!this.active;
242
+ };
243
+
244
+ return CheckboxOption;
245
+
246
+ })(models.FilterNode);
247
+
248
+ models.Filter = (function(_super) {
249
+ __extends(Filter, _super);
250
+
251
+ function Filter(filter_definition) {
252
+ Filter.__super__.constructor.call(this);
253
+ this._initFilters(filter_definition);
254
+ }
255
+
256
+ Filter.prototype.deselectHierarchicalFilters = function() {
257
+ return _.each(this.getHierarchicalFilters(), function(filter) {
258
+ return filter.deselect();
259
+ });
260
+ };
261
+
262
+ Filter.prototype.setSearchTerm = function(newTerm) {
263
+ this.searchTerm = newTerm;
264
+ return this.changed();
265
+ };
266
+
267
+ Filter.prototype.deselectAllFilters = function() {
268
+ this.deselectHierarchicalFilters();
269
+ return this.changed();
270
+ };
271
+
272
+ Filter.prototype.hasActiveChildren = function() {
273
+ return _.some(_.union(this.getHierarchicalFilters(), this.additionalFilters), function(subFilter) {
274
+ return subFilter.hasActiveChildren();
275
+ });
276
+ };
277
+
278
+ Filter.prototype.getHierarchicalFilters = function() {
279
+ return _.flatten(_.map(this.getTreeFilters(), function(filter) {
280
+ return filter.subFilters;
281
+ }));
282
+ };
283
+
284
+ Filter.prototype.getTreeFilters = function() {
285
+ return this.treeFilters;
286
+ };
287
+
288
+ Filter.prototype.hasHierarchicalFilters = function() {
289
+ return this.treeFilters.length > 0;
290
+ };
291
+
292
+ Filter.prototype.hasAdditionalFilters = function() {
293
+ return this.additionalFilters.length > 0;
294
+ };
295
+
296
+ Filter.prototype._initFilters = function(filter_definition) {
297
+ this.treeFilters = [];
298
+ this.additionalFilters = [];
299
+ return _.each(filter_definition, (function(_this) {
300
+ return function(definition, name) {
301
+ var subFilters;
302
+ if ((definition.type == null) || definition.type === 'tree') {
303
+ subFilters = [];
304
+ _.each(definition.options, function(definition, name) {
305
+ return subFilters.push(new models.TreeFilter(_this, name, definition));
306
+ });
307
+ _this.treeFilters.push({
308
+ config: definition,
309
+ subFilters: subFilters
310
+ });
311
+ }
312
+ if (definition.type === 'radio_button') {
313
+ _this.additionalFilters.push(new models.RadioFilter(_this, name, definition));
314
+ }
315
+ if (definition.type === 'check_box') {
316
+ return _this.additionalFilters.push(new models.CheckboxFilter(_this, name, definition));
317
+ }
318
+ };
319
+ })(this));
320
+ };
321
+
322
+ return Filter;
323
+
324
+ })(models.Listenable);
325
+
326
+ models.Inspector = (function(_super) {
327
+ __extends(Inspector, _super);
328
+
329
+ function Inspector() {
330
+ return Inspector.__super__.constructor.apply(this, arguments);
331
+ }
332
+
333
+ Inspector.prototype.fileDetail = function() {
334
+ var fileDetail;
335
+ fileDetail = "(No description)";
336
+ if (this._inpsectedObj != null) {
337
+ fileDetail = this._inpsectedObj.title || fileDetail;
338
+ }
339
+ return fileDetail;
340
+ };
341
+
342
+ Inspector.prototype.inspectorUrl = function() {
343
+ if (this._inpsectedObj != null) {
344
+ return scrivito.details_url_for_obj_id(this._inpsectedObj.id);
345
+ }
346
+ };
347
+
348
+ Inspector.prototype.setInspectedObj = function(obj) {
349
+ this._inpsectedObj = obj;
350
+ return this.changed();
351
+ };
352
+
353
+ Inspector.prototype.getInspectedObj = function() {
354
+ return this._inpsectedObj;
355
+ };
356
+
357
+ return Inspector;
358
+
359
+ })(models.Listenable);
360
+
361
+ models.ObjCollection = (function(_super) {
362
+ __extends(ObjCollection, _super);
363
+
364
+ function ObjCollection(selectedObjs, _selectionMode) {
365
+ this._selectionMode = _selectionMode;
366
+ ObjCollection.__super__.constructor.call(this);
367
+ this._selectionMode || (this._selectionMode = 'single');
368
+ this._selectedObjs = selectedObjs || [];
369
+ this._objs = [];
370
+ this._curQueryNumber = 0;
371
+ }
372
+
373
+ ObjCollection.prototype.objs = function() {
374
+ return this._objs;
375
+ };
376
+
377
+ ObjCollection.prototype.selectedObjs = function() {
378
+ return this._selectedObjs;
379
+ };
380
+
381
+ ObjCollection.prototype.reload = function() {
382
+ if (this._query) {
383
+ return this.loadFromBackend(this._query);
384
+ }
385
+ };
386
+
387
+ ObjCollection.prototype.loadFromBackend = function(query) {
388
+ var promise;
389
+ this._query = query;
390
+ this._curQueryNumber += 1;
391
+ promise = $.Deferred();
392
+ if (query) {
393
+ this._initialLoadObjs(query, promise, this._curQueryNumber);
394
+ } else {
395
+ promise.resolve();
396
+ this._objs = [];
397
+ }
398
+ this.trigger('loading-obj', promise);
399
+ return promise;
400
+ };
401
+
402
+ ObjCollection.prototype._removeObjFromSelectedCollection = function(objId) {
403
+ return this._selectedObjs = _.without(this._selectedObjs, objId);
404
+ };
405
+
406
+ ObjCollection.prototype.toggleSelected = function(objId) {
407
+ if (this.isSelected(objId)) {
408
+ this._removeObjFromSelectedCollection(objId);
409
+ } else {
410
+ if (this._isSingleSelection()) {
411
+ this._selectedObjs = [objId];
412
+ } else {
413
+ this._selectedObjs.push(objId);
414
+ }
415
+ }
416
+ return this.changed();
417
+ };
418
+
419
+ ObjCollection.prototype.isSelected = function(objId) {
420
+ return _.contains(this._selectedObjs, objId);
421
+ };
422
+
423
+ ObjCollection.prototype.destroyById = function(objId) {
424
+ return scrivito.delete_obj(objId).done((function(_this) {
425
+ return function() {
426
+ return _this._removeObjFromSelectedCollection(objId);
427
+ };
428
+ })(this));
429
+ };
430
+
431
+ ObjCollection.prototype.destroySelectedObjs = function() {
432
+ var deferreds;
433
+ if (this._selectedObjs.length > 0) {
434
+ deferreds = _.map(this._selectedObjs, (function(_this) {
435
+ return function(objId) {
436
+ return _this.destroyById(objId);
437
+ };
438
+ })(this));
439
+ $.when.apply($, deferreds).done((function(_this) {
440
+ return function() {
441
+ return _this.reload();
442
+ };
443
+ })(this));
444
+ return this.trigger('loading-obj');
445
+ }
446
+ };
447
+
448
+ ObjCollection.prototype._initialLoadObjs = function(query, promise, queryNumber) {
449
+ return query.load_batch().then((function(_this) {
450
+ return function(results, next) {
451
+ promise.resolve();
452
+ if (queryNumber === _this._curQueryNumber) {
453
+ _this._objs = [];
454
+ return _this._setAndLoadObjs(results, next, queryNumber);
455
+ }
456
+ };
457
+ })(this));
458
+ };
459
+
460
+ ObjCollection.prototype._setAndLoadObjs = function(results, next, queryNumber) {
461
+ if (queryNumber === this._curQueryNumber) {
462
+ this._objs = this._objs.concat(results.hits);
463
+ this.changed();
464
+ if (next) {
465
+ return next.load_batch().then((function(_this) {
466
+ return function(results, next) {
467
+ return _this._setAndLoadObjs(results, next, queryNumber);
468
+ };
469
+ })(this));
470
+ }
471
+ }
472
+ };
473
+
474
+ ObjCollection.prototype._isSingleSelection = function() {
475
+ return this._selectionMode === 'single';
476
+ };
477
+
478
+ return ObjCollection;
479
+
480
+ })(models.Listenable);
481
+
482
+ models.ObjUpload = (function() {
483
+ function ObjUpload(uploadSet, file) {
484
+ var objClass;
485
+ this.uploadSet = uploadSet;
486
+ this._status = 'active';
487
+ this._fileName = file.name;
488
+ objClass = scrivito.default_obj_class_for_content_type(file.type);
489
+ scrivito.create_obj({
490
+ blob: file,
491
+ _obj_class: objClass,
492
+ _path: this._path()
493
+ }).done((function(_this) {
494
+ return function(objData) {
495
+ _this._obj = objData;
496
+ return _this._setStatus('completed');
497
+ };
498
+ })(this)).fail((function(_this) {
499
+ return function(failure) {
500
+ _this._failureMessage = failure.message;
501
+ return _this._setStatus('failed');
502
+ };
503
+ })(this));
504
+ }
505
+
506
+ ObjUpload.prototype.status = function() {
507
+ return this._status;
508
+ };
509
+
510
+ ObjUpload.prototype.createdObj = function() {
511
+ return this._obj;
512
+ };
513
+
514
+ ObjUpload.prototype.failureMessage = function() {
515
+ return this._failureMessage;
516
+ };
517
+
518
+ ObjUpload.prototype.fileName = function() {
519
+ return this._fileName;
520
+ };
521
+
522
+ ObjUpload.prototype.progress = function() {
523
+ switch (this.status()) {
524
+ case 'active':
525
+ return 10;
526
+ case 'completed':
527
+ return 100;
528
+ case 'failed':
529
+ return 0;
530
+ }
531
+ };
532
+
533
+ ObjUpload.prototype._path = function() {
534
+ return "_resources/" + (this._randomResourceId()) + "/" + (this._sanitizedFilenameForBackend());
535
+ };
536
+
537
+ ObjUpload.prototype._randomResourceId = function() {
538
+ var hex;
539
+ hex = Math.floor(Math.random() * Math.pow(16, 8)).toString(16);
540
+ while (hex.length < 8) {
541
+ hex = '0' + hex;
542
+ }
543
+ return hex;
544
+ };
545
+
546
+ ObjUpload.prototype._sanitizedFilenameForBackend = function() {
547
+ return this.fileName().replace(/[^a-z0-9_.$\-]/ig, '-');
548
+ };
549
+
550
+ ObjUpload.prototype._setStatus = function(newStatus) {
551
+ this._status = newStatus;
552
+ return this.uploadSet.changed();
553
+ };
554
+
555
+ return ObjUpload;
556
+
557
+ })();
558
+
559
+ models.QueryBuilder = (function() {
560
+ function QueryBuilder(filter) {
561
+ this.filter = filter;
562
+ }
563
+
564
+ QueryBuilder.prototype.searchRequest = function() {
565
+ var query;
566
+ query = this._buildTreeFilterQuery() || null;
567
+ query = this._addSearchTerm(query);
568
+ return this._addAdditionalFilters(query);
569
+ };
570
+
571
+ QueryBuilder.prototype._addAdditionalFilters = function(query) {
572
+ var activeChildren, baseQuery, filter, searchQuery, _i, _len, _ref;
573
+ baseQuery = query;
574
+ _ref = this.filter.additionalFilters;
575
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
576
+ filter = _ref[_i];
577
+ activeChildren = _.filter(filter.children, function(child) {
578
+ return child.isActive();
579
+ });
580
+ if (activeChildren.length > 0) {
581
+ searchQuery = this._buildActiveChildrenSearchQuery(activeChildren, filter);
582
+ if (searchQuery != null) {
583
+ baseQuery = this._addOrCreateQuery(baseQuery, searchQuery);
584
+ }
585
+ }
586
+ }
587
+ return baseQuery;
588
+ };
589
+
590
+ QueryBuilder.prototype._buildActiveChildrenSearchQuery = function(activeChildren, filter) {
591
+ if (filter.type === 'checkbox') {
592
+ return this._buildFOVQuery(filter, activeChildren);
593
+ } else {
594
+ return this._buildRadioQuery(filter, activeChildren[0]);
595
+ }
596
+ };
597
+
598
+ QueryBuilder.prototype._buildRadioQuery = function(filter, activeChild) {
599
+ if (activeChild.query) {
600
+ return activeChild.query;
601
+ } else {
602
+ return this._buildFOVQuery(filter, [activeChild]);
603
+ }
604
+ };
605
+
606
+ QueryBuilder.prototype._buildFOVQuery = function(config, activeNodes) {
607
+ var operator, values;
608
+ values = _.flatten(_.map(activeNodes, function(node) {
609
+ return node.value || node.name;
610
+ }));
611
+ operator = config.operator || 'equals';
612
+ return scrivito.obj_where(config.field, operator, values);
613
+ };
614
+
615
+ QueryBuilder.prototype._addSearchTerm = function(query) {
616
+ var searchQuery;
617
+ if (this.filter.searchTerm && this.filter.searchTerm.length > 0) {
618
+ searchQuery = scrivito.obj_where('*', 'contains_prefix', this.filter.searchTerm);
619
+ return this._addOrCreateQuery(query, searchQuery);
620
+ } else {
621
+ return query;
622
+ }
623
+ };
624
+
625
+ QueryBuilder.prototype._buildTreeFilterQuery = function() {
626
+ var activeConfig, field, operator, query;
627
+ activeConfig = this._findActiveTreeFilterItem();
628
+ if (activeConfig) {
629
+ if (activeConfig.node.query) {
630
+ return models.QueryBuilder.prepareQuery(activeConfig.node.query);
631
+ } else {
632
+ field = this._findField(activeConfig);
633
+ if (field) {
634
+ operator = this._findOperator(activeConfig);
635
+ query = this._buildFOVQuery({
636
+ field: field,
637
+ operator: operator
638
+ }, [activeConfig.node]);
639
+ return models.QueryBuilder.prepareQuery(query);
640
+ }
641
+ }
642
+ }
643
+ };
644
+
645
+ QueryBuilder.prototype._findActiveTreeFilterItem = function() {
646
+ var activeConfig, subFilter, treeFilter, _i, _j, _len, _len1, _ref, _ref1;
647
+ _ref = this.filter.getTreeFilters();
648
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
649
+ treeFilter = _ref[_i];
650
+ _ref1 = treeFilter.subFilters;
651
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
652
+ subFilter = _ref1[_j];
653
+ activeConfig = this._findActiveSubFilterItem(subFilter);
654
+ if (activeConfig) {
655
+ activeConfig.parents.push(treeFilter.config);
656
+ return activeConfig;
657
+ }
658
+ }
659
+ }
660
+ };
661
+
662
+ QueryBuilder.prototype._findActiveSubFilterItem = function(filterNode) {
663
+ var activeConfig, childNode, _i, _len, _ref;
664
+ if (filterNode.isActive()) {
665
+ return {
666
+ node: filterNode,
667
+ parents: []
668
+ };
669
+ } else {
670
+ _ref = filterNode.children;
671
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
672
+ childNode = _ref[_i];
673
+ activeConfig = this._findActiveSubFilterItem(childNode);
674
+ if (activeConfig) {
675
+ activeConfig.parents.push(filterNode);
676
+ return activeConfig;
677
+ }
678
+ }
679
+ }
680
+ };
681
+
682
+ QueryBuilder.prototype._addOrCreateQuery = function(oldQuery, newQuery) {
683
+ if (oldQuery) {
684
+ return oldQuery.and(newQuery);
685
+ } else {
686
+ return models.QueryBuilder.prepareQuery(newQuery);
687
+ }
688
+ };
689
+
690
+ QueryBuilder.prototype._findOperator = function(config) {
691
+ return this._findAttributeInConfig('operator', config);
692
+ };
693
+
694
+ QueryBuilder.prototype._findField = function(config) {
695
+ return this._findAttributeInConfig('field', config);
696
+ };
697
+
698
+ QueryBuilder.prototype._findAttributeInConfig = function(attributeName, config) {
699
+ var parentWithAttribute;
700
+ if (config.node[attributeName]) {
701
+ return config.node[attributeName];
702
+ } else {
703
+ parentWithAttribute = _.find(config.parents, function(node) {
704
+ return node[attributeName];
705
+ });
706
+ return parentWithAttribute && parentWithAttribute[attributeName];
707
+ }
708
+ };
709
+
710
+ return QueryBuilder;
711
+
712
+ })();
713
+
714
+ models.QueryBuilder.prepareQuery = function(query) {
715
+ return query.clone().format('content_browser').order('_last_changed').reverse_order();
716
+ };
717
+
718
+ models.QueryBuilder.by_id = function(ids) {
719
+ return models.QueryBuilder.prepareQuery(scrivito.obj_where('id', 'equals', ids));
720
+ };
721
+
722
+ models.RadioFilter = (function(_super) {
723
+ __extends(RadioFilter, _super);
724
+
725
+ function RadioFilter(filter, name, filterDefinition) {
726
+ RadioFilter.__super__.constructor.call(this, filter, name, filterDefinition);
727
+ this.type = 'radio';
728
+ this.field = filterDefinition.field, this.expanded = filterDefinition.expanded, this.operator = filterDefinition.operator;
729
+ this.children = _.map(filterDefinition.options, (function(_this) {
730
+ return function(definition, name) {
731
+ return new models.RadioOption(_this, name, definition);
732
+ };
733
+ })(this));
734
+ }
735
+
736
+ RadioFilter.prototype.isExpanded = function() {
737
+ return !!this.expanded;
738
+ };
739
+
740
+ RadioFilter.prototype.hasActiveChildren = function() {
741
+ return _.some(this.children, function(child) {
742
+ return child.isActive();
743
+ });
744
+ };
745
+
746
+ RadioFilter.prototype.activate = function(radioOption) {
747
+ _.each(this.children, function(child) {
748
+ return child.active = child === radioOption;
749
+ });
750
+ return this.filter.changed();
751
+ };
752
+
753
+ RadioFilter.prototype.deactivateAll = function() {
754
+ _.each(this.children, function(child) {
755
+ return child.active = false;
756
+ });
757
+ return this.filter.changed();
758
+ };
759
+
760
+ return RadioFilter;
761
+
762
+ })(models.FilterNode);
763
+
764
+ models.RadioOption = (function(_super) {
765
+ __extends(RadioOption, _super);
766
+
767
+ function RadioOption(group, name, definition) {
768
+ this.group = group;
769
+ RadioOption.__super__.constructor.call(this, this.group.filter, name, definition);
770
+ this.value = definition.value, this.query = definition.query;
771
+ this.active = definition.selected;
772
+ }
773
+
774
+ RadioOption.prototype.setActive = function() {
775
+ return this.group.activate(this);
776
+ };
777
+
778
+ RadioOption.prototype.isActive = function() {
779
+ return !!this.active;
780
+ };
781
+
782
+ return RadioOption;
783
+
784
+ })(models.FilterNode);
785
+
786
+ models.TreeFilter = (function(_super) {
787
+ __extends(TreeFilter, _super);
788
+
789
+ function TreeFilter(filter, name, filterDefinition) {
790
+ var childrenDefinition;
791
+ TreeFilter.__super__.constructor.call(this, filter, name, filterDefinition);
792
+ this.type = 'tree';
793
+ this.icon = filterDefinition.icon, this.query = filterDefinition.query, this.expanded = filterDefinition.expanded, this.value = filterDefinition.value, this.field = filterDefinition.field, this.operator = filterDefinition.operator;
794
+ this.active = filterDefinition.selected;
795
+ childrenDefinition = filterDefinition.options || [];
796
+ this.children = _.map(childrenDefinition, function(definition, name) {
797
+ return new models.TreeFilter(filter, name, definition);
798
+ });
799
+ }
800
+
801
+ TreeFilter.prototype.isLeaf = function() {
802
+ return this.children.length === 0;
803
+ };
804
+
805
+ TreeFilter.prototype.isExpanded = function() {
806
+ return !!this.expanded;
807
+ };
808
+
809
+ TreeFilter.prototype.isActive = function() {
810
+ return !!this.active;
811
+ };
812
+
813
+ TreeFilter.prototype.toogleActive = function() {
814
+ if (this.isActive()) {
815
+ this.active = false;
816
+ } else {
817
+ this.filter.deselectHierarchicalFilters();
818
+ this.active = true;
819
+ }
820
+ return this.filter.changed();
821
+ };
822
+
823
+ TreeFilter.prototype.hasActiveChildren = function() {
824
+ return this.isActive() || _.some(this.children, function(child) {
825
+ return child.isActive();
826
+ });
827
+ };
828
+
829
+ TreeFilter.prototype.deselect = function() {
830
+ this.active = false;
831
+ return _.each(this.children, function(filter) {
832
+ return filter.deselect();
833
+ });
834
+ };
835
+
836
+ return TreeFilter;
837
+
838
+ })(models.FilterNode);
839
+
840
+ models.UploadSet = (function(_super) {
841
+ __extends(UploadSet, _super);
842
+
843
+ function UploadSet() {
844
+ UploadSet.__super__.constructor.call(this);
845
+ this._uploads = [];
846
+ }
847
+
848
+ UploadSet.prototype.uploads = function() {
849
+ return this._uploads;
850
+ };
851
+
852
+ UploadSet.prototype.addFiles = function(files) {
853
+ _.each(files, (function(_this) {
854
+ return function(file) {
855
+ return _this._uploads.unshift(new models.ObjUpload(_this, file));
856
+ };
857
+ })(this));
858
+ return this.changed();
859
+ };
860
+
861
+ UploadSet.prototype.hasActiveUploads = function() {
862
+ return _.some(this._uploads, function(upload) {
863
+ return upload.status() === 'active';
864
+ });
865
+ };
866
+
867
+ return UploadSet;
868
+
869
+ })(models.Listenable);
870
+
871
+ models.ViewMode = (function(_super) {
872
+ __extends(ViewMode, _super);
873
+
874
+ function ViewMode(mode) {
875
+ ViewMode.__super__.constructor.call(this);
876
+ if (mode == null) {
877
+ mode = "normal";
878
+ }
879
+ this._mode = mode;
880
+ }
881
+
882
+ ViewMode.prototype.setMode = function(newMode) {
883
+ this._mode = newMode;
884
+ return this.changed();
885
+ };
886
+
887
+ ViewMode.prototype.getMode = function() {
888
+ return this._mode;
889
+ };
890
+
891
+ return ViewMode;
892
+
893
+ })(models.Listenable);
894
+
895
+ ui.App = React.createClass({
896
+ displayName: 'App',
897
+ updateFilter: function(filter) {
898
+ return this.setState({
899
+ filter: filter
900
+ });
901
+ },
902
+ updateViewMode: function(viewMode) {
903
+ return this.setState({
904
+ viewMode: viewMode
905
+ });
906
+ },
907
+ updateObjCollection: function(objCollection) {
908
+ return this.setState({
909
+ objCollection: objCollection
910
+ });
911
+ },
912
+ setLoadingState: function(promise) {
913
+ this.refs.itemView.setState({
914
+ loading: true
915
+ });
916
+ return promise.then((function(_this) {
917
+ return function() {
918
+ return _this.refs.itemView.setState({
919
+ loading: false
920
+ });
921
+ };
922
+ })(this));
923
+ },
924
+ updateUploadSet: function(uploadSet) {
925
+ this.setState({
926
+ uploadSet: uploadSet
927
+ });
928
+ if (!uploadSet.hasActiveUploads()) {
929
+ return this.state.objCollection.reload();
930
+ }
931
+ },
932
+ updateInspector: function(inspector) {
933
+ return this.setState({
934
+ inspector: inspector
935
+ });
936
+ },
937
+ componentDidMount: function() {
938
+ this.state.filter.onChange(this.updateFilter);
939
+ this.state.viewMode.onChange(this.updateViewMode);
940
+ this.state.uploadSet.onChange(this.updateUploadSet);
941
+ this.state.objCollection.onChange(this.updateObjCollection);
942
+ this.state.objCollection.on('loading-obj', this.setLoadingState);
943
+ return this.state.inspector.onChange(this.updateInspector);
944
+ },
945
+ getInitialState: function() {
946
+ var initialSelection, selectionMode;
947
+ initialSelection = this.props.container.options.selection || [];
948
+ selectionMode = this.props.container.options.selectionMode;
949
+ return {
950
+ filter: this.props.initialFilter,
951
+ objs: [],
952
+ viewMode: new models.ViewMode(),
953
+ uploadSet: new models.UploadSet(),
954
+ objCollection: new models.ObjCollection(initialSelection, selectionMode),
955
+ inspector: new models.Inspector()
956
+ };
957
+ },
958
+ render: function() {
959
+ return React.createElement("div", {
960
+ "className": "scrivito-app-root"
961
+ }, React.createElement("div", {
962
+ "className": "scrivito-content-browser-body"
963
+ }, React.createElement("div", {
964
+ "className": "scrivito-content-browser-wrapper"
965
+ }, React.createElement(ui.TopBar, {
966
+ "filter": this.state.filter,
967
+ "viewMode": this.state.viewMode
968
+ }), React.createElement(ui.Filter, {
969
+ "filter": this.state.filter,
970
+ "objCollection": this.state.objCollection
971
+ }), React.createElement(ui.Items, {
972
+ "ref": "itemView",
973
+ "objCollection": this.state.objCollection,
974
+ "viewMode": this.state.viewMode,
975
+ "uploadSet": this.state.uploadSet,
976
+ "inspector": this.state.inspector
977
+ })), React.createElement(ui.Inspector, {
978
+ "inspector": this.state.inspector
979
+ })), React.createElement(ui.Footer, {
980
+ "container": this.props.container,
981
+ "objCollection": this.state.objCollection
982
+ }));
983
+ }
984
+ });
985
+
986
+ ui.Filter = React.createClass({
987
+ displayName: 'Filter',
988
+ mixins: [FilterMixin],
989
+ handleDeselectAllFilters: function() {
990
+ return this.props.filter.deselectAllFilters();
991
+ },
992
+ renderAdditionalFilters: function() {
993
+ var subFilters;
994
+ subFilters = _.map(this.props.filter.additionalFilters, function(additionalFilter) {
995
+ return React.createElement(ui.Filter.AdditionalOptionFilter, {
996
+ "filter": additionalFilter
997
+ });
998
+ });
999
+ return this.renderSubFiltersList(subFilters, "compact");
1000
+ },
1001
+ loadObjsByFilterQuery: function(filter) {
1002
+ var query, queryBuilder;
1003
+ this.setState({
1004
+ selectedFilter: false
1005
+ });
1006
+ queryBuilder = new models.QueryBuilder(filter);
1007
+ query = queryBuilder.searchRequest();
1008
+ return this.props.objCollection.loadFromBackend(query);
1009
+ },
1010
+ componentDidMount: function() {
1011
+ this.props.filter.onChange(this.loadObjsByFilterQuery);
1012
+ return this.activateInitialFilter();
1013
+ },
1014
+ activateInitialFilter: function() {
1015
+ if (this.props.filter.hasActiveChildren()) {
1016
+ return this.loadObjsByFilterQuery(this.props.filter);
1017
+ } else {
1018
+ return this.activateSelectedFilter();
1019
+ }
1020
+ },
1021
+ activateSelectedFilter: function() {
1022
+ var query;
1023
+ this.props.filter.deselectHierarchicalFilters();
1024
+ this.setState({
1025
+ selectedFilter: true
1026
+ });
1027
+ query = models.QueryBuilder.by_id(this.props.objCollection.selectedObjs());
1028
+ return this.props.objCollection.loadFromBackend(query);
1029
+ },
1030
+ getInitialState: function() {
1031
+ return {
1032
+ selectedFilter: false
1033
+ };
1034
+ },
1035
+ renderFilterSeparator: function() {
1036
+ if (this.props.filter.hasAdditionalFilters() && this.props.filter.hasHierarchicalFilters()) {
1037
+ return React.createElement("div", {
1038
+ "className": "scrivito_separator"
1039
+ }, "more filters");
1040
+ }
1041
+ },
1042
+ render: function() {
1043
+ var selectedObjsCount, treeSubFilters;
1044
+ treeSubFilters = _.map(this.props.filter.getHierarchicalFilters(), function(treeFilter) {
1045
+ return React.createElement(ui.Filter.TreeFilter, {
1046
+ "filter": treeFilter
1047
+ });
1048
+ });
1049
+ selectedObjsCount = this.props.objCollection.selectedObjs().length;
1050
+ return React.createElement("div", {
1051
+ "className": "scrivito-content-browser-filter"
1052
+ }, React.createElement(ui.Filter.SelectedFilter, {
1053
+ "selectedCount": selectedObjsCount,
1054
+ "active": this.state.selectedFilter,
1055
+ "activateSelectedFilter": this.activateSelectedFilter
1056
+ }), React.createElement("div", {
1057
+ "className": "scrivito-content-browser-filter-scroll"
1058
+ }, React.createElement(ui.Filter.DeselectFilter, {
1059
+ "onDeselectAllFilters": this.handleDeselectAllFilters
1060
+ }), this.renderSubFiltersList(treeSubFilters), this.renderFilterSeparator(), this.renderAdditionalFilters()));
1061
+ }
1062
+ });
1063
+
1064
+ ui.Filter.AdditionalOptionFilter = React.createClass({
1065
+ displayName: 'AdditionalOptionFilter',
1066
+ mixins: [ExpandableFilterNodeMixin],
1067
+ getInitialState: function() {
1068
+ return this.defaultExpansionState();
1069
+ },
1070
+ getAdditionalLableClasses: function() {
1071
+ return classSet(this.openClassSetOptions());
1072
+ },
1073
+ createDeselctAllRadioOption: function() {
1074
+ return React.createElement(ui.Filter.DeselectAllRadioOptionFilter, {
1075
+ "filter": this.props.filter
1076
+ });
1077
+ },
1078
+ renderSubRadioOptionFilters: function() {
1079
+ var childKey, element, i, _i, _len, _ref, _results;
1080
+ _ref = this.props.filter.children;
1081
+ _results = [];
1082
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
1083
+ element = _ref[i];
1084
+ childKey = "" + element.title + "-" + i;
1085
+ if (this.props.filter.type === "radio") {
1086
+ _results.push(React.createElement(ui.Filter.RadioOptionFilter, {
1087
+ "key": childKey,
1088
+ "filter": element
1089
+ }));
1090
+ } else if (this.props.filter.type === "checkbox") {
1091
+ _results.push(React.createElement(ui.Filter.CheckBoxOptionFilter, {
1092
+ "key": childKey,
1093
+ "filter": element
1094
+ }));
1095
+ } else {
1096
+ _results.push(void 0);
1097
+ }
1098
+ }
1099
+ return _results;
1100
+ },
1101
+ render: function() {
1102
+ var labelClasses;
1103
+ labelClasses = this.getAdditionalLableClasses();
1104
+ return React.createElement("li", {
1105
+ "className": labelClasses
1106
+ }, this.renderArrowTag(), React.createElement("div", {
1107
+ "className": "scrivito-content-browser-hierarchy-label",
1108
+ "onClick": this.arrowHandleClick
1109
+ }, React.createElement("span", null, this.props.filter.title)), React.createElement("ul", null, (this.props.filter.type === "radio" ? this.createDeselctAllRadioOption() : void 0), this.renderSubRadioOptionFilters()));
1110
+ }
1111
+ });
1112
+
1113
+ ui.Filter.CheckBoxOptionFilter = React.createClass({
1114
+ displayName: 'CheckBoxOptionFilter',
1115
+ mixins: [OptionFilterMixin],
1116
+ render: function() {
1117
+ return React.createElement("li", {
1118
+ "className": this.activeClassName(),
1119
+ "onClick": this.optionLabelToogleClick
1120
+ }, React.createElement("div", {
1121
+ "className": "scrivito-content-browser-hierarchy-checkbox"
1122
+ }), this.renderOptionFilterTitle());
1123
+ }
1124
+ });
1125
+
1126
+ ui.Filter.DeselectFilter = React.createClass({
1127
+ displayName: 'DeselectFilter',
1128
+ handleDeselect: function() {
1129
+ return this.props.onDeselectAllFilters();
1130
+ },
1131
+ render: function() {
1132
+ return React.createElement("div", {
1133
+ "className": "scrivito_button",
1134
+ "onClick": this.handleDeselect
1135
+ }, "deselect all");
1136
+ }
1137
+ });
1138
+
1139
+ ui.Filter.DeselectAllRadioOptionFilter = React.createClass({
1140
+ displayName: 'DeselectAllRadioOptionFilter',
1141
+ mixins: [OptionFilterLabelRenderMixin],
1142
+ getActiveClass: function() {
1143
+ if (this.props.filter.hasActiveChildren()) {
1144
+ return '';
1145
+ } else {
1146
+ return "active";
1147
+ }
1148
+ },
1149
+ deselectAllRadioOption: function() {
1150
+ return this.props.filter.deactivateAll();
1151
+ },
1152
+ render: function() {
1153
+ return React.createElement("li", {
1154
+ "className": this.getActiveClass(),
1155
+ "onClick": this.deselectAllRadioOption
1156
+ }, React.createElement("div", {
1157
+ "className": "scrivito-content-browser-hierarchy-radio"
1158
+ }), this.renderHierarchyLabelTitle('All'));
1159
+ }
1160
+ });
1161
+
1162
+ ui.Filter.RadioOptionFilter = React.createClass({
1163
+ displayName: 'RadioOptionFilter',
1164
+ mixins: [OptionFilterMixin],
1165
+ labelToogleClick: function() {
1166
+ if (!this.props.filter.isActive()) {
1167
+ return this.props.filter.setActive();
1168
+ }
1169
+ },
1170
+ render: function() {
1171
+ return React.createElement("li", {
1172
+ "className": this.activeClassName(),
1173
+ "onClick": this.labelToogleClick
1174
+ }, React.createElement("div", {
1175
+ "className": "scrivito-content-browser-hierarchy-radio"
1176
+ }), this.renderOptionFilterTitle());
1177
+ }
1178
+ });
1179
+
1180
+ ui.Filter.SelectedFilter = React.createClass({
1181
+ displayName: 'SelectedFilter',
1182
+ filterClass: function() {
1183
+ return classSet({
1184
+ 'scrivito-content-browser-filter-item': true,
1185
+ 'selected-filter': true,
1186
+ 'active': this.props.active
1187
+ });
1188
+ },
1189
+ render: function() {
1190
+ return React.createElement("div", {
1191
+ "className": "scrivito-content-browser-filter-fixed"
1192
+ }, React.createElement("div", {
1193
+ "className": this.filterClass(),
1194
+ "onClick": this.props.activateSelectedFilter
1195
+ }, React.createElement("span", {
1196
+ "className": "scrivito-content-browser-icon scrivito-content-browser-icon-ok-box"
1197
+ }), React.createElement("span", {
1198
+ "className": "scrivito-content-browser-filter-label"
1199
+ }, "Selected", React.createElement("span", {
1200
+ "className": "scrivito-content-browser-counter selected-total"
1201
+ }, this.props.selectedCount))));
1202
+ }
1203
+ });
1204
+
1205
+ ui.Filter.TreeFilter = React.createClass({
1206
+ displayName: 'TreeFilter',
1207
+ mixins: [ExpandableFilterNodeMixin],
1208
+ getInitialState: function() {
1209
+ return this.defaultExpansionState();
1210
+ },
1211
+ renderIconTag: function() {
1212
+ var baseIconClass, iconClass;
1213
+ if (this.props.filter.icon != null) {
1214
+ baseIconClass = "scrivito-content-browser-icon";
1215
+ iconClass = baseIconClass + ("-" + this.props.filter.icon);
1216
+ return React.createElement("i", {
1217
+ "className": "" + baseIconClass + " " + iconClass
1218
+ });
1219
+ }
1220
+ },
1221
+ getLabelClasses: function() {
1222
+ var activeClass, classes;
1223
+ activeClass = {
1224
+ 'active': this.props.filter.isActive()
1225
+ };
1226
+ classes = _.extend(this.openClassSetOptions(), activeClass);
1227
+ return classSet(classes);
1228
+ },
1229
+ renderSubTrees: function() {
1230
+ var childKey, element, i, _i, _len, _ref, _results;
1231
+ _ref = this.props.filter.children;
1232
+ _results = [];
1233
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
1234
+ element = _ref[i];
1235
+ childKey = "" + element.title + "-" + i;
1236
+ _results.push(React.createElement(ui.Filter.TreeFilter, {
1237
+ "key": childKey,
1238
+ "filter": element
1239
+ }));
1240
+ }
1241
+ return _results;
1242
+ },
1243
+ labelToogleClick: function() {
1244
+ return this.props.filter.toogleActive();
1245
+ },
1246
+ render: function() {
1247
+ var labelClasses;
1248
+ labelClasses = this.getLabelClasses();
1249
+ return React.createElement("li", {
1250
+ "className": labelClasses
1251
+ }, (!this.props.filter.isLeaf() ? this.renderArrowTag() : void 0), React.createElement("div", {
1252
+ "className": "scrivito-content-browser-hierarchy-label",
1253
+ "onClick": this.labelToogleClick
1254
+ }, this.renderIconTag(), React.createElement("span", null, this.props.filter.title)), (!this.props.filter.isLeaf() ? React.createElement("ul", null, this.renderSubTrees()) : void 0));
1255
+ }
1256
+ });
1257
+
1258
+ ui.Footer = React.createClass({
1259
+ displayName: 'Footer',
1260
+ currentSelectedCount: function() {
1261
+ return this.props.objCollection.selectedObjs().length;
1262
+ },
1263
+ cancelClick: function() {
1264
+ this.props.container._promise.reject();
1265
+ return this.props.container.close();
1266
+ },
1267
+ doneClick: function() {
1268
+ this.props.container._promise.resolve(this.props.objCollection.selectedObjs());
1269
+ return this.props.container.close();
1270
+ },
1271
+ deleteClick: function() {
1272
+ return this.props.objCollection.destroySelectedObjs();
1273
+ },
1274
+ render: function() {
1275
+ return React.createElement("div", {
1276
+ "className": "scrivito-content-browser-footer"
1277
+ }, React.createElement("a", {
1278
+ "className": "scrivito_button scrivito_lightgrey content-browser-delete",
1279
+ "onClick": this.deleteClick
1280
+ }, "Delete", React.createElement("span", {
1281
+ "className": "scrivito-content-browser-counter selected-total"
1282
+ }, this.currentSelectedCount())), React.createElement("a", {
1283
+ "className": "scrivito_button scrivito_green content-browser-save",
1284
+ "onClick": this.doneClick
1285
+ }, "Select", React.createElement("span", {
1286
+ "className": "scrivito-content-browser-counter selected-total"
1287
+ }, this.currentSelectedCount())), React.createElement("a", {
1288
+ "className": "scrivito_button content-browser-close",
1289
+ "onClick": this.cancelClick
1290
+ }, "Cancel"));
1291
+ }
1292
+ });
1293
+
1294
+ ui.Inspector = React.createClass({
1295
+ displayName: 'Inspector',
1296
+ getDetailsClassName: function() {
1297
+ return "scrivito-content-browser-icon scrivito-content-browser-icon-eye";
1298
+ },
1299
+ render: function() {
1300
+ return React.createElement("div", {
1301
+ "className": "scrivito-content-browser-inspector"
1302
+ }, (this.props.inspector.inspectorUrl() != null ? React.createElement("div", null, React.createElement("h3", null, React.createElement("span", {
1303
+ "title": "Details",
1304
+ "className": this.getDetailsClassName()
1305
+ }), React.createElement("span", {
1306
+ "className": "title"
1307
+ }, this.props.inspector.fileDetail())), React.createElement("div", {
1308
+ "className": "inspector-content"
1309
+ }, React.createElement("iframe", {
1310
+ "src": this.props.inspector.inspectorUrl()
1311
+ }))) : void 0));
1312
+ }
1313
+ });
1314
+
1315
+ ui.Items = React.createClass({
1316
+ displayName: 'Items',
1317
+ getInitialState: function() {
1318
+ return {
1319
+ loading: false,
1320
+ dragInProgres: false
1321
+ };
1322
+ },
1323
+ dropZoneClass: function() {
1324
+ return classSet({
1325
+ "scrivito-content-browser-items": true,
1326
+ "uploader-drag-over": this.state.dragInProgres
1327
+ });
1328
+ },
1329
+ uploadFiles: function(event) {
1330
+ var dataTransfer, files;
1331
+ this.changeDragState(false)(event);
1332
+ dataTransfer = event.dataTransfer;
1333
+ if (dataTransfer == null) {
1334
+ return;
1335
+ }
1336
+ files = dataTransfer.files;
1337
+ if (files.length > 0) {
1338
+ return this.props.uploadSet.addFiles(files);
1339
+ }
1340
+ },
1341
+ changeDragState: function(toValue) {
1342
+ return (function(_this) {
1343
+ return function(event) {
1344
+ event.preventDefault();
1345
+ event.stopPropagation();
1346
+ return _this.setState({
1347
+ dragInProgres: toValue
1348
+ });
1349
+ };
1350
+ })(this);
1351
+ },
1352
+ render: function() {
1353
+ return React.createElement("div", {
1354
+ "className": this.dropZoneClass(),
1355
+ "onDragOver": this.changeDragState(true),
1356
+ "onDrop": this.uploadFiles,
1357
+ "onDragLeave": this.changeDragState(false)
1358
+ }, (this.state.loading ? React.createElement("div", {
1359
+ "className": "scrivito-content-browser-loading"
1360
+ }, React.createElement("i", {
1361
+ "className": "scrivito-content-browser-icon scrivito-content-browser-icon-refresh"
1362
+ })) : this.props.uploadSet.hasActiveUploads() ? React.createElement(ui.UploadItems, {
1363
+ "uploadSet": this.props.uploadSet
1364
+ }) : React.createElement(ui.ThumbnailItems, {
1365
+ "objCollection": this.props.objCollection,
1366
+ "viewMode": this.props.viewMode,
1367
+ "toggleSelected": this.props.toggleSelected,
1368
+ "inspector": this.props.inspector
1369
+ })));
1370
+ }
1371
+ });
1372
+
1373
+ ui.ResizeBar = React.createClass({
1374
+ displayName: 'ResizeBar',
1375
+ resizeButtonsData: ["small", "normal", "big", "large"],
1376
+ render: function() {
1377
+ var size;
1378
+ return React.createElement("div", null, (function() {
1379
+ var _i, _len, _ref, _results;
1380
+ _ref = this.resizeButtonsData;
1381
+ _results = [];
1382
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1383
+ size = _ref[_i];
1384
+ _results.push(React.createElement(ui.ResizeItem, {
1385
+ "viewMode": this.props.viewMode,
1386
+ "size": size
1387
+ }));
1388
+ }
1389
+ return _results;
1390
+ }).call(this));
1391
+ }
1392
+ });
1393
+
1394
+ ui.ResizeItem = React.createClass({
1395
+ displayName: 'ResizeItem',
1396
+ resizeButtonsData: {
1397
+ "large": {
1398
+ iconTitle: "Large thumbnails",
1399
+ iconClassName: "scrivito-content-browser-icon-th-large"
1400
+ },
1401
+ "big": {
1402
+ iconTitle: "Big thumbnails",
1403
+ iconClassName: "scrivito-content-browser-icon-th"
1404
+ },
1405
+ "normal": {
1406
+ iconTitle: "Thumbnails",
1407
+ iconClassName: "scrivito-content-browser-icon-th-medium"
1408
+ },
1409
+ "small": {
1410
+ iconTitle: "Small thumbnails",
1411
+ iconClassName: "scrivito-content-browser-icon-th-small"
1412
+ }
1413
+ },
1414
+ getIconClassName: function(size) {
1415
+ return "scrivito-content-browser-icon " + this.resizeButtonsData[size].iconClassName;
1416
+ },
1417
+ getIconTitle: function(size) {
1418
+ return this.resizeButtonsData[size].iconTitle;
1419
+ },
1420
+ getLabelClasses: function() {
1421
+ return classSet({
1422
+ 'active': this.props.viewMode.getMode() === this.props.size,
1423
+ "editing-button-view": true
1424
+ });
1425
+ },
1426
+ changeViewMode: function() {
1427
+ return this.props.viewMode.setMode(this.props.size);
1428
+ },
1429
+ render: function() {
1430
+ return React.createElement("span", {
1431
+ "data-size": this.props.size,
1432
+ "className": this.getLabelClasses(),
1433
+ "onClick": this.changeViewMode
1434
+ }, React.createElement("i", {
1435
+ "title": this.getIconTitle(this.props.size),
1436
+ "className": this.getIconClassName(this.props.size)
1437
+ }));
1438
+ }
1439
+ });
1440
+
1441
+ ui.ThumbnailItem = React.createClass({
1442
+ displayName: 'ThumbnailItem',
1443
+ title: function() {
1444
+ return this.props.obj.title || "(No description)";
1445
+ },
1446
+ selectClass: function() {
1447
+ var className;
1448
+ className = 'scrivito-content-browser-thumbnails-select select-item';
1449
+ if (this.props.objCollection.isSelected(this.props.obj.id)) {
1450
+ className += ' active';
1451
+ }
1452
+ return className;
1453
+ },
1454
+ previewImage: function() {
1455
+ if (this.props.obj.preview) {
1456
+ return React.createElement("img", {
1457
+ "src": this.props.obj.preview
1458
+ });
1459
+ } else {
1460
+ return React.createElement("span", {
1461
+ "className": "scrivito-content-browser-icon scrivito-content-browser-icon-generic"
1462
+ });
1463
+ }
1464
+ },
1465
+ handleSelectClick: function() {
1466
+ return this.props.objCollection.toggleSelected(this.props.obj.id);
1467
+ },
1468
+ changeInspectObj: function() {
1469
+ return this.props.inspector.setInspectedObj(this.props.obj);
1470
+ },
1471
+ getItemClasses: function() {
1472
+ return classSet({
1473
+ 'active': this.props.inspector.getInspectedObj() === this.props.obj,
1474
+ "content-browser-item": true
1475
+ });
1476
+ },
1477
+ render: function() {
1478
+ return React.createElement("li", {
1479
+ "className": this.getItemClasses()
1480
+ }, React.createElement("div", {
1481
+ "className": "scrivito-content-browser-item-wrapper"
1482
+ }, React.createElement("div", {
1483
+ "className": "scrivito-content-browser-preview",
1484
+ "onClick": this.changeInspectObj
1485
+ }, this.previewImage(), React.createElement("span", {
1486
+ "className": "scrivito-content-browser-inspect"
1487
+ })), React.createElement("div", {
1488
+ "className": "scrivito-content-browser-meta",
1489
+ "onClick": this.handleSelectClick
1490
+ }, React.createElement("span", {
1491
+ "className": "scrivito-content-browser-thumbnails-name"
1492
+ }, this.title()), React.createElement("span", {
1493
+ "className": this.selectClass()
1494
+ }))));
1495
+ }
1496
+ });
1497
+
1498
+ ui.ThumbnailItems = React.createClass({
1499
+ displayName: 'ThumbnailItems',
1500
+ getSizeClassName: function() {
1501
+ return "items scrivito-content-browser-thumbnails " + (this.props.viewMode.getMode());
1502
+ },
1503
+ render: function() {
1504
+ var items;
1505
+ items = _.map(this.props.objCollection.objs(), (function(_this) {
1506
+ return function(obj) {
1507
+ return React.createElement(ui.ThumbnailItem, {
1508
+ "key": obj.id,
1509
+ "obj": obj,
1510
+ "objCollection": _this.props.objCollection,
1511
+ "inspector": _this.props.inspector
1512
+ });
1513
+ };
1514
+ })(this));
1515
+ return React.createElement("ul", {
1516
+ "className": this.getSizeClassName()
1517
+ }, items);
1518
+ }
1519
+ });
1520
+
1521
+ ui.TopBar = React.createClass({
1522
+ displayName: 'TopBar',
1523
+ setSearchTerm: function() {
1524
+ return this.props.filter.setSearchTerm(this.state.searchTerm);
1525
+ },
1526
+ getInitialState: function() {
1527
+ return {
1528
+ searchTerm: this.props.filter.searchTerm
1529
+ };
1530
+ },
1531
+ triggerSearchWithEnter: function(event) {
1532
+ if (event.keyCode === 13) {
1533
+ return this.setSearchTerm();
1534
+ }
1535
+ },
1536
+ updateSearchTerm: function(event) {
1537
+ return this.setState({
1538
+ searchTerm: event.target.value
1539
+ });
1540
+ },
1541
+ render: function() {
1542
+ return React.createElement("div", {
1543
+ "className": "scrivito-content-browser-topbar"
1544
+ }, React.createElement("div", {
1545
+ "className": "scrivito-content-browser-search"
1546
+ }, React.createElement("input", {
1547
+ "type": "text",
1548
+ "placeholder": "Search",
1549
+ "className": "search-field",
1550
+ "value": this.state.searchTerm,
1551
+ "onChange": this.updateSearchTerm,
1552
+ "onKeyUp": this.triggerSearchWithEnter
1553
+ }), React.createElement("button", {
1554
+ "className": "search-field-button",
1555
+ "onClick": this.setSearchTerm
1556
+ }, "Search")), React.createElement(ui.ResizeBar, {
1557
+ "viewMode": this.props.viewMode
1558
+ }));
1559
+ }
1560
+ });
1561
+
1562
+ ui.UploadItem = React.createClass({
1563
+ displayName: 'UploadItem',
1564
+ progressWidth: function() {
1565
+ return {
1566
+ width: "" + (this.props.objUpload.progress()) + "%"
1567
+ };
1568
+ },
1569
+ failureMessage: function() {
1570
+ return this.props.objUpload.failureMessage() || "Upload failed. Please check your network connection.";
1571
+ },
1572
+ failureContent: function() {
1573
+ if (this.props.objUpload.status() === 'failed') {
1574
+ return React.createElement("p", {
1575
+ "className": "scrivito-content-browser-error"
1576
+ }, this.failureMessage());
1577
+ }
1578
+ },
1579
+ render: function() {
1580
+ return React.createElement("div", {
1581
+ "className": "scrivito-content-browser-progress-file"
1582
+ }, React.createElement("p", null, this.props.objUpload.fileName()), this.failureContent(), React.createElement("div", {
1583
+ "className": "scrivito-content-browser-progress"
1584
+ }, React.createElement("div", {
1585
+ "className": "scrivito-content-browser-progress-bar",
1586
+ "style": this.progressWidth()
1587
+ })));
1588
+ }
1589
+ });
1590
+
1591
+ ui.UploadItems = React.createClass({
1592
+ displayName: 'UploadItems',
1593
+ render: function() {
1594
+ var items;
1595
+ items = _.map(this.props.uploadSet.uploads(), function(objUpload) {
1596
+ return React.createElement(ui.UploadItem, {
1597
+ "objUpload": objUpload
1598
+ });
1599
+ });
1600
+ return React.createElement("div", {
1601
+ "className": "scrivito-content-browser-progress-wrapper"
1602
+ }, items);
1603
+ }
1604
+ });
1605
+
1606
+ scrivito.content_browser.stub_filters = {
1607
+ categories: {
1608
+ type: 'tree',
1609
+ options: {
1610
+ all_generics: {
1611
+ title: 'Generics',
1612
+ query: scrivito.obj_where('_obj_class', 'equals', 'Generic'),
1613
+ icon: 'pdf',
1614
+ options: {
1615
+ reports: {
1616
+ title: 'Reports',
1617
+ query: 'empty'
1618
+ },
1619
+ datasheets: {
1620
+ title: 'Datasheets',
1621
+ query: 'empty'
1622
+ }
1623
+ }
1624
+ }
1625
+ }
1626
+ }
1627
+ };
1628
+
1629
+ }).call(this);