DEV: Prepare modal implementation for Ember upgrade (#24564)
- Skip rendering DModalLegacy when running Ember 5 - Move named outlet inside the DModalLegacy component file - Exclude that DModalLegacy template from the build when running Ember 5 - Skip LegacySupport version of modal service when running Ember 5 - Add error popup for legacy modals when running Ember 5 Extracted from https://github.com/discourse/discourse/pull/21720. This is a no-op under our current Ember 3.28 version.
This commit is contained in:
parent
59bae95190
commit
056898c55f
|
@ -76,7 +76,7 @@
|
||||||
{{~this.flash.text~}}
|
{{~this.flash.text~}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{yield}}
|
{{outlet "modalBody"}}
|
||||||
|
|
||||||
{{#each this.errors as |error|}}
|
{{#each this.errors as |error|}}
|
||||||
<div class="alert alert-error">
|
<div class="alert alert-error">
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{! Legacy modals depend on this wrapper being in the DOM at all times. Eventually this will be dropped.
|
{{#if this.renderLegacy}}
|
||||||
For now, we mitigate the potential impact on things like tests by removing the `modal` and `d-modal` classes when inactive }}
|
|
||||||
<DModalLegacy
|
<DModalLegacy
|
||||||
@modalClass={{if
|
@modalClass={{if
|
||||||
this.modal.isLegacy
|
this.modal.isLegacy
|
||||||
|
@ -31,6 +30,5 @@ For now, we mitigate the potential impact on things like tests by removing the `
|
||||||
@hidden={{this.modal.hidden}}
|
@hidden={{this.modal.hidden}}
|
||||||
@errors={{this.modal.errors}}
|
@errors={{this.modal.errors}}
|
||||||
@closeModal={{this.closeModal}}
|
@closeModal={{this.closeModal}}
|
||||||
>
|
/>
|
||||||
{{outlet "modalBody"}}
|
{{/if}}
|
||||||
</DModalLegacy>
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { EMBER_MAJOR_VERSION } from "discourse/lib/ember-version";
|
||||||
|
|
||||||
export default class ModalContainer extends Component {
|
export default class ModalContainer extends Component {
|
||||||
@service modal;
|
@service modal;
|
||||||
|
@ -9,4 +10,8 @@ export default class ModalContainer extends Component {
|
||||||
closeModal(data) {
|
closeModal(data) {
|
||||||
this.modal.close(data);
|
this.modal.close(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get renderLegacy() {
|
||||||
|
return EMBER_MAJOR_VERSION < 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { VERSION } from "@ember/version";
|
||||||
|
|
||||||
|
const parts = VERSION.split(".");
|
||||||
|
|
||||||
|
export const EMBER_MAJOR_VERSION = parseInt(parts[0], 10);
|
|
@ -5,6 +5,7 @@ import Service, { inject as service } from "@ember/service";
|
||||||
import { dasherize } from "@ember/string";
|
import { dasherize } from "@ember/string";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
import { CLOSE_INITIATED_BY_MODAL_SHOW } from "discourse/components/d-modal";
|
import { CLOSE_INITIATED_BY_MODAL_SHOW } from "discourse/components/d-modal";
|
||||||
|
import { EMBER_MAJOR_VERSION } from "discourse/lib/ember-version";
|
||||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||||
import deprecated, {
|
import deprecated, {
|
||||||
withSilencedDeprecations,
|
withSilencedDeprecations,
|
||||||
|
@ -23,6 +24,8 @@ const LEGACY_OPTS = new Set([
|
||||||
|
|
||||||
@disableImplicitInjections
|
@disableImplicitInjections
|
||||||
class ModalService extends Service {
|
class ModalService extends Service {
|
||||||
|
@service dialog;
|
||||||
|
|
||||||
@tracked activeModal;
|
@tracked activeModal;
|
||||||
@tracked opts = {};
|
@tracked opts = {};
|
||||||
|
|
||||||
|
@ -43,6 +46,23 @@ class ModalService extends Service {
|
||||||
* @returns {Promise} A promise that resolves when the modal is closed, with any data passed to closeModal
|
* @returns {Promise} A promise that resolves when the modal is closed, with any data passed to closeModal
|
||||||
*/
|
*/
|
||||||
show(modal, opts) {
|
show(modal, opts) {
|
||||||
|
if (typeof modal === "string") {
|
||||||
|
this.dialog.alert(
|
||||||
|
`Error: the '${modal}' modal needs updating to work with the latest version of Discourse. See https://meta.discourse.org/t/268057.`
|
||||||
|
);
|
||||||
|
deprecated(
|
||||||
|
`Defining modals using a controller is no longer supported. Use the component-based API instead. (modal: ${modal})`,
|
||||||
|
{
|
||||||
|
id: "discourse.modal-controllers",
|
||||||
|
since: "3.1",
|
||||||
|
dropFrom: "3.2",
|
||||||
|
url: "https://meta.discourse.org/t/268057",
|
||||||
|
raiseError: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.close({ initiatedBy: CLOSE_INITIATED_BY_MODAL_SHOW });
|
this.close({ initiatedBy: CLOSE_INITIATED_BY_MODAL_SHOW });
|
||||||
|
|
||||||
let resolveShowPromise;
|
let resolveShowPromise;
|
||||||
|
@ -50,7 +70,7 @@ class ModalService extends Service {
|
||||||
resolveShowPromise = resolve;
|
resolveShowPromise = resolve;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.opts = opts || {};
|
this.opts = opts ??= {};
|
||||||
this.activeModal = { component: modal, opts, resolveShowPromise };
|
this.activeModal = { component: modal, opts, resolveShowPromise };
|
||||||
|
|
||||||
const unsupportedOpts = Object.keys(opts).filter((key) =>
|
const unsupportedOpts = Object.keys(opts).filter((key) =>
|
||||||
|
@ -75,7 +95,7 @@ class ModalService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all logic below when legacy modals are dropped (deprecation: discourse.modal-controllers)
|
// Remove all logic below when legacy modals are dropped (deprecation: discourse.modal-controllers)
|
||||||
export default class ModalServiceWithLegacySupport extends ModalService {
|
class ModalServiceWithLegacySupport extends ModalService {
|
||||||
@service appEvents;
|
@service appEvents;
|
||||||
|
|
||||||
@tracked name;
|
@tracked name;
|
||||||
|
@ -261,3 +281,7 @@ export default class ModalServiceWithLegacySupport extends ModalService {
|
||||||
return this.name && !this.activeModal;
|
return this.name && !this.activeModal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default EMBER_MAJOR_VERSION >= 4
|
||||||
|
? ModalService
|
||||||
|
: ModalServiceWithLegacySupport;
|
||||||
|
|
|
@ -17,8 +17,25 @@ const { StatsWriterPlugin } = require("webpack-stats-plugin");
|
||||||
const withSideWatch = require("./lib/with-side-watch");
|
const withSideWatch = require("./lib/with-side-watch");
|
||||||
const RawHandlebarsCompiler = require("discourse-hbr/raw-handlebars-compiler");
|
const RawHandlebarsCompiler = require("discourse-hbr/raw-handlebars-compiler");
|
||||||
|
|
||||||
|
const EMBER_MAJOR_VERSION = parseInt(
|
||||||
|
require("ember-source/package.json").version.split(".")[0],
|
||||||
|
10
|
||||||
|
);
|
||||||
|
|
||||||
process.env.BROCCOLI_ENABLED_MEMOIZE = true;
|
process.env.BROCCOLI_ENABLED_MEMOIZE = true;
|
||||||
|
|
||||||
|
function filterForEmberVersion(tree) {
|
||||||
|
if (EMBER_MAJOR_VERSION < 4) {
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
return funnel(tree, {
|
||||||
|
// d-modal-legacy includes a named outlet which would cause
|
||||||
|
// a build failure in modern Ember
|
||||||
|
exclude: ["**/components/d-modal-legacy.hbs"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function (defaults) {
|
module.exports = function (defaults) {
|
||||||
const discourseRoot = path.resolve("../../../..");
|
const discourseRoot = path.resolve("../../../..");
|
||||||
const vendorJs = discourseRoot + "/vendor/assets/javascripts/";
|
const vendorJs = discourseRoot + "/vendor/assets/javascripts/";
|
||||||
|
@ -74,8 +91,10 @@ module.exports = function (defaults) {
|
||||||
},
|
},
|
||||||
|
|
||||||
trees: {
|
trees: {
|
||||||
app: RawHandlebarsCompiler(
|
app: filterForEmberVersion(
|
||||||
|
RawHandlebarsCompiler(
|
||||||
withSideWatch("app", { watching: ["../discourse-markdown-it"] })
|
withSideWatch("app", { watching: ["../discourse-markdown-it"] })
|
||||||
|
)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue