Solution to create Access Request Form for Tableau dashboard

Our team is currently looking for a solution to manage Tableau dashboard access requests efficiently. Ideally, we need:

  • A form where users can submit access requests (specifying market, category, etc.)
  • An approval workflow where requests are reviewed & approved by managers
  • Once approved, the user should automatically receive access to the Tableau dashboard

We are considering building this form as an Alteryx Analytical App but would love to hear your thoughts on:

  • Pros & cons of using Alteryx for this (e.g., performance, scalability, maintenance)
  • Alternative solutions/tools that might be more efficient (e.g., Power Automate, ServiceNow, or custom scripts)

Has anyone implemented something similar? Would love to hear your experiences & recommendations!

Omit “” in Database Text Storage [duplicate]

I have a message system. When storing a message in the database, it should store normally and display normally. For example, “What’s Up?” -> “What’s Up?”. However, it stores and displays as “What’s Up” with a backlash after the “t”. How can I fix this so that the message is sent and displayed normally, as it is supposed to.

Here’s my code currently:

<div id="chatSection" class="consult-window-section" style="display: none;">
<?php
// Load chat messages
$chatQuery = "SELECT * FROM consultation_chat
              WHERE consultation_id = $consultation_id
              ORDER BY sent_at ASC";
$chatResult = mysqli_query($connection, $chatQuery);
?>

<div class="chat-box">
  <div class="chat-messages" id="chatMessages">
    <?php while ($chat = mysqli_fetch_assoc($chatResult)): ?>
      <div class="chat-message <?= $chat['sender_id'] == $_SESSION['id'] ? 'sent' : 'received' ?>">
        <p><?= htmlspecialchars(stripslashes($chat['message']), ENT_QUOTES) ?></p>
        <span class="timestamp"><?= date("H:i", strtotime($chat['sent_at'])) ?></span>
      </div>
    <?php endwhile; ?>
  </div>

  <form method="POST" class="chat-form" id="chatForm">
    <input type="hidden" name="consultation_id" value="<?= $consultation_id ?>">
    <input type="hidden" name="sender_id" value="<?= $_SESSION['id'] ?>">
    <input type="hidden" name="receiver_id" value="<?= $consultant['id'] ?>">
    <input type="text" name="message" placeholder="Type your message..." required autocomplete="off">
    <button type="submit">Send</button>
  </form>
</div>
if (isset($_GET['fetchMessages']) && isset($_GET['consultation_id'])) {
  $consultation_id = intval($_GET['consultation_id']);
  $user_id = $_SESSION['id'];

  $query = "SELECT * FROM consultation_chat WHERE consultation_id = ? ORDER BY sent_at ASC";
  $stmt = $connection->prepare($query);
  $stmt->bind_param("i", $consultation_id);
  $stmt->execute();
  $result = $stmt->get_result();

  while ($msg = $result->fetch_assoc()) {
    $isSender = $msg['sender_id'] === $user_id;
    $align = $isSender ? 'right' : 'left';
    $color = $isSender ? '#d2bca9' : '#e3d2c3';
    echo "<div style='text-align: $align; margin: 10px 0;'>
            <div style='display: inline-block; background: $color; padding: 10px 15px; border-radius: 10px; max-width: 70%;'>
              <p style='margin: 0; font-size: 16px; font-family: Lora;'>{$msg['message']}</p>
              <small style='font-size: 12px; color: gray;'>{$msg['sent_at']}</small>
            </div>
          </div>";
  }
  exit;
}

// Handle new message POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['message'])) {
  $msg = mysqli_real_escape_string($connection, $_POST['message']);
  $sender_id = intval($_POST['sender_id']);
  $receiver_id = intval($_POST['receiver_id']);
  $consult_id = intval($_POST['consultation_id']);

  $stmt = $connection->prepare("INSERT INTO consultation_chat (consultation_id, sender_id, receiver_id, message) VALUES (?, ?, ?, ?)");
  $stmt->bind_param("iiis", $consult_id, $sender_id, $receiver_id, $msg);
  $stmt->execute();

  header("Location: user_window.php?consultation_id=$consult_id&section=chat");
}

 

Changing Footer Page in WordPress according to Language set by Polylang

My theme (Novo Theme) lets you create pages as footers.

I created a footer in German and one in English and linked them in polylang.

In Polylang Settings > Custom post types and Taxonomies I checked everything including “Footers (yprm_footer_builder)”

The footer being displayed is always the one selected in Appearance -> Customize.

I tried adding

<?php
// Get the current language code
$current_language = pll_current_language();

// Check if the current language is English
if ($current_language == 'en') {
    // Display the English footer
    get_template_part('footer-en');
} elseif ($current_language == 'fr') {
    // Display the French footer
    get_template_part('footer-fr');
} else {
    // Display the default footer
    get_template_part('footer');
}
?>

to the page template as suggested by Google AI.

I also tried adding

function switch_footer_language() {
    if(pll_current_language=='th') {
        get_footer('footer_th.php');

    } elseif(pll_current_language=='en') {
        get_footer('footer_en.php');
    }
}

as suggested at Switch footer for different languages on WordPress website using Polylang plugin and Footer in multiple languages free WordPress

I couldn’t even get it to echo “DE” or “EN” depending on language, let alone to change the footer.

As far as I understand from posting on wordpress stackexchange at https://wordpress.stackexchange.com/questions/428859/changing-footer-according-to-language (question closed because outside their scope), I don’t need to load footer_en or footer_de but a page.

Different themes (like Avada Theme) apparently work by selecting the language as described here: Footer using Avada Theme in WordPress and the Polylang Plug-In but not Novo

I also contacted Envato Theme Support but got told customisation is beyond their scope. I have some programming skills and some worpress knowledge but not enough to take a good guess on where to start looking which support also didn’t want to tell me.

So, my questions are:

  1. How do I find the location where the footer page gets picked?

  2. Can I change it according to Polylang-Language using php? Would the ybove code be correct for querying the langauage set by polylang?

  3. Would I (probably) have to change each template the theme provides or is there a more central location?

Rerender Vue.js 3 Single File Component

I have Vue Single File Component on my page under <discussion-filter></discussion-filter> tag in discussion.blade.php wich renders from Laravel controller this way return View::make('discussions.discussions',['dto'=>$dto])->render(); during ajax request. Problem is that after ajax in this single file component i change inner html of <div id="discussion-wrapper"></div> (wich contains vue component) and my component desapears. How to re-render component? this.$forceUpdate() doesn’t helps.

here is my code. At first i render index.blade.php which include discussions.blade.php from a controller and it renders entire page with my app.js where i am registering and mounting component and its renders.

//discussions.blade.php
<div class="row">
    <div class="col-8">
        <div class="row">
            @foreach($dto->discussions as $discussion)
                <div class="col-6 mt-5 mb-5">
                    <x-discussioncard
                        title="{{$discussion->title}}"
                        username="{{$discussion->username}}"
                        date="{{$discussion->date}}"
                        slug="{{$discussion->slug}}"
                    ></x-discussioncard>
                </div>
            @endforeach
        </div>
    </div>
    <div class="col-4">
        <discussion-filter>
        </discussion-filter>
    </div>
</div>
//app.js
import {createApp} from 'vue/dist/vue.esm-bundler';
import SignupForm from './components/SignupForm.vue';
import LoginForm from './components/LoginForm.vue';
import DiscussionFilter from './components/DiscussionFilter.vue'

const app = createApp({});
app.component('signup-form',SignupForm);
app.component('login-form',LoginForm);
app.component('discussion-filter',DiscussionFilter);
app.mount('#app'); //#app goes from layouts/app.blade.php

Fragment of my DiscussionFilter.vue where i am sending ajax to another controller wich renders only discussions.blade.php

axios.get('/discussions/filter',{params:data})
     .then((response) => {
            $('#discussions-wrapper').html(response.data);
     }).catch((error) => console.log(error));

Problems is that template from controller renders my data in page but Vue component doesn’t renders. It seems i need something like re render or re mount. But how i can achieve this?

why isn’t my bookmark manager extension working?

I am currently learning javascript so I’m trying a lot of projects. I built a bookmark manager extension for chrome, but it keeps throwing an error when i try to add a bookmark.

I need it to append the saved bookmarks to the bookmark list but i keep getting an error saying

cannot read properties of null(reading appendChild)

here’s my html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="popup.css">
    <title>Bookmark Manager</title>
</head>
<body>
    <h1>Bookmark Manager</h1>
    <input type="text" id="urlInput" placeholder="Enter URL">
    <input type="text" id="titleInput" placeholder="Enter Title">
    <button id="saveButton">Save Bookmark</button>
    <h2>Your Bookmarks</h2>
    <ul id="bookmarkList"></ul>

    <script src="Popup.js"></script>
    
</body>
</html>type here

And my Popup.js:

document.getElementById('saveButton').addEventListener('click', saveBookmark);

function saveBookmark() {
    const url = document.getElementById('urlInput').value;
    const title = document.getElementById('titleInput').value;

    if (!url || !title) {
        alert('Please enter both a URL and a title.');
        return;
    }

    const bookmark = { parentId: "1" ,title, url };

    // Save bookmark to Chrome bookmarks
    chrome.bookmarks.create(bookmark, function(newBookmark) {
        console.log("Bookmark Created:", newBookmark);
        displayBookmark(newBookmark);
        clearInputs();
    });
}

function clearInputs() {
    document.getElementById('urlInput').value = '';
    document.getElementById('titleInput').value = '';
}

function displayBookmark(bookmark) {
    const bookmarkList = document.getElementById('bookmarkList');
    const li = document.createElement('li');
    li.textContent = bookmark.title;
    li.addEventListener('click', () => {
        chrome.tabs.create({ url: bookmark.url });
    });
    bookmarkList.appendChild(li);
}

// Load existing bookmarks on popup open
document.addEventListener('DOMContentLoaded', loadBookmarks);

function loadBookmarks() {
    chrome.bookmarks.getTree(function(bookmarkTreeNodes) {
        bookmarkTreeNodes.forEach(node => {
            if (node.children) {
                node.children.forEach(child => {
                    displayBookmark(child);
                });
            }
        });
    });
}

Failed to load resource: the server responded with a status of 500 (Internal Server Error) on react And nodejs. with failed to comment posts

Error in Post Comment Route—Need Help:

I’m facing the error in my post comment route, and while I understand it’s coming from the catch block, I can’t find the exact issue. All other functionalities in my code work perfectly—only this part fails. I’ve tried multiple approaches but still can’t resolve it.

Frontend (React) – onSubmit Handler
When a user submits the form, this function executes:

const onSubmit = async (data) => {
  try {
    console.log("Comment is ", data.Comment);
    const response = await postComment(id, { Comment: data.Comment });
    console.log("Response data", response.data);
    setComments(prevComments => [...prevComments, response.data]);
    toastSuccess("New comment added successfully");
    reset();
  } catch (error) {
    toastError(error.message);
    if (error.response?.status === 401) {
      navigate("/login");
      toastError(error?.response?.message);
    }
  }
};
  • I’m using React Hook Form for form handling.
  • Previously, I used axios.post directly, but later moved it to a separate api.jsx file and imported postComment from there.
  • The id comes from .
  • On success, I update the comments list using the spread operator, show a success toast, and reset the form.
  • If the user isn’t logged in (401), they’re redirected to the login page.

Backend (Express) – postComment Controller

module.exports.postComment = async (req, res) => {
  try {
    let postId = req.params.id;
    
    if (!req.user || !req.user._id) {
      console.log("You must be logged in first");
      return res.status(401).json({ message: "Unauthorized: Please log in first." });
    }

    const userId = req.user?._id || null;
    let newComment = new CommentListing({
      Comment: req.body.Comment,
      userName: userId,
      date: new Date(),
      postId: postId
    });

    let savedComment = await newComment.save();
    res.status(200).json(savedComment);
  } catch (error) {
    console.error("Error in catch block:", error);
    res.status(500).json({ 
      message: "Error posting comment", 
      error: error.message 
    });
  }
};

This is my route. JS backend:
router.post( wrapAsync(postComment))

This is api.jsx for reference:

export const postComment = (id, commentData) => API.post(`/tools/${id}/comment`, commentData);

  • Everything else (sessions, CORS, Axios) works fine—only the comment route fails..

  • The error appears in the catch block, but I can’t determine its origin.

  • I’ve added a screenshot of the error for reference.

    enter image description here

How to record audio from speaker (and not microphone)?

I am trying to record audio from speaker only using TypeScript or javascript.

Expected: it is recording audio from speaker only not microphone.

Actual: it is recording audio from microphone

Please help me what is the problem in my code?

let audioChunks: any = [];
navigator.mediaDevices.getUserMedia({ audio: true })
  .then(stream => {
    audioChunks = []; 
    let rec = new MediaRecorder(stream);

    rec.ondataavailable = e => {
      audioChunks.push(e.data);
      if (rec.state == "inactive") {
        let blob = new Blob(audioChunks, { type: 'audio/x-mpeg-3' });
        downloadFile(blob, "filename.wav");
      }
    }

    rec.start();  

    setTimeout(() => {
      rec.stop();
    }, 10000);
  })
  .catch(e => console.log(e));

How to open a custom registered Windows protocol handler?

I’m trying to trigger a custom Windows application from my PHP code using a custom protocol handler (videoplugin). I’ve registered the protocol in the Windows Registry and confirmed that it works when I run it manually from the Windows Run dialog.

What works:
Running this from Win + R works and launches the application successfully:

"C:Program Files (x86)IPRPLocalServiceComponentsIPRP Video PluginVideoPlugin.exe" "IP:100.100.210.16;Port:90;UserName:admin;Password:P@ssword1;AccountID:8518;ZoneNo.:501;AlarmTime:2025-04-08T15:01:46;AlarmInfo:Motion Detection Alarm;PCAlarmTimeTag:0;"

And here is my registry config (.reg file):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOTvideoplugin]
@="URL:VideoPlugin Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOTvideopluginshell]

[HKEY_CLASSES_ROOTvideopluginshellopen]

[HKEY_CLASSES_ROOTvideopluginshellopencommand]
@="C:\Program Files (x86)\IPRPLocalServiceComponents\IPRP Video Plugin\VideoPlugin.exe %1"

What fails:

From my PHP code, I’m trying to trigger the URL like this:

if (isset($_POST['triggerVideo'])) {
    $firstFourDigits = substr($accountno, 0, 4);
    $formattedStartDate = ($DateTimeStart instanceof DateTime) ? $DateTimeStart->format('Y-m-dTH:i:s') : date('Y-m-dTH:i:s');
    
    $videoUrl = "videoplugin:IP:100.100.210.16;Port:90;UserName:admin;Password:P@ssword1;AccountID:$firstFourDigits;ZoneNo.:501;AlarmTime:$formattedStartDate;AlarmInfo:Motion Detection Alarm;PCAlarmTimeTag:0;";
    
    echo "<script>console.log('$videoUrl');</script>";
    echo "<script>window.location.href = '$videoUrl';</script>";
    exit;
}

When I run this in the browser, nothing happens. The browser either ignores it or throws a permission error. No exceptions are caught in the try…catch block either.

What I’ve tried:

  • Verified the protocol is correctly registered in regedit.
  • Manually tested the command — works.
  • Ensured browser allows custom protocol handlers (tried in Chrome and Edge).

Confirmed that JavaScript is executing by adding console.log.

Question:

How can I reliably open my custom videoplugin: protocol handler from PHP via browser (ideally Chrome or Edge)? Is this behavior blocked by the browser, or is there a better way to launch a native app from PHP?

How can I get prettier not to break when using component syntax?

When I say component syntax, what I’m referring to is this: https://flow.org/en/docs/react/component-syntax/

which looks like this:

export default component MyComponent(someProp: string) {

prettier doesn’t recognize component as a valid keyword (understandably so) and so it breaks and doesn’t check anything in the file

It doesn’t have to be prettier, I’d use another formatter if it works better with Flow’s component syntax, and I’m also open to in depth solutions like cloning the prettier repo and making the changes to support component syntax myself.

Custom Point Tooltip for Nivo Area Bump Chart

I’m trying to create Custom Point Tooltip for Nivo Area Bump Chart some like this for Bump Chart
https://nivo.rocks/storybook/iframe.html?globals=backgrounds.grid:!false&args=&id=bump–custom-point-tooltip&viewMode=story.

{
  render: () => {
    const data = generateDataWithHoles();
    return <Bump<{
      x: number;
      y: number | null;
    }> {...commonProps} useMesh={true} debugMesh={true} pointTooltip={PointTooltip} data={data} />;
  }
}

I don’t know if it’s even possible with Area Bump. Any other suggestions?

Is there a way to pause then continue a WebTransport request using Chrome Dev Tools Protocol?

I have previously intercepted, paused, inserted a body, then continued a fetch() request made from any tab or window using Fetch.enable, listening for Fetch.requestPaused and other Fetch domain definitions, something like this

chrome.debugger.onEvent.addListener(async ({
  tabId
}, message, params) => {
  console.log(tabId, message, params);
  if (
    message === 'Fetch.requestPaused' &&
    /^chrome-extension|ext_stream/.test(params.request.url)
  ) {
    await chrome.debugger.sendCommand({
      tabId
    }, 'Fetch.fulfillRequest', {
      responseCode: 200,
      requestId: params.requestId,
      requestHeaders: params.request.headers,
      body: bytesArrToBase64(
        encoder.encode(
          JSON.stringify([...Uint8Array.from({
            length: 1764
          }, () => 255)])
        )
      ),
    });

    await chrome.debugger.sendCommand({
      tabId
    }, 'Fetch.continueRequest', {
      requestId: params.requestId,
    });
  } else {
    await chrome.debugger.sendCommand({
      tabId
    }, 'Fetch.continueRequest', {
      requestId: params.requestId,
    });
  }
});

const tabId = tab.id;
await chrome.debugger.attach({
  tabId
}, '1.3');
await chrome.debugger.sendCommand({
  tabId
}, 'Fetch.enable', {
  patterns: [{
    requestStage: "Request",
    resourceType: "XHR",
    urlPattern: '*ext_stream'
  }]
});

Now I’m working on intercepting a WebTransport request, then start a local WebTransport server using Native Messaging, then continue the request.

First iteration of code. I ordinarily wouldn’t ask questions about my first draft. Generally I hack away at for a while before asking about any part of the process. Here goes, anyway, using Network.webTransportCreated

globalThis.port;
chrome.debugger.onEvent.addListener(async ({
  tabId
}, message, params) => {
  if (message === "Network.webTransportCreated" &&
    params.url ===
    "https://localhost:4433/path") {
    if (globalThis.port === undefined) {
      globalThis.port = chrome.runtime.connectNative(chrome.runtime.getManifest().short_name);
      port.onMessage.addListener(async (e) => {
        console.log(e);
      });
      port.onDisconnect.addListener(async (e) => {
        if (chrome.runtime.lastError) {
          console.log(chrome.runtime.lastError);
        }
        console.log(e);
      });
    } else {
      // ...
    }
  }
});

At least this is my initial concept for what I want to do. If the Dev Tools Protocol, or other extension API’s don’t have an explicit or implicit way to do this, then I’ll just do this another way. I’ve done this different ways in the past.

I looked. Didn’t find anything that was obvious to me in the Network domain that will facilitate the process I’m able to do with Fetch domain and fetch().

The Network.webTransportCreated event is dispatched when the request is made from the arbitrary Web page console or Snippets. The code looks something like this

(async () => {
  try {
    const serverCertificateHashes = [
      {
        "algorithm": "sha-256",
        // Hardcoding the certificate here
        // after serilizing to JSON for import with {type: "json"}...
        "value": Uint8Array.of(
          0, 1, 2, ...
        ),
      },
    ];

    const client = new WebTransport(
      `https://localhost:4433/path`,
      {
        serverCertificateHashes,
      },
    );
    // ...

The request doesn’t pause though. It usually takes between 200 to 300 milliseconds to start a node or deno or bun, etc. server using Native Messaging to launch the application; startup time of the executable. So the server is not started in time to handle the request.

I also tried making two (2) WebTransport requests. The first just to start the local WebTransport server. Then the error has to be handled, which involves including async code in error handling code. I think the double request to do one thing pattern has some technical debt. If all else fails, I’ll retry that, though.

Just curious if I’m missing something in the Network domain or extension API’s that could be used for this case – pausing a created WebTransport request, then continuing that request, programmatically?

Error while using setData containing HTML tags on a custom ckeditor5 build

I’m trying to set-up a custom UMD build for CKEditor5 and the relevant files are available here:

The issue can be seen live at https://saurabhnanda.in/ckeditor-bug/ While I am able to do editor.setData('string without HTML'), a string containing even the most basic HTML, such as, editor.setData('<strong>foobar</strong>'); throws the following error:

Uncaught CKEditorError: pattern is undefined
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-pattern is undefined
    _isElementMatching matcher.js:165
    match matcher.js:95
    node_modules custom-ckeditor.js:14875
    fire emittermixin.js:145
    _convertItem upcastdispatcher.js:221
    _convertChildren upcastdispatcher.js:250
    convertChildren upcastdispatcher.js:154
    node_modules custom-ckeditor.js:14597
    fire emittermixin.js:145
    _convertItem upcastdispatcher.js:227
    convert upcastdispatcher.js:189
    node_modules custom-ckeditor.js:8481
    change model.js:192
    toModel datacontroller.js:396
    node_modules custom-ckeditor.js:98901
    fire emittermixin.js:145
    node_modules custom-ckeditor.js:98904
    parse datacontroller.js:379
    node_modules custom-ckeditor.js:8445
    _runPendingChanges model.js:822
    enqueueChange model.js:215
    set datacontroller.js:354
    node_modules custom-ckeditor.js:98901
    fire emittermixin.js:145
    node_modules custom-ckeditor.js:98904
    setData editor.js:600
    <anonymous> (index):15
    setInterval handler* (index):14
    promise callback* (index):9
3 ckeditorerror.js:65

I’ve tried with multiple permutations of plugins and including/excluding the GeneralHtmlSupport plugin, but nothing seems to work.

I think I am missing something very basis due to a blind spot. Any help would be appreciated.

Why is my JS animation not being detected as starting by my ‘animationstart’ event listener?

I have an animation that I am declaring and playing using JS, but when the animation plays, my event listener doesn’t fire.

Here’s the HTML file:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body id="body">
    <div id="anim"></div>
    <style>
      #anim {
        top: 500px;
        left: 500px;
        width: 100px;
        height: 100px;
        background-color: black;
        position: absolute;
      }
    </style>
    <script>
      let anim = document.getElementById("anim");

      const animkeyFrames = new KeyframeEffect(
        anim,
        [
          { transform: `translate3d(0px, 0px, 0px)` }, // keyframe
          { transform: `translate3d(0px, ${200}px, 0px)` },
        ],
        {
          // keyframe options
          duration: 1000,
          iterations: "1",
        },
      );
      let animation = new Animation(animkeyFrames, document.timeline);
      
      animation.play();
      
      anim.addEventListener('animationstart', () => {
        console.log("STARTED");
      })
      </script>
  </body>
</html>

I want “STARTED” to be logged when the animation plays but nothing happens.