How to control select2 selection on chage event?

I have a multiple select element with select2 v 3.5.2 plugin.

I need to be sure that the specific option value -1 will be not selected with other values.

I tried this solution:

$('#mysel').on("change",function(e){
    if($("#mysel option[value=-1]").is(":selected") && $("#mysel option[value!=-1]:selected").length>0){
        $("#mysel").val(-1).trigger('change.select2');
    }
});

But it doesn’t work, it change the value in html but select2 container is not updated. I also tried to switch the trigger to .trigger('change') but it didn’t work.

I tried to run a change with a setTimeout() and it works… so I guess there is an issue on the event triggering the same event. Is there a solution other than not-so-elegant setTimeout update?

Optimize this JS code change listener for fast response

How do you optimize the Javascript code for fast response… the code works perfectly fine but the issue is the checkboxes have delay when clicked due to large amount of data in database…

in the logs it says:

[Violation] ‘change’ handler took 296ms

make sure the logic stays the same..

JS code: optimize this code

// Checkbox "change" listener
    document.querySelectorAll('input[type="checkbox"]').forEach((checkbox) =>
        checkbox.addEventListener("change", (event) => {

            const type = event.target.getAttribute("data-column");
            const value = event.target.value;
            state[type] = event.target.checked ? value : null;

            const isAnySelected = Object.values(state).some((val) => val !== null);

            manufacturerCheckboxes.forEach((checkbox) => {
                const families = ic_family_arr
                    .filter(({ ic_manufacturer }) => ic_manufacturer === checkbox.value)
                    .map(({ ic_family }) => ic_family);
                const crypartNumbers = cry_part_num_arr
                    .filter(({ ic_manufacturer }) => ic_manufacturer === checkbox.value)
                    .map(({ field_cry_part_num }) => field_cry_part_num);
                const dimensions = cry_dimensions_arr
                    .filter(({ ic_manufacturer }) => ic_manufacturer === checkbox.value)
                    .map(({ field_cry_dimensions }) => field_cry_dimensions);
                const frequencies = cry_freq_mhz_arr
                    .filter(({ ic_manufacturer }) => ic_manufacturer === checkbox.value)
                    .map(({ field_cry_freq_mhz }) => field_cry_freq_mhz);
                const load_capacitances = cry_load_capacitance_arr
                    .filter(({ ic_manufacturer }) => ic_manufacturer === checkbox.value)
                    .map(
                        ({ field_cry_load_capacitance }) => field_cry_load_capacitance
                    );
                const aecs = cry_aec_arr
                    .filter(({ ic_manufacturer }) => ic_manufacturer === checkbox.value)
                    .map(({ field_cry_aec }) => field_cry_aec);
                const hasManufacturer =
                    state.manufacturer && state.manufacturer !== checkbox.value;
                const hasSelectedUnrelatedFamily =
                    state.family && !families.includes(state.family);
                const hasSelectedUnrelatedCrypartNum =
                    state.crystal_part_num &&
                    !crypartNumbers.includes(state.crystal_part_num);
                const hasSelectedUnrelatedDimension =
                    state.dimensions && !dimensions.includes(state.dimensions);
                const hasSelectedUnrelatedFrequency =
                    state.frequency && !frequencies.includes(state.frequency);
                const hasSelectedUnrelatedLoadCapacitance =
                    state.load_capacitance &&
                    !load_capacitances.includes(state.load_capacitance);
                const hasSelectedUnrelatedAec =
                    state.aec && !aecs.includes(state.aec);
                const shouldHide =
                    isAnySelected &&
                    (hasManufacturer ||
                        hasSelectedUnrelatedFamily ||
                        hasSelectedUnrelatedCrypartNum ||
                        hasSelectedUnrelatedDimension ||
                        hasSelectedUnrelatedFrequency ||
                        hasSelectedUnrelatedLoadCapacitance ||
                        hasSelectedUnrelatedAec);

                toggleCheckbox(checkbox, shouldHide);
            });

            familyCheckboxes.forEach((checkbox) => {
                const manufacturer = ic_family_arr.find(
                    ({ ic_family }) => ic_family === checkbox.value
                ).ic_manufacturer;
                const crypartNumbers = cry_part_num_arr
                    .filter(({ ic_family }) => ic_family === checkbox.value)
                    .map(({ field_cry_part_num }) => field_cry_part_num);
                const dimensions = cry_dimensions_arr
                    .filter(({ ic_family }) => ic_family === checkbox.value)
                    .map(({ field_cry_dimensions }) => field_cry_dimensions);
                const frequencies = cry_freq_mhz_arr
                    .filter(({ ic_family }) => ic_family === checkbox.value)
                    .map(({ field_cry_freq_mhz }) => field_cry_freq_mhz);
                const load_capacitances = cry_load_capacitance_arr
                    .filter(({ ic_family }) => ic_family === checkbox.value)
                    .map(
                        ({ field_cry_load_capacitance }) => field_cry_load_capacitance
                    );
                const aecs = cry_aec_arr
                    .filter(({ ic_family }) => ic_family === checkbox.value)
                    .map(({ field_cry_aec }) => field_cry_aec);
                const hasFamily = state.family && state.family !== checkbox.value;
                const hasSelectedUnrelatedManufacturer =
                    state.manufacturer && state.manufacturer !== manufacturer;
                const hasSelectedUnrelatedCrypartNum =
                    state.crystal_part_num &&
                    !crypartNumbers.includes(state.crystal_part_num);
                const hasSelectedUnrelatedDimension =
                    state.dimensions && !dimensions.includes(state.dimensions);
                const hasSelectedUnrelatedFrequency =
                    state.frequency && !frequencies.includes(state.frequency);
                const hasSelectedUnrelatedLoadCapacitance =
                    state.load_capacitance &&
                    !load_capacitances.includes(state.load_capacitance);
                const hasSelectedUnrelatedAec =
                    state.aec && !aecs.includes(state.aec);
                const shouldHide =
                    isAnySelected &&
                    (hasFamily ||
                        hasSelectedUnrelatedManufacturer ||
                        hasSelectedUnrelatedCrypartNum ||
                        hasSelectedUnrelatedDimension ||
                        hasSelectedUnrelatedFrequency ||
                        hasSelectedUnrelatedLoadCapacitance ||
                        hasSelectedUnrelatedAec);

                toggleCheckbox(checkbox, shouldHide);
            });

            crypartnumCheckboxes.forEach((checkbox) => {
                const cry_part_num = cry_part_num_arr.find(
                    ({ field_cry_part_num }) => field_cry_part_num === checkbox.value
                );
                const manufacturer = cry_part_num.ic_manufacturer;
                const family = cry_part_num.ic_family;
                const dimensions = cry_dimensions_arr
                    .filter(
                        ({ field_cry_part_num }) => field_cry_part_num === checkbox.value
                    )
                    .map(({ field_cry_dimensions }) => field_cry_dimensions);
                const frequencies = cry_freq_mhz_arr
                    .filter(
                        ({ field_cry_part_num }) => field_cry_part_num === checkbox.value
                    )
                    .map(({ field_cry_freq_mhz }) => field_cry_freq_mhz);
                const load_capacitances = cry_load_capacitance_arr
                    .filter(
                        ({ field_cry_part_num }) => field_cry_part_num === checkbox.value
                    )
                    .map(
                        ({ field_cry_load_capacitance }) => field_cry_load_capacitance
                    );
                const aecs = cry_aec_arr
                    .filter(
                        ({ field_cry_part_num }) => field_cry_part_num === checkbox.value
                    )
                    .map(({ field_cry_aec }) => field_cry_aec);
                const hasSelectedUnrelatedManufacturer =
                    state.manufacturer && state.manufacturer !== manufacturer;
                const hasSelectedUnrelatedFamily =
                    state.family && state.family !== family;
                const hasCrypartNumber =
                    state.crystal_part_num && state.crystal_part_num !== checkbox.value;
                const hasSelectedUnrelatedDimension =
                    state.dimensions && !dimensions.includes(state.dimensions);
                const hasSelectedUnrelatedFrequency =
                    state.frequency && !frequencies.includes(state.frequency);
                const hasSelectedUnrelatedLoadCapacitance =
                    state.load_capacitance &&
                    !load_capacitances.includes(state.load_capacitance);
                const hasSelectedUnrelatedAec =
                    state.aec && !aecs.includes(state.aec);
                const shouldHide =
                    isAnySelected &&
                    (hasSelectedUnrelatedManufacturer ||
                        hasSelectedUnrelatedFamily ||
                        hasCrypartNumber ||
                        hasSelectedUnrelatedDimension ||
                        hasSelectedUnrelatedFrequency ||
                        hasSelectedUnrelatedLoadCapacitance ||
                        hasSelectedUnrelatedAec);

                toggleCheckbox(checkbox, shouldHide);
            });

            dimensionsCheckboxes.forEach((checkbox) => {
                const dimensions = cry_dimensions_arr.filter(
                    ({ field_cry_dimensions }) =>
                        field_cry_dimensions === checkbox.value
                );
                const manufacturers = [],
                    families = [],
                    crypart_nums = [];
                dimensions.forEach((dimension) => {
                    manufacturers.push(dimension.ic_manufacturer);
                    families.push(dimension.ic_family);
                    crypart_nums.push(dimension.field_cry_part_num);
                });
                const frequencies = cry_freq_mhz_arr
                    .filter(
                        ({ field_cry_dimensions }) =>
                            field_cry_dimensions === checkbox.value
                    )
                    .map(({ field_cry_freq_mhz }) => field_cry_freq_mhz);
                const load_capacitances = cry_load_capacitance_arr
                    .filter(
                        ({ field_cry_dimensions }) =>
                            field_cry_dimensions === checkbox.value
                    )
                    .map(
                        ({ field_cry_load_capacitance }) => field_cry_load_capacitance
                    );
                const aecs = cry_aec_arr
                    .filter(
                        ({ field_cry_dimensions }) =>
                            field_cry_dimensions === checkbox.value
                    )
                    .map(({ field_cry_aec }) => field_cry_aec);
                const hasDimension =
                    state.dimensions && state.dimensions !== checkbox.value;
                const hasSelectedUnrelatedManufacturer =
                    state.manufacturer && !manufacturers.includes(state.manufacturer);
                const hasSelectedUnrelatedFamily =
                    state.family && !families.includes(state.family);
                const hasSelectedUnrelatedCrypartNum =
                    state.crystal_part_num &&
                    !crypart_nums.includes(state.crystal_part_num);
                const hasSelectedUnrelatedFrequency =
                    state.frequency && !frequencies.includes(state.frequency);
                const hasSelectedUnrelatedLoadCapacitance =
                    state.load_capacitance &&
                    !load_capacitances.includes(state.load_capacitance);
                const hasSelectedUnrelatedAec =
                    state.aec && !aecs.includes(state.aec);
                const shouldHide =
                    isAnySelected &&
                    (hasDimension ||
                        hasSelectedUnrelatedManufacturer ||
                        hasSelectedUnrelatedFamily ||
                        hasSelectedUnrelatedCrypartNum ||
                        hasSelectedUnrelatedFrequency ||
                        hasSelectedUnrelatedLoadCapacitance ||
                        hasSelectedUnrelatedAec);

                toggleCheckbox(checkbox, shouldHide);
            });

            frequencyCheckboxes.forEach((checkbox) => {
                const frequencies = cry_freq_mhz_arr.filter(
                    ({ field_cry_freq_mhz }) => field_cry_freq_mhz === checkbox.value
                );
                const manufacturers = [],
                    families = [],
                    crypart_nums = [],
                    dimensions = [];
                frequencies.forEach((frequency) => {
                    manufacturers.push(frequency.ic_manufacturer);
                    families.push(frequency.ic_family);
                    crypart_nums.push(frequency.field_cry_part_num);
                    dimensions.push(frequency.field_cry_dimensions);
                });
                const load_capacitances = cry_load_capacitance_arr
                    .filter(
                        ({ field_cry_freq_mhz }) => field_cry_freq_mhz === checkbox.value
                    )
                    .map(
                        ({ field_cry_load_capacitance }) => field_cry_load_capacitance
                    );
                const aecs = cry_aec_arr
                    .filter(
                        ({ field_cry_freq_mhz }) => field_cry_freq_mhz === checkbox.value
                    )
                    .map(({ field_cry_aec }) => field_cry_aec);
                const hasFrequency =
                    state.frequency && state.frequency !== checkbox.value;
                const hasSelectedUnrelatedManufacturer =
                    state.manufacturer && !manufacturers.includes(state.manufacturer);
                const hasSelectedUnrelatedFamily =
                    state.family && !families.includes(state.family);
                const hasSelectedUnrelatedCrypartNum =
                    state.crystal_part_num &&
                    !crypart_nums.includes(state.crystal_part_num);
                const hasSelectedUnrelatedDimension =
                    state.dimensions && !dimensions.includes(state.dimensions);
                const hasSelectedUnrelatedLoadCapacitance =
                    state.load_capacitance &&
                    !load_capacitances.includes(state.load_capacitance);
                const hasSelectedUnrelatedAec =
                    state.aec && !aecs.includes(state.aec);
                const shouldHide =
                    isAnySelected &&
                    (hasFrequency ||
                        hasSelectedUnrelatedManufacturer ||
                        hasSelectedUnrelatedFamily ||
                        hasSelectedUnrelatedCrypartNum ||
                        hasSelectedUnrelatedDimension ||
                        hasSelectedUnrelatedLoadCapacitance ||
                        hasSelectedUnrelatedAec);

                toggleCheckbox(checkbox, shouldHide);
            });

            load_capacitanceCheckboxes.forEach((checkbox) => {
                const load_capacitances = cry_load_capacitance_arr.filter(
                    ({ field_cry_load_capacitance }) =>
                        field_cry_load_capacitance === checkbox.value
                );
                const manufacturers = [],
                    families = [],
                    crypart_nums = [],
                    dimensions = [],
                    frequencies = [];
                load_capacitances.forEach((load_capacitance) => {
                    manufacturers.push(load_capacitance.ic_manufacturer);
                    families.push(load_capacitance.ic_family);
                    crypart_nums.push(load_capacitance.field_cry_part_num);
                    dimensions.push(load_capacitance.field_cry_dimensions);
                    frequencies.push(load_capacitance.field_cry_freq_mhz);
                });
                const aecs = cry_aec_arr
                    .filter(
                        ({ field_cry_load_capacitance }) =>
                            field_cry_load_capacitance === checkbox.value
                    )
                    .map(({ field_cry_aec }) => field_cry_aec);
                const hasLoadCapacitance =
                    state.load_capacitance && state.load_capacitance !== checkbox.value;
                const hasSelectedUnrelatedManufacturer =
                    state.manufacturer && !manufacturers.includes(state.manufacturer);
                const hasSelectedUnrelatedFamily =
                    state.family && !families.includes(state.family);
                const hasSelectedUnrelatedCrypartNum =
                    state.crystal_part_num &&
                    !crypart_nums.includes(state.crystal_part_num);
                const hasSelectedUnrelatedDimension =
                    state.dimensions && !dimensions.includes(state.dimensions);
                const hasSelectedUnrelatedFrequency =
                    state.frequency && !frequencies.includes(state.frequency);
                const hasSelectedUnrelatedAec =
                    state.aec && !aecs.includes(state.aec);
                const shouldHide =
                    isAnySelected &&
                    (hasLoadCapacitance ||
                        hasSelectedUnrelatedManufacturer ||
                        hasSelectedUnrelatedFamily ||
                        hasSelectedUnrelatedCrypartNum ||
                        hasSelectedUnrelatedDimension ||
                        hasSelectedUnrelatedFrequency ||
                        hasSelectedUnrelatedAec);

                toggleCheckbox(checkbox, shouldHide);
            });

            aecCheckboxes.forEach((checkbox) => {
                const aecs = cry_aec_arr.filter(
                    ({ field_cry_aec }) => field_cry_aec === checkbox.value
                );
                const manufacturers = [],
                    families = [],
                    crypart_nums = [],
                    dimensions = [],
                    frequencies = [],
                    load_capacitances = [];
                aecs.forEach((aec) => {
                    manufacturers.push(aec.ic_manufacturer);
                    families.push(aec.ic_family);
                    crypart_nums.push(aec.field_cry_part_num);
                    dimensions.push(aec.field_cry_dimensions);
                    frequencies.push(aec.field_cry_freq_mhz);
                    load_capacitances.push(aec.field_cry_load_capacitance);
                });
                const hasAec = state.aec && state.aec !== checkbox.value;
                const hasSelectedUnrelatedManufacturer =
                    state.manufacturer && !manufacturers.includes(state.manufacturer);
                const hasSelectedUnrelatedFamily =
                    state.family && !families.includes(state.family);
                const hasSelectedUnrelatedCrypartNum =
                    state.crystal_part_num &&
                    !crypart_nums.includes(state.crystal_part_num);
                const hasSelectedUnrelatedDimension =
                    state.dimensions && !dimensions.includes(state.dimensions);
                const hasSelectedUnrelatedFrequency =
                    state.frequency && !frequencies.includes(state.frequency);
                const hasSelectedUnrelatedLoadCapacitance =
                    state.load_capacitance &&
                    !load_capacitances.includes(state.load_capacitance);
                const shouldHide =
                    isAnySelected &&
                    (hasAec ||
                        hasSelectedUnrelatedManufacturer ||
                        hasSelectedUnrelatedFamily ||
                        hasSelectedUnrelatedCrypartNum ||
                        hasSelectedUnrelatedDimension ||
                        hasSelectedUnrelatedFrequency ||
                        hasSelectedUnrelatedLoadCapacitance);

                toggleCheckbox(checkbox, shouldHide);
            });
    })
);

sample html container: i could not paste long code due to limited text in the body.

 <div class="col-sm-2">
      <div class="cr_filter mt-1">
            <div class="card text-s cr-card-filter" data-id="large">
                <div class="card-header p-0" id="frequency_dropdown_btn">
                    <button class="btn text-s d-flex arrow-down arrow-bl justify-content-between align-items-center w-100" type="button" id="btn-frequency">
                        <span>{{ 'Frequency(MHz)'|t }}</span>
                    </button>
                </div>
                <div id="frequency_dropdown_list" class="dropdown-list">
                    <div class="card-body d-flex flex-column">
                        <ul id="frequencyDropdown" class="list-unstyled">
                            {% for cry_freq_mhz in cry_freq_mhz_arr_no_duplicate %}
                            <li>
                                <label>
                                    <input 
                                        class="kc_checkbox" 
                                        type="checkbox" 
                                        id="cry_freq_mhz_{{ loop.index }}" 
                                        value="{{ cry_freq_mhz.field_cry_freq_mhz }}" 
                                        data-column="frequency" 
                                        data-family="{{ cry_freq_mhz.ic_family }}" 
                                        data-manufacturer="{{ cry_freq_mhz.ic_manufacturer }}">
                                    <span class="kc_checkbox_parts d-flex align-items-center">
                                        {{ cry_freq_mhz.field_cry_freq_mhz }}
                                    </span>
                                </label>
                            </li>
                            {% endfor %}
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>

Are there any typescript bundlers that support sequential watcher/dev-server startup?

We have a project that we are currently restructuring. Our project is a monorepo with purely client-side code, separated into a lot of packages where some of them are running module federation.

Some of our packages might look like this:

  • Host
  • Remote 1
  • Remote 2
  • Component 1
  • Component 2
  • SharedConfig
  • SharedBase

Tried to draw a dependency diagram
Dependency diagram
The 2 striped lines are because of federated modules. Theses are not strictly needed during the build process.
Every package is depending on both SharedConfig and SharedBase. The globe is dev-servers and the boxes are watchers.

We are using yarn workspaces to organize and select which projects to start, using their workspace foreach cmd. Host and remotes will be running locally on a webpack-dev-server and the other projects will be running with a webpack watcher. All packages are built separately before consumed, and we are very interested in keeping it that way.

When using yarn workspaces foreach cmd, we only have the option to start all in parallel. As starting them in sequence will stop at the first one, since the watcher or dev-server only returns when they are stopped again. This makes for a lot of errors in the console as we run in to instances where a package tries to consume a half-built package. My initial though was that webpack’s watchers/dev-servers would rebuild when the half-built package was fully built. But it seems that is not the case.

Ideally we would like to start the watchers/dev-servers sequentially. So starting from the package without any dependencies, and working its way up. And only starting the next when the project is fully built.

I’ve experimented with the Webpack node api, and seems like we can do that in a custom setup. But i can’t believe we are the first to encounter this issue. We are not locked to Webpack as our bundler, and can use a mix of bundlers if necessary. We would like to stick with yarn, but are open to move to another tool if absolutely necessary-

So are there any typescript bundlers that support sequential watcher/dev-server startup? Or are we in teoritory where we should make a custom solution.

Odoo18: override of t-name template not applied

In odoo.sh, after the successfull upgrade of my DATABASE from odoo16 into odoo18 on a Staging branch, I have changed the js and its related t-template files (to display html into gantt cell) of one of my custom module, and git-commited my changes into this Staging branch.
But, my xml-change (xpath) are not applied (and no error displayed at all and nothing in the browser-console).

enter image description here

mycustommodule/static/src/views/event_gantt_renderer_zsb.xml :

<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
    <t t-name="mycustommodule.GanttRenderer.Pill" t-inherit="web_gantt.GanttRenderer.Pill">
        <xpath expr="//span[hasclass('o_gantt_pill_title')]" position="replace">
            <span class="o_gantt_pill_title text-truncate mx-2" t-out="pill.displayName" />
        </xpath>
    </t>
</templates>

mycustommodule/__manifest__.py:

{
    'name': "mycustommodule",
    """,
    'version': '18.0.0.0.3',
    'depends': ['event_enterprise','website_event_sale','web_gantt'],
    'data': [
        'views/event_gantt_js_class_view.xml',
    ],

    'license': 'LGPL-3',
    'assets': {
        'web.assets_backend_lazy':['mycustommodule/static/src/views/**/*',],
    }
}

React Native Error: unable to load script error in react native

REACT NATIVE CLI
I’m currently facing an issue with my React Native project. It successfully runs on one specific physical device, but I’m unable to run it on any emulator or other physical devices. Although the terminal shows “Build Successful,” the app fails to load the script on the device.

Here are the solutions I’ve already tried:

Enabled Wireless Debugging.
Set CleartextTraffic = true in the Android manifest.
Cleared the cache and node_modules.
Used the command adb reverse tcp:8081 tcp:8081.
Killed any processes using port 8081.
Created a new project and copied over the code from the old one.
Tried to run the project on another laptop.

Despite these attempts, the issue persists.

Enabled Wireless Debugging.
Set CleartextTraffic = true in the Android manifest.
Cleared the cache and node_modules.
Used the command adb reverse tcp:8081 tcp:8081.
Killed any processes using port 8081.
Created a new project and copied over the code from the old one.
Tried to run the project on another laptop.

expecting my app to debug on every device

How to get the IANA time zone from a Date object which is in UTC? [duplicate]

I have a Javascript Date object myTime which is in UTC time. When you do myTime.toString() then the output will be like 2025-03-12T05:17:53.8447517Z. As an aside, that time is 3/12/2025, 5:17 AM UTC in US format. I want to get the IANA time zone name America/New_York from the myTime Date object. How do I do it ? I searched online and could not get any answer to my question.

VueJS – Creating Custom Calendar

can you help me find the problem with my code?

I have a custom calendar in Vue.js for the schedule page. The columns are Title, Type, and the Time in military format (00:00 to 23:00).

If there is an event from January 2, 2025, at 05:00 AM to January 3, 2025, at 03:00 AM, it should be displayed as follows:

When I search for January 2, 2025, the event should be highlighted from 05:00 to 23:00.
When I search for January 3, 2025, the event should be highlighted from 00:00 to 03:00.

And it should calculate the width of the event to fit in the table. the time table cell is 60px. I’m stuck here for so long

<template>
  <div class="schedule-container">
    <div class="schedule-header">
      <div class="schedule-header-title">
        <h1>Schedule</h1>
        <button v-if="userCanCreateReservations" class="button-primary" @click="openReservationModal">
          Add Event
          <img src="/static/img/plus-white.svg" alt="">
        </button>
      </div>
      <input type="date" v-model="selectedDate" @change="emitDateChange" />
      <CustomSelect v-model="filter.selectedEventType" :options="eventTypes" searchable placeholder="Type" />
      <HiloSelect v-model="filter.selectedScheduleType" :options="scheduleTypes" searchable placeholder="Full Schedule" />
    </div>
    <pre>{{ allEvents }}</pre>
    <div class="table-responsive">
      <table class="table table-bordered">
        <thead>
          <tr>
            <th></th>
            <th class="text-left">Tail Number</th>
            <th class="text-left">Type</th>
            <th v-for="hour in 24" :key="hour" :style="{ minWidth: hourWidth + 'px', maxWidth: '60px' }">
              {{ String(hour - 1).padStart(2, '0') }}:00
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(row, index) in tableData" :key="index">
            <td>
              <center>
                <div>{{ row.id }}</div>
              </center>
            </td>
            <td class="text-left">{{ row.tailNumber || row.name }}</td>
            <td class="text-left">{{ row.model }}</td>
            <td v-for="hour in 24" :key="hour" class="position-relative">
              <div
                v-if="shouldHighlight(row, hour - 1)"
                class="position-absolute rounded p-1 small event-text"
                :style="getEventStyle(row, hour - 1)"
              >
                {{ getEventName(row) }}
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

<script>
import CustomSelect from "@/components/Common/CustomSelect.vue";
import dayjs from "dayjs";

export default {
  components: { CustomSelect },
  props: {
    currentUser: Object,
    aircraft: Array,
    instructors: Array,
    rooms: Array,
    eventTypes: Array,
    selectedCalendarDate: Object,
    userCanCreateReservations: Boolean,
    userCanAccessSettings: Boolean,
    standbyFlightsExist: Boolean,
    events: Array,
    filteredAircraft: Array,
    allEvents: Array
  },
  data() {
    return {
      selectedDate: dayjs().format("YYYY-MM-DD"),
      hourWidth: 60,
      selectedType: null,
      filter: {
        selectedEventType: "all",
        selectedScheduleType: "all"
      },
      scheduleTypes: []
    };
  },
  watch: {
    selectedDate(newDate) {
      this.emitDateChange();
    }
  },
  computed: {
    tableData() {
      return [...this.filteredAircraft, ...this.instructors, ...this.rooms];
    },
    filteredEvents() {
      const selectedDate = new Date(this.selectedDate);
      return this.events.filter(event => {
        const eventStartDate = new Date(event.startDateTime);
        const eventEndDate = new Date(event.endDateTime);
        return (
          eventStartDate.toDateString() === selectedDate.toDateString() ||
          eventEndDate.toDateString() === selectedDate.toDateString() ||
          (eventStartDate <= selectedDate && eventEndDate >= selectedDate)
        );
      });
    }
  },
  methods: {
    openReservationModal() {
      this.$emit("show-reservation-modal");
    },
    resetShortcutButtons() {
      this.filter = {
        selectedEventType: null,
        selectedScheduleType: null
      };
    },
    resetFilters() {
      this.resetShortcutButtons();
      this.$emit("reset-schedule-filters");
    },
    emitDateChange() {
      this.$emit("update-date", this.selectedDate);
    },
    shouldHighlight(row, hour) {
      const matchingEvents = this.filteredEvents.filter(event => 
        event.aircraftId === row.id || 
        event.instructorId === row.id || 
        event.roomId === row.id
      );

      for (const event of matchingEvents) {
        const eventStartDate = new Date(event.startDateTime);
        const eventEndDate = new Date(event.endDateTime);
        const selectedDate = new Date(this.selectedDate);

        if (
          eventStartDate.toDateString() === selectedDate.toDateString() ||
          eventEndDate.toDateString() === selectedDate.toDateString() ||
          (eventStartDate <= selectedDate && eventEndDate >= selectedDate)
        ) {
          if (eventStartDate.toDateString() !== eventEndDate.toDateString()) {
            if (selectedDate.toDateString() === eventStartDate.toDateString()) {
              const startHour = eventStartDate.getHours();
              if (hour >= startHour) {
                return true;
              }
            }
            else if (selectedDate.toDateString() === eventEndDate.toDateString()) {
              const endHour = eventEndDate.getHours();
              if (hour < endHour) {
                return true;
              }
            }
            else {
              return true;
            }
          } else {
            const startHour = eventStartDate.getHours();
            const endHour = eventEndDate.getHours();
            if (hour >= startHour && hour < endHour) {
              return true;
            }
          }
        }
      }

      return false;
    },
    getEventStyle(row, hour) {
      const matchingEvents = this.filteredEvents.filter(event => 
        event.aircraftId === row.id || 
        event.instructorId === row.id || 
        event.roomId === row.id
      );

      for (const event of matchingEvents) {
        const eventStartDate = new Date(event.startDateTime);
        const eventEndDate = new Date(event.endDateTime);
        const selectedDate = new Date(this.selectedDate);

        if (
          eventStartDate.toDateString() === selectedDate.toDateString() ||
          eventEndDate.toDateString() === selectedDate.toDateString() ||
          (eventStartDate <= selectedDate && eventEndDate >= selectedDate)
        ) {
          if (eventStartDate.toDateString() !== eventEndDate.toDateString()) {
            if (selectedDate.toDateString() === eventStartDate.toDateString()) {
              const startHour = eventStartDate.getHours();
              if (hour >= startHour) {
                const remainingHours = 24 - startHour;
                return {
                  width: `${remainingHours * this.hourWidth}px`,
                  backgroundColor: event.eventType.scheduledColor,
                  color: event.eventType.textColor,
                  minHeight: '26px',
                  padding: '2px 5px',
                  textAlign: 'center'
                };
              }
            }
            else if (selectedDate.toDateString() === eventEndDate.toDateString()) {
              const endHour = eventEndDate.getHours();
              if (hour < endHour) {
                return {
                  width: `${endHour * this.hourWidth}px`,
                  backgroundColor: event.eventType.scheduledColor,
                  color: event.eventType.textColor,
                  minHeight: '26px',
                  padding: '2px 5px',
                  textAlign: 'center'
                };
              }
            }
            else {
              return {
                width: `${24 * this.hourWidth}px`,
                backgroundColor: event.eventType.scheduledColor,
                color: event.eventType.textColor,
                minHeight: '26px',
                padding: '2px 5px',
                textAlign: 'center'
              };
            }
          } else {
            const startHour = eventStartDate.getHours();
            const endHour = eventEndDate.getHours();
            if (hour >= startHour && hour < endHour) {
              const duration = endHour - startHour;
              return {
                width: `${duration * this.hourWidth}px`,
                backgroundColor: event.eventType.scheduledColor,
                color: event.eventType.textColor,
                minHeight: '26px',
                padding: '2px 5px',
                textAlign: 'center'
              };
            }
          }
        }
      }

      return {};
    },
    getEventName(row) {
      const matchingEvent = this.filteredEvents.find(event => 
        event.aircraftId === row.id || 
        event.instructorId === row.id || 
        event.roomId === row.id
      );

      return matchingEvent ? matchingEvent.displayName : "";
    }
  },
  mounted() {
    
  }
};
</script>

<style scoped>
.schedule-container {
    display: flex;
    flex-direction: column;
}

.schedule-header {
    display: grid;
    align-items: center;
    gap: 15px;
    grid-template-columns: repeat(4, 1fr);
    box-sizing: border-box;
}

.button-primary {
    background-color: #3C78FF;
    color: #fff;
    border-radius: 5px;
    padding: 3px 10px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: normal;
    box-sizing: border-box;
    height: fit-content;
    font-size: 16px;
}

.schedule-header-title {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.schedule-header-title h1 {
    font-weight: 600;
    color: #404040;
}

.table-responsive {
    overflow-x: auto;
    white-space: nowrap;
    overflow-y: hidden;
}

.table-bordered {
    border-collapse: collapse;
    width: 100%;
}

th,
td {
    padding: 3px !important;
    text-align: center;
}

th {
    background: #3C78FF;
    color: white !important;
    text-transform: lowercase !important;
    text-transform: capitalize !important;
}

.position-absolute {
    top: 0;
    left: 0;
    border-radius: 30px !important;
    text-overflow: ellipsis;
}

.schedule-header-filter {
    display: grid;
}

td:first-child div {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: gray;
}

.event-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    font-size: 12px;
}
input[type="date"] {
    background: #fff;
    border: 1px solid #ccc;
    height: 33px;
}
</style>

javascript array remap.. please help me

[
  { start_status: 'WAT', finish_status: 'FNS', id: ['1-001'] },
  { start_status: 'WAT', finish_status: 'STP', id: ['1-002'] },
  { start_status: 'FNS', finish_status: 'WAT', id: ['2-002'] },
  { start_status: 'FNS', finish_status: 'WAT', id: ['2-003'] },
  { start_status: 'FNS', finish_status: 'WAT', id: ['2-004'] },
  { start_status: 'FNS', finish_status: 'WAT', id: ['2-005'] }
]

interface IUnitChange {
  start_status: string,
  finish_status: string,
  id: string[],
}
const log_json: any = JSON.parse(JSON.stringify(arr));
const result: IUnitChange[] = [];

log_json.map((row) => {
const data = result.find((value) => (value.start_status === row.start_status && value.finish_status === row.finish_status));

  if (data === undefined) {
    result.push(row);
  }
  else {
    data.id.push(row.id);
  }
})

console.dir(result,{depth: null});
=====>

[
  { start_status: 'WAT', finish_status: 'FNS', id: ['1-001'] },
  { start_status: 'WAT', finish_status: 'STP', id: ['1-002'] },
  { start_status: 'FNS', finish_status: 'WAT', id: ['2-002','2-003','2-004','2-005'] }
]

I want to change json array like upper screen.
[status value] can be added.
So I can’t branch with an if statement.

I want to make one sentence not using if statement.

i cant access any updates happens to an array (board) whenever im trying to access it to get a winner, i keep getting its initial values

//GameBoard
function Gameboard() {
  const rows = 3;
  const columns = 3;
  const board = [];

  for (i = 0; i < rows; i++) {
    board[i] = [];
    for (j = 0; j < columns; j++) {
      // Cell function adds value=0 for each square
      board[i].push(Cell());
    }
  }
  const getBoard = () => board;
  const printBoard = () => {
    return board.map((row) => row.map((cell) => cell.getValue()));
  };
  const applyMark = (row, column, player) => {
    return board[row][column].addMark(player);
  };

  return { printBoard, getBoard, applyMark };
}

function Test() {
  console.log(gameBoard.printBoard());
}
//Check for winner
function Checkforwinner() {
  const board = Gameboard();
  const array = board
    .getBoard()
    .map((row) =>
      row.reduce(
        (accummulator, current) => accummulator + current.getValue(),
        "",
      ),
    );
  //Check for winning horizontally
  const winnerX = () => {
    for (i = 0; i < 3; i++) {
      if (array[i] === "XXX") {
        console.log(`It's ${players[0].name}'s win!!!`);
      }
    }
    //Check for winning for first vertical line
    let verticalX0 = 0;
    for (i = 0; i < 3; i++) {
      if (board.getBoard()[i][0].getValue() === "X") {
        verticalX0 += 1;
      }
    }
    if (verticalX0 === 3) {
      console.log(`It's ${players[0].name}'s win!!!`);
    }
    //Check for winning for second vertical line
    let verticalX1 = 0;
    for (i = 0; i < 3; i++) {
      if (board.getBoard()[i][1].getValue() === "X") {
        verticalX1 += 1;
      }
    }
    if (verticalX1 === 3) {
      console.log(`It's ${players[0].name}'s win!!!`);
    }
    //Check for winning for third vertical line
    let verticalX2 = 0;
    for (i = 0; i < 3; i++) {
      if (board.getBoard()[i][2].getValue() === "X") {
        verticalX2 += 1;
      }
    }
    if (verticalX2 === 3) {
      console.log(`It's ${players[0].name}'s win!!!`);
    }
  };
  const winnerO = () => {
    for (i = 0; i < 3; i++) {
      if (array[i] === "OOO") {
        console.log(`It's ${players[1].name}'s win!!!`);
      }
    }

    //Check for winning for first vertical line
    let verticalO0 = 0;
    for (i = 0; i < 3; i++) {
      if (board.getBoard()[i][0].getValue() === "O") {
        verticalO0 += 1;
      }
    }
    if (verticalO0 === 3) {
      console.log(`It's ${players[1].name}'s win!!!`);
    }
    //Check for winning for second vertical line
    let verticalO1 = 0;
    for (i = 0; i < 3; i++) {
      if (board.getBoard()[i][1].getValue() === "O") {
        verticalO1 += 1;
      }
    }
    if (verticalO1 === 3) {
      console.log(`It's ${players[1].name}'s win!!!`);
    }
    //Check for winning for third vertical line
    let verticalO2 = 0;
    for (i = 0; i < 3; i++) {
      if (board.getBoard()[i][2].getValue() === "O") {
        verticalO2 += 1;
      }
    }
    if (verticalO2 === 3) {
      console.log(`It's ${players[1].name}'s win!!!`);
    }
  };
  winnerX();
  winnerO();
  console.log(array);
  return { winnerX, winnerO };
}

function Cell() {
  let value = 0;

  let addMark = (player) => {
    value = player;
  };
  const getValue = () => value;
  return { addMark, getValue };
}

function Gamecontroller(player1 = "firstPlayer", player2 = "secondPlayer") {
  const board = Gameboard();
  const players = [
    { name: player1, mark: "X" },
    { name: player2, mark: "O" },
  ];
  const getPlayers = () => players;
  let activePlayer = players[0];
  const getActivePlayer = () => activePlayer;
  const switchPlayer = () => {
    activePlayer = activePlayer === players[0] ? players[1] : players[0];
  };
  const nextRound = () => {
    console.log(board.printBoard());
    console.log(`Now it's ${getActivePlayer().name}'s turn to play`);
  };
  const playRound = (row, column) => {
    console.log(
      `${getActivePlayer().name} has played in ${row}row and ${column}column`,
    );
    board.applyMark(row, column, getActivePlayer().mark);
    checkForWinner.winnerX();
    checkForWinner.winnerO();
    Checkforwinner();
    switchPlayer();
    nextRound();
  };
  nextRound();
  return { nextRound, getActivePlayer, playRound, getPlayers };
}

const gameBoard = Gameboard();
const gameController = Gamecontroller();
const checkForWinner = Checkforwinner();

i get the right values of the array in Gamecontroller but i dont get it in Checkforwinner
although when i first created Checkforwinner i did it inside Gameboard function and it gave me the results i wanted but i thought of making it a function of its own away from the Gameboard function to be more organized and now i dont get any updated values

i tried accessing the board array by using getBoard() rather than just accessing the variable it still doesn’t work

Why does using element.scrollIntoView() change my layout sizes in my Angular app?

My app is using Angular Material Components as a component library.
To supplement for layout I am importing Bootstrap 5 utilities.

The problem is that when my scrollToTop() function is called in my List Wrapper Class it pushes the div row in the Shell Template above it up by about 5px. It is enough that the buttons inside the first row have no margin with the my app header (which I am not going to add code for).

When I comment out element.scrollIntoView(true); The problem does not occur.

The scrollToTop() function is triggered as soon as the component is rendered due to the signal effect that is instantiated in the constructor.

Please note the CSS in Shell Component.

The application requirement is that the user should not have to use a scroll wheel on the list. It should keep the selected item in the view and at least one other item above the selected, if index is not zero, so the user can click to go up or down.

List Wrapper Class:

import { Component, computed, effect, ElementRef, inject, viewChildren } from '@angular/core';
import { MyStore } from '../../../stores/my-store.store';

@Component({
  selector: 'app-my-list-wrapper',
  standalone: true,
  templateUrl: './my-list-wrapper.component.html'
})
export class MyListWrapperComponent {
  listItems = viewChildren<ElementRef>('orderedListItem');
  myStore = inject(MyStore);

  readonly items = computed(() =>
    this.myStore
      .getItems()
      .map((result) => result.model)
  );

  selected= computed(
    () => this.myStore.selected()?.index - 1
  );

  constructor() {
    effect(() => {
      const index = this.selected();
      if (index >= 0 && !!this.listItems()) {
        setTimeout(() => this.scrollToTop(index), 0); // Ensure DOM is updated before scrolling
      }
    });
  }

  setCurrent(index: number) {
    if (step < this.myStore.items().length && step >= 0) {
      this.myStore.setSelected(
        this.myStore.items()[index]
      );
      this.scrollToTop(index);
    }
  }

  scrollToTop(index: number) {
    if (index > 0) index--;
    const element = this.listItems().at(index)?.nativeElement;
    if (element) {
      element.scrollIntoView(true);
    } else {
      console.error('List item not found at index:', index);
    }
  }
}

List Wrapper Template:

<div class="row">
  <div class="col overflow-y-hidden">
    @for (item of items(); track item; let index = $index) {
      <div class="ordered-list-item" (click)="setCurrent(index)" #orderedListItem>
        <div
          class="ordered-list-item-content {{
            index === selected() ? 'content-active' : ''
          }}"
        >
          <div mat-card-avatar class="ordered-list-item-content-icon">
            {{ index + 1 }}
          </div>
          <div class="ordered-list-item-content-title">
            {{ item }}
          </div>
        </div>
      </div>
      }
  </div>
</div>

Shell Class:

import { Component, OnInit, computed, inject } from '@angular/core';
import { MyStore } from '../../stores/my-store.store';
import { ActivatedRoute, Router } from '@angular/router';
import { MatDividerModule } from '@angular/material/divider';
import { MyOtherStore } from '../../stores/my-other-store.store';
import { MyListWrapperComponent } from './list-wrapper/list-wrapper.component';
import { MyItemDetailsComponent } from './item-details/item-details.component';

@Component({
  selector: 'app-shell',
  standalone: true,
  imports: [
    MatDividerModule,
    MyListWrapperComponent,
    MyItemDetailsComponent
  ],
  templateUrl: './shell.component.html',
  styleUrl: './shell.component.scss',
})
export class ShellComponent implements OnInit {
  readonly route = inject(ActivatedRoute);
  readonly router = inject(Router);
  myStore = inject(MyStore);
  myOtherStore = inject(MyOtherStore);

  readonly selectedDetails = computed(() =>
    this.myStore
      .items()
      .flatMap((result) => result.details)
  );

  selected = this.myOtherStore.selected;

  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id') ?? 'error';

    this.myStore.fetchItems(id);
  }
}

Shell Template:

<div class="container-fluid overflow-hidden">
  <div class="row">
    <div class="col">
      <div class="row align-items-center">
        <div class="col-auto">
          <button ... />
        </div>
        <div class="col">
          <p>
            {{ title }}
          </p>
        </div>
        <div class="col-auto">
          <button ... />
        </div>
      </div>
      <div class="row">
        <div class="col">
          @if (selected().title != '') {
            <h1>
              {{ selected().title }}
            </h1>
          }
          @else {
            <h1>
              No Selected
            </h1>
          }
        </div>
      </div>
    </div>
  </div>
  <div class="row shell-body">
    <div class="col-3 hl-container">
      @if (selected().title != '') {
        <app-my-list-wrapper />
      }
      @else {
        <div class="w-100 h-100 bg-primary text-center">
          <h2>My List Wrapper Goes Here</h2>
        </div>
      }
    </div>
    <div class="col-9 shell-body">
      <app-item-details />
    </div>
  </div>
</div>

Shell CSS:

.hl-container {
  height: calc(
    90vh - 50px
  ); // 10vh is the height of the shell header, 50px is the height of the application header
  overflow-y: scroll;
}

.hl-container::-webkit-scrollbar {
  display: none;
}

What I already tried:

I was getting the selected element from a div with #scrollContainer for these.

scrollToTop(index: number) {
  const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
  if (itemElement) {
    const container = this.scrollContainer().nativeElement;
    const itemOffsetTop = itemElement.offsetTop;
    container.scrollTop = itemOffsetTop;
  } else {
    console.error('List item not found at index:', index);
  }
}
scrollToTop(index: number) {
  const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
  if (itemElement) {
    const container = this.scrollContainer().nativeElement;
    const itemOffsetTop = itemElement.offsetTop;
    container.scrollTop = itemOffsetTop - container.offsetTop;
  } else {
    console.error('List item not found at index:', index);
  }
}
scrollToTop(index: number) {
  if (index > 0) index--;
  const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
  if (itemElement) {
    const container = this.scrollContainer().nativeElement;
    const itemRect = itemElement.getBoundingClientRect();
    const containerRect = container.getBoundingClientRect();
    const offset = itemRect.top - containerRect.top + container.scrollTop;
    container.scrollTo({ top: offset, behavior: 'smooth' });
  } else {
    console.error('List item not found at index:', index);
  }
}
scrollToTop(index: number) {
  if (index > 0) index--;
  const itemElement = this.scrollContainer().nativeElement.querySelector(`#ordered-item-${index}`);
  if (itemElement) {
    const container = this.scrollContainer().nativeElement;
    const itemOffsetTop = itemElement.offsetTop;
    container.scrollTo({ top: itemOffsetTop, behavior: 'smooth' });
  } else {
    console.error('List item not found at index:', index);
  }
}

Hoping someone here can at least explain what is happening with element.scrollIntoView(true) if not provide a fix. That is the only thing that makes the selected element actually scroll.

Adding Application Data in Twilio Event Stream

Hey I am Looking for adding application related data in twilio webhook event stream currently there is option called statusCallback Url we can provide webhook url with query params to track the data but for large volume messages we can’t rely on indivdual message updates instead we can use event stream but the problem is in event stream there is no options to get custom application data does anyone knew

kindly provide me tip to find the way to solve this usecase

How can I call the function even in the case of myFunction{}?

function myFunction() {
    return "Hello World!";
}

console.log(myFunction{}); 

We know that in JavaScript, a function is called as myFunction(). That is, using () , but I want to use {} as myFunction{} . According to the rules, this is not possible. But is it possible to do this?

I tried RegExp replaces. But it doesn’t work at all.

Coordinate function in Google Maps API polygon?

Is anyone familiar with Google Maps API and putting polygons onto a still map?

I have a lot of coordinates I want to place down, but it’s difficult to copy and paste every single one into the structure they have on their Javascript sample page.

I have my lat and lng stored like this for each of my locations (which makes it hard to copy and paste into the polygon-making parts):

  const tourStops = [
            {
                id: 1,
                position: { lat: ##, lng: ## },
                title: "Some title",
            },
            {
                id: 2,
                position: { lat: ##, lng: ## },
                title: "Some other title",
            },

Is there a function I could build that would make it so that each lat and lng gets fed in from my locations instead of copying and pasting every single set into the structure like in their example (below)?

  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];