mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 23:58:31 -05:00
ES6: Migrated and deprecated a bunch of views
This commit is contained in:
parent
c88bff5e0c
commit
580a1bf8b0
64 changed files with 206 additions and 382 deletions
|
@ -10,4 +10,4 @@ Discourse.AdminGithubCommitsController = Ember.ArrayController.extend({
|
||||||
goToGithub: function() {
|
goToGithub: function() {
|
||||||
window.open('https://github.com/discourse/discourse');
|
window.open('https://github.com/discourse/discourse');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -94,4 +94,4 @@ Discourse.AdminLogsScreenedIpAddressController = Ember.ObjectController.extend({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,4 +16,4 @@ Discourse.AdminReportsController = Ember.ObjectController.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,4 +25,4 @@ Discourse.AdminSiteContentEditController = Discourse.Controller.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.AdminSiteContentsController = Ember.ArrayController.extend({});
|
Discourse.AdminSiteContentsController = Ember.ArrayController.extend({});
|
||||||
|
|
|
@ -14,4 +14,4 @@ Handlebars.registerHelper('valueAtTrustLevel', function(property, trustLevel) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,4 +10,4 @@ Discourse.AdminCustomizeIndexRoute = Discourse.Route.extend({
|
||||||
redirect: function() {
|
redirect: function() {
|
||||||
this.transitionTo('adminCustomize.colors');
|
this.transitionTo('adminCustomize.colors');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,4 +105,4 @@ Discourse.AdminLogsScreenedUrlsRoute = Discourse.Route.extend({
|
||||||
setupController: function() {
|
setupController: function() {
|
||||||
return this.controllerFor('adminLogsScreenedUrls').show();
|
return this.controllerFor('adminLogsScreenedUrls').show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,4 +10,4 @@ Discourse.AdminReportsRoute = Discourse.Route.extend({
|
||||||
model: function(params) {
|
model: function(params) {
|
||||||
return Discourse.Report.find(params.type);
|
return Discourse.Report.find(params.type);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="current-style color-scheme">
|
<div class="current-style color-scheme">
|
||||||
<div class="admin-container">
|
<div class="admin-container">
|
||||||
{{#with selectedItem}}
|
{{#with selectedItem}}
|
||||||
<h1>{{textField class="style-name" value=name}}</h1>
|
<h1>{{text-field class="style-name" value=name}}</h1>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button {{action save}} {{bind-attr disabled="disableSave"}} class='btn'>{{i18n admin.customize.save}}</button>
|
<button {{action save}} {{bind-attr disabled="disableSave"}} class='btn'>{{i18n admin.customize.save}}</button>
|
||||||
|
@ -75,4 +75,4 @@
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p class="about">{{i18n admin.customize.colors.about}}</p>
|
<p class="about">{{i18n admin.customize.colors.about}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
{{#if selectedItem}}
|
{{#if selectedItem}}
|
||||||
<div class='current-style'>
|
<div class='current-style'>
|
||||||
{{#with selectedItem}}
|
{{#with selectedItem}}
|
||||||
{{textField class="style-name" value=name}}
|
{{text-field class="style-name" value=name}}
|
||||||
|
|
||||||
<div class='admin-controls'>
|
<div class='admin-controls'>
|
||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
<tr class="filters">
|
<tr class="filters">
|
||||||
<td>{{i18n admin.email.logs.filters.title}}</td>
|
<td>{{i18n admin.email.logs.filters.title}}</td>
|
||||||
<td>{{textField value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
<td>{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
<td>{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
<td>{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}</td>
|
<td>{{text-field value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{{#each model}}
|
{{#each model}}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<div class='span15 controls'>{{i18n admin.email.sending_test}}</div>
|
<div class='span15 controls'>{{i18n admin.email.sending_test}}</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class='controls'>
|
<div class='controls'>
|
||||||
{{textField value=testEmailAddress placeholderKey="admin.email.test_email_address"}}
|
{{text-field value=testEmailAddress placeholderKey="admin.email.test_email_address"}}
|
||||||
</div>
|
</div>
|
||||||
<div class='span10 controls'>
|
<div class='span10 controls'>
|
||||||
<button class='btn' {{action sendTestEmail}} {{bind-attr disabled="sendTestEmailDisabled"}}>{{i18n admin.email.send_test}}</button>
|
<button class='btn' {{action sendTestEmail}} {{bind-attr disabled="sendTestEmailDisabled"}}>{{i18n admin.email.send_test}}</button>
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
<tr class="filters">
|
<tr class="filters">
|
||||||
<td>{{i18n admin.email.logs.filters.title}}</td>
|
<td>{{i18n admin.email.logs.filters.title}}</td>
|
||||||
<td>{{textField value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
<td>{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
<td>{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
<td>{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.reply_key placeholderKey="admin.email.logs.filters.reply_key_placeholder"}}</td>
|
<td>{{text-field value=filter.reply_key placeholderKey="admin.email.logs.filters.reply_key_placeholder"}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{{#each model}}
|
{{#each model}}
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
<tr class="filters">
|
<tr class="filters">
|
||||||
<td>{{i18n admin.email.logs.filters.title}}</td>
|
<td>{{i18n admin.email.logs.filters.title}}</td>
|
||||||
<td>{{textField value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
<td>{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
<td>{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
<td>{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
||||||
<td>{{textField value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}</td>
|
<td>{{text-field value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{{#each model}}
|
{{#each model}}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{{#if automatic}}
|
{{#if automatic}}
|
||||||
<h3>{{name}}</h3>
|
<h3>{{name}}</h3>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{textField value=name placeholderKey="admin.groups.name_placeholder"}}
|
{{text-field value=name placeholderKey="admin.groups.name_placeholder"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">{{i18n admin.groups.group_members}}</label>
|
<label class="control-label">{{i18n admin.groups.group_members}}</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{userSelector usernames=usernames id="group-users" placeholderKey="admin.groups.selector_placeholder" tabindex="1" disabled=automatic}}
|
{{user-selector usernames=usernames id="group-users" placeholderKey="admin.groups.selector_placeholder" tabindex="1" disabled=automatic}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="col first ip_address">
|
<div class="col first ip_address">
|
||||||
{{#if editing}}
|
{{#if editing}}
|
||||||
{{textField value=ip_address autofocus="autofocus"}}
|
{{text-field value=ip_address autofocus="autofocus"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<span {{action edit this}}>{{ip_address}}</span>
|
<span {{action edit this}}>{{ip_address}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form>
|
<form>
|
||||||
{{i18n admin.user.suspend_duration}}
|
{{i18n admin.user.suspend_duration}}
|
||||||
{{textField value=duration maxlength="5" autofocus="autofocus"}}
|
{{text-field value=duration maxlength="5" autofocus="autofocus"}}
|
||||||
{{i18n admin.user.suspend_duration_units}}<br/>
|
{{i18n admin.user.suspend_duration_units}}<br/>
|
||||||
<br/>
|
<br/>
|
||||||
{{{i18n admin.user.suspend_reason_label}}}<br/>
|
{{{i18n admin.user.suspend_reason_label}}}<br/>
|
||||||
<br/>
|
<br/>
|
||||||
{{textField value=reason class="span8"}}
|
{{text-field value=reason class="span8"}}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class='controls'>
|
<div class='controls'>
|
||||||
{{textField value=filter placeholderKey="type_to_filter"}}
|
{{text-field value=filter placeholderKey="type_to_filter"}}
|
||||||
<button {{action clearFilter}} class="btn">{{i18n admin.site_settings.clear_filter}}</button>
|
<button {{action clearFilter}} class="btn">{{i18n admin.site_settings.clear_filter}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<h3>{{unbound settingName}}</h3>
|
<h3>{{unbound settingName}}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{textField value=value classNames="input-setting-string"}}
|
{{text-field value=value classNames="input-setting-string"}}
|
||||||
<div {{bind-attr class=":validation-error validationMessage::hidden"}}><i class='fa fa-times'></i> {{validationMessage}}</div>
|
<div {{bind-attr class=":validation-error validationMessage::hidden"}}><i class='fa fa-times'></i> {{validationMessage}}</div>
|
||||||
<div class='desc'>{{unbound description}}</div>
|
<div class='desc'>{{unbound description}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<div class='field'>{{i18n user.title.title}}</div>
|
<div class='field'>{{i18n user.title.title}}</div>
|
||||||
<div class='value'>
|
<div class='value'>
|
||||||
{{#if editingTitle}}
|
{{#if editingTitle}}
|
||||||
{{textField value=title autofocus="autofocus"}}
|
{{text-field value=title autofocus="autofocus"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<span {{action toggleTitleEdit}}>{{title}} </span>
|
<span {{action toggleTitleEdit}}>{{title}} </span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class='username controls'>
|
<div class='username controls'>
|
||||||
{{textField value=username placeholderKey="username"}}
|
{{text-field value=username placeholderKey="username"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Discourse.AdminReportCountsView = Discourse.View.extend({
|
Discourse.AdminReportCountsView = Discourse.View.extend({
|
||||||
templateName: 'admin/templates/reports/summed_counts_report',
|
templateName: 'admin/templates/reports/summed_counts_report',
|
||||||
tagName: 'tbody'
|
tagName: 'tbody'
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,4 +30,4 @@ Ember.EventDispatcher.reopen({
|
||||||
drop : 'drop',
|
drop : 'drop',
|
||||||
dragend : 'dragEnd'
|
dragend : 'dragEnd'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -130,4 +130,4 @@ Ember.Handlebars.registerHelper('groupedEach', function(path, options) {
|
||||||
options.hash.dataSourceBinding = path;
|
options.hash.dataSourceBinding = path;
|
||||||
options.data.insideGroup = true;
|
options.data.insideGroup = true;
|
||||||
new DiscourseGroupedEach(this, path, options).render();
|
new DiscourseGroupedEach(this, path, options).render();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
var deprecatedViewHelpers = {
|
var deprecatedViewHelpers = {
|
||||||
inputTip: 'input-tip',
|
inputTip: 'input-tip',
|
||||||
pagedown: 'pagedown-editor'
|
pagedown: 'pagedown-editor',
|
||||||
|
textField: 'text-field',
|
||||||
|
userSelector: 'user-selector'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var helpers = ['input-tip', 'pagedown-editor'];
|
var helpers = ['input-tip', 'pagedown-editor', 'text-field', 'user-selector'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates view helpers for some views. Many of these should probably be converted
|
Creates view helpers for some views. Many of these should probably be converted
|
||||||
|
@ -9,8 +9,8 @@ export default {
|
||||||
initialize: function(container) {
|
initialize: function(container) {
|
||||||
helpers.forEach(function(h) {
|
helpers.forEach(function(h) {
|
||||||
Ember.Handlebars.registerHelper(h, function(options) {
|
Ember.Handlebars.registerHelper(h, function(options) {
|
||||||
var helper = container.lookupFactory('view:' + h);
|
var helper = container.lookupFactory('view:' + h),
|
||||||
var hash = options.hash,
|
hash = options.hash,
|
||||||
types = options.hashTypes;
|
types = options.hashTypes;
|
||||||
|
|
||||||
Discourse.Utilities.normalizeHash(hash, types);
|
Discourse.Utilities.normalizeHash(hash, types);
|
||||||
|
|
|
@ -65,4 +65,4 @@ Discourse.ScrollingDOMMethods = {
|
||||||
$(document).unbind('touchmove.discourse-' + name);
|
$(document).unbind('touchmove.discourse-' + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,4 +32,4 @@ Discourse.ComposerMessage.reopenClass({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,4 +8,4 @@
|
||||||
**/
|
**/
|
||||||
Discourse.TrustLevel = Discourse.Model.extend({
|
Discourse.TrustLevel = Discourse.Model.extend({
|
||||||
detailedName: Discourse.computed.fmt('id', 'name', '%@ - %@')
|
detailedName: Discourse.computed.fmt('id', 'name', '%@ - %@')
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,4 +37,4 @@ Discourse.UserInvitedRoute = Discourse.Route.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,4 +14,4 @@
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<label for='choose-topic-title'>{{i18n choose_topic.title.search}}</label>
|
<label for='choose-topic-title'>{{i18n choose_topic.title.search}}</label>
|
||||||
|
|
||||||
{{textField value=view.topicTitle placeholderKey="choose_topic.title.placeholder" id="choose-topic-title"}}
|
{{text-field value=view.topicTitle placeholderKey="choose_topic.title.placeholder" id="choose-topic-title"}}
|
||||||
|
|
||||||
{{#if view.loading}}
|
{{#if view.loading}}
|
||||||
<p>{{i18n loading}}</p>
|
<p>{{i18n loading}}</p>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<i class="fa fa-clock-o"></i>
|
<i class="fa fa-clock-o"></i>
|
||||||
{{label}}
|
{{label}}
|
||||||
{{textField value=autoCloseTime}}
|
{{text-field value=autoCloseTime}}
|
||||||
{{i18n composer.auto_close_units}}
|
{{i18n composer.auto_close_units}}
|
||||||
</div>
|
</div>
|
||||||
<div class="examples">
|
<div class="examples">
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{textField class="hex-input" value=hexValue maxlength="6"}}
|
{{text-field class="hex-input" value=hexValue maxlength="6"}}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<b>{{i18n admin.logs.screened_ips.form.label}}</b>
|
<b>{{i18n admin.logs.screened_ips.form.label}}</b>
|
||||||
{{textField value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}}
|
{{text-field value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}}
|
||||||
{{combobox content=actionNames value=actionName}}
|
{{combobox content=actionNames value=actionName}}
|
||||||
<button class="btn btn-small" {{action submit target="view"}} {{bind-attr disabled="formSubmitted"}}>{{i18n admin.logs.screened_ips.form.add}}</button>
|
<button class="btn btn-small" {{action submit target="view"}} {{bind-attr disabled="formSubmitted"}}>{{i18n admin.logs.screened_ips.form.add}}</button>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
{{#if canEdit}}
|
{{#if canEdit}}
|
||||||
{{#if showEditReason}}
|
{{#if showEditReason}}
|
||||||
<div class="edit-reason-input">
|
<div class="edit-reason-input">
|
||||||
{{textField value=editReason tabindex="5" id="edit-reason" maxlength="255" placeholderKey="composer.edit_reason_placeholder"}}
|
{{text-field value=editReason tabindex="5" id="edit-reason" maxlength="255" placeholderKey="composer.edit_reason_placeholder"}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a {{action displayEditReason}} class="display-edit-reason">{{i18n composer.show_edit_reason}}</a>
|
<a {{action displayEditReason}} class="display-edit-reason">{{i18n composer.show_edit_reason}}</a>
|
||||||
|
@ -27,18 +27,18 @@
|
||||||
{{#if model.canEditTitle}}
|
{{#if model.canEditTitle}}
|
||||||
<div class='form-element clearfix'>
|
<div class='form-element clearfix'>
|
||||||
{{#if model.creatingPrivateMessage}}
|
{{#if model.creatingPrivateMessage}}
|
||||||
{{userSelector topicId=controller.controllers.topic.model.id
|
{{user-selector topicId=controller.controllers.topic.model.id
|
||||||
excludeCurrentUser="true"
|
excludeCurrentUser="true"
|
||||||
id="private-message-users"
|
id="private-message-users"
|
||||||
include_groups="true"
|
include_groups="true"
|
||||||
class="span8"
|
class="span8"
|
||||||
placeholderKey="composer.users_placeholder"
|
placeholderKey="composer.users_placeholder"
|
||||||
tabindex="1"
|
tabindex="1"
|
||||||
usernames=model.targetUsernames}}
|
usernames=model.targetUsernames}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<div class="title-input">
|
<div class="title-input">
|
||||||
{{textField value=model.title tabindex="2" id="reply-title" maxlength="255" placeholderKey="composer.title_placeholder"}}
|
{{text-field value=model.title tabindex="2" id="reply-title" maxlength="255" placeholderKey="composer.title_placeholder"}}
|
||||||
{{popupInputTip validation=view.titleValidation shownAt=view.showTitleTip}}
|
{{popupInputTip validation=view.titleValidation shownAt=view.showTitleTip}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<label for='login-account-name'>{{i18n login.username}} </label>
|
<label for='login-account-name'>{{i18n login.username}} </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{textField value=loginName placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off"}}
|
{{text-field value=loginName placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off"}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<label for='login-account-password'>{{i18n login.password}} </label>
|
<label for='login-account-password'>{{i18n login.password}} </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{textField value=loginPassword type="password" id="login-account-password"}}
|
{{text-field value=loginPassword type="password" id="login-account-password"}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<label>{{i18n topic.change_owner.label}}</label>
|
<label>{{i18n topic.change_owner.label}}</label>
|
||||||
{{userSelector single=true usernames=new_user include_groups="false" placeholderKey="topic.change_owner.placeholder"}}
|
{{user-selector single=true usernames=new_user include_groups="false" placeholderKey="topic.change_owner.placeholder"}}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<tr class="input">
|
<tr class="input">
|
||||||
<td style="width:80px" class="label"><label for='new-account-name'>{{i18n user.name.title}}</label></td>
|
<td style="width:80px" class="label"><label for='new-account-name'>{{i18n user.name.title}}</label></td>
|
||||||
<td style="width:496px">
|
<td style="width:496px">
|
||||||
{{textField value=accountName id="new-account-name" autofocus="autofocus"}}
|
{{text-field value=accountName id="new-account-name" autofocus="autofocus"}}
|
||||||
{{input-tip validation=nameValidation}}
|
{{input-tip validation=nameValidation}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<form>
|
<form>
|
||||||
<section class='field'>
|
<section class='field'>
|
||||||
<label>{{i18n category.name}}</label>
|
<label>{{i18n category.name}}</label>
|
||||||
{{textField value=name placeholderKey="category.name_placeholder" maxlength="50"}}
|
{{text-field value=name placeholderKey="category.name_placeholder" maxlength="50"}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class='field'>
|
<section class='field'>
|
||||||
|
@ -56,13 +56,13 @@
|
||||||
|
|
||||||
<div class='input-prepend input-append' style="margin-top: 10px;">
|
<div class='input-prepend input-append' style="margin-top: 10px;">
|
||||||
<span class='color-title'>{{i18n category.background_color}}:</span>
|
<span class='color-title'>{{i18n category.background_color}}:</span>
|
||||||
<span class='add-on'>#</span>{{textField value=color placeholderKey="category.color_placeholder" maxlength="6"}}
|
<span class='add-on'>#</span>{{text-field value=color placeholderKey="category.color_placeholder" maxlength="6"}}
|
||||||
{{colorPicker colors=backgroundColors usedColors=usedBackgroundColors value=color}}
|
{{colorPicker colors=backgroundColors usedColors=usedBackgroundColors value=color}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='input-prepend input-append'>
|
<div class='input-prepend input-append'>
|
||||||
<span class='color-title'>{{i18n category.foreground_color}}:</span>
|
<span class='color-title'>{{i18n category.foreground_color}}:</span>
|
||||||
<span class='add-on'>#</span>{{textField value=text_color placeholderKey="category.color_placeholder" maxlength="6"}}
|
<span class='add-on'>#</span>{{text-field value=text_color placeholderKey="category.color_placeholder" maxlength="6"}}
|
||||||
{{colorPicker colors=foregroundColors value=text_color}}
|
{{colorPicker colors=foregroundColors value=text_color}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
<div>
|
<div>
|
||||||
<i class="fa fa-clock-o"></i>
|
<i class="fa fa-clock-o"></i>
|
||||||
{{i18n category.auto_close_label}}
|
{{i18n category.auto_close_label}}
|
||||||
{{textField value=auto_close_hours}}
|
{{text-field value=auto_close_hours}}
|
||||||
{{i18n category.auto_close_units}}
|
{{i18n category.auto_close_units}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
<div>
|
<div>
|
||||||
<i class="fa fa-envelope-o"></i>
|
<i class="fa fa-envelope-o"></i>
|
||||||
{{i18n category.email_in}}
|
{{i18n category.email_in}}
|
||||||
{{textField value=email_in}}
|
{{text-field value=email_in}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="checkbox-label">
|
<label class="checkbox-label">
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
{{#if showPositionInput}}
|
{{#if showPositionInput}}
|
||||||
<section class='field'>
|
<section class='field'>
|
||||||
<label>{{i18n category.position}}</label>
|
<label>{{i18n category.position}}</label>
|
||||||
{{textField value=position class="position-input"}}
|
{{text-field value=position class="position-input"}}
|
||||||
</section>
|
</section>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>{{i18n category.position_disabled}}</p>
|
<p>{{i18n category.position_disabled}}</p>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<form>
|
<form>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<label for='username-or-email'>{{i18n forgot_password.invite}}</label>
|
<label for='username-or-email'>{{i18n forgot_password.invite}}</label>
|
||||||
{{textField value=accountEmailOrUsername placeholderKey="login.email_placeholder" id="username-or-email" autocorrect="off" autocapitalize="off"}}
|
{{text-field value=accountEmailOrUsername placeholderKey="login.email_placeholder" id="username-or-email" autocorrect="off" autocapitalize="off"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class='btn btn-large btn-primary' {{bind-attr disabled="submitDisabled"}} {{action submit}}>{{i18n forgot_password.reset}}</button>
|
<button class='btn btn-large btn-primary' {{bind-attr disabled="submitDisabled"}} {{action submit}}>{{i18n forgot_password.reset}}</button>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
||||||
<label>{{inviteInstructions}}</label>
|
<label>{{inviteInstructions}}</label>
|
||||||
{{textField value=email placeholderKey="topic.invite_reply.email_placeholder"}}
|
{{text-field value=email placeholderKey="topic.invite_reply.email_placeholder"}}
|
||||||
|
|
||||||
{{#if isAdmin}}
|
{{#if isAdmin}}
|
||||||
<label>{{i18n topic.automatically_add_to_groups}}</label>
|
<label>{{i18n topic.automatically_add_to_groups}}</label>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{{i18n topic.invite_private.success}}
|
{{i18n topic.invite_private.success}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<label>{{i18n topic.invite_private.email_or_username}}</label>
|
<label>{{i18n topic.invite_private.email_or_username}}</label>
|
||||||
{{userSelector single=true allowAny=true usernames=emailOrUsername include_groups="true" placeholderKey="topic.invite_private.email_or_username_placeholder"}}
|
{{user-selector single=true allowAny=true usernames=emailOrUsername include_groups="true" placeholderKey="topic.invite_private.email_or_username_placeholder"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<label for='login-account-name'>{{i18n login.username}} </label>
|
<label for='login-account-name'>{{i18n login.username}} </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{textField value=loginName placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off" autofocus="autofocus"}}
|
{{text-field value=loginName placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off" autofocus="autofocus"}}
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<label for='login-account-password'>{{i18n login.password}} </label>
|
<label for='login-account-password'>{{i18n login.password}} </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{textField value=loginPassword type="password" id="login-account-password"}}
|
{{text-field value=loginPassword type="password" id="login-account-password"}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a id="forgot-password-link" {{action showForgotPassword}}>{{i18n forgot_password.action}}</a>
|
<a id="forgot-password-link" {{action showForgotPassword}}>{{i18n forgot_password.action}}</a>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<label>{{i18n topic.split_topic.topic_name}}</label>
|
<label>{{i18n topic.split_topic.topic_name}}</label>
|
||||||
{{textField value=topicName placeholderKey="composer.title_placeholder" elementId='split-topic-name'}}
|
{{text-field value=topicName placeholderKey="composer.title_placeholder" elementId='split-topic-name'}}
|
||||||
|
|
||||||
<label>{{i18n categories.category}}</label>
|
<label>{{i18n categories.category}}</label>
|
||||||
{{categoryChooser value=categoryId}}
|
{{categoryChooser value=categoryId}}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{view Discourse.SearchTextField valueBinding="term" searchContextBinding="searchContext" id="search-term"}}
|
{{view 'search-text-field' value=term searchContext=searchContext id="search-term"}}
|
||||||
{{#unless loading}}
|
{{#unless loading}}
|
||||||
{{#unless noResults}}
|
{{#unless noResults}}
|
||||||
{{#each resultType in content}}
|
{{#each resultType in content}}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
{{categoryChooser valueAttribute="id" value=newCategoryId source=category_id}}
|
{{categoryChooser valueAttribute="id" value=newCategoryId source=category_id}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{textField id='edit-title' value=newTitle}}
|
{{text-field id='edit-title' value=newTitle}}
|
||||||
|
|
||||||
<button class='btn btn-primary btn-small no-text' {{action finishedEditingTopic}}><i class='fa fa-check'></i></button>
|
<button class='btn btn-primary btn-small no-text' {{action finishedEditingTopic}}><i class='fa fa-check'></i></button>
|
||||||
<button class='btn btn-small no-text' {{action cancelEditingTopic}}><i class='fa fa-times'></i></button>
|
<button class='btn btn-small no-text' {{action cancelEditingTopic}}><i class='fa fa-times'></i></button>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">{{i18n user.email.title}}</label>
|
<label class="control-label">{{i18n user.email.title}}</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{textField value=newEmail id="change_email" classNames="input-xxlarge"}}
|
{{text-field value=newEmail id="change_email" classNames="input-xxlarge"}}
|
||||||
</div>
|
</div>
|
||||||
<div class='instructions'>
|
<div class='instructions'>
|
||||||
{{#if taken}}
|
{{#if taken}}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
{{#if showSearch}}
|
{{#if showSearch}}
|
||||||
<form>
|
<form>
|
||||||
{{textField value=searchTerm placeholderKey="user.invited.search"}}
|
{{text-field value=searchTerm placeholderKey="user.invited.search"}}
|
||||||
</form>
|
</form>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<label class="control-label">{{i18n user.name.title}}</label>
|
<label class="control-label">{{i18n user.name.title}}</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{#if can_edit_name}}
|
{{#if can_edit_name}}
|
||||||
{{textField value=newNameInput classNames="input-xxlarge"}}
|
{{text-field value=newNameInput classNames="input-xxlarge"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class='static'>{{name}}</span>
|
<span class='static'>{{name}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">{{i18n user.username.title}}</label>
|
<label class="control-label">{{i18n user.username.title}}</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{textField value=newUsername id="change_username" classNames="input-xxlarge" maxlengthBinding="Discourse.SiteSettings.max_username_length"}}
|
{{text-field value=newUsername id="change_username" classNames="input-xxlarge" maxlengthBinding="Discourse.SiteSettings.max_username_length"}}
|
||||||
</div>
|
</div>
|
||||||
<div class='instructions'>
|
<div class='instructions'>
|
||||||
{{#if taken}}
|
{{#if taken}}
|
||||||
|
|
|
@ -19,4 +19,4 @@ Discourse.InviteReplyButton = Discourse.ButtonView.extend({
|
||||||
click: function() {
|
click: function() {
|
||||||
return this.get('controller').send('showInvite');
|
return this.get('controller').send('showInvite');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,4 +15,4 @@ Discourse.LoginReplyButton = Discourse.ButtonView.extend({
|
||||||
renderIcon: function(buffer) {
|
renderIcon: function(buffer) {
|
||||||
buffer.push("<i class='fa fa-user'></i>");
|
buffer.push("<i class='fa fa-user'></i>");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -176,8 +176,8 @@ Discourse.ComposerView = Discourse.View.extend(Ember.Evented, {
|
||||||
|
|
||||||
$LAB.script(assetPath('defer/html-sanitizer-bundle'));
|
$LAB.script(assetPath('defer/html-sanitizer-bundle'));
|
||||||
Discourse.ComposerView.trigger("initWmdEditor");
|
Discourse.ComposerView.trigger("initWmdEditor");
|
||||||
var template = Discourse.UserSelector.templateFunction();
|
|
||||||
|
|
||||||
|
var template = this.container.lookupFactory('view:user-selector').templateFunction();
|
||||||
$wmdInput.data('init', true);
|
$wmdInput.data('init', true);
|
||||||
$wmdInput.autocomplete({
|
$wmdInput.autocomplete({
|
||||||
template: template,
|
template: template,
|
||||||
|
|
|
@ -32,4 +32,4 @@ Discourse.ContainerView = Ember.ContainerView.extend(Discourse.Presence, {
|
||||||
this.attachViewWithArgs(null, viewClass);
|
this.attachViewWithArgs(null, viewClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
@namespace Discourse
|
@namespace Discourse
|
||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
Discourse.SearchTextField = Discourse.TextField.extend({
|
|
||||||
|
import TextField from 'discourse/views/text-field';
|
||||||
|
|
||||||
|
export default TextField.extend({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A dynamic placeholder for the search field based on our context
|
A dynamic placeholder for the search field based on our context
|
||||||
|
@ -27,7 +30,4 @@ Discourse.SearchTextField = Discourse.TextField.extend({
|
||||||
|
|
||||||
return I18n.t('search.placeholder');
|
return I18n.t('search.placeholder');
|
||||||
}.property('searchContext')
|
}.property('searchContext')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
@namespace Discourse
|
@namespace Discourse
|
||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
Discourse.TextField = Ember.TextField.extend({
|
export default Ember.TextField.extend({
|
||||||
attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus'],
|
attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus'],
|
||||||
|
|
||||||
placeholder: function() {
|
placeholder: function() {
|
||||||
|
@ -16,7 +16,4 @@ Discourse.TextField = Ember.TextField.extend({
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}.property('placeholderKey')
|
}.property('placeholderKey')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.View.registerHelper('textField', Discourse.TextField);
|
|
108
app/assets/javascripts/discourse/views/user-selector.js.es6
Normal file
108
app/assets/javascripts/discourse/views/user-selector.js.es6
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import TextField from 'discourse/views/text-field';
|
||||||
|
|
||||||
|
var compiled;
|
||||||
|
function templateFunction() {
|
||||||
|
if (!compiled) {
|
||||||
|
Handlebars.registerHelper("showMax", function(context, block) {
|
||||||
|
var maxLength = parseInt(block.hash.max) || 3;
|
||||||
|
if (context.length > maxLength){
|
||||||
|
return context.slice(0, maxLength).join(", ") + ", +" + (context.length - maxLength);
|
||||||
|
} else {
|
||||||
|
return context.join(", ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
compiled = Handlebars.compile(
|
||||||
|
"<div class='autocomplete'>" +
|
||||||
|
"<ul>" +
|
||||||
|
"{{#each options.users}}" +
|
||||||
|
"<li>" +
|
||||||
|
"<a href='#'>{{avatar this imageSize=\"tiny\"}} " +
|
||||||
|
"<span class='username'>{{this.username}}</span> " +
|
||||||
|
"<span class='name'>{{this.name}}</span></a>" +
|
||||||
|
"</li>" +
|
||||||
|
"{{/each}}" +
|
||||||
|
"{{#if options.groups}}" +
|
||||||
|
"{{#if options.users}}<hr>{{/if}}"+
|
||||||
|
"{{#each options.groups}}" +
|
||||||
|
"<li>" +
|
||||||
|
"<a href=''><i class='icon-group'></i>" +
|
||||||
|
"<span class='username'>{{this.name}}</span> " +
|
||||||
|
"<span class='name'>{{showMax this.usernames max=3}}</span>" +
|
||||||
|
"</a>" +
|
||||||
|
"</li>" +
|
||||||
|
"{{/each}}" +
|
||||||
|
"{{/if}}" +
|
||||||
|
"</ul>" +
|
||||||
|
"</div>");
|
||||||
|
}
|
||||||
|
return compiled;
|
||||||
|
}
|
||||||
|
|
||||||
|
var UserSelector = TextField.extend({
|
||||||
|
|
||||||
|
didInsertElement: function() {
|
||||||
|
var userSelectorView = this,
|
||||||
|
selected = [];
|
||||||
|
|
||||||
|
function excludedUsernames() {
|
||||||
|
var exclude = selected;
|
||||||
|
if (userSelectorView.get('excludeCurrentUser')) {
|
||||||
|
exclude = exclude.concat([Discourse.User.currentProp('username')]);
|
||||||
|
}
|
||||||
|
return exclude;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this.get('element')).val(this.get('usernames')).autocomplete({
|
||||||
|
template: templateFunction(),
|
||||||
|
|
||||||
|
disabled: this.get('disabled'),
|
||||||
|
single: this.get('single'),
|
||||||
|
allowAny: this.get('allowAny'),
|
||||||
|
|
||||||
|
dataSource: function(term) {
|
||||||
|
return Discourse.UserSearch.search({
|
||||||
|
term: term,
|
||||||
|
topicId: userSelectorView.get('topicId'),
|
||||||
|
exclude: excludedUsernames(),
|
||||||
|
include_groups: userSelectorView.get('include_groups')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
transformComplete: function(v) {
|
||||||
|
if (v.username) {
|
||||||
|
return v.username;
|
||||||
|
} else {
|
||||||
|
var excludes = excludedUsernames();
|
||||||
|
return v.usernames.filter(function(item){
|
||||||
|
// include only, those not found in the exclude list
|
||||||
|
return excludes.indexOf(item) === -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onChangeItems: function(items) {
|
||||||
|
items = _.map(items, function(i) {
|
||||||
|
if (i.username) {
|
||||||
|
return i.username;
|
||||||
|
} else {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
userSelectorView.set('usernames', items.join(","));
|
||||||
|
selected = items;
|
||||||
|
},
|
||||||
|
|
||||||
|
reverseTransform: function(i) {
|
||||||
|
return { username: i };
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
UserSelector.reopenClass({ templateFunction: templateFunction });
|
||||||
|
|
||||||
|
export default UserSelector;
|
|
@ -1,103 +0,0 @@
|
||||||
Discourse.UserSelector = Discourse.TextField.extend({
|
|
||||||
|
|
||||||
didInsertElement: function() {
|
|
||||||
var userSelectorView = this,
|
|
||||||
selected = [];
|
|
||||||
|
|
||||||
function excludedUsernames() {
|
|
||||||
var exclude = selected;
|
|
||||||
if (userSelectorView.get('excludeCurrentUser')) {
|
|
||||||
exclude = exclude.concat([Discourse.User.currentProp('username')]);
|
|
||||||
}
|
|
||||||
return exclude;
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this.get('element')).val(this.get('usernames')).autocomplete({
|
|
||||||
template: Discourse.UserSelector.templateFunction(),
|
|
||||||
|
|
||||||
disabled: this.get('disabled'),
|
|
||||||
single: this.get('single'),
|
|
||||||
allowAny: this.get('allowAny'),
|
|
||||||
|
|
||||||
dataSource: function(term) {
|
|
||||||
return Discourse.UserSearch.search({
|
|
||||||
term: term,
|
|
||||||
topicId: userSelectorView.get('topicId'),
|
|
||||||
exclude: excludedUsernames(),
|
|
||||||
include_groups: userSelectorView.get('include_groups')
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
transformComplete: function(v) {
|
|
||||||
if (v.username) {
|
|
||||||
return v.username;
|
|
||||||
} else {
|
|
||||||
var excludes = excludedUsernames();
|
|
||||||
return v.usernames.filter(function(item){
|
|
||||||
// include only, those not found in the exclude list
|
|
||||||
return excludes.indexOf(item) === -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onChangeItems: function(items) {
|
|
||||||
items = _.map(items, function(i) {
|
|
||||||
if (i.username) {
|
|
||||||
return i.username;
|
|
||||||
} else {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
userSelectorView.set('usernames', items.join(","));
|
|
||||||
selected = items;
|
|
||||||
},
|
|
||||||
|
|
||||||
reverseTransform: function(i) {
|
|
||||||
return { username: i };
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper("showMax", function(context, block) {
|
|
||||||
var maxLength = parseInt(block.hash.max) || 3;
|
|
||||||
if (context.length > maxLength){
|
|
||||||
return context.slice(0, maxLength).join(", ") + ", +" + (context.length - maxLength);
|
|
||||||
} else {
|
|
||||||
return context.join(", ");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Discourse.UserSelector.reopenClass({
|
|
||||||
// I really want to move this into a template file, but I need a handlebars template here, not an ember one
|
|
||||||
templateFunction: function() {
|
|
||||||
this.compiled = this.compiled || Handlebars.compile(
|
|
||||||
"<div class='autocomplete'>" +
|
|
||||||
"<ul>" +
|
|
||||||
"{{#each options.users}}" +
|
|
||||||
"<li>" +
|
|
||||||
"<a href='#'>{{avatar this imageSize=\"tiny\"}} " +
|
|
||||||
"<span class='username'>{{this.username}}</span> " +
|
|
||||||
"<span class='name'>{{this.name}}</span></a>" +
|
|
||||||
"</li>" +
|
|
||||||
"{{/each}}" +
|
|
||||||
"{{#if options.groups}}" +
|
|
||||||
"{{#if options.users}}<hr>{{/if}}"+
|
|
||||||
"{{#each options.groups}}" +
|
|
||||||
"<li>" +
|
|
||||||
"<a href=''><i class='icon-group'></i>" +
|
|
||||||
"<span class='username'>{{this.name}}</span> " +
|
|
||||||
"<span class='name'>{{showMax this.usernames max=3}}</span>" +
|
|
||||||
"</a>" +
|
|
||||||
"</li>" +
|
|
||||||
"{{/each}}" +
|
|
||||||
"{{/if}}" +
|
|
||||||
"</ul>" +
|
|
||||||
"</div>");
|
|
||||||
return this.compiled;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Discourse.View.registerHelper('userSelector', Discourse.UserSelector);
|
|
|
@ -19,6 +19,7 @@
|
||||||
//= require ./discourse/controllers/controller
|
//= require ./discourse/controllers/controller
|
||||||
//= require ./discourse/controllers/object_controller
|
//= require ./discourse/controllers/object_controller
|
||||||
//= require ./discourse/controllers/navigation/default
|
//= require ./discourse/controllers/navigation/default
|
||||||
|
//= require ./discourse/views/text-field
|
||||||
//= require ./discourse/views/modal/modal_body_view
|
//= require ./discourse/views/modal/modal_body_view
|
||||||
//= require ./discourse/views/modal/flag_view
|
//= require ./discourse/views/modal/flag_view
|
||||||
//= require ./discourse/views/combobox_view
|
//= require ./discourse/views/combobox_view
|
||||||
|
|
|
@ -1,181 +0,0 @@
|
||||||
var controller, oldSearchTextField, oldSearchResultsTypeView, oldViews;
|
|
||||||
|
|
||||||
var SearchTextFieldStub = Ember.View.extend({
|
|
||||||
classNames: ["search-text-field-stub"],
|
|
||||||
template: Ember.Handlebars.compile("{{view.value}} {{view.searchContext}}")
|
|
||||||
});
|
|
||||||
|
|
||||||
var SearchResultsTypeViewStub = Ember.View.extend({
|
|
||||||
classNames: ["search-results-type-view-stub"],
|
|
||||||
template: Ember.Handlebars.compile("{{view.type}} {{view.content}}")
|
|
||||||
});
|
|
||||||
|
|
||||||
var setUpController = function(properties) {
|
|
||||||
Ember.run(function() {
|
|
||||||
controller.setProperties(properties);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var appendView = function() {
|
|
||||||
Ember.run(function() {
|
|
||||||
Ember.View.create({
|
|
||||||
container: Discourse.__container__,
|
|
||||||
controller: controller,
|
|
||||||
templateName: "search"
|
|
||||||
}).appendTo(fixture());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var resultsSectionSelector = "ul";
|
|
||||||
var resultsFilterSelector = ".filter";
|
|
||||||
var noResultsSelector = ".no-results";
|
|
||||||
var searchInProgressSelector = ".searching";
|
|
||||||
|
|
||||||
module("Template: search", {
|
|
||||||
setup: function() {
|
|
||||||
sinon.stub(I18n, "t").returnsArg(0);
|
|
||||||
|
|
||||||
oldSearchTextField = Discourse.SearchTextField;
|
|
||||||
Discourse.SearchTextField = SearchTextFieldStub;
|
|
||||||
|
|
||||||
oldSearchResultsTypeView = Discourse.SearchResultsTypeView;
|
|
||||||
Discourse.SearchResultsTypeView = SearchResultsTypeViewStub;
|
|
||||||
|
|
||||||
oldViews = Ember.View.views;
|
|
||||||
Ember.View.views = {};
|
|
||||||
|
|
||||||
controller = Ember.ArrayController.create();
|
|
||||||
},
|
|
||||||
|
|
||||||
teardown: function() {
|
|
||||||
I18n.t.restore();
|
|
||||||
|
|
||||||
Discourse.SearchTextField = oldSearchTextField;
|
|
||||||
Discourse.SearchResultsTypeView = oldSearchResultsTypeView;
|
|
||||||
|
|
||||||
Ember.View.views = oldViews;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
test("contain search text field (correctly bound to contextual placeholder and search term values)", function() {
|
|
||||||
setUpController({
|
|
||||||
term: "term",
|
|
||||||
searchContext: "searchContext"
|
|
||||||
});
|
|
||||||
|
|
||||||
appendView();
|
|
||||||
|
|
||||||
var $searchTextField = fixture(".search-text-field-stub");
|
|
||||||
ok(exists($searchTextField), "the field exists");
|
|
||||||
equal($searchTextField.text(), "term searchContext", "the placeholder and search term values are correctly bound");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("shows spinner icon instead of results area when loading", function() {
|
|
||||||
setUpController({
|
|
||||||
loading: true
|
|
||||||
});
|
|
||||||
|
|
||||||
appendView();
|
|
||||||
|
|
||||||
ok(exists(fixture(".search-text-field-stub")), "the search field is still shown, even when loading results");
|
|
||||||
|
|
||||||
ok(!exists(fixture(resultsSectionSelector)), "no results are shown");
|
|
||||||
ok(!exists(fixture(noResultsSelector)), "the 'no results' message is not shown");
|
|
||||||
|
|
||||||
var $searchInProgress = fixture(searchInProgressSelector);
|
|
||||||
ok(exists($searchInProgress), "the 'search in progress' message is shown");
|
|
||||||
ok(exists($searchInProgress.find(".fa-spinner")), "the 'search in progress' message contains a spinner icon");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("shows 'no results' message when loading has finished and there are no results found", function() {
|
|
||||||
setUpController({
|
|
||||||
loading: false,
|
|
||||||
noResults: true
|
|
||||||
});
|
|
||||||
|
|
||||||
appendView();
|
|
||||||
|
|
||||||
ok(exists(fixture(".search-text-field-stub")), "the search field is shown to allow another search");
|
|
||||||
|
|
||||||
ok(!exists(fixture(resultsSectionSelector)), "no results are shown");
|
|
||||||
ok(!exists(fixture(searchInProgressSelector)), "the 'search in progress' message is not shown");
|
|
||||||
|
|
||||||
var $noResults = fixture(noResultsSelector);
|
|
||||||
ok(exists($noResults), "the 'no results' message is shown");
|
|
||||||
notEqual($noResults.text().indexOf("search.no_results"), -1, "the 'no results' message contains correct text");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("shows only search text field when user starts typing a new search term, but there are not enough characters typed yet", function() {
|
|
||||||
setUpController({
|
|
||||||
loading: false,
|
|
||||||
noResults: false,
|
|
||||||
content: []
|
|
||||||
});
|
|
||||||
|
|
||||||
appendView();
|
|
||||||
|
|
||||||
ok(exists(fixture(".search-text-field-stub")), "search text field is shown");
|
|
||||||
|
|
||||||
ok(!exists(fixture(resultsSectionSelector)), "no results are shown");
|
|
||||||
ok(!exists(fixture(searchInProgressSelector)), "the 'search in progress' message is not shown");
|
|
||||||
ok(!exists(fixture(noResultsSelector)), "the 'no results' message is not shown");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("correctly iterates through and displays search results when the search succeeds", function() {
|
|
||||||
setUpController({
|
|
||||||
loading: false,
|
|
||||||
noResults: false,
|
|
||||||
content: [
|
|
||||||
Ember.Object.create({
|
|
||||||
more: true,
|
|
||||||
name: "name_1",
|
|
||||||
results: "results_1",
|
|
||||||
type: "type_1"
|
|
||||||
}),
|
|
||||||
Ember.Object.create({
|
|
||||||
more: false,
|
|
||||||
name: "name_2",
|
|
||||||
results: "results_2",
|
|
||||||
type: "type_2"
|
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
appendView();
|
|
||||||
|
|
||||||
var $resultSections = fixture(resultsSectionSelector);
|
|
||||||
|
|
||||||
equal(count($resultSections), 2, "the number of sections in results is correct");
|
|
||||||
|
|
||||||
var $firstSection = $resultSections.eq(0);
|
|
||||||
var $filter = $firstSection.find(resultsFilterSelector);
|
|
||||||
notEqual($firstSection.text().indexOf("name_1"), -1, "the name of the first section is correct");
|
|
||||||
ok(exists($filter), "the 'show more' link in the first section exists");
|
|
||||||
notEqual($filter.text().indexOf("show_more"), -1, "the 'show more' link in the first section contains correct text");
|
|
||||||
equal($firstSection.find(".search-results-type-view-stub").text(), "type_1 results_1", "the results view in the first section is correctly rendered");
|
|
||||||
|
|
||||||
var $secondSection = $resultSections.eq(1);
|
|
||||||
notEqual($secondSection.text().indexOf("name_2"), -1, "the name of the second section is correct");
|
|
||||||
ok(!exists($secondSection.find(resultsFilterSelector)), "the 'show more' link in the second section does not exist");
|
|
||||||
equal($secondSection.find(".search-results-type-view-stub").text(), "type_2 results_2", "the results view in the second section is correctly rendered");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("displays 'close more results' button when the search is in the more results mode", function() {
|
|
||||||
setUpController({
|
|
||||||
loading: false,
|
|
||||||
noResults: false,
|
|
||||||
showCancelFilter: true,
|
|
||||||
content: [
|
|
||||||
Ember.Object.create({
|
|
||||||
more: false
|
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
appendView();
|
|
||||||
|
|
||||||
var $firstSection = fixture(resultsSectionSelector).eq(0);
|
|
||||||
var $filter = $firstSection.find(resultsFilterSelector);
|
|
||||||
ok(exists($filter), "the 'close more results' button exists");
|
|
||||||
ok(exists($filter.find(".fa-times-circle")), "the 'close more results' contains correct icon");
|
|
||||||
});
|
|
|
@ -6,13 +6,13 @@ var placeholderUsesKeyAndContext = function(key, context) {
|
||||||
deepEqual(placeholder.context, context, "correct parameters are passed to the message");
|
deepEqual(placeholder.context, context, "correct parameters are passed to the message");
|
||||||
};
|
};
|
||||||
|
|
||||||
module("Discourse.SearchTextField", {
|
module("view:search-text-field", {
|
||||||
setup: function() {
|
setup: function() {
|
||||||
sinon.stub(I18n, "t", function(key, context) {
|
sinon.stub(I18n, "t", function(key, context) {
|
||||||
return {key: key, context: context};
|
return {key: key, context: context};
|
||||||
});
|
});
|
||||||
|
|
||||||
view = Discourse.SearchTextField.create();
|
view = viewClassFor('search-text-field').create();
|
||||||
},
|
},
|
||||||
|
|
||||||
teardown: function() {
|
teardown: function() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
var appendTextFieldWithProperties = function(properties) {
|
var appendTextFieldWithProperties = function(properties) {
|
||||||
var view = Discourse.TextField.create(properties);
|
var view = viewClassFor('text-field').create(properties);
|
||||||
Ember.run(function() {
|
Ember.run(function() {
|
||||||
view.appendTo(fixture());
|
view.appendTo(fixture());
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,7 @@ var hasNoAttr = function($element, attrName) {
|
||||||
equal($element.attr(attrName), undefined, "'" + attrName + "' attribute is not rendered");
|
equal($element.attr(attrName), undefined, "'" + attrName + "' attribute is not rendered");
|
||||||
};
|
};
|
||||||
|
|
||||||
module("Discourse.TextField");
|
module("view:text-field");
|
||||||
|
|
||||||
test("renders correctly with no properties set", function() {
|
test("renders correctly with no properties set", function() {
|
||||||
appendTextFieldWithProperties({});
|
appendTextFieldWithProperties({});
|
||||||
|
|
Loading…
Reference in a new issue