Kann das JS in meiner Komponente nicht kompilieren: SyntaxError: Private Felder müssen in einer umschließenden Klasse verwendet werden

Am Ende des Tages benötige ich einen neuen Button für das Thema im Hauptbereich der Themenliste im Discourse Central Theme. Jeder Ingenieur beschwert sich, dass ihm der Button “Neue Konversation starten” nur am Ende der Themenliste innerhalb jeder Kategorie nicht gefällt. Sie möchten nicht die Option “Neues Thema” oben verwenden, da dies das Thema nicht in der Kategorie startet, in der sie sich gerade befinden.

Ich habe dies sowohl mit Llama 3.1 405B als auch mit GPT-4 über ask.discourse.com ausprobiert, konnte aber keine JavaScript-Version erhalten, die kompiliert. Ich erhalte ständig den Kompilierungsfehler: SyntaxError: Private field must be used in an enclosing class.

Ich erhalte auch einen Widget-Registrierungsfehler, aber das liegt daran, dass das benutzerdefinierte Widget aufgrund des JS-Kompilierungsfehlers nie erstellt wird.

Ich verwende das Discourse Central Theme.

Mit diesem Header-Abschnitt:
"<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>"

Mit diesem Kopfbereich:

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

Und diesem 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;
  }

Das war mein ursprünglicher Code, die neueste Empfehlung ist:

<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

Ich habe es zum Laufen gebracht. @sam Ich habe meine täglichen Anrufe erschöpft, um zu fragen … entschuldige das. Und dann bin ich zu unserem LLAMA 405 B gerannt und nach viel Hin und Her habe ich funktionierenden Code erhalten. Ich kann mir nicht vorstellen, wie viel Geld mich das gekostet hätte. Ich höre vielleicht von anderen Leuten im Forum, hey Idiot, es gab eine Einstellung, um das hier zu tun. Aber das war eine unterhaltsame Übung der kontinuierlichen Überarbeitung von Prompts, um funktionierenden Code zu erhalten.

Einige der Schlüssel sind (beachten Sie, dass einige davon ungenau sein können, da ich insgesamt nur zwei Tage lang JavaScript-Entwickler und Discourse-Entwickler war):

Dies ist ein Forum, das von Discourse gehostet wird, und ich habe keinen OS-Zugriff.
Dies ist ein Plugin, daher können Sie Discourse nicht direkt referenzieren.
Sie können Ember nicht direkt referenzieren.
Wenn Sie dies verwenden möchten, stellen Sie sicher, dass Sie es an self binden.

Und dann gehen Sie zu den gewünschten funktionalen Merkmalen.

<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('Kategorie nicht gefunden');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Aktueller Benutzer nicht gefunden');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Kann Thema nicht erstellen, nicht definiert');
        return;
      }

      console.log('Kategorie:', category);
      console.log('Kann Thema erstellen:', 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; // Verwenden Sie das Element der Komponente als 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 = 'Neues Thema';

          const self = this; // Speichern Sie den Kontext der Komponente
          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('Schaltfläche hinzugefügt');
        }
      }
    }
  });
</script>

Ich habe zu früh gesprochen, diese Version hatte ein hartnäckiges didRender-Problem, bei dem sie sich nicht in andere Kategorien als die erste einfügen wollte. Llama hat das behoben.

<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('Kategorie nicht gefunden');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Aktueller Benutzer nicht gefunden');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Kann Thema erstellen nicht definiert');
        return;
      }

      console.log('Kategorie:', category);
      console.log('Kann Thema erstellen:', 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; // Verwenden Sie das Element der Komponente als 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 hinzugefügt');
        }

        newTopicButton.setAttribute('data-category-id', category.id);
        newTopicButton.textContent = 'Neues Thema';

        const self = this; // Speichern Sie den Kontext der Komponente
        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>

Es scheint, als hätten Sie Ihr Problem gelöst, so wie ich es oft tue, wenn ich um Hilfe bitte.

New Topic Header Button - #67 by patrickemin wäre ein Beispiel und vielleicht genau das, wonach Sie suchen.

Sagen Sie Ihren Ingenieuren auch, dass sie die Taste c drücken können, um eine Nachricht zu verfassen.

3 „Gefällt mir“

In Central befindet sich die Schaltfläche zum Starten einer neuen Unterhaltung am Ende der Themenliste. Jeder wünschte sich eine Schaltfläche oben. Ich werde sie vielleicht in ein kleines Pluszeichen ändern, aber diese beiden Screenshots zeigen sie.


1 „Gefällt mir“

@pfaffman Ich habe die neue Themenüberschriften-Schaltfläche als ersten Versuch ausprobiert. Dies funktioniert jedoch nicht gut mit dem neuen Discourse Central-Theme.

Widgets werden abgeschafft. Es ist keine gute Idee, die Widget-API zu verwenden.

Verwenden Sie Glimmer-Komponenten.

2 „Gefällt mir“

Wir müssen dann auch eine Menge alter Inhalte aus KI-Fetzen entfernen und darauf warten, dass die Post-Widget-Modelle fein abgestimmt werden. Sogar ask.discourse.com drängte in Richtung des Widget-Ansatzes. Was wird Widgets ersetzen? Ich werde sehen, ob ich ein Modell dazu bringen kann, Code auszugeben, der dies berücksichtigt. Übrigens besteht der Großteil meiner Übung darin, zu sehen, ob ich ein Modell dazu bringen kann, diese Arbeit zu erledigen, da ich so gut wie nichts über JS weiß :slight_smile:

Ich kenne das Gefühl.

Glimmer-Komponenten. Irgendwo gibt es ein gutes Thema, das sie beschreibt.

Hier ist jedoch ein Beispiel für die Erstellung der Komponente:

Und hier ist eine JavaScript-Methode, um sie einzufügen:

Der andere Weg, sie einzufügen, ist der altmodische Weg, einen Connector zu erstellen, der dann die Komponente einfügt, aber der Vorteil des Initializer-Weges ist, dass Sie dann den gewünschten Plugin-Outlet an den Initializer übergeben können, sodass Sie eine Einstellung haben, die ändert, wo sie angezeigt wird.

Ich denke, Sie möchten ein Beispiel für etwas finden, das shouldDisplay (oder etwas Ähnliches) aufruft, wenn Sie möchten, dass es nur manchmal angezeigt wird (z. B. wenn sie angemeldet sind).

4 „Gefällt mir“

OH mein letzter Code, den Llama gestern Abend ausgespuckt hat, hat keine Widgets verwendet, aber auch kein Glimmer. Ich werde mich später am Tag mit Glimmer beschäftigen.

<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('Kategorie nicht gefunden');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Aktueller Benutzer nicht gefunden');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Kann Thema nicht erstellen nicht definiert');
        return;
      }

      console.log('Kategorie:', category);
      console.log('Kann Thema erstellen:', 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; // Verwenden Sie das Element der Komponente als 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('Schaltfläche hinzugefügt');
        }

        newTopicButton.setAttribute('data-category-id', category.id);
        newTopicButton.textContent = 'Neues Thema';

        const self = this; // Speichern Sie den Kontext der Komponente
        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>

Hinweis: Die Themenliste wird derzeit nicht in Glimmer konvertiert.

Wenn Sie jedoch Komponenten an Plugin-Outlets anhängen, sollten Sie Glimmer verwenden.

Wenn Sie an ein Widget anhängen müssen, können Sie RenderGlimmer verwenden, um dies zu erreichen.

Beispiel hier:

Ich bitte Sie, sich nicht zu sehr auf LLMs zu verlassen, ohne die Grundlagen selbst zu lernen, da Sie die ultimative Qualitätssicherung für die Ausgabe des LLM sein müssen.

Sie müssen die Lösung auch korrekt entwerfen.

Lesen Sie mehr über EmberJS hier:

3 „Gefällt mir“

Danke. Ich werde auf jeden Fall mehr lernen, da ich ganz neu bei Discourse und JS bin.

Ich arbeite für ein KI-Unternehmen, daher war dies auch eine Übung in Prompt Engineering.

3 „Gefällt mir“

Kühl, so Sie werden eine gute Vorstellung von ihren Stärken und Schwächen haben.

Ich habe den ersten KI-Bot für Discourse namens Chatbot geschrieben, daher habe ich auch einige Einblicke.

2 „Gefällt mir“

Es wird eine spezielle Anleitung für die Systemaufforderung hinzugefügt, um sicherzustellen, dass „ask“ niemals die Verwendung von Widgets empfiehlt.

5 „Gefällt mir“