diff --git a/app/assets/javascripts/discourse/app/components/modal/publish-page.hbs b/app/assets/javascripts/discourse/app/components/modal/publish-page.hbs
new file mode 100644
index 00000000000..1ca0c842e39
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/modal/publish-page.hbs
@@ -0,0 +1,105 @@
+
+ <:body>
+ {{#if this.unpublished}}
+ {{i18n "topic.publish_page.unpublished"}}
+ {{else}}
+
+ {{i18n
+ "topic.publish_page.description"
+ }}
+
+
+
+
+
+
+ {{#if this.existing}}
+
+ {{i18n "topic.publish_page.publish_url"}}
+
+
+ {{else}}
+ {{#if this.showUrl}}
+
+ {{i18n "topic.publish_page.preview_url"}}
+
{{this.publishedPage.url}}
+
+ {{/if}}
+
+ {{#if this.invalid}}
+ {{i18n "topic.publish_page.invalid_slug"}}
+
{{this.reason}}.
+ {{/if}}
+ {{/if}}
+
+
+
+ {{/if}}
+
+ <:footer>
+ {{#if this.showUnpublish}}
+
+
+
+ {{else if this.unpublished}}
+
+ {{else}}
+
+ {{/if}}
+
+
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/modal/publish-page.js b/app/assets/javascripts/discourse/app/components/modal/publish-page.js
new file mode 100644
index 00000000000..0907b484ffc
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/modal/publish-page.js
@@ -0,0 +1,165 @@
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
+import { tracked } from "@glimmer/tracking";
+import Component from "@glimmer/component";
+import { ajax } from "discourse/lib/ajax";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+
+const States = {
+ initializing: "initializing",
+ checking: "checking",
+ valid: "valid",
+ invalid: "invalid",
+ saving: "saving",
+ new: "new",
+ existing: "existing",
+ unpublishing: "unpublishing",
+ unpublished: "unpublished",
+};
+
+export default class PublishPageModal extends Component {
+ @service store;
+
+ @tracked state = States.initializing;
+ @tracked reason = null;
+ @tracked publishedPage = null;
+
+ constructor() {
+ super(...arguments);
+ this.store
+ .find("published_page", this.args.model.id)
+ .then((page) => {
+ this.state = States.existing;
+ this.publishedPage = page;
+ })
+ .catch(this.startNew);
+ }
+
+ get initializing() {
+ return this.state === States.initializing;
+ }
+
+ get checking() {
+ return this.state === States.checking;
+ }
+
+ get valid() {
+ return this.state === States.valid;
+ }
+
+ get invalid() {
+ return this.state === States.invalid;
+ }
+
+ get saving() {
+ return this.state === States.saving;
+ }
+
+ get new() {
+ return this.state === States.new;
+ }
+
+ get existing() {
+ return this.state === States.existing;
+ }
+
+ get unpublishing() {
+ return this.state === States.unpublishing;
+ }
+
+ get unpublished() {
+ return this.state === States.unpublished;
+ }
+
+ get disabled() {
+ return this.state !== States.valid;
+ }
+
+ get showUrl() {
+ return (
+ this.state === States.valid ||
+ this.state === States.saving ||
+ this.state === States.existing
+ );
+ }
+
+ get showUnpublish() {
+ return this.state === States.existing || this.state === States.unpublishing;
+ }
+
+ @action
+ startCheckSlug() {
+ if (this.state === States.existing) {
+ return;
+ }
+
+ this.state = States.checking;
+ }
+
+ @action
+ checkSlug() {
+ if (this.state === States.existing) {
+ return;
+ }
+ return ajax("/pub/check-slug", {
+ data: { slug: this.publishedPage.slug },
+ }).then((result) => {
+ if (result.valid_slug) {
+ this.state = States.valid;
+ } else {
+ this.state = States.invalid;
+ this.reason = result.reason;
+ }
+ });
+ }
+
+ @action
+ unpublish() {
+ this.state = States.unpublishing;
+ return this.publishedPage
+ .destroyRecord()
+ .then(() => {
+ this.state = States.unpublished;
+ this.args.model.set("publishedPage", null);
+ })
+ .catch((result) => {
+ this.state = States.existing;
+ popupAjaxError(result);
+ });
+ }
+
+ @action
+ publish() {
+ this.state = States.saving;
+
+ return this.publishedPage
+ .update(this.publishedPage.getProperties("slug", "public"))
+ .then(() => {
+ this.state = States.existing;
+ this.args.model.set("publishedPage", this.publishedPage);
+ })
+ .catch((errResult) => {
+ popupAjaxError(errResult);
+ this.state = States.existing;
+ });
+ }
+
+ @action
+ startNew() {
+ this.state = States.new;
+ this.publishedPage = this.store.createRecord(
+ "published_page",
+ this.args.model.getProperties("id", "slug", "public")
+ );
+ this.checkSlug();
+ }
+
+ @action
+ onChangePublic(event) {
+ this.publishedPage.set("public", event.target.checked);
+
+ if (this.showUnpublish) {
+ this.publish();
+ }
+ }
+}
diff --git a/app/assets/javascripts/discourse/app/controllers/publish-page.js b/app/assets/javascripts/discourse/app/controllers/publish-page.js
deleted file mode 100644
index f237944de4b..00000000000
--- a/app/assets/javascripts/discourse/app/controllers/publish-page.js
+++ /dev/null
@@ -1,130 +0,0 @@
-import { action, computed } from "@ember/object";
-import { equal, not } from "@ember/object/computed";
-import Controller from "@ember/controller";
-import ModalFunctionality from "discourse/mixins/modal-functionality";
-import { ajax } from "discourse/lib/ajax";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-
-const States = {
- initializing: "initializing",
- checking: "checking",
- valid: "valid",
- invalid: "invalid",
- saving: "saving",
- new: "new",
- existing: "existing",
- unpublishing: "unpublishing",
- unpublished: "unpublished",
-};
-
-const StateHelpers = {};
-Object.keys(States).forEach((name) => {
- StateHelpers[name] = equal("state", name);
-});
-
-export default Controller.extend(ModalFunctionality, StateHelpers, {
- state: null,
- reason: null,
- publishedPage: null,
- disabled: not("valid"),
-
- showUrl: computed("state", function () {
- return (
- this.state === States.valid ||
- this.state === States.saving ||
- this.state === States.existing
- );
- }),
-
- showUnpublish: computed("state", function () {
- return this.state === States.existing || this.state === States.unpublishing;
- }),
-
- onShow() {
- this.set("state", States.initializing);
-
- this.store
- .find("published_page", this.model.id)
- .then((page) => {
- this.setProperties({ state: States.existing, publishedPage: page });
- })
- .catch(this.startNew);
- },
-
- @action
- startCheckSlug() {
- if (this.state === States.existing) {
- return;
- }
-
- this.set("state", States.checking);
- },
-
- @action
- checkSlug() {
- if (this.state === States.existing) {
- return;
- }
- return ajax("/pub/check-slug", {
- data: { slug: this.publishedPage.slug },
- }).then((result) => {
- if (result.valid_slug) {
- this.set("state", States.valid);
- } else {
- this.setProperties({ state: States.invalid, reason: result.reason });
- }
- });
- },
-
- @action
- unpublish() {
- this.set("state", States.unpublishing);
- return this.publishedPage
- .destroyRecord()
- .then(() => {
- this.set("state", States.unpublished);
- this.model.set("publishedPage", null);
- })
- .catch((result) => {
- this.set("state", States.existing);
- popupAjaxError(result);
- });
- },
-
- @action
- publish() {
- this.set("state", States.saving);
-
- return this.publishedPage
- .update(this.publishedPage.getProperties("slug", "public"))
- .then(() => {
- this.set("state", States.existing);
- this.model.set("publishedPage", this.publishedPage);
- })
- .catch((errResult) => {
- popupAjaxError(errResult);
- this.set("state", States.existing);
- });
- },
-
- @action
- startNew() {
- this.setProperties({
- state: States.new,
- publishedPage: this.store.createRecord(
- "published_page",
- this.model.getProperties("id", "slug", "public")
- ),
- });
- this.checkSlug();
- },
-
- @action
- onChangePublic(isPublic) {
- this.publishedPage.set("public", isPublic);
-
- if (this.showUnpublish) {
- this.publish();
- }
- },
-});
diff --git a/app/assets/javascripts/discourse/app/routes/topic.js b/app/assets/javascripts/discourse/app/routes/topic.js
index ac37d4aaba3..8743d764655 100644
--- a/app/assets/javascripts/discourse/app/routes/topic.js
+++ b/app/assets/javascripts/discourse/app/routes/topic.js
@@ -11,6 +11,7 @@ import showModal from "discourse/lib/show-modal";
import TopicFlag from "discourse/lib/flag-targets/topic-flag";
import PostFlag from "discourse/lib/flag-targets/post-flag";
import HistoryModal from "discourse/components/modal/history";
+import PublishPageModal from "discourse/components/modal/publish-page";
const SCROLL_DELAY = 500;
@@ -112,9 +113,8 @@ const TopicRoute = DiscourseRoute.extend({
@action
showPagePublish() {
const model = this.modelFor("topic");
- showModal("publish-page", {
+ this.modal.show(PublishPageModal, {
model,
- title: "topic.publish_page.title",
});
},
diff --git a/app/assets/javascripts/discourse/app/templates/modal/publish-page.hbs b/app/assets/javascripts/discourse/app/templates/modal/publish-page.hbs
deleted file mode 100644
index a2608b31a96..00000000000
--- a/app/assets/javascripts/discourse/app/templates/modal/publish-page.hbs
+++ /dev/null
@@ -1,100 +0,0 @@
-
- {{#if this.unpublished}}
- {{i18n "topic.publish_page.unpublished"}}
- {{else}}
-
- {{i18n
- "topic.publish_page.description"
- }}
-
-
-
-
-
-
- {{#if this.existing}}
-
- {{i18n "topic.publish_page.publish_url"}}
-
-
- {{else}}
- {{#if this.showUrl}}
-
- {{i18n "topic.publish_page.preview_url"}}
-
{{this.publishedPage.url}}
-
- {{/if}}
-
- {{#if this.invalid}}
- {{i18n "topic.publish_page.invalid_slug"}}
-
{{this.reason}}.
- {{/if}}
- {{/if}}
-
-
-
- {{/if}}
-
-
-
\ No newline at end of file