Safe PowerBI iFrame implementation using a proxy service

My main goal is to display a PowerBI report within an older website built with the .NET Framework 4.0. There are a few considerations:
The PowerBI report needs to be visible and interactive, but we need to hide the original link URL.
The PowerBI report was shared using the public URL method (so anyone with the link can access the project). It was created this way, rather than using the secure sharing method, as it requires a PowerBI account to view it. Therefore, we want to display the information but restrict full access to the report.

It currently works with the public URL, but it presents a serious security issue: the URL is exposed in the HTML src attribute.
The main issue is that the src URL displayed in the web development tools cannot be hidden or cleared, so the next step was to implement a proxy to hide the actual URL.

I created another project to properly test it and decided to create a proxy service that would redirect the original request to my target site to avoid displaying the actual PowerBI URL, which contains sensitive data.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Amazing Title</title>
        <link rel="stylesheet" href="styles.css">
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    </head>
    <body>
        <header style="height: 3em;">
            <h1>PowerBI Report</h1>
        </header>
        <div class="iframe-container" style="width: 100%; height: 52em;">
            <iframe
            id="inlineFrameExample"
            title="Inline Frame Example"
            width="100%"
            height="100%"
            src="">
            </iframe>
        </div>

        <footer>
            <p>&copy; 2023 CLF.</p>
        </footer>

        <script src="script.js"></script>
    </body>
    </html>
    $(document).ready(function () {
      var url = 'https://localhost:7103/api/powerbi/report';
      $('#inlineFrameExample').attr('src', url);
    });

And this is my new Proxy Service:

    [ApiController]
    [Route("api/powerbi")]
    public class ProxyController : ControllerBase
    {
        private readonly IHttpClientFactory _httpClientFactory;

        public ProxyController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        [HttpGet("report")]
        public async Task<IActionResult> GetPowerBIReport()
        {
            var client = _httpClientFactory.CreateClient();
            var powerBIUrl = "https://app.powerbi.com/view?r=TheUrlThatIWantToHide";
            var response = await client.GetAsync(powerBIUrl);

            if (!response.IsSuccessStatusCode)
            {
                return StatusCode((int)response.StatusCode, "Error");
            }

            var contentType = response.Content.Headers.ContentType?.ToString() ?? "text/html";
            var content = await response.Content.ReadAsStreamAsync();
            return File(content, contentType);
        }
    }

So now I’m facing the following issues:
#First: Millions of failed requests trying to search hash-manifest.js. At first, I thought this is happening because it’s trying to load resources from the website and can’t due to the proxy service implementation.
This makes a lot of sense, although I have my doubts about emulating that behavior, considering the security risk that doing so can present.
image-MultipleErrorLogs

#Second: When I visit the URL https://localhost:7103/api/powerbi/report (the URL of my service that should return the content of the actual PowerBI URL), it starts reloading infinitely, and the URL changes to https://localhost:7103/api/powerbi/report?disablecdnExpiration=1744249594, with the disablednExpiration number constantly changing.
I thought it was an anti-proxy or something similar, but I’m not sure. What I do see is that the service is making so many requests per second that it even crashes on some frames, and the PowerBI page says Too Many Requests.
image-DirectProxyServiceUrl

I’m trying to fix this, but I’m stuck.

Best practices for dependency management in a monorepo using npm workspaces and Nx [closed]

I’m working with a monorepo in JavaScript/TypeScript that uses npm workspaces and Nx. The setup includes:

  • 2 frontend apps

  • 2 backend apps

  • Several shared utility packages

I’m trying to establish a clean and maintainable dependency management strategy, but there seem to be conflicting recommendations:

  • Some suggest putting all dependencies in the root package.json

  • Others recommend including only shared dependencies (used by 2+ apps) at the root

  • Some prefer putting all dev dependencies at the root

  • while others recommend scoping everything (including devDeps) to each app’s package.json

I’d love to hear from folks who’ve tried these different approaches. Specifically:

  • What are the pros and cons you’ve experienced with each strategy?

  • How does the choice affect maintenance, especially as the number of apps grows?

  • Any impact on CI build performance or caching when dependencies are hoisted vs scoped locally?

  • Would it make sense to put tools like react, vite, or even framework-specific dev dependencies at the root?

For context, I’ve currently only placed common tools like typescript, eslint, and the testing suite in the root package.json.

Thanks in advance for your insights!

Uploading a file in Cypress in Salesforce and there is no type = file

I’m trying to attach a .csv file in Salesforce application and there is no type = file. How can we attach file? None of the solutions worked for me. Any help.

Tried:

const filePath = 'shelf_upload_template.csv';
cy.xpath("//span[text()='Upload Files']").eq(1).invoke('show').attachFile(filePath)
cy.wait(5000);
cy.xpath("//span[text()='Add']").click()
AND
cy.xpath("//a[@data-label='Attachments']").click({force:true})

Here is the Console:

<lightning-icon icon-name="utility:upload" class="slds-icon-utility-upload slds-button__icon slds-button__icon--left slds-icon_container forceIcon" data-data-rendering-service-uid="1157" data-aura-rendered-by="5616:0" lwc-4897l11qtae-host="" data-aura-class="forceIcon"><span lwc-4897l11qtae="" style="--sds-c-icon-color-background: var(--slds-c-icon-color-background, transparent)" part="boundary"><lightning-primitive-icon lwc-4897l11qtae="" exportparts="icon" size="xx-small" variant="inverse" lwc-55d10h1nfm1-host=""><svg focusable="false" aria-hidden="true" viewBox="0 0 520 520" part="icon" lwc-55d10h1nfm1="" data-key="upload" class="slds-icon slds-icon_xx-small"><g lwc-55d10h1nfm1=""><path d="M485 310h-30c-8 0-15 8-15 15v100c0 8-7 15-15 15H95c-8 0-15-7-15-15V325c0-7-7-15-15-15H35c-8 0-15 8-15 15v135a40 40 0 0040 40h400a40 40 0 0040-40V325c0-7-7-15-15-15zM270 24c-6-6-15-6-21 0L114 159c-6 6-6 15 0 21l21 21c6 6 15 6 21 0l56-56c6-6 18-2 18 7v212c0 8 6 15 14 15h30c8 0 16-8 16-15V153c0-9 10-13 17-7l56 56c6 6 15 6 21 0l21-21c6-6 6-15 0-21z" lwc-55d10h1nfm1=""></path></g></svg></lightning-primitive-icon></span></lightning-icon>

CORS issue in Unity WebGL app when using mobile network (but works on office Wi-Fi)

I’m building a Unity WebGL app hosted at mydomain.com that dynamically loads images from another domain (api.example.in). These images are used as elements for an AR experience.

Everything works perfectly on office Wi-Fi, but when I access the same app using mobile data, the image loading fails due to CORS (Cross-Origin Resource Sharing) errors in the browser console.

Here’s the relevant part of my JavaScript code in the WebGL index.html:

function createImageTargets(data, folderPath) {
  const files = data.files;
  files.forEach((file) => {
    if (!file.match(/.(jpg|jpeg|png|gif)$/i)) return;

    const imagetarget = document.createElement("imagetarget");
    const id = file.replace(/.[^/.]+$/, "");
    imagetarget.id = id;

    const imageUrl = `${folderPath}/ARBuildsImages/${file}`;
    imagetarget.setAttribute("src", imageUrl);
    imagetarget.setAttribute("crossorigin", "anonymous");

    document.body.appendChild(imagetarget);
  });
}
  1. Accessing the image URLs directly works fine from office Wi-Fi, but from mobile data I get CORS errors in the browser console.
    2.Removing crossorigin=”anonymous” doesn’t help—images still fail to load on mobile network.
    3.The CORS error happens only on image loading, not API calls.
    4.Accesing images directly in browser through link works fine.

What I’m expecting
To solve the cors issue and access to the image

Want to know a better way to do bulk insertion in typeorm without save()

I’m doing a bulk insert using repository.insert(...) in TypeORM, and I’m trying to figure out the best way to associate inserted records with their related metadata for follow-up inserts in other tables.
Here’s the situation:
I’m inserting a list of Product entities where each product has a unique name. I’m also maintaining a Map<string, { product, tags, locations }> where the key is the product’s name, and the value includes all the related data that will be inserted into other tables (like product_tags, product_locations, etc.) that depend on the generated productId.
I use this code:

 const productsToInsert = [...productMap.values()].map(entry => entry.product);
const insertResult = await dataSource.getRepository(Product).insert(productsToInsert);

 insertResult.generatedMaps.forEach((p, idx) => {
   // Trying to get the name to map back to productMap
   const productName = p.name; // not available here
   const id = p.id;
 });

The issue is that generatedMaps only contains columns that were generated (e.g., id), and not columns like name that were explicitly set. So I can’t match back the inserted ID with the original product using name, which was my key.>
Is there a better way to track which inserted ID belongs to which original entity when using .insert()?

  • I want to get the ids after insertion so i can map the ids with name and then insert in other tables too where we need this id for foreign key.

Syncing audio with score scrolling

I’m buiding a webpage that will be used by drummers to practise patterns.

In order to do so, I must have:

  1. An adjustable metronome (functional)
  2. A score including automatic scrolling synced to the metronome created with HTML canvas (not fully functional)

The problem lies in syncing the score scrolling to the metronome. For the moment, I use purely empirical values because when I’ve tried to calculate the distances and used settimeout to scroll the score I couldn’t get a satisfying result.

Please note:

  1. the space between the notes is 30 pixels.
  2. The canvas will probably be 100% page width as in the exemple.
  3. The vertical bar in the middle of the canvas is the reference point. When a note reaches this bar, a sound will be played so that the user can hear what drum element should be played and how (snare max vol or min vol in this example).

The script does the job but is quite approximate. In order for the script to be usable, there should be a very good synchronisation between the metronome and the notes reaching the reference bar.

I’ve tried calculating the distance that should be offset each millisecond but settimeout won’t allow for less than 15 to 17 ms and it varying is not accurate enough.

Below is the full code for the project.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DrumChallenge.com</title>
    <style>
        #div_patterns {
            display: inline-block;
            margin: 20px;
        }
        #div_tempo {
            display: inline-block;
            margin: 20px;
        }
        #drumscore {
            position: relative;
            width: 100%;
            height: 200px;
        }
        #drumscore canvas {
            position: absolute;
            top: 0px;
            left: 0px;
        }
        canvas {
            border: 1px solid black;
            width: 100%;
            height: 200px;
        }
    </style>
</head>
<body>
    <div id="params">
        <div id="div_patterns"></div>
        <div id="div_tempo">
            <span>Tempo :</span>
            <input type="text" id="value_tempo" value="60" />
            
            <span>Delai :</span>
            <span id="value_delai"></span>
            
            <span>Timer :</span>
            <span id="value_timer"></span>
            
        </div>
        <button id="launch" class="launch" type="button">Lancer challenge</button>
    </div>
    <div id="drumscore">
        <canvas id="score"></canvas>
        <canvas id="scoreCanvas"></canvas>
    </div>
    <script src="metronome.js"></script>

    <script>
        
        
        
    document.addEventListener('DOMContentLoaded', () => {
        const audioContext = new (window.AudioContext || window.webkitAudioContext)();
        const metronome = new Metronome(audioContext);
        
        var Current_Audio = false;
        var Challenge_Launched = false;
        var Current_Animation = false;
        var Timer_Challenge = false;
        var Timer_General = false;
        var Tempo = 60;
        var Delai;
        var Distance_Between_Notes = 30;
        var General_Timer = 0;
        var NextNoteTime = 0;
        //
        //
        //
        const LaunchButton = document.getElementById('launch');
        LaunchButton.addEventListener('click', function(){
            if (Challenge_Launched == false){
                CreerChallenge();
                Challenge_Launched = true;
                
                const bpm = parseInt(InputTempo.value, 10);
                metronome.setTempo(bpm);
                metronome.start();
                
                Timer_General = setInterval(SetGeneralTimer, 1000);
                NextNoteTime = performance.now();
                //drawNotes();
                requestAnimationFrame(drawNotes);
            } else {
                Challenge_Launched = false;
                clearTimeout(Timer_Challenge);
                clearInterval(Timer_General);
                metronome.stop();
                //cancelAnimationFrame(Current_Animation);
            }
        });
        //
        //
        //
        function SetTempo(){
            Tempo = InputTempo.value;
            Delai = (60000 / Tempo).toFixed(2);
            document.getElementById('value_tempo').innerHTML = Tempo;
            document.getElementById('value_delai').innerHTML = Delai + 'ms';
            metronome.setTempo(Tempo);
            /*if (Challenge_Launched){
                clearTimeout(Timer_Challenge);
                //Timer_Challenge = setTimeout(drawNotes, Delai);
            }*/
        }
        //
        //
        //
        const InputTempo = document.getElementById('value_tempo');
        InputTempo.addEventListener('blur', function(){
            SetTempo()
        });
        SetTempo()
        //
        //
        //
        const drumscore = document.getElementById('drumscore');
        //
        // Canvas et contexte de la partition
        //
        const score = document.getElementById('score');
        const scorectx = score.getContext('2d');
        scorectx.canvas.width  = drumscore.offsetWidth;
        scorectx.canvas.height = drumscore.offsetHeight;
        //
        // Canvas et contexte des notes
        //
        const canvas = document.getElementById('scoreCanvas');
        const ctx = canvas.getContext('2d');
        ctx.canvas.width  = drumscore.offsetWidth;
        ctx.canvas.height = drumscore.offsetHeight;
        //
        // Lignes de la partition
        //
        const ScoreLines = [60,80,100,120,140];
        //
        //
        //
        const Elements = [
             {Name: 'Snare', Line: ScoreLines[2]}
        ];
        //
        // Patterns
        //
        const Patterns = [
            {
                Name:       'Rll',
                Element:    'Snare',
                Notes:      ['R', 'l', 'l'],
                Checkbox:   false,
                Label:      false,
                Checked:    false,
            },
            {
                Name:       'rrL',
                Element:    'Snare',
                Notes:      ['r', 'r', 'L'],
                Checkbox:   false,
                Label:      false,
                Checked:    false,
            }
        ];
        //
        // Affichage patterns
        //
        const DivPatterns = document.getElementById('div_patterns');
        Patterns.forEach(pattern => {
            pattern.Checkbox = document.createElement('input');
            pattern.Checkbox.type = "checkbox";

            pattern.Label = document.createElement('label')
            pattern.Label.htmlFor = pattern.Name;
            pattern.Label.appendChild(document.createTextNode(pattern.Name));
            
            DivPatterns.appendChild(pattern.Checkbox);
            DivPatterns.appendChild(pattern.Label);
        });
        //
        // Sounds
        //
        const Sounds = [
            {
                Element:    'Snare',
                Type:       'Normal',
                URL:        '',
                Audio:      new Audio('snare_normal.wav')
            },
            {
                Element:    'Snare',
                Type:       'Ghost',
                Audio:      new Audio('snare_ghost.wav')
            }
            
        ];
        //
        // Notes à afficher
        //
        
        const measures = 20;
        const noteWidth = 10;
        const noteHeight = 10;
        const scrollSpeed = 3;
        //
        // Main Droite ou Gauche
        //
        const isAccented = str => str === str.toUpperCase();
        const isRightHand = str => str.toUpperCase() === 'R';
        
        //
        // Créer le challenge
        //
        var notes = [];
        var current_pattern;
        //
        // Dessiner la partition
        //
        function CreerChallenge() {
            notes = [];
            for (var i=0 ; i<measures ; i++){
                current_pattern = Patterns[Math.floor(Math.random() * 2)];
                
                for (var j=0 ; j<current_pattern.Notes.length ; j++){
                    notes.push({
                        x:      canvas.width / 2 + 180 + (notes.length * Distance_Between_Notes) + 1,
                        y:      isRightHand(current_pattern.Notes[j]) ? ScoreLines[2] - 5 : ScoreLines[2] + 5,
                        w:      isAccented(current_pattern.Notes[j]) ? 7 : 4,
                        h:      isAccented(current_pattern.Notes[j]) ? 5 : 3,
                        Audio:  isAccented(current_pattern.Notes[j]) ? new Audio('snare_normal.wav') : new Audio('snare_ghost.wav')
                    })
                }
            }
            console.log(notes);
        }
        //
        // Dessiner la partition
        //
        function drawScore() {
            scorectx.clearRect(0, 0, canvas.width, canvas.height);
            scorectx.strokeStyle = "#A0A0A0";
            
            ScoreLines.forEach(Line => {
                scorectx.beginPath();
                scorectx.moveTo(0, Line);
                scorectx.lineTo(canvas.width, Line);
                scorectx.stroke();
            });
            
            scorectx.beginPath();
            scorectx.moveTo(canvas.width / 2, ScoreLines[0]);
            scorectx.lineTo(canvas.width / 2, ScoreLines[ScoreLines.length-1]);
            scorectx.stroke();
        }
        //
        //
        //
        function nextNote() {
            const secondsPerBeat = 60.0 / Tempo;
            NextNoteTime += 1000 / Distance_Between_Notes;
        }

        //
        // Dessiner et animer les notes
        //
        function drawNotes() {
            
            NextNoteTime = performance.now();
            
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            notes.forEach(note => {
            
                //ctx.fillRect(note.x, note.y, note.w, note.w);
                ctx.beginPath();
                ctx.ellipse(note.x, note.y, note.w, note.h, Math.PI, 0, 2 * Math.PI);
                ctx.fill();
                
                if (note.x > canvas.width / 2 - 5 && note.x <= canvas.width / 2){
                    Current_Audio = note.Audio;
                    note.Audio.play();
                }
                
                //note.x -= scrollSpeed;
                note.x -= Tempo / 15;
            });

            
            //const endTime = performance.now()

            //console.log(`Call to doSomething took ${endTime - startTime} milliseconds ` + endTime)
            //Current_Animation = requestAnimationFrame(drawNotes);
            if (Challenge_Launched){
                //Timer_Challenge = setTimeout(drawNotes, 1);
                Timer_Challenge = setTimeout(() => requestAnimationFrame(drawNotes), 1);
            }
        }
        
        function SetGeneralTimer(){
            const startTime = performance.now()
            General_Timer++;
            document.getElementById('value_timer').innerHTML = General_Timer
            const endTime = performance.now()
            //console.log(`Started ` + startTime + ' | ' + (endTime - startTime) + ' | ' + General_Timer)
        }
        
        
        drawScore();
    });
    </script>
</body>
</html>

And the metronome class:

class Metronome {
    constructor(context) {
        this.context = context;
        this.isPlaying = false;
        this.current16thNote = 0;
        this.tempo = 60;
        this.lookahead = 25.0;
        this.scheduleAheadTime = 0.1;
        this.nextNoteTime = 0.0;
        this.timerID = null;
    }

    nextNote() {
        const secondsPerBeat = 60.0 / this.tempo;
        this.nextNoteTime += 0.25 * secondsPerBeat;
        this.current16thNote++;
        if (this.current16thNote === 16) {
            this.current16thNote = 0;
        }
    }

    scheduleNote(beatNumber, time) {
        const osc = this.context.createOscillator();
        const envelope = this.context.createGain();
        osc.frequency.value = (beatNumber % 4 === 0) ? 1000 : 800;
        envelope.gain.value = 1;
        envelope.gain.exponentialRampToValueAtTime(0.001, time + 0.2);
        osc.connect(envelope);
        envelope.connect(this.context.destination);
        osc.start(time);
        osc.stop(time + 0.2);
    }

    scheduler() {
        console.log(this.nextNoteTime);
        console.log(this.context.currentTime);
        console.log(this.scheduleAheadTime);
        while (this.nextNoteTime < this.context.currentTime + this.scheduleAheadTime) {
            this.scheduleNote(this.current16thNote, this.nextNoteTime);
            this.nextNote();
        }
        this.timerID = setTimeout(this.scheduler.bind(this), this.lookahead);
    }

    start() {
        if (!this.isPlaying) {
            this.isPlaying = true;
            this.current16thNote = 0;
            this.nextNoteTime = this.context.currentTime;
            this.scheduler();
        }
    }

    stop() {
        this.isPlaying = false;
        clearTimeout(this.timerID);
    }

    setTempo(newTempo) {
        this.tempo = newTempo;
    }
}

Unchecked runtime.lastError: Could not load file: ‘content.js’

So, I am building a Chrome extension using manifest v3. My content.js is not even being loaded; it’s in the root directory, and when I run ‘npm run build,’ there are no errors
Has anyone here experienced this same error?

I am using ReactJS, Vite, and JavaScript to build this extension.

I am not an experienced dev and here is the code:

content.js

console.log("content.js loaded!");
let fetchDefinition = async (word) => {
  try {
    let response = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${word}`)
    let data = await response.json()
    console.log(data);
    return data
  }
  catch(e) {
    console.error(e);
  }
}

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  console.log(request, sender, sendResponse);
    if (message.action === "findMeaning") {
      const selectedText = message.text.trim().toLowerCase();
      if (selectedText) {
        // Showing a temporary loading bubble
        showDefinitionPopup(`Looking up: "${selectedText}"`);
        let data = await fetchDefinition(selectedText)

        
        setTimeout(() => {
          showDefinitionPopup(`Definition of "${selectedText}":n mock def here`);
        }, 1000);
      }
    }
  });
  
  function showDefinitionPopup(content) {
    removeExistingPopup();
  
    const popup = document.createElement("div");
    popup.id = "wmd-popup";
    popup.innerText = content;
  
    Object.assign(popup.style, {
      position: "fixed",
      top: "20px",
      right: "20px",
      background: "#fff",
      color: "#000",
      padding: "12px",
      border: "1px solid #ccc",
      borderRadius: "8px",
      boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
      zIndex: "999999",
      maxWidth: "300px",
      fontSize: "14px",
      whiteSpace: "pre-wrap"
    });
  
    document.body.appendChild(popup);
  
    setTimeout(() => {
      popup.remove();
    }, 6000);
  }
  
  function removeExistingPopup() {
    const existing = document.getElementById("wmd-popup");
    if (existing) existing.remove();
  }
  

background.js

chrome.runtime.onInstalled.addListener(() => {
    chrome.contextMenus.create({
      id: "lookupMeaning",
      title: "Find Meaning",
      contexts: ["selection"],
    });
  });
  
  chrome.contextMenus.onClicked.addListener((info, tab) => {
    console.log("Context menu clicked!", info, tab); 
    if (info.menuItemId === "lookupMeaning") {
      // Inject content script first
      chrome.scripting.executeScript({
        target: { tabId: tab.id },
        files: ["content.js"]
      }, () => {
        // Then sending message
        chrome.tabs.sendMessage(tab.id, {
          action: "findMeaning",
          text: info.selectionText
        });
      });
    }
  });
  

manifest.config.js

export default {
    name: "Word Meaning Detective",
    version: "1.0.0",
    manifest_version: 3,
    description: "Right-click or select any word to see its meaning instantly.",
    permissions: ["contextMenus", "scripting", "tabs", "activeTab"],
    host_permissions: ["<all_urls>"],
    background: {
      service_worker: "background.js"
    },
    action: {
      default_popup: "popup.html",
      default_icon: "icon.png"
    },
    content_scripts: [
      {
        matches: ["<all_urls>"],
        js: ["content.js"]
      }
    ],
    icons: {
      "16": "icon.png",
      "48": "icon.png",
      "128": "icon.png"
    }
  };

How can I change a progress bar on a webpage that checks for clicked links and completed activities? [closed]

OS: Windows 10 Pro 19045.5679
Browser: Microsoft Edge Version 135.0.3179.54
Sorry for vague preface here is the situation:

I work for Toyota, and I am required to complete Engage XP missions to build on product knowledge and to give my sales manager the satisfaction knowing that I have a higher score than my respective coworkers in service. I digress.

This module has an issue where the PDF that is required for viewing cannot be found after clicking on “Check It Out,” so I cannot complete this activity to take the test and finish the module. Unfortunately, it has been this way for at least two weeks with no repair in sight. If you look at my screenshot you will notice that I have the developer tools open to try to inspect each element on the page. Engage Tasks and Progress I have not developed anything or studied webpage structure, front-end or back-end, since 2015 so I need some direction. Is there a way to tinker with the developer tools, like an event listener, to permanently save the task as completed? When I click on “check it out,” it does not direct me to a PDF, but a webpage hosting the PDF where the file cannot be found. Typically, after that PDF link is clicked, I can click “Back to Mission” and it will show as completed on the module’s homepage. See photo below. Thanks!
404 No File

I tried changing div and span elements but was reminded that only changes what I see in the moment but will not save any progress, it is just design elements. I sifted through event listeners but was not sure what might be the correct course of action. I did find a file in the event listeners under click -> a.react-dom.production.min.js (react-dom.production.min.js:114) which points to “Check it out,” but I do not know if that is wishful thinking or that I am onto something. See below:
Click Event Listener

Error when Importing External Javascript into Angular Typescript

I have this bundled JS that i want to import into my TS App
The Bundled JS File
I tried adding it into index.html under script tag, it worked fine locally
I also use ‘declare var widget:any’ on my ts and worked fine, until i build my app into webpack

after i build into webpack into /dist folder and deployed into server it returned Unexpected token ‘<‘ at widget.js 1:1

after i opened the js file from console its exactly the same as my index.html file hence the error Unexpected token ‘<‘ because index.html start from <!DOCTYPE html

ive tried importing the JS file straight from my TS
with something like

import * as widget from ‘/src/xx/xx/widget.js’
and
importing ‘/src/xx/xx/widget.js’ in vendor.ts file

but everytime i tried to import JS when building it returned this error
Module Parse Failed : unexpected token, you may need an appropriate loader to handle this file type
Error when building

is there any way i can import this JS file into my angular app ?
ive tried searching for ways to import JS into the webpack but returned no results

What’s the best approach to integrate AI-powered autocomplete or suggestion features into a custom web-based form using JavaScript or Python? [closed]

I’m working on a web-based form and want to enhance the user experience by adding AI-powered autocomplete or suggestion features — similar to how Gmail or ChatGPT offers smart predictions while typing.

Specifically, I want the system to suggest relevant text, phrases, or options based on what the user is typing into a form input field (e.g., product descriptions, FAQs, support tickets).

I’m open to using JavaScript (frontend) for real-time interaction and Python (backend) for AI model handling.

After adding ssr ( angular Universal ) to angular 19 ngmodule approch. Angular Universal SSR works fine, but CSR not working

After the initial render with Server-Side Rendering (SSR), my Client-Side Rendering (CSR) is not functioning properly. I am using the NgModule approach, and my project was previously running on Angular 15. After upgrading to Angular 19 and integrating Angular Universal, this issue has surfaced. The problem persists even after following the recommended configurations for Angular Universal. I would greatly appreciate any insights or solutions that could resolve this issue, particularly regarding the CSR not initializing correctly post-SSR

I start with:

  • npx -p @angular/cli@19 ng add @angular/ssr
    This created and updated required files. After this I installed below package
  • npm install @angular/platform-server --legacy-peer-deps

Below are my scripts in package.json:

 "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "dev:ssr": "ng run Angular-POMS:serve-ssr",
    "serve:ssr": "node dist/Angular-POMS/server/main.js",
    "build:ssr": "ng build && ng run Angular-POMS:server",
    "prerender": "ng run Angular-POMS:prerender"
  }

When I run npm run dev:ssr, then I get console values in terminal in first render and expecting same value be console in browser but nothing is happening in CSR side. CSR is totally not working

below is server terminal ouput

 npm run dev:ssr  

> Angular-POMS@1.0.0 dev:ssr
> ng run Angular-POMS:serve-ssr

****************************************************************************************
This is a simple server for use in testing or debugging Angular applications locally.
It hasn't been reviewed for security issues.

DON'T USE IT FOR PRODUCTION!
****************************************************************************************
    Components styles sourcemaps are not generated when styles optimization is enabled.
    Components styles sourcemaps are not generated when styles optimization is enabled.
✔ Server application bundle generation complete.

Initial chunk files | Names                        | Raw size
vendor.js           | vendor                       |  7.75 MB | 
main.js             | main                         | 96.01 kB | 

                    | Initial total                |  7.84 MB

Lazy chunk files    | Names                        | Raw size
937.js              | views-quote-quote-module     |  3.59 MB | 
565.js              | views-order-order-module     |  3.56 MB | 
929.js              | xhr2                         | 15.65 kB | 
140.js              | views-account-account-module |  9.82 kB | 

Build at: 2025-04-09T12:00:35.020Z - Hash: b0584ff083856287 - Time: 146208ms
✔ Browser application bundle generation complete.
⠋ Generating index html...9 rules skipped due to selector errors:
  .table>>*>* -> Did not expect successive traversals.
  .table-sm>>*>* -> Did not expect successive traversals.
  .table-bordered>>* -> Did not expect successive traversals.
  .table-bordered>>*>* -> Did not expect successive traversals.
  .table-borderless>>*>* -> Did not expect successive traversals.
  .form-floating>~label -> Did not expect successive traversals.
  .btn-group>+.btn -> Did not expect successive traversals.
  .btn-group>+.btn -> Did not expect successive traversals.
  .btn-group-vertical>+.btn -> Did not expect successive traversals.
✔ Index html generation complete.

Initial chunk files | Names   | Raw size | Estimated transfer size
main.js             | main    | 64.96 kB |                16.96 kB
scripts.js          | scripts | 10.82 kB |                 3.07 kB

7 unchanged chunks

Build at: 2025-04-09T12:00:55.730Z - Hash: 7128f687559f95fb - Time: 110769ms

Warning: D:GithubAngular.POMSAngular.POMSsrcappServicescryptocrypto.service.ts depends on 'crypto-js'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies

Warning: D:GithubAngular.POMSAngular.POMSsrcappviewsorderupload-orderupload-order.component.ts depends on 'csvtojson'. CommonJS or AMD dependencies can cause optimization bailouts.        
For more info see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies



Compiled successfully.
** Angular Universal Live Development Server is listening on http://localhost:4200, open your browser on http://localhost:4200 **
(node:596) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
isPlatformBrowser server

but nothing in the browser console

Echart custom renderItem() optimalizations

I am creating event graph with hundred thousand of events and i want them to be rendered as lines in time using echarts.

Currently,I am rendering this like chart type: ‘custom’, with renderItem() function that simply put small rect on position.

function renderItem(params, api) {
    var categoryIndex = api.value(0);
    var shape;
    var style;

    var start = api.coord([api.value(1), categoryIndex]); // get element position
    var height = api.size([0, 1])[1] * 0.6; //calculate element height
    style = api.style({fill:this.data.colors[categoryIndex]}); // get color in the category

    //create dimensions
    shape = {
        x: start[0]-1,
        y: start[1] - height / 2,
        width: 2,
        height:  height ,
      }
    //return shape
    return (
      shape && {
        type: 'rect',
        shape: shape,
        style: style
      }
    );
};

But this aproche is relatively slow.
Viedo example of loading

Can i somehaw fasten this process by optimalizations?

I think about grouping the little rerctangles to a bigger one if they are overlaping.
But i dont know where to start.
Becouse it renders one item at time i cant figured out haw to optimalize it.

Any opinion or speculation or help would be welcomed.

How to integrate Tableau private dashboard in Angular

I have set up a private tableau dashboard and would like to integrate it with my Angular application.
I have used the tableau-viz tag provided by the dashboard, but it asks for login. On login with the correct credentials, it gives an error and doesn’t load the dashboard.
Is there a way I can bypass the login for my angular application

How to convert a simple select to use AngularJS data array?

I have an old system which needs a bit of a tweak. All works as I expect when I have some AngularJS declarations and plain HTML/JavaScript. Current code is:

<div ng-controller="myController as vm">
 
    <select name="items" id="items">
    </select>
 
    <script type="text/javascript">
        // Sample data
        const options = [
            { value: '1', text: 'Option 1' },
            { value: '2', text: 'Option 2' },
            { value: '3', text: 'Option 3' },
        ];
 
        // Get the select element
        const select = document.getElementById('items');
 
        // Populate the select with options
        options.forEach(option => {
            const opt = document.createElement('option'); // Create a new <option> element
            opt.value = option.value; // Set the value attribute
            opt.textContent = option.text; // Set the visible text
            select.appendChild(opt); // Add the option to the <select>
        });
 
    </script>
</div>

I have some data in myController declared in the first div ng-controller which returns an array of data.

Instead of having the items hardcoded as they currently are, how can I use my vm variable to call getData (which I already have and is bringing back data) so the items are replaced by the data retrieved by the AngularJS controller?

I tried

 const options = vm.getData();

but that didn’t work.

I have tried other sites for syntax reference but either way I can’t connect it using the JavaScript declaration above