Fix invoice period i18n release gate (#245)
Replace unreviewed dynamic invoice-period translation calls with a bounded literal-key contract and focused fallback coverage.
This commit is contained in:
+2
-4
@@ -25,14 +25,12 @@ import {
|
||||
import { buildPossibleDuplicateGroups } from "../../utils/possibleDuplicateGroups.js";
|
||||
import { isUsageOrderAttachedToOrder } from "@/components/displays/department/pos/sync/xlvaskUsageFilters.js";
|
||||
import { SELFWASH_PERIOD_ALL_LIMIT } from "@/components/displays/department/pos/sync/xlvaskUsagePeriodConstants.js";
|
||||
import { translateInvoicingPeriodReview } from "../../services/invoicingPeriodTranslation.js";
|
||||
|
||||
const period_result = ref<any>(null);
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const tr = (key: string, fallback: string) => {
|
||||
const translated = i18n.global.t(`invoicing_period.review_workspace.${key}`);
|
||||
return translated === `invoicing_period.review_workspace.${key}` ? fallback : translated;
|
||||
};
|
||||
const tr = (key: string, fallback: string) => translateInvoicingPeriodReview(i18n.global, key, fallback);
|
||||
const DRAFT_STATUS_REFRESH_INTERVAL_MS = 130_000;
|
||||
let draftStatusRefreshTimer: ReturnType<typeof setInterval> | null = null;
|
||||
let draftStatusRefreshInFlight = false;
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
const REVIEW_WORKSPACE_TRANSLATORS = {
|
||||
"analytics.title": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.analytics.title", params),
|
||||
"detail.next": (composer, params) => composer.t("invoicing_period.review_workspace.detail.next", params),
|
||||
"detail.open_prompt": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.detail.open_prompt", params),
|
||||
"detail.previous": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.detail.previous", params),
|
||||
"detail.selected_customer": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.detail.selected_customer", params),
|
||||
"headline.aria_label": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.headline.aria_label", params),
|
||||
"headline.booked": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.headline.booked", params),
|
||||
"headline.not_booked": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.headline.not_booked", params),
|
||||
"headline.total": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.headline.total", params),
|
||||
"navigation.agreements": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.navigation.agreements", params),
|
||||
"navigation.aria_label": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.navigation.aria_label", params),
|
||||
"navigation.billing": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.navigation.billing", params),
|
||||
"navigation.operations": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.navigation.operations", params),
|
||||
"navigation.review": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.navigation.review", params),
|
||||
"next_actions.create_invoice": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.create_invoice", params),
|
||||
"next_actions.none": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.none", params),
|
||||
"next_actions.resolve_collection_errors": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.resolve_collection_errors", params),
|
||||
"next_actions.resolve_draft": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.resolve_draft", params),
|
||||
"next_actions.resolve_manual_flags": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.resolve_manual_flags", params),
|
||||
"next_actions.review_warnings": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.review_warnings", params),
|
||||
"next_actions.wait_for_export": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.next_actions.wait_for_export", params),
|
||||
"queue.count": (composer, params) => composer.t("invoicing_period.review_workspace.queue.count", params),
|
||||
"queue.title": (composer, params) => composer.t("invoicing_period.review_workspace.queue.title", params),
|
||||
"reasons.automatic_flags": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.automatic_flags", params),
|
||||
"reasons.automatic_warnings": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.automatic_warnings", params),
|
||||
"reasons.collection_errors": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.collection_errors", params),
|
||||
"reasons.completed": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.completed", params),
|
||||
"reasons.draft": (composer, params) => composer.t("invoicing_period.review_workspace.reasons.draft", params),
|
||||
"reasons.draft_blocks_action": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.draft_blocks_action", params),
|
||||
"reasons.export_in_progress": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.export_in_progress", params),
|
||||
"reasons.manual_flags": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.manual_flags", params),
|
||||
"reasons.queued": (composer, params) => composer.t("invoicing_period.review_workspace.reasons.queued", params),
|
||||
"reasons.ready_to_invoice": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.ready_to_invoice", params),
|
||||
"reasons.requires_action": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.requires_action", params),
|
||||
"reasons.unbooked_transactions": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.reasons.unbooked_transactions", params),
|
||||
"severities.blue": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.severities.blue", params),
|
||||
"severities.green": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.severities.green", params),
|
||||
"severities.red": (composer, params) => composer.t("invoicing_period.review_workspace.severities.red", params),
|
||||
"severities.yellow": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.severities.yellow", params),
|
||||
"sort.customer_name": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.sort.customer_name", params),
|
||||
"sort.customer_number": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.sort.customer_number", params),
|
||||
"sort.priority": (composer, params) => composer.t("invoicing_period.review_workspace.sort.priority", params),
|
||||
"sort.total_amount": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.sort.total_amount", params),
|
||||
"states.attention": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.attention", params),
|
||||
"states.blocked": (composer, params) => composer.t("invoicing_period.review_workspace.states.blocked", params),
|
||||
"states.completed": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.completed", params),
|
||||
"states.empty_body": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.empty_body", params),
|
||||
"states.empty_title": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.empty_title", params),
|
||||
"states.error_body": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.error_body", params),
|
||||
"states.error_title": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.error_title", params),
|
||||
"states.filtered_empty_body": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.filtered_empty_body", params),
|
||||
"states.filtered_empty_title": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.filtered_empty_title", params),
|
||||
"states.loading_body": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.loading_body", params),
|
||||
"states.loading_title": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.loading_title", params),
|
||||
"states.queued": (composer, params) => composer.t("invoicing_period.review_workspace.states.queued", params),
|
||||
"states.ready": (composer, params) => composer.t("invoicing_period.review_workspace.states.ready", params),
|
||||
"states.refreshing": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.refreshing", params),
|
||||
"states.retained_error": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.states.retained_error", params),
|
||||
"toolbar.all_departments": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.all_departments", params),
|
||||
"toolbar.all_invoice_states": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.all_invoice_states", params),
|
||||
"toolbar.all_severities": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.all_severities", params),
|
||||
"toolbar.all_states": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.all_states", params),
|
||||
"toolbar.change_direction": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.change_direction", params),
|
||||
"toolbar.clear_filters": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.clear_filters", params),
|
||||
"toolbar.department": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.department", params),
|
||||
"toolbar.invoice_state": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.invoice_state", params),
|
||||
"toolbar.reload": (composer, params) => composer.t("invoicing_period.review_workspace.toolbar.reload", params),
|
||||
"toolbar.retry": (composer, params) => composer.t("invoicing_period.review_workspace.toolbar.retry", params),
|
||||
"toolbar.search": (composer, params) => composer.t("invoicing_period.review_workspace.toolbar.search", params),
|
||||
"toolbar.severity": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.severity", params),
|
||||
"toolbar.sort": (composer, params) => composer.t("invoicing_period.review_workspace.toolbar.sort", params),
|
||||
"toolbar.workflow": (composer, params) =>
|
||||
composer.t("invoicing_period.review_workspace.toolbar.workflow", params),
|
||||
};
|
||||
|
||||
export const translateInvoicingPeriodReview = (composer, key, fallback, params = {}) => {
|
||||
const translate = REVIEW_WORKSPACE_TRANSLATORS[key];
|
||||
if (typeof translate !== "function" || typeof composer?.t !== "function") {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const translated = translate(composer, params);
|
||||
return translated === `invoicing_period.review_workspace.${key}` ? fallback : translated;
|
||||
};
|
||||
+3
-5
@@ -37,13 +37,11 @@ import {
|
||||
getDuplicateTransactionPlate,
|
||||
} from "../utils/possibleDuplicateGroups.js";
|
||||
import { deriveLegacyPeriodCustomerReview } from "../services/invoicingPeriodReview.js";
|
||||
import { translateInvoicingPeriodReview } from "../services/invoicingPeriodTranslation.js";
|
||||
|
||||
const expandedDuplicateGroupKey = ref<string | null>(null);
|
||||
const tr = (key: string, fallback: string, params: Record<string, any> = {}) => {
|
||||
const fullKey = `invoicing_period.review_workspace.${key}`;
|
||||
const translated = i18n.global.t(fullKey, params);
|
||||
return translated === fullKey ? fallback : translated;
|
||||
};
|
||||
const tr = (key: string, fallback: string, params: Record<string, any> = {}) =>
|
||||
translateInvoicingPeriodReview(i18n.global, key, fallback, params);
|
||||
const showAnalytics = ref(false);
|
||||
|
||||
const onClickCustomer = (customer: any) => {
|
||||
|
||||
@@ -3,10 +3,26 @@ import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { buildPeriodCacheKey } from "../../src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/imports/InvoicingBillingPeriodImportPaging.js";
|
||||
import { deriveLegacyPeriodCustomerReview } from "../../src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/services/invoicingPeriodReview.js";
|
||||
import { translateInvoicingPeriodReview } from "../../src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/services/invoicingPeriodTranslation.js";
|
||||
|
||||
const readProjectFile = (path) => readFileSync(fileURLToPath(new URL(`../../${path}`, import.meta.url)), "utf8");
|
||||
|
||||
describe("invoicing period review workspace", () => {
|
||||
it("translates only the bounded review-workspace key contract", () => {
|
||||
const calls = [];
|
||||
const composer = {
|
||||
t(key, params) {
|
||||
calls.push([key, params]);
|
||||
return key === "invoicing_period.review_workspace.queue.count" ? `${params.count} kunder` : key;
|
||||
},
|
||||
};
|
||||
|
||||
expect(translateInvoicingPeriodReview(composer, "queue.count", "fallback", { count: 3 })).toBe("3 kunder");
|
||||
expect(translateInvoicingPeriodReview(composer, "queue.unknown", "fallback")).toBe("fallback");
|
||||
expect(translateInvoicingPeriodReview(composer, "../queue.count", "fallback")).toBe("fallback");
|
||||
expect(calls).toEqual([["invoicing_period.review_workspace.queue.count", { count: 3 }]]);
|
||||
});
|
||||
|
||||
it("scopes cached pages by every server-side review and sorting input", () => {
|
||||
const base = {
|
||||
dateFrom: "2026-08-01",
|
||||
|
||||
Reference in New Issue
Block a user