scrivito_content_browser 0.42.1 → 0.50.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  (function() {
2
- var ExpandableFilterNodeMixin, FilterMixin, InfiniteScrollMixin, OptionFilterLabelRenderMixin, OptionFilterMixin, classSet, models, ui,
2
+ var ExpandableFilterNodeMixin, FilterMixin, InfiniteScrollMixin, InspectedItemMixin, OptionFilterLabelRenderMixin, OptionFilterMixin, classSet, models, ui,
3
3
  __hasProp = {}.hasOwnProperty,
4
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
5
 
@@ -37,6 +37,13 @@
37
37
  }
38
38
  return _results;
39
39
  },
40
+ _showAlert: function(props) {
41
+ var alertContainer;
42
+ alertContainer = document.createElement('DIV');
43
+ document.body.appendChild(alertContainer);
44
+ props.container = alertContainer;
45
+ return React.render(React.createElement(models.AlertApp, React.__spread({}, props)), alertContainer);
46
+ },
40
47
  _loadModal: function() {
41
48
  $('<div></div>').addClass('scrivito_overlay scrivito_show').appendTo($('body'));
42
49
  $('<div></div>').addClass('scrivito-content-browser show').appendTo($('body'));
@@ -145,23 +152,30 @@
145
152
  };
146
153
 
147
154
  InfiniteScrollMixin = {
155
+ loadingAdditionalItems: function() {
156
+ return this.props.objCollection.loadNextPage();
157
+ },
158
+ hasMoreItems: function() {
159
+ return this.props.objCollection.hasMoreItems();
160
+ },
161
+ isViewportNotFullFilled: function() {
162
+ return this.props.objCollection.objs().length > 0;
163
+ },
148
164
  screenBottomTolerance: function() {
149
165
  return 20;
150
166
  },
151
- getDefaultProps: function() {
152
- return {
153
- loadingAdditionalItems: function() {}
154
- };
155
- },
156
167
  componentDidMount: function() {
157
168
  return this.attachScrollListener();
158
169
  },
159
170
  componentDidUpdate: function() {
160
- return this.attachScrollListener();
171
+ this.attachScrollListener();
172
+ if (this.isViewportNotFullFilled()) {
173
+ return this.fillViewPort();
174
+ }
161
175
  },
162
176
  scrollListener: function() {
163
177
  var isViewportAtBottom, node;
164
- node = this.getDOMNode();
178
+ node = this.getElementDOMNode();
165
179
  isViewportAtBottom = node.scrollTop + node.offsetHeight >= node.scrollHeight - this.screenBottomTolerance();
166
180
  if (isViewportAtBottom) {
167
181
  this.detachScrollListener();
@@ -173,13 +187,21 @@
173
187
  if (!this.hasMoreItems()) {
174
188
  return;
175
189
  }
176
- node = this.getDOMNode();
190
+ node = this.getElementDOMNode();
177
191
  node.addEventListener("scroll", this.scrollListener);
178
192
  return this.scrollListener();
179
193
  },
194
+ fillViewPort: function() {
195
+ if (!this._isFullViewPort()) {
196
+ return this.loadingAdditionalItems();
197
+ }
198
+ },
199
+ _isFullViewPort: function() {
200
+ return this.getElementDOMNode().scrollHeight > this.getElementDOMNode().offsetHeight;
201
+ },
180
202
  detachScrollListener: function() {
181
203
  var node;
182
- node = this.getDOMNode();
204
+ node = this.getElementDOMNode();
183
205
  return node.removeEventListener("scroll", this.scrollListener);
184
206
  },
185
207
  componentWillUnmount: function() {
@@ -187,6 +209,31 @@
187
209
  }
188
210
  };
189
211
 
212
+ InspectedItemMixin = {
213
+ changeInspectObj: function() {
214
+ return this.props.inspector.setInspectedObj(this.props.obj);
215
+ },
216
+ getItemClasses: function() {
217
+ var className;
218
+ className = 'content-browser-item ';
219
+ if (this.props.obj.equals(this.props.inspector.getInspectedObj())) {
220
+ className += 'active';
221
+ }
222
+ return className;
223
+ },
224
+ selectClass: function() {
225
+ var className;
226
+ className = this.baseSelectClass();
227
+ if (this.props.objCollection.isSelected(this.props.obj.id())) {
228
+ className += ' active';
229
+ }
230
+ return className;
231
+ },
232
+ handleSelectClick: function() {
233
+ return this.props.objCollection.toggleSelected(this.props.obj.id());
234
+ }
235
+ };
236
+
190
237
  OptionFilterLabelRenderMixin = {
191
238
  renderHierarchyLabelTitle: function(title) {
192
239
  return React.createElement("div", {
@@ -237,6 +284,8 @@
237
284
 
238
285
  function FilterCollectionNode(filter, name, filterDefinition) {
239
286
  FilterCollectionNode.__super__.constructor.call(this, filter, name, filterDefinition);
287
+ this.field = filterDefinition.field, this.operator = filterDefinition.operator;
288
+ this.expanded = filterDefinition.expanded !== false;
240
289
  this.children = [];
241
290
  }
242
291
 
@@ -295,12 +344,87 @@
295
344
 
296
345
  })();
297
346
 
298
- models.ActiveFilterNodeCollector = (function() {
299
- function ActiveFilterNodeCollector(filter) {
347
+ models.ActiveNodeConfig = (function() {
348
+ function ActiveNodeConfig(parents, nodes) {
349
+ this._parents = parents;
350
+ this._activeNodes = nodes;
351
+ }
352
+
353
+ ActiveNodeConfig.prototype.activeNodes = function() {
354
+ return this._activeNodes;
355
+ };
356
+
357
+ ActiveNodeConfig.prototype.values = function() {
358
+ return _.flatten(_.map(this._activeNodes, this._valueForNode));
359
+ };
360
+
361
+ ActiveNodeConfig.prototype.query = function() {
362
+ return this._filter().type !== 'checkbox' && this._activeNodes[0].query;
363
+ };
364
+
365
+ ActiveNodeConfig.prototype.hasQuery = function() {
366
+ return !!this.query();
367
+ };
368
+
369
+ ActiveNodeConfig.prototype.field = function() {
370
+ return this._findConfig('field');
371
+ };
372
+
373
+ ActiveNodeConfig.prototype.hasField = function() {
374
+ return !!this.field();
375
+ };
376
+
377
+ ActiveNodeConfig.prototype.preventsCreation = function() {
378
+ return this.nodesPreventingCreation().length > 0;
379
+ };
380
+
381
+ ActiveNodeConfig.prototype.nodesPreventingCreation = function() {
382
+ return _.select(this.activeNodes(), function(node) {
383
+ return node.enable_create === false;
384
+ });
385
+ };
386
+
387
+ ActiveNodeConfig.prototype.enablesCreation = function() {
388
+ return _.some(this.activeNodes(), function(node) {
389
+ return node.enable_create === true;
390
+ });
391
+ };
392
+
393
+ ActiveNodeConfig.prototype.operator = function() {
394
+ return this._findConfig('operator') || 'equals';
395
+ };
396
+
397
+ ActiveNodeConfig.prototype._valueForNode = function(node) {
398
+ return node.value || node.name;
399
+ };
400
+
401
+ ActiveNodeConfig.prototype._findConfig = function(attrName) {
402
+ var activeNode, parentWithAttribute;
403
+ activeNode = this._activeNodes[0];
404
+ if (this._filter().type !== 'checkbox' && activeNode[attrName]) {
405
+ return activeNode[attrName];
406
+ } else {
407
+ parentWithAttribute = _.find(this._parents, function(node) {
408
+ return node[attrName];
409
+ });
410
+ return parentWithAttribute && parentWithAttribute[attrName];
411
+ }
412
+ };
413
+
414
+ ActiveNodeConfig.prototype._filter = function() {
415
+ return _.last(this._parents);
416
+ };
417
+
418
+ return ActiveNodeConfig;
419
+
420
+ })();
421
+
422
+ models.ActiveNodeConfigCollector = (function() {
423
+ function ActiveNodeConfigCollector(filter) {
300
424
  this._filter = filter;
301
425
  }
302
426
 
303
- ActiveFilterNodeCollector.prototype.findActiveFilterItems = function() {
427
+ ActiveNodeConfigCollector.prototype.findActiveFilterItems = function() {
304
428
  var filterItems, treeFilterItem;
305
429
  filterItems = this._findActiveAdditionalFilters();
306
430
  treeFilterItem = this._findActiveTreeFilterItem();
@@ -310,7 +434,7 @@
310
434
  return filterItems;
311
435
  };
312
436
 
313
- ActiveFilterNodeCollector.prototype._findActiveTreeFilterItem = function() {
437
+ ActiveNodeConfigCollector.prototype._findActiveTreeFilterItem = function() {
314
438
  var activeConfig, subFilter, treeFilter, _i, _j, _len, _len1, _ref, _ref1;
315
439
  _ref = this._filter.getTreeFilters();
316
440
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -327,7 +451,7 @@
327
451
  }
328
452
  };
329
453
 
330
- ActiveFilterNodeCollector.prototype._findActiveAdditionalFilters = function() {
454
+ ActiveNodeConfigCollector.prototype._findActiveAdditionalFilters = function() {
331
455
  var activeChildren, activeFilters, additionalFilter, _i, _len, _ref;
332
456
  activeFilters = [];
333
457
  _ref = this._filter.additionalFilters;
@@ -343,7 +467,7 @@
343
467
  return activeFilters;
344
468
  };
345
469
 
346
- ActiveFilterNodeCollector.prototype._findActiveSubFilterItem = function(filterNode) {
470
+ ActiveNodeConfigCollector.prototype._findActiveSubFilterItem = function(filterNode) {
347
471
  var activeConfig, childNode, _i, _len, _ref;
348
472
  if (filterNode.isActive()) {
349
473
  return {
@@ -363,76 +487,211 @@
363
487
  }
364
488
  };
365
489
 
366
- return ActiveFilterNodeCollector;
490
+ return ActiveNodeConfigCollector;
367
491
 
368
492
  })();
369
493
 
370
- models.ActiveNodeConfig = (function() {
371
- function ActiveNodeConfig(parents, nodes) {
372
- this._parents = parents;
373
- this._activeNodes = nodes;
494
+ models.AddedObj = (function() {
495
+ AddedObj.prototype.MAX_RETRY = 2;
496
+
497
+ function AddedObj(addedObjsCollection, file, presetAttributes) {
498
+ var objAttributes;
499
+ this.addedObjsCollection = addedObjsCollection;
500
+ if (presetAttributes == null) {
501
+ presetAttributes = {};
502
+ }
503
+ this._status = 'active';
504
+ this._updateProgressByStatus(this._status);
505
+ this._fileName = file != null ? file.name : void 0;
506
+ objAttributes = this._buildObjAttributes(file, presetAttributes);
507
+ scrivito.create_obj(objAttributes).done((function(_this) {
508
+ return function(objData) {
509
+ _this._progress = 50;
510
+ _this.addedObjsCollection.changed();
511
+ return _this._fetchObj(objData.id);
512
+ };
513
+ })(this)).fail((function(_this) {
514
+ return function(failure) {
515
+ _this._failureMessage = failure.message;
516
+ return _this._setStatus('failed');
517
+ };
518
+ })(this));
374
519
  }
375
520
 
376
- ActiveNodeConfig.prototype.activeNodes = function() {
377
- return this._activeNodes;
521
+ AddedObj.prototype.status = function() {
522
+ return this._status;
378
523
  };
379
524
 
380
- ActiveNodeConfig.prototype.values = function() {
381
- return _.flatten(_.map(this._activeNodes, this._valueForNode));
525
+ AddedObj.prototype.createdObj = function() {
526
+ return this._obj;
382
527
  };
383
528
 
384
- ActiveNodeConfig.prototype.query = function() {
385
- return this._filter().type !== 'checkbox' && this._activeNodes[0].query;
529
+ AddedObj.prototype.failureMessage = function() {
530
+ return this._failureMessage;
386
531
  };
387
532
 
388
- ActiveNodeConfig.prototype.hasQuery = function() {
389
- return !!this.query();
533
+ AddedObj.prototype.fileName = function() {
534
+ return this._fileName;
390
535
  };
391
536
 
392
- ActiveNodeConfig.prototype.field = function() {
393
- return this._findConfig('field');
537
+ AddedObj.prototype.progress = function() {
538
+ return this._progress;
394
539
  };
395
540
 
396
- ActiveNodeConfig.prototype.hasField = function() {
397
- return !!this.field();
541
+ AddedObj.prototype._fetchObj = function(id, retryCount) {
542
+ if (retryCount == null) {
543
+ retryCount = 0;
544
+ }
545
+ return models.QueryBuilder.byId(id).load_batch().then(((function(_this) {
546
+ return function(searchResult) {
547
+ if (searchResult.hits.length > 0) {
548
+ _this._obj = new models.Obj(searchResult.hits[0]);
549
+ return _this._setStatus('completed');
550
+ } else {
551
+ return _this._objNotYetIndexed(id, retryCount);
552
+ }
553
+ };
554
+ })(this)), (function(_this) {
555
+ return function() {
556
+ return _this._setStatus('failed');
557
+ };
558
+ })(this));
398
559
  };
399
560
 
400
- ActiveNodeConfig.prototype.operator = function() {
401
- return this._findConfig('operator') || 'equals';
561
+ AddedObj.prototype._objNotYetIndexed = function(id, retryCount) {
562
+ var fetchObjFunction;
563
+ if (retryCount < this.MAX_RETRY) {
564
+ fetchObjFunction = (function(_this) {
565
+ return function() {
566
+ return _this._fetchObj(id, retryCount + 1);
567
+ };
568
+ })(this);
569
+ return window.setTimeout(fetchObjFunction, 500);
570
+ } else {
571
+ this._setStatus('failed');
572
+ return $.Deferred().reject();
573
+ }
402
574
  };
403
575
 
404
- ActiveNodeConfig.prototype._valueForNode = function(node) {
405
- return node.value || node.name;
576
+ AddedObj.prototype._setStatus = function(status) {
577
+ this._status = status;
578
+ this._updateProgressByStatus(status);
579
+ return this.addedObjsCollection.changed();
406
580
  };
407
581
 
408
- ActiveNodeConfig.prototype._findConfig = function(attrName) {
409
- var activeNode, parentWithAttribute;
410
- activeNode = this._activeNodes[0];
411
- if (this._filter().type !== 'checkbox' && activeNode[attrName]) {
412
- return activeNode[attrName];
413
- } else {
414
- parentWithAttribute = _.find(this._parents, function(node) {
415
- return node[attrName];
416
- });
417
- return parentWithAttribute && parentWithAttribute[attrName];
582
+ AddedObj.prototype._updateProgressByStatus = function(status) {
583
+ return this._progress = (function() {
584
+ switch (this.status()) {
585
+ case 'active':
586
+ return 10;
587
+ case 'completed':
588
+ return 100;
589
+ case 'failed':
590
+ return 0;
591
+ }
592
+ }).call(this);
593
+ };
594
+
595
+ AddedObj.prototype._buildObjAttributes = function(file, presetAttributes) {
596
+ var objAttributes;
597
+ objAttributes = {
598
+ _path: this._path()
599
+ };
600
+ if (file) {
601
+ _.extend(objAttributes, this._fileAttributes(file));
418
602
  }
603
+ return _.extend(objAttributes, presetAttributes);
419
604
  };
420
605
 
421
- ActiveNodeConfig.prototype._filter = function() {
422
- return _.last(this._parents);
606
+ AddedObj.prototype._fileAttributes = function(file) {
607
+ var objClass;
608
+ objClass = scrivito.default_obj_class_for_content_type(file.type);
609
+ return {
610
+ blob: file,
611
+ _obj_class: objClass
612
+ };
423
613
  };
424
614
 
425
- return ActiveNodeConfig;
615
+ AddedObj.prototype._path = function() {
616
+ return "_resources/" + (this._randomResourceId()) + "/" + (this._lastPathComponent());
617
+ };
618
+
619
+ AddedObj.prototype._randomResourceId = function() {
620
+ var hex;
621
+ hex = Math.floor(Math.random() * Math.pow(16, 8)).toString(16);
622
+ while (hex.length < 8) {
623
+ hex = '0' + hex;
624
+ }
625
+ return hex;
626
+ };
627
+
628
+ AddedObj.prototype._lastPathComponent = function() {
629
+ if (this.fileName()) {
630
+ return this.fileName().replace(/[^a-z0-9_.$\-]/ig, '-');
631
+ } else {
632
+ return this._randomResourceId();
633
+ }
634
+ };
635
+
636
+ return AddedObj;
426
637
 
427
638
  })();
428
639
 
640
+ models.AddedObjsCollection = (function(_super) {
641
+ __extends(AddedObjsCollection, _super);
642
+
643
+ function AddedObjsCollection(basePreset) {
644
+ if (basePreset == null) {
645
+ basePreset = {};
646
+ }
647
+ AddedObjsCollection.__super__.constructor.call(this);
648
+ this._basePreset = basePreset;
649
+ this._objs = [];
650
+ }
651
+
652
+ AddedObjsCollection.prototype.objs = function() {
653
+ return this._objs;
654
+ };
655
+
656
+ AddedObjsCollection.prototype.addFiles = function(files, presets) {
657
+ if (presets == null) {
658
+ presets = {};
659
+ }
660
+ presets = this._buildPresets(presets);
661
+ _.each(files, (function(_this) {
662
+ return function(file) {
663
+ return _this._objs.unshift(new models.AddedObj(_this, file, presets));
664
+ };
665
+ })(this));
666
+ return this.changed();
667
+ };
668
+
669
+ AddedObjsCollection.prototype.createObj = function(presets) {
670
+ presets = this._buildPresets(presets);
671
+ this._objs.unshift(new models.AddedObj(this, null, presets));
672
+ return this.changed();
673
+ };
674
+
675
+ AddedObjsCollection.prototype.hasActiveCreations = function() {
676
+ return _.some(this._objs, function(upload) {
677
+ return upload.status() === 'active';
678
+ });
679
+ };
680
+
681
+ AddedObjsCollection.prototype._buildPresets = function(presets) {
682
+ return _.extend({}, this._basePreset, presets);
683
+ };
684
+
685
+ return AddedObjsCollection;
686
+
687
+ })(models.Listenable);
688
+
429
689
  models.CheckboxFilter = (function(_super) {
430
690
  __extends(CheckboxFilter, _super);
431
691
 
432
692
  function CheckboxFilter(filter, name, filterDefinition) {
433
693
  CheckboxFilter.__super__.constructor.call(this, filter, name, filterDefinition);
434
694
  this.type = 'checkbox';
435
- this.expanded = filterDefinition.expanded, this.field = filterDefinition.field, this.operator = filterDefinition.operator;
436
695
  this.children = _.map(filterDefinition.options, (function(_this) {
437
696
  return function(definition, name) {
438
697
  return new models.CheckboxOption(_this.filter, name, definition);
@@ -440,16 +699,6 @@
440
699
  })(this));
441
700
  }
442
701
 
443
- CheckboxFilter.prototype.isExpanded = function() {
444
- return !!this.expanded;
445
- };
446
-
447
- CheckboxFilter.prototype.hasActiveChildren = function() {
448
- return _.some(this.children, function(child) {
449
- return child.isActive();
450
- });
451
- };
452
-
453
702
  return CheckboxFilter;
454
703
 
455
704
  })(models.FilterCollectionNode);
@@ -459,7 +708,7 @@
459
708
 
460
709
  function CheckboxOption(filter, name, filterDefinition) {
461
710
  CheckboxOption.__super__.constructor.call(this, filter, name, filterDefinition);
462
- this.value = filterDefinition.value, this.preset = filterDefinition.preset;
711
+ this.value = filterDefinition.value, this.preset = filterDefinition.preset, this.enable_create = filterDefinition.enable_create;
463
712
  this.active = filterDefinition.selected;
464
713
  }
465
714
 
@@ -495,12 +744,6 @@
495
744
  return this.changed();
496
745
  };
497
746
 
498
- Filter.prototype.deactivateAllFilters = function() {
499
- this.deselectHierarchicalFilters();
500
- this._deselectAdditionalFilters();
501
- return this.changed();
502
- };
503
-
504
747
  Filter.prototype._deselectAdditionalFilters = function() {
505
748
  if (this.hasAdditionalFilters()) {
506
749
  return _.each(this.additionalFilters, function(filter) {
@@ -509,8 +752,12 @@
509
752
  }
510
753
  };
511
754
 
755
+ Filter.prototype.getAllFilters = function() {
756
+ return _.union(this.getHierarchicalFilters(), this.additionalFilters);
757
+ };
758
+
512
759
  Filter.prototype.hasActiveChildren = function() {
513
- return _.some(_.union(this.getHierarchicalFilters(), this.additionalFilters), function(subFilter) {
760
+ return _.some(this.getAllFilters(), function(subFilter) {
514
761
  return subFilter.hasActiveChildren();
515
762
  });
516
763
  };
@@ -595,6 +842,44 @@
595
842
 
596
843
  })(models.Listenable);
597
844
 
845
+ models.MimeTypeIcon = (function() {
846
+ function MimeTypeIcon() {}
847
+
848
+ MimeTypeIcon.getMimeTypeIconClassName = function(mimeType) {
849
+ var icon, matchedType;
850
+ if (mimeType != null) {
851
+ matchedType = this._getMatchedIconType(mimeType);
852
+ icon = this._mimeTypesHash[matchedType];
853
+ }
854
+ if (icon == null) {
855
+ icon = "scrivito_icon_generic";
856
+ }
857
+ return icon;
858
+ };
859
+
860
+ MimeTypeIcon._mimeTypesHash = {
861
+ "video": "scrivito_icon_movie",
862
+ "audio": "scrivito_icon_music",
863
+ "msword": "scrivito_icon_doc",
864
+ "zip": "scrivito_icon_zip",
865
+ "pdf": "scrivito_icon_pdf",
866
+ "ms-excel": "scrivito_icon_xls",
867
+ "ms-powerpoint": "scrivito_icon_ppt",
868
+ "openxmlformats-officedocument.spreadsheetml": "scrivito_icon_xls",
869
+ "wordprocessingml": "scrivito_icon_doc",
870
+ "presentationml": "scrivito_icon_ppt"
871
+ };
872
+
873
+ MimeTypeIcon._getMatchedIconType = function(mimeType) {
874
+ return _.find(Object.keys(this._mimeTypesHash), function(keyName) {
875
+ return mimeType.match(RegExp("\\b" + keyName + "\\b"));
876
+ });
877
+ };
878
+
879
+ return MimeTypeIcon;
880
+
881
+ })();
882
+
598
883
  models.Obj = (function() {
599
884
  function Obj(attributes) {
600
885
  this._attr = attributes;
@@ -604,10 +889,18 @@
604
889
  return this._attr['title'] || '(No description)';
605
890
  };
606
891
 
892
+ Obj.prototype.subtitle = function() {
893
+ return this._attr['subtitle'];
894
+ };
895
+
607
896
  Obj.prototype.id = function() {
608
897
  return this._attr['id'];
609
898
  };
610
899
 
900
+ Obj.prototype.equals = function(other) {
901
+ return this.id() === (other != null ? other.id() : void 0);
902
+ };
903
+
611
904
  Obj.prototype.hasPreview = function() {
612
905
  return !!this._attr['preview'];
613
906
  };
@@ -616,6 +909,22 @@
616
909
  return this._attr['preview'];
617
910
  };
618
911
 
912
+ Obj.prototype.lastChanged = function() {
913
+ return this._attr['last_changed'];
914
+ };
915
+
916
+ Obj.prototype.mimeType = function() {
917
+ return this._attr['mime_type'];
918
+ };
919
+
920
+ Obj.prototype.fileSize = function() {
921
+ return this._attr['file_size'];
922
+ };
923
+
924
+ Obj.prototype.fileType = function() {
925
+ return this._attr['file_type'];
926
+ };
927
+
619
928
  Obj.prototype.hasDetailsView = function() {
620
929
  return this._attr['has_details_view'];
621
930
  };
@@ -684,7 +993,7 @@
684
993
  if (this.isSelected(objId)) {
685
994
  this._removeObjFromSelectedCollection(objId);
686
995
  } else {
687
- if (this._isSingleSelection()) {
996
+ if (this.isSingleSelectionMode()) {
688
997
  this._selectedObjs = [objId];
689
998
  } else {
690
999
  this._selectedObjs.push(objId);
@@ -761,105 +1070,97 @@
761
1070
  })(this));
762
1071
  };
763
1072
 
764
- ObjCollection.prototype._setAndLoadObjs = function(results, next, queryNumber) {
765
- var curObjs;
766
- if (queryNumber === this._curQueryNumber) {
767
- curObjs = _.map(results.hits, function(attr) {
768
- return new models.Obj(attr);
769
- });
770
- this._objs = this._objs.concat(curObjs);
771
- this._nextQuery = next;
772
- return this.changed();
773
- }
774
- };
775
-
776
- ObjCollection.prototype._isSingleSelection = function() {
777
- return this._selectionMode === 'single';
778
- };
779
-
780
- return ObjCollection;
781
-
782
- })(models.Listenable);
783
-
784
- models.ObjUpload = (function() {
785
- function ObjUpload(uploadSet, file, presetAttributes) {
786
- var objAttributes, objClass;
787
- this.uploadSet = uploadSet;
788
- if (presetAttributes == null) {
789
- presetAttributes = {};
790
- }
791
- this._status = 'active';
792
- this._fileName = file.name;
793
- objClass = scrivito.default_obj_class_for_content_type(file.type);
794
- objAttributes = {
795
- blob: file,
796
- _obj_class: objClass,
797
- _path: this._path()
798
- };
799
- objAttributes = _.extend(objAttributes, presetAttributes);
800
- scrivito.create_obj(objAttributes).done((function(_this) {
801
- return function(objData) {
802
- _this._obj = objData;
803
- return _this._setStatus('completed');
804
- };
805
- })(this)).fail((function(_this) {
806
- return function(failure) {
807
- _this._failureMessage = failure.message;
808
- return _this._setStatus('failed');
809
- };
810
- })(this));
811
- }
812
-
813
- ObjUpload.prototype.status = function() {
814
- return this._status;
1073
+ ObjCollection.prototype._setAndLoadObjs = function(results, next, queryNumber) {
1074
+ var curObjs;
1075
+ if (queryNumber === this._curQueryNumber) {
1076
+ curObjs = _.map(results.hits, function(attr) {
1077
+ return new models.Obj(attr);
1078
+ });
1079
+ this._objs = this._objs.concat(curObjs);
1080
+ this._nextQuery = next;
1081
+ return this.changed();
1082
+ }
815
1083
  };
816
1084
 
817
- ObjUpload.prototype.createdObj = function() {
818
- return this._obj;
1085
+ ObjCollection.prototype.isSingleSelectionMode = function() {
1086
+ return this._selectionMode === 'single';
819
1087
  };
820
1088
 
821
- ObjUpload.prototype.failureMessage = function() {
822
- return this._failureMessage;
1089
+ return ObjCollection;
1090
+
1091
+ })(models.Listenable);
1092
+
1093
+ models.ObjCreation = (function() {
1094
+ function ObjCreation(filter) {
1095
+ var collector, presetBuilder;
1096
+ collector = new models.ActiveNodeConfigCollector(filter);
1097
+ this.activeConfigs = collector.findActiveFilterItems();
1098
+ presetBuilder = new models.PresetBuilder(filter);
1099
+ this._preset = presetBuilder.generatePreset();
1100
+ }
1101
+
1102
+ ObjCreation.prototype.preset = function() {
1103
+ return this._preset.values();
823
1104
  };
824
1105
 
825
- ObjUpload.prototype.fileName = function() {
826
- return this._fileName;
1106
+ ObjCreation.prototype.showCreationItem = function() {
1107
+ return _.some(this.activeConfigs, function(nodeConfig) {
1108
+ return nodeConfig.enablesCreation();
1109
+ });
1110
+ };
1111
+
1112
+ ObjCreation.prototype.isActive = function() {
1113
+ return !!(!this._preventCreation() && this._presetIsValid());
827
1114
  };
828
1115
 
829
- ObjUpload.prototype.progress = function() {
830
- switch (this.status()) {
831
- case 'active':
832
- return 10;
833
- case 'completed':
834
- return 100;
835
- case 'failed':
836
- return 0;
1116
+ ObjCreation.prototype.error = function() {
1117
+ if (this._preventCreation()) {
1118
+ return {
1119
+ type: 'creation_not_possible',
1120
+ nodeTitles: this._nodeTitlesPreventingCreation()
1121
+ };
1122
+ } else if (this._preset.isValid()) {
1123
+ return {
1124
+ type: 'obj_class_not_provided'
1125
+ };
1126
+ } else {
1127
+ return {
1128
+ type: 'preset_conflict',
1129
+ fields: this._buildPresetConflictError()
1130
+ };
837
1131
  }
838
1132
  };
839
1133
 
840
- ObjUpload.prototype._path = function() {
841
- return "_resources/" + (this._randomResourceId()) + "/" + (this._sanitizedFilenameForBackend());
1134
+ ObjCreation.prototype._preventCreation = function() {
1135
+ return _.some(this.activeConfigs, function(nodeConfig) {
1136
+ return nodeConfig.preventsCreation();
1137
+ });
842
1138
  };
843
1139
 
844
- ObjUpload.prototype._randomResourceId = function() {
845
- var hex;
846
- hex = Math.floor(Math.random() * Math.pow(16, 8)).toString(16);
847
- while (hex.length < 8) {
848
- hex = '0' + hex;
849
- }
850
- return hex;
1140
+ ObjCreation.prototype._presetIsValid = function() {
1141
+ return this._preset.isValid() && this.preset()['_obj_class'];
851
1142
  };
852
1143
 
853
- ObjUpload.prototype._sanitizedFilenameForBackend = function() {
854
- return this.fileName().replace(/[^a-z0-9_.$\-]/ig, '-');
1144
+ ObjCreation.prototype._nodeTitlesPreventingCreation = function() {
1145
+ var nodes;
1146
+ nodes = _.flatten(_.map(this.activeConfigs, function(node) {
1147
+ return node.nodesPreventingCreation();
1148
+ }));
1149
+ return _.map(nodes, function(node) {
1150
+ return node.title;
1151
+ });
855
1152
  };
856
1153
 
857
- ObjUpload.prototype._setStatus = function(newStatus) {
858
- this._status = newStatus;
859
- return this.uploadSet.changed();
1154
+ ObjCreation.prototype._buildPresetConflictError = function() {
1155
+ var presetConflicts;
1156
+ presetConflicts = {};
1157
+ _.each(this._preset.errors(), function(values, field) {
1158
+ return presetConflicts[field] = values;
1159
+ });
1160
+ return presetConflicts;
860
1161
  };
861
1162
 
862
- return ObjUpload;
1163
+ return ObjCreation;
863
1164
 
864
1165
  })();
865
1166
 
@@ -911,7 +1212,7 @@
911
1212
  })();
912
1213
 
913
1214
  function PresetBuilder(filter) {
914
- this._collector = new models.ActiveFilterNodeCollector(filter);
1215
+ this._collector = new models.ActiveNodeConfigCollector(filter);
915
1216
  }
916
1217
 
917
1218
  PresetBuilder.prototype.generatePreset = function() {
@@ -951,7 +1252,7 @@
951
1252
  models.QueryBuilder = (function() {
952
1253
  function QueryBuilder(filter, baseQuery) {
953
1254
  this.filter = filter;
954
- this._collector = new models.ActiveFilterNodeCollector(this.filter);
1255
+ this._collector = new models.ActiveNodeConfigCollector(this.filter);
955
1256
  if (baseQuery) {
956
1257
  this._baseQuery = models.QueryBuilder.prepareQuery(baseQuery);
957
1258
  }
@@ -1028,7 +1329,6 @@
1028
1329
  function RadioFilter(filter, name, filterDefinition) {
1029
1330
  RadioFilter.__super__.constructor.call(this, filter, name, filterDefinition);
1030
1331
  this.type = 'radio';
1031
- this.field = filterDefinition.field, this.expanded = filterDefinition.expanded, this.operator = filterDefinition.operator;
1032
1332
  this.children = _.map(filterDefinition.options, (function(_this) {
1033
1333
  return function(definition, name) {
1034
1334
  return new models.RadioOption(_this, name, definition);
@@ -1058,7 +1358,7 @@
1058
1358
  function RadioOption(group, name, filterDefinition) {
1059
1359
  this.group = group;
1060
1360
  RadioOption.__super__.constructor.call(this, this.group.filter, name, filterDefinition);
1061
- this.value = filterDefinition.value, this.query = filterDefinition.query, this.preset = filterDefinition.preset;
1361
+ this.value = filterDefinition.value, this.query = filterDefinition.query, this.preset = filterDefinition.preset, this.enable_create = filterDefinition.enable_create;
1062
1362
  this.active = filterDefinition.selected;
1063
1363
  }
1064
1364
 
@@ -1081,7 +1381,7 @@
1081
1381
  var childrenDefinition;
1082
1382
  TreeFilter.__super__.constructor.call(this, filter, name, filterDefinition);
1083
1383
  this.type = 'tree';
1084
- this.icon = filterDefinition.icon, this.query = filterDefinition.query, this.expanded = filterDefinition.expanded, this.value = filterDefinition.value, this.field = filterDefinition.field, this.operator = filterDefinition.operator, this.preset = filterDefinition.preset;
1384
+ this.icon = filterDefinition.icon, this.query = filterDefinition.query, this.expanded = filterDefinition.expanded, this.value = filterDefinition.value, this.field = filterDefinition.field, this.operator = filterDefinition.operator, this.preset = filterDefinition.preset, this.enable_create = filterDefinition.enable_create;
1085
1385
  this.active = filterDefinition.selected;
1086
1386
  childrenDefinition = filterDefinition.options || [];
1087
1387
  this.children = _.map(childrenDefinition, function(definition, name) {
@@ -1128,52 +1428,13 @@
1128
1428
 
1129
1429
  })(models.FilterNode);
1130
1430
 
1131
- models.UploadSet = (function(_super) {
1132
- __extends(UploadSet, _super);
1133
-
1134
- function UploadSet(basePreset) {
1135
- if (basePreset == null) {
1136
- basePreset = {};
1137
- }
1138
- UploadSet.__super__.constructor.call(this);
1139
- this._basePreset = basePreset;
1140
- this._uploads = [];
1141
- }
1142
-
1143
- UploadSet.prototype.uploads = function() {
1144
- return this._uploads;
1145
- };
1146
-
1147
- UploadSet.prototype.addFiles = function(files, presets) {
1148
- if (presets == null) {
1149
- presets = {};
1150
- }
1151
- presets = _.extend(_.clone(this._basePreset), presets);
1152
- _.each(files, (function(_this) {
1153
- return function(file) {
1154
- return _this._uploads.unshift(new models.ObjUpload(_this, file, presets));
1155
- };
1156
- })(this));
1157
- return this.changed();
1158
- };
1159
-
1160
- UploadSet.prototype.hasActiveUploads = function() {
1161
- return _.some(this._uploads, function(upload) {
1162
- return upload.status() === 'active';
1163
- });
1164
- };
1165
-
1166
- return UploadSet;
1167
-
1168
- })(models.Listenable);
1169
-
1170
1431
  models.ViewMode = (function(_super) {
1171
1432
  __extends(ViewMode, _super);
1172
1433
 
1173
1434
  function ViewMode(mode) {
1174
1435
  ViewMode.__super__.constructor.call(this);
1175
1436
  if (mode == null) {
1176
- mode = "small";
1437
+ mode = "thumbnails";
1177
1438
  }
1178
1439
  this._mode = mode;
1179
1440
  }
@@ -1187,10 +1448,73 @@
1187
1448
  return this._mode;
1188
1449
  };
1189
1450
 
1451
+ ViewMode.prototype.isList = function() {
1452
+ return this._mode === "list";
1453
+ };
1454
+
1190
1455
  return ViewMode;
1191
1456
 
1192
1457
  })(models.Listenable);
1193
1458
 
1459
+ models.AlertBody = React.createClass({
1460
+ displayName: 'AlertBody',
1461
+ render: function() {
1462
+ return React.createElement("div", {
1463
+ "className": "scrivito_modal_body"
1464
+ }, this.props.body);
1465
+ }
1466
+ });
1467
+
1468
+ models.AlertHeader = React.createClass({
1469
+ displayName: 'AlertHeader',
1470
+ render: function() {
1471
+ return React.createElement("div", {
1472
+ "className": "scrivito_modal_header"
1473
+ }, React.createElement("i", {
1474
+ "className": "scrivito_icon scrivito_icon_error"
1475
+ }), React.createElement("h3", {
1476
+ "className": "scrivito_title"
1477
+ }, this.props.title), (this.props.subtitle ? React.createElement("p", {
1478
+ "className": "scrivito_description"
1479
+ }, this.props.subtitle) : void 0));
1480
+ }
1481
+ });
1482
+
1483
+ models.AlertApp = React.createClass({
1484
+ displayName: 'AlertApp',
1485
+ alertClassName: function() {
1486
+ return "scrivito_prompt_dialog scrivito_center_dialog scrivito_modal_prompt scrivito_show scrivito_red";
1487
+ },
1488
+ closeAlert: function(event) {
1489
+ event.preventDefault();
1490
+ React.unmountComponentAtNode(this.props.container);
1491
+ return this.props.container.remove();
1492
+ },
1493
+ render: function() {
1494
+ return React.createElement("div", null, React.createElement("div", {
1495
+ "className": "scrivito_overlay two scrivito_show",
1496
+ "style": {
1497
+ zIndex: 4444444
1498
+ }
1499
+ }), React.createElement("div", {
1500
+ "className": this.alertClassName(),
1501
+ "style": {
1502
+ zIndex: 4444444
1503
+ }
1504
+ }, React.createElement(models.AlertHeader, {
1505
+ "title": this.props.title,
1506
+ "subtitle": this.props.subtitle
1507
+ }), React.createElement(models.AlertBody, {
1508
+ "body": this.props.body
1509
+ }), React.createElement("div", {
1510
+ "className": "scrivito_modal_footer"
1511
+ }, React.createElement("a", {
1512
+ "className": "scrivito_button scrivito_cancel",
1513
+ "onClick": this.closeAlert
1514
+ }, "Close"))));
1515
+ }
1516
+ });
1517
+
1194
1518
  ui.App = React.createClass({
1195
1519
  displayName: 'App',
1196
1520
  updateFilter: function(filter) {
@@ -1220,11 +1544,14 @@
1220
1544
  };
1221
1545
  })(this));
1222
1546
  },
1223
- updateUploadSet: function(uploadSet) {
1547
+ updateAddedObjsCollection: function(addedObjsCollection) {
1548
+ var lastCreatedObj;
1224
1549
  this.setState({
1225
- uploadSet: uploadSet
1550
+ addedObjsCollection: addedObjsCollection
1226
1551
  });
1227
- if (!uploadSet.hasActiveUploads()) {
1552
+ if (!addedObjsCollection.hasActiveCreations()) {
1553
+ lastCreatedObj = _.first(addedObjsCollection.objs()).createdObj();
1554
+ this.state.inspector.setInspectedObj(lastCreatedObj);
1228
1555
  return this.state.objCollection.reload();
1229
1556
  }
1230
1557
  },
@@ -1241,7 +1568,7 @@
1241
1568
  componentDidMount: function() {
1242
1569
  this.state.filter.onChange(this.updateFilter);
1243
1570
  this.state.viewMode.onChange(this.updateViewMode);
1244
- this.state.uploadSet.onChange(this.updateUploadSet);
1571
+ this.state.addedObjsCollection.onChange(this.updateAddedObjsCollection);
1245
1572
  this.state.objCollection.onChange(this.updateObjCollection);
1246
1573
  this.state.objCollection.on('loading-obj', this.setLoadingState);
1247
1574
  this.state.inspector.onChange(this.updateInspector);
@@ -1256,7 +1583,7 @@
1256
1583
  filter: this.props.initialFilter,
1257
1584
  objs: [],
1258
1585
  viewMode: new models.ViewMode(),
1259
- uploadSet: new models.UploadSet(basePreset),
1586
+ addedObjsCollection: new models.AddedObjsCollection(basePreset),
1260
1587
  objCollection: new models.ObjCollection(initialSelection, selectionMode),
1261
1588
  inspector: new models.Inspector()
1262
1589
  };
@@ -1280,7 +1607,7 @@
1280
1607
  "ref": "itemView",
1281
1608
  "objCollection": this.state.objCollection,
1282
1609
  "viewMode": this.state.viewMode,
1283
- "uploadSet": this.state.uploadSet,
1610
+ "addedObjsCollection": this.state.addedObjsCollection,
1284
1611
  "inspector": this.state.inspector,
1285
1612
  "filter": this.state.filter
1286
1613
  }), React.createElement(ui.MoreItemsSpinner, {
@@ -1297,9 +1624,6 @@
1297
1624
  ui.Filter = React.createClass({
1298
1625
  displayName: 'Filter',
1299
1626
  mixins: [FilterMixin],
1300
- handleDeselectAllFilters: function() {
1301
- return this.props.filter.deactivateAllFilters();
1302
- },
1303
1627
  renderAdditionalFilters: function() {
1304
1628
  var subFilters;
1305
1629
  subFilters = _.map(this.props.filter.additionalFilters, function(additionalFilter) {
@@ -1365,9 +1689,7 @@
1365
1689
  "activateSelectedFilter": this.activateSelectedFilter
1366
1690
  }), React.createElement("div", {
1367
1691
  "className": "scrivito-content-browser-filter-scroll"
1368
- }, React.createElement(ui.Filter.DeselectFilter, {
1369
- "onDeselectAllFilters": this.handleDeselectAllFilters
1370
- }), this.renderSubFiltersList(treeSubFilters), this.renderFilterSeparator(), this.renderAdditionalFilters()));
1692
+ }, this.renderSubFiltersList(treeSubFilters), this.renderFilterSeparator(), this.renderAdditionalFilters()));
1371
1693
  }
1372
1694
  });
1373
1695
 
@@ -1456,19 +1778,6 @@
1456
1778
  }
1457
1779
  });
1458
1780
 
1459
- ui.Filter.DeselectFilter = React.createClass({
1460
- displayName: 'DeselectFilter',
1461
- handleDeselect: function() {
1462
- return this.props.onDeselectAllFilters();
1463
- },
1464
- render: function() {
1465
- return React.createElement("div", {
1466
- "className": "scrivito_button",
1467
- "onClick": this.handleDeselect
1468
- }, "deselect all");
1469
- }
1470
- });
1471
-
1472
1781
  ui.Filter.RadioOptionFilter = React.createClass({
1473
1782
  displayName: 'RadioOptionFilter',
1474
1783
  mixins: [OptionFilterMixin],
@@ -1503,8 +1812,6 @@
1503
1812
  "className": this.filterClass(),
1504
1813
  "onClick": this.props.activateSelectedFilter
1505
1814
  }, React.createElement("span", {
1506
- "className": "scrivito_icon scrivito_icon_ok_box"
1507
- }), React.createElement("span", {
1508
1815
  "className": "scrivito-content-browser-filter-label"
1509
1816
  }, "Selected", React.createElement("span", {
1510
1817
  "className": "scrivito-content-browser-counter selected-total"
@@ -1624,14 +1931,14 @@
1624
1931
  }, this.props.inspector.fileDetail())), React.createElement("div", {
1625
1932
  "className": "inspector-content"
1626
1933
  }, (this.props.inspector.getInspectedObj().hasDetailsView() ? React.createElement("iframe", {
1627
- "src": this.props.inspector.inspectorUrl()
1934
+ "src": this.props.inspector.inspectorUrl(),
1935
+ "name": "scrivito_inspector"
1628
1936
  }) : this.getEmptyPlaceholder()))) : void 0));
1629
1937
  }
1630
1938
  });
1631
1939
 
1632
1940
  ui.Items = React.createClass({
1633
1941
  displayName: 'Items',
1634
- mixins: [InfiniteScrollMixin],
1635
1942
  getInitialState: function() {
1636
1943
  return {
1637
1944
  dragInProgres: false
@@ -1654,7 +1961,7 @@
1654
1961
  if (files.length > 0) {
1655
1962
  preset = this.buildPreset();
1656
1963
  if (preset.isValid()) {
1657
- return this.props.uploadSet.addFiles(files, preset.values());
1964
+ return this.props.addedObjsCollection.addFiles(files, preset.values());
1658
1965
  } else {
1659
1966
  message = 'The selected filter options cannot be applied to the file(s) you wanted to upload. Please select only one of the following options, then try again:\n';
1660
1967
  _.each(preset.errors(), function(values, field) {
@@ -1680,20 +1987,6 @@
1680
1987
  };
1681
1988
  })(this);
1682
1989
  },
1683
- fillViewPort: function() {
1684
- if (!this._isFullViewPort()) {
1685
- return this.loadingAdditionalItems();
1686
- }
1687
- },
1688
- _isFullViewPort: function() {
1689
- return this.getDOMNode().scrollHeight > this.getDOMNode().offsetHeight;
1690
- },
1691
- loadingAdditionalItems: function() {
1692
- return this.props.objCollection.loadNextPage();
1693
- },
1694
- hasMoreItems: function() {
1695
- return this.props.objCollection.hasMoreItems();
1696
- },
1697
1990
  render: function() {
1698
1991
  return React.createElement("div", {
1699
1992
  "className": this.dropZoneClass(),
@@ -1704,14 +1997,19 @@
1704
1997
  "className": "scrivito-content-browser-loading"
1705
1998
  }, React.createElement("i", {
1706
1999
  "className": "scrivito_icon scrivito_icon_refresh"
1707
- })) : this.props.uploadSet.hasActiveUploads() ? React.createElement(ui.UploadItems, {
1708
- "uploadSet": this.props.uploadSet
1709
- }) : React.createElement(ui.ThumbnailItems, {
2000
+ })) : this.props.addedObjsCollection.hasActiveCreations() ? React.createElement(ui.UploadItems, {
2001
+ "addedObjsCollection": this.props.addedObjsCollection
2002
+ }) : this.props.viewMode.isList() ? React.createElement(ui.TableView, {
1710
2003
  "objCollection": this.props.objCollection,
1711
- "onBuildAllItems": this.fillViewPort,
1712
- "viewMode": this.props.viewMode,
1713
2004
  "toggleSelected": this.props.toggleSelected,
1714
2005
  "inspector": this.props.inspector
2006
+ }) : React.createElement(ui.ThumbnailItems, {
2007
+ "objCollection": this.props.objCollection,
2008
+ "viewMode": this.props.viewMode.getMode(),
2009
+ "onBuildAllItems": this.fillViewPort,
2010
+ "inspector": this.props.inspector,
2011
+ "filter": this.props.filter,
2012
+ "addedObjsCollection": this.props.addedObjsCollection
1715
2013
  })));
1716
2014
  }
1717
2015
  });
@@ -1748,27 +2046,6 @@
1748
2046
  }
1749
2047
  });
1750
2048
 
1751
- ui.ResizeBar = React.createClass({
1752
- displayName: 'ResizeBar',
1753
- resizeButtonsData: ["small", "normal", "big", "large"],
1754
- render: function() {
1755
- var size;
1756
- return React.createElement("div", null, (function() {
1757
- var _i, _len, _ref, _results;
1758
- _ref = this.resizeButtonsData;
1759
- _results = [];
1760
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1761
- size = _ref[_i];
1762
- _results.push(React.createElement(ui.ResizeItem, {
1763
- "viewMode": this.props.viewMode,
1764
- "size": size
1765
- }));
1766
- }
1767
- return _results;
1768
- }).call(this));
1769
- }
1770
- });
1771
-
1772
2049
  ui.ResizeItem = React.createClass({
1773
2050
  displayName: 'ResizeItem',
1774
2051
  resizeButtonsData: {
@@ -1816,17 +2093,196 @@
1816
2093
  }
1817
2094
  });
1818
2095
 
2096
+ ui.TableView = React.createClass({
2097
+ render: function() {
2098
+ return React.createElement("div", {
2099
+ "className": "scrivito-content-browser-list"
2100
+ }, React.createElement("div", {
2101
+ "className": "scrivito-content-browser-list-head"
2102
+ }, React.createElement("table", null, React.createElement("tbody", null, React.createElement("tr", null, React.createElement("th", null), React.createElement("th", null, "Title"), React.createElement("th", null, "Type"), React.createElement("th", null, "File type"), React.createElement("th", null, "File size"), React.createElement("th", null, "Last change"))))), React.createElement(ui.TableViewContent, React.__spread({}, this.props)));
2103
+ }
2104
+ });
2105
+
2106
+ ui.TableViewContent = React.createClass({
2107
+ mixins: [InfiniteScrollMixin],
2108
+ getTableViewItems: function() {
2109
+ var items;
2110
+ return items = _.map(this.props.objCollection.objs(), (function(_this) {
2111
+ return function(obj) {
2112
+ return React.createElement(ui.TableViewItem, {
2113
+ "key": obj.id(),
2114
+ "obj": obj,
2115
+ "objCollection": _this.props.objCollection,
2116
+ "inspector": _this.props.inspector
2117
+ });
2118
+ };
2119
+ })(this));
2120
+ },
2121
+ getElementDOMNode: function() {
2122
+ return this.getDOMNode();
2123
+ },
2124
+ render: function() {
2125
+ return React.createElement("div", {
2126
+ "className": "scrivito-content-browser-list-content"
2127
+ }, React.createElement("table", null, React.createElement("tbody", null, this.getTableViewItems())));
2128
+ }
2129
+ });
2130
+
2131
+ ui.TableViewItem = React.createClass({
2132
+ displayName: 'TableViewItem',
2133
+ mixins: [InspectedItemMixin],
2134
+ baseSelectClass: function() {
2135
+ return 'scrivito-content-browser-list-select';
2136
+ },
2137
+ getLastChangedFormatedDate: function() {
2138
+ var result;
2139
+ if (this.props.obj.lastChanged() !== void 0) {
2140
+ result = moment(this.props.obj.lastChanged()).zone(this.props.obj.lastChanged());
2141
+ return result.format("dddd, MMMM Do YYYY, h:mm A");
2142
+ }
2143
+ },
2144
+ _getFileTypeTitleTag: function() {
2145
+ var mimeType;
2146
+ mimeType = this.props.obj.mimeType();
2147
+ if (mimeType != null) {
2148
+ return mimeType.match(/\w+$/)[0];
2149
+ }
2150
+ },
2151
+ render: function() {
2152
+ return React.createElement("tr", {
2153
+ "onClick": this.changeInspectObj,
2154
+ "className": this.getItemClasses()
2155
+ }, React.createElement("td", null, React.createElement("div", {
2156
+ "onClick": this.handleSelectClick,
2157
+ "className": this.selectClass()
2158
+ })), React.createElement("td", {
2159
+ "title": this.props.obj.title()
2160
+ }, this.props.obj.title()), React.createElement("td", null, this.props.obj.fileType()), React.createElement("td", {
2161
+ "title": this.props.obj.mimeType()
2162
+ }, this._getFileTypeTitleTag()), React.createElement("td", null, this.props.obj.fileSize()), React.createElement("td", null, React.createElement("span", null, React.createElement("time", {
2163
+ "dateTime": this.props.obj.lastChanged(),
2164
+ "title": this.getLastChangedFormatedDate()
2165
+ }, moment.utc(this.props.obj.lastChanged()).fromNow()))));
2166
+ }
2167
+ });
2168
+
2169
+ ui.ThumbnailAddItem = React.createClass({
2170
+ displayName: 'ThumbnailAddItem',
2171
+ itemClassName: function() {
2172
+ var className;
2173
+ className = "scrivito-content-browser-add";
2174
+ if (!this.props.objCreation.isActive()) {
2175
+ className += " disabled";
2176
+ }
2177
+ return className;
2178
+ },
2179
+ iconClassName: function() {
2180
+ var iconClass;
2181
+ iconClass = this.props.objCreation.isActive() ? "scrivito_icon_plus" : "scrivito_icon_disabled";
2182
+ return "scrivito_icon " + iconClass;
2183
+ },
2184
+ creationNotPossibleBody: function(error) {
2185
+ return React.createElement("ul", null, _.map(error.nodeTitles, function(title) {
2186
+ return React.createElement("li", null, title);
2187
+ }));
2188
+ },
2189
+ presetConflictBody: function(error) {
2190
+ return React.createElement("div", null, "The selected filter options cannot be applied to the file(s)\nyou wanted to upload. Please select only one of the following options,\nthen try again:\n", _.map(error.fields, function(values, field) {
2191
+ return React.createElement("div", null, React.createElement("h4", null, field), React.createElement("ul", null, _.map(values, function(value) {
2192
+ return React.createElement("li", null, value);
2193
+ })));
2194
+ }));
2195
+ },
2196
+ showErrorAlert: function(error) {
2197
+ var alertProps;
2198
+ alertProps = (function() {
2199
+ switch (error.type) {
2200
+ case 'creation_not_possible':
2201
+ return {
2202
+ subtitle: 'Creation of items matching the selected filters has been disabled.',
2203
+ body: this.creationNotPossibleBody(error)
2204
+ };
2205
+ case 'obj_class_not_provided':
2206
+ return {
2207
+ subtitle: "Configuration error: No '_obj_class' provided."
2208
+ };
2209
+ case 'preset_conflict':
2210
+ return {
2211
+ body: this.presetConflictBody(error)
2212
+ };
2213
+ }
2214
+ }).call(this);
2215
+ alertProps.title = "Creation not possible";
2216
+ return scrivito.content_browser._showAlert(alertProps);
2217
+ },
2218
+ buildErrorMessage: function(error) {
2219
+ var message, nodesString;
2220
+ switch (error.type) {
2221
+ case 'creation_not_possible':
2222
+ nodesString = error.nodeTitles.join(', ');
2223
+ return "The selected filter options " + nodesString + " prevent the creation";
2224
+ case 'obj_class_not_provided':
2225
+ return "Configuration error: No '_obj_class' provided";
2226
+ case 'preset_conflict':
2227
+ message = 'The selected filter options cannot be applied to the file(s) you wanted to upload. Please select only one of the following options, then try again:\n';
2228
+ _.each(error.fields, function(value, field) {
2229
+ return message += "" + field + ": " + (value.join(', ')) + "\n";
2230
+ });
2231
+ return message;
2232
+ }
2233
+ },
2234
+ iconTitle: function() {
2235
+ if (!this.props.objCreation.isActive()) {
2236
+ return this.buildErrorMessage(this.props.objCreation.error());
2237
+ }
2238
+ },
2239
+ textMessage: function() {
2240
+ if (this.props.objCreation.isActive()) {
2241
+ return "Create Item";
2242
+ } else {
2243
+ return "Item creation not possible";
2244
+ }
2245
+ },
2246
+ handleClick: function() {
2247
+ if (this.props.objCreation.isActive()) {
2248
+ return this.props.addedObjsCollection.createObj(this.props.objCreation.preset());
2249
+ } else {
2250
+ return this.showErrorAlert(this.props.objCreation.error());
2251
+ }
2252
+ },
2253
+ render: function() {
2254
+ return React.createElement("li", {
2255
+ "className": "content-browser-item",
2256
+ "onClick": this.handleClick
2257
+ }, React.createElement("div", {
2258
+ "className": this.itemClassName()
2259
+ }, React.createElement("div", {
2260
+ "className": "scrivito-content-browser-text"
2261
+ }, React.createElement("span", {
2262
+ "className": this.iconClassName(),
2263
+ "title": this.iconTitle()
2264
+ }), React.createElement("span", null, this.textMessage()))));
2265
+ }
2266
+ });
2267
+
1819
2268
  ui.ThumbnailItem = React.createClass({
1820
2269
  displayName: 'ThumbnailItem',
1821
- title: function() {
1822
- return this.props.obj.title();
2270
+ mixins: [InspectedItemMixin],
2271
+ itemToolTip: function() {
2272
+ var itemToolTip;
2273
+ itemToolTip = this.props.obj.title();
2274
+ if (this.props.obj.subtitle() != null) {
2275
+ itemToolTip += "\n" + (this.props.obj.subtitle());
2276
+ }
2277
+ return itemToolTip;
1823
2278
  },
1824
- selectClass: function() {
2279
+ baseSelectClass: function() {
2280
+ return 'scrivito-content-browser-meta ';
2281
+ },
2282
+ mimeTypeIconClassName: function() {
1825
2283
  var className;
1826
- className = 'scrivito-content-browser-thumbnails-select select-item';
1827
- if (this.props.objCollection.isSelected(this.props.obj.id())) {
1828
- className += ' active';
1829
- }
2284
+ className = 'scrivito_icon ';
2285
+ className += models.MimeTypeIcon.getMimeTypeIconClassName(this.props.obj.mimeType());
1830
2286
  return className;
1831
2287
  },
1832
2288
  previewImage: function() {
@@ -1836,22 +2292,10 @@
1836
2292
  });
1837
2293
  } else {
1838
2294
  return React.createElement("span", {
1839
- "className": "scrivito_icon scrivito_icon_generic"
2295
+ "className": this.mimeTypeIconClassName()
1840
2296
  });
1841
2297
  }
1842
2298
  },
1843
- handleSelectClick: function() {
1844
- return this.props.objCollection.toggleSelected(this.props.obj.id());
1845
- },
1846
- changeInspectObj: function() {
1847
- return this.props.inspector.setInspectedObj(this.props.obj);
1848
- },
1849
- getItemClasses: function() {
1850
- return classSet({
1851
- 'active': this.props.inspector.getInspectedObj() === this.props.obj,
1852
- "content-browser-item": true
1853
- });
1854
- },
1855
2299
  render: function() {
1856
2300
  return React.createElement("li", {
1857
2301
  "className": this.getItemClasses()
@@ -1863,26 +2307,35 @@
1863
2307
  }, this.previewImage(), React.createElement("span", {
1864
2308
  "className": "scrivito-content-browser-inspect"
1865
2309
  })), React.createElement("div", {
1866
- "className": "scrivito-content-browser-meta",
1867
- "onClick": this.handleSelectClick
2310
+ "className": this.selectClass(),
2311
+ "onClick": this.handleSelectClick,
2312
+ "title": this.itemToolTip()
1868
2313
  }, React.createElement("span", {
1869
- "className": "scrivito-content-browser-thumbnails-name",
1870
- "title": this.title()
1871
- }, this.title()), React.createElement("span", {
1872
- "className": this.selectClass()
1873
- }))));
2314
+ "className": "scrivito-content-browser-thumbnails-name"
2315
+ }, this.props.obj.title()), React.createElement("span", {
2316
+ "className": "scrivito-content-browser-thumbnails-size"
2317
+ }, this.props.obj.subtitle()), (!this.props.objCollection.isSingleSelectionMode() ? React.createElement("span", {
2318
+ "className": 'scrivito-content-browser-thumbnails-select select-item'
2319
+ }) : void 0))));
1874
2320
  }
1875
2321
  });
1876
2322
 
1877
2323
  ui.ThumbnailItems = React.createClass({
1878
2324
  displayName: 'ThumbnailItems',
2325
+ mixins: [InfiniteScrollMixin],
2326
+ getElementDOMNode: function() {
2327
+ return this.getDOMNode().parentElement;
2328
+ },
1879
2329
  getSizeClassName: function() {
1880
- return "items scrivito-content-browser-thumbnails " + (this.props.viewMode.getMode());
2330
+ return "items scrivito-content-browser-thumbnails small";
1881
2331
  },
1882
- componentDidUpdate: function() {
1883
- if (this.props.objCollection.objs().length > 0) {
1884
- return this.handleBuildItems();
1885
- }
2332
+ activeFilterNodes: function() {
2333
+ var collector;
2334
+ collector = new models.ActiveNodeConfigCollector(this.props.filter);
2335
+ return collector.findActiveFilterItems();
2336
+ },
2337
+ objCreation: function() {
2338
+ return new models.ObjCreation(this.props.filter);
1886
2339
  },
1887
2340
  buildItems: function() {
1888
2341
  return _.map(this.props.objCollection.objs(), (function(_this) {
@@ -1896,13 +2349,13 @@
1896
2349
  };
1897
2350
  })(this));
1898
2351
  },
1899
- handleBuildItems: function() {
1900
- return this.props.onBuildAllItems();
1901
- },
1902
2352
  render: function() {
1903
2353
  return React.createElement("ul", {
1904
2354
  "className": this.getSizeClassName()
1905
- }, this.buildItems());
2355
+ }, (this.objCreation().showCreationItem() ? React.createElement(ui.ThumbnailAddItem, {
2356
+ "objCreation": this.objCreation(),
2357
+ "addedObjsCollection": this.props.addedObjsCollection
2358
+ }) : void 0), this.buildItems());
1906
2359
  }
1907
2360
  });
1908
2361
 
@@ -1921,6 +2374,22 @@
1921
2374
  return this.setSearchTerm();
1922
2375
  }
1923
2376
  },
2377
+ _getSearchPlaceholder: function() {
2378
+ var activeCriteriaTitle, activeFilters, actvieFilterNodeConfigs, collector, searchPlaceHolder;
2379
+ collector = new models.ActiveNodeConfigCollector(this.props.filter);
2380
+ searchPlaceHolder = "Search everywhere";
2381
+ actvieFilterNodeConfigs = collector.findActiveFilterItems();
2382
+ activeFilters = _.flatten(_.map(actvieFilterNodeConfigs, function(config) {
2383
+ return config.activeNodes();
2384
+ }));
2385
+ if (activeFilters.length > 1) {
2386
+ searchPlaceHolder = "Search filtered content";
2387
+ } else if (activeFilters.length === 1) {
2388
+ activeCriteriaTitle = activeFilters[0].title;
2389
+ searchPlaceHolder = "Search \"" + activeCriteriaTitle + "\" ";
2390
+ }
2391
+ return searchPlaceHolder;
2392
+ },
1924
2393
  updateSearchTerm: function(event) {
1925
2394
  return this.setState({
1926
2395
  searchTerm: event.target.value
@@ -1933,7 +2402,7 @@
1933
2402
  "className": "scrivito-content-browser-search"
1934
2403
  }, React.createElement("input", {
1935
2404
  "type": "text",
1936
- "placeholder": "Search",
2405
+ "placeholder": this._getSearchPlaceholder(),
1937
2406
  "className": "search-field",
1938
2407
  "value": this.state.searchTerm,
1939
2408
  "onChange": this.updateSearchTerm,
@@ -1941,7 +2410,7 @@
1941
2410
  }), React.createElement("button", {
1942
2411
  "className": "search-field-button",
1943
2412
  "onClick": this.setSearchTerm
1944
- }, "Search")), React.createElement(ui.ResizeBar, {
2413
+ }, "Search")), React.createElement(ui.ViewModeBar, {
1945
2414
  "viewMode": this.props.viewMode
1946
2415
  }));
1947
2416
  }
@@ -1980,7 +2449,7 @@
1980
2449
  displayName: 'UploadItems',
1981
2450
  render: function() {
1982
2451
  var items;
1983
- items = _.map(this.props.uploadSet.uploads(), function(objUpload) {
2452
+ items = _.map(this.props.addedObjsCollection.objs(), function(objUpload) {
1984
2453
  return React.createElement(ui.UploadItem, {
1985
2454
  "objUpload": objUpload
1986
2455
  });
@@ -1991,6 +2460,66 @@
1991
2460
  }
1992
2461
  });
1993
2462
 
2463
+ ui.ViewModeBar = React.createClass({
2464
+ displayName: 'ViewModeBar',
2465
+ viewModeButtonsData: ["list", "thumbnails"],
2466
+ render: function() {
2467
+ var mode;
2468
+ return React.createElement("div", null, (function() {
2469
+ var _i, _len, _ref, _results;
2470
+ _ref = this.viewModeButtonsData;
2471
+ _results = [];
2472
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2473
+ mode = _ref[_i];
2474
+ _results.push(React.createElement(ui.ViewModeBarItem, {
2475
+ "viewMode": this.props.viewMode,
2476
+ "mode": mode
2477
+ }));
2478
+ }
2479
+ return _results;
2480
+ }).call(this));
2481
+ }
2482
+ });
2483
+
2484
+ ui.ViewModeBarItem = React.createClass({
2485
+ displayName: 'ViewModeBarItem',
2486
+ viewModeButtonsData: {
2487
+ "thumbnails": {
2488
+ iconTitle: "Thumbnails",
2489
+ iconClassName: "scrivito_icon_th_small"
2490
+ },
2491
+ "list": {
2492
+ iconTitle: "List",
2493
+ iconClassName: "scrivito_icon_list_medium"
2494
+ }
2495
+ },
2496
+ getIconClassName: function(mode) {
2497
+ return "scrivito_icon " + this.viewModeButtonsData[mode].iconClassName;
2498
+ },
2499
+ getIconTitle: function(mode) {
2500
+ return this.viewModeButtonsData[mode].iconTitle;
2501
+ },
2502
+ getLabelClasses: function() {
2503
+ return classSet({
2504
+ 'active': this.props.viewMode.getMode() === this.props.mode,
2505
+ "editing-button-view": true
2506
+ });
2507
+ },
2508
+ changeViewMode: function() {
2509
+ return this.props.viewMode.setMode(this.props.mode);
2510
+ },
2511
+ render: function() {
2512
+ return React.createElement("span", {
2513
+ "data-size": this.props.mode,
2514
+ "className": this.getLabelClasses(),
2515
+ "onClick": this.changeViewMode
2516
+ }, React.createElement("i", {
2517
+ "title": this.getIconTitle(this.props.mode),
2518
+ "className": this.getIconClassName(this.props.mode)
2519
+ }));
2520
+ }
2521
+ });
2522
+
1994
2523
  scrivito.content_browser.stub_filters = {
1995
2524
  categories: {
1996
2525
  type: 'tree',