Typescript Node test cannot redifine property?

So i have this test doing in my typescript project and when i do the mock tests two test have been failing all the issues are related to TypeError [Error]: Cannot redefine property: fetchAndNormalizePullRequests i looked all the way and couldn’t find a way to fix the issue. this is the

pull-request.handler.test.ts

import { test, describe, beforeEach, afterEach, mock } from 'node:test';
import assert from 'node:assert';
import type { Request, Response } from 'express';
import { getAllPullRequests } from '../../handlers/pull-requests.handler.js';

const originalEnv = process.env;
// const pullRequestsService = await import('../../services/pull-requests.service.js');

describe('Pull Requests Handler', () => {
  let mockReq: Partial<Request>;
  let mockRes: Partial<Response>;
  let statusMock: any;
  let jsonMock: any;
  let fetchMock: any;

  beforeEach(() => {
    mock.restoreAll();

    statusMock = mock.fn(() => mockRes);
    jsonMock = mock.fn();
    
    mockRes = {
      status: statusMock,
      json: jsonMock
    };

    process.env = { ...originalEnv };
  });

  afterEach(() => {
    process.env = originalEnv;
    mock.restoreAll();
  });

  test('should return 500 when GITHUB_API_TOKEN is missing', async () => {
    delete process.env.GITHUB_API_TOKEN;
    mockReq = {
      query: { owner: 'testowner', repo: 'testrepo' }
    };

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Missing environment variables.' }]);
  });

  test('should return 500 when owner is missing', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { repo: 'testrepo' }
    };

    try{
    await getAllPullRequests(mockReq as Request, mockRes as Response);
    }
    catch(e){
      console.error(e);
    }

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Missing environment variables.' }]);
  });

  test('should return 500 when repo is missing', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { owner: 'testowner' }
    };

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Missing environment variables.' }]);
  });

  test('should return 200 with pull requests when all parameters are valid', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { owner: 'testowner', repo: 'testrepo' }
    };

    const mockPullRequests = [
      {
        prNumber: 1,
        title: 'Test PR',
        creator: 'testuser',
        creationTimestamp: '2024-01-01T00:00:00Z',
        requestedReviewers: ['reviewer1'],
        lastActionType: 'open',
        lastActionTimestamp: '2024-01-01T00:00:00Z'
      }
    ];

    const fetchMock = mock.fn(() => Promise.resolve(mockPullRequests));
    mock.method(await import('../../services/pull-requests.service.js'), 'fetchAndNormalizePullRequests', fetchMock);

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [200]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [mockPullRequests]);
  });

  test('should return 500 when service throws an error', async () => {
    process.env.GITHUB_API_TOKEN = 'test-token';
    mockReq = {
      query: { owner: 'testowner', repo: 'testrepo' }
    };

    const fetchMock = mock.fn(() => Promise.reject(new Error('Service error')));
    mock.method(await import('../../services/pull-requests.service.js'), 'fetchAndNormalizePullRequests', fetchMock);

    await getAllPullRequests(mockReq as Request, mockRes as Response);

    assert.strictEqual(statusMock.mock.callCount(), 1);
    assert.deepStrictEqual(statusMock.mock.calls[0].arguments, [500]);
    assert.strictEqual(jsonMock.mock.callCount(), 1);
    assert.deepStrictEqual(jsonMock.mock.calls[0].arguments, [{ error: 'Internal server error.' }]);
  });
});

and this is my fetchAndNormalizePullRequest function

import axios from 'axios';
import type{ NormalizedPR } from '../types/types.js';

export const fetchAndNormalizePullRequests = async (owner: string, repo: string, token: string): Promise<NormalizedPR[]> => {
  const url = `https://api.github.com/repos/${owner}/${repo}/pulls?state=all`;

  try {
    const response = await axios.get(url, {
      headers: {
        Authorization: `token ${token}`,
        'Content-Type': 'application/json',
      },
    });

    return response.data.map((pr: any) => ({
      prNumber: pr.number,
      title: pr.title,
      creator: pr.user.login,
      creationTimestamp: pr.created_at,
      requestedReviewers: pr.requested_reviewers.map((reviewer: any) => reviewer.login),
      lastActionType: pr.merged_at ? 'merged' : pr.state,
      lastActionTimestamp: pr.updated_at,
    }));
  } catch (error) {
    throw new Error('Failed to fetch pull requests from GitHub API.');
  }
};

what am i doing wrong? can’t fix the issue

iPad – how to have a numeric floating keyboard with return/enter or tab key

This is what a number floating keyboard on iPad is looking like

iPad numeric keyboard

I want to have a enter/return or tab key here. There is an input field for each row in a table and I want to enter some value in it (0-9) and move to next row/cell. If I use the full screen keyboard, it suffices the requirement but the keyboard is taking 80% of the screen. So I want to use this floating keyboard but if I want to go to next cell, I need to click to that next cell and then enter value. I want to improve user experience on it. I tried input type number, numeric and tel and it did not help.

Problem with contact form HTML & JS for submit on php after required fields [closed]

I have a problem with my contact form. I have required fields that work when I click on submit, but once everything is entered, the form is not sent to the .php file. Maybe it’s only a small problem, so I add the whole code. Sorry for the length of the codes.
Where am I going wrong? I’ve been working on this for hours šŸ™ I hope someone can help me.

const form = document.getElementById('userForm');
const firstNameInput = document.getElementById('name_surname');
const emailInput = document.getElementById('mail');
const firstNameError = document.getElementById('firstNameError');
const emailError = document.getElementById('emailError');
const submitBtn = document.getElementById("invia");

form.addEventListener('submit', function(event) {
  // Prevent the form from submitting normally
  event.preventDefault();

  if (validateForm()) {
    return;
    // You can now submit the form programmatically or clear it
  }

  // do animation
  submitBtn.classList.add("is-active");
  setTimeout(function() {
    submitBtn.classList.remove("is-active");

    actual_submit();
  }, 2500);

})

function actual_submit() {
  alert('Form was submitted')
  return; // for testing purposes
  $.ajax({
    type: 'post',
    url: '../../php/kontakt.php',
    data: $('form').serialize(),
    success: function() {
      alert('form was submitted');
    }
  });
}

function validateForm() {
  let isValid = true;

  // Validate First Name
  if (firstNameInput.value.trim() === '') {
    firstNameError.textContent = 'First name is required.';
    firstNameInput.classList.add('invalid'); // Add a class for styling
    isValid = false;
  } else {
    firstNameError.textContent = '';
    firstNameInput.classList.remove('invalid');
  }

  // Validate Email
  const emailValue = emailInput.value.trim();
  const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/; // Basic email regex

  if (emailValue === '') {
    emailError.textContent = 'Email is required.';
    emailInput.classList.add('invalid');
    isValid = false;
  } else if (!emailRegex.test(emailValue)) {
    emailError.textContent = 'Please enter a valid email address.';
    emailInput.classList.add('invalid');
    isValid = false;
  } else {
    emailError.textContent = '';
    emailInput.classList.remove('invalid');
  }

  return isValid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="userForm" method="post"> <!-- Do not remove this ID, it is used to identify the page so that the pagination script can work correctly -->
  <fieldset class="formContainer uk-form uk-form-stacked" id="rsform_3_page_0">
    <div class="uk-form-row rsform-block rsform-block-nome-cognome">
      <div class="formControls">
        <input type="text" value="" size="20" placeholder="Name & Nachname" name="form[name_surname]" id="name_surname" class="uk-form-large rsform-input-box" />
        <span id="firstNameError" class="error-message"></span>
      </div>
    </div>
    <div class="uk-form-row rsform-block rsform-block-mail">
      <div class="formControls">
        <input type="email" value="" size="20" placeholder="Mailadresse" name="form[mail]" id="mail" class="uk-form-large rsform-input-box" aria-required="true" />
        <span id="emailError" class="error-message"></span>
      </div>
    </div>
    <div class="uk-form-row rsform-block rsform-block-data-arrivo-3">
      <div class="formControls">
        <input type="text" value="" size="20" placeholder="Datum Anreise" name="form[arrival]" id="arrival" class="omnidatepicker-from uk-form-large rsform-input-box" aria-required="true" />
        <span class="formValidation"><span id="component61" class="formNoError"></span></span>
      </div>
    </div>
    <div class="uk-form-row rsform-block rsform-block-data-partenza-3">
      <div class="formControls">
        <input type="text" value="" size="20" placeholder="Datum Abreise" name="form[departure]" id="departure" class="omnidatepicker-to uk-form-large rsform-input-box" aria-required="true" />

      </div>
    </div>

    <div class="uk-form-row rsform-block rsform-block-messaggio">
      <div class="formControls">
        <textarea cols="50" rows="3" placeholder="Mitteilung (Bitte teilen Sie uns alle wichtigen Details mit, damit wir Ihren Aufenthalt bestens gestalten kƶnnen.)" name="form[message]" id="message" class="uk-form-large rsform-text-box"></textarea>
        <span class="formValidation"><span id="component28" class="formNoError"></span></span>
      </div>
    </div>

    <div class="uk-form-row rsform-block rsform-block-accetto-privace">
      <div class="formControls">
        <div><label for="accetto_privace0"><input type="checkbox"  name="form[privacy][]" value="1" id="privacy" class="rsform-checkbox" aria-required="true" />Akzeptiere <a href="#privacy-3" data-uk-modal>Privacy</a><div id="privacy-3" class="uk-modal"><div class="uk-modal-dialog uk-modal-dialog-lightbox uk-modal-dialog-large"><a href="/" class="uk-modal-close uk-close uk-close-alt"></a><iframe src="https://www.omnigrafitalia.it/gdpr/index.php?site=https%3A%2F%2Fwww.musacomo.com%2F#googtrans(it)" width="100%" height="600px"></iframe></div></div></label> </div>
        <span class="formValidation"><span id="component31" class="formNoError"></span></span>
      </div>
    </div>


    <div id="rsform_error_3" style="display: none;">
      <p class="formRed"><i class="uk-icon-exclamation-triangle"></i> Bitte alle Felder ausfüllen.</p>
    </div>
    <div class="uk-form-row rsform-block rsform-block-invia">
      <div class="formControls">
        <input type="submit" name="form[invia]" id="invia" class="uk-width-1-1 rsform-submit-button  uk-button uk-button-primary" value="Anfrage absenden" />
        <span class="formValidation"></span>
      </div>
    </div>

  </fieldset>

  <input type="hidden" name="form[language]" id="language" value="de" />
  <input type="hidden" name="form[hiddenlist_local]" id="hiddenlist_local" value="1" />

  <input type="hidden" name="form[nome_offerta_3]" id="nome_offerta_3" value="Angebot Relax BHB" />

</form>

How to automatically refresh access token when receiving 403 errors in Redux Toolkit async thunks?

I’m building a React application with Redux Toolkit and need to handle token expiration automatically. When my access token expires, the server returns a 403 error, and I want to automatically refresh the token and retry the original request.
I have favourites-related async thunks that need authentication. The server expects the access token in the Authorization header. My access token is stored in Redux memory (state.auth.accessToken). Here’s my current code:

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

const url = import.meta.env.VITE_APP_SERVER_URL;

// Thunk to add to favourites
export const addToFavouritesThunk = createAsyncThunk(
  'favourites/add',
  async (dishId, { rejectWithValue, getState }) => {
    try {
      const { auth: { accessToken } } = getState();
      const response = await axios.post(
        `${url}favourites`,
        { dishId },
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      return response.data;
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Failed to add to favourites'
      );
    }
  }
);

// Thunk to get all favourites
export const getFavouritesThunk = createAsyncThunk(
  'favourites/getAll',
  async (_, { rejectWithValue, getState }) => {
    try {
      const { auth: { accessToken } } = getState();
      const response = await axios.get(
        `${url}favourites`,
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      return response.data;
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Failed to get favourites'
      );
    }
  }
);

// Thunk to remove from favourites
export const removeFromFavouritesThunk = createAsyncThunk(
  'favourites/remove',
  async (dishId, { rejectWithValue, getState }) => {
    try {
      const { auth: { accessToken } } = getState();
      const response = await axios.delete(
        `${url}favourites/${dishId}`,
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      return response.data;
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Failed to remove from favourites'
      );
    }
  }
);

// Refresh token thunk (simplified version)
export const refreshTokenThunk = createAsyncThunk(
  'auth/refresh',
  async (_, { rejectWithValue, getState }) => {
    try {
      const { auth: { refreshToken } } = getState();
      const response = await axios.post(
        `${url}auth/refresh`,
        { refreshToken }
      );
      return response.data; // Contains new accessToken
    } catch (error) {
      return rejectWithValue(
        error.response?.data?.message || 'Token refresh failed'
      );
    }
  }
);

const favouritesSlice = createSlice({
  name: 'favourites',
  initialState: {
    items: [],
    loading: false,
    error: null,
    lastAction: null
  },
  reducers: {
    clearFavouritesError: (state) => {
      state.error = null;
    },
    resetLastAction: (state) => {
      state.lastAction = null;
    }
  },
  extraReducers: (builder) => {
    builder
      // Add to favourites
      .addCase(addToFavouritesThunk.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(addToFavouritesThunk.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload;
        state.lastAction = { type: 'add' };
      })
      .addCase(addToFavouritesThunk.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      })
      // Get all favourites
      .addCase(getFavouritesThunk.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(getFavouritesThunk.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload.favourites || [];
      })
      .addCase(getFavouritesThunk.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      })
      // Remove from favourites
      .addCase(removeFromFavouritesThunk.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(removeFromFavouritesThunk.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload;
        state.lastAction = { type: 'remove' };
      })
      .addCase(removeFromFavouritesThunk.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  }
});

export const { clearFavouritesError, resetLastAction } = favouritesSlice.actions;
export default favouritesSlice.reducer;

The Problem
When the access token expires, my server returns a 403 error. I want to automatically:

Detect 403 errors in any thunk

Call refreshTokenThunk to get a new access token

Retry the original request with the new token

Handle concurrent requests (if multiple requests fail with 403 at the same time)

Fetching overridden events from Google Calendar

I have a Google Apps Script to automate the description of Google Calendar events. The script runs once a week and tries to fetch, and modify, the occurrence for the week to follow.

The code to find the next meeting looks like this:

  const now = new Date();
  const nowIso = now.toISOString();
  const oneWeekLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
  const oneWeekLaterIso = oneWeekLater.toISOString();
  const instances = Calendar.Events.instances(calendarId, recurringEventId, {
    timeMin: nowIso,
    timeMax: oneWeekLaterIso,
    maxResults: 1
  });
  if (!instances.items || !instances.items.length) {
    // No upcoming occurrences found; snothing to do
    Logger.log("No upcoming instances found");
    return;
  }
  const nextInstance = instances.items[0];

This normally works. However, if an event has been modified (either manually or by my own code), it is not found by this. It seems Calendar.Events.instances only lists unaltered events. How do I get around this? I want to find the next occurrence (modified or not, but not deleted) of a recurring event.

How can I add structured data (JSON-LD) for multiple products on a single blog page?

I’m trying to improve the SEO of a blog page that also highlights a few of our products. For example, here’s one of the pages I’m working with:

Famous Places to visit in Salem

The page is mostly a travel article, but in between the content, we mention some of our products (different varieties of Salem mangoes).

I know how to add JSON-LD schema for a single Product, but in this case, I’m not sure:

Should I add multiple “@type”: “Product” blocks inside one tag, or use multiple tags?

Since the page is primarily a blog post and not a product listing, is it still valid to use Product schema here, or should I only use Article schema and skip products?

What’s the best practice so Google doesn’t treat this as ā€œspammyā€ structured data?

Here’s an example of what I tried with two products:

<script type="application/ld+json">
{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Alphonso Mango",
  "image": "https://www.salemmango.com/images/alphonso-mango.jpg",
  "description": "Premium Alphonso Mangoes from Salem",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "INR",
    "price": "999",
    "availability": "https://schema.org/InStock"
  }
},
{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Imam Pasand Mango",
  "image": "https://www.salemmango.com/images/imam-pasand-mango.jpg",
  "description": "Rare Salem Imam Pasand Mango",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "INR",
    "price": "899",
    "availability": "https://schema.org/InStock"
  }
}
</script>

But this throws validation errors in Google’s Rich Results Test.

What’s the correct way to structure multiple product schemas on the same blog page?

Using browser’s native pdfViewer from JavaScript?

Browser’s navigator.pdfViewerEnabled property indicates whether the browser supports inline display of PDF files when navigating to them.

If we think of going further – is it possible to use browser’s built-in (native) capability of processing PDF files from JavaScript code? One particular thing I need is to get page size and page count of a selected local PDF file.

In other words, is there any API exposed by a browser to use its native PDF-processing capabilities without importing any JS/npm library or implementing it from scratch?

How to intercept all HTTP requests from page

I am trying to learn how to use JavaScript to block all outgoing HTTP requests from an HTML file. The problem is when you click the link to www.example.com it doesn’t seem to catch it as a fetch event.

test.html:

<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">


if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("./sw.js", { scope: "/" }).then(
    (registration) => {
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      console.error(`Service worker registration failed: ${error}`);
    },
  );
} else {
  console.error("Service workers are not supported.");
}

  
</script>
<div>
<a href="https://www.example.com">Visit Example</a>
</div>
</body>
</html>

sw.js:

console.log('loaded')
self.addEventListener('fetch', function (event) {
    console.log('fetch', event.request.url);
});

Looking at my console:

loaded
fetch test.html
test.html:31 Service worker registration succeeded
fetch favicon.ico
favicon.ico:1   GET favicon.ico 404 (Not Found)

So you can see above that it even blocks an attempt to load favicon.ico (host provider icon) but it doesn’t block me if I click the link – I just go to example.com.

ExtJS – changing css class in another cell based on value and renderer

I have a requirement to change the class of the nominal_currency_id cell based on information from the ch_nominal_currency_id_flag column. I simply want to assign a background color to it.

I could use a renderer in the nominal_currency_id cell, but this is impossible because I have a resolveView that handles changing the ID to one retrieved from the dictionary. The renderer overrides this, and I still see the ID instead of the code value.

Therefore, I would like to add a renderer to the column with the ch_nominal_currency_id_flag flag, but I don’t know how to add to the nominal_currency_id column to assign a class to it. metadata, of course, only works for the column containing the renderer.

In short, I want to apply a red background color to the nominal_currency_id cell based on the value from the true/false ch_nominal_currency_id_flag cell

How should I approach this?

        {
            name: 'nominal_currency_id',
            title: 'Nominal Currency',
            editable: true,
            type: 'string',
            maxLength: 3,
            formSortOrder: 13,
            resolveView: {
                dataProviderId: 'PROVIDER_ID',
                childrenTable: 'pd_currency',
                remote: false,
                valueField: 'currency_id',
                displayField: 'currency_code',
                addBlank: true
            }
        },
        {
            name: 'ch_nominal_currency_id_flag',
            title: 'Ch Nominal Currency Flag',
            editable: true,
            type: 'boolean',
            hidden: true,
            hiddenInForm: true,
            formSortOrder: 45
        },

I also add the code that adds my resolveView, maybe it will help in solving

if (column.resolveView !== undefined) {
        ;(() => {
          const resolveView = column.resolveView
          const columnName = column.name
          let dropDownTemplate
          let dropDownTemplateList

          tempColumnType.filter = {
            type: 'resolver',
            addBlank: false,
            underlyingField: columnName,
            ...resolveView,
            control,
          }

          tempColumnType.renderer = function (value, _metaData, record) {
            if (!_.isNil(value)) {
              const retrivedValue = app.nameResolver.resolve(
                {
                  value,
                  underlyingField: columnName,
                  ...resolveView,
                },
                record?.data,
              )

              return _.isString(retrivedValue)
                ? _.unescape(retrivedValue)
                : retrivedValue
            }
          }

          if (column.editable !== false) {
            tempColumnType.field = {
              xtype: 'resolvercombo',
              underlyingField: columnName,
              ...resolveView,
            }
          }

          if (dropDownTemplate) {
            tempColumnType.field.tpl = dropDownTemplateList
            tempColumnType.field.displayTpl = dropDownTemplate
            tempColumnType.filter.tpl = dropDownTemplateList
            tempColumnType.filter.displayTpl = dropDownTemplate
          }
        })()
      }

Owner Id showing instead of userName

Problem
I’ve been working on this for a couple of days now, trying to figure out why the frontend keeps displaying the user’s object ID instead of their username. Despite setting up the authentication and role-based logic, the username isn’t rendering as expected, and I suspect the issue might be with how the user data is being fetched or decoded from the token.

Ticket Schema

import mongoose  from 'mongoose'

const Schema = new mongoose.Schema({
    title : {type:String , required : true},
    description : {type : String, required : true},
    status : { type : String , default: 'open'},
    assignedTech: {type: String},
     priority: {
        type: String,
        enum: ['Low', 'Medium', 'High'],
        default: 'Low',
        required: true
        },
    owner: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'users',
    required: true
  }

    },{timestamps: true})

const TicketModel = mongoose.model("version2",Schema)

export {TicketModel}

Create Ticket Logic

async function PostData(req,res) {
    try{
        const UserId  = req.user.id
        const AssignedTo = await AutoAssign()
        console.log('i am '+AssignedTo)
        const New =  new TicketModel({...req.body, 
                                        assignedTech: AssignedTo,
                                        owner:UserId
                                    })  

        if(req.body.title && req.body.description !== ""){
            await  New.save()
            return sendSuccess(res,200,"Ticket created successfully","","Ticket created successfully")    
        }
        else{
            return sendError(res,401,"Please fill in required fields")
        }
    }
    catch(error){
        return sendError(res,500,"Failed to create ticket",error,error)
    }
}

Get Ticket Logic

async function  GetData(req,res) {
    try{
        const UserID = req.user.id
        const read =  await TicketModel.find().sort({createdAt:-1})

        if(!read){
            return sendError(res,404,"No tickets are currenlty in the database",read,"No tickets currenlty in the database")
        }
        return sendSuccess(res,200,"Tickets retrieved successfully",read,"Tickets retrieved successfully")
    }

    catch(error){
        return sendError(res,500,"Failed to retrieve tickets",error,error)
    }

Front End Logic

 {
            Fetching ? (<h1>Fecthing Tickets....</h1>): 
            fetchingTickets ? fetchingTickets.data.length === 0 ? (<PlayFullMessage/>):
            fetchingTickets?.data?.map(({_id:id,["title"]:title,["description"]:description,["status"]:status,["assignedTech"]:Technician,["priority"]:Priorty,["owner"]:owner}) =>(
                <div onClick={() => navigate(`/home/tickets/${id}`)} key={id} className='w-full m-h-[100px] border-[2px] grid grid-cols-6 p-5 rounded-[10px] text-[1.5rem] bg-secondary dark:border-primaryDark dark:bg-backgroundDark shadow-md hover:shadow-lg hover:scale-105 cursor-pointer gap-6'>
                    <p className='grid grid-rows-2 w-full'>Title  <span className='text-[1.2rem]'>{title}</span></p>
                    <p className='grid grid-rows-2 w-full'>Description  <span className='text-[1.2rem]'>{description}</span></p>
                    <p className='grid grid-rows-2 w-full'>Status  <span className='text-[1.2rem]'>{status}</span></p>
                    <p className='grid grid-rows-2 w-full'>Assigned to  <span className='text-[1.2rem]'>{Technician}</span></p>
                    <p className='grid grid-rows-2 w-full'>
                      Priority  
                      <span className='text-[1.2rem]'>
                        {Priorty === "High" ? (
                          <span className='text-red-500'>{Priorty}</span>
                        ) : Priorty === "Medium" ? (
                          <span className='text-yellow-500'>{Priorty}</span>
                        ) : Priorty === "Low" ? (
                          <span className='text-green-500'>{Priorty}</span>
                        ) : (
                          <span>{Priorty}</span> 
                        )}
                      </span>
                    </p>
                    <p className='grid grid-rows-2 w-full'>Created by  <span className='text-[1.2rem]'>{owner}</span></p>
                </div>
            )
            ):(<h1>Failed to fetch tickets.....</h1>)
        }
      </div>

Output
current output

How to configure LightningChart scrolling X axis

I’m trying to create a web application with scrolling line chart connected to real-time data coming over websocket. The chart should always show the latest 100 points and move right to reveal new points as they arrive.

I’m using LightningChart JS library (https://www.npmjs.com/package/@lightningchart/lcjs)

The chart is created correctly, and data points even arrive properly, but the only problem is that after 100 data points, the new ones are not revealed and I only see the very first 100.

I found the API to set “scrolling” scroll strategy which sounds like the behavior I want but it doesn’t seem to do anything (even if I comment it out/back)

Here is my current minimal reproduction:

const lc = lcjs.lightningChart()
const chart = lc.ChartXY({ defaultAxisX: { type: 'linear-highPrecision' } })
const series = chart.addLineSeries()

chart.axisX
    .setTickStrategy(lcjs.AxisTickStrategies.DateTime)
    .setScrollStrategy(lcjs.AxisScrollStrategies.scrolling)
    .setInterval({ start: 0, end: 100 })

setInterval(() => {
    series.appendSample({ y: Math.random() })
}, 100)
<script src="https://cdn.jsdelivr.net/npm/@lightningchart/[email protected]/dist/lcjs.iife.js"></script>

I tried a couple things:

  • only use “setTickStrategy” -> the axis scrolls, but the time window keeps increasing always (so it displays ALL data points at all times, rather than latest 100)
  • comment out “setInterval” -> this is actually the closest to what I want, but it only displays the 10 newest points. Now only remaining problem is how to show 100 last points.

How to keep 1 page public when every page is password protected in Shopify

I’ve enabled the password protection feature on my Shopify store, so that only visitors with the password can access the site.

However, I’d like to achieve two things:

Keep one specific page (e.g., /pages/landing-page-become-a-vendor) publicly accessible without requiring the password.

Redirect anyone who visits the homepage (/) to that public page.

Is there a way to configure this in Shopify (through theme code, Liquid, or settings) so that the password protection remains for all other pages, but one page stays accessible and acts as the homepage redirect?

Render webpage that sets X-Frame-Options and redirects to OAuth flow in IFrame

I have a requirement where I need to render a web app that uses oauth to login in an iframe. The iframe setup is for tutorials, where the tutorial content is in one column, and the web app is in another column. The web app is rendered in an iframe. The web apps are deployed by me, I can’t really change them but I do run them in kubernetes so I do proxy their requests/responses and can modify request/response headers. It’s easy enough remove X-Frame-Options headers, and modify CSB headers to allow the web apps to run in an iframe. Now I have a new web app that I need to display, it uses oauth so the user gets redirected to the oauth login page, and back via the redirect link passed at login time. I can’t unfortunately easily proxy the requests/reponses from the oauth provider. It is techincally possible I believe, but I’m reaching out here to find out if anyone has any other ideas on how to meet this requirement.

I’ve tried https://github.com/Rob–W/cors-anywhere, which works more or less the same as the route proxy above, and breaks down as soon as i hit the oauth endpoint.

Only working solution I have so far is a docker image running VNC, noVnc, IceWM and firefox. It’s great, fast and all the redirects work without any extra configuration. Negatives here are memory usage, the container requires 1GB+ of RAM and even then it crashes occasionally. We could have 200-300 users at one time doing the tutorials. While I do have the RAM available, it’s obviously not efficient. And the RAM usuage multiplies when I need more than 1 web app in an iframe.

Layer disappears when zooming. esri leaflet with proj4leaflet

I have a problem where the ArcGisDynamicLayer disappears when zoomed in and then reappears after a while. It looks super weird and ugly. I looked at the ArcGIS sample, and the situation is the same: https://developers.arcgis.com/esri-leaflet/samples/non-mercator-projection-3/

I noticed that the image itself is not removed from the map, but rather shifted to the side by a bunch of pixels.

I only see this problem when using Proj4 library. Has anyone else encountered this? Maybe they’ve found a solution already.

I went through the Leaflet code and found that this happens on fire(‘zoom’). You can fix it a bit by commenting out the line in _onZoomTransitionEnd, but then the image might shift, which also doesn’t look very good, and I wouldn’t call digging into the library a good solution. I also tried to force a redraw at the end of the zoom, but it didn’t help either.