FEATURE: improves select-box to support category selection on new topic

This commit is contained in:
Joffrey JAFFEUX 2017-08-23 15:08:19 +02:00 committed by GitHub
parent 7c15b27a90
commit 7b4e302677
18 changed files with 439 additions and 173 deletions

View File

@ -36,11 +36,11 @@
<h3>{{i18n "admin.customize.theme.color_scheme"}}</h3> <h3>{{i18n "admin.customize.theme.color_scheme"}}</h3>
<p>{{i18n "admin.customize.theme.color_scheme_select"}}</p> <p>{{i18n "admin.customize.theme.color_scheme_select"}}</p>
<p>{{d-select-box content=colorSchemes <p>{{select-box content=colorSchemes
textKey="name" textKey="name"
filterable=true filterable=true
value=colorSchemeId value=colorSchemeId
icon="paint-brush"}} icon="paint-brush"}}
{{#if colorSchemeChanged}} {{#if colorSchemeChanged}}
{{d-button action="changeScheme" class="btn-primary btn-small submit-edit" icon="check"}} {{d-button action="changeScheme" class="btn-primary btn-small submit-edit" icon="check"}}
{{d-button action="cancelChangeScheme" class="btn-small cancel-edit" icon="times"}} {{d-button action="cancelChangeScheme" class="btn-small cancel-edit" icon="times"}}

View File

@ -0,0 +1,107 @@
import SelectBoxComponent from "discourse/components/select-box";
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
import { observes, on } from 'ember-addons/ember-computed-decorators';
import PermissionType from 'discourse/models/permission-type';
import Category from 'discourse/models/category';
export default SelectBoxComponent.extend({
classNames: ["category-select-box"],
textKey: "name",
filterable: true,
castInteger: true,
width: '100%',
@on("willInsertElement")
@observes("selectedContent")
_setHeaderText: function() {
let headerText;
if (Ember.isNone(this.get("selectedContent"))) {
if (this.siteSettings.allow_uncategorized_topics) {
headerText = Ember.get(Category.findUncategorized(), this.get("textKey"));
} else {
headerText = I18n.t("category.choose");
}
} else {
headerText = this.get("selectedContent.text");
}
this.set("headerText", headerText);
},
// original method is kept for compatibility
selectBoxRowTemplate: function() {
return (rowComponent) => this.rowContentTemplate(rowComponent.get("content"));
}.property(),
@observes("scopedCategoryId", "categories")
_scopeCategories() {
let scopedCategoryId = this.get("scopedCategoryId");
const categories = this.get("categories");
// Always scope to the parent of a category, if present
if (scopedCategoryId) {
const scopedCat = Category.findById(scopedCategoryId);
scopedCategoryId = scopedCat.get("parent_category_id") || scopedCat.get("id");
}
const excludeCategoryId = this.get("excludeCategoryId");
const filteredCategories = categories.filter(c => {
const categoryId = c.get("id");
if (scopedCategoryId && categoryId !== scopedCategoryId && c.get("parent_category_id") !== scopedCategoryId) { return false; }
if (excludeCategoryId === categoryId) { return false; }
return c.get("permission") === PermissionType.FULL;
});
this.set("content", filteredCategories);
},
@on("init")
@observes("site.sortedCategories")
_updateCategories() {
if (!this.get("categories")) {
const categories = Discourse.SiteSettings.fixed_category_positions_on_create ?
Category.list() :
Category.listByActivity();
this.set("categories", categories);
}
},
rowContentTemplate(item) {
let category;
let result = '<div class="category-status">';
// If we have no id, but text with the uncategorized name, we can use that badge.
if (Ember.isEmpty(item.id)) {
const uncat = Category.findUncategorized();
if (uncat && uncat.get("name") === item.text) {
category = uncat;
}
} else {
category = Category.findById(parseInt(item.id,10));
}
if (!category) return item.text;
result += categoryBadgeHTML(category, {link: false, allowUncategorized: true, hideParent: true});
const parentCategoryId = category.get("parent_category_id");
if (parentCategoryId) {
result += categoryBadgeHTML(Category.findById(parentCategoryId), {link: false}) + "&nbsp;" + result;
}
result += ` <span class='topic-count'>&times; ${category.get("topic_count")}</span></div>`;
const description = category.get("description");
// TODO wtf how can this be null?;
if (description && description !== 'null') {
result += `<div class="category-desc">${description.substr(0, 200)}${description.length > 200 ? '&hellip;' : ''}</div>`;
}
return result;
}
});

View File

@ -1,7 +0,0 @@
import SelectBoxComponent from "discourse/components/select-box";
export default SelectBoxComponent.extend({
layoutName: "components/select-box",
classNames: "discourse"
});

View File

@ -1,17 +1,18 @@
import { on, observes } from "ember-addons/ember-computed-decorators"; import { on, observes } from "ember-addons/ember-computed-decorators";
import { iconHTML } from 'discourse-common/lib/icon-library';
export default Ember.Component.extend({ export default Ember.Component.extend({
layoutName: "components/select-box",
classNames: "select-box", classNames: "select-box",
width: 220,
classNameBindings: ["expanded:is-expanded"], classNameBindings: ["expanded:is-expanded"],
attributeBindings: ['componentStyle:style'],
componentStyle: function() {
return Ember.String.htmlSafe(`width: ${this.get("maxWidth")}px`);
}.property("maxWidth"),
expanded: false, expanded: false,
focused: false, focused: false,
tabindex: 0,
caretUpIcon: "caret-up", caretUpIcon: "caret-up",
caretDownIcon: "caret-down", caretDownIcon: "caret-down",
@ -19,6 +20,7 @@ export default Ember.Component.extend({
icon: null, icon: null,
value: null, value: null,
selectedContent: null,
noContentText: I18n.t("select_box.no_content"), noContentText: I18n.t("select_box.no_content"),
lastHoveredId: null, lastHoveredId: null,
@ -43,6 +45,31 @@ export default Ember.Component.extend({
renderBody: false, renderBody: false,
castInteger: false,
filterFunction: function() {
return (selectBox) => {
const filter = selectBox.get("filter").toLowerCase();
return _.filter(selectBox.get("content"), (content) => {
return content[selectBox.get("textKey")].toLowerCase().indexOf(filter) > -1;
});
};
},
selectBoxRowTemplate: function() {
return (rowComponent) => {
let template = "";
if (rowComponent.get("content.icon")) {
template += iconHTML(Handlebars.escapeExpression(rowComponent.get("content.icon")));
}
template += `<p class="text">${Handlebars.escapeExpression(rowComponent.get("text"))}</p>`;
return template;
};
}.property(),
init() { init() {
this._super(); this._super();
@ -52,8 +79,7 @@ export default Ember.Component.extend({
this.setProperties({ this.setProperties({
componentId: this.elementId, componentId: this.elementId,
filteredContent: [], filteredContent: []
selectedContent: {}
}); });
}, },
@ -71,9 +97,7 @@ export default Ember.Component.extend({
if (Ember.isEmpty(this.get("filter"))) { if (Ember.isEmpty(this.get("filter"))) {
this.set("filteredContent", this._remapContent(this.get("content"))); this.set("filteredContent", this._remapContent(this.get("content")));
} else { } else {
const filtered = _.filter(this.get("content"), (content) => { const filtered = this.filterFunction()(this);
return content[this.get("textKey")].toLowerCase().indexOf(this.get("filter")) > -1;
});
this.set("filteredContent", this._remapContent(filtered)); this.set("filteredContent", this._remapContent(filtered));
} }
}, },
@ -95,18 +119,26 @@ export default Ember.Component.extend({
$(document).off("keydown.select-box"); $(document).off("keydown.select-box");
this.$(".select-box-offscreen").off("focusin.select-box"); this.$(".select-box-offscreen").off("focusin.select-box");
this.$(".select-box-offscreen").off("focusout.select-box"); this.$(".select-box-offscreen").off("focusout.select-box");
this.$(".select-box-offscreen").off("keydown.select-box");
$(window).off("resize.select-box");
}, },
@on("didRender") @on("didRender")
_configureSelectBoxDOM: function() { _configureSelectBoxDOM: function() {
this.$().css("width", this.get("width"));
this.$(".select-box-header").css("height", this.$().height());
this.$(".select-box-filter").css("height", this.$().height());
if (this.get("expanded")) { if (this.get("expanded")) {
this.$(".select-box-body").css('width', this.get("maxWidth")); this.$(".select-box-body").css('width', this.$().width());
this.$(".select-box-filter .filter-query").focus();
this.$(".select-box-collection").css("max-height", this.get("maxCollectionHeight")); this.$(".select-box-collection").css("max-height", this.get("maxCollectionHeight"));
this._bindTab(); this._bindTab();
this._applyDirection();
this._positionSelectBoxWrapper(); Ember.run.schedule('afterRender', () => {
this._applyDirection();
this._positionSelectBoxWrapper();
});
} else { } else {
$(document).off("keydown.select-box"); $(document).off("keydown.select-box");
this.$(".select-box-wrapper").hide(); this.$(".select-box-wrapper").hide();
@ -124,7 +156,10 @@ export default Ember.Component.extend({
this.set("filteredContent", this._remapContent(this.get("content"))); this.set("filteredContent", this._remapContent(this.get("content")));
this._setSelectedContent(this.get("content")); this._setSelectedContent(this.get("content"));
this.set("headerText", this.get("defaultHeaderText") || this.get("selectedContent.text"));
if (Ember.isNone(this.get("headerText"))) {
this.set("headerText", this.get("selectedContent.text"));
}
}, },
@on("didInsertElement") @on("didInsertElement")
@ -143,9 +178,27 @@ export default Ember.Component.extend({
this.set("focused", true); this.set("focused", true);
}); });
this.$(".select-box-offscreen").on("keydown.select-box", (event) => {
const keyCode = event.keyCode || event.which;
if(keyCode === 13 || keyCode === 40) {
this.setProperties({expanded: true, focused: false});
return false;
}
if(keyCode === 27) {
this.$(".select-box-offscreen").blur();
return false;
}
});
this.$(".select-box-offscreen").on("focusout.select-box", () => { this.$(".select-box-offscreen").on("focusout.select-box", () => {
this.set("focused", false); this.set("focused", false);
}); });
$(window).on("resize.select-box", () => {
this.set("expanded", false);
});
}, },
actions: { actions: {
@ -158,6 +211,10 @@ export default Ember.Component.extend({
}, },
onSelectRow(id) { onSelectRow(id) {
if(this.get("castInteger") === true) {
id = parseInt(id, 10);
}
this.setProperties({ this.setProperties({
value: id, value: id,
expanded: false expanded: false
@ -184,8 +241,13 @@ export default Ember.Component.extend({
}, },
_normalizeContent(content) { _normalizeContent(content) {
let id = content[this.get("idKey")];
if(this.get("castInteger") === true) {
id = parseInt(id, 10);
}
return { return {
id: content[this.get("idKey")], id,
text: content[this.get("textKey")], text: content[this.get("textKey")],
icon: content[this.get("iconKey")] icon: content[this.get("iconKey")]
}; };
@ -204,7 +266,7 @@ export default Ember.Component.extend({
const headerHeight = this.$(".select-box-header").outerHeight(); const headerHeight = this.$(".select-box-header").outerHeight();
this.$(".select-box-wrapper").css({ this.$(".select-box-wrapper").css({
width: this.get("maxWidth"), width: this.$().width(),
display: "block", display: "block",
height: headerHeight + this.$(".select-box-body").outerHeight() height: headerHeight + this.$(".select-box-body").outerHeight()
}); });

View File

@ -1,3 +1,5 @@
import { on, observes } from 'ember-addons/ember-computed-decorators';
export default Ember.Component.extend({ export default Ember.Component.extend({
classNames: "select-box-row", classNames: "select-box-row",
@ -9,6 +11,14 @@ export default Ember.Component.extend({
lastHoveredId: null, lastHoveredId: null,
@on("init")
@observes("content", "lastHoveredId", "selectedId", "selectBoxRowTemplate")
_updateTemplate: function() {
this.set("isHighlighted", this._isHighlighted());
this.set("text", this.get("content.text"));
this.set("template", this.get("selectBoxRowTemplate")(this));
},
mouseEnter() { mouseEnter() {
this.sendAction("onHover", this.get("content.id")); this.sendAction("onHover", this.get("content.id"));
}, },

View File

@ -1,13 +1,16 @@
import { observes } from 'ember-addons/ember-computed-decorators'; import { observes } from 'ember-addons/ember-computed-decorators';
import DiscourseSelectBoxComponent from "discourse/components/d-select-box"; import SelectBoxComponent from "discourse/components/select-box";
export default SelectBoxComponent.extend({
textKey: "name",
headerText: I18n.t("topic.controls"),
maxCollectionHeight: 300,
export default DiscourseSelectBoxComponent.extend({
init() { init() {
this._super(); this._super();
this.set("textKey", "name");
this.set("defaultHeaderText", I18n.t("topic.controls"));
this.set("maxCollectionHeight", 300);
this._createContent(); this._createContent();
}, },

View File

@ -99,7 +99,7 @@ function positioningWorkaround($fixedElement) {
fixedElement.style.top = '0px'; fixedElement.style.top = '0px';
composingTopic = $('#reply-control select.category-combobox').length > 0; composingTopic = $('#reply-control .category-select-box').length > 0;
const height = calcHeight(composingTopic); const height = calcHeight(composingTopic);

View File

@ -4,6 +4,7 @@
aria-haspopup="true" aria-haspopup="true"
role="button" role="button"
aria-labelledby="select-box-input-{{componentId}}" aria-labelledby="select-box-input-{{componentId}}"
tabindex={{tabindex}}
/> />
{{component selectBoxHeaderComponent {{component selectBoxHeaderComponent
@ -29,6 +30,7 @@
{{component selectBoxCollectionComponent {{component selectBoxCollectionComponent
filteredContent=filteredContent filteredContent=filteredContent
selectBoxRowComponent=selectBoxRowComponent selectBoxRowComponent=selectBoxRowComponent
selectBoxRowTemplate=selectBoxRowTemplate
lastHoveredId=lastHoveredId lastHoveredId=lastHoveredId
onSelectRow=(action "onSelectRow") onSelectRow=(action "onSelectRow")
onHoverRow=(action "onHoverRow") onHoverRow=(action "onHoverRow")

View File

@ -2,6 +2,7 @@
{{#each filteredContent as |content|}} {{#each filteredContent as |content|}}
{{component selectBoxRowComponent {{component selectBoxRowComponent
content=content content=content
selectBoxRowTemplate=selectBoxRowTemplate
lastHoveredId=lastHoveredId lastHoveredId=lastHoveredId
onSelect=onSelectRow onSelect=onSelectRow
onHover=onHoverRow onHover=onHoverRow

View File

@ -1,14 +1,10 @@
<div class="wrapper"> {{input
{{input tabindex="-1"
tabindex="-1" class="filter-query"
class="filter-query" placeholder=filterPlaceholder
placeholder=filterPlaceholder key-up=onFilterChange
key-up=onFilterChange }}
}}
{{#if filterIcon}} {{#if filterIcon}}
<div class="filter-icon"> {{d-icon filterIcon}}
{{d-icon filterIcon}} {{/if}}
</div>
{{/if}}
</div>

View File

@ -1,7 +1 @@
{{#if content.icon}} {{{template}}}
{{d-icon content.icon}}
{{/if}}
<p class="text">
{{content.text}}
</p>

View File

@ -72,7 +72,7 @@
{{#if model.showCategoryChooser}} {{#if model.showCategoryChooser}}
<div class="category-input"> <div class="category-input">
{{category-chooser valueAttribute="id" value=model.categoryId scopedCategoryId=scopedCategoryId tabindex="3"}} {{category-select-box valueAttribute="id" value=model.categoryId scopedCategoryId=scopedCategoryId tabindex="3"}}
{{popup-input-tip validation=categoryValidation}} {{popup-input-tip validation=categoryValidation}}
</div> </div>
{{#if model.archetype.hasOptions}} {{#if model.archetype.hasOptions}}

View File

@ -0,0 +1,34 @@
.category-select-box.select-box {
height: 34px;
.select-box-row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
line-height: 14px;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
.topic-count {
font-size: 11px;
color: $primary;
}
.category-status {
-webkit-box-flex: 0;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
}
.category-desc {
-webkit-box-flex: 0;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
color: $primary;
font-size: 0.857em;
line-height: 16px;
}
}
}

View File

@ -1,21 +1,53 @@
.select-box { .select-box {
border-radius: 3px; border-radius: 3px;
box-sizing: border-box; -webkit-box-sizing: border-box;
display: inline-block; box-sizing: border-box;
flex-direction: column; display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
position: relative; position: relative;
z-index: 998; z-index: 998;
height: 34px;
&.is-expanded { &.is-expanded {
z-index: 999; z-index: 999;
.select-box-wrapper {
border: 1px solid $tertiary;
border-radius: 3px;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
}
.select-box-body { .select-box-body {
border-radius: 3px 3px 0 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
flex-direction: column; -webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
left: 0; left: 0;
position: absolute; position: absolute;
top: 0; top: 0;
} }
.collection, {
border-radius: 0 0 3px 3px;
}
}
&.is-highlighted {
.select-box-header {
border: 1px solid $tertiary;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
}
} }
&.is-reversed { &.is-reversed {
@ -37,35 +69,52 @@
.select-box-header { .select-box-header {
background: $secondary; background: $secondary;
border: 1px solid transparent; border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
box-sizing: border-box; border-radius: 3px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
cursor: pointer; cursor: pointer;
height: 32px;
outline: none; outline: none;
&.is-focused {
border: 1px solid $tertiary;
border-radius: 3px;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
}
} }
.select-box-body { .select-box-body {
display: none; display: none;
box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box;
} }
.select-box-row { .select-box-row {
cursor: pointer; cursor: pointer;
outline: none; outline: none;
padding: 5px; padding: 5px;
height: 28px; display: -webkit-box;
min-height: 28px; display: -ms-flexbox;
line-height: 28px;
display: flex; display: flex;
align-items: center; -webkit-box-pack: start;
justify-content: flex-start; -ms-flex-pack: start;
justify-content: flex-start;
} }
.select-box-collection { .select-box-collection {
box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box;
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
flex: 1; -webkit-box-flex: 1;
flex-direction: column; -ms-flex: 1;
flex: 1;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
background: $secondary; background: $secondary;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
@ -86,7 +135,8 @@
left: 0; left: 0;
background: none; background: none;
display: none; display: none;
box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box;
pointer-events: none; pointer-events: none;
border: 1px solid transparent; border: 1px solid transparent;
} }
@ -95,17 +145,28 @@
.select-box .select-box-header { .select-box .select-box-header {
.wrapper { .wrapper {
height: inherit; height: inherit;
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
flex-direction: row; -webkit-box-orient: horizontal;
align-items: center; -webkit-box-direction: normal;
justify-content: space-between; -ms-flex-direction: row;
flex-direction: row;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
padding-left: 10px; padding-left: 10px;
padding-right: 10px; padding-right: 10px;
} }
.current-selection { .current-selection {
text-align: left; text-align: left;
flex: 1; -webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@ -128,7 +189,9 @@
} }
.select-box .select-box-collection { .select-box .select-box-collection {
flex: 0 1 auto; -webkit-box-flex: 0;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
.collection { .collection {
padding: 0; padding: 0;
@ -144,8 +207,6 @@
cursor: pointer; cursor: pointer;
border-radius: 5px; border-radius: 5px;
background: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%)); background: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%));
-webkit-transition: color .2s ease;
transition: color .2s ease;
} }
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
@ -155,6 +216,9 @@
} }
.select-box .select-box-row { .select-box .select-box-row {
margin: 5px;
min-height: 1px;
.d-icon { .d-icon {
margin-right: 5px; margin-right: 5px;
} }
@ -171,26 +235,30 @@
} }
.select-box .select-box-filter { .select-box .select-box-filter {
.wrapper { background: $secondary;
display: flex; display: -webkit-box;
align-items: center; display: -ms-flexbox;
justify-content: space-between; display: flex;
margin: 5px 10px; -webkit-box-align: center;
} -ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
padding: 0 10px;
input, input:focus { input, input:focus {
margin: 0; margin: 0;
flex: 1; -webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
outline: none; outline: none;
border: 0; border: 0;
box-shadow: none; -webkit-box-shadow: none;
box-shadow: none;
width: 100%; width: 100%;
padding: 5px 0; padding: 5px 0;
} }
.icon {
margin-right: 5px;
}
} }
.select-box .select-box-offscreen, .select-box .select-box-offscreen:focus { .select-box .select-box-offscreen, .select-box .select-box-offscreen:focus {

View File

@ -162,7 +162,7 @@
padding-left: 7px; padding-left: 7px;
} }
.control-row { .control-row {
margin: 0 0 0 5px; margin: 0 5px 0 5px;
} }
.saving-text { .saving-text {
display: none; display: none;
@ -221,14 +221,9 @@
.contents { .contents {
input#reply-title { input#reply-title {
padding: 7px 10px; padding: 7px 10px;
margin: 6px 10px 3px 0; margin-bottom: 0;
color: $primary; color: $primary;
}
input#reply-title {
width: 400px; width: 400px;
color: $primary;
} }
.wmd-controls { .wmd-controls {
transition: top 0.3s ease; transition: top 0.3s ease;
@ -242,34 +237,13 @@
min-width: 1280px; min-width: 1280px;
.form-element { .form-element {
position: relative; position: relative;
display: inline-block; display: flex;
.select2-container {
width: 400px;
margin-top: 5px; .category-input {
a {
padding-top: 4px;
height: 28px;
}
b {
margin-top: 4px;
}
}
.category-combobox {
width: 430px; width: 430px;
@include medium-width { width: 285px; } @include medium-width { width: 285px; }
@include small-width { width: 220px; } @include small-width { width: 220px; }
.select2-drop {
left: -9000px;
width: 428px;
@include medium-width { width: 283px; }
@include small-width { width: 218px; }
}
.select2-search input {
width: 378px;
@include medium-width { width: 233px; }
@include small-width { width: 168px; }
}
} }
} }
.edit-reason-input { .edit-reason-input {
@ -286,7 +260,7 @@
} }
#reply-title { #reply-title {
color: $primary; color: $primary;
margin-right: 10px; margin-right: 5px;
float: left; float: left;
&:disabled { &:disabled {
background-color: $primary-low; background-color: $primary-low;

View File

@ -19,7 +19,7 @@ input {
padding: 4px; padding: 4px;
border-radius: 3px; border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(0,0,0, .3); box-shadow: inset 0 1px 1px rgba(0,0,0, .3);
border: 1px solid $primary-low; border: 1px solid $primary-low;
} }
input[type=radio], input[type=checkbox] { input[type=radio], input[type=checkbox] {
box-shadow: none; box-shadow: none;
@ -38,7 +38,7 @@ input[type=radio], input[type=checkbox] {
width: 100%; width: 100%;
z-index: 1039; z-index: 1039;
height: 0; height: 0;
background-color: $primary-low; background-color: $primary-low;
bottom: 0; bottom: 0;
font-size: 1em; font-size: 1em;
position: fixed; position: fixed;
@ -58,7 +58,7 @@ input[type=radio], input[type=checkbox] {
line-height: 30px; line-height: 30px;
} }
.control-row { .control-row {
margin: 0 0 0 5px; margin: 0 5px 0 5px;
.reply-to { .reply-to {
overflow: hidden; overflow: hidden;
max-width: 80%; max-width: 80%;
@ -88,7 +88,7 @@ input[type=radio], input[type=checkbox] {
&.draft { &.draft {
height: 35px !important; height: 35px !important;
cursor: pointer; cursor: pointer;
border-top: 1px solid $primary-low; border-top: 1px solid $primary-low;
.draft-text { .draft-text {
display: block; display: block;
position: absolute; position: absolute;
@ -122,10 +122,17 @@ input[type=radio], input[type=checkbox] {
input#reply-title { input#reply-title {
padding: 5px; padding: 5px;
margin-top: 6px; margin-top: 6px;
width: 99%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid $secondary; border: 1px solid $secondary;
} }
.category-input {
margin-top: 3px;
.category-select-box {
height: 28px;
}
}
.wmd-controls { .wmd-controls {
transition: top 0.3s ease; transition: top 0.3s ease;
top: 110px; top: 110px;
@ -134,20 +141,7 @@ input[type=radio], input[type=checkbox] {
} }
.contents { .contents {
padding: 8px 5px 0 5px; padding: 8px 5px 0 5px;
.form-element {
.select2-container {
width: 99%;
margin-top: 6px;
a {
padding-top: 4px;
height: 28px;
}
b {
margin-top: 4px;
}
}
}
.edit-reason-input, .display-edit-reason { .edit-reason-input, .display-edit-reason {
display: none; display: none;
} }
@ -194,12 +188,6 @@ input[type=radio], input[type=checkbox] {
} }
} }
} }
.category-input {
// hack, select2 is using inline styles
.select2-container {
width: 99% !important;
}
}
.popup-tip .close { .popup-tip .close {
padding: 0 2px 2px 8px; // so my fingers can touch the little x padding: 0 2px 2px 8px; // so my fingers can touch the little x
} }

View File

@ -99,7 +99,7 @@ QUnit.test("Reply as new topic", assert => {
"it fills composer with the ring string" "it fills composer with the ring string"
); );
assert.equal( assert.equal(
find('.category-combobox').select2('data').text, "feature", find('.category-select-box .select-box-header .current-selection').html().trim(), "feature",
"it fills category selector with the right category" "it fills category selector with the right category"
); );
}); });

View File

@ -33,7 +33,7 @@ componentTest('accepts a value by reference', {
andThen(() => { andThen(() => {
assert.equal( assert.equal(
this.$(".select-box-row.is-highlighted .text").html().trim(), "robin", find(".select-box-row.is-highlighted .text").html().trim(), "robin",
"it highlights the row corresponding to the value" "it highlights the row corresponding to the value"
); );
}); });
@ -79,7 +79,7 @@ componentTest('no default icon', {
template: '{{select-box}}', template: '{{select-box}}',
test(assert) { test(assert) {
assert.equal(this.$(".select-box-header .icon").length, 0, "it doesnt have an icon if not specified"); assert.equal(find(".select-box-header .icon").length, 0, "it doesnt have an icon if not specified");
} }
}); });
@ -87,7 +87,7 @@ componentTest('customisable icon', {
template: '{{select-box icon="shower"}}', template: '{{select-box icon="shower"}}',
test(assert) { test(assert) {
assert.equal(this.$(".select-box-header .icon").html().trim(), "<i class=\"fa fa-shower d-icon d-icon-shower\"></i>", "it has a the correct icon"); assert.equal(find(".select-box-header .icon").html().trim(), "<i class=\"fa fa-shower d-icon d-icon-shower\"></i>", "it has a the correct icon");
} }
}); });
@ -98,7 +98,7 @@ componentTest('default search icon', {
click(".select-box-header"); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(find(".select-box-filter .filter-icon").html().trim(), "<i class=\"fa fa-search d-icon d-icon-search\"></i>", "it has a the correct icon"); assert.equal(find(".select-box-filter .d-icon-search").length, 1, "it has a the correct icon");
}); });
} }
}); });
@ -122,7 +122,7 @@ componentTest('custom search icon', {
click(".select-box-header"); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(find(".select-box-filter .filter-icon").html().trim(), "<i class=\"fa fa-shower d-icon d-icon-shower\"></i>", "it has a the correct icon"); assert.equal(find(".select-box-filter .d-icon-shower").length, 1, "it has a the correct icon");
}); });
} }
}); });
@ -145,13 +145,13 @@ componentTest('select-box is expandable', {
click(".select-box-header"); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box").hasClass("is-expanded"), true); assert.equal(find(".select-box").hasClass("is-expanded"), true);
}); });
click(".select-box-header"); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box").hasClass("is-expanded"), false); assert.equal(find(".select-box").hasClass("is-expanded"), false);
}); });
} }
}); });
@ -165,10 +165,10 @@ componentTest('accepts custom id/text keys', {
}, },
test(assert) { test(assert) {
click(this.$(".select-box-header")); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box-row.is-highlighted .text").html().trim(), "robin"); assert.equal(find(".select-box-row.is-highlighted .text").html().trim(), "robin");
}); });
} }
}); });
@ -181,12 +181,12 @@ componentTest('doesnt render collection content before first expand', {
}, },
test(assert) { test(assert) {
assert.equal(this.$(".select-box-body .collection").length, 0); assert.equal(find(".select-box-body .collection").length, 0);
click(this.$(".select-box-header")); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box-body .collection").length, 1); assert.equal(find(".select-box-body .collection").length, 1);
}); });
} }
}); });
@ -199,42 +199,76 @@ componentTest('persists filter state when expandind/collapsing', {
}, },
test(assert) { test(assert) {
click(this.$(".select-box-header")); click(".select-box-header");
fillIn('.filter-query', 'rob'); fillIn('.filter-query', 'rob');
triggerEvent('.filter-query', 'keyup'); triggerEvent('.filter-query', 'keyup');
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box-row").length, 1); assert.equal(find(".select-box-row").length, 1);
}); });
click(this.$(".select-box-header")); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(this.$().hasClass("is-expanded"), false); assert.equal(find(".select-box").hasClass("is-expanded"), false);
}); });
click(this.$(".select-box-header")); click(".select-box-header");
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box-row").length, 1); assert.equal(find(".select-box-row").length, 1);
}); });
} }
}); });
componentTest('supports options to limit size', { componentTest('supports options to limit size', {
template: '{{select-box maxWidth=100 maxCollectionHeight=20 content=content}}', template: '{{select-box width=50 maxCollectionHeight=20 content=content}}',
beforeEach() { beforeEach() {
this.set("content", [{ id: 1, text: "robin" }]); this.set("content", [{ id: 1, text: "robin" }]);
}, },
test(assert) { test(assert) {
assert.equal(this.$(".select-box-header").outerWidth(), 100, "it limits the width"); click(".select-box-header");
click(this.$(".select-box-header"));
andThen(() => { andThen(() => {
assert.equal(this.$(".select-box-body").height(), 20, "it limits the height"); assert.equal(find(".select-box-body").height(), 20, "it limits the height");
assert.equal(find(".select-box").width(), 50, "it limits the width");
});
}
});
componentTest('supports custom row template', {
template: '{{select-box content=content selectBoxRowTemplate=selectBoxRowTemplate}}',
beforeEach() {
this.set("content", [{ id: 1, text: "robin" }]);
this.set("selectBoxRowTemplate", (rowComponent) => {
return `<b>${rowComponent.get("text")}</b>`;
});
},
test(assert) {
click(".select-box-header");
andThen(() => {
assert.equal(find(".select-box-row").html().trim(), "<b>robin</b>");
});
}
});
componentTest('supports converting select value to integer', {
template: '{{select-box value=2 content=content castInteger=true}}',
beforeEach() {
this.set("content", [{ id: "1", text: "robin"}, {id: "2", text: "régis" }]);
},
test(assert) {
click(".select-box-header");
andThen(() => {
assert.equal(find(".select-box-row.is-highlighted .text").text(), "régis");
}); });
} }
}); });