so when a user selects an option i want that option to be the Id from and array of objects

i want the functionality to be when i select and option i want that option to contain one of the ID’s from the array of objects

 <label for="selectTechCompany">Tech Company</label>
              <select
                class="form-select"
                id="selectTechCompany"
                aria-label="Default select example"
              >
                <option selected>Select</option>
                <option value="1">One</option>
                <option value="2">Two</option>
                <option value="3">three</option>
                <option value="4">four</option>
                <option value="5">five</option>
              </select>
            </div>

*** below is the array of objects
0
: 
{id: 84114, slug: '54146064986150486516464', statusId: 'Active', name: 'techCompany5', headline: 'headline5', …}
1
: 
{id: 84113, slug: '5414606498615086516464', statusId: 'Active', name: 'techCompany4', headline: 'headline4', …}
2
: 
{id: 84112, slug: '541460649861508651646', statusId: 'Active', name: 'techCompany3', headline: 'headline3', …}
3
: 
{id: 84111, slug: '541460649861508651645', statusId: 'Active', name: 'techCompany2', headline: 'headline2', …}
4
: 
{id: 84110, slug: '30110974915602206', statusId: 'Active', name: 'techCompany1', headline: 'headline1', …}
5
: 
{id: 84108, slug: '130166580319', statusId: 'Active', name: 'techCompany1', headline: 'headline1', …}
6
: 
{id: 84104, slug: '0916503104153049', statusId: 'Active', name: 'techCompany1', headline: 'headline1', …}
7
: 
{id: 84100, slug: '79841562130', statusId: 'Active', name: 'techCompany1', headline: 'headline1', …}
8
: 
{id: 84098, slug: 'slug1', statusId: 'Active', name: 'techCompany1', headline: 'headline1', …}

i know that ill have to use jquery i just dont know what the end results supposed to look like

how to access json object that is in a form of array in javascript

I am trying to access merchant name in the following json:

[{“merchant_id”:”90151″,”merchant_name”:”Wimpy”}]

the above json formt is returned by an api, I tried access merchant_name value but all I got was none

below is what I tried:

fetch("http://127.0.0.1:8000/vcl/retrieve/"+url, {
          method: "GET",
          headers: {
            "Content-Type": "application/json"
          },
        }).then((res) => res.json()).then((response) => {  
          console.log (response);
          const data = JSON.stringify(response);
          const info = JSON.parse(data);
          var merchant_name = info.merchant_name;
          console.log(merchant_name);
        })

all I am getting is undefined

Finding out order of properties for a given object

A Json web service returns an object like { "id": 12, "name": "xxx", "age": 12 }. How do I find out the order of the property keys or retrieve each property in the shown sequence?

I need to copy the properties into an array in the same order. This is for a generic web service, so I don’t know in advance what the properties will be in the object”.

TypeORM: How to always format database value in where condition for strings

I would like to use a generic method “exist” given by TypeORM to verify if name is already inserted in database.

My probleme is that I can’t know if name have been inserted in Uppercase or Lowercase and so I can face some false validation and end up inserting twice the same name.

I would like TypeORM and PostgreSQL to always put in lower case the database value (here name) while doing the WHERE condition : WHERE “myname” = valueOfDatabase

Why is my element disappearing for no reason?

Tthe plus sign is placed inside .pokemon-list as a ::before, and I need .pokemon-list to have overflow-y: scroll in order to be able to scroll through all the pokemons. However, the + is still getting hidden as if I had set overflow-x: hidden which I didn’t.
Any idea of what’s happening ?

don’t pay attention to the small images not displaying, they are stored locally

const url = "https://pokeapi.co/api/v2/pokemon/";

const sprite3dElement = document.querySelector(".pokemon-3Dmodel img");

const pokemonList = document.querySelector(".pokemon-list");
const shinyButton = document.querySelector(".shiny-button");

const premierPokemon = 1;
const dernierPokemon = 151;
const nbPokemon = dernierPokemon - premierPokemon + 1;

window.addEventListener("load", getPokedata);

function getPokedata() {
  const pokemonData = []; // array to store each Pokemon's data

  for (let i = premierPokemon; i <= dernierPokemon; i++) {
    const finalUrl = url + i;
    fetch(finalUrl)
      .then((response) => response.json())
      .then((data) => {
        pokemonData[i - premierPokemon + 1] = data; // store the data for each Pokemon in the correct order
      })
      .then(() => {
        if (pokemonData.length === nbPokemon + 1) {
          // if we have fetched all the Pokemon data, generate the cards in the correct order
          pokemonData.forEach((data) => {
            generateCard(data);
          });
          betterPokemonCards();
          toggleShiny();
        }
      });
  }
}

function generateCard(data) {
  console.log(data);
  const dex_number = data.id;
  const name = data.name;
  const sprite3D = data.sprites.other["official-artwork"].front_default;
  const sprite3DShiny = data.sprites.other["official-artwork"].front_shiny;
  const sprite2D = data.sprites.versions["generation-viii"].icons.front_default;

  pokemonList.innerHTML += ` <li class="pokemon${
    dex_number == dernierPokemon ? " pokemon-active" : ""
  }" data-sprite3D="${sprite3D}" data-shiny3D="${sprite3DShiny}" data-id="${dex_number}">
  <div>
  <div class="pokemon__sprite">
  <img src="${sprite2D}" alt="sprite">
  </div>
  <p class="pokemon__num">No. <span class="pokemon__num--field">${dex_number}</span></p>
  </div>
  <p class="pokemon__name">${name}</p>
  <div class="pokeball">
  <img src="images/pokeball.png" alt="pokeball">
  </div>
  </li>
  `;
  sprite3dElement.src = sprite3D;
}

function betterPokemonCards() {
  let pokemons = document.querySelectorAll(".pokemon");

  //adds one or two 0 to the dex number if it is less than 10 or 100
  pokemons.forEach((pokemon) => {
    let dex_entry =
      pokemon.firstElementChild.lastElementChild.lastElementChild.innerText;
    if (dex_entry.length == 1) {
      pokemon.firstElementChild.lastElementChild.lastElementChild.innerText =
        "00" + dex_entry;
    } else if (dex_entry.length == 2) {
      pokemon.firstElementChild.lastElementChild.lastElementChild.innerText =
        "0" + dex_entry;
    }
    //adds an event listener to each pokemon so that when you click on it, it adds the class pokemon-active
    pokemon.addEventListener("click", () => {
      sprite3dElement.src = pokemon.getAttribute("data-sprite3D");
      pokemons.forEach((pokemon) => {
        pokemon.classList.remove("pokemon-active");
      });
      pokemon.classList.add("pokemon-active");
    });
  });
}
:root {
  --attachment: fixed;
  --degrees: 115deg;
  --colorStop-1: 50%;
  --colorStop-2: calc(var(--colorStop-1) + 100px);
}
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
img {
  width: 100%;
}
body {
  font-family: "Noto Sans KR", sans-serif;
  background-color: #fff;
  color: #282828;
  background-image: linear-gradient(
      var(--degrees),
      transparent var(--colorStop-1),
      #fe4d3e var(--colorStop-1) var(--colorStop-2),
      #fa7246 var(--colorStop-2)
    ),
    radial-gradient(
      circle at 20% 70%,
      rgb(239 208 234 / 0.9),
      rgb(234 201 242 / 0.6),
      rgb(231 238 197 / 0.6),
      rgb(205 240 219 / 0.6),
      rgb(231 237 245 / 0.6)
    );
  background-attachment: var(--attachment);
  min-height: 100vh;
  overflow: hidden;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-image: linear-gradient(
    115deg,
    rgba(50 0 0 / 0.15) var(--colorStop-1),
    rgb(53 53 53) var(--colorStop-1)
  );
  background-attachment: var(--attachment);
  margin-top: 10px;
}
.header h1 {
  font-size: 2rem;
  padding-left: 1rem;
}
.header p {
  font-size: 1.5rem;
  color: white;
  padding-right: 13%;
}
.pokedex {
  position: relative;
  display: flex;
  justify-content: flex-end;
}
.shiny-button {
  position: absolute;
  left: 20px;
  top: 20px;
  width: 5rem;
  filter: drop-shadow(5px 5px 0 rgba(130, 217, 211, 0.408));
  cursor: pointer;
}
div:has(.pokemon-3Dmodel) {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-inline: auto;
}
.pokemon-3Dmodel {
  filter: drop-shadow(8px 8px 3px #39393951);
}
.pokemon-list {
  width: clamp(360px, 100%, 520px);
  height: calc(100vh - 56px);
  display: flex;
  overflow-y: scroll;
  overflow-x: visible;
  flex-direction: column;
  gap: 15px;
  padding: 20px 10px 20px 0;
  margin-right: 20px;
  border: 3px solid gold;
  position: relative;
}
.pokemon-list::before {
  content: "+";
  position: absolute;
  top: 0;
  left: -1rem;
  font-size: 3rem;
  border: 3px solid blue;
  line-height: 1em;
}
.pokemon {
  display: flex;
  justify-content: space-between;
  align-items: center;
  text-transform: capitalize;
  padding: 0 10px 0 0;
  color: black;
  font-weight: 500;
  font-size: 1.3rem;
  border-radius: 100vw;
  cursor: pointer;
}
.pokemon:hover,
.pokemon-active {
  background-image: linear-gradient(115deg, #f04f17 45%, black 45%);
  color: white;
}
.pokemon-active {
  position: relative;
}
.pokemon-active .pokeball {
  animation: rotate 1600ms infinite linear;
}

@keyframes rotate {
  to {
    rotate: 360deg;
  }
}
.pokemon > div:first-of-type {
  display: flex;
  align-items: center;
}
.pokemon__sprite {
  width: 60px;
  scale: 1.2;
  transform-origin: bottom;
  margin-inline: 10px;
}
.pokemon__num {
  display: flex;
}
.pokemon__num--field {
  margin-left: 0.5rem;
}
.pokeball {
  width: 25px;
  height: 25px;
  display: flex;
}
<main>
  <div class="header">
    <h1>Pokédex</h1>
    <p>By Number</p>
  </div>
  <section class="pokedex">
    <div>
      <div class="pokemon-3Dmodel">
        <img src="">
      </div>
    </div>
    <ul class="pokemon-list">
    </ul>
  </section>
</main>

Download iCal files does not working on mobile Chrome

I have a simple code that generate an ics file and automatically opens calendar app on ios
I tested works well on MacOS desktop and safari on ios mobile phones, however my code does not works for chrome browser on mobile,

  var test =
        "BEGIN:VCALENDARn" +
        "CALSCALE:GREGORIANn" +
        "METHOD:PUBLISHn" +
        "PRODID:-//Test Cal//ENn" +
        "VERSION:2.0n" +
        "BEGIN:VEVENTn" +
        "UID:test-1n" +
        "DTSTART;VALUE=DATE:" +
        convertDate(starting_date_html) +
        "n" +
        "DTEND;VALUE=DATE:" +
        convertDate(ending_date_html) +
        "n" +
        "SUMMARY:" +
        event_title +
        "n" +
        "DESCRIPTION:" +
        event_location +
        "n" +
        "END:VEVENTn" +
        "END:VCALENDAR";
    window.open("data:text/Calendar;charset=utf8," + escape(test)); 

I cannot get my head around on this issue …

I also tried the encodeURIComponent but no luck :/


window.open("data:text/Calendar;charset=utf8," + encodeURIComponent(test)); 

Trying to get a filter button to click on page load

I have a set of filters. I want the first button to be selected and clicked on at the loading of the page, so as to show all projects. Unfortunately I cannot seem to make this happen and I’m stumped.
If someone could help me understand where the problem lies I’d be very grateful.

function getProjects(event) {
    console.log("get projects");
    fetch('http://localhost:5678/api/works') // récuparation des données de l'API
        .then((resp) => resp.json()) // transforme la réponse en JSON
        .then(projects => { // réception de la réponse et exécute le code contenu après réception
            // on récupère toutes les boutons de catégories pour pouvoir filtrer les travaux
            const btnsCategory = document.querySelectorAll('.filter-btn');
            // pour chaque bouton récupéré
            btnsCategory.forEach(btnCategory => {
                // on clique sur une catégorie
                btnCategory.addEventListener('click', event => {
                    // récupération de la catégorie sélectionnée auparavant 
                    // et on lui enlève la classe active pour lui enlever la surbrillance
                    document.querySelector('.filter-btn.active').classList.remove("active");
                    event.target.classList.add("active");
                    // on exécute le code
                    //filterProjects(event, projects); // on affiche les projets correspondant au filtre actif
                    const gallery = document.querySelector('.gallery'); // Sélection de l'élément HTML qui contient les projets
                    gallery.innerHTML = ''; // Vide la galerie afin de pouvoir la remplir avec les éléments filtrés
                    let filterSelected = event.target.dataset.filter;
                    projects.forEach(project => {// on crée une boucle  
                        if (project.categoryId == filterSelected || filterSelected == "all") { // on vérifie si le projet doit être affiché en fonction du filtre choisi
                            const figure = document.createElement('figure'); // on crée un élément figure pour chaque objet
                            const image = document.createElement('img'); // même chose avec img
                            image.setAttribute('src', project.imageUrl); // on attribue l'url de l'image à l'élément img
                            image.setAttribute('alt', project.title); // on donne le titre du projet à l'attribut alt de l'img 
                            const title = document.createElement('figcaption'); // on crée un élément figcaption pour chaque projet
                            title.innerHTML = project.title; // on ajoute le titre du projet à figcaption
                            figure.appendChild(image); // on attache image à figure
                            figure.appendChild(title); // on attache figcaption à figure
                            gallery.appendChild(figure); // on attche figure à la galerie
                        }
                    });
                });
            });
        });
}


async function getCategories() {
    await fetch('http://localhost:5678/api/categories')
        .then(resp => resp.json())
        .then(categories => {
            const filterButtons = document.querySelector('.filter-buttons');
            // Ajoute un bouton de filtre pour chaque catégorie
            categories.forEach(category => {
                const button = document.createElement('button');
                button.classList.add('filter-btn');
                button.dataset.filter = category.id;
                button.textContent = category.name;
                filterButtons.appendChild(button);
            });
            // Ajoute un bouton "Tous" pour afficher tous les projets
            const allButton = document.createElement('button');
            allButton.classList.add('filter-btn');
            allButton.dataset.filter = 'all';
            allButton.id = "allWorks";
            allButton.textContent = 'Tous';
            filterButtons.prepend(allButton);
            allButton.click();
            // Sélectionne tous les boutons de filtre et ajoute un écouteur d'événement sur chacun
            const filterBtns = document.querySelectorAll('.filter-btn');
            filterBtns.forEach(filterBtn => {                
                filterBtn.addEventListener('click', event => {
                    // Enlève la classe "active" du bouton de filtre actif et ajoute-la au bouton sélectionné
                    let elementActive = document.querySelector('.filter-btn.active');
                    if (elementActive != null) {
                        elementActive.classList.remove('active');
                    }
                    event.target.classList.add('active');
                    // Filtre les projets selon la catégorie sélectionnée
                    getProjects(event);
                });
            });
        });

}


document.addEventListener('DOMContentLoaded', async (event) => { // vérifie si la page est chargée
    await getCategories();
    await document.querySelector("#allWorks").click(); 
     


});


I’ve tried to have a list of filters that help the user search through the projects available on the website. Unfortunately while the “Tous” (all) button is indeed selected at page load, it isn’t clicked and the display of all the projects needs to be done manually which isn’t what I want.

Unable to set angle in transform, rotate using an anom.function

I cannot figure out what is wrong with the following code:

 svg.selectAll(".axislabel")
            .data(featureData)
            .join(
                enter => enter.append("text")
                    .attr("x", d => d.label_coord.x)
                    .attr("y", d => d.label_coord.y)
                    .attr("transform", "rotate(" + (d => d.angle)+ ")" )  //ERROR
                    .text(d => d.name)
            );

I’m getting this error:

Error: <text> attribute transform: Expected number, "rotate(d =u003E d.angle)".

If I use .attr("transform", "rotate(90)" ) then it works.

Thank you

I’ve tried various versions of the syntax.

How are dot relative paths and rootDir paths treated differently in my projects jest configuration?

Problem Description

I have a question about the jest.config.ts that I am setting up.
There I use a moduleNameMapper, so that imports a la import ... from "@base/..." also work in the tests. For this I use a function of ts-jest, which returns the corresponding regular expressions from the tsconfig.json.compilerOptions.paths. tsconfig.json is a json file which I am importing with typescript’s resolveJsonModule option. See here for the documentation on moduleNameMapper.

The function from ts-jest returns one of the following two objects to be used as the moduleNameWrapper, depending on other parameters passed. How that works is not relevant for the question, as I am also able to just enter the keys and values directly, not using the ts-jest function.

First Object: { '^@base/(.*)$': './src/$1' }
Second Object: { '^@base/(.*)$': '<rootDir>/src/$1' }
The first does not work (the modules are then not resolved), the second works correctly.

Question

Hence my question: What does . mean as a path for jest? What is the difference with <rootDir>? Why do they both not point to the same directory? My jest config is in the root directory of the project, so I would assume that both . and <rootDir would point to the root directory (the folder where the jest config is located). Also see the documentation for rootDir.

What I’ve tried so far

I tried putting both objects in as moduleNameWrapper in the jest.config, but only the one with rootDir worked. I would have expected ./src/$1 to have worked as well, but it did not.

The rootDir solution is unsatisfying, as producing the object including <rootDir> requires an additional options parameter, which sets a prefix. This prefix is hard coded, and could e.g. result in problems further in this project or when using this project as a foundation for the next.

This is the call to create the moduleNameMapper object via ts-jest:

pathsToModuleNameMapper(compilerOptions.paths, {prefix: "<rootDir>/src/"}),

If the second parameter is omitted, then the dot version is produced, which does not work.

Thanks.

Problem with Formidable Error : Request aborted

I have an application with Node.js, Express.js , MongoDB and Javascript for front-end. I want to create file upload to add image . I use formidable and use AWS like cloud platform to save images too.

The problem is :
In my application , I have a form for add information about a car , for example: mark, model, year, location ,price, Choose image button and Submit button. When I fill the fields with data and choose image , then click on Submit button, in the console it write this:

Error: Request aborted
    at IncomingMessage.<anonymous> (C:Users201217040DocumentsCarRentalnode_modulesformidablelibincoming_form.js:122:19)
    at IncomingMessage.emit (node:events:369:20)
    at IncomingMessage.emit (node:domain:470:12)
    at abortIncoming (node:_http_server:598:9)
    at socketOnClose (node:_http_server:589:3)
    at Socket.emit (node:events:381:22)
    at Socket.emit (node:domain:470:12)
    at TCP.<anonymous> (node:net:666:12)

I put part of app.js :

const express = require('express');
const exphbs = require('express-handlebars');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const passport = require('passport');
const bcrypt = require('bcryptjs');
const formidable = require('formidable');
const socketIO = require('socket.io')

// init app
const app = express();

// setup body parser
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

// configuration for autthentication
app.use(cookieParser());
app.use(session({
    secret: 'mysecret',
    resave: true,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

// load helpers
const {requireLogin, ensureGuest} = require('./helpers/authHelper');
const {upload} = require('./helpers/aws');

// load passports
require('./passport/local');
require('./passport/facebook.js');

// receive image
app.post('/uploadImage',requireLogin,upload.any(),(req,res)=>{
    const form = new formidable.IncomingForm();
    form.on('file',(field,file)=>{
        console.log(file);
    });
    form.on('error',(err)=>{
        console.log(err);
    });
    form.on('end',()=>{
        console.log('Image received successfully.');
    });
    form.parse(req);
});

Here is where I add “upload” in aws.js :

const aws = require('aws-sdk');
const multer = require('multer');
const multers3 = require('multer-s3');
const keys = require('../config/keys');

aws.config.update({
    accessKeyId:keys.AWSAccessID,
    secretAccessKey: keys.AWSSecretKey,
    region: 'eu-north-1'
});

const s3 = new aws.S3({});

const upload = multer({
    storage: multers3({
        s3:s3,
        bucket: 'car-rental-application',
        ac1:'public-read',
        metadata:(req,file,cb)=>{
            cb(null,{fieldName:file.fieldname});
        }, 
        key: (req,file,cb)=>{
            cb(null,file.originalname);
        },
        rename: (fieldName,fileName) =>{
            return fileName.replace(/W+/g, '-').toLowerCase();
        }
    })
});
exports.upload = upload;

And here is html form:

<div class="row">
    <div class="col-sm"></div>

    <div class="col-sm-5">
            <form action="/listCar2" method="POST">
            <input type="hidden" name="carID" value="{{car._id}}">
            <div class="form-group">
                <label for="pricePerHour">Price per hour</label>
                <input type="number" name="pricePerHour" id="pricePerhour" class="form-control" required>
            </div>
            <div class="form-group">
                <label for="pricePerWeek">Price per week</label>
                <input type="number" name="pricePerWeek" id="pricePerWeek" class="form-control" required>
            </div>
            <div class="form-group">
                <label for="location">Location</label>
                <input type="text" name="location" id="location" class="form-control" placeholder="street, city, state and zipcode " required>
            </div>
            <div class="form-group">
                <button class="btn btn-info upload-btn" type="button">Choose image</button>
                <input type="file" name="image" id="upload-input" style="display: none;" required>
            </div>
            <div class="form-group">
                <button type="submit" class="btn btn-primary">List a car</button>
            </div>
            </form>
    </div>

    <div class="col-sm"></div>
</div>
<script src="https://code.jquery.com/jquery-3.6.4.js" integrity="sha256-a9jBBRygX1Bh5lt8GZjXDzyOB+bWve9EiO7tROUtj/E=" crossorigin="anonymous"></script>
<script>
    // fetch location using javascript
function initMap(){
    var location = document.getElementById('location');
    var Autocomplete = new google.maps.places.Autocomplete(location);
}

// jquery code starts here
$(document).ready(function(){
    $('.upload-btn').on('click',function(){
        $('#upload-input').click();
    });
    $('#upload-input').on('change', function(){
        var uploadInput = $('#upload-input');
        if(uploadInput.val() != ''){
            var formData = new FormData();
            formData.append('image', uploadInput[0].files[0]);
            
            // make ajax request to send image to database
            $.ajax({
                url: '/uploadImage',
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                success: function() {
                    uploadInput.val('');
                }
            })
         }
    })
})

</script>
<script async
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCZa44WBMahTn9Zf2z9x6fKiZTMQQh3vbw&libraries=places&callback=initMap"></script>

How can I fix this problem?

Cypress API testing : How to access data generated from it block to another it block

How can I access the token generated from 1st it block to 2nd it block.

here is the code:

1st it block

      it('Login using new user', () => {
        cy.api({
          method: "POST",
          url:    "https://api-stg.sample.com/v1/user/login",
          body: 
          {
          "mobile_number": "+9912345678"
          "password": "p@ssword"  
          }

        })
          .then((response) => {
            expect(response.status).to.eq(200)
        })
          .then((response) => {
            const bearer_token = response.body.data.user.access_token.token // 
*in here where I get and put the token in var bearer_token*

            cy.log("Bearer token: " + token )
        })
      })

2nd it block

     it('Create New Mobile', () => {
        cy.api({
          method: "POST",
          url:    "https://api-stg.sample.com/v1/user/add_new_mobile_numbers",
          headers: {
            'Authorization': 'Bearer ' + token // *in here where I put the token*
          },
          body: 
          {
            "mobile_prefix": "+991",
            "mobile_number": "9912345679"
          }
})

I login from 1st block, then i need to use the token to add new mobile num in 2nd block.
in cypress dashboard it returns an error:
token is not defined

await this.showPopup(”); don’t show the Popup

I wanted to show the CreateOrderPopup in Odoo15 BUT it’s not showing and there is no error message.
I created 2 logs : ffffffff and QQQQQ
the fffffffff is shown in the logs but the QQQQQ which is after calling ” await this.showPopup(‘CreateOrderPopup’); ” it’s not being shown.

I have this in the JS file :

odoo.define("point_of_sale.CreateOrderButton", function (require) {
    "use strict";

    const PosComponent = require("point_of_sale.PosComponent");
    const ProductScreen = require("point_of_sale.ProductScreen");
    const Registries = require("point_of_sale.Registries");
   
    class CreateOrderButton extends PosComponent {
        async onClick() {
            console.log("ffffffffffffffffffff");
           await this.showPopup('CreateOrderPopup');
            console.log('QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ');
        };
        
    }
    CreateOrderButton.template = "CreateOrderButton";
    
    ProductScreen.addControlButton({
        
        component: CreateOrderButton,
        condition: function () {
            return (
                this.env.pos.config.iface_create_sale_order &&
                this.env.pos.get_order().get_client() &&
                this.env.pos.get_order().get_orderlines().length !== 0
                
            );
        },
    });

    Registries.Component.add(CreateOrderButton);
});

But the CreateOrderPopup is not showing when I click on the button. Also the QQQQ logs don’t get shown

For the CreateOrderPopUp i have :

odoo.define("point_of_sale.CreateOrderPopup", function (require) {
    "use strict";

    const AbstractAwaitablePopup = require("point_of_sale.AbstractAwaitablePopup");
    const Registries = require("point_of_sale.Registries");
    const framework = require("web.framework");

    class CreateOrderPopup extends AbstractAwaitablePopup {
        setup() {
            super.setup();
            this.createOrderClicked = false;
        }

        async createDraftSaleOrder() {
            await this._createSaleOrder("draft");
        }

        async createConfirmedSaleOrder() {
            await this._createSaleOrder("confirmed");
        }

        async createDeliveredSaleOrder() {
            await this._createSaleOrder("delivered");
        }

        async createInvoicedSaleOrder() {
            await this._createSaleOrder("invoiced");
        }

        async _createSaleOrder(order_state) {
            var current_order = this.env.pos.get_order();

            framework.blockUI();

            await this.rpc({
                model: "sale.order",
                method: "create_order_from_pos",
                args: [current_order.export_as_JSON(), order_state],
            })
                .catch(function (error) {
                    throw error;
                })
                .finally(function () {
                    framework.unblockUI();
                });

            // Delete current order
            this.env.pos.removeOrder(current_order);
            this.env.pos.add_new_order();

            // Close popup
            return await super.confirm();
        }
    }

    CreateOrderPopup.template = "CreateOrderPopup";
    Registries.Component.add(CreateOrderPopup);

    return CreateOrderPopup;
});

both templates are created and they are all called like this in the manifest file :

  "assets": {
        "point_of_sale.assets": [
            "pos_order_to_sale_order/static/src/css/pos.css",
            "pos_order_to_sale_order/static/src/js/CreateOrderPopup.js",
            "pos_order_to_sale_order/static/src/js/CreateOrderButton.js",
        ],
        'web.assets_qweb': [
            "pos_order_to_sale_order/static/src/xml/CreateOrderPopup.xml",
            "pos_order_to_sale_order/static/src/xml/CreateOrderButton.xml",

        ],

Why does the PopUp stops the QQQQ log from showing in the logs and itself in the POS

Install npm project A which has dependency to project B in project B but use current project B’s index.js file instead of original project B’s version

I have such case:

  1. I created npm project A which has peer dependency to project B
{
  "name": "project-A",
  "peerDependencies": {
    "project-B": "*"
  }
}
  1. I want to test project A inside project B without the need of installing specific version of project B inside project A
  2. I want to install project A inside project B and resolve project A’s dependency to project B’s index.js file which exports all the needed modules.

Is it achievable?

Currently I need to release project A with dependency to specific version of project B and install it like so in project B to test it. Obviously, if there are some changes in project B, project A becomes incompatible.

{
  "name": "project-A",
  "dependencies": {
    "project-B": "1.0.0"
  }
}

Tooltips overlap in vueform slider

I’m using this slider (https://github.com/vueform/slider#multiple-slider) in one of my form field and for some reasons, both the tooltips are stuck at one place.

Template Code of the slider component:

<template>
  <div class="input-container">
    <label class="input-label">{{ label }}</label>
    <div class="input-field">
      <Slider 
        v-model="value"
        :min="0"
        :max="4500"
        :showTooltip="always"
        :format="formatTooltip"
        class="slider-red"
        />
    </div>
  </div>
</template>

Script:

<script>

import Slider from '@vueform/slider'
import '@vueform/slider/themes/default.css';

export default {
  name: 'RangeSlider',
  components: {
    Slider,
  },
  props: {
    label: String,
  },
  data() {
    return {
      value: [0, 4500],
    }
  },
  watch: {
    activeButton(newValue) {
      this.activeButtonValue = newValue
    },
  },
  methods: {
    formatTooltip(val) {
      return `$${val}`
    },
  },
}
</script>

<style scoped>
.input-label {
  position: absolute;
  top: -10px;
  left: 10px;
  color: #d7c8f1;
  padding: 0 5px;
  text-decoration-color: white;
}

.input-field {
  padding-top: 20px;
  padding-bottom: 20px;
  border: 1px solid var(--secondary-color);
  color: white;
  cursor: pointer;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

.space-right {
  margin-right: 16px;
}

.active {
  border: 1px solid var(--secondary-color);
  padding: 4px !important;
  border-radius: 12px !important;
  color: #101828 !important;
  background-color: #f9fafb;
}

.button {
  border: none;
  color: var(--primary-color);
  font-weight: 500;
  font: inherit;
  cursor: pointer;
  padding: 0px;
  border-radius: 8px;
}
.content-button {
  padding-left: 12px;
  padding-right: 12px;
  padding-top: 6px;
  padding-bottom: 6px;
  border-radius: 8px;
  border: 1px solid var(--secondary-color);
}

.slider-red {
  --slider-connect-bg: #EF4444;
  --slider-tooltip-bg: #EF4444;
  --slider-handle-ring-color: #EF444430;
}

</style>


I have tried formatting the width/height of the class, but it doesn’t seem to work.

The problem state:

enter image description here