コンポーネントのjsがコンパイルできない SyntaxError: Private field must be used in an enclosing class

最終的に、Discourse Central テーマのトピックリスト本文に新しいトピックボタンが必要です。すべてのエンジニアが、各カテゴリ内のトピックリストの最下部にある「新しい会話を開始」ボタンを気に入らないと不満を言っています。上部の「新しいトピック」メニュー選択肢を使いたくないのは、現在いるカテゴリでトピックが開始されないためです。

これは Llama 3.1 405B および ask.discourse.com 経由の GPT-4 で試しましたが、コンパイルできる JavaScript のバージョンが得られません。常に「コンパイルエラー: SyntaxError: プライベートフィールドは囲むクラスで使用する必要があります」というエラーが発生します。

カスタムウィジェットが JS コンパイルエラーのために作成されないため、ウィジェットレジストリエラーも発生します。

Discourse Central テーマを使用しています。

このヘッダーセクションを与えられた場合:
"<script type=\"text/discourse-plugin\" version=\"0.8.18\">
  api.createWidget('custom-new-topic-button', {
    tagName: 'div.custom-new-topic-button',

    buildKey: () => `custom-new-topic-button`,

    html() {
      return [
        this.attach('button', {
          className: 'btn btn-primary',
          action: 'createNewTopic',
          contents: 'New Topic'
        })
      ];
    },

    click() {
      const composerController = this.container.lookup("controller:composer");
      const currentCategory = this.container.lookup("controller:navigation/category").get("model.id");

      composerController.open({
        action: require("discourse/models/composer").default.CREATE_TOPIC,
        draftKey: require("discourse/models/composer").default.DRAFT,
        categoryId: currentCategory,
      });

      return false;
    },
  });

  api.decorateWidget('topic-list:before', (helper) => {
    if (api.getCurrentUser()) {
      helper.appendChild(helper.createWidget('custom-new-topic-button'));
    }
  });

</script>"

このヘッダーセクションで:

<script>
    {{#if currentUser}}
     <div class="topic-list-body-new-topic">
      {{custom-new-topic-button}}
     </div>
   {{/if}}
</script>

そしてこのCSS:

.topic-list-body::before {
    content: "";
    display: block;
    position: relative; /* Important to allow absolute positioning within */
  }

  .topic-list-body-new-topic {
    position: absolute;
    top: 0;
    left: 0;
    padding: 10px;
    background: #f2f3f5;
    border-bottom: 1px solid #ccc;
  }
  .custom-new-topic-button .btn.btn-primary {
    background-color: #007bff;
    border-color: #007bff;
    color: #fff;
  }

これが私の元のコードでした。最新の推奨事項は次のとおりです。

<script type="text/discourse-plugin" version="0.8.18">
  api.createWidget('custom-new-topic-button', {
    tagName: 'div.custom-new-topic-button',

    buildKey() {
      return 'custom-new-topic-button';
    },

    defaultState() {
      return {};
    },

    html() {
      return [
        this.attach('button', {
          className: 'btn btn-primary',
          action: 'createNewTopic',
          contents: 'New Topic'
        })
      ];
    },

    createNewTopic() {
      const composerController = this.container.lookup("controller:composer");
      const currentCategory = this.container.lookup("controller:navigation/category").get("model.id");
      const Composer = require("discourse/models/composer").default;

      composerController.open({
        action: Composer.CREATE_TOPIC,
        draftKey: Composer.DRAFT,
        categoryId: currentCategory,
      });

      return false;
    },
  });

  api.decorateWidget('topic-list:before', (helper) => {
    if (api.getCurrentUser()) {
      helper.appendChild(helper.createWidget('custom-new-topic-button'));
    }
  });
</script>

@steven.webster @vasanth.mohan

うまくいきました。@sam、毎日の呼び出しを使い果たしてしまいました…すみません。そして、LLAMA 405 B に駆け寄り、あれこれ試行錯誤した結果、動作するコードを入手しました。これがどれだけ費用がかかったか想像もできません。フォーラムの他の人から「おい、バカ、この設定はここにあったぞ」と連絡が来るかもしれませんが、これは動作するコードを得るための継続的なプロンプト改訂の楽しい演習でした。

いくつか重要な点は、(これらのいくつかは不正確かもしれませんが、私は合計で2日間しか JavaScript 開発者および Discourse 開発者ではありませんでした)

これは Discourse によってホストされているフォーラムであり、OS へのアクセス権はありません。
これはプラグインなので、Discourse を直接参照することはできません。
Ember を直接参照することはできません。
これを使用する場合は、必ず self にバインドしてください。

そして、望む機能特性に入ります。

<script type="text/discourse-plugin" version="1.24.0">
  api.modifyClass('component:topic-list', {
    pluginId: 'your-plugin-id',

    didRender: function() {
      const category = this.get('category');
      if (!category) {
        console.error('Category not found');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Current user not found');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Can create topic not defined');
        return;
      }

      console.log('category:', category);
      console.log('canCreateTopic:', canCreateTopic);

      if (category && canCreateTopic) {
        const topicListBody = document.querySelector('.topic-list-body');
        const listContainer = document.querySelector('.list-container');
        const topicList = document.querySelector('.topic-list');

        let container = topicListBody || listContainer || topicList;

        if (!container) {
          container = this.element; // Use the component's element as the container
        }

        console.log('container:', container);

        const existingButton = container.querySelector('.new-topic-button');
        if (!existingButton) {
          const newTopicButton = document.createElement('a');
          newTopicButton.href = '#';
          newTopicButton.className = 'new-topic-button';
          newTopicButton.setAttribute('data-category-id', category.id);
          newTopicButton.textContent = 'New Topic';

          const self = this; // Store the component's context
          newTopicButton.onclick = (e) => {
            e.preventDefault();
            const router = api.container.lookup('router:main');
            const url = router.generate('new-topic', { queryParams: { category: category.slug } });
            router.transitionTo(url);
          };


          container.prepend(newTopicButton);
          console.log('button added');
        }
      }
    }
  });
</script>

早計でした。そのバージョンには、最初のカテゴリ以外には何も投稿したがらない、厄介な didRender の問題がありました。llama に修正してもらいました。

<script type="text/discourse-plugin" version="1.24.0">
  api.modifyClass('component:topic-list', {
    pluginId: 'your-plugin-id',

    didRender: function() {
      const category = this.get('category');
      if (!category) {
        console.error('Category not found');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Current user not found');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Can create topic not defined');
        return;
      }

      console.log('category:', category);
      console.log('canCreateTopic:', canCreateTopic);

      if (category && canCreateTopic) {
        const topicListBody = document.querySelector('.topic-list-body');
        const listContainer = document.querySelector('.list-container');
        const topicList = document.querySelector('.topic-list');

        let container = topicListBody || listContainer || topicList;

        if (!container) {
          container = this.element; // Use the component's element as the container
        }

        console.log('container:', container);

        let newTopicButton = container.querySelector('.new-topic-button');
        if (!newTopicButton) {
          newTopicButton = document.createElement('a');
          newTopicButton.href = '#';
          newTopicButton.className = 'new-topic-button';
          container.prepend(newTopicButton);
          console.log('button added');
        }

        newTopicButton.setAttribute('data-category-id', category.id);
        newTopicButton.textContent = 'New Topic';

        const self = this; // Store the component's context
        newTopicButton.onclick = (e) => {
          e.preventDefault();
          const router = api.container.lookup('router:main');
          const url = router.generate('new-topic', { queryParams: { category: category.slug } });
          router.transitionTo(url);
        };
      }
    }
  });
</script>

問題は解決したようですね。私もヘルプを求めるリクエストを作成する際によくそうします。

New Topic Header Button - #67 by patrickemin に例があり、まさに探しているものかもしれません。

また、エンジニアにメッセージを作成するには「c」キーを押すと伝えられます。

「いいね!」 3

Centralでは、新しい会話を開始するボタンがトピックリストの下部にあります。誰もが上部にボタンを配置することを望んでいました。小さなプラス記号に変更するかもしれませんが、これらの2つのスクリーンショットがそれを示しています。


「いいね!」 1

@pfaffman 新しいトピックヘッダーボタンを最初に試しましたが、新しいDiscourse Centralテーマとはうまく連携しませんでした。

ウィジェットは廃止されます。ウィジェットAPIの使用は推奨されません。

Glimmerコンポーネントを使用してください。

「いいね!」 2

AI ragsからも古いコンテンツを削除する必要があり、ウィジェットモデルのファインチューニングを待つ必要があります。ask.discourse.comでさえウィジェットのルートに進みました。ウィジェットに取って代わるものは何でしょうか?それを考慮したコードをモデルに生成させることができるか見てみます。ちなみに、私のエクササイズの大部分は、jsについてほとんど何も知らないので、モデルにこの作業をさせることができるかどうかを確認することです。 :slight_smile:

その気持ちはわかります。

Glimmerコンポーネントです。それらを説明する適切なトピックがどこかにあります。

しかし、コンポーネントを作成する例を次に示します。

そして、それを挿入するJavaScriptの方法を次に示します。

それを挿入するもう1つの方法は、コネクタを作成してコンポーネントを挿入するという、時代遅れになりつつある方法ですが、イニシャライザの方法の利点は、イニシャライザに目的のプラグインアウトレットを渡すことができるため、表示場所を変更する設定を持つことができることです。

時々(たとえばログインしている場合など)表示したい場合は、shouldDisplay(またはそれに類するもの)を呼び出す例を探す必要があると思います。

「いいね!」 4

昨夜llamaに生成させた最終コードはウィジェットを使用していませんでしたが、glimmerも使用していませんでした。後でglimmerをいじってみます。

<script type="text/discourse-plugin" version="1.24.0">
  api.modifyClass('component:topic-list', {
    pluginId: 'your-plugin-id',

    didRender: function() {
      const category = this.get('category');
      if (!category) {
        console.error('Category not found');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Current user not found');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Can create topic not defined');
        return;
      }

      console.log('category:', category);
      console.log('canCreateTopic:', canCreateTopic);

      if (category && canCreateTopic) {
        const topicListBody = document.querySelector('.topic-list-body');
        const listContainer = document.querySelector('.list-container');
        const topicList = document.querySelector('.topic-list');

        let container = topicListBody || listContainer || topicList;

        if (!container) {
          container = this.element; // Use the component's element as the container
        }

        console.log('container:', container);

        let newTopicButton = container.querySelector('.new-topic-button');
        if (!newTopicButton) {
          newTopicButton = document.createElement('a');
          newTopicButton.href = '#';
          newTopicButton.className = 'new-topic-button';
          container.prepend(newTopicButton);
          console.log('button added');
        }

        newTopicButton.setAttribute('data-category-id', category.id);
        newTopicButton.textContent = 'New Topic';

        const self = this; // Store the component's context
        newTopicButton.onclick = (e) => {
          e.preventDefault();
          const router = api.container.lookup('router:main');
          const url = router.generate('new-topic', { queryParams: { category: category.slug } });
          router.transitionTo(url);
        };
      }
    }
  });

</script>

注意: トピックリストは現在Glimmerに変換されていません。

ただし、コンポーネントをプラグインのアウトレットにアタッチする場合は、Glimmerを使用する必要があります。

ウィジェットにアタッチする必要がある場合は、RenderGlimmerを使用してそれを実現できます。

例はこちら:

LLMに過度に依存せず、まず自分で基本を学ぶことを強くお勧めします。LLMが出力するものの最終的なQAはあなた自身が行う必要があるからです。

また、ソリューションを正しくアーキテクトする必要があります。

EmberJSの詳細はこちらをご覧ください:

「いいね!」 3

ありがとうございます。ディスコースとJSは全くの初心者なので、もっと勉強します。

AI企業で働いているので、これはプロンプトエンジニアリングの演習でもありました。

「いいね!」 3

それで、彼らの強みと弱みの両方をよく理解できるでしょう。

私は、Discourse 用の最初の AI ボットである Chatbot を書いたので、私にもいくつかの洞察があります。

「いいね!」 2

システムプロンプトに特別なガイダンスを追加し、「ask」がウィジェットの使用を推奨しないようにします。

「いいね!」 5