خطأ في استيراد مكون Plugin Modal - اتبعت الوثائق الرسمية ولكن ما زلت أحصل على أخطاء

Problem Summary

I’m developing a Discourse plugin that adds a toolbar button to open a modal form. I’ve followed the official DModal API migration documentation step-by-step, but I’m still getting module import errors and the “modal needs updating” warning. Need guidance on what I’m missing.

A quick note: I don’t know how to program, this plugin was created entirely with the help of AI.

Current Errors

Error 1 - Module Import:

Uncaught (in promise) Error: Could not find module `discourse/components/modal/lottery-form-modal` imported from `discourse/plugins/discourse-lottery-v3/discourse/initializers/lottery-toolbar`

Error 2 - Legacy Modal Warning:

Error: the 'lottery-form' modal needs updating to work with the latest version of Discourse. See https://meta.discourse.org/t/268057.

Error 3 - Deprecation Notice:

Deprecation notice: Defining modals using a controller is no longer supported. Use the component-based API instead. (modal: lottery-form) [deprecated since Discourse 3.1] [removal in Discourse 3.2]

Official Documentation I’ve Followed

I’ve carefully studied and implemented based on these official resources:

  1. Converting modals from legacy controllers to new DModal component API

    • URL: https://meta.discourse.org/t/268057
    • Followed all 4 steps: moved files to /components/modal/, updated JS to extend Component, updated template to use <DModal>, updated show calls to use modal.show()
  2. Using the DModal API to render Modal windows

    • URL: https://meta.discourse.org/t/268304
    • Implemented DModal with proper @closeModal, @title, and named blocks
  3. Discourse Core Plugin API

    • Source: https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/lib/plugin-api.gjs
    • Used api.onToolbarCreate() and modal service injection
  4. Discourse Developer Docs - Converting Modals

    • URL: https://github.com/discourse/discourse-developer-docs/blob/main/docs/03-code-internals/10-converting-modals.md
    • Cross-referenced migration steps

What I’m Trying to Do

  • Add a toolbar button in the composer
  • Click button opens a modal form
  • User fills form and clicks submit
  • Modal closes and inserts content into composer

What I’ve Tried

Approach 1: Dynamic Import + Modal Service (Current)

  • Getting module import error

Approach 2: showModal() with Controller

  • Getting deprecation warnings about legacy controllers

Approach 3: Static Import

  • Also tried static imports but same module resolution issues

File structure:

discourse-lottery-v3/
├── plugin.rb
└── assets/javascripts/discourse/
    ├── initializers/
    │   └── lottery-toolbar.js
    └── components/modal/
        ├── lottery-form-modal.js
        └── lottery-form-modal.hbs

Toolbar button code:

// assets/javascripts/discourse/initializers/lottery-toolbar.js
import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "lottery-toolbar",
  initialize() {
    withPluginApi("1.0.0", (api) => {
      api.onToolbarCreate((toolbar) => {
        toolbar.addButton({
          id: "lottery-insert",
          group: "extras",
          icon: "dice",
          title: "Insert Lottery",
          perform: () => {
            const modal = api.container.lookup("service:modal");

            // This line causes the import error:
            import("discourse/components/modal/lottery-form-modal").then((module) => {
              const LotteryFormModal = module.default;
              modal.show(LotteryFormModal, { model: {} });
            });
          }
        });
      });
    });
  }
};

Modal component:

// assets/javascripts/discourse/components/modal/lottery-form-modal.js
import Component from "@ember/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";

export default class LotteryFormModal extends Component {
  @tracked inputValue = "";

  @action
  submit() {
    // Handle form submission
    this.args.closeModal();
  }
}

Modal template:

{{! assets/javascripts/discourse/components/modal/lottery-form-modal.hbs }}
<DModal @title="My Modal" @closeModal={{this.args.closeModal}} class="my-modal">
  <:body>
    <input value={{this.inputValue}} />
  </:body>
  <:footer>
    <button {{on "click" this.submit}}>Submit</button>
  </:footer>
</DModal>

Questions

Based on all the code, errors, and background information provided above, how should I modify my code to correctly implement my feature?

Any guidance on the correct implementation approach would be greatly appreciated

Try importing it from ../components/modal/lottery-form-modal instead.

When you start your import with discourse, it will look for the file and directory in the Discourse codebase, not your own project.

For example, your line:

imports this from app/assets/javascripts/discourse/app/lib/plugin-api.gjs in the Discourse codebase.

As an example on how you could do this, see @abroun_beholder’s GitHub - Beholder-Vision/discourse-insert-model-3d: A Discourse theme component for adding 3D models to topics.

Thank you! That explanation about the import paths was exactly what I needed. The modal is working perfectly now. Really appreciate your help!

إعجابَين (2)

No problem, happy to help!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.