mirror of
https://github.com/discourse/discourse.git
synced 2025-03-15 19:20:20 +08:00
DEV: Convert feature-topic
modal to component-based API (#23277)
Updated styles with some sign off from @jordanvidrine <img width="655" alt="Screenshot 2023-08-28 at 9 07 47 AM" src="https://github.com/discourse/discourse/assets/50783505/31b453ef-a787-436f-9fd9-48c9cd3a2e81">
This commit is contained in:
parent
81d8c6ba6c
commit
6870f38e87
@ -0,0 +1,232 @@
|
||||
<DModal
|
||||
class="feature-topic"
|
||||
@title={{i18n "topic.feature_topic.title"}}
|
||||
@closeModal={{@closeModal}}
|
||||
>
|
||||
<:body>
|
||||
{{#if @model.topic.pinned_at}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
{{#if @model.topic.pinned_globally}}
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{#if this.pinnedGloballyCount}}
|
||||
{{html-safe
|
||||
(i18n
|
||||
"topic.feature_topic.already_pinned_globally"
|
||||
count=this.pinnedGloballyCount
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{html-safe (i18n "topic.feature_topic.not_pinned_globally")}}
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>{{i18n "topic.feature_topic.global_pin_note"}}</p>
|
||||
{{else}}
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{html-safe this.alreadyPinnedMessage}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>{{i18n "topic.feature_topic.pin_note"}}</p>
|
||||
{{/if}}
|
||||
<p>{{html-safe this.unPinMessage}}</p>
|
||||
<p><DButton
|
||||
@action={{this.unpin}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.unpin"
|
||||
class="btn-primary"
|
||||
/></p>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{html-safe this.alreadyPinnedMessage}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.pin_note"}}
|
||||
</p>
|
||||
{{#if this.site.isMobileDevice}}
|
||||
<p>
|
||||
{{html-safe this.pinMessage}}
|
||||
</p>
|
||||
<p class="with-validation">
|
||||
<FutureDateInput
|
||||
class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{@model.topic.pinnedInCategoryUntil}}
|
||||
@onChangeInput={{action
|
||||
(mut @model.topic.pinnedInCategoryUntil)
|
||||
}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinInCategoryValidation}}
|
||||
@shownAt={{this.pinInCategoryTipShownAt}}
|
||||
/>
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="with-validation">
|
||||
{{html-safe this.pinMessage}}
|
||||
<span>
|
||||
{{d-icon "far-clock"}}
|
||||
<FutureDateInput
|
||||
class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{@model.topic.pinnedInCategoryUntil}}
|
||||
@onChangeInput={{action
|
||||
(mut @model.topic.pinnedInCategoryUntil)
|
||||
}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinInCategoryValidation}}
|
||||
@shownAt={{this.pinInCategoryTipShownAt}}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
{{/if}}
|
||||
<p>
|
||||
<DButton
|
||||
@action={{this.pin}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.pin"
|
||||
class="btn-primary"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.canPinGlobally}}
|
||||
<hr />
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{#if this.pinnedGloballyCount}}
|
||||
{{html-safe
|
||||
(i18n
|
||||
"topic.feature_topic.already_pinned_globally"
|
||||
count=this.pinnedGloballyCount
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{html-safe (i18n "topic.feature_topic.not_pinned_globally")}}
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.global_pin_note"}}
|
||||
</p>
|
||||
{{#if this.site.isMobileDevice}}
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.pin_globally"}}
|
||||
</p>
|
||||
<p class="with-validation">
|
||||
<FutureDateInput
|
||||
class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{@model.topic.pinnedGloballyUntil}}
|
||||
@onChangeInput={{action
|
||||
(mut @model.topic.pinnedGloballyUntil)
|
||||
}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinGloballyValidation}}
|
||||
@shownAt={{this.pinGloballyTipShownAt}}
|
||||
/>
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="with-validation">
|
||||
{{i18n "topic.feature_topic.pin_globally"}}
|
||||
<span>
|
||||
{{d-icon "far-clock"}}
|
||||
<FutureDateInput
|
||||
class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{@model.topic.pinnedGloballyUntil}}
|
||||
@onChangeInput={{action
|
||||
(mut @model.topic.pinnedGloballyUntil)
|
||||
}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinGloballyValidation}}
|
||||
@shownAt={{this.pinGloballyTipShownAt}}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
{{/if}}
|
||||
<p>
|
||||
<DButton
|
||||
@action={{this.pinGlobally}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.pin_globally"
|
||||
class="btn-primary"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<hr />
|
||||
{{#if this.currentUser.staff}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{#if this.bannerCount}}
|
||||
{{html-safe (i18n "topic.feature_topic.banner_exists")}}
|
||||
{{else}}
|
||||
{{html-safe (i18n "topic.feature_topic.no_banner_exists")}}
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.banner_note"}}
|
||||
</p>
|
||||
<p>
|
||||
{{#if @model.topic.isBanner}}
|
||||
{{i18n "topic.feature_topic.remove_banner"}}
|
||||
{{else}}
|
||||
{{i18n "topic.feature_topic.make_banner"}}
|
||||
{{/if}}
|
||||
</p>
|
||||
<p>
|
||||
{{#if @model.topic.isBanner}}
|
||||
<DButton
|
||||
@action={{this.removeBanner}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.remove_banner"
|
||||
class="btn-primary"
|
||||
/>
|
||||
{{else}}
|
||||
<DButton
|
||||
@action={{this.makeBanner}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.make_banner"
|
||||
class="btn-primary make-banner"
|
||||
/>
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</:body>
|
||||
</DModal>
|
@ -0,0 +1,180 @@
|
||||
import Component from "@glimmer/component";
|
||||
import I18n from "I18n";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import EmberObject, { action } from "@ember/object";
|
||||
import { categoryLinkHTML } from "discourse/helpers/category-link";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
export default class FeatureTopic extends Component {
|
||||
@service currentUser;
|
||||
@service dialog;
|
||||
|
||||
@tracked loading = true;
|
||||
@tracked pinnedInCategoryCount = 0;
|
||||
@tracked pinnedGloballyCount = 0;
|
||||
@tracked bannerCount = 0;
|
||||
@tracked pinInCategoryTipShownAt = false;
|
||||
@tracked pinGloballyTipShownAt = false;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.loadFeatureStats();
|
||||
}
|
||||
|
||||
get categoryLink() {
|
||||
return categoryLinkHTML(this.args.model.topic.category, {
|
||||
allowUncategorized: true,
|
||||
});
|
||||
}
|
||||
|
||||
get unPinMessage() {
|
||||
let name = "topic.feature_topic.unpin";
|
||||
if (this.args.model.topic.pinned_globally) {
|
||||
name += "_globally";
|
||||
}
|
||||
if (moment(this.args.model.topic.pinned_until) > moment()) {
|
||||
name += "_until";
|
||||
}
|
||||
const until = moment(this.args.model.topic.pinned_until).format("LL");
|
||||
return I18n.t(name, { categoryLink: this.categoryLink, until });
|
||||
}
|
||||
|
||||
get canPinGlobally() {
|
||||
return (
|
||||
this.currentUser.canManageTopic &&
|
||||
this.args.model.topic.details.can_pin_unpin_topic
|
||||
);
|
||||
}
|
||||
|
||||
get pinMessage() {
|
||||
return I18n.t("topic.feature_topic.pin", {
|
||||
categoryLink: this.categoryLink,
|
||||
});
|
||||
}
|
||||
|
||||
get alreadyPinnedMessage() {
|
||||
const key =
|
||||
this.pinnedInCategoryCount === 0
|
||||
? "topic.feature_topic.not_pinned"
|
||||
: "topic.feature_topic.already_pinned";
|
||||
return I18n.t(key, {
|
||||
categoryLink: this.categoryLink,
|
||||
count: this.pinnedInCategoryCount,
|
||||
});
|
||||
}
|
||||
|
||||
get pinDisabled() {
|
||||
return !this._isDateValid(this.parsedPinnedInCategoryUntil);
|
||||
}
|
||||
|
||||
get pinGloballyDisabled() {
|
||||
return !this._isDateValid(this.parsedPinnedGloballyUntil);
|
||||
}
|
||||
|
||||
get parsedPinnedInCategoryUntil() {
|
||||
return this._parseDate(this.args.model.topic.pinnedInCategoryUntil);
|
||||
}
|
||||
|
||||
get parsedPinnedGloballyUntil() {
|
||||
return this._parseDate(this.args.model.topic.pinnedGloballyUntil);
|
||||
}
|
||||
|
||||
get pinInCategoryValidation() {
|
||||
if (this.pinDisabled) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("topic.feature_topic.pin_validation"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get pinGloballyValidation() {
|
||||
if (this.pinGloballyDisabled) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("topic.feature_topic.pin_validation"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_parseDate(date) {
|
||||
return moment(date, ["YYYY-MM-DD", "YYYY-MM-DD HH:mm"]);
|
||||
}
|
||||
|
||||
_isDateValid(parsedDate) {
|
||||
return parsedDate.isValid() && parsedDate > moment();
|
||||
}
|
||||
|
||||
@action
|
||||
async loadFeatureStats() {
|
||||
try {
|
||||
this.loading = true;
|
||||
const result = await ajax("/topics/feature_stats.json", {
|
||||
data: { category_id: this.args.model.topic.category.id },
|
||||
});
|
||||
|
||||
if (result) {
|
||||
this.pinnedInCategoryCount = result.pinned_in_category_count;
|
||||
this.pinnedGloballyCount = result.pinned_globally_count;
|
||||
this.bannerCount = result.banner_count;
|
||||
}
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
async _confirmBeforePinningGlobally() {
|
||||
if (this.pinnedGloballyCount < 4) {
|
||||
this.args.model.pinGlobally();
|
||||
this.args.closeModal();
|
||||
} else {
|
||||
this.dialog.yesNoConfirm({
|
||||
message: I18n.t("topic.feature_topic.confirm_pin_globally", {
|
||||
count: this.pinnedGloballyCount,
|
||||
}),
|
||||
didConfirm: () => {
|
||||
this.args.model.pinGlobally();
|
||||
this.args.closeModal();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
pin() {
|
||||
if (this.pinDisabled) {
|
||||
this.pinInCategoryTipShownAt = Date.now();
|
||||
} else {
|
||||
this.args.model.togglePinned();
|
||||
this.args.closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
pinGlobally() {
|
||||
if (this.pinGloballyDisabled) {
|
||||
this.pinGloballyTipShownAt = Date.now();
|
||||
} else {
|
||||
this._confirmBeforePinningGlobally();
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
unpin() {
|
||||
this.args.model.togglePinned();
|
||||
this.args.closeModal();
|
||||
}
|
||||
|
||||
@action
|
||||
makeBanner() {
|
||||
this.args.model.makeBanner();
|
||||
this.args.closeModal();
|
||||
}
|
||||
|
||||
@action
|
||||
removeBanner() {
|
||||
this.args.model.removeBanner();
|
||||
this.args.closeModal();
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import EmberObject from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { categoryLinkHTML } from "discourse/helpers/category-link";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
topicController: controller("topic"),
|
||||
dialog: service(),
|
||||
|
||||
loading: true,
|
||||
pinnedInCategoryCount: 0,
|
||||
pinnedGloballyCount: 0,
|
||||
bannerCount: 0,
|
||||
|
||||
reset() {
|
||||
this.setProperties({
|
||||
"model.pinnedInCategoryUntil": null,
|
||||
"model.pinnedGloballyUntil": null,
|
||||
pinInCategoryTipShownAt: false,
|
||||
pinGloballyTipShownAt: false,
|
||||
});
|
||||
},
|
||||
|
||||
@discourseComputed("model.category")
|
||||
categoryLink(category) {
|
||||
return categoryLinkHTML(category, { allowUncategorized: true });
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"categoryLink",
|
||||
"model.pinned_globally",
|
||||
"model.pinned_until"
|
||||
)
|
||||
unPinMessage(categoryLink, pinnedGlobally, pinnedUntil) {
|
||||
let name = "topic.feature_topic.unpin";
|
||||
if (pinnedGlobally) {
|
||||
name += "_globally";
|
||||
}
|
||||
if (moment(pinnedUntil) > moment()) {
|
||||
name += "_until";
|
||||
}
|
||||
const until = moment(pinnedUntil).format("LL");
|
||||
|
||||
return I18n.t(name, { categoryLink, until });
|
||||
},
|
||||
|
||||
@discourseComputed("model.details.can_pin_unpin_topic")
|
||||
canPinGlobally(canPinUnpinTopic) {
|
||||
return this.currentUser.canManageTopic && canPinUnpinTopic;
|
||||
},
|
||||
|
||||
@discourseComputed("categoryLink")
|
||||
pinMessage(categoryLink) {
|
||||
return I18n.t("topic.feature_topic.pin", { categoryLink });
|
||||
},
|
||||
|
||||
@discourseComputed("categoryLink", "pinnedInCategoryCount")
|
||||
alreadyPinnedMessage(categoryLink, count) {
|
||||
const key =
|
||||
count === 0
|
||||
? "topic.feature_topic.not_pinned"
|
||||
: "topic.feature_topic.already_pinned";
|
||||
return I18n.t(key, { categoryLink, count });
|
||||
},
|
||||
|
||||
@discourseComputed("parsedPinnedInCategoryUntil")
|
||||
pinDisabled(parsedPinnedInCategoryUntil) {
|
||||
return !this._isDateValid(parsedPinnedInCategoryUntil);
|
||||
},
|
||||
|
||||
@discourseComputed("parsedPinnedGloballyUntil")
|
||||
pinGloballyDisabled(parsedPinnedGloballyUntil) {
|
||||
return !this._isDateValid(parsedPinnedGloballyUntil);
|
||||
},
|
||||
|
||||
@discourseComputed("model.pinnedInCategoryUntil")
|
||||
parsedPinnedInCategoryUntil(pinnedInCategoryUntil) {
|
||||
return this._parseDate(pinnedInCategoryUntil);
|
||||
},
|
||||
|
||||
@discourseComputed("model.pinnedGloballyUntil")
|
||||
parsedPinnedGloballyUntil(pinnedGloballyUntil) {
|
||||
return this._parseDate(pinnedGloballyUntil);
|
||||
},
|
||||
|
||||
@discourseComputed("pinDisabled")
|
||||
pinInCategoryValidation(pinDisabled) {
|
||||
if (pinDisabled) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("topic.feature_topic.pin_validation"),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("pinGloballyDisabled")
|
||||
pinGloballyValidation(pinGloballyDisabled) {
|
||||
if (pinGloballyDisabled) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("topic.feature_topic.pin_validation"),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_parseDate(date) {
|
||||
return moment(date, ["YYYY-MM-DD", "YYYY-MM-DD HH:mm"]);
|
||||
},
|
||||
|
||||
_isDateValid(parsedDate) {
|
||||
return parsedDate.isValid() && parsedDate > moment();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.set("loading", true);
|
||||
|
||||
return ajax("/topics/feature_stats.json", {
|
||||
data: { category_id: this.get("model.category.id") },
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setProperties({
|
||||
pinnedInCategoryCount: result.pinned_in_category_count,
|
||||
pinnedGloballyCount: result.pinned_globally_count,
|
||||
bannerCount: result.banner_count,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => this.set("loading", false));
|
||||
},
|
||||
|
||||
_forwardAction(name) {
|
||||
this.topicController.send(name);
|
||||
this.send("closeModal");
|
||||
},
|
||||
|
||||
_confirmBeforePinningGlobally() {
|
||||
const count = this.pinnedGloballyCount;
|
||||
|
||||
if (count < 4) {
|
||||
this._forwardAction("pinGlobally");
|
||||
} else {
|
||||
this.send("hideModal");
|
||||
this.dialog.yesNoConfirm({
|
||||
message: I18n.t("topic.feature_topic.confirm_pin_globally", { count }),
|
||||
didConfirm: () => this._forwardAction("pinGlobally"),
|
||||
didCancel: () => this.send("reopenModal"),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
pin() {
|
||||
if (this.pinDisabled) {
|
||||
this.set("pinInCategoryTipShownAt", Date.now());
|
||||
} else {
|
||||
this._forwardAction("togglePinned");
|
||||
}
|
||||
},
|
||||
|
||||
pinGlobally() {
|
||||
if (this.pinGloballyDisabled) {
|
||||
this.set("pinGloballyTipShownAt", Date.now());
|
||||
} else {
|
||||
this._confirmBeforePinningGlobally();
|
||||
}
|
||||
},
|
||||
|
||||
unpin() {
|
||||
this._forwardAction("togglePinned");
|
||||
},
|
||||
makeBanner() {
|
||||
this._forwardAction("makeBanner");
|
||||
},
|
||||
removeBanner() {
|
||||
this._forwardAction("removeBanner");
|
||||
},
|
||||
},
|
||||
});
|
@ -15,6 +15,7 @@ import PublishPageModal from "discourse/components/modal/publish-page";
|
||||
import EditSlowModeModal from "discourse/components/modal/edit-slow-mode";
|
||||
import ChangeTimestampModal from "discourse/components/modal/change-timestamp";
|
||||
import EditTopicTimerModal from "discourse/components/modal/edit-topic-timer";
|
||||
import FeatureTopicModal from "discourse/components/modal/feature-topic";
|
||||
|
||||
const SCROLL_DELAY = 500;
|
||||
|
||||
@ -154,11 +155,22 @@ const TopicRoute = DiscourseRoute.extend({
|
||||
|
||||
@action
|
||||
showFeatureTopic() {
|
||||
showModal("feature-topic", {
|
||||
model: this.modelFor("topic"),
|
||||
title: "topic.feature_topic.title",
|
||||
const topicController = this.controllerFor("topic");
|
||||
const model = this.modelFor("topic");
|
||||
model.setProperties({
|
||||
pinnedInCategoryUntil: null,
|
||||
pinnedGloballyUntil: null,
|
||||
});
|
||||
|
||||
this.modal.show(FeatureTopicModal, {
|
||||
model: {
|
||||
topic: model,
|
||||
pinGlobally: () => topicController.send("pinGlobally"),
|
||||
togglePinned: () => topicController.send("togglePinned"),
|
||||
makeBanner: () => topicController.send("makeBanner"),
|
||||
removeBanner: () => topicController.send("removeBanner"),
|
||||
},
|
||||
});
|
||||
this.controllerFor("feature_topic").reset();
|
||||
},
|
||||
|
||||
@action
|
||||
|
@ -18,7 +18,6 @@ const KNOWN_LEGACY_MODALS = [
|
||||
"create-account",
|
||||
"create-invite-bulk",
|
||||
"create-invite",
|
||||
"feature-topic",
|
||||
"flag",
|
||||
"grant-badge",
|
||||
"group-default-notifications",
|
||||
|
@ -1,213 +0,0 @@
|
||||
<DModalBody @class="feature-topic">
|
||||
{{#if this.model.pinned_at}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
{{#if this.model.pinned_globally}}
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{#if this.pinnedGloballyCount}}
|
||||
{{html-safe
|
||||
(i18n
|
||||
"topic.feature_topic.already_pinned_globally"
|
||||
count=this.pinnedGloballyCount
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{html-safe (i18n "topic.feature_topic.not_pinned_globally")}}
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>{{i18n "topic.feature_topic.global_pin_note"}}</p>
|
||||
{{else}}
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{html-safe this.alreadyPinnedMessage}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>{{i18n "topic.feature_topic.pin_note"}}</p>
|
||||
{{/if}}
|
||||
<p>{{html-safe this.unPinMessage}}</p>
|
||||
<p><DButton
|
||||
@action={{action "unpin"}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.unpin"
|
||||
@class="btn-primary"
|
||||
/></p>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
<p>
|
||||
<ConditionalLoadingSpinner @size="small" @condition={{this.loading}}>
|
||||
{{html-safe this.alreadyPinnedMessage}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.pin_note"}}
|
||||
</p>
|
||||
{{#if this.site.isMobileDevice}}
|
||||
<p>
|
||||
{{html-safe this.pinMessage}}
|
||||
</p>
|
||||
<p class="with-validation">
|
||||
<FutureDateInput
|
||||
@class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{this.model.pinnedInCategoryUntil}}
|
||||
@onChangeInput={{action (mut this.model.pinnedInCategoryUntil)}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinInCategoryValidation}}
|
||||
@shownAt={{this.pinInCategoryTipShownAt}}
|
||||
/>
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="with-validation">
|
||||
{{html-safe this.pinMessage}}
|
||||
<span>
|
||||
{{d-icon "far-clock"}}
|
||||
<FutureDateInput
|
||||
@class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{this.model.pinnedInCategoryUntil}}
|
||||
@onChangeInput={{action (mut this.model.pinnedInCategoryUntil)}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinInCategoryValidation}}
|
||||
@shownAt={{this.pinInCategoryTipShownAt}}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
{{/if}}
|
||||
<p>
|
||||
<DButton
|
||||
@action={{action "pin"}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.pin"
|
||||
@class="btn-primary"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.canPinGlobally}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
<p>
|
||||
<ConditionalLoadingSpinner
|
||||
@size="small"
|
||||
@condition={{this.loading}}
|
||||
>
|
||||
{{#if this.pinnedGloballyCount}}
|
||||
{{html-safe
|
||||
(i18n
|
||||
"topic.feature_topic.already_pinned_globally"
|
||||
count=this.pinnedGloballyCount
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{html-safe (i18n "topic.feature_topic.not_pinned_globally")}}
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.global_pin_note"}}
|
||||
</p>
|
||||
{{#if this.site.isMobileDevice}}
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.pin_globally"}}
|
||||
</p>
|
||||
<p class="with-validation">
|
||||
<FutureDateInput
|
||||
@class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{this.model.pinnedGloballyUntil}}
|
||||
@onChangeInput={{action (mut this.model.pinnedGloballyUntil)}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinGloballyValidation}}
|
||||
@shownAt={{this.pinGloballyTipShownAt}}
|
||||
/>
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="with-validation">
|
||||
{{i18n "topic.feature_topic.pin_globally"}}
|
||||
<span>
|
||||
{{d-icon "far-clock"}}
|
||||
<FutureDateInput
|
||||
@class="pin-until"
|
||||
@clearable={{true}}
|
||||
@input={{this.model.pinnedGloballyUntil}}
|
||||
@onChangeInput={{action (mut this.model.pinnedGloballyUntil)}}
|
||||
/>
|
||||
<PopupInputTip
|
||||
@validation={{this.pinGloballyValidation}}
|
||||
@shownAt={{this.pinGloballyTipShownAt}}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
{{/if}}
|
||||
<p>
|
||||
<DButton
|
||||
@action={{action "pinGlobally"}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.pin_globally"
|
||||
@class="btn-primary"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.currentUser.staff}}
|
||||
<div class="feature-section">
|
||||
<div class="desc">
|
||||
<p>
|
||||
<ConditionalLoadingSpinner @size="small" @condition={{this.loading}}>
|
||||
{{#if this.bannerCount}}
|
||||
{{html-safe (i18n "topic.feature_topic.banner_exists")}}
|
||||
{{else}}
|
||||
{{html-safe (i18n "topic.feature_topic.no_banner_exists")}}
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</p>
|
||||
<p>
|
||||
{{i18n "topic.feature_topic.banner_note"}}
|
||||
</p>
|
||||
<p>
|
||||
{{#if this.model.isBanner}}
|
||||
{{i18n "topic.feature_topic.remove_banner"}}
|
||||
{{else}}
|
||||
{{i18n "topic.feature_topic.make_banner"}}
|
||||
{{/if}}
|
||||
</p>
|
||||
<p>
|
||||
{{#if this.model.isBanner}}
|
||||
<DButton
|
||||
@action={{action "removeBanner"}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.remove_banner"
|
||||
@class="btn-primary"
|
||||
/>
|
||||
{{else}}
|
||||
<DButton
|
||||
@action={{action "makeBanner"}}
|
||||
@icon="thumbtack"
|
||||
@label="topic.feature.make_banner"
|
||||
@class="btn-primary make-banner"
|
||||
/>
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</DModalBody>
|
||||
<div class="modal-footer">
|
||||
<DModalCancel @close={{route-action "closeModal"}} />
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user