492 lines
16 KiB
Vue
492 lines
16 KiB
Vue
<script lang="ts">
|
|
import { NavigationItemProps } from "@/components/models/navigation/NavigationItem.vue";
|
|
import { computed, defineComponent, ref, watch } from "vue";
|
|
import SessionUser from "@/components/session/token/SessionUser.vue";
|
|
import i18n from "@/i18n";
|
|
import {
|
|
ensureDraftTransactionCustomerLoaded,
|
|
getDraftTransactionCustomerNumber,
|
|
} from "@/composables/useDraftTransactionCustomer.js";
|
|
import { fetchSuperUserDraftCount } from "@/components/models/navigation/items/superUserDraftCount.js";
|
|
import { fetchSuperUserBookingCounts } from "@/components/models/navigation/items/superUserBookingCount.js";
|
|
import { NAVIGATION_COUNT_REFRESH_EVENT } from "@/components/models/navigation/items/navigationCountEvents.js";
|
|
|
|
const firstToUpperCase = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
|
|
const t = (key: string) => i18n.global.t(key);
|
|
const tf = (key: string, fallback: string) => {
|
|
const value = t(key);
|
|
return value === key ? fallback : value;
|
|
};
|
|
const superuser_draft_count = ref(0);
|
|
const superuser_draft_count_loading = ref(false);
|
|
const superuser_booking_counts = ref({
|
|
past: 0,
|
|
current: 0,
|
|
future: 0,
|
|
});
|
|
const superuser_booking_count_loading = ref(false);
|
|
const draftTransactionCustomerNumber = computed(() => getDraftTransactionCustomerNumber());
|
|
let draftCountRequestId = 0;
|
|
let bookingCountRequestId = 0;
|
|
let superUserBookingCountFetchInFlight = false;
|
|
let superUserDraftCountFetchInFlight = false;
|
|
let superUserBookingCountRefreshQueued = false;
|
|
let superUserDraftCountRefreshQueued = false;
|
|
let queuedSuperUserBookingLoadingIndicator = false;
|
|
let queuedSuperUserDraftLoadingIndicator = false;
|
|
|
|
const canUseSuperUserNavigationCounts = () => SessionUser.canAccessSuperUser();
|
|
|
|
const resetSuperUserNavigationCounts = () => {
|
|
bookingCountRequestId += 1;
|
|
draftCountRequestId += 1;
|
|
superuser_booking_counts.value = {
|
|
past: 0,
|
|
current: 0,
|
|
future: 0,
|
|
};
|
|
superuser_booking_count_loading.value = false;
|
|
superuser_draft_count.value = 0;
|
|
superuser_draft_count_loading.value = false;
|
|
superUserBookingCountFetchInFlight = false;
|
|
superUserDraftCountFetchInFlight = false;
|
|
superUserBookingCountRefreshQueued = false;
|
|
superUserDraftCountRefreshQueued = false;
|
|
queuedSuperUserBookingLoadingIndicator = false;
|
|
queuedSuperUserDraftLoadingIndicator = false;
|
|
};
|
|
|
|
const getSuperUserBookingsBadges = () => {
|
|
if (superuser_booking_count_loading.value) {
|
|
return [
|
|
{
|
|
type: "info" as const,
|
|
text: "",
|
|
condition: true,
|
|
classes: ["desktop-buefy-badge-loading"],
|
|
testId: "desktop-buefy-nav-bookings-badge-loading",
|
|
tooltip: "Indlæser bookinger",
|
|
tooltipTestId: "desktop-buefy-nav-bookings-badge-loading-tooltip",
|
|
},
|
|
];
|
|
}
|
|
|
|
return [
|
|
{
|
|
type: "danger" as const,
|
|
text: superuser_booking_counts.value.past.toString(),
|
|
condition: superuser_booking_counts.value.past > 0,
|
|
testId: "desktop-buefy-nav-bookings-badge-overdue",
|
|
tooltip: "Tidligere",
|
|
tooltipTestId: "desktop-buefy-nav-bookings-badge-overdue-tooltip",
|
|
},
|
|
{
|
|
type: "info" as const,
|
|
text: superuser_booking_counts.value.current.toString(),
|
|
condition: superuser_booking_counts.value.current > 0,
|
|
testId: "desktop-buefy-nav-bookings-badge",
|
|
tooltip: "I dag",
|
|
tooltipTestId: "desktop-buefy-nav-bookings-badge-tooltip",
|
|
},
|
|
{
|
|
type: "info" as const,
|
|
text: superuser_booking_counts.value.future.toString(),
|
|
condition: superuser_booking_counts.value.future > 0,
|
|
classes: ["desktop-buefy-bookings-badge-future"],
|
|
testId: "desktop-buefy-nav-bookings-badge-future",
|
|
tooltip: "Fremtidige",
|
|
tooltipTestId: "desktop-buefy-nav-bookings-badge-future-tooltip",
|
|
},
|
|
];
|
|
};
|
|
|
|
const getSuperUserDraftsBadge = () => {
|
|
if (superuser_draft_count_loading.value) {
|
|
return {
|
|
type: "info" as const,
|
|
text: "",
|
|
condition: true,
|
|
classes: ["desktop-buefy-badge-loading"],
|
|
testId: "desktop-buefy-nav-drafts-badge-loading",
|
|
tooltip: "Indlæser kladder",
|
|
tooltipTestId: "desktop-buefy-nav-drafts-badge-loading-tooltip",
|
|
};
|
|
}
|
|
|
|
return {
|
|
type: "info" as const,
|
|
text: superuser_draft_count.value.toString(),
|
|
condition: superuser_draft_count.value > 0,
|
|
testId: "desktop-buefy-nav-drafts-badge",
|
|
tooltip: t("nav.drafts"),
|
|
tooltipTestId: "desktop-buefy-nav-drafts-badge-tooltip",
|
|
};
|
|
};
|
|
|
|
const fetchCurrentSuperUserBookingCount = async ({ showLoadingIndicator = false } = {}) => {
|
|
if (!canUseSuperUserNavigationCounts()) {
|
|
resetSuperUserNavigationCounts();
|
|
return;
|
|
}
|
|
|
|
if (superUserBookingCountFetchInFlight) {
|
|
superUserBookingCountRefreshQueued = true;
|
|
queuedSuperUserBookingLoadingIndicator = queuedSuperUserBookingLoadingIndicator || showLoadingIndicator;
|
|
return;
|
|
}
|
|
|
|
if (showLoadingIndicator) {
|
|
superuser_booking_count_loading.value = true;
|
|
superuser_booking_counts.value = {
|
|
past: 0,
|
|
current: 0,
|
|
future: 0,
|
|
};
|
|
}
|
|
|
|
superUserBookingCountFetchInFlight = true;
|
|
const requestId = ++bookingCountRequestId;
|
|
let didApply = false;
|
|
|
|
try {
|
|
const nextBookingCounts = await fetchSuperUserBookingCounts();
|
|
|
|
if (requestId !== bookingCountRequestId) {
|
|
return;
|
|
}
|
|
|
|
superuser_booking_counts.value = nextBookingCounts;
|
|
superuser_booking_count_loading.value = false;
|
|
didApply = true;
|
|
} finally {
|
|
superUserBookingCountFetchInFlight = false;
|
|
|
|
const shouldRerun = superUserBookingCountRefreshQueued;
|
|
const shouldShowLoadingIndicator = queuedSuperUserBookingLoadingIndicator;
|
|
|
|
superUserBookingCountRefreshQueued = false;
|
|
queuedSuperUserBookingLoadingIndicator = false;
|
|
|
|
if (shouldRerun) {
|
|
void fetchCurrentSuperUserBookingCount({
|
|
showLoadingIndicator: shouldShowLoadingIndicator,
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (!didApply) {
|
|
superuser_booking_count_loading.value = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
const fetchCurrentSuperUserDraftCount = async ({ showLoadingIndicator = false } = {}) => {
|
|
if (!canUseSuperUserNavigationCounts()) {
|
|
resetSuperUserNavigationCounts();
|
|
return;
|
|
}
|
|
|
|
if (draftTransactionCustomerNumber.value === null) {
|
|
superuser_draft_count.value = 0;
|
|
superuser_draft_count_loading.value = false;
|
|
superUserDraftCountFetchInFlight = false;
|
|
superUserDraftCountRefreshQueued = false;
|
|
queuedSuperUserDraftLoadingIndicator = false;
|
|
return;
|
|
}
|
|
|
|
if (superUserDraftCountFetchInFlight) {
|
|
superUserDraftCountRefreshQueued = true;
|
|
queuedSuperUserDraftLoadingIndicator = queuedSuperUserDraftLoadingIndicator || showLoadingIndicator;
|
|
return;
|
|
}
|
|
|
|
if (showLoadingIndicator) {
|
|
superuser_draft_count_loading.value = true;
|
|
superuser_draft_count.value = 0;
|
|
}
|
|
|
|
superUserDraftCountFetchInFlight = true;
|
|
const requestId = ++draftCountRequestId;
|
|
const currentCustomerNumber = draftTransactionCustomerNumber.value;
|
|
let didApply = false;
|
|
|
|
try {
|
|
const nextDraftCount = await fetchSuperUserDraftCount({
|
|
customerNumber: currentCustomerNumber,
|
|
});
|
|
|
|
if (requestId !== draftCountRequestId || currentCustomerNumber !== draftTransactionCustomerNumber.value) {
|
|
return;
|
|
}
|
|
|
|
superuser_draft_count.value = nextDraftCount;
|
|
superuser_draft_count_loading.value = false;
|
|
didApply = true;
|
|
} finally {
|
|
superUserDraftCountFetchInFlight = false;
|
|
|
|
const shouldRerun = superUserDraftCountRefreshQueued;
|
|
const shouldShowLoadingIndicator = queuedSuperUserDraftLoadingIndicator;
|
|
|
|
superUserDraftCountRefreshQueued = false;
|
|
queuedSuperUserDraftLoadingIndicator = false;
|
|
|
|
if (shouldRerun) {
|
|
void fetchCurrentSuperUserDraftCount({
|
|
showLoadingIndicator: shouldShowLoadingIndicator,
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (!didApply) {
|
|
superuser_draft_count_loading.value = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
const refreshSuperUserNavigationCounts = ({
|
|
showBookingLoadingIndicator = false,
|
|
showDraftLoadingIndicator = false,
|
|
} = {}) => {
|
|
if (!canUseSuperUserNavigationCounts()) {
|
|
resetSuperUserNavigationCounts();
|
|
return;
|
|
}
|
|
|
|
void fetchCurrentSuperUserBookingCount({
|
|
showLoadingIndicator: showBookingLoadingIndicator,
|
|
});
|
|
|
|
if (draftTransactionCustomerNumber.value === null) {
|
|
superuser_draft_count.value = 0;
|
|
superuser_draft_count_loading.value = false;
|
|
superUserDraftCountFetchInFlight = false;
|
|
superUserDraftCountRefreshQueued = false;
|
|
queuedSuperUserDraftLoadingIndicator = false;
|
|
return;
|
|
}
|
|
|
|
void fetchCurrentSuperUserDraftCount({
|
|
showLoadingIndicator: showDraftLoadingIndicator,
|
|
});
|
|
};
|
|
|
|
watch(
|
|
draftTransactionCustomerNumber,
|
|
() => {
|
|
refreshSuperUserNavigationCounts({
|
|
showBookingLoadingIndicator: true,
|
|
showDraftLoadingIndicator: true,
|
|
});
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
void ensureDraftTransactionCustomerLoaded();
|
|
|
|
if (typeof window !== "undefined") {
|
|
window.addEventListener(NAVIGATION_COUNT_REFRESH_EVENT, refreshSuperUserNavigationCounts);
|
|
}
|
|
|
|
setInterval(() => {
|
|
if (canUseSuperUserNavigationCounts()) {
|
|
refreshSuperUserNavigationCounts();
|
|
}
|
|
}, 5000);
|
|
|
|
const items = computed<NavigationItemProps[]>(() => [
|
|
// Invoicing
|
|
{
|
|
label: t("superuser.nav.invoicing"),
|
|
type: "category",
|
|
children: [
|
|
{ label: t("common.invoices"), to: "/superuser/invoices" },
|
|
{ label: t("superuser.nav.orders"), to: "/superuser/orders" },
|
|
{
|
|
label: t("nav.bookings"),
|
|
to: "/superuser/bookings",
|
|
badges: getSuperUserBookingsBadges(),
|
|
},
|
|
{
|
|
label: t("nav.drafts"),
|
|
to: "/superuser/orders/drafts",
|
|
hidden: draftTransactionCustomerNumber.value === null,
|
|
badge: getSuperUserDraftsBadge(),
|
|
},
|
|
],
|
|
},
|
|
// Products
|
|
{
|
|
label: t("common.products"),
|
|
type: "category",
|
|
children: [
|
|
{ label: t("common.products"), to: "/superuser/products" },
|
|
{ label: t("superuser.nav.categories"), to: "/superuser/categories" },
|
|
],
|
|
},
|
|
// Users
|
|
{
|
|
label: t("common.users"),
|
|
type: "category",
|
|
children: [
|
|
{ label: t("superuser.nav.employees"), to: "/superuser/users" },
|
|
{ label: "Chauffører", to: "/superuser/subusers" },
|
|
{ label: t("superuser.nav.customers"), to: "/superuser/customers" },
|
|
{ label: t("superuser.nav.complaints"), to: "/superuser/complaints" },
|
|
{ label: t("superuser.nav.roles"), to: "/superuser/roles" },
|
|
],
|
|
},
|
|
// Departments
|
|
{
|
|
label: t("common.departments"),
|
|
type: "category",
|
|
children: [
|
|
{ label: t("common.departments"), to: "/superuser/departments" },
|
|
{ label: t("superuser.nav.department_lanes"), to: "/superuser/department/lanes" },
|
|
{ label: t("superuser.nav.department_gates"), to: "/superuser/department/gates" },
|
|
{ label: t("superuser.nav.department_relays"), to: "/superuser/department/relays" },
|
|
{ label: t("superuser.nav.scanners"), to: "/superuser/scanners" },
|
|
{ label: t("superuser.nav.selfserve"), to: "/superuser/selfserve" },
|
|
{ label: "Self-serve sessions", to: "/superuser/selfserve/sessions" },
|
|
{ label: "Edge Agents", to: "/superuser/selfserve/edge-agents" },
|
|
],
|
|
},
|
|
// Configurations
|
|
{
|
|
label: t("superuser.nav.configuration"),
|
|
type: "category",
|
|
children: [
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.xlvask.meta.labels.multiple),
|
|
to: "/superuser/configuration/xlvask",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.economic.meta.labels.multiple),
|
|
to: "/superuser/configuration/economic",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.reCAPTCHA.meta.labels.multiple),
|
|
to: "/superuser/configuration/recaptcha",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.email.meta.labels.multiple),
|
|
to: "/superuser/configuration/email",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.backups.meta.labels.multiple),
|
|
to: "/superuser/configuration/backup",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.failover.meta.labels.multiple),
|
|
to: "/superuser/configuration/failover",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.coolify.meta.labels.multiple),
|
|
to: "/superuser/configuration/coolify",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.releasemanager.meta.labels.multiple),
|
|
to: "/superuser/configuration/releases",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.motorapi.meta.labels.multiple),
|
|
to: "/superuser/configuration/motorapi",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.stripe.meta.labels.multiple),
|
|
to: "/superuser/configuration/stripe",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.fxratesapi.meta.labels.multiple),
|
|
to: "/superuser/configuration/fxratesapi",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.weatherapi.meta.labels.multiple),
|
|
to: "/superuser/configuration/weatherapi",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.workfeed.meta.labels.multiple),
|
|
to: "/superuser/configuration/workfeed",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.gatewayapi.meta.labels.multiple),
|
|
to: "/superuser/configuration/gatewayapi",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.entra.meta.labels.multiple),
|
|
to: "/superuser/configuration/entra",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.limble.meta.labels.multiple),
|
|
to: "/superuser/configuration/limble",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.ocrspace.meta.labels.multiple),
|
|
to: "/superuser/configuration/ocrspace",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.openai.meta.labels.multiple),
|
|
to: "/superuser/configuration/openai",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.licenseplaterecognizer.meta.labels.multiple),
|
|
to: "/superuser/configuration/licenseplaterecognizer",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.virkdata.meta.labels.multiple),
|
|
to: "/superuser/configuration/virkdata",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.shelly.meta.labels.multiple),
|
|
to: "/superuser/configuration/shelly",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.edgegateway.meta.labels.multiple),
|
|
to: "/superuser/configuration/edgegateway",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.selfserve.meta.labels.multiple),
|
|
to: "/superuser/configuration/selfserve",
|
|
},
|
|
{
|
|
label: firstToUpperCase(SessionUser.superUser.modules.bird.meta.labels.multiple),
|
|
to: "/superuser/configuration/bird",
|
|
},
|
|
],
|
|
},
|
|
// Other
|
|
{
|
|
label: t("superuser.nav.other"),
|
|
type: "category",
|
|
children: [
|
|
//{ label: 'Statistics', to: '/superuser/statistics' },
|
|
{ label: tf("superuser.nav.error_reports", "Error reports"), to: "/superuser/error-reports" },
|
|
{ label: t("common.vehicles"), to: "/superuser/vehicles" },
|
|
],
|
|
},
|
|
]);
|
|
|
|
const parsedItems = () => {
|
|
return items.value;
|
|
};
|
|
|
|
export default defineComponent({
|
|
name: "NavigationMenuItemsSuperUser",
|
|
setup() {
|
|
return {
|
|
items,
|
|
parsedItems,
|
|
};
|
|
},
|
|
});
|
|
|
|
// Named exports if needed
|
|
export { items, parsedItems };
|
|
</script>
|
|
|
|
<template>
|
|
<!-- Add a template section even if empty -->
|
|
</template>
|