mirror of
https://github.com/flarum/core.git
synced 2025-07-18 23:31:17 +02:00
Big component restructure/overhaul
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.View.extend({
|
||||
title: '',
|
||||
icon: '',
|
||||
class: '',
|
||||
action: null,
|
||||
|
||||
tagName: 'a',
|
||||
classNames: ['btn'],
|
||||
classNameBindings: ['class', 'disabled'],
|
||||
|
||||
layout: Ember.Handlebars.compile('{{#if view.icon}}{{fa-icon view.icon class="fa-fw"}} {{/if}}<span class="label">{{view.title}}</span>'),
|
||||
|
||||
click: function() {
|
||||
this.action();
|
||||
}
|
||||
});
|
@@ -1,55 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import Menu from '../utils/menu';
|
||||
import MenuItem from '../components/menu-item';
|
||||
|
||||
export default Ember.View.extend({
|
||||
tagName: 'article',
|
||||
templateName: 'discussion-post',
|
||||
|
||||
controls: null,
|
||||
|
||||
contentComponent: function() {
|
||||
return 'post-type-'+this.get('post.type');
|
||||
}.property('post.type'),
|
||||
|
||||
classNames: ['post'],
|
||||
classNameBindings: ['post.deleted', 'post.edited'],
|
||||
|
||||
construct: function() {
|
||||
this.set('controls', Menu.create());
|
||||
|
||||
var post = this.get('post');
|
||||
|
||||
if (post.get('deleted')) {
|
||||
this.addControl('restore', 'Restore', 'reply', 'canEdit');
|
||||
this.addControl('delete', 'Delete', 'times', 'canDelete');
|
||||
} else {
|
||||
if (post.get('type') == 'comment') {
|
||||
this.addControl('edit', 'Edit', 'pencil', 'canEdit');
|
||||
this.addControl('hide', 'Delete', 'times', 'canEdit');
|
||||
} else {
|
||||
this.addControl('delete', 'Delete', 'times', 'canDelete');
|
||||
}
|
||||
}
|
||||
}.on('init'),
|
||||
|
||||
didInsertElement: function() {
|
||||
this.$().hide().fadeIn('slow');
|
||||
},
|
||||
|
||||
addControl: function(tag, title, icon, permissionAttribute) {
|
||||
if (permissionAttribute && ! this.get('post').get(permissionAttribute)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var action = function(post) {
|
||||
self.get('controller').send(actionName, post);
|
||||
};
|
||||
|
||||
var item = MenuItem.extend({title: title, icon: icon, action: action});
|
||||
this.get('controls').addItem(tag, item);
|
||||
}
|
||||
|
||||
});
|
@@ -1,12 +1,12 @@
|
||||
|
||||
import Ember from 'ember';
|
||||
import Menu from '../utils/menu';
|
||||
import MenuItem from '../components/menu-item';
|
||||
|
||||
export default Ember.View.extend({
|
||||
import TaggedArray from '../../utils/tagged-array';
|
||||
import ActionButton from '../ui/controls/action-button';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
|
||||
_init: function() {
|
||||
this.set('controls', Menu.create());
|
||||
// this.set('controls', Menu.create());
|
||||
}.on('init'),
|
||||
|
||||
tagName: 'li',
|
||||
@@ -18,7 +18,7 @@ export default Ember.View.extend({
|
||||
'discussion.following:following',
|
||||
'active'
|
||||
],
|
||||
templateName: 'discussions-result',
|
||||
templateName: 'components/discussions/discussion-listing',
|
||||
|
||||
active: function() {
|
||||
return this.get('childViews').anyBy('active');
|
55
framework/core/ember/app/components/discussions/post.js
Normal file
55
framework/core/ember/app/components/discussions/post.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import TaggedArray from '../../utils/tagged-array';
|
||||
import ActionButton from '../ui/controls/action-button';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'article',
|
||||
templateName: 'components/discussions/post',
|
||||
|
||||
// controls: null,
|
||||
|
||||
contentComponent: function() {
|
||||
return 'discussions/post-'+this.get('post.type');
|
||||
}.property('post.type'),
|
||||
|
||||
classNames: ['post'],
|
||||
classNameBindings: ['post.deleted', 'post.edited'],
|
||||
|
||||
construct: function() {
|
||||
// this.set('controls', Menu.create());
|
||||
|
||||
// var post = this.get('post');
|
||||
|
||||
// if (post.get('deleted')) {
|
||||
// this.addControl('restore', 'Restore', 'reply', 'canEdit');
|
||||
// this.addControl('delete', 'Delete', 'times', 'canDelete');
|
||||
// } else {
|
||||
// if (post.get('type') == 'comment') {
|
||||
// this.addControl('edit', 'Edit', 'pencil', 'canEdit');
|
||||
// this.addControl('hide', 'Delete', 'times', 'canEdit');
|
||||
// } else {
|
||||
// this.addControl('delete', 'Delete', 'times', 'canDelete');
|
||||
// }
|
||||
// }
|
||||
}.on('init'),
|
||||
|
||||
didInsertElement: function() {
|
||||
this.$().hide().fadeIn('slow');
|
||||
},
|
||||
|
||||
addControl: function(tag, title, icon, permissionAttribute) {
|
||||
if (permissionAttribute && ! this.get('post').get(permissionAttribute)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var action = function(post) {
|
||||
self.get('controller').send(actionName, post);
|
||||
};
|
||||
|
||||
var item = MenuItem.extend({title: title, icon: icon, action: action});
|
||||
this.get('controls').addItem(tag, item);
|
||||
}
|
||||
|
||||
});
|
@@ -4,7 +4,7 @@ import Ember from 'ember';
|
||||
// single item may represent a single post, or it may represent a gap of many
|
||||
// posts which have not been loaded.
|
||||
|
||||
export default Ember.View.extend({
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['item'],
|
||||
classNameBindings: ['item.gap:gap', 'loading', 'direction'],
|
||||
attributeBindings: [
|
@@ -1,8 +1,7 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import MenuItem from '../components/menu-item';
|
||||
import Scrollbar from '../utils/scrollbar';
|
||||
import PostStreamMixin from '../mixins/post-stream';
|
||||
import Scrollbar from '../../utils/scrollbar';
|
||||
import PostStreamMixin from '../../mixins/post-stream';
|
||||
|
||||
export default Ember.View.extend(PostStreamMixin, {
|
||||
|
||||
@@ -10,7 +9,7 @@ export default Ember.View.extend(PostStreamMixin, {
|
||||
@property templateName
|
||||
@type String
|
||||
*/
|
||||
templateName: 'components/discussion-scrollbar',
|
||||
templateName: 'components/discussions/stream-scrollbar',
|
||||
classNames: ['scrubber', 'discussion-scrubber'],
|
||||
|
||||
// An object which represents/ecapsulates the scrollbar.
|
@@ -1,37 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import MenuItemContainer from '../components/menu-item-container';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
items: null, // NamedContainerView/Menu
|
||||
layoutName: 'components/dropdown-button',
|
||||
classNames: ['dropdown', 'btn-group'],
|
||||
classNameBindings: ['itemCountClass'],
|
||||
|
||||
title: 'Controls',
|
||||
icon: 'ellipsis-v',
|
||||
buttonClass: 'btn-default',
|
||||
menuClass: 'pull-right',
|
||||
|
||||
dropdownMenuClass: function() {
|
||||
return 'dropdown-menu '+this.get('menuClass');
|
||||
}.property('menuClass'),
|
||||
|
||||
itemCountClass: function() {
|
||||
return 'item-count-'+this.get('items.length');
|
||||
}.property('items'),
|
||||
|
||||
containedItems: function() {
|
||||
var contained = [];
|
||||
this.get('items').forEach(function(item) {
|
||||
if (item.tagName != 'li') {
|
||||
contained.push(MenuItemContainer.extend({
|
||||
item: item
|
||||
}));
|
||||
} else {
|
||||
contained.push(item);
|
||||
}
|
||||
});
|
||||
return contained;
|
||||
}.property('items.[]')
|
||||
});
|
@@ -1,40 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import MenuItemContainer from '../components/menu-item-container';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
items: null, // NamedContainerView/Menu
|
||||
layoutName: 'components/dropdown-split',
|
||||
classNames: ['dropdown', 'dropdown-split', 'btn-group'],
|
||||
classNameBindings: ['itemCountClass'],
|
||||
|
||||
buttonClass: 'btn-default',
|
||||
menuClass: 'pull-right',
|
||||
icon: 'ellipsis-v',
|
||||
|
||||
mainButtonClass: function() {
|
||||
return 'btn '+this.get('buttonClass');
|
||||
}.property('buttonClass'),
|
||||
|
||||
dropdownMenuClass: function() {
|
||||
return 'dropdown-menu '+this.get('menuClass');
|
||||
}.property('menuClass'),
|
||||
|
||||
itemCountClass: function() {
|
||||
return 'item-count-'+this.get('items.length');
|
||||
}.property('items'),
|
||||
|
||||
containedItems: function() {
|
||||
var contained = [];
|
||||
this.get('items').forEach(function(item) {
|
||||
if (item.tagName != 'li') {
|
||||
contained.push(MenuItemContainer.extend({
|
||||
item: item
|
||||
}));
|
||||
} else {
|
||||
contained.push(item);
|
||||
}
|
||||
});
|
||||
return contained;
|
||||
}.property('items.[]')
|
||||
});
|
@@ -1,6 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'ul',
|
||||
layoutName: 'components/item-collection',
|
||||
});
|
@@ -1,6 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'ul',
|
||||
layoutName: 'components/menu-list'
|
||||
});
|
@@ -1,6 +1,6 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
var MenuItem = Ember.Component.extend({
|
||||
export default Ember.Component.extend({
|
||||
title: '',
|
||||
icon: '',
|
||||
className: '',
|
||||
@@ -8,6 +8,8 @@ var MenuItem = Ember.Component.extend({
|
||||
divider: false,
|
||||
active: false,
|
||||
|
||||
classNames: ['btn', 'btn-default'],
|
||||
|
||||
tagName: 'a',
|
||||
attributeBindings: ['href'],
|
||||
classNameBindings: ['className'],
|
||||
@@ -19,14 +21,4 @@ var MenuItem = Ember.Component.extend({
|
||||
// this.sendAction('action');
|
||||
this.get('action')();
|
||||
}
|
||||
});
|
||||
|
||||
MenuItem.reopenClass({
|
||||
separator: function() {
|
||||
return this.create({
|
||||
divider: true
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
export default MenuItem;
|
||||
});
|
@@ -0,0 +1,21 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
items: null, // TaggedArray
|
||||
layoutName: 'components/ui/controls/dropdown-button',
|
||||
classNames: ['dropdown', 'btn-group'],
|
||||
classNameBindings: ['itemCountClass'],
|
||||
|
||||
title: 'Controls',
|
||||
icon: 'ellipsis-v',
|
||||
buttonClass: 'btn-default',
|
||||
menuClass: 'pull-right',
|
||||
|
||||
dropdownMenuClass: function() {
|
||||
return 'dropdown-menu '+this.get('menuClass');
|
||||
}.property('menuClass'),
|
||||
|
||||
itemCountClass: function() {
|
||||
return 'item-count-'+this.get('items.length');
|
||||
}.property('items.length')
|
||||
});
|
@@ -1,10 +1,8 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import Menu from '../utils/menu';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
items: [],
|
||||
layoutName: 'components/dropdown-select',
|
||||
layoutName: 'components/ui/controls/dropdown-select',
|
||||
classNames: ['dropdown', 'dropdown-select', 'btn-group'],
|
||||
classNameBindings: ['itemCountClass'],
|
||||
|
||||
@@ -24,7 +22,12 @@ export default Ember.Component.extend({
|
||||
return 'item-count-'+this.get('items.length');
|
||||
}.property('items.length'),
|
||||
|
||||
currentItem: function() {
|
||||
activeItem: function() {
|
||||
return this.get('menu.childViews').findBy('active');
|
||||
}.property('menu.childViews.@each.active')
|
||||
|
||||
}).reopenClass({
|
||||
createWithItems: function(items) {
|
||||
return this.create({items: items});
|
||||
}
|
||||
});
|
@@ -0,0 +1,16 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import DropdownButton from './dropdown-button';
|
||||
|
||||
export default DropdownButton.extend({
|
||||
layoutName: 'components/ui/controls/dropdown-split',
|
||||
classNames: ['dropdown', 'dropdown-split', 'btn-group'],
|
||||
|
||||
mainButtonClass: function() {
|
||||
return 'btn '+this.get('buttonClass');
|
||||
}.property('buttonClass'),
|
||||
|
||||
firstItem: function() {
|
||||
return this.get('items').objectAt(0);
|
||||
}.property('items.[]')
|
||||
});
|
20
framework/core/ember/app/components/ui/controls/item-list.js
Normal file
20
framework/core/ember/app/components/ui/controls/item-list.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import ComponentItem from '../items/component-item';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'ul',
|
||||
layoutName: 'components/ui/controls/item-list',
|
||||
|
||||
listItems: function() {
|
||||
if (!this.get('items')) return [];
|
||||
var listItems = [];
|
||||
this.get('items').forEach(function(item) {
|
||||
if (item.tagName != 'li') {
|
||||
item = ComponentItem.extend({component: item});
|
||||
}
|
||||
listItems.push(item);
|
||||
});
|
||||
return listItems;
|
||||
}.property('items.[]')
|
||||
});
|
@@ -1,7 +1,6 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
|
||||
classNames: ['loading'],
|
||||
|
||||
layout: Ember.Handlebars.compile(' '),
|
||||
@@ -9,5 +8,4 @@ export default Ember.Component.extend({
|
||||
didInsertElement: function() {
|
||||
this.$().spin(this.get('size'));
|
||||
}
|
||||
|
||||
});
|
@@ -1,9 +1,7 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.View.extend({
|
||||
|
||||
tagName: 'span',
|
||||
classNames: ['select'],
|
||||
layout: Ember.Handlebars.compile('{{view "select" content=view.content optionValuePath=view.optionValuePath optionLabelPath=view.optionLabelPath value=view.value}} {{fa-icon "sort"}}')
|
||||
|
||||
});
|
@@ -2,5 +2,5 @@ import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'li',
|
||||
layoutName: 'components/menu-item-container'
|
||||
layoutName: 'components/ui/items/component-item'
|
||||
});
|
@@ -1,6 +1,6 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
liClass: 'divider',
|
||||
active: false
|
||||
});
|
||||
tagName: 'li',
|
||||
classNames: ['divider']
|
||||
});
|
@@ -23,17 +23,17 @@
|
||||
{{/link-to}}
|
||||
</h1>
|
||||
|
||||
{{menu-list items=headerPrimaryControls class="nav"}}
|
||||
{{ui/controls/item-list items=headerPrimaryControls class="nav"}}
|
||||
|
||||
</div>
|
||||
|
||||
<div id="header-secondary">
|
||||
|
||||
<div class="search">
|
||||
{{search-input placeholder="Search forum" value=searchQuery active=searchActive action="search"}}
|
||||
{{ui/controls/search-input placeholder="Search forum" value=searchQuery active=searchActive action="search"}}
|
||||
</div>
|
||||
|
||||
{{menu-list items=headerSecondaryControls}}
|
||||
{{ui/controls/item-list items=headerSecondaryControls}}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</main>
|
||||
|
||||
<footer id="footer">
|
||||
{{menu-list items=footerControls}}
|
||||
{{ui/controls/item-list items=footerControls}}
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
@@ -1,13 +0,0 @@
|
||||
{{#if view.controls}}
|
||||
<div class="controls btn-group">
|
||||
<button data-toggle="dropdown" class="dropdown-toggle btn btn-default btn-icon btn-xs">{{fa-icon "caret-down"}}</button>
|
||||
{{menu-list items=view.controls class="dropdown-menu pull-right"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#link-to "discussion" view.post.discussion (query-params start=view.post.number) class="time"}}
|
||||
{{abbreviate-time view.post.time}}
|
||||
{{!-- #{{view.post.number}} (ID: {{view.post.id}}) --}}
|
||||
{{/link-to}}
|
||||
|
||||
{{dynamic-component type=view.contentComponent post=view.post}}
|
@@ -1,7 +1,4 @@
|
||||
<div class="contextual-controls btn-group">
|
||||
<button class="dropdown-toggle btn btn-default btn-icon" data-toggle="dropdown">{{fa-icon "ellipsis-v"}}</button>
|
||||
{{menu-list items=controls class="dropdown-menu pull-right"}}
|
||||
</div>
|
||||
{{ui/controls/dropdown-button items=controls class="contextual-controls"}}
|
||||
|
||||
<div class="discussion-summary">
|
||||
|
@@ -0,0 +1,12 @@
|
||||
{{!-- {{#if view.controls}}
|
||||
<div class="controls btn-group">
|
||||
<button data-toggle="dropdown" class="dropdown-toggle btn btn-default btn-icon btn-xs">{{fa-icon "caret-down"}}</button>
|
||||
{{menu-list items=controls class="dropdown-menu pull-right"}}
|
||||
</div>
|
||||
{{/if}} --}}
|
||||
|
||||
{{#link-to "discussion" post.discussion (query-params start=post.number) class="time"}}
|
||||
{{abbreviate-time post.time}}
|
||||
{{/link-to}}
|
||||
|
||||
{{dynamic-component type=contentComponent post=post}}
|
@@ -1 +0,0 @@
|
||||
{{view item}}
|
@@ -1,3 +0,0 @@
|
||||
{{#each item in items}}
|
||||
{{view item}}
|
||||
{{/each}}
|
@@ -4,5 +4,5 @@
|
||||
<span class="label">{{title}}</span>
|
||||
{{fa-icon "caret-down" class="icon-caret"}}
|
||||
</button>
|
||||
{{menu-list items=containedItems class=dropdownMenuClass}}
|
||||
{{ui/controls/item-list items=items class=dropdownMenuClass}}
|
||||
{{/if}}
|
@@ -1,7 +1,7 @@
|
||||
{{#if items}}
|
||||
<button {{bind-attr class=":dropdown-toggle :btn buttonClass"}} data-toggle="dropdown">
|
||||
<span class="label">{{currentItem.title}}</span>
|
||||
<span class="label">{{activeItem.title}}</span>
|
||||
{{fa-icon "sort" class="icon-caret"}}
|
||||
</button>
|
||||
{{menu-list items=items class=dropdownMenuClass viewName="menu"}}
|
||||
{{ui/controls/item-list items=items class=dropdownMenuClass viewName="menu"}}
|
||||
{{/if}}
|
@@ -1,8 +1,8 @@
|
||||
{{#if items}}
|
||||
{{view items.firstItem class=mainButtonClass}}
|
||||
{{view firstItem class=mainButtonClass}}
|
||||
<button {{bind-attr class=":dropdown-toggle :btn buttonClass"}} data-toggle="dropdown">
|
||||
{{fa-icon "caret-down" class="icon-caret"}}
|
||||
{{fa-icon icon class="icon-glyph"}}
|
||||
</button>
|
||||
{{menu-list items=containedItems class=dropdownMenuClass}}
|
||||
{{ui/controls/item-list items=items class=dropdownMenuClass}}
|
||||
{{/if}}
|
@@ -1,3 +1,3 @@
|
||||
{{#each item in items}}
|
||||
{{#each item in listItems}}
|
||||
{{view item}}
|
||||
{{/each}}
|
@@ -0,0 +1 @@
|
||||
{{view component}}
|
@@ -11,7 +11,7 @@
|
||||
<h3>{{{title}}}</h3>
|
||||
|
||||
<div class="composer-editor">
|
||||
{{text-editor placeholder=""}}
|
||||
{{ui/controls/text-editor placeholder=""}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@@ -1,44 +1,40 @@
|
||||
<div class="discussions-area">
|
||||
|
||||
<nav class="discussions-nav">
|
||||
{{view view.sidebarView viewName="sidebar"}}
|
||||
{{ui/controls/item-list items=view.sidebarItems}}
|
||||
</nav>
|
||||
|
||||
<div class="discussions-results">
|
||||
|
||||
<div class="discussions-toolbar">
|
||||
<div class="discussions-toolbar-view">
|
||||
<span class="btn-group">
|
||||
{{#link-to (query-params show="discussions") class="btn btn-default btn-sm"}}{{fa-icon "bars"}}{{/link-to}}
|
||||
{{#link-to (query-params show="posts") class="btn btn-default btn-sm"}}{{fa-icon "square-o"}}{{/link-to}}
|
||||
<span class="btn-group control-show">
|
||||
{{#link-to (query-params show="discussions") class="btn btn-default"}}{{fa-icon "bars"}}{{/link-to}}
|
||||
{{#link-to (query-params show="posts") class="btn btn-default"}}{{fa-icon "square-o"}}{{/link-to}}
|
||||
</span>
|
||||
|
||||
{{select-input
|
||||
content=sortOptions
|
||||
optionValuePath="content.sort"
|
||||
optionLabelPath="content.label"
|
||||
value=sort}}
|
||||
{{ui/controls/select-input class="control-sort" content=sortOptions optionValuePath="content.sort" optionLabelPath="content.label" value=sort}}
|
||||
</div>
|
||||
<div class="discussions-toolbar-action">
|
||||
<button class="btn btn-default">{{fa-icon "check"}}</button>
|
||||
{{#ui/controls/action-button class="control-markAsRead"}}{{fa-icon "check"}}{{/ui/controls/action-button}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if resultsLoading}}
|
||||
{{loading-indicator size="small"}}
|
||||
{{ui/controls/loading-indicator size="small"}}
|
||||
{{else}}
|
||||
<ul class="discussions-list">
|
||||
{{#each discussion in content}}
|
||||
{{discussions-list-item discussion=discussion}}
|
||||
{{discussions/discussion-listing discussion=discussion}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
{{#if moreResults}}
|
||||
<div class="load-more">
|
||||
{{#if loadingMore}}
|
||||
{{loading-indicator size="small"}}
|
||||
{{ui/controls/loading-indicator size="small"}}
|
||||
{{else}}
|
||||
<button class="btn btn-default" {{action loadMore}}>Load More</button>
|
||||
{{#ui/controls/action-button class="control-loadMore" action="loadMore"}}Load More{{/ui/controls/action-button}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@@ -1,14 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import NamedContainerView from './named-container-view';
|
||||
import MenuItemSeparator from '../components/menu-item-separator';
|
||||
|
||||
export default NamedContainerView.extend({
|
||||
|
||||
i: 1,
|
||||
addSeparator: function(index) {
|
||||
var item = MenuItemSeparator;
|
||||
this.addItem('separator'+(this.i++), item, index);
|
||||
}
|
||||
|
||||
});
|
@@ -1,56 +0,0 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.ArrayProxy.extend({
|
||||
|
||||
content: null,
|
||||
namedViews: null,
|
||||
|
||||
init: function() {
|
||||
this.set('content', Ember.A()); // this is an important line.
|
||||
this.set('namedViews', Ember.Object.create());
|
||||
this._super();
|
||||
},
|
||||
|
||||
// Add an item to the container.
|
||||
addItem: function(name, viewClass, index) {
|
||||
// view = this.createChildView(view);
|
||||
|
||||
if (typeof index == 'undefined') {
|
||||
index = this.get('length');
|
||||
}
|
||||
this.replace(index, 0, [viewClass]);
|
||||
this.get('namedViews').set(name, viewClass);
|
||||
},
|
||||
|
||||
// Remove an item from the container.
|
||||
removeItem: function(name) {
|
||||
this.removeObject(this.get('namedViews').get(name));
|
||||
this.get('namedViews').set(name, null);
|
||||
},
|
||||
|
||||
// Replace an item in the container with another one.
|
||||
replaceItem: function(name, viewClass) {
|
||||
// view = this.createChildView(view);
|
||||
|
||||
var oldView = this.get('namedViews').get(name);
|
||||
var index = this.indexOf(oldView);
|
||||
this.replace(index, 1, [viewClass])
|
||||
this.get('namedViews').set(name, viewClass);
|
||||
},
|
||||
|
||||
// Move an item in the container to a new position.
|
||||
moveItem: function(name, index) {
|
||||
var view = this.get('namedViews').get(name);
|
||||
this.removeItem(name);
|
||||
this.addItem(name, view, index);
|
||||
},
|
||||
|
||||
firstItem: function() {
|
||||
return this.objectAt(0);
|
||||
}.property('content.@each'),
|
||||
|
||||
getItem: function(name) {
|
||||
return this.get('namedViews').get(name);
|
||||
}
|
||||
|
||||
});
|
57
framework/core/ember/app/utils/tagged-array.js
Normal file
57
framework/core/ember/app/utils/tagged-array.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.ArrayProxy.extend({
|
||||
content: null,
|
||||
taggedObjects: null,
|
||||
|
||||
init: function() {
|
||||
this.set('content', []);
|
||||
this.set('taggedObjects', {});
|
||||
this._super();
|
||||
},
|
||||
|
||||
pushObjectWithTag: function(obj, tag) {
|
||||
this.insertAtWithTag(this.get('length'), obj, tag);
|
||||
},
|
||||
|
||||
insertAtWithTag: function(idx, obj, tag) {
|
||||
this.insertAt(idx, obj);
|
||||
this.get('taggedObjects')[tag] = obj;
|
||||
},
|
||||
|
||||
insertAfterTag: function(anchorTag, obj, tag) {
|
||||
var idx = this.indexOfTag(anchorTag);
|
||||
this.insertAtWithTag(idx + 1, obj, newTag);
|
||||
},
|
||||
|
||||
insertBeforeTag: function(anchorTag, obj, tag) {
|
||||
var idx = this.indexOfTag(anchorTag);
|
||||
this.insertAtWithTag(idx - 1, obj, tag);
|
||||
},
|
||||
|
||||
removeByTag: function(tag) {
|
||||
var idx = this.indexOfTag(tag);
|
||||
this.removeAt(idx);
|
||||
delete this.get('taggedObjects')[tag];
|
||||
},
|
||||
|
||||
replaceByTag: function(tag, obj) {
|
||||
var idx = this.indexOfTag(tag);
|
||||
this.removeByTag(tag);
|
||||
this.insertAtWithTag(idx, obj, tag);
|
||||
},
|
||||
|
||||
moveByTag: function(tag, idx) {
|
||||
var obj = this.objectByTag(tag);
|
||||
this.removeByTag(tag);
|
||||
this.insertAtWithTag(idx, obj, tag);
|
||||
},
|
||||
|
||||
indexOfTag: function(tag) {
|
||||
return this.indexOf(this.get('taggedObjects')[tag]);
|
||||
},
|
||||
|
||||
objectByTag: function(tag) {
|
||||
return this.get('taggedObjects')[tag];
|
||||
}
|
||||
});
|
@@ -1,16 +1,15 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import NamedContainerView from '../utils/named-container-view';
|
||||
import Menu from '../utils/menu';
|
||||
import MenuItem from '../components/menu-item';
|
||||
import DropdownSplit from '../components/dropdown-split';
|
||||
import DropdownButton from '../components/dropdown-button';
|
||||
import DiscussionScrollbar from '../components/discussion-scrollbar';
|
||||
import TaggedArray from '../utils/tagged-array';
|
||||
import ActionButton from '../components/ui/controls/action-button';
|
||||
import DropdownSplit from '../components/ui/controls/dropdown-split';
|
||||
import DropdownButton from '../components/ui/controls/dropdown-button';
|
||||
import DiscussionScrollbar from '../components/discussions/stream-scrollbar';
|
||||
import PostStreamMixin from '../mixins/post-stream';
|
||||
|
||||
export default Ember.View.extend(Ember.Evented, PostStreamMixin, {
|
||||
|
||||
sidebar: Ember.ContainerView,
|
||||
sidebarItems: Ember.ContainerView,
|
||||
|
||||
// Set up a new menu view that will contain controls to be shown in the
|
||||
// footer. The template will only render these controls if the last post is
|
||||
@@ -30,7 +29,7 @@ export default Ember.View.extend(Ember.Evented, PostStreamMixin, {
|
||||
didInsertElement: function() {
|
||||
|
||||
// We've just inserted the discussion view.
|
||||
this.trigger('populateSidebar', this.get('sidebar'));
|
||||
// this.trigger('populateSidebar', this.get('sidebar'));
|
||||
|
||||
// Whenever the window's scroll position changes, we want to check to
|
||||
// see if any terminal 'gaps' are in the viewport and trigger their
|
||||
@@ -60,14 +59,14 @@ export default Ember.View.extend(Ember.Evented, PostStreamMixin, {
|
||||
},
|
||||
|
||||
setupSidebar: function(sidebar) {
|
||||
this.set('controls', Menu.create());
|
||||
this.trigger('populateControls', this.get('controls'));
|
||||
sidebar.pushObject(DropdownSplit.create({
|
||||
items: this.get('controls'),
|
||||
var items = TaggedArray.create();
|
||||
this.trigger('populateControls', items);
|
||||
sidebarItems.pushObject(DropdownSplit.create({
|
||||
items: items,
|
||||
icon: 'reply',
|
||||
buttonClass: 'btn-primary',
|
||||
menuClass: 'pull-right'
|
||||
}));
|
||||
}), 'controls');
|
||||
|
||||
sidebar.pushObject(DropdownButton.create({items: this.get('controls')}));
|
||||
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
import DropdownSelect from '../components/dropdown-select';
|
||||
import ButtonItem from '../components/button-item';
|
||||
import NavItem from '../components/nav-item';
|
||||
import Menu from '../utils/menu';
|
||||
import DropdownSelect from '../components/ui/controls/dropdown-select';
|
||||
import ActionButton from '../components/ui/controls/action-button';
|
||||
import NavItem from '../components/ui/items/nav-item';
|
||||
import TaggedArray from '../utils/tagged-array';
|
||||
|
||||
export default Ember.View.extend({
|
||||
|
||||
sidebarView: Ember.ContainerView.extend(),
|
||||
sidebarItems: null,
|
||||
|
||||
classNameBindings: ['pinned'],
|
||||
|
||||
@@ -17,7 +17,9 @@ export default Ember.View.extend({
|
||||
|
||||
didInsertElement: function() {
|
||||
|
||||
this.trigger('populateSidebar', this.get('sidebar'));
|
||||
var sidebarItems = TaggedArray.create();
|
||||
this.trigger('populateSidebar', sidebarItems);
|
||||
this.set('sidebarItems', sidebarItems);
|
||||
|
||||
var view = this;
|
||||
|
||||
@@ -58,44 +60,37 @@ export default Ember.View.extend({
|
||||
});
|
||||
},
|
||||
|
||||
setupSidebar: function(sidebar) {
|
||||
sidebar.pushObject(ButtonItem.create({
|
||||
populateSidebarDefault: function(sidebar) {
|
||||
var newDiscussion = ActionButton.create({
|
||||
title: 'Start a Discussion',
|
||||
icon: 'edit',
|
||||
class: 'btn-primary'
|
||||
}));
|
||||
})
|
||||
sidebar.pushObjectWithTag(newDiscussion, 'newDiscussion');
|
||||
|
||||
var nav = Menu.create();
|
||||
var nav = TaggedArray.create();
|
||||
this.trigger('populateNav', nav);
|
||||
sidebar.pushObject(DropdownSelect.create({
|
||||
items: nav
|
||||
}));
|
||||
sidebar.pushObjectWithTag(DropdownSelect.createWithItems(nav), 'nav');
|
||||
}.on('populateSidebar'),
|
||||
|
||||
setupNav: function(nav) {
|
||||
nav.addItem('all', NavItem.create({
|
||||
populateNavDefault: function(nav) {
|
||||
nav.pushObjectWithTag(NavItem.create({
|
||||
title: 'All Discussions',
|
||||
icon: 'comments-o',
|
||||
linkTo: '"discussions" (query-params filter="")'
|
||||
}));
|
||||
}), 'all');
|
||||
|
||||
nav.addItem('private', NavItem.create({
|
||||
nav.pushObjectWithTag(NavItem.create({
|
||||
title: 'Private',
|
||||
icon: 'envelope-o',
|
||||
linkTo: '"discussions" (query-params filter="private")'
|
||||
}));
|
||||
}), 'private');
|
||||
|
||||
nav.addItem('following', NavItem.create({
|
||||
nav.pushObjectWithTag(NavItem.create({
|
||||
title: 'Following',
|
||||
icon: 'star',
|
||||
linkTo: '"discussions" (query-params filter="following")'
|
||||
}));
|
||||
|
||||
nav.addItem('categories', NavItem.create({
|
||||
title: 'Categories',
|
||||
icon: 'reorder',
|
||||
linkTo: '"categories"'
|
||||
}));
|
||||
}), 'following');
|
||||
}.on('populateNav'),
|
||||
|
||||
willDestroyElement: function() {
|
||||
|
Reference in New Issue
Block a user