Embeding google sheets in google sites with google app script

I am currently integrating my values from my google sheet into my google site. I know, this would also be possible by just placing the box of the google sheet into the site but I want to improve the style by using google app script. I got following code:

<!DOCTYPE html>
<html>
<head>
    <base target="_top">
    <script>
        function submitForm() {
            const name = document.getElementById('name').value;
            const message = document.getElementById('message').value;

            google.script.run.withSuccessHandler(function() {
                document.getElementById('name').value = '';
                document.getElementById('message').value = '';
                displayMessages(); // Refresh the message list after submission
            }).withFailureHandler(function(error) {
                alert("Error submitting message: " + error.message);
            }).submitMessage(name, message);
        }

        function displayMessages() {
            google.script.run.withSuccessHandler(renderMessages).getMessages(); // Calling getMessages
        }

        function renderMessages(data) {
            const dataList = document.getElementById('dataList');
            dataList.innerHTML = ''; // Clear previous data

            // Handle null or unexpected data format
            if (!data || !Array.isArray(data) || data.length === 0) {
                const listItem = document.createElement('li');
                listItem.textContent = "No messages available.";
                dataList.appendChild(listItem);
                return;
            }

            // Process each row of data
            data.forEach(function(row) {
                // Ensure the row is an array and has the expected length
                if (Array.isArray(row) && row.length === 3) {
                    const listItem = document.createElement('li');
                    
                    // Format the timestamp using toLocaleString
                    const formattedDate = new Date(row[0]).toLocaleString(); // Format the date
                    listItem.textContent = `${formattedDate} - ${row[1] || 'Anonymous'}: ${row[2] || 'No message'}`; // Format the message display
                    dataList.appendChild(listItem);
                } else {
                    console.error("Unexpected row format:", row); // Log unexpected row formats
                }
            });
        }

        window.onload = function() {
            displayMessages(); // Load messages when the page is opened
        };
    </script>
</head>
<body>
    <h1>Message Board</h1>
    <form onsubmit="submitForm(); return false;">
        <label for="name">Name:</label>
        <input type="text" id="name" required>
        <br>
        <label for="message">Message:</label>
        <textarea id="message" required></textarea>
        <br>
        <input type="submit" value="Submit">
    </form>
    <h2>Messages:</h2>
    <ul id="dataList"></ul>
</body>
</html>

and following google app script:

function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}

function submitMessage(name, message) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const timestamp = new Date();
  sheet.appendRow([timestamp, name, message]);
}

function getMessages() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const data = sheet.getDataRange().getValues();

  // Log the raw data retrieved from the sheet
  Logger.log("Raw data from sheet: " + JSON.stringify(data));

  if (data.length < 1) {
    // If there's no data (only header), return an empty array
    return [];
  }

  // Remove the header row
  data.shift(); 

  // Log the data after removing the header
  Logger.log("Data after removing header: " + JSON.stringify(data));
  Logger.log(data);

  return data;
}

And I think the code.gs works fine as the output corresponds to the values of my google sheet. So my question is, where the error would be regarding the problem, that the site doesnt show the values of the site but the input works absolutely fine.

Kind regards.

I tried to adjust the html several times within the browser console and I found that the error occurs at the forEach as the data is Null but the code.gs returns a list with the correct values.

Wrap overflowing menu items in dropdown if there’s not enough space

I have a Bootstrap navbar menu, and I’m trying to wrap overflowing menu items in a dropdown if there’s not enough avaliable space. I have this solution – it works perfectly and does what I’m looking for:

const contentBar = document.querySelector(".context-bar")
const dropdown = document.querySelector(".grouped-content")

const update = () => {
  const offsetTop = contentBar.offsetTop
  dropdown.innerHTML = ""

  document.querySelectorAll(".context-bar > a").forEach((item) => {
    if (item.offsetTop > offsetTop) {
      let li = document.createElement("li")
      li.innerHTML += item.outerHTML
      dropdown.appendChild(li)
    }
  })
}

update()
window.addEventListener("resize", update)
.link-bar {
  display: flex;
  position: relative;
  background: #ddd;
  padding: 0 10px;
  color: #000;
  width: 100%;
  box-sizing: border-box;
}

.context-bar {
  flex: 1;
  height: 60px;
  overflow: hidden;
}

.context-bar-link, .grouped-link {
  color: #000;
  display: inline-block;
  white-space: nowrap;
  max-width: 18rem;
  text-overflow: ellipsis;
  overflow: hidden;
  padding: 20px 10px;
}

.grouped-content {
    display: none;
    list-style-type: none;
    position: absolute;
    background-color: #f9f9f9;
    min-width: 160px;
    right: 10px;
    max-height: 200px;
    overflow-y: auto;
}

.grouped:hover .grouped-content {
 display: block;
}

body {
  padding-top: 50px;
}


a {
  text-decoration: none;
}
<div class="container">
  <nav class="link-bar">
    <div class="context-bar">
      <a href="#" class="context-bar-link">Item 1</a>
      <a href="#" class="context-bar-link">Item 22</a>
      <a href="#" class="context-bar-link">Item 333</a>
      <a href="#" class="context-bar-link">Item 4444</a>
      <a href="#" class="context-bar-link">Item 5555555</a>
      <a href="#" class="context-bar-link">Item 66</a>
      <a href="#" class="context-bar-link">Item 7777777777777</a>
      <a href="#" class="context-bar-link">Item 8</a>
      <a href="#" class="context-bar-link">Item 999999</a>
      <a href="#" class="context-bar-link">Item 10101010</a>
      <a href="#" class="context-bar-link">Item 1111</a>
      <a href="#" class="context-bar-link">Item 12121212</a>
      <a href="#" class="context-bar-link">Item 1313131313131</a>
      <a href="#" class="context-bar-link">Item 1414</a>
      <a href="#" class="context-bar-link">Item 15</a>
      <a href="#" class="context-bar-link">Item 16161616</a>
      <a href="#" class="context-bar-link">Item 1717</a>
      <a href="#" class="context-bar-link">Item 18181818181818</a>
      <a href="#" class="context-bar-link">Item 191919</a>
      <a href="#" class="context-bar-link">Item 20</a>
      <a href="#" class="context-bar-link">Item 212121</a>
      <a href="#" class="context-bar-link">Item 2222</a>
    </div>
    <div class="grouped">
      <a href="#" class="grouped-link">More</a>
      <ul class="grouped-content"></ul>
    </div>
  </nav>
</div>

However, it doesn’t woth with Bootstrap’s navbar – probably because we can’t check for offsetTop? How can I change the script to work with the Bootstrap navbar?

This is what I have:

const contentBar = document.querySelector(".context-bar")
const dropdown = document.querySelector(".grouped-content")

const update = () => {
  const offsetTop = contentBar.offsetTop
  dropdown.innerHTML = ""

  document.querySelectorAll(".context-bar > li").forEach((item) => {
    if (item.offsetTop > offsetTop) {
      let li = document.createElement("li")
      li.innerHTML += item.outerHTML
      dropdown.appendChild(li)
    }
  })
}

update()
window.addEventListener("resize", update)
.context-bar {
  flex: 1;
  height: 60px;
  overflow: hidden;
}

.nav-link,
.grouped-link {
  color: #000;
  display: inline-block;
  white-space: nowrap;
  max-width: 18rem;
  text-overflow: ellipsis;
  overflow: hidden;
  padding: 20px 10px;
}

.grouped-content {
  display: none;
  list-style-type: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  right: 10px;
  max-height: 200px;
  overflow-y: auto;
}

.grouped:hover .grouped-content {
  display: block;
}

body {
  padding-top: 50px;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<nav class="navbar navbar-expand-sm link-bar">
  <ul class="navbar-nav context-bar">
    <li class="nav-item"><a href="#" class="nav-link">Item 1</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 22</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 333</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 4444</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 5555555</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 66</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 7777777777777</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 8</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 999999</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 10101010</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 1111</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 12121212</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 1313131313131</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 1414</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 15</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 16161616</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 1717</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 18181818181818</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 191919</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 20</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 212121</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Item 2222</a></li>
    <li class="grouped">
      <a href="#" class="grouped-link">More</a>
      <ul class="grouped-content"></ul>
    </li>
  </ul>
</nav>
</div>

How can I modify the script to work with the styling from Bootstrap? Anyone with a good idea? Thank you.

Cart Quantity Update using flask

I want to implement quantity update option on cart by using + and – button to increase or decrease the quantity and I dont know how to implement this, I passed the quantity input as hidden to retrieve in flask, and I have tried by writing Update query to update the database in flask but still I cant identify how to implement this help me complete this process

I have tried by retrieving data in flask and passed the update query to update the database it not gives any error but also I have debugged that to identify the data retrieve or not in that the output give quantity: None now I want to implement the quantity update option in cart using flask

Reactivity in $effect goes away if I remove a console.log()

I have a $state with an array:

let clicks = $state([])

I have an effect, which references the clicks state:

$effect(() => {
    // Box selection
    if (autoDetectSettings.value.mode === 'box' && drawingBox && clicks.length === 2) {
        const poly = objectSchema.parse({
            id: createId(),
            type: 'poly',
            coords: [
                { x: clicks[0].x, y: clicks[0].y },
                { x: clicks[0].x, y: clicks[1].y },
                { x: clicks[1].x, y: clicks[1].y },
                { x: clicks[1].x, y: clicks[0].y },
            ],
            color: '#ffffff',
            opacity: 0.15,
            stroke_color: '#ffffff',
            stroke_opacity: 1,
            stroke_width: 2,
            blend_mode: 'normal',
        })
        artboard.objects.push(poly)
    }
})

Adding an $inspect shows that the value of clicks is updating, but the effect is not triggering. Adding a console.log(clicks) at the start of the effect fixes the issue. What am I doing wrong?

Assigning css style in type script using setAttribute

I am trying to assign element’s attributes in typescript using setAttribute like this w3school example

Here is my JavaScript:

const p = document.createElement('p');
p.setAttribute('class', 'demoClass');
p.innerText = 'Hello';

and .css:

.demoClass {
  background-color: #00ffff !important;  
}

But this way it doesn’t take the style.
The only solution I’ve found is the following:

p.setAttribute('style', 'background-color: #00ffff !important');

Does anyone know how I can give the style using the class and not directly assigning it? Thank you in advance.

How to make LLM update code in the code editor seamlessly

So I have a project I’m working on and it will require an LLM to update existing code and write it back to the editor,where I’m having issues is finding a good way to update anywhere within the code without Messing up unchanged ones, I know converting the source code to AST can help when doing function/class wide updates it has easy as transversing the nodes and identifying which function or classes require change.

But for use cases where the updates are limited to few lines of code or for code that are just scripts with no classes and functions,I can’t really come up with a good solution to update the code with messing up other lines that aren’t affected, I’ve tried searching on Google to see similar implementations or articles on it but all of them only talk about how to parse and transverse AST.

how to prevent page reload after file upload

I wrote some code to provide image upload function. After uploading, the html page should show the image name of the uploaded file.

HTML CODE:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>test</h1>
    <form id="uploadForm">
        <input type="file" id="myFiles" accept="image/*" multiple />
        <button>Submit</button>
    </form>
    <h2></h2>
    <script>
        const form = document.getElementById("uploadForm")
        const sendFiles = async () => {
            const myFiles = document.getElementById("myFiles").files
            const formData = new FormData()
            Object.keys(myFiles).forEach(fk => {
                console.log("%%%%%%%%", Object.keys(myFiles), fk, typeof (fk))
                formData.append(myFiles.item(fk).name, myFiles.item(fk))
            })
            const res = await fetch("http://127.0.0.1:3500/upload", {
                method: "POST",
                body: formData
            })
            const json = await res.json()
            const h2 = document.querySelector("h2")
            h2.textContent = `message:${json?.message}`
        }

        form.addEventListener("submit", (ev) => {
            ev.preventDefault()
            sendFiles()
        })
    </script>
</body>

NODE JS CODE:

const express = require("express")
const path = require("path")
const fileUpload = require("express-fileupload")
const app = express()
const PORT = process.env.PORT || 3500
const cors = require("cors")

app.use(cors())
app.get("/", (req, res) => {
    res.sendFile(path.join(__dirname, "index.html"))
})
app.post("/upload",
    fileUpload({ createParentPath: true }),
    (req, res) => {
        const file = req.files
        Object.keys(file).forEach(k => {
            const fileP = path.join(__dirname, "uploadFolder", file[k].name)

            file[k].mv(fileP, (e) => {
                if (e) return res.status(500).json({ status: "err!!!!!", message: e })
            })
        })

        return res.json({ message: Object.keys(file).toString() })
    })

app.listen(PORT, () => { console.log(`listen on port ${PORT}`) })

I uploaded an image “cookie_screenshot” and submitted it. The html showed the name just for a sec and the page reloaded immediately. How to make the name always displayed on screen?

I use express 4.21.1nodemon 3.1.7.

BEFORE SUBMIT:
enter image description here

DISPLAY NAME FOR INSTANT:
enter image description here

PAGE RELOADED IMMEDIATELY:
enter image description here

How to decode base64 to pdf in POSTMAN

I want to send pdf file by using Postman. Before I send it, I decode base64 in code below.

in Scripts Tab (Pre-request)

var base64 = "JVBERi0xLjMKJcT....."
var pdf = atob(base64); //Decode
pm.environment.set("pdf", pdf);

After that, I set body by using parameter environment (pdf) before in request body
enter image description here

After I send request to destination I can open pdf but file pdf is empty. What should I do?

Why pdf become empty. I try converting base64 to pdf in online, PDF is not empty.

Is there a library that can be used to test multiple techniques of tcp/udp holepunching? [closed]

I have tried to punch a hole using netcat in udp mode and couldn’t make it work, i also tried libp2p circuit-relay technique to no avail, i also experimented with bittorrent holepunching in the past and it didn’t work.

I then discovered pystun3 and when i run it in the peers i control, i get “Full Cone” as the nat type of both my peers, which should in theory be the easiest NAT type to punch a hole in but i didn’t had much success doing it.

Is there a library that can be used to traverse the NAT(punch a hole) between 2 peers?

the library should contain multiple techniques to test to find which technique works best for these peers, I do have access to a public peers which i can use as a signaling server if it is need.

the library can be in about any language, go,c,c++,python,javascript …etc

how to smooth transaction with animejs in three js when the target camera position move?

I had a button when the current position was on the top and then it moved to the bottom and centered with Vector3, but it was not smooth, it is like when we do **display: none; to display: block** for my transaction above here,

const setupCameraForPart2 = (propsCameraPart: CameraPropsPart): void => {
  const { center, distance, name } = propsCameraPart;
  if (!name) {
    console.error('Part name is not provided);
    return;
  }
  console.log('Current Position:', _camera.position);
  const targetPosition = new THREE.Vector3(center.x, center.y, center.z + (distance * 1));
  console.log('Target Position:', targetPosition);

  // Animate opacity to 0 first
  anime({
    targets: '.viewport-three-d > canvas',
    opacity: 0,
    duration: 400,
    easing: 'easeInOutQuad',
    complete: () => {
      // After opacity animation completes, animate the camera position
      anime({
        targets: _camera.position,
        x: targetPosition.x,
        y: targetPosition.y,
        z: targetPosition.z,
        duration: 1200,
        easing: 'easeInOutQuad',
        update: () => {
          renderSceneAndCamera();
        },
        complete: () => {
          _camera.lookAt(_scene.position);
          _control.target.set(center.x, center.y, 0);
          _control.update();

          // Animate opacity back to 1 after camera movement completes
          anime({
            targets: '.viewport-three-d > canvas',
            opacity: 1,
            duration: 1000,
            delay: 800,
            easing: 'easeInOutQuad',
            update: () => {
              renderSceneAndCamera();
            }
          });
        }
      });
    }
  });

  _camera.lookAt(_scene.position);
  _control.target.set(center.x, center.y, center.z);
  _control.update();
}

where for the current position camera into the target camera

Current Position: _Vector3 {x: 0, y: 1.3438600897789001, z: 0.4259342574950393}
----
Target Position: _Vector3 {x: 0, y: 1.5364376306533813, z: 0.20977267946690245}

my current function did not have transactions when it was moved to another position, my goal here is to make the transaction when the current and target positions move

Turn an FFmpeg command into an FFmpeg wasm exec function

I have this gnarly FFmpeg command:

ffmpeg -i music.mp3 -i video.mp4 -i speech.mp3 -filter_complex "[0:a]atrim=0:$(ffprobe -i speech.mp3 -show_entries format=duration -v quiet -of csv=p=0),volume=0.08[trimmed_music]; [2:a]volume=2[speech]; [1:v]loop=-1,trim=duration=$(ffprobe -i speech.mp3 -show_entries format=duration -v quiet -of csv=p=0),setdar=9/16[vout]; [trimmed_music][speech]amix=inputs=2:duration=first[aout]" -map "[vout]" -map "[aout]" -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 192k final_output.mp4

What it does is:

  • Get the duration of a speech.mp3 file
  • Crop a video.mp4 to portrait dimensions
  • Trim a longer music.mp3 file to the duration of the speech
  • Loop a the video and trim the final loop so that the whole thing matches the duration of the speech
  • Adjust the volume of the music and speech
  • Combine them all into a single video with talking (speech) and music

I can’t figure out how to run it using the FFmpeg wasm. I realise ffprobe isn’t a thing with the wasm so we’ll have to find a different way to get the duration of the speech.mp3 by probably breaking it up into 2 or more exec functions, but I have no idea how to do that, which is why I’m here asking for help.

For reference, here’s the function into which I want to insert this exec function, but feel free to change it however needed. And let me know if I need to provide more information.

  const processVideo = async (speech, video, music) => {
    const ffmpeg = new FFmpeg();

    // ffmpeg loading code goes here, assume that part works without issue

    await ffmpeg.writeFile("video.mp4", new Uint8Array(video));
    await ffmpeg.writeFile("speech.mp3", new Uint8Array(speech));
    await ffmpeg.writeFile("music.mp3", new Uint8Array(music));

    await ffmpeg.exec([
      // command(s) should go here
    ]);

    const fileData = await ffmpeg.readFile("final_output.mp4");
    const blob = new Blob([fileData.buffer], { type: "video/mp4" });
    const blobUrl = URL.createObjectURL(blob);

    return blobUrl;
  };

Center the image within the frame without stuttering – HTML5 Canvas

I have the above code consisting of image and declarative json. Please help me fix the code so that the displayed images are not jerky and it is centered.

const data = {
  scaleX: 133,
  scaleY: 133,
  res: {
      "101": { "w": 704, "h": 354, "x": 0, "y": 0 },
      "102": { "w": 652, "h": 358, "x": 705, "y": 0 },
      "103": { "w": 652, "h": 361, "x": 1358, "y": 0 },
      "104": { "w": 704, "h": 351, "x": 0, "y": 362 },
      "105": { "w": 652, "h": 358, "x": 705, "y": 362 },
      "106": { "w": 652, "h": 339, "x": 1358, "y": 362 },
      "107": { "w": 671, "h": 351, "x": 0, "y": 721 },
      "108": { "w": 671, "h": 354, "x": 672, "y": 721 },
      "109": { "w": 636, "h": 386, "x": 1344, "y": 721 },
      "110": { "w": 671, "h": 355, "x": 0, "y": 1108 },
      "111": { "w": 671, "h": 343, "x": 672, "y": 1108 },
      "112": { "w": 636, "h": 358, "x": 1344, "y": 1108 }
  },
  frames: [
      { "x": -352, "y": -403, "res": 104 },
      { "x": -337, "y": -403, "res": 108 },
      { "x": -327, "y": -403, "res": 102 },
      { "x": -318, "y": -402, "res": 112 },
      { "x": -327, "y": -402, "res": 105 },
      { "x": -337, "y": -399, "res": 110 },
      { "x": -352, "y": -399, "res": 101 },
      { "x": -337, "y": -396, "res": 107 },
      { "x": -327, "y": -409, "res": 103 },
      { "x": -318, "y": -437, "res": 109 },
      { "x": -327, "y": -398, "res": 106 },
      { "x": -337, "y": -400, "res": 111 }
  ],
  frameRate: 12
};

// Canvas setup
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const image = new Image();
image.src = "http://171.244.52.145/ver/0/res/wingui/wing226.png"; // Your uploaded image path

// Set canvas dimensions
const frameWidth = 700; // Max frame width
const frameHeight = 500; // Max frame height
canvas.width = frameWidth;
canvas.height = frameHeight;

// Animation variables
let currentFrame = 0;
const totalFrames = data.frames.length;
const frameInterval = 1000 / data.frameRate; // Time per frame in ms
let lastFrameTime = 0;

// Draw a frame
function drawFrame(timestamp) {
  if (!lastFrameTime) lastFrameTime = timestamp;
  const elapsedTime = timestamp - lastFrameTime;

  if (elapsedTime > frameInterval) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      const frameData = data.frames[currentFrame];
      const { x: destX, y: destY, res } = frameData;
      const { x: srcX, y: srcY, w: srcW, h: srcH } = data.res[res];

      const offsetX = (canvas.width - srcW) / 2;
      const offsetY = (canvas.height - srcH) / 2;

      const centerX = canvas.width - destX / 2;
      const centerY = canvas.height - destY / 2;
      const radio = Math.PI + Math.round(centerX, centerY) + Math.ceil(hi)

      ctx.drawImage(
          image,
          srcX, srcY,
          srcW, srcH,
          offsetX, offsetY,
          srcW, srcH
      );

      currentFrame = (currentFrame + 1) % totalFrames;
      lastFrameTime = timestamp;
  }

  requestAnimationFrame(drawFrame);
}

image.onload = () => {
  requestAnimationFrame(drawFrame);
};

You can copy the following code to try it out.

I was able to crop the images into frames after centering the parameters in the json. Everything is fine but the frames are jerky. It is necessary to use the x,y parameters in the “frame”. But it’s a negative number, I don’t know how to use it

How to generate a TOC (Table of Contents) in Node.js based on a list

“I am using Node.js to generate a TOC in HTML. How can I generate this output with high performance?”

Source:

const data = [
{ text: "A2", level: 2 },
{ text: "B2", level: 2 },
{ text: "B3", level: 3 },
{ text: "B3", level: 3 },
{ text: "C2", level: 2 },
{ text: "C3", level: 3 },
{ text: "C4", level: 4 },
{ text: "C4", level: 4 },
];

Experted:

<ul class="markdownIt-TOC">
    <li><a href="#A2">A2</a></li>
    <li><a href="#B2">B2</a></li>
    <li><a href="#C2">C2</a></li>
    <ul>
        <li><a href="#C3">C3</a></li>
    </ul>
    <ul>
        <li><a href="#C4">C4</a></li>
        <li><a href="#C4">C4</a></li>
    </ul>
</ul>

Custom Event not triggered on Modal Dialog Page

one of classic Report columns setted to be link and its javascript link which is javascript:$.event.trigger({type:'customEvent',id:'#ID#'});
Dynamic Action created with the following attributes:

When: custom
Custom Event: customEvent
Selection Type:  JavaScript Expression
 JavaScript Expression : document

the action is Execute javascript code:

console.log('event triggered')
var student_id = this.browserEvent.student_id
console.log(student_id)

this scenario working perfectly in Normal Page, but not in Modal Dialog Page. Why? Any suggestions?

How to Parse React and Angular Legacy codebase and Generate documentation using LLM?

I’m working on a project similar to RepoAgent, which generates documentation for Python code. In their approach, they use Jedi to analyze references, imports, and dependencies, creating a dependency graph between code files.

However, I want to extend this concept to work with React and Angular codebases. I need to identify and document dependencies, components, imports, and their relationships across the codebase.

Currently, I’m trying to use Tree-sitter to parse the code and extract the required information, but I’m finding this approach quite challenging.

Can someone suggest:

  1. Better tools or libraries for analyzing React/Angular codebases?
  2. Effective methods for creating a dependency graph for JavaScript/TypeScript files?
  3. Best practices for handling large projects in this context?