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" + }}

+ +
+
+ + +
+ +
+ + +

+ + {{i18n "topic.publish_page.public_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" - }}

- -
-
- - -
- -
- - -

- - {{i18n "topic.publish_page.public_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