Impossible d'obtenir le js dans mon composant à compiler SyntaxError : Un champ privé doit être utilisé dans une classe englobante

Au bout du compte, j’ai besoin d’un bouton « Nouveau sujet » dans le corps de la liste des sujets du thème central de Discourse. Tous les ingénieurs se plaignent qu’ils n’aiment pas le bouton « Démarrer une nouvelle conversation » qui se trouve juste en bas de la liste des sujets à l’intérieur de chaque catégorie. Ils ne veulent pas utiliser le choix du menu « Nouveau sujet » en haut car cela ne démarre pas le sujet dans la catégorie dans laquelle ils se trouvent actuellement.

J’ai exécuté cela via Llama 3.1 405B ainsi que GPT4 via ask.discourse.com, mais je n’arrive pas à obtenir une version de JavaScript qui se compile. Je reçois constamment une erreur de compilation : SyntaxError : Private field must be used in an enclosing class.

Je reçois également une erreur de registre de widgets, mais c’est parce que le widget personnalisé n’est jamais créé en raison de l’erreur de compilation JS.

J’utilise le thème Discourse Central.

Étant donné cette section d'en-tête :
« <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>

»
Avec cette section d'en-tête
<script>
    {{#if currentUser}}
     <div>
      {{custom-new-topic-button}}
     </div>
   {{/if}}
</script>

Et ce CSS

.topic-list-body::before {
    content: "";
    display: block;
    position: relative; /* Important pour permettre le positionnement absolu à l'intérieur */
  }
  
  .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;
  }

C’était mon code original, la dernière recommandation est

<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

J’ai réussi à le faire fonctionner. @sam J’ai épuisé mes appels quotidiens pour demander… désolé pour ça. Puis j’ai couru vers notre LLAMA 405 B et après beaucoup d’allers-retours, j’ai obtenu du code fonctionnel. Je n’ose imaginer combien cela m’aurait coûté. Je pourrais entendre d’autres personnes sur le forum dire “hé idiot, il y avait un réglage pour faire ça à cet endroit”. Mais c’était un exercice amusant de révision continue des invites pour obtenir du code fonctionnel.

Certaines des clés sont de dire (notez que certaines d’entre elles peuvent être inexactes car je suis développeur JavaScript et développeur Discourse depuis environ 2 jours au total) :

Ceci est un forum hébergé par Discourse et je n’ai pas d’accès OS
Ceci est un plugin, vous ne pouvez donc pas référencer Discourse directement.
Vous ne pouvez pas référencer Ember directement
Si vous comptez l’utiliser, assurez-vous de le lier à self

Puis allez dans les traits fonctionnels que vous souhaitez.

<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('Catégorie non trouvée');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Utilisateur actuel non trouvé');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Impossible de créer le sujet non défini');
        return;
      }

      console.log('catégorie:', category);
      console.log('peut créer un sujet:', 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; // Utiliser l'élément du composant comme conteneur
        }

        console.log('conteneur:', 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 = 'Nouveau Sujet';

          const self = this; // Stocker le contexte du composant
          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('bouton ajouté');
        }
      }
    }
  });
</script>

Je me suis précipité en disant que cette version avait un problème de didRender qui ne voulait pas poster dans d’autres catégories que la première. J’ai demandé à Llama de corriger cela.

<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('Catégorie non trouvée');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Utilisateur actuel non trouvé');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Peut créer un sujet non défini');
        return;
      }

      console.log('catégorie:', category);
      console.log('peut créer un sujet:', 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; // Utiliser l'élément du composant comme conteneur
        }

        console.log('conteneur:', 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('bouton ajouté');
        }

        newTopicButton.setAttribute('data-category-id', category.id);
        newTopicButton.textContent = 'Nouveau sujet';

        const self = this; // Stocker le contexte du composant
        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>

Il semble que vous ayez résolu votre problème, comme je le fais souvent lorsque je rédige des demandes d’aide.

New Topic Header Button - #67 by patrickemin fournit un exemple et pourrait être exactement ce que vous recherchez.

Dites également à vos ingénieurs qu’ils peuvent appuyer sur la touche c pour composer un message.

3 « J'aime »

Dans Central, le bouton pour démarrer une nouvelle conversation se trouve en bas de la liste des sujets. Tout le monde voulait un bouton en haut. Je vais peut-être le changer en un petit plus, mais ces deux captures d’écran le montrent.


1 « J'aime »

@pfaffman J’ai essayé le nouveau bouton d’en-tête de sujet comme première tentative. Cependant, cela ne fonctionne pas bien avec le nouveau thème Discourse Central.

Les widgets disparaissent. Il n’est pas conseillé d’utiliser l’API des widgets.

Utilisez les composants Glimmer.

2 « J'aime »

Nous devrons également supprimer un tas de vieux contenus des “AI rags” et attendre que les modèles de widgets post-publication soient affinés. Même ask.discourse.com s’est orienté vers la voie des widgets. Qu’est-ce qui remplacera les widgets ? Je vais voir si je peux obtenir un modèle qui génère du code en tenant compte de cela. D’ailleurs, l’essentiel de mon exercice est de voir si je peux obtenir un modèle pour faire ce travail puisque je ne connais pratiquement rien au JS :slight_smile:

Je connais ce sentiment.

Composants Glimmer. Quelque part, il y a un bon sujet qui les décrit.

Mais voici un exemple pour créer le composant :

Et voici une façon JavaScript de l’insérer :

L’autre façon de l’insérer est la manière qui devient démodée de créer un connecteur qui insère ensuite le composant, mais l’avantage de la méthode de l’initialiseur est que vous pouvez ensuite passer le plugin outlet souhaité à l’initialiseur afin que vous puissiez avoir un paramètre qui change où il est affiché.

Je pense que vous voulez trouver un exemple de quelque chose qui appelle shouldDisplay (ou quelque chose comme ça) si vous voulez qu’il s’affiche seulement parfois (comme s’ils sont connectés).

4 « J'aime »

Mon dernier code que Llama a généré la nuit dernière n’utilisait pas de widgets, mais il n’utilisait pas non plus Glimmer. Je vais expérimenter avec Glimmer plus tard aujourd’hui.

<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('Catégorie introuvable');
        return;
      }

      const currentUser = this.currentUser;
      if (!currentUser) {
        console.error('Utilisateur actuel introuvable');
        return;
      }

      const canCreateTopic = currentUser.can_create_topic;
      if (canCreateTopic === undefined) {
        console.error('Impossible de créer le sujet non défini');
        return;
      }

      console.log('catégorie:', category);
      console.log('peut créer un sujet:', 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; // Utiliser l'élément du composant comme conteneur
        }

        console.log('conteneur:', 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('bouton ajouté');
        }

        newTopicButton.setAttribute('data-category-id', category.id);
        newTopicButton.textContent = 'Nouveau sujet';

        const self = this; // Stocker le contexte du composant
        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>

Attention : La liste des sujets n’est actuellement pas convertie en Glimmer.

Cependant, si vous attachez des composants à des Plugin Outlets, vous devriez utiliser Glimmer.

Si vous devez attacher à un widget, vous pouvez utiliser RenderGlimmer pour y parvenir.

Exemple ici :

Je vous implore de ne pas trop vous fier aux LLM sans avoir d’abord appris les bases par vous-même, car vous devez être le garant ultime de ce que le LLM produit.

Vous devez également architecturer la solution correctement.

En savoir plus sur EmberJS ici :

3 « J'aime »

Merci. J’étudierai certainement davantage car je suis tout nouveau dans le discourse et le js.

Je travaille pour une entreprise d’IA, donc c’était aussi un exercice d’ingénierie de prompt.

3 « J'aime »

Génial, vous aurez donc une bonne idée de leurs forces et de leurs faiblesses.

J’ai écrit le premier bot IA pour Discourse appelé Chatbot, j’ai donc aussi quelques éclaircissements.

2 « J'aime »

J’ajouterai des instructions spéciales à l’invite système pour garantir que « ask » ne recommande jamais l’utilisation de widgets.

5 « J'aime »