DEV: select-kit 2 (#7998)
This new iteration of select-kit focuses on following best principales and disallowing mutations inside select-kit components. A best effort has been made to avoid breaking changes, however if you content was a flat array, eg: ["foo", "bar"] You will need to set valueProperty=null and nameProperty=null on the component. Also almost every component should have an `onChange` handler now to decide what to do with the updated data. **select-kit will not mutate your data by itself anymore**
This commit is contained in:
parent
0e2cbee339
commit
0431942f3d
|
@ -21,13 +21,11 @@ export default Component.extend({
|
|||
|
||||
actions: {
|
||||
penaltyChanged() {
|
||||
let postAction = this.postAction;
|
||||
|
||||
// If we switch to edit mode, jump to the edit textarea
|
||||
if (postAction === "edit") {
|
||||
if (this.postAction === "edit") {
|
||||
scheduleOnce("afterRender", () => {
|
||||
let elem = this.element;
|
||||
let body = elem.closest(".modal-body");
|
||||
const elem = this.element;
|
||||
const body = elem.closest(".modal-body");
|
||||
body.scrollTop(body.height());
|
||||
elem.querySelector(".post-editor").focus();
|
||||
});
|
||||
|
|
|
@ -20,6 +20,19 @@ export default Component.extend({
|
|||
];
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
schedule("afterRender", () => {
|
||||
$(this.element.querySelector(".external-url")).keydown(e => {
|
||||
// enter key
|
||||
if (e.keyCode === 13) {
|
||||
this.send("submit");
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
focusPermalink() {
|
||||
schedule("afterRender", () =>
|
||||
this.element.querySelector(".permalink-url").focus()
|
||||
|
@ -64,19 +77,10 @@ export default Component.extend({
|
|||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
onChangePermalinkType(type) {
|
||||
this.set("permalinkType", type);
|
||||
}
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
schedule("afterRender", () => {
|
||||
$(this.element.querySelector(".external-url")).keydown(e => {
|
||||
// enter key
|
||||
if (e.keyCode === 13) {
|
||||
this.send("submit");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import Component from "@ember/component";
|
||||
import Category from "discourse/models/category";
|
||||
import { computed } from "@ember/object";
|
||||
|
||||
export default Component.extend({
|
||||
@discourseComputed("value")
|
||||
selectedCategories: {
|
||||
get(value) {
|
||||
return Category.findByIds(value.split("|"));
|
||||
},
|
||||
set(value) {
|
||||
this.set("value", value.mapBy("id").join("|"));
|
||||
return value;
|
||||
selectedCategories: computed("value", function() {
|
||||
return Category.findByIds(this.value.split("|").filter(Boolean));
|
||||
}),
|
||||
|
||||
actions: {
|
||||
onChangeSelectedCategories(value) {
|
||||
this.set("value", (value || []).mapBy("id").join("|"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import Component from "@ember/component";
|
||||
import { computed } from "@ember/object";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
|
||||
export default Component.extend({
|
||||
tokenSeparator: "|",
|
||||
|
||||
createdChoices: null,
|
||||
|
||||
settingValue: computed("value", function() {
|
||||
return this.value
|
||||
.toString()
|
||||
.split(this.tokenSeparator)
|
||||
.filter(Boolean);
|
||||
}),
|
||||
|
||||
settingChoices: computed(
|
||||
"settingValue",
|
||||
"setting.choices.[]",
|
||||
"createdChoices.[]",
|
||||
function() {
|
||||
return [
|
||||
...new Set([
|
||||
...makeArray(this.settingValue),
|
||||
...makeArray(this.setting.choices),
|
||||
...makeArray(this.createdChoices)
|
||||
])
|
||||
];
|
||||
}
|
||||
),
|
||||
|
||||
actions: {
|
||||
onChangeListSetting(value) {
|
||||
this.set("value", value.join(this.tokenSeparator));
|
||||
},
|
||||
|
||||
onChangeChoices(choices) {
|
||||
this.set("createdChoices", [
|
||||
...new Set([...makeArray(this.createdChoices), ...makeArray(choices)])
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,11 +1,25 @@
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { computed } from "@ember/object";
|
||||
import Component from "@ember/component";
|
||||
|
||||
export default Component.extend({
|
||||
@discourseComputed()
|
||||
groupChoices() {
|
||||
return this.site.get("groups").map(g => {
|
||||
tokenSeparator: "|",
|
||||
|
||||
nameProperty: "name",
|
||||
valueProperty: "id",
|
||||
|
||||
groupChoices: computed("site.groups", function() {
|
||||
return (this.site.groups || []).map(g => {
|
||||
return { name: g.name, id: g.id.toString() };
|
||||
});
|
||||
}),
|
||||
|
||||
settingValue: computed("value", function() {
|
||||
return (this.value || "").split(this.tokenSeparator).filter(Boolean);
|
||||
}),
|
||||
|
||||
actions: {
|
||||
onChangeGroupListSetting(value) {
|
||||
this.set("value", value.join(this.tokenSeparator));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
import { empty, alias } from "@ember/object/computed";
|
||||
import { empty, reads } from "@ember/object/computed";
|
||||
import Component from "@ember/component";
|
||||
import { on } from "discourse-common/utils/decorators";
|
||||
|
||||
export default Component.extend({
|
||||
classNameBindings: [":value-list"],
|
||||
|
||||
inputInvalid: empty("newValue"),
|
||||
|
||||
inputDelimiter: null,
|
||||
inputType: null,
|
||||
newValue: "",
|
||||
collection: null,
|
||||
values: null,
|
||||
noneKey: alias("addKey"),
|
||||
noneKey: reads("addKey"),
|
||||
|
||||
@on("didReceiveAttrs")
|
||||
_setupCollection() {
|
||||
|
@ -47,7 +45,7 @@ export default Component.extend({
|
|||
addValue(newValue) {
|
||||
if (this.inputInvalid) return;
|
||||
|
||||
this.set("newValue", "");
|
||||
this.set("newValue", null);
|
||||
this._addValue(newValue);
|
||||
},
|
||||
|
||||
|
@ -62,12 +60,26 @@ export default Component.extend({
|
|||
|
||||
_addValue(value) {
|
||||
this.collection.addObject(value);
|
||||
|
||||
if (this.choices) {
|
||||
this.set("choices", this.choices.rejectBy("id", value));
|
||||
} else {
|
||||
this.set("choices", []);
|
||||
}
|
||||
|
||||
this._saveValues();
|
||||
},
|
||||
|
||||
_removeValue(value) {
|
||||
const collection = this.collection;
|
||||
collection.removeObject(value);
|
||||
this.collection.removeObject(value);
|
||||
|
||||
const item = { id: value, name: value };
|
||||
if (this.choices) {
|
||||
this.choices.addObject(item);
|
||||
} else {
|
||||
this.set("choices", makeArray(item));
|
||||
}
|
||||
|
||||
this._saveValues();
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import { reads } from "@ember/object/computed";
|
||||
import { inject } from "@ember/controller";
|
||||
import Controller from "@ember/controller";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
@ -10,15 +10,37 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
adminBadges: inject(),
|
||||
saving: false,
|
||||
savingStatus: "",
|
||||
|
||||
badgeTypes: alias("adminBadges.badgeTypes"),
|
||||
badgeGroupings: alias("adminBadges.badgeGroupings"),
|
||||
badgeTriggers: alias("adminBadges.badgeTriggers"),
|
||||
protectedSystemFields: alias("adminBadges.protectedSystemFields"),
|
||||
|
||||
readOnly: alias("buffered.system"),
|
||||
badgeTypes: reads("adminBadges.badgeTypes"),
|
||||
badgeGroupings: reads("adminBadges.badgeGroupings"),
|
||||
badgeTriggers: reads("adminBadges.badgeTriggers"),
|
||||
protectedSystemFields: reads("adminBadges.protectedSystemFields"),
|
||||
readOnly: reads("buffered.system"),
|
||||
showDisplayName: propertyNotEqual("name", "displayName"),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
// this is needed because the model doesnt have default values
|
||||
// and as we are using a bufferedProperty it's not accessible
|
||||
// in any other way
|
||||
Ember.run.next(() => {
|
||||
if (!this.model.badge_type_id) {
|
||||
this.model.set("badge_type_id", this.get("badgeTypes.firstObject.id"));
|
||||
}
|
||||
|
||||
if (!this.model.badge_grouping_id) {
|
||||
this.model.set(
|
||||
"badge_grouping_id",
|
||||
this.get("badgeGroupings.firstObject.id")
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.model.trigger) {
|
||||
this.model.set("trigger", this.get("badgeTriggers.firstObject.id"));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@discourseComputed("model.query", "buffered.query")
|
||||
hasQuery(modelQuery, bufferedQuery) {
|
||||
if (bufferedQuery) {
|
||||
|
|
|
@ -278,7 +278,7 @@ export default Controller.extend(CanCheckEmails, {
|
|||
},
|
||||
|
||||
resetCustomGroups() {
|
||||
this.set("customGroupIdsBuffer", null);
|
||||
this.set("customGroupIdsBuffer", this.model.customGroups.mapBy("id"));
|
||||
},
|
||||
|
||||
savePrimaryGroup() {
|
||||
|
|
|
@ -5,6 +5,17 @@ import ModalFunctionality from "discourse/mixins/modal-functionality";
|
|||
export default Controller.extend(ModalFunctionality, {
|
||||
adminCustomizeColors: inject(),
|
||||
|
||||
selectedBaseThemeId: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
const defaultScheme = this.get(
|
||||
"adminCustomizeColors.baseColorSchemes.0.base_scheme_id"
|
||||
);
|
||||
this.set("selectedBaseThemeId", defaultScheme);
|
||||
},
|
||||
|
||||
actions: {
|
||||
selectBase() {
|
||||
this.adminCustomizeColors.send(
|
||||
|
|
|
@ -19,7 +19,7 @@ export default DiscourseRoute.extend({
|
|||
controller.setProperties({
|
||||
originalPrimaryGroupId: model.primary_group_id,
|
||||
availableGroups: this._availableGroups,
|
||||
customGroupIdsBuffer: null,
|
||||
customGroupIdsBuffer: model.customGroups.mapBy("id"),
|
||||
model
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
{{/admin-form-row}}
|
||||
|
||||
{{#admin-form-row label="admin.api.user_mode"}}
|
||||
{{combo-box content=userModes value=userMode onSelect=(action "changeUserMode")}}
|
||||
{{combo-box content=userModes value=userMode onChange=(action "changeUserMode")}}
|
||||
{{/admin-form-row}}
|
||||
|
||||
{{#if showUserSelector}}
|
||||
|
@ -28,11 +28,11 @@
|
|||
{{user-selector single="true"
|
||||
usernames=model.username
|
||||
placeholderKey="admin.api.user_placeholder"
|
||||
}}
|
||||
}}
|
||||
{{/admin-form-row}}
|
||||
{{/if}}
|
||||
{{#admin-form-row}}
|
||||
{{d-button icon="check" label="admin.api.save" action=(action "save") class="btn-primary"}}
|
||||
{{/admin-form-row}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -23,30 +23,35 @@
|
|||
|
||||
<div>
|
||||
<label for="badge_type_id">{{i18n 'admin.badges.badge_type'}}</label>
|
||||
{{combo-box name="badge_type_id"
|
||||
value=buffered.badge_type_id
|
||||
content=badgeTypes
|
||||
allowInitialValueMutation=true
|
||||
isDisabled=readOnly}}
|
||||
{{combo-box
|
||||
name="badge_type_id"
|
||||
value=buffered.badge_type_id
|
||||
content=badgeTypes
|
||||
onChange=(action (mut buffered.badge_type_id))
|
||||
isDisabled=readOnly
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="badge_grouping_id">{{i18n 'admin.badges.badge_grouping'}}</label>
|
||||
|
||||
<div class="badge-grouping-control">
|
||||
{{combo-box name="badge_grouping_id"
|
||||
{{combo-box
|
||||
name="badge_grouping_id"
|
||||
value=buffered.badge_grouping_id
|
||||
content=badgeGroupings
|
||||
class="badge-selector"
|
||||
nameProperty="name"}}
|
||||
nameProperty="name"
|
||||
onChange=(action (mut buffered.badge_grouping_id))
|
||||
}}
|
||||
{{d-button
|
||||
class="btn-default"
|
||||
action=(route-action "editGroupings")
|
||||
icon="pencil-alt"}}
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<label for="description">{{i18n 'admin.badges.description'}}</label>
|
||||
{{#if buffered.system}}
|
||||
|
@ -95,12 +100,13 @@
|
|||
|
||||
<div>
|
||||
<label for="trigger">{{i18n 'admin.badges.trigger'}}</label>
|
||||
{{combo-box name="trigger"
|
||||
value=buffered.trigger
|
||||
content=badgeTriggers
|
||||
optionValuePath="content.id"
|
||||
optionLabelPath="content.name"
|
||||
disabled=readOnly}}
|
||||
{{combo-box
|
||||
name="trigger"
|
||||
value=buffered.trigger
|
||||
content=badgeTriggers
|
||||
onChange=(action (mut buffered.trigger))
|
||||
disabled=readOnly
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
|
|
@ -130,7 +130,10 @@
|
|||
</span>
|
||||
|
||||
<div class="input">
|
||||
{{date-input date=startDate onChange=(action "onChangeStartDate")}}
|
||||
{{date-input
|
||||
date=startDate
|
||||
onChange=(action "onChangeStartDate")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -140,7 +143,10 @@
|
|||
</span>
|
||||
|
||||
<div class="input">
|
||||
{{date-input date=endDate onChange=(action "onChangeEndDate")}}
|
||||
{{date-input
|
||||
date=endDate
|
||||
onChange=(action "onChangeEndDate")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
{{#if editing}}
|
||||
{{#admin-form-row label="admin.user_fields.type"}}
|
||||
{{combo-box content=fieldTypes value=buffered.field_type}}
|
||||
{{combo-box
|
||||
content=fieldTypes
|
||||
value=buffered.field_type
|
||||
onChange=(action (mut buffered.field_type))
|
||||
}}
|
||||
{{/admin-form-row}}
|
||||
|
||||
{{#admin-form-row label="admin.user_fields.name"}}
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
</td>
|
||||
<td class="editing-input">
|
||||
<div class="label">{{i18n "admin.embedding.category"}}</div>
|
||||
{{category-chooser value=categoryId class="small"}}
|
||||
{{category-chooser
|
||||
value=categoryId
|
||||
class="small"
|
||||
onChange=(action (mut categoryId))
|
||||
}}
|
||||
</td>
|
||||
<td class="editing-controls">
|
||||
{{d-button icon="check" action=(action "save") class="btn-primary" disabled=cantSave}}
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
{{{i18n 'admin.user.penalty_post_actions'}}}
|
||||
</div>
|
||||
</label>
|
||||
{{combo-box value=postAction content=penaltyActions onSelect=(action "penaltyChanged")}}
|
||||
{{combo-box
|
||||
value=postAction
|
||||
content=penaltyActions
|
||||
onChange=(action "penaltyChanged")
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{#if editing}}
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
autocorrect="off"
|
||||
autocapitalize="off"}}
|
||||
|
||||
{{combo-box content=permalinkTypes value=permalinkType}}
|
||||
{{combo-box
|
||||
content=permalinkTypes
|
||||
value=permalinkType
|
||||
onChange=(action (mut permalinkType))
|
||||
}}
|
||||
|
||||
{{text-field
|
||||
value=permalink_type_value
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
{{search-advanced-category-chooser
|
||||
filterable=true
|
||||
value=category
|
||||
castInteger=true
|
||||
onSelectNone=(action "onChange")
|
||||
onDeselect=(action "onDeselect")
|
||||
onSelect=(action "onChange")}}
|
||||
onChange=(action (mut category))
|
||||
}}
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
allowAny=filter.allow_any
|
||||
value=filter.default
|
||||
none="admin.dashboard.report_filter_any"
|
||||
onSelectNone=(action "onChange")
|
||||
onSelect=(action "onChange")}}
|
||||
onChange=(action "onChange")
|
||||
}}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
{{combo-box
|
||||
castInteger=true
|
||||
filterable=true
|
||||
valueAttribute="value"
|
||||
valueProperty="value"
|
||||
content=groupOptions
|
||||
value=groupId
|
||||
allowAny=filter.allow_any
|
||||
none="admin.dashboard.reports.groups"
|
||||
onSelectNone=(action "onChange")
|
||||
onSelect=(action "onChange")}}
|
||||
onChange=(action "onChange")
|
||||
}}
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
<b>{{i18n 'admin.logs.screened_ips.form.label'}}</b>
|
||||
{{text-field value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}}
|
||||
{{combo-box content=actionNames value=actionName}}
|
||||
|
||||
{{combo-box
|
||||
content=actionNames
|
||||
value=actionName
|
||||
onChange=(action (mut actionName))
|
||||
}}
|
||||
|
||||
{{d-button class="btn-default" action=(action "submit") disabled=formSubmitted label="admin.logs.screened_ips.form.add"}}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{{category-selector categories=selectedCategories}}
|
||||
{{category-selector
|
||||
categories=selectedCategories
|
||||
onChange=(action "onChangeSelectedCategories")
|
||||
}}
|
||||
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{{category-chooser value=value allowUncategorized="true"}}
|
||||
{{category-chooser
|
||||
value=value
|
||||
allowUncategorized=true
|
||||
onChange=(action (mut value))
|
||||
}}
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
{{list-setting settingValue=value choices=setting.choices settingName=setting.setting allowAny=allowAny}}
|
||||
{{list-setting
|
||||
value=settingValue
|
||||
settingName=setting.setting
|
||||
allowAny=allowAny
|
||||
choices=settingChoices
|
||||
onChange=(action "onChangeListSetting")
|
||||
onChangeChoices=(action "onChangeChoices")
|
||||
}}
|
||||
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
{{combo-box castInteger=true valueAttribute="value" content=setting.validValues value=value none=setting.allowsNone}}
|
||||
{{combo-box
|
||||
valueProperty="value"
|
||||
content=setting.validValues
|
||||
value=value
|
||||
onChange=(action (mut value))
|
||||
allowAny=setting.allowsNone
|
||||
}}
|
||||
|
||||
{{preview}}
|
||||
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
||||
|
||||
<div class='desc'>
|
||||
{{{unbound setting.description}}}
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
{{list-setting settingValue=value choices=groupChoices settingName='name'}}
|
||||
{{list-setting
|
||||
value=settingValue
|
||||
choices=groupChoices
|
||||
settingName="name"
|
||||
nameProperty=nameProperty
|
||||
valueProperty=valueProperty
|
||||
onChange=(action "onChangeGroupListSetting")
|
||||
}}
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
||||
|
|
|
@ -2,12 +2,19 @@
|
|||
<div class='values'>
|
||||
{{#each collection as |value index|}}
|
||||
<div class='value' data-index={{index}}>
|
||||
{{d-button action=(action "removeValue")
|
||||
actionParam=value
|
||||
icon="times"
|
||||
class="btn-default remove-value-btn btn-small"}}
|
||||
{{d-button
|
||||
action=(action "removeValue")
|
||||
actionParam=value
|
||||
icon="times"
|
||||
class="remove-value-btn btn-small"
|
||||
}}
|
||||
|
||||
{{input title=value value=value class="value-input" focus-out=(action "changeValue" index)}}
|
||||
{{input
|
||||
title=value
|
||||
value=value
|
||||
class="value-input"
|
||||
focus-out=(action "changeValue" index)
|
||||
}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
@ -15,7 +22,10 @@
|
|||
|
||||
{{combo-box
|
||||
allowAny=true
|
||||
allowContentReplacement=true
|
||||
none=noneKey
|
||||
valueProperty=null
|
||||
nameProperty=null
|
||||
value=newValue
|
||||
content=filteredChoices
|
||||
onSelect=(action "selectChoice")}}
|
||||
onChange=(action "selectChoice")
|
||||
}}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{combo-box
|
||||
content=sortedTemplates
|
||||
valueAttribute="id"
|
||||
valueProperty="id"
|
||||
nameProperty="title"
|
||||
onSelect=(action "selectTemplate")
|
||||
onChange=(action "selectTemplate")
|
||||
}}
|
||||
|
||||
{{outlet}}
|
||||
|
|
|
@ -30,7 +30,13 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{i18n "admin.logs.staff_actions.filter"}} {{combo-box content=userHistoryActions value=filterActionId none="admin.logs.staff_actions.all" onSelect=(action "filterActionIdChanged")}}
|
||||
{{i18n "admin.logs.staff_actions.filter"}}
|
||||
{{combo-box
|
||||
content=userHistoryActions
|
||||
value=filterActionId
|
||||
none="admin.logs.staff_actions.all"
|
||||
onChange=(action "filterActionIdChanged")
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
{{d-button class="btn-default" action=(action "exportStaffActionLogs") label="admin.export_csv.button_text" icon="download"}}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
<div>
|
||||
{{#d-modal-body title="admin.customize.colors.select_base.title"}}
|
||||
{{i18n "admin.customize.colors.select_base.description"}}
|
||||
{{combo-box content=model
|
||||
value=selectedBaseThemeId
|
||||
allowInitialValueMutation=true
|
||||
valueAttribute="base_scheme_id"}}
|
||||
{{combo-box
|
||||
content=model
|
||||
value=selectedBaseThemeId
|
||||
onChange=(action (mut selectedBaseThemeId))
|
||||
valueProperty="base_scheme_id"
|
||||
}}
|
||||
{{/d-modal-body}}
|
||||
|
||||
<div class="modal-footer">
|
||||
{{d-button
|
||||
class="btn-primary"
|
||||
action=(action "selectBase")
|
||||
icon="plus"
|
||||
label="admin.customize.new"}}
|
||||
label="admin.customize.new"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -89,7 +89,12 @@
|
|||
{{input value=name placeholder=placeholder}}
|
||||
|
||||
<div class="label">{{I18n "admin.customize.theme.create_type"}}</div>
|
||||
{{combo-box valueAttribute="value" content=createTypes value=selectedType}}
|
||||
{{combo-box
|
||||
valueProperty="value"
|
||||
content=createTypes
|
||||
value=selectedType
|
||||
onChange=(action (mut selectedType))
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
label="admin.user.silence_duration"
|
||||
includeFarFuture=true
|
||||
clearable=false
|
||||
input=silenceUntil}}
|
||||
input=silenceUntil
|
||||
onChangeInput=(action (mut silenceUntil))
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
label="admin.user.suspend_duration"
|
||||
includeFarFuture=true
|
||||
clearable=false
|
||||
input=suspendUntil}}
|
||||
input=suspendUntil
|
||||
onChangeInput=(action (mut suspendUntil))
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
{{suspension-details reason=reason message=message}}
|
||||
|
|
|
@ -4,4 +4,5 @@
|
|||
filters=model
|
||||
reportOptions=reportOptions
|
||||
showFilteringUI=true
|
||||
onRefresh=(route-action "onParamsChange")}}
|
||||
onRefresh=(route-action "onParamsChange")
|
||||
}}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<div class="admin-title">
|
||||
{{period-chooser period=period}}
|
||||
{{combo-box content=searchTypeOptions value=searchType class='search-logs-filter'}}
|
||||
{{period-chooser period=period onChange=(action (mut period))}}
|
||||
{{combo-box
|
||||
content=searchTypeOptions
|
||||
value=searchType
|
||||
class="search-logs-filter"
|
||||
onChange=(action (mut searchType))
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{#conditional-loading-spinner condition=loading}}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<div class="admin-title">
|
||||
{{period-chooser period=period}}
|
||||
{{combo-box content=searchTypeOptions value=searchType class='search-logs-filter'}}
|
||||
{{period-chooser period=period onChange=(action (mut period))}}
|
||||
{{combo-box
|
||||
content=searchTypeOptions
|
||||
value=searchType
|
||||
class="search-logs-filter"
|
||||
onChange=(action (mut searchType))
|
||||
}}
|
||||
</div>
|
||||
|
||||
<h2>
|
||||
|
|
|
@ -15,8 +15,13 @@
|
|||
{{else}}
|
||||
<form class="form-horizontal">
|
||||
<div>
|
||||
<label>{{i18n 'admin.badges.badge'}}</label>
|
||||
{{combo-box forceEscape=true filterable=true value=selectedBadgeId content=grantableBadges}}
|
||||
<label>{{i18n 'admin.badges.badge'}}</label>
|
||||
{{combo-box
|
||||
filterable=true
|
||||
value=selectedBadgeId
|
||||
content=grantableBadges
|
||||
onChange=(action (mut selectedBadgeId))
|
||||
}}
|
||||
</div>
|
||||
<div>
|
||||
<label>{{i18n 'admin.badges.reason'}}</label>
|
||||
|
|
|
@ -298,7 +298,7 @@
|
|||
</div>
|
||||
<div class="controls">
|
||||
{{d-button href="/admin/api/keys" label="admin.api.manage_keys"}}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -350,8 +350,9 @@
|
|||
<div class="value">
|
||||
{{combo-box
|
||||
content=site.trustLevels
|
||||
value=model.trust_level
|
||||
nameProperty="detailedName"
|
||||
value=model.trustLevel.id
|
||||
onChange=(action (mut model.trust_level))
|
||||
}}
|
||||
|
||||
{{#if model.dirty}}
|
||||
|
@ -514,9 +515,10 @@
|
|||
<div class="field">{{i18n "admin.groups.custom"}}</div>
|
||||
<div class="value">
|
||||
{{admin-group-selector
|
||||
selected=model.customGroups
|
||||
available=availableGroups
|
||||
buffer=customGroupIdsBuffer}}
|
||||
content=availableGroups
|
||||
value=customGroupIdsBuffer
|
||||
onChange=(action (mut customGroupIdsBuffer))
|
||||
}}
|
||||
</div>
|
||||
{{#if customGroupsDirty}}
|
||||
<div class="controls">
|
||||
|
@ -532,7 +534,9 @@
|
|||
{{combo-box
|
||||
content=model.customGroups
|
||||
value=model.primary_group_id
|
||||
none="admin.groups.no_primary"}}
|
||||
none="admin.groups.no_primary"
|
||||
onChange=(action (mut model.primary_group_id))
|
||||
}}
|
||||
</div>
|
||||
{{#if primaryGroupDirty}}
|
||||
<div class="controls">
|
||||
|
|
|
@ -14,9 +14,12 @@
|
|||
|
||||
<div>
|
||||
<label for='content-type'>{{i18n 'admin.web_hooks.content_type'}}</label>
|
||||
{{combo-box content=contentTypes
|
||||
name="content-type"
|
||||
value=model.content_type}}
|
||||
{{combo-box
|
||||
content=contentTypes
|
||||
name="content-type"
|
||||
value=model.content_type
|
||||
onChange=(action (mut model.content_type))
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
@ -48,7 +51,10 @@
|
|||
<div class='filters'>
|
||||
<div class="filter">
|
||||
<label>{{d-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.categories_filter'}}</label>
|
||||
{{category-selector categories=model.categories}}
|
||||
{{category-selector
|
||||
categories=model.categories
|
||||
onChange=(action (mut model.categories))
|
||||
}}
|
||||
<div class="instructions">{{i18n 'admin.web_hooks.categories_filter_instructions'}}</div>
|
||||
</div>
|
||||
{{#if showTagsFilter}}
|
||||
|
|
|
@ -637,6 +637,12 @@ registerIconRenderer({
|
|||
params.title
|
||||
).replace(/'/g, "'")}'>${html}</span>`;
|
||||
}
|
||||
if (params.translatedtitle) {
|
||||
html = `<span class="svg-icon-title" title='${params.translatedtitle.replace(
|
||||
/'/g,
|
||||
"'"
|
||||
)}'>${html}</span>`;
|
||||
}
|
||||
return html;
|
||||
},
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
||||
import { computed } from "@ember/object";
|
||||
|
||||
export default DropdownSelectBoxComponent.extend({
|
||||
classNames: ["auth-token-dropdown"],
|
||||
headerIcon: "wrench",
|
||||
allowInitialValueMutation: false,
|
||||
showFullTitle: false,
|
||||
|
||||
computeContent() {
|
||||
const content = [
|
||||
selectKitOptions: {
|
||||
icon: "wrench",
|
||||
showFullTitle: false
|
||||
},
|
||||
|
||||
content: computed(function() {
|
||||
return [
|
||||
{
|
||||
id: "notYou",
|
||||
icon: "user-times",
|
||||
|
@ -21,12 +24,10 @@ export default DropdownSelectBoxComponent.extend({
|
|||
description: ""
|
||||
}
|
||||
];
|
||||
|
||||
return content;
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
onSelect(id) {
|
||||
onChange(id) {
|
||||
switch (id) {
|
||||
case "notYou":
|
||||
this.showToken(this.token);
|
||||
|
|
|
@ -49,5 +49,22 @@ export default Component.extend(FilterModeMixin, {
|
|||
noSubcategories,
|
||||
persistedQueryParams: params
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
changeCategoryNotificationLevel(notificationLevel) {
|
||||
this.category.setNotification(notificationLevel);
|
||||
},
|
||||
|
||||
selectCategoryAdminDropdownAction(actionId) {
|
||||
switch (actionId) {
|
||||
case "create":
|
||||
this.createCategory();
|
||||
break;
|
||||
case "reorder":
|
||||
this.reorderCategories();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -32,8 +32,9 @@ export default Component.extend({
|
|||
didUpdateAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
if (this._picker) {
|
||||
this._picker.setDate(this.date, true);
|
||||
if (this._picker && typeof date === "string") {
|
||||
const [year, month, day] = this.date.split("-").map(x => parseInt(x, 10));
|
||||
this._picker.setDate(new Date(year, month - 1, day), true);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -84,7 +85,7 @@ export default Component.extend({
|
|||
this._picker && this._picker.hide();
|
||||
|
||||
if (this.onChange) {
|
||||
this.onChange(moment(value).toDate());
|
||||
this.onChange(value);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -103,5 +104,11 @@ export default Component.extend({
|
|||
|
||||
_opts() {
|
||||
return null;
|
||||
},
|
||||
|
||||
actions: {
|
||||
onInput(event) {
|
||||
this._picker && this._picker.setDate(event.target.value, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,7 +10,8 @@ export default DatePicker.extend({
|
|||
moment()
|
||||
.add(1, "day")
|
||||
.toDate(),
|
||||
setDefaultDate: !!this.defaultDate
|
||||
setDefaultDate: !!this.defaultDate,
|
||||
minDate: this.minDate || moment().toDate()
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { next } from "@ember/runloop";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
/* global Pikaday:true */
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
|
@ -28,7 +28,7 @@ export default Component.extend({
|
|||
|
||||
_loadPikadayPicker(container) {
|
||||
loadScript("/javascripts/pikaday.js").then(() => {
|
||||
next(() => {
|
||||
schedule("afterRender", () => {
|
||||
const options = {
|
||||
field: this.element.querySelector(".date-picker"),
|
||||
container: container || null,
|
||||
|
|
|
@ -9,6 +9,16 @@ export default buildCategoryPanel("security", {
|
|||
showPendingGroupChangesAlert: false,
|
||||
interactedWithDropdowns: false,
|
||||
|
||||
@on("init")
|
||||
_setup() {
|
||||
this.setProperties({
|
||||
selectedGroup: this.get("category.availableGroups.firstObject"),
|
||||
selectedPermission: this.get(
|
||||
"category.availablePermissions.firstObject.id"
|
||||
)
|
||||
});
|
||||
},
|
||||
|
||||
@on("init")
|
||||
_registerValidator() {
|
||||
this.registerValidator(() => {
|
||||
|
@ -24,8 +34,18 @@ export default buildCategoryPanel("security", {
|
|||
},
|
||||
|
||||
actions: {
|
||||
onDropdownChange() {
|
||||
this.set("interactedWithDropdowns", true);
|
||||
onSelectGroup(selectedGroup) {
|
||||
this.setProperties({
|
||||
interactedWithDropdowns: true,
|
||||
selectedGroup
|
||||
});
|
||||
},
|
||||
|
||||
onSelectPermission(selectedPermission) {
|
||||
this.setProperties({
|
||||
interactedWithDropdowns: true,
|
||||
selectedPermission
|
||||
});
|
||||
},
|
||||
|
||||
editPermissions() {
|
||||
|
@ -42,11 +62,8 @@ export default buildCategoryPanel("security", {
|
|||
});
|
||||
}
|
||||
|
||||
this.set(
|
||||
"selectedGroup",
|
||||
this.get("category.availableGroups.firstObject")
|
||||
);
|
||||
this.setProperties({
|
||||
selectedGroup: this.get("category.availableGroups.firstObject"),
|
||||
showPendingGroupChangesAlert: false,
|
||||
interactedWithDropdowns: false
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { isEmpty } from "@ember/utils";
|
||||
import { alias, equal, or } from "@ember/object/computed";
|
||||
import { equal, or, readOnly } from "@ember/object/computed";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import discourseComputed, {
|
||||
|
@ -16,7 +16,7 @@ import {
|
|||
} from "discourse/controllers/edit-topic-timer";
|
||||
|
||||
export default Component.extend({
|
||||
selection: alias("topicTimer.status_type"),
|
||||
selection: readOnly("topicTimer.status_type"),
|
||||
autoOpen: equal("selection", OPEN_STATUS_TYPE),
|
||||
autoClose: equal("selection", CLOSE_STATUS_TYPE),
|
||||
autoDelete: equal("selection", DELETE_STATUS_TYPE),
|
||||
|
@ -27,16 +27,11 @@ export default Component.extend({
|
|||
|
||||
@discourseComputed(
|
||||
"topicTimer.updateTime",
|
||||
"loading",
|
||||
"publishToCategory",
|
||||
"topicTimer.category_id"
|
||||
)
|
||||
saveDisabled(updateTime, loading, publishToCategory, topicTimerCategoryId) {
|
||||
return (
|
||||
isEmpty(updateTime) ||
|
||||
loading ||
|
||||
(publishToCategory && !topicTimerCategoryId)
|
||||
);
|
||||
saveDisabled(updateTime, publishToCategory, topicTimerCategoryId) {
|
||||
return isEmpty(updateTime) || (publishToCategory && !topicTimerCategoryId);
|
||||
},
|
||||
|
||||
@discourseComputed("topic.visible")
|
||||
|
@ -70,5 +65,25 @@ export default Component.extend({
|
|||
this.set("topicTimer.based_on_last_post", false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
// TODO: get rid of this hack
|
||||
schedule("afterRender", () => {
|
||||
if (!this.get("topicTimer.status_type")) {
|
||||
this.set(
|
||||
"topicTimer.status_type",
|
||||
this.get("timerTypes.firstObject.id")
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
onChangeTimerType(value) {
|
||||
this.set("topicTimer.status_type", value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -45,9 +45,10 @@ export default Component.extend({
|
|||
const dateTime = moment(`${this.date}${time}`);
|
||||
|
||||
if (dateTime.isValid()) {
|
||||
this.set("input", dateTime.format(FORMAT));
|
||||
this.attrs.onChangeInput &&
|
||||
this.attrs.onChangeInput(dateTime.format(FORMAT));
|
||||
} else {
|
||||
this.set("input", null);
|
||||
this.attrs.onChangeInput && this.attrs.onChangeInput(null);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -109,7 +110,10 @@ export default Component.extend({
|
|||
}
|
||||
|
||||
if (isCustom) {
|
||||
return date || time;
|
||||
if (date) {
|
||||
return moment(`${date}${time ? " " + time : ""}`).isAfter(moment());
|
||||
}
|
||||
return time;
|
||||
} else {
|
||||
return input;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,16 @@
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
||||
import { computed } from "@ember/object";
|
||||
|
||||
export default DropdownSelectBoxComponent.extend({
|
||||
pluginApiIdentifiers: ["group-member-dropdown"],
|
||||
classNames: "group-member-dropdown",
|
||||
showFullTitle: false,
|
||||
allowInitialValueMutation: false,
|
||||
allowAutoSelectFirst: false,
|
||||
classNames: ["group-member-dropdown"],
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.headerIcon = ["wrench"];
|
||||
selectKitOptions: {
|
||||
icon: "wrench",
|
||||
showFullTitle: false
|
||||
},
|
||||
|
||||
autoHighlight() {},
|
||||
|
||||
@discourseComputed("member.owner")
|
||||
content(isOwner) {
|
||||
content: computed("member.owner", function() {
|
||||
const items = [
|
||||
{
|
||||
id: "removeMember",
|
||||
|
@ -29,8 +22,8 @@ export default DropdownSelectBoxComponent.extend({
|
|||
}
|
||||
];
|
||||
|
||||
if (this.currentUser && this.currentUser.admin) {
|
||||
if (isOwner) {
|
||||
if (this.get("currentUser.admin")) {
|
||||
if (this.member.owner) {
|
||||
items.push({
|
||||
id: "removeOwner",
|
||||
name: I18n.t("groups.members.remove_owner"),
|
||||
|
@ -52,19 +45,5 @@ export default DropdownSelectBoxComponent.extend({
|
|||
}
|
||||
|
||||
return items;
|
||||
},
|
||||
|
||||
mutateValue(id) {
|
||||
switch (id) {
|
||||
case "removeMember":
|
||||
this.removeMember(this.member);
|
||||
break;
|
||||
case "makeOwner":
|
||||
this.makeOwner(this.get("member.username"));
|
||||
break;
|
||||
case "removeOwner":
|
||||
this.removeOwner(this.member);
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import Component from "@ember/component";
|
||||
import { computed } from "@ember/object";
|
||||
|
||||
export default Component.extend({
|
||||
tokenSeparator: "|",
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
|
@ -17,6 +20,17 @@ export default Component.extend({
|
|||
];
|
||||
},
|
||||
|
||||
groupTrustLevel: computed(
|
||||
"model.grant_trust_level",
|
||||
"trustLevelOptions",
|
||||
function() {
|
||||
return (
|
||||
this.model.get("grant_trust_level") ||
|
||||
this.trustLevelOptions.firstObject.value
|
||||
);
|
||||
}
|
||||
),
|
||||
|
||||
@discourseComputed("model.visibility_level", "model.public_admission")
|
||||
disableMembershipRequestSetting(visibility_level, publicAdmission) {
|
||||
visibility_level = parseInt(visibility_level, 10);
|
||||
|
@ -30,5 +44,11 @@ export default Component.extend({
|
|||
disablePublicSetting(visibility_level, allowMembershipRequests) {
|
||||
visibility_level = parseInt(visibility_level, 10);
|
||||
return allowMembershipRequests || visibility_level > 1;
|
||||
},
|
||||
|
||||
actions: {
|
||||
onChangeEmailDomainsSetting(value) {
|
||||
this.set("model.emailDomains", value.join(this.tokenSeparator));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
export default Ember.Component.extend({
|
||||
actions: {
|
||||
onChange(tags) {
|
||||
this.valueChanged &&
|
||||
this.valueChanged({
|
||||
target: {
|
||||
value: tags
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
|
@ -182,10 +182,13 @@ export default Component.extend({
|
|||
.finally(() => this.set("updating", false));
|
||||
},
|
||||
|
||||
categoryChanged(category) {
|
||||
categoryChanged(categoryId) {
|
||||
let category = Category.findById(categoryId);
|
||||
|
||||
if (!category) {
|
||||
category = Category.findUncategorized();
|
||||
}
|
||||
|
||||
this._updates.category_id = category.id;
|
||||
},
|
||||
|
||||
|
|
|
@ -553,7 +553,6 @@ export default Component.extend({
|
|||
}
|
||||
},
|
||||
|
||||
@observes("searchedTerms.time.when", "searchedTerms.time.days")
|
||||
updateSearchTermForPostTime() {
|
||||
const match = this.filterBlocks(REGEXP_POST_TIME_PREFIX);
|
||||
const timeDaysFilter = this.get("searchedTerms.time.days");
|
||||
|
@ -603,5 +602,28 @@ export default Component.extend({
|
|||
|
||||
badgeFinder(term) {
|
||||
return Badge.findAll({ search: term });
|
||||
},
|
||||
|
||||
actions: {
|
||||
onChangeWhenTime(time) {
|
||||
if (time) {
|
||||
this.set("searchedTerms.time.when", time);
|
||||
this.updateSearchTermForPostTime();
|
||||
}
|
||||
},
|
||||
onChangeWhenDate(date) {
|
||||
if (date) {
|
||||
this.set("searchedTerms.time.days", moment(date).format("YYYY-MM-DD"));
|
||||
this.updateSearchTermForPostTime();
|
||||
}
|
||||
},
|
||||
|
||||
onChangeCategory(categoryId) {
|
||||
if (categoryId) {
|
||||
this.set("searchedTerms.category", Category.findById(categoryId));
|
||||
} else {
|
||||
this.set("searchedTerms.category", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,8 +11,8 @@ export default Component.extend({
|
|||
},
|
||||
|
||||
actions: {
|
||||
updateDestinationCategory(category) {
|
||||
return this.topic.updateDestinationCategory(category.get("id"));
|
||||
updateDestinationCategory(categoryId) {
|
||||
return this.topic.updateDestinationCategory(categoryId);
|
||||
},
|
||||
|
||||
publish() {
|
||||
|
|
|
@ -1,47 +1,38 @@
|
|||
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
||||
import { computed } from "@ember/object";
|
||||
|
||||
export default DropdownSelectBoxComponent.extend({
|
||||
pluginApiIdentifiers: ["tags-admin-dropdown"],
|
||||
classNames: "tags-admin-dropdown",
|
||||
showFullTitle: false,
|
||||
allowInitialValueMutation: false,
|
||||
actionsMapping: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.headerIcon = ["bars", "caret-down"];
|
||||
selectKitOptions: {
|
||||
icons: ["bars", "caret-down"],
|
||||
showFullTitle: false
|
||||
},
|
||||
|
||||
autoHighlight() {},
|
||||
|
||||
computeContent() {
|
||||
const items = [
|
||||
content: computed(function() {
|
||||
return [
|
||||
{
|
||||
id: "manageGroups",
|
||||
name: I18n.t("tagging.manage_groups"),
|
||||
description: I18n.t("tagging.manage_groups_description"),
|
||||
icon: "wrench",
|
||||
__sk_row_type: "noopRow"
|
||||
icon: "wrench"
|
||||
},
|
||||
{
|
||||
id: "uploadTags",
|
||||
name: I18n.t("tagging.upload"),
|
||||
description: I18n.t("tagging.upload_description"),
|
||||
icon: "upload",
|
||||
__sk_row_type: "noopRow"
|
||||
icon: "upload"
|
||||
},
|
||||
{
|
||||
id: "deleteUnusedTags",
|
||||
name: I18n.t("tagging.delete_unused"),
|
||||
description: I18n.t("tagging.delete_unused_description"),
|
||||
icon: "trash-alt",
|
||||
__sk_row_type: "noopRow"
|
||||
icon: "trash-alt"
|
||||
}
|
||||
];
|
||||
|
||||
return items;
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
onSelect(id) {
|
||||
|
|
|
@ -17,15 +17,6 @@ export default Component.extend({
|
|||
notice: null,
|
||||
showTopicTimer: null,
|
||||
|
||||
rerenderTriggers: [
|
||||
"topicClosed",
|
||||
"statusType",
|
||||
"executeAt",
|
||||
"basedOnLastPost",
|
||||
"duration",
|
||||
"categoryId"
|
||||
],
|
||||
|
||||
@discourseComputed("statusType")
|
||||
canRemoveTimer(type) {
|
||||
if (type === REMINDER_TYPE) return true;
|
||||
|
@ -38,7 +29,7 @@ export default Component.extend({
|
|||
},
|
||||
|
||||
renderTopicTimer() {
|
||||
if (!this.executeAt) {
|
||||
if (!this.executeAt || this.executeAt < moment()) {
|
||||
this.set("showTopicTimer", null);
|
||||
return;
|
||||
}
|
||||
|
@ -50,7 +41,6 @@ export default Component.extend({
|
|||
const statusUpdateAt = moment(this.executeAt);
|
||||
const duration = moment.duration(statusUpdateAt - moment());
|
||||
const minutesLeft = duration.asMinutes();
|
||||
|
||||
if (minutesLeft > 0) {
|
||||
let rerenderDelay = 1000;
|
||||
if (minutesLeft > 2160) {
|
||||
|
@ -82,9 +72,11 @@ export default Component.extend({
|
|||
);
|
||||
}
|
||||
|
||||
this.set("title", `${moment(this.executeAt).format("LLLL")}`.htmlSafe());
|
||||
this.set("notice", `${I18n.t(this._noticeKey(), options)}`.htmlSafe());
|
||||
this.set("showTopicTimer", true);
|
||||
this.setProperties({
|
||||
title: `${moment(this.executeAt).format("LLLL")}`.htmlSafe(),
|
||||
notice: `${I18n.t(this._noticeKey(), options)}`.htmlSafe(),
|
||||
showTopicTimer: true
|
||||
});
|
||||
|
||||
// TODO Sam: concerned this can cause a heavy rerender loop
|
||||
if (ENV.environment !== "test") {
|
||||
|
|
|
@ -100,13 +100,19 @@ export default Controller.extend(ModalFunctionality, {
|
|||
});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
popupAjaxError(error);
|
||||
})
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => this.set("loading", false));
|
||||
},
|
||||
|
||||
actions: {
|
||||
onChangeStatusType(value) {
|
||||
this.set("topicTimer.status_type", value);
|
||||
},
|
||||
|
||||
onChangeUpdateTime(value) {
|
||||
this.set("topicTimer.updateTime", value);
|
||||
},
|
||||
|
||||
saveTimer() {
|
||||
if (!this.get("topicTimer.updateTime")) {
|
||||
this.flash(
|
||||
|
|
|
@ -86,6 +86,20 @@ export default Controller.extend({
|
|||
this.toggleProperty("showActions");
|
||||
},
|
||||
|
||||
actOnGroup(member, actionId) {
|
||||
switch (actionId) {
|
||||
case "removeMember":
|
||||
this.send("removeMember", member);
|
||||
break;
|
||||
case "makeOwner":
|
||||
this.send("makeOwner", member.username);
|
||||
break;
|
||||
case "removeOwner":
|
||||
this.send("removeOwner", member);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
removeMember(user) {
|
||||
this.model.removeMember(user, this.memberParams);
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
isiPad,
|
||||
iOSWithVisualViewport
|
||||
} from "discourse/lib/utilities";
|
||||
import { computed } from "@ember/object";
|
||||
|
||||
const USER_HOMES = {
|
||||
1: "latest",
|
||||
|
@ -76,6 +77,17 @@ export default Controller.extend(PreferencesTabController, {
|
|||
});
|
||||
},
|
||||
|
||||
homepageId: computed(
|
||||
"model.user_option.homepage_id",
|
||||
"userSelectableHome.[]",
|
||||
function() {
|
||||
return (
|
||||
this.model.user_option.homepage_id ||
|
||||
this.userSelectableHome.firstObject.value
|
||||
);
|
||||
}
|
||||
),
|
||||
|
||||
@discourseComputed
|
||||
titleCountModes() {
|
||||
return TITLE_COUNT_MODES.map(value => {
|
||||
|
@ -195,6 +207,8 @@ export default Controller.extend(PreferencesTabController, {
|
|||
|
||||
// Force refresh when leaving this screen
|
||||
Discourse.set("assetVersion", "forceRefresh");
|
||||
|
||||
this.set("textSize", newSize);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -155,9 +155,8 @@ export default Controller.extend(BulkTopicSelection, FilterModeMixin, {
|
|||
});
|
||||
},
|
||||
|
||||
changeTagNotification(id) {
|
||||
const tagNotification = this.tagNotification;
|
||||
tagNotification.update({ notification_level: id });
|
||||
changeTagNotificationLevel(notificationLevel) {
|
||||
this.tagNotification.update({ notification_level: notificationLevel });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -242,12 +242,12 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
},
|
||||
|
||||
actions: {
|
||||
topicCategoryChanged(selection) {
|
||||
this.set("buffered.category_id", selection.value);
|
||||
topicCategoryChanged(categoryId) {
|
||||
this.set("buffered.category_id", categoryId);
|
||||
},
|
||||
|
||||
topicTagsChanged({ target }) {
|
||||
this.set("buffered.tags", target.value);
|
||||
topicTagsChanged(value) {
|
||||
this.set("buffered.tags", value);
|
||||
},
|
||||
|
||||
deletePending(pending) {
|
||||
|
|
|
@ -59,6 +59,9 @@ export default Controller.extend({
|
|||
},
|
||||
|
||||
actions: {
|
||||
changeGroupNotificationLevel(notificationLevel) {
|
||||
this.group.setNotification(notificationLevel, this.get("user.id"));
|
||||
},
|
||||
archive() {
|
||||
this.bulkOperation("archive_messages");
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@ import CanCheckEmails from "discourse/mixins/can-check-emails";
|
|||
import User from "discourse/models/user";
|
||||
import optionalService from "discourse/lib/optional-service";
|
||||
import { prioritizeNameInUx } from "discourse/lib/settings";
|
||||
import { set } from "@ember/object";
|
||||
import { set, computed } from "@ember/object";
|
||||
|
||||
export default Controller.extend(CanCheckEmails, {
|
||||
indexStream: false,
|
||||
|
@ -136,6 +136,21 @@ export default Controller.extend(CanCheckEmails, {
|
|||
}
|
||||
},
|
||||
|
||||
userNotificationLevel: computed(
|
||||
"currentUser.ignored_ids",
|
||||
"model.ignored",
|
||||
"model.muted",
|
||||
function() {
|
||||
if (this.get("model.ignored")) {
|
||||
return "changeToIgnored";
|
||||
} else if (this.get("model.muted")) {
|
||||
return "changeToMuted";
|
||||
} else {
|
||||
return "changeToNormal";
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
actions: {
|
||||
collapseProfile() {
|
||||
this.set("forceExpand", false);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
|
||||
registerUnbound(
|
||||
"component-for-collection",
|
||||
(collectionIdentifier, selectKit) => {
|
||||
return selectKit.modifyComponentForCollection(collectionIdentifier);
|
||||
}
|
||||
);
|
|
@ -0,0 +1,8 @@
|
|||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
|
||||
registerUnbound(
|
||||
"component-for-row",
|
||||
(collectionForIdentifier, item, selectKit) => {
|
||||
return selectKit.modifyComponentForRow(collectionForIdentifier, item);
|
||||
}
|
||||
);
|
|
@ -17,7 +17,7 @@ const DiscourseLocation = EmberObject.extend({
|
|||
this._super(...arguments);
|
||||
|
||||
this.set("location", this.location || window.location);
|
||||
this.initState();
|
||||
this.initOptions();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -25,9 +25,9 @@ const DiscourseLocation = EmberObject.extend({
|
|||
|
||||
Used to set state on first call to setURL
|
||||
|
||||
@method initState
|
||||
@method initOptions
|
||||
*/
|
||||
initState() {
|
||||
initOptions() {
|
||||
const history = this.history || window.history;
|
||||
if (history && history.scrollRestoration) {
|
||||
history.scrollRestoration = "manual";
|
||||
|
|
|
@ -292,6 +292,10 @@ const DiscourseURL = EmberObject.extend({
|
|||
return this.handleURL(path, opts);
|
||||
},
|
||||
|
||||
routeToUrl(url, opts = {}) {
|
||||
this.routeTo(Discourse.getURL(url), opts);
|
||||
},
|
||||
|
||||
rewrite(regexp, replacement, opts) {
|
||||
rewrites.push({ regexp, replacement, opts: opts || {} });
|
||||
},
|
||||
|
|
|
@ -120,15 +120,14 @@ const Category = RestModel.extend({
|
|||
return topicCount > (this.num_featured_topics || 2);
|
||||
},
|
||||
|
||||
@discourseComputed("topic_count", "subcategories")
|
||||
totalTopicCount(topicCount, subcats) {
|
||||
let count = topicCount;
|
||||
if (subcats) {
|
||||
subcats.forEach(s => {
|
||||
count += s.get("topic_count");
|
||||
@discourseComputed("topic_count", "subcategories.[]")
|
||||
totalTopicCount(topicCount, subcategories) {
|
||||
if (subcategories) {
|
||||
subcategories.forEach(subcategory => {
|
||||
topicCount += subcategory.topic_count;
|
||||
});
|
||||
}
|
||||
return count;
|
||||
return topicCount;
|
||||
},
|
||||
|
||||
save() {
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
{{combo-box
|
||||
value=selectedUserBadgeId
|
||||
nameProperty="badge.name"
|
||||
content=selectableUserBadges}}
|
||||
content=selectableUserBadges
|
||||
onChange=(action (mut selectedUserBadgeId))
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
{{#each categoryBreadcrumbs as |breadcrumb|}}
|
||||
{{#if breadcrumb.hasOptions}}
|
||||
{{category-drop
|
||||
category=breadcrumb.category
|
||||
category=breadcrumb.category
|
||||
categories=breadcrumb.options
|
||||
options=(hash
|
||||
parentCategory=breadcrumb.parentCategory
|
||||
categories=breadcrumb.options
|
||||
subCategory=breadcrumb.isSubcategory
|
||||
noSubcategories=breadcrumb.noSubcategories}}
|
||||
noSubcategories=breadcrumb.noSubcategories
|
||||
autoFilterable=true
|
||||
)
|
||||
}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
|
||||
{{#if siteSettings.tagging_enabled}}
|
||||
{{tag-drop
|
||||
currentCategory=category
|
||||
tagId=tagId}}
|
||||
{{tag-drop currentCategory=category tagId=tagId}}
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="bread-crumbs-right" connectorTagName="li" tagName=""}}
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
{{else}}
|
||||
{{composer-actions
|
||||
composerModel=model
|
||||
options=model.replyOptions
|
||||
replyOptions=model.replyOptions
|
||||
canWhisper=canWhisper
|
||||
openComposer=openComposer
|
||||
closeComposer=closeComposer
|
||||
action=model.action
|
||||
tabindex=tabindex}}
|
||||
tabindex=tabindex
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
<span class="action-title">
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
{{#each group.buttons as |b|}}
|
||||
{{#if b.popupMenu}}
|
||||
{{toolbar-popup-menu-options
|
||||
onSelect=onPopupMenuAction
|
||||
content=popupMenuOptions
|
||||
onChange=onPopupMenuAction
|
||||
onExpand=(action b.action b)
|
||||
title=b.title
|
||||
headerIcon=b.icon
|
||||
class=b.className
|
||||
content=popupMenuOptions}}
|
||||
options=(hash
|
||||
popupTitle=b.title
|
||||
icon=b.icon
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{d-button
|
||||
action=b.action
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
|
||||
{{#if showCategoryAdmin}}
|
||||
{{categories-admin-dropdown
|
||||
create=createCategory
|
||||
reorder=reorderCategories}}
|
||||
onChange=(action "selectCategoryAdminDropdownAction")
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
{{navigation-bar navItems=navItems filterMode=filterMode category=category}}
|
||||
|
||||
{{#if showCategoryNotifications}}
|
||||
{{category-notifications-button value=category.notification_level category=category}}
|
||||
{{category-notifications-button
|
||||
value=category.notification_level
|
||||
category=category
|
||||
onChange=(action "changeCategoryNotificationLevel")
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="before-create-topic-button"
|
||||
|
|
|
@ -2,4 +2,6 @@
|
|||
type=inputType
|
||||
class="date-picker"
|
||||
placeholder=placeholder
|
||||
value=value}}
|
||||
value=value
|
||||
input=(action "onInput")
|
||||
}}
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
excludeCategoryId=category.id
|
||||
categories=parentCategories
|
||||
allowSubCategories=true
|
||||
allowUncategorized=false}}
|
||||
allowUncategorized=false
|
||||
onChange=(action (mut category.parent_category_id))
|
||||
}}
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -22,18 +22,21 @@
|
|||
{{/unless}}
|
||||
{{#if editingPermissions}}
|
||||
{{#if category.availableGroups}}
|
||||
{{combo-box class="available-groups"
|
||||
allowInitialValueMutation=true
|
||||
allowContentReplacement=true
|
||||
content=category.availableGroups
|
||||
onSelect=(action "onDropdownChange")
|
||||
value=selectedGroup}}
|
||||
{{combo-box allowInitialValueMutation=true
|
||||
class="permission-selector"
|
||||
nameProperty="description"
|
||||
content=category.availablePermissions
|
||||
onSelect=(action "onDropdownChange")
|
||||
value=selectedPermission}}
|
||||
{{combo-box
|
||||
class="available-groups"
|
||||
content=category.availableGroups
|
||||
onChange=(action "onSelectGroup")
|
||||
value=selectedGroup
|
||||
valueProperty=null
|
||||
nameProperty=null
|
||||
}}
|
||||
{{combo-box
|
||||
class="permission-selector"
|
||||
nameProperty="description"
|
||||
content=category.availablePermissions
|
||||
onChange=(action "onSelectPermission")
|
||||
value=selectedPermission
|
||||
}}
|
||||
{{d-button
|
||||
action=(action "addPermission" selectedGroup selectedPermission)
|
||||
class="btn-primary add-permission"
|
||||
|
|
|
@ -33,10 +33,13 @@
|
|||
{{i18n "category.search_priority.label"}}
|
||||
</label>
|
||||
<div class="controls">
|
||||
{{combo-box valueAttribute="value"
|
||||
id="category-search-priority"
|
||||
content=searchPrioritiesOptions
|
||||
value=category.search_priority}}
|
||||
{{combo-box
|
||||
valueProperty="value"
|
||||
id="category-search-priority"
|
||||
content=searchPrioritiesOptions
|
||||
value=category.search_priority
|
||||
onChange=(action (mut category.search_priority))
|
||||
}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -145,7 +148,7 @@
|
|||
{{i18n "category.default_view"}}
|
||||
</label>
|
||||
<div class="controls">
|
||||
{{combo-box valueAttribute="value" id="category-default-view" content=availableViews value=category.default_view}}
|
||||
{{combo-box valueProperty="value" id="category-default-view" content=availableViews value=category.default_view}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -154,7 +157,7 @@
|
|||
{{i18n "category.default_top_period"}}
|
||||
</label>
|
||||
<div class="controls">
|
||||
{{combo-box valueAttribute="value" id="category-default-period" content=availableTopPeriods value=category.default_top_period}}
|
||||
{{combo-box valueProperty="value" id="category-default-period" content=availableTopPeriods value=category.default_top_period}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -163,9 +166,9 @@
|
|||
{{i18n "category.sort_order"}}
|
||||
</label>
|
||||
<div class="controls">
|
||||
{{combo-box valueAttribute="value" content=availableSorts value=category.sort_order none="category.sort_options.default"}}
|
||||
{{combo-box valueProperty="value" content=availableSorts value=category.sort_order none="category.sort_options.default"}}
|
||||
{{#unless isDefaultSortOrder}}
|
||||
{{combo-box castBoolean=true valueAttribute="value" content=sortAscendingOptions value=category.sort_ascending none="category.sort_options.default"}}
|
||||
{{combo-box castBoolean=true valueProperty="value" content=sortAscendingOptions value=category.sort_ascending none="category.sort_options.default"}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</section>
|
||||
|
@ -184,7 +187,7 @@
|
|||
<label for="subcategory-list-style">
|
||||
{{i18n "category.subcategory_list_style"}}
|
||||
</label>
|
||||
{{combo-box valueAttribute="value" id="subcategory-list-style" content=availableSubcategoryListStyles value=category.subcategory_list_style}}
|
||||
{{combo-box valueProperty="value" id="subcategory-list-style" content=availableSubcategoryListStyles value=category.subcategory_list_style}}
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -6,12 +6,17 @@
|
|||
tags=category.allowed_tags
|
||||
everyTag=true
|
||||
excludeSynonyms=true
|
||||
unlimitedTagCount=true}}
|
||||
unlimitedTagCount=true
|
||||
onChange=(action (mut category.allowed_tags))
|
||||
}}
|
||||
</section>
|
||||
|
||||
<section class="field">
|
||||
<label for="category-allowed-tag-groups">{{i18n 'category.tags_allowed_tag_groups'}}</label>
|
||||
{{tag-group-chooser id="category-allowed-tag-groups" tagGroups=category.allowed_tag_groups}}
|
||||
{{tag-group-chooser
|
||||
id="category-allowed-tag-groups"
|
||||
tagGroups=category.allowed_tag_groups
|
||||
}}
|
||||
{{#link-to 'tagGroups'}}{{i18n 'category.manage_tag_groups_link'}}{{/link-to}}
|
||||
</section>
|
||||
|
||||
|
|
|
@ -1,39 +1,52 @@
|
|||
<form>
|
||||
<div class="control-group">
|
||||
{{combo-box class="timer-type" allowInitialValueMutation=true content=timerTypes value=selection}}
|
||||
{{combo-box
|
||||
class="timer-type"
|
||||
onChange=onChangeStatusType
|
||||
content=timerTypes
|
||||
value=selection
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{#if showTimeOnly}}
|
||||
{{future-date-input
|
||||
input=topicTimer.updateTime
|
||||
label="topic.topic_status_update.when"
|
||||
statusType=selection
|
||||
includeWeekend=true
|
||||
basedOnLastPost=topicTimer.based_on_last_post}}
|
||||
input=(readonly topicTimer.updateTime)
|
||||
label="topic.topic_status_update.when"
|
||||
statusType=selection
|
||||
includeWeekend=true
|
||||
basedOnLastPost=topicTimer.based_on_last_post
|
||||
onChangeInput=onChangeUpdateTime
|
||||
}}
|
||||
{{else if publishToCategory}}
|
||||
<div class="control-group">
|
||||
<label>{{i18n 'topic.topic_status_update.publish_to'}}</label>
|
||||
{{category-chooser
|
||||
value=topicTimer.category_id
|
||||
excludeCategoryId=excludeCategoryId}}
|
||||
excludeCategoryId=excludeCategoryId
|
||||
onChange=(action (mut topicTimer.category_id))
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{future-date-input
|
||||
input=topicTimer.updateTime
|
||||
label="topic.topic_status_update.when"
|
||||
statusType=selection
|
||||
includeWeekend=true
|
||||
categoryId=topicTimer.category_id
|
||||
basedOnLastPost=topicTimer.based_on_last_post}}
|
||||
input=(readonly topicTimer.updateTime)
|
||||
label="topic.topic_status_update.when"
|
||||
statusType=selection
|
||||
includeWeekend=true
|
||||
categoryId=topicTimer.category_id
|
||||
basedOnLastPost=topicTimer.based_on_last_post
|
||||
onChangeInput=onChangeUpdateTime
|
||||
}}
|
||||
{{else if autoClose}}
|
||||
{{future-date-input
|
||||
input=topicTimer.updateTime
|
||||
label="topic.topic_status_update.when"
|
||||
statusType=selection
|
||||
includeWeekend=true
|
||||
basedOnLastPost=topicTimer.based_on_last_post
|
||||
lastPostedAt=model.last_posted_at}}
|
||||
input=topicTimer.updateTime
|
||||
label="topic.topic_status_update.when"
|
||||
statusType=selection
|
||||
includeWeekend=true
|
||||
basedOnLastPost=topicTimer.based_on_last_post
|
||||
lastPostedAt=model.last_posted_at
|
||||
onChangeInput=onChangeUpdateTime
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -2,21 +2,29 @@
|
|||
<div class="control-group">
|
||||
<label>{{displayLabel}}</label>
|
||||
{{future-date-input-selector
|
||||
minimumResultsForSearch=-1
|
||||
statusType=statusType
|
||||
value=selection
|
||||
input=input
|
||||
includeDateTime=includeDateTime
|
||||
includeWeekend=includeWeekend
|
||||
includeFarFuture=includeFarFuture
|
||||
includeMidFuture=includeMidFuture
|
||||
clearable=clearable
|
||||
none="topic.auto_update_input.none"}}
|
||||
minimumResultsForSearch=-1
|
||||
statusType=statusType
|
||||
value=(readonly selection)
|
||||
input=(readonly input)
|
||||
includeDateTime=includeDateTime
|
||||
includeWeekend=includeWeekend
|
||||
includeFarFuture=includeFarFuture
|
||||
includeMidFuture=includeMidFuture
|
||||
clearable=clearable
|
||||
none="topic.auto_update_input.none"
|
||||
onChangeInput=onChangeInput
|
||||
onChange=(action (mut selection))
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{#if displayDateAndTimePicker}}
|
||||
<div class="control-group">
|
||||
{{d-icon "calendar-alt"}} {{date-picker-future value=date defaultDate=date}}
|
||||
{{d-icon "calendar-alt"}}
|
||||
{{date-picker-future
|
||||
value=date
|
||||
defaultDate=date
|
||||
onSelect=(action (mut date))
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
|
@ -44,11 +52,12 @@
|
|||
{{#if showTopicStatusInfo}}
|
||||
<div class="alert alert-info">
|
||||
{{topic-timer-info
|
||||
statusType=statusType
|
||||
executeAt=executeAt
|
||||
basedOnLastPost=basedOnLastPost
|
||||
duration=duration
|
||||
categoryId=categoryId}}
|
||||
statusType=statusType
|
||||
executeAt=executeAt
|
||||
basedOnLastPost=basedOnLastPost
|
||||
duration=duration
|
||||
categoryId=categoryId
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
{{/link-to}}
|
||||
</li>
|
||||
{{else}}
|
||||
{{group-dropdown content=group.extras.visible_group_names value=group.name}}
|
||||
{{group-dropdown
|
||||
groups=group.extras.visible_group_names
|
||||
value=group.name
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
{{#each tabs as |tab|}}
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
<label class="control-label">{{i18n 'admin.groups.manage.interaction.visibility'}}</label>
|
||||
<label for="visiblity">{{i18n 'admin.groups.manage.interaction.visibility_levels.title'}}</label>
|
||||
|
||||
{{combo-box name="alias"
|
||||
valueAttribute="value"
|
||||
value=model.visibility_level
|
||||
content=visibilityLevelOptions
|
||||
castInteger=true
|
||||
class="groups-form-visibility-level"}}
|
||||
{{combo-box
|
||||
name="alias"
|
||||
valueProperty="value"
|
||||
value=model.visibility_level
|
||||
content=visibilityLevelOptions
|
||||
castInteger=true
|
||||
class="groups-form-visibility-level"
|
||||
onChange=(action (mut model.visibility_level))
|
||||
}}
|
||||
|
||||
<div class="control-instructions">
|
||||
{{i18n 'admin.groups.manage.interaction.visibility_levels.description'}}
|
||||
|
@ -19,7 +22,7 @@
|
|||
<label for="visiblity">{{i18n 'admin.groups.manage.interaction.members_visibility_levels.title'}}</label>
|
||||
|
||||
{{combo-box name="alias"
|
||||
valueAttribute="value"
|
||||
valueProperty="value"
|
||||
value=model.members_visibility_level
|
||||
content=visibilityLevelOptions
|
||||
castInteger=true
|
||||
|
@ -35,21 +38,27 @@
|
|||
<label class="control-label">{{i18n 'groups.manage.interaction.posting'}}</label>
|
||||
<label for="alias">{{i18n 'groups.alias_levels.mentionable'}}</label>
|
||||
|
||||
{{combo-box name="alias"
|
||||
valueAttribute="value"
|
||||
value=model.mentionable_level
|
||||
content=aliasLevelOptions
|
||||
class="groups-form-mentionable-level"}}
|
||||
{{combo-box
|
||||
name="alias"
|
||||
valueProperty="value"
|
||||
value=model.mentionable_level
|
||||
content=aliasLevelOptions
|
||||
class="groups-form-mentionable-level"
|
||||
onChange=(action (mut model.mentionable_level))
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="alias">{{i18n 'groups.alias_levels.messageable'}}</label>
|
||||
|
||||
{{combo-box name="alias"
|
||||
valueAttribute="value"
|
||||
value=model.messageable_level
|
||||
content=aliasLevelOptions
|
||||
class="groups-form-messageable-level"}}
|
||||
{{combo-box
|
||||
name="alias"
|
||||
valueProperty="value"
|
||||
value=model.messageable_level
|
||||
content=aliasLevelOptions
|
||||
class="groups-form-messageable-level"
|
||||
onChange=(action (mut model.messageable_level))
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
{{i18n 'admin.groups.manage.membership.automatic_membership_email_domains'}}
|
||||
</label>
|
||||
|
||||
{{list-setting name="automatic_membership"
|
||||
settingValue=model.emailDomains
|
||||
class="group-form-automatic-membership-automatic"}}
|
||||
{{list-setting
|
||||
name="automatic_membership"
|
||||
settingValue=model.emailDomains
|
||||
class="group-form-automatic-membership-automatic"
|
||||
onChange=(action "onChangeEmailDomainsSetting")
|
||||
}}
|
||||
|
||||
<label>
|
||||
{{input type="checkbox"
|
||||
|
@ -26,12 +29,14 @@
|
|||
<label class="control-label">{{i18n "admin.groups.manage.membership.effects"}}</label>
|
||||
<label for="grant_trust_level">{{i18n 'admin.groups.manage.membership.trust_levels_title'}}</label>
|
||||
|
||||
{{combo-box name="grant_trust_level"
|
||||
valueAttribute="value"
|
||||
value=model.grant_trust_level
|
||||
content=trustLevelOptions
|
||||
class="groups-form-grant-trust-level"}}
|
||||
|
||||
{{combo-box
|
||||
name="grant_trust_level"
|
||||
valueProperty="value"
|
||||
value=groupTrustLevel
|
||||
content=trustLevelOptions
|
||||
class="groups-form-grant-trust-level"
|
||||
onChange=(action (mut model.grant_trust_level))
|
||||
}}
|
||||
<label>
|
||||
{{input type="checkbox"
|
||||
checked=model.primary_group
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
{{#if multiple}}
|
||||
{{dropdown-select-box
|
||||
headerIcon=bundle.icon
|
||||
class="reviewable-action-dropdown"
|
||||
nameProperty="label"
|
||||
title=bundle.label
|
||||
content=bundle.actions
|
||||
onSelect=(action "performById")
|
||||
disabled=reviewableUpdating}}
|
||||
onChange=(action "performById")
|
||||
options=(hash
|
||||
icon=bundle.icon
|
||||
disabled=reviewableUpdating
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{d-button
|
||||
class=(concat "reviewable-action " (dasherize first.id) " " first.button_class)
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
{{category-chooser value=value onChooseCategory=categoryChanged}}
|
||||
{{category-chooser
|
||||
value=value
|
||||
onChange=categoryChanged
|
||||
}}
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
{{mini-tag-chooser tags=value onChangeTags=valueChanged}}
|
||||
{{mini-tag-chooser
|
||||
value=value
|
||||
onChange=(action "onChange")
|
||||
}}
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
|
||||
{{#each reviewable.editable_fields as |f|}}
|
||||
<div class='editable-field {{dasherize f.id}}'>
|
||||
{{component
|
||||
(concat "reviewable-field-" f.type)
|
||||
{{component (concat "reviewable-field-" f.type)
|
||||
tagName=''
|
||||
value=(editable-value reviewable f.id)
|
||||
tagCategoryId=reviewable.category.id
|
||||
valueChanged=(action "valueChanged" f.id)
|
||||
categoryChanged=(action "categoryChanged")}}
|
||||
categoryChanged=(action "categoryChanged")
|
||||
}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
<div class="control-group pull-left">
|
||||
<label class="control-label" for="search-in-category">{{i18n "search.advanced.in_category.label"}}</label>
|
||||
<div class="controls">
|
||||
{{search-advanced-category-chooser value=searchedTerms.category}}
|
||||
{{search-advanced-category-chooser
|
||||
value=searchedTerms.category.id
|
||||
onChange=(action "onChangeCategory")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -47,7 +50,9 @@
|
|||
allowCreate=false
|
||||
filterPlaceholder=null
|
||||
everyTag=true
|
||||
unlimitedTagCount=true}}
|
||||
unlimitedTagCount=true
|
||||
onChange=(action (mut searchedTerms.tags))
|
||||
}}
|
||||
<section class="field">
|
||||
<label>{{ input type="checkbox" class="all-tags" checked=searchedTerms.special.all_tags}} {{i18n "search.advanced.filters.all_tags"}} </label>
|
||||
</section>
|
||||
|
@ -68,13 +73,27 @@
|
|||
<label>{{input type="checkbox" class="in-seen" checked=searchedTerms.special.in.seen}} {{i18n "search.advanced.filters.seen"}}</label>
|
||||
</section>
|
||||
{{/if}}
|
||||
{{combo-box id="in" valueAttribute="value" content=inOptions value=searchedTerms.in none="user.locale.any"}}
|
||||
{{combo-box
|
||||
id="in"
|
||||
valueProperty="value"
|
||||
content=inOptions
|
||||
value=searchedTerms.in
|
||||
none="user.locale.any"
|
||||
onChange=(action (mut searchedTerms.in))
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group pull-left">
|
||||
<label class="control-label" for="search-status-options">{{i18n "search.advanced.statuses.label"}}</label>
|
||||
<div class="controls">
|
||||
{{combo-box id="status" valueAttribute="value" content=statusOptions value=searchedTerms.status none="user.locale.any"}}
|
||||
{{combo-box
|
||||
id="status"
|
||||
valueProperty="value"
|
||||
content=statusOptions
|
||||
value=searchedTerms.status
|
||||
none="user.locale.any"
|
||||
onChange=(action (mut searchedTerms.status))
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -83,8 +102,18 @@
|
|||
<div class="control-group pull-left">
|
||||
<label class="control-label" for="search-post-date">{{i18n "search.advanced.post.time.label"}}</label>
|
||||
<div class="controls full-search-dates">
|
||||
{{combo-box id="postTime" valueAttribute="value" content=postTimeOptions value=searchedTerms.time.when}}
|
||||
{{date-picker value=searchedTerms.time.days id="search-post-date"}}
|
||||
{{combo-box
|
||||
id="postTime"
|
||||
valueProperty="value"
|
||||
content=postTimeOptions
|
||||
value=searchedTerms.time.when
|
||||
onChange=(action "onChangeWhenTime")
|
||||
}}
|
||||
{{date-input
|
||||
date=searchedTerms.time.days
|
||||
onChange=(action "onChangeWhenDate")
|
||||
id="search-post-date"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group pull-left">
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<label>{{i18n "shared_drafts.destination_category"}}</label>
|
||||
{{category-chooser
|
||||
value=topic.destination_category_id
|
||||
onChooseCategory=(action "updateDestinationCategory")}}
|
||||
onChange=(action "updateDestinationCategory")
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div class='publish-field'>
|
||||
|
|
|
@ -54,7 +54,10 @@
|
|||
</div>
|
||||
|
||||
{{#if showNotificationsButton}}
|
||||
{{topic-notifications-button notificationLevel=topic.details.notification_level topic=topic}}
|
||||
{{topic-notifications-button
|
||||
notificationLevel=topic.details.notification_level
|
||||
topic=topic
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="after-topic-footer-buttons"
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<label class="control-label" for="{{concat 'user-' elementId}}">{{{field.name}}} {{#if field.required}}<span class='required'>*</span>{{/if}}
|
||||
</label>
|
||||
<div class='controls'>
|
||||
{{combo-box id=(concat 'user-' elementId) content=field.options value=value none=noneLabel}}
|
||||
{{combo-box
|
||||
id=(concat 'user-' elementId)
|
||||
content=field.options
|
||||
value=value
|
||||
none=noneLabel
|
||||
onChange=(action (mut value))
|
||||
}}
|
||||
<div class="instructions">{{{field.description}}}</div>
|
||||
</div>
|
||||
|
|
|
@ -73,16 +73,28 @@
|
|||
{{#if model.showCategoryChooser}}
|
||||
<div class="category-input">
|
||||
{{category-chooser
|
||||
fullWidthOnMobile=true
|
||||
value=model.categoryId
|
||||
scopedCategoryId=scopedCategoryId
|
||||
tabindex="3"
|
||||
onChange=(action (mut model.categoryId))
|
||||
isDisabled=disableCategoryChooser
|
||||
tabindex="3"}}
|
||||
options=(hash
|
||||
scopedCategoryId=scopedCategoryId
|
||||
)
|
||||
}}
|
||||
{{popup-input-tip validation=categoryValidation}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if canEditTags}}
|
||||
{{mini-tag-chooser tags=model.tags tabindex="4" categoryId=model.categoryId minimum=model.minimumRequiredTags isDisabled=disableTagsChooser}}
|
||||
{{mini-tag-chooser
|
||||
value=model.tags
|
||||
tabindex=4
|
||||
isDisabled=disableTagsChooser
|
||||
onChange=(action (mut model.tags))
|
||||
options=(hash
|
||||
categoryId=model.categoryId
|
||||
minimum=model.minimumRequiredTags
|
||||
)
|
||||
}}
|
||||
{{popup-input-tip validation=tagValidation}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -55,7 +55,12 @@
|
|||
<span class='desc'>
|
||||
{{i18n "search.sort_by"}}
|
||||
</span>
|
||||
{{combo-box value=sortOrder content=sortOrders castInteger=true}}
|
||||
{{combo-box
|
||||
value=sortOrder
|
||||
content=sortOrders
|
||||
castInteger=true
|
||||
onChange=(action (mut sortOrder))
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -194,12 +199,18 @@
|
|||
{{#if site.mobileView}}
|
||||
{{#if expanded}}
|
||||
<div class="search-advanced-filters">
|
||||
{{search-advanced-options searchTerm=searchTerm isExpanded=expanded}}
|
||||
{{search-advanced-options
|
||||
searchTerm=searchTerm
|
||||
isExpanded=expanded
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="search-advanced-filters">
|
||||
{{search-advanced-options searchTerm=searchTerm isExpanded=true}}
|
||||
{{search-advanced-options
|
||||
searchTerm=searchTerm
|
||||
isExpanded=true
|
||||
}}
|
||||
|
||||
{{d-button
|
||||
label="submit"
|
||||
|
|
|
@ -63,11 +63,13 @@
|
|||
<td>
|
||||
{{#if canManageGroup}}
|
||||
{{group-member-dropdown
|
||||
removeMember=(action "removeMember")
|
||||
makeOwner=(action "makeOwner")
|
||||
removeOwner=(action "removeOwner")
|
||||
member=m
|
||||
group=model}}
|
||||
removeMember=(action "removeMember")
|
||||
makeOwner=(action "makeOwner")
|
||||
removeOwner=(action "removeOwner")
|
||||
member=m
|
||||
group=model
|
||||
onChange=(action "actOnGroup" m)
|
||||
}}
|
||||
{{/if}}
|
||||
{{!-- group parameter is used by plugins --}}
|
||||
</td>
|
||||
|
|
|
@ -12,12 +12,16 @@
|
|||
placeholderKey="groups.index.all"
|
||||
class="groups-header-filters-name no-blur"}}
|
||||
|
||||
{{combo-box value=type
|
||||
content=types
|
||||
clearable=true
|
||||
allowAutoSelectFirst=false
|
||||
noneLabel="groups.index.filter"
|
||||
class="groups-header-filters-type"}}
|
||||
{{combo-box
|
||||
value=type
|
||||
content=types
|
||||
class="groups-header-filters-type"
|
||||
onChange=(action (mut type))
|
||||
options=(hash
|
||||
clearable=true
|
||||
none="groups.index.filter"
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
<div class="group-members-manage">
|
||||
{{#if canManageGroup}}
|
||||
{{#if currentUser.admin}}
|
||||
{{group-members-dropdown
|
||||
showAddMembersModal=(route-action "showAddMembersModal")
|
||||
showBulkAddModal=(route-action "showBulkAddModal")}}
|
||||
{{group-members-dropdown onChange=(action "groupMembersDropdown")}}
|
||||
{{else}}
|
||||
{{d-button
|
||||
icon="plus"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{plugin-outlet name="users-top" connectorTagName='div' args=(hash model=model)}}
|
||||
|
||||
<div class='clearfix user-controls'>
|
||||
{{period-chooser period=period}}
|
||||
{{period-chooser period=period onChange=(action (mut period))}}
|
||||
{{text-field value=nameInput placeholderKey="directory.filter_name" class="filter-name no-blur"}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -24,17 +24,17 @@
|
|||
{{#if userHasTimezoneSet}}
|
||||
{{#tap-tile-grid activeTile=selectedReminderType as |grid|}}
|
||||
{{#if usingMobileDevice}}
|
||||
<!-- {{tap-tile icon="desktop" text=(i18n "bookmarks.reminders.at_desktop") tileId=reminderTypes.AT_DESKTOP activeTile=grid.activeTile onSelect=(action "selectReminderType")}} -->
|
||||
<!-- {{tap-tile icon="desktop" text=(i18n "bookmarks.reminders.at_desktop") tileId=reminderTypes.AT_DESKTOP activeTile=grid.activeTile onChange=(action "selectReminderType")}} -->
|
||||
{{/if}}
|
||||
|
||||
{{#if showLaterToday}}
|
||||
{{tap-tile icon="far-moon" text=laterTodayFormatted tileId=reminderTypes.LATER_TODAY activeTile=grid.activeTile onSelect=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-moon" text=laterTodayFormatted tileId=reminderTypes.LATER_TODAY activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{/if}}
|
||||
{{tap-tile icon="briefcase" text=nextBusinessDayFormatted tileId=reminderTypes.NEXT_BUSINESS_DAY activeTile=grid.activeTile onSelect=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-sun" text=tomorrowFormatted tileId=reminderTypes.TOMORROW activeTile=grid.activeTile onSelect=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-clock" text=nextWeekFormatted tileId=reminderTypes.NEXT_WEEK activeTile=grid.activeTile onSelect=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-calendar-plus" text=nextMonthFormatted tileId=reminderTypes.NEXT_MONTH activeTile=grid.activeTile onSelect=(action "selectReminderType")}}
|
||||
<!-- {{tap-tile icon="calendar-alt" text=(I18n "bookmarks.reminders.custom") tileId=reminderTypes.CUSTOM activeTile=grid.activeTile onSelect=(action "selectReminderType")}} -->
|
||||
{{tap-tile icon="briefcase" text=nextBusinessDayFormatted tileId=reminderTypes.NEXT_BUSINESS_DAY activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-sun" text=tomorrowFormatted tileId=reminderTypes.TOMORROW activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-clock" text=nextWeekFormatted tileId=reminderTypes.NEXT_WEEK activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-calendar-plus" text=nextMonthFormatted tileId=reminderTypes.NEXT_MONTH activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
<!-- {{tap-tile icon="calendar-alt" text=(I18n "bookmarks.reminders.custom") tileId=reminderTypes.CUSTOM activeTile=grid.activeTile onChange=(action "selectReminderType")}} -->
|
||||
{{/tap-tile-grid}}
|
||||
{{else}}
|
||||
<div class="alert alert-info">{{{i18n "bookmarks.no_timezone" basePath=basePath }}}</div>
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<p>{{i18n "topics.bulk.choose_new_category"}}</p>
|
||||
|
||||
<p>{{category-chooser value=newCategoryId}}</p>
|
||||
<p>
|
||||
{{category-chooser
|
||||
value=newCategoryId
|
||||
onChange=(action (mut newCategoryId))
|
||||
}}
|
||||
</p>
|
||||
|
||||
{{#conditional-loading-spinner condition=loading}}
|
||||
{{d-button action=(action "changeCategory") label="topics.bulk.change_category"}}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
{{date-picker-past
|
||||
value=(unbound date)
|
||||
containerId="date-container"
|
||||
onSelect=(action (mut date))}}
|
||||
onChange=(action (mut date))}}
|
||||
|
||||
{{input type="time" value=time}}
|
||||
</form>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue