diff --git a/src/components/AppShell.tsx b/src/components/AppShell.tsx index 2848b8e..dfb8b8b 100644 --- a/src/components/AppShell.tsx +++ b/src/components/AppShell.tsx @@ -30,7 +30,8 @@ import { SunIcon, MoonIcon, } from "@heroicons/react/16/solid"; -import { useLabelStore, useHistory, canCallLabelary } from "../store/labelStore"; +import { useLabelStore, useHistory } from "../store/labelStore"; +import { LabelaryNoticeModal } from "./Output/LabelaryNoticeModal"; import { localeNames } from "../locales"; import type { LocaleCode } from "../locales"; import { mmToUnit } from "../lib/units"; @@ -50,7 +51,9 @@ export function AppShell() { const setLocale = useLabelStore((s) => s.setLocale); const theme = useLabelStore((s) => s.theme); const setTheme = useLabelStore((s) => s.setTheme); - const labelaryReady = useLabelStore(canCallLabelary); + const labelaryEnabled = useLabelStore((s) => s.thirdParty.labelary); + const noticeAcknowledged = useLabelStore((s) => s.labelaryNoticeAcknowledged); + const [showPrintNotice, setShowPrintNotice] = useState(false); // Bridge the theme preference to so the CSS variables in // index.css pick it up. @@ -202,14 +205,13 @@ export function AppShell() { {t.app.saveDesign} - {/* Print also routes through Labelary. Until the user has seen - the privacy notice (shown only via the Preview modal), Print - is hidden so the very first Labelary call cannot bypass the - disclosure. After acknowledgement Print stays available. */} - {labelaryReady && ( + {/* Print routes through Labelary. The button is shown whenever + the Labelary gate is on; clicking it before the notice has + been acknowledged opens the disclosure first, then prints. */} + {labelaryEnabled && ( (noticeAcknowledged ? handlePrint() : setShowPrintNotice(true))} disabled={!hasObjects} > {t.app.print} @@ -344,6 +346,15 @@ export function AppShell() { {showZebraPrint && ( )} + {showPrintNotice && ( + setShowPrintNotice(false)} + onContinue={() => { + setShowPrintNotice(false); + handlePrint(); + }} + /> + )} ); } diff --git a/src/components/Output/LabelPreview.tsx b/src/components/Output/LabelPreview.tsx index 2ecbe29..c7300fc 100644 --- a/src/components/Output/LabelPreview.tsx +++ b/src/components/Output/LabelPreview.tsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from 'react'; import { XMarkIcon, ArrowDownTrayIcon } from '@heroicons/react/16/solid'; -import { useLabelStore, useCurrentObjects, canCallLabelary } from '../../store/labelStore'; +import { useLabelStore, useCurrentObjects } from '../../store/labelStore'; import { generateZPL } from '../../lib/zplGenerator'; import { fetchPreview, labelaryErrorMessage } from '../../lib/labelary'; import { triggerDownload } from '../../lib/triggerDownload'; @@ -10,28 +10,22 @@ interface Props { onClose: () => void; } - +/** Preview modal — assumes the privacy notice has already been + * acknowledged. Callers (ZPLOutput) gate the modal behind + * LabelaryNoticeModal so this component never has to handle the + * pre-ack state. */ export function LabelPreviewModal({ onClose }: Props) { const t = useT(); const label = useLabelStore((s) => s.label); const objects = useCurrentObjects(); - const noticeAcknowledged = useLabelStore((s) => s.labelaryNoticeAcknowledged); - const acknowledgeLabelaryNotice = useLabelStore((s) => s.acknowledgeLabelaryNotice); - // Same gate as every other Labelary consumer (Print, …) — single source - // of truth in the store. The modal opens only when the gate is on, so in - // practice this resolves to noticeAcknowledged here, but we route through - // the shared selector to stay in lockstep with future call sites. - const canFetch = useLabelStore(canCallLabelary); const [previewUrl, setPreviewUrl] = useState(null); const [error, setError] = useState(null); const urlRef = useRef(null); const zplRef = useRef(generateZPL(label, objects)); - // Derived: fetch is in flight while we have neither result nor error yet. - const loading = canFetch && !previewUrl && !error; + const loading = !previewUrl && !error; useEffect(() => { - if (!canFetch) return; let cancelled = false; fetchPreview(zplRef.current, label) .then((url) => { @@ -50,7 +44,7 @@ export function LabelPreviewModal({ onClose }: Props) { // `label` and the generated ZPL are intentionally captured once at mount // (via zplRef): the preview should reflect the snapshot the user saw when // they opened the modal, not refetch when the canvas changes underneath. - }, [canFetch]); // eslint-disable-line react-hooks/exhaustive-deps + }, []); // eslint-disable-line react-hooks/exhaustive-deps const handleDownloadFallback = () => { triggerDownload(new Blob([zplRef.current], { type: 'text/plain' }), 'label.zpl'); @@ -60,17 +54,21 @@ export function LabelPreviewModal({ onClose }: Props) {
e.stopPropagation()} >
- + {t.output.previewHeading} -
- )} - {canFetch && loading && ( + {loading && ( {t.output.loading} )} - {canFetch && !loading && error && ( + {!loading && error && (
{error}
)} - {canFetch && !loading && !error && previewUrl && ( + {!loading && !error && previewUrl && ( Label preview void; + onClose: () => void; +} + +/** Privacy notice shown the first time the user invokes a Labelary-backed + * feature (Preview, Print). After acknowledgement the gate + * (`canCallLabelary`) opens permanently and this modal is no longer + * rendered. Shared between Preview and Print so the disclosure wording + * stays in lockstep. */ +export function LabelaryNoticeModal({ onContinue, onClose }: Props) { + const t = useT(); + const acknowledgeLabelaryNotice = useLabelStore((s) => s.acknowledgeLabelaryNotice); + + const handleContinue = () => { + acknowledgeLabelaryNotice(); + onContinue(); + }; + + return ( +
+
e.stopPropagation()} + > +
+ + {t.output.previewNoticeTitle} + + +
+ +
+ {t.output.previewNoticeBody} + + {t.output.previewNoticePrivacyLink} + + +
+
+
+ ); +} diff --git a/src/components/Output/ZPLOutput.tsx b/src/components/Output/ZPLOutput.tsx index 381608b..96df205 100644 --- a/src/components/Output/ZPLOutput.tsx +++ b/src/components/Output/ZPLOutput.tsx @@ -4,6 +4,7 @@ import { useLabelStore } from '../../store/labelStore'; import { generateMultiPageZPL } from '../../lib/zplGenerator'; import { useT } from '../../lib/useT'; import { LabelPreviewModal } from './LabelPreview'; +import { LabelaryNoticeModal } from './LabelaryNoticeModal'; interface Props { collapsed?: boolean; @@ -15,12 +16,11 @@ export function ZPLOutput({ collapsed, onCollapse, onExpand }: Props) { const t = useT(); const label = useLabelStore((s) => s.label); const pages = useLabelStore((s) => s.pages); - // Direct gate check — Preview is the path to the privacy notice, so the - // button must be reachable before acknowledgement. Other Labelary callers - // (AppShell.Print, LabelPreview.fetch) use the stricter canCallLabelary. const labelaryEnabled = useLabelStore((s) => s.thirdParty.labelary); + const noticeAcknowledged = useLabelStore((s) => s.labelaryNoticeAcknowledged); const [copied, setCopied] = useState(false); const [showPreview, setShowPreview] = useState(false); + const [showNotice, setShowNotice] = useState(false); const hasObjects = pages.some((p) => p.objects.length > 0); const zpl = hasObjects ? generateMultiPageZPL(label, pages) : ''; @@ -49,7 +49,7 @@ export function ZPLOutput({ collapsed, onCollapse, onExpand }: Props) {
{labelaryEnabled && (
); diff --git a/src/locales/ar.ts b/src/locales/ar.ts index 866de5f..f153b91 100644 --- a/src/locales/ar.ts +++ b/src/locales/ar.ts @@ -97,6 +97,7 @@ const ar = { newDesign: 'تصميم جديد', addPage: 'إضافة صفحة', cancel: 'إلغاء', + close: 'إغلاق', deletePage: 'حذف الصفحة', deletePageConfirm: 'حذف الصفحة الحالية؟', openDesign: 'فتح تصميم', @@ -122,7 +123,7 @@ const ar = { previewEmpty: 'تظهر المعاينة\nبعد إجراء تغييرات', previewProvider: 'معاينة عبر api.labelary.com', previewNoticeTitle: 'إشعار الخصوصية', - previewNoticeBody: 'يتم إنشاء المعاينة بواسطة الخدمة الخارجية api.labelary.com. يتم إرسال ZPL الكامل للملصق، بما في ذلك أي بيانات حساسة، عبر الشبكة.', + previewNoticeBody: 'يتم إنشاء المعاينة والطباعة بواسطة الخدمة الخارجية api.labelary.com. يتم إرسال ZPL الكامل للملصق، بما في ذلك أي بيانات حساسة، عبر الشبكة.', previewNoticePrivacyLink: 'معلومات خصوصية Labelary', previewNoticeAcknowledge: 'فهمت، تابع', }, diff --git a/src/locales/bg.ts b/src/locales/bg.ts index 3e00ea7..f6ce769 100644 --- a/src/locales/bg.ts +++ b/src/locales/bg.ts @@ -97,6 +97,7 @@ const bg = { newDesign: 'Нов дизайн', addPage: 'Добавяне на страница', cancel: 'Отказ', + close: 'Затваряне', deletePage: 'Изтриване на страница', deletePageConfirm: 'Изтриване на текущата страница?', openDesign: 'Отвори дизайн', @@ -122,7 +123,7 @@ const bg = { previewEmpty: 'Преглед се появява\nслед промени', previewProvider: 'Преглед чрез api.labelary.com', previewNoticeTitle: 'Известие за поверителност', - previewNoticeBody: 'Прегледът се изобразява от външната услуга api.labelary.com. Целият ZPL на етикета, включително чувствителните данни, се изпраща през мрежата.', + previewNoticeBody: 'Прегледът и отпечатването се изобразяват от външната услуга api.labelary.com. Целият ZPL на етикета, включително чувствителните данни, се изпраща през мрежата.', previewNoticePrivacyLink: 'Информация за поверителност на Labelary', previewNoticeAcknowledge: 'Разбрах, продължи', }, diff --git a/src/locales/cs.ts b/src/locales/cs.ts index 22fc2dd..6b35536 100644 --- a/src/locales/cs.ts +++ b/src/locales/cs.ts @@ -97,6 +97,7 @@ const cs = { newDesign: 'Nový návrh', addPage: 'Přidat stránku', cancel: 'Zrušit', + close: 'Zavřít', deletePage: 'Smazat stránku', deletePageConfirm: 'Smazat aktuální stránku?', openDesign: 'Otevřít návrh', @@ -122,7 +123,7 @@ const cs = { previewEmpty: 'Náhled se zobrazí\npo úpravách', previewProvider: 'Náhled přes api.labelary.com', previewNoticeTitle: 'Upozornění na ochranu údajů', - previewNoticeBody: 'Náhled se generuje pomocí externí služby api.labelary.com. Celý ZPL štítku, včetně citlivých údajů, je odesílán přes síť.', + previewNoticeBody: 'Náhled a tisk se generují pomocí externí služby api.labelary.com. Celý ZPL štítku, včetně citlivých údajů, je odesílán přes síť.', previewNoticePrivacyLink: 'Informace o ochraně údajů Labelary', previewNoticeAcknowledge: 'Rozumím, pokračovat', }, diff --git a/src/locales/da.ts b/src/locales/da.ts index 3e62111..db476ea 100644 --- a/src/locales/da.ts +++ b/src/locales/da.ts @@ -97,6 +97,7 @@ const da = { newDesign: 'Nyt design', addPage: 'Tilføj side', cancel: 'Annuller', + close: 'Luk', deletePage: 'Slet side', deletePageConfirm: 'Slet den aktuelle side?', openDesign: 'Åbn design', @@ -122,7 +123,7 @@ const da = { previewEmpty: 'Forhåndsvisning vises\nefter ændringer', previewProvider: 'Forhåndsvisning via api.labelary.com', previewNoticeTitle: 'Privatlivsmeddelelse', - previewNoticeBody: 'Forhåndsvisningen genereres af den eksterne tjeneste api.labelary.com. Hele etikettens ZPL, inklusive følsomme data, sendes over netværket.', + previewNoticeBody: 'Forhåndsvisning og udskrivning genereres af den eksterne tjeneste api.labelary.com. Hele etikettens ZPL, inklusive følsomme data, sendes over netværket.', previewNoticePrivacyLink: 'Labelary-privatlivsoplysninger', previewNoticeAcknowledge: 'Forstået, fortsæt', }, diff --git a/src/locales/de.ts b/src/locales/de.ts index e9ea97b..384a40d 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -97,6 +97,7 @@ const de = { newDesign: 'Neues Design', addPage: 'Seite hinzufügen', cancel: 'Abbrechen', + close: 'Schließen', deletePage: 'Seite löschen', deletePageConfirm: 'Aktuelle Seite löschen?', openDesign: 'Design öffnen', @@ -142,7 +143,7 @@ const de = { previewEmpty: 'Vorschau erscheint\nnach Änderungen', previewProvider: 'Vorschau über api.labelary.com', previewNoticeTitle: 'Datenschutzhinweis', - previewNoticeBody: 'Die Vorschau wird vom externen Dienst api.labelary.com erstellt. Dabei wird das vollständige Label-ZPL inklusive sensibler Daten übertragen.', + previewNoticeBody: 'Vorschau und Druck werden vom externen Dienst api.labelary.com erstellt. Dabei wird das vollständige Label-ZPL inklusive sensibler Daten übertragen.', previewNoticePrivacyLink: 'Labelary-Datenschutzhinweise', previewNoticeAcknowledge: 'Verstanden, fortfahren', }, diff --git a/src/locales/el.ts b/src/locales/el.ts index 3314283..fa97960 100644 --- a/src/locales/el.ts +++ b/src/locales/el.ts @@ -97,6 +97,7 @@ const el = { newDesign: 'Νέο σχέδιο', addPage: 'Προσθήκη σελίδας', cancel: 'Ακύρωση', + close: 'Κλείσιμο', deletePage: 'Διαγραφή σελίδας', deletePageConfirm: 'Διαγραφή της τρέχουσας σελίδας;', openDesign: 'Άνοιγμα σχεδίου', @@ -122,7 +123,7 @@ const el = { previewEmpty: 'Η προεπισκόπηση εμφανίζεται\nμετά τις αλλαγές', previewProvider: 'Προεπισκόπηση μέσω api.labelary.com', previewNoticeTitle: 'Ειδοποίηση απορρήτου', - previewNoticeBody: 'Η προεπισκόπηση δημιουργείται από την εξωτερική υπηρεσία api.labelary.com. Ολόκληρο το ZPL της ετικέτας, συμπεριλαμβανομένων ευαίσθητων δεδομένων, αποστέλλεται μέσω δικτύου.', + previewNoticeBody: 'Η προεπισκόπηση και η εκτύπωση δημιουργούνται από την εξωτερική υπηρεσία api.labelary.com. Ολόκληρο το ZPL της ετικέτας, συμπεριλαμβανομένων ευαίσθητων δεδομένων, αποστέλλεται μέσω δικτύου.', previewNoticePrivacyLink: 'Πληροφορίες απορρήτου Labelary', previewNoticeAcknowledge: 'Κατάλαβα, συνέχεια', }, diff --git a/src/locales/en.ts b/src/locales/en.ts index 99685ee..e671b5a 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -97,6 +97,7 @@ const en = { newDesign: 'New design', addPage: 'Add page', cancel: 'Cancel', + close: 'Close', deletePage: 'Delete page', deletePageConfirm: 'Delete the current page?', openDesign: 'Open design', @@ -142,7 +143,7 @@ const en = { previewEmpty: 'Preview appears\nafter changes', previewProvider: 'Preview via api.labelary.com', previewNoticeTitle: 'Privacy notice', - previewNoticeBody: 'Preview rendering is performed by the external service api.labelary.com. The full label ZPL, including any sensitive data, is sent over the network.', + previewNoticeBody: 'Preview and print rendering is performed by the external service api.labelary.com. The full label ZPL, including any sensitive data, is sent over the network.', previewNoticePrivacyLink: 'Labelary privacy information', previewNoticeAcknowledge: 'Got it, continue', }, diff --git a/src/locales/es.ts b/src/locales/es.ts index e8e6659..76cfe60 100644 --- a/src/locales/es.ts +++ b/src/locales/es.ts @@ -97,6 +97,7 @@ const es = { newDesign: 'Nuevo diseño', addPage: 'Añadir página', cancel: 'Cancelar', + close: 'Cerrar', deletePage: 'Eliminar página', deletePageConfirm: '¿Eliminar la página actual?', openDesign: 'Abrir diseño', @@ -122,7 +123,7 @@ const es = { previewEmpty: 'La vista previa aparece\ntras los cambios', previewProvider: 'Vista previa vía api.labelary.com', previewNoticeTitle: 'Aviso de privacidad', - previewNoticeBody: 'La previsualización se genera mediante el servicio externo api.labelary.com. Se envía el ZPL completo de la etiqueta, incluidos los datos sensibles.', + previewNoticeBody: 'La previsualización y la impresión se generan mediante el servicio externo api.labelary.com. Se envía el ZPL completo de la etiqueta, incluidos los datos sensibles.', previewNoticePrivacyLink: 'Información de privacidad de Labelary', previewNoticeAcknowledge: 'Entendido, continuar', }, diff --git a/src/locales/et.ts b/src/locales/et.ts index 10b7ddf..c8eef9a 100644 --- a/src/locales/et.ts +++ b/src/locales/et.ts @@ -97,6 +97,7 @@ const et = { newDesign: 'Uus kujundus', addPage: 'Lisa leht', cancel: 'Loobu', + close: 'Sulge', deletePage: 'Kustuta leht', deletePageConfirm: 'Kustuta praegune leht?', openDesign: 'Ava kujundus', @@ -122,7 +123,7 @@ const et = { previewEmpty: 'Eelvaade kuvatakse\npärast muudatusi', previewProvider: 'Eelvaade api.labelary.com kaudu', previewNoticeTitle: 'Privaatsusteatis', - previewNoticeBody: 'Eelvaate genereerib väline teenus api.labelary.com. Sildi terve ZPL, sealhulgas tundlikud andmed, saadetakse võrgu kaudu.', + previewNoticeBody: 'Eelvaate ja printimise genereerib väline teenus api.labelary.com. Sildi terve ZPL, sealhulgas tundlikud andmed, saadetakse võrgu kaudu.', previewNoticePrivacyLink: 'Labelary privaatsusteave', previewNoticeAcknowledge: 'Selge, jätka', }, diff --git a/src/locales/fa.ts b/src/locales/fa.ts index bfd2d57..c53db8f 100644 --- a/src/locales/fa.ts +++ b/src/locales/fa.ts @@ -97,6 +97,7 @@ const fa = { newDesign: 'طرح جدید', addPage: 'افزودن صفحه', cancel: 'لغو', + close: 'بستن', deletePage: 'حذف صفحه', deletePageConfirm: 'صفحه فعلی حذف شود؟', openDesign: 'باز کردن طرح', @@ -122,7 +123,7 @@ const fa = { previewEmpty: 'پیش‌نمایش پس از\nتغییرات نمایش داده می‌شود', previewProvider: 'پیش‌نمایش از طریق api.labelary.com', previewNoticeTitle: 'اطلاعیه حریم خصوصی', - previewNoticeBody: 'پیش‌نمایش توسط سرویس خارجی api.labelary.com تولید می‌شود. ZPL کامل برچسب، شامل داده‌های حساس، از طریق شبکه ارسال می‌شود.', + previewNoticeBody: 'پیش‌نمایش و چاپ توسط سرویس خارجی api.labelary.com تولید می‌شود. ZPL کامل برچسب، شامل داده‌های حساس، از طریق شبکه ارسال می‌شود.', previewNoticePrivacyLink: 'اطلاعات حریم خصوصی Labelary', previewNoticeAcknowledge: 'متوجه شدم، ادامه', }, diff --git a/src/locales/fi.ts b/src/locales/fi.ts index 591448b..6091e60 100644 --- a/src/locales/fi.ts +++ b/src/locales/fi.ts @@ -97,6 +97,7 @@ const fi = { newDesign: 'Uusi rakenne', addPage: 'Lisää sivu', cancel: 'Peruuta', + close: 'Sulje', deletePage: 'Poista sivu', deletePageConfirm: 'Poistetaanko nykyinen sivu?', openDesign: 'Avaa rakenne', @@ -122,7 +123,7 @@ const fi = { previewEmpty: 'Esikatselu näkyy\nmuutosten jälkeen', previewProvider: 'Esikatselu palvelusta api.labelary.com', previewNoticeTitle: 'Tietosuojailmoitus', - previewNoticeBody: 'Esikatselun tuottaa ulkoinen palvelu api.labelary.com. Etiketin koko ZPL, mukaan lukien arkaluonteiset tiedot, lähetetään verkon yli.', + previewNoticeBody: 'Esikatselun ja tulostuksen tuottaa ulkoinen palvelu api.labelary.com. Etiketin koko ZPL, mukaan lukien arkaluonteiset tiedot, lähetetään verkon yli.', previewNoticePrivacyLink: 'Labelary-tietosuojatiedot', previewNoticeAcknowledge: 'Selvä, jatka', }, diff --git a/src/locales/fr.ts b/src/locales/fr.ts index 9a3d884..ae2a9ee 100644 --- a/src/locales/fr.ts +++ b/src/locales/fr.ts @@ -97,6 +97,7 @@ const fr = { newDesign: 'Nouveau design', addPage: 'Ajouter une page', cancel: 'Annuler', + close: 'Fermer', deletePage: 'Supprimer la page', deletePageConfirm: 'Supprimer la page actuelle ?', openDesign: 'Ouvrir le design', @@ -122,7 +123,7 @@ const fr = { previewEmpty: "L'aperçu apparaît\naprès les modifications", previewProvider: 'Aperçu via api.labelary.com', previewNoticeTitle: 'Avis de confidentialité', - previewNoticeBody: 'Le rendu de l\'aperçu est effectué par le service externe api.labelary.com. Le ZPL complet de l\'étiquette, y compris toute donnée sensible, est envoyé sur le réseau.', + previewNoticeBody: "Le rendu de l'aperçu et de l'impression est effectué par le service externe api.labelary.com. Le ZPL complet de l'étiquette, y compris toute donnée sensible, est envoyé sur le réseau.", previewNoticePrivacyLink: 'Informations sur la confidentialité de Labelary', previewNoticeAcknowledge: 'Compris, continuer', }, diff --git a/src/locales/he.ts b/src/locales/he.ts index b81a469..f981342 100644 --- a/src/locales/he.ts +++ b/src/locales/he.ts @@ -97,6 +97,7 @@ const he = { newDesign: 'עיצוב חדש', addPage: 'הוסף דף', cancel: 'ביטול', + close: 'סגור', deletePage: 'מחק דף', deletePageConfirm: 'למחוק את הדף הנוכחי?', openDesign: 'פתח עיצוב', @@ -122,7 +123,7 @@ const he = { previewEmpty: 'התצוגה המקדימה מופיעה\nלאחר שינויים', previewProvider: 'תצוגה מקדימה דרך api.labelary.com', previewNoticeTitle: 'הודעת פרטיות', - previewNoticeBody: 'התצוגה המקדימה מופקת על ידי השירות החיצוני api.labelary.com. ה-ZPL המלא של התווית, כולל נתונים רגישים, נשלח ברשת.', + previewNoticeBody: 'התצוגה המקדימה וההדפסה מופקות על ידי השירות החיצוני api.labelary.com. ה-ZPL המלא של התווית, כולל נתונים רגישים, נשלח ברשת.', previewNoticePrivacyLink: 'מידע פרטיות של Labelary', previewNoticeAcknowledge: 'הבנתי, המשך', }, diff --git a/src/locales/hr.ts b/src/locales/hr.ts index b743134..58455f4 100644 --- a/src/locales/hr.ts +++ b/src/locales/hr.ts @@ -97,6 +97,7 @@ const hr = { newDesign: 'Novi dizajn', addPage: 'Dodaj stranicu', cancel: 'Odustani', + close: 'Zatvori', deletePage: 'Izbriši stranicu', deletePageConfirm: 'Izbrisati trenutnu stranicu?', openDesign: 'Otvori dizajn', @@ -122,7 +123,7 @@ const hr = { previewEmpty: 'Pregled se prikazuje\nnakon promjena', previewProvider: 'Pregled putem api.labelary.com', previewNoticeTitle: 'Obavijest o privatnosti', - previewNoticeBody: 'Pregled generira vanjska usluga api.labelary.com. Cijeli ZPL naljepnice, uključujući osjetljive podatke, šalje se putem mreže.', + previewNoticeBody: 'Pregled i ispis generira vanjska usluga api.labelary.com. Cijeli ZPL naljepnice, uključujući osjetljive podatke, šalje se putem mreže.', previewNoticePrivacyLink: 'Informacije o privatnosti Labelary', previewNoticeAcknowledge: 'Razumijem, nastavi', }, diff --git a/src/locales/hu.ts b/src/locales/hu.ts index 83258c7..5ee4a23 100644 --- a/src/locales/hu.ts +++ b/src/locales/hu.ts @@ -97,6 +97,7 @@ const hu = { newDesign: 'Új terv', addPage: 'Oldal hozzáadása', cancel: 'Mégse', + close: 'Bezárás', deletePage: 'Oldal törlése', deletePageConfirm: 'Törli az aktuális oldalt?', openDesign: 'Terv megnyitása', @@ -122,7 +123,7 @@ const hu = { previewEmpty: 'Az előnézet megjelenik\nmódosítás után', previewProvider: 'Előnézet az api.labelary.com útján', previewNoticeTitle: 'Adatvédelmi tájékoztató', - previewNoticeBody: 'Az előnézetet a külső api.labelary.com szolgáltatás készíti. A címke teljes ZPL-je, beleértve a bizalmas adatokat is, hálózaton keresztül kerül elküldésre.', + previewNoticeBody: 'Az előnézetet és a nyomtatást a külső api.labelary.com szolgáltatás készíti. A címke teljes ZPL-je, beleértve a bizalmas adatokat is, hálózaton keresztül kerül elküldésre.', previewNoticePrivacyLink: 'Labelary adatvédelmi tájékoztató', previewNoticeAcknowledge: 'Értem, folytatás', }, diff --git a/src/locales/it.ts b/src/locales/it.ts index 0f8c278..73d3f84 100644 --- a/src/locales/it.ts +++ b/src/locales/it.ts @@ -97,6 +97,7 @@ const it = { newDesign: 'Nuovo design', addPage: 'Aggiungi pagina', cancel: 'Annulla', + close: 'Chiudi', deletePage: 'Elimina pagina', deletePageConfirm: 'Eliminare la pagina corrente?', openDesign: 'Apri design', @@ -122,7 +123,7 @@ const it = { previewEmpty: "L'anteprima appare\ndopo le modifiche", previewProvider: 'Anteprima tramite api.labelary.com', previewNoticeTitle: 'Informativa sulla privacy', - previewNoticeBody: 'L\'anteprima è generata dal servizio esterno api.labelary.com. L\'intero ZPL dell\'etichetta, inclusi eventuali dati sensibili, viene trasmesso in rete.', + previewNoticeBody: "L'anteprima e la stampa sono generate dal servizio esterno api.labelary.com. L'intero ZPL dell'etichetta, inclusi eventuali dati sensibili, viene trasmesso in rete.", previewNoticePrivacyLink: 'Informativa sulla privacy di Labelary', previewNoticeAcknowledge: 'Ho capito, continua', }, diff --git a/src/locales/ja.ts b/src/locales/ja.ts index b736ba7..8efbdd9 100644 --- a/src/locales/ja.ts +++ b/src/locales/ja.ts @@ -97,6 +97,7 @@ const ja = { newDesign: '新しいデザイン', addPage: 'ページを追加', cancel: 'キャンセル', + close: '閉じる', deletePage: 'ページを削除', deletePageConfirm: '現在のページを削除しますか?', openDesign: 'デザインを開く', @@ -122,7 +123,7 @@ const ja = { previewEmpty: '変更後にプレビューが\n表示されます', previewProvider: 'api.labelary.com 経由のプレビュー', previewNoticeTitle: 'プライバシーに関する通知', - previewNoticeBody: 'プレビューは外部サービス api.labelary.com で生成されます。機密データを含むラベル全体の ZPL がネットワーク経由で送信されます。', + previewNoticeBody: 'プレビューと印刷は外部サービス api.labelary.com で生成されます。機密データを含むラベル全体の ZPL がネットワーク経由で送信されます。', previewNoticePrivacyLink: 'Labelary のプライバシー情報', previewNoticeAcknowledge: '了解しました、続行', }, diff --git a/src/locales/ko.ts b/src/locales/ko.ts index dab88f3..7c41997 100644 --- a/src/locales/ko.ts +++ b/src/locales/ko.ts @@ -97,6 +97,7 @@ const ko = { newDesign: '새 디자인', addPage: '페이지 추가', cancel: '취소', + close: '닫기', deletePage: '페이지 삭제', deletePageConfirm: '현재 페이지를 삭제하시겠습니까?', openDesign: '디자인 열기', @@ -122,7 +123,7 @@ const ko = { previewEmpty: '변경 후 미리보기가\n표시됩니다', previewProvider: 'api.labelary.com을(를) 통한 미리 보기', previewNoticeTitle: '개인정보 보호 고지', - previewNoticeBody: '미리 보기는 외부 서비스 api.labelary.com에서 생성됩니다. 민감한 데이터를 포함한 전체 라벨 ZPL이 네트워크를 통해 전송됩니다.', + previewNoticeBody: '미리 보기와 인쇄는 외부 서비스 api.labelary.com에서 생성됩니다. 민감한 데이터를 포함한 전체 라벨 ZPL이 네트워크를 통해 전송됩니다.', previewNoticePrivacyLink: 'Labelary 개인정보 보호 정보', previewNoticeAcknowledge: '이해했습니다, 계속', }, diff --git a/src/locales/lt.ts b/src/locales/lt.ts index 6e51ac7..5abd6b3 100644 --- a/src/locales/lt.ts +++ b/src/locales/lt.ts @@ -97,6 +97,7 @@ const lt = { newDesign: 'Naujas dizainas', addPage: 'Pridėti puslapį', cancel: 'Atšaukti', + close: 'Uždaryti', deletePage: 'Ištrinti puslapį', deletePageConfirm: 'Ištrinti dabartinį puslapį?', openDesign: 'Atidaryti dizainą', @@ -122,7 +123,7 @@ const lt = { previewEmpty: 'Peržiūra rodoma\npo pakeitimų', previewProvider: 'Peržiūra per api.labelary.com', previewNoticeTitle: 'Privatumo pranešimas', - previewNoticeBody: 'Peržiūrą generuoja išorinė paslauga api.labelary.com. Visa etiketės ZPL, įskaitant jautrius duomenis, siunčiama tinklu.', + previewNoticeBody: 'Peržiūrą ir spausdinimą generuoja išorinė paslauga api.labelary.com. Visa etiketės ZPL, įskaitant jautrius duomenis, siunčiama tinklu.', previewNoticePrivacyLink: 'Labelary privatumo informacija', previewNoticeAcknowledge: 'Supratau, tęsti', }, diff --git a/src/locales/lv.ts b/src/locales/lv.ts index 59bd7d2..3c44611 100644 --- a/src/locales/lv.ts +++ b/src/locales/lv.ts @@ -97,6 +97,7 @@ const lv = { newDesign: 'Jauns dizains', addPage: 'Pievienot lapu', cancel: 'Atcelt', + close: 'Aizvērt', deletePage: 'Dzēst lapu', deletePageConfirm: 'Dzēst pašreizējo lapu?', openDesign: 'Atvērt dizainu', @@ -122,7 +123,7 @@ const lv = { previewEmpty: 'Priekšskatījums parādās\npēc izmaiņām', previewProvider: 'Priekšskatījums caur api.labelary.com', previewNoticeTitle: 'Paziņojums par privātumu', - previewNoticeBody: 'Priekšskatījumu ģenerē ārējais pakalpojums api.labelary.com. Visa etiķetes ZPL, tostarp sensitīvi dati, tiek sūtīta tīklā.', + previewNoticeBody: 'Priekšskatījumu un drukāšanu ģenerē ārējais pakalpojums api.labelary.com. Visa etiķetes ZPL, tostarp sensitīvi dati, tiek sūtīta tīklā.', previewNoticePrivacyLink: 'Labelary privātuma informācija', previewNoticeAcknowledge: 'Saprotu, turpināt', }, diff --git a/src/locales/nl.ts b/src/locales/nl.ts index f30bd17..1caf659 100644 --- a/src/locales/nl.ts +++ b/src/locales/nl.ts @@ -97,6 +97,7 @@ const nl = { newDesign: 'Nieuw ontwerp', addPage: 'Pagina toevoegen', cancel: 'Annuleren', + close: 'Sluiten', deletePage: 'Pagina verwijderen', deletePageConfirm: 'Huidige pagina verwijderen?', openDesign: 'Ontwerp openen', @@ -122,7 +123,7 @@ const nl = { previewEmpty: 'Voorbeeld verschijnt\nna wijzigingen', previewProvider: 'Voorbeeld via api.labelary.com', previewNoticeTitle: 'Privacymelding', - previewNoticeBody: 'De voorbeeldweergave wordt gegenereerd door de externe dienst api.labelary.com. De volledige ZPL van het label, inclusief gevoelige gegevens, wordt verzonden.', + previewNoticeBody: 'De voorbeeldweergave en het afdrukken worden gegenereerd door de externe dienst api.labelary.com. De volledige ZPL van het label, inclusief gevoelige gegevens, wordt verzonden.', previewNoticePrivacyLink: 'Privacy-informatie van Labelary', previewNoticeAcknowledge: 'Begrepen, doorgaan', }, diff --git a/src/locales/no.ts b/src/locales/no.ts index b7d930f..ffbd1d3 100644 --- a/src/locales/no.ts +++ b/src/locales/no.ts @@ -97,6 +97,7 @@ const no = { newDesign: 'Nytt design', addPage: 'Legg til side', cancel: 'Avbryt', + close: 'Lukk', deletePage: 'Slett side', deletePageConfirm: 'Slette gjeldende side?', openDesign: 'Åpne design', @@ -122,7 +123,7 @@ const no = { previewEmpty: 'Forhåndsvisning vises\netter endringer', previewProvider: 'Forhåndsvisning via api.labelary.com', previewNoticeTitle: 'Personvernmelding', - previewNoticeBody: 'Forhåndsvisningen genereres av den eksterne tjenesten api.labelary.com. Hele etikettens ZPL, inkludert sensitive data, sendes over nettverket.', + previewNoticeBody: 'Forhåndsvisning og utskrift genereres av den eksterne tjenesten api.labelary.com. Hele etikettens ZPL, inkludert sensitive data, sendes over nettverket.', previewNoticePrivacyLink: 'Labelary personverninformasjon', previewNoticeAcknowledge: 'Forstått, fortsett', }, diff --git a/src/locales/pl.ts b/src/locales/pl.ts index d80bbd8..c6208d8 100644 --- a/src/locales/pl.ts +++ b/src/locales/pl.ts @@ -97,6 +97,7 @@ const pl = { newDesign: 'Nowy projekt', addPage: 'Dodaj stronę', cancel: 'Anuluj', + close: 'Zamknij', deletePage: 'Usuń stronę', deletePageConfirm: 'Usunąć bieżącą stronę?', openDesign: 'Otwórz projekt', @@ -122,7 +123,7 @@ const pl = { previewEmpty: 'Podgląd pojawi się\npo zmianach', previewProvider: 'Podgląd przez api.labelary.com', previewNoticeTitle: 'Informacja o prywatności', - previewNoticeBody: 'Podgląd jest renderowany przez zewnętrzny serwis api.labelary.com. Cały ZPL etykiety, włącznie z danymi wrażliwymi, jest wysyłany przez sieć.', + previewNoticeBody: 'Podgląd i drukowanie są renderowane przez zewnętrzny serwis api.labelary.com. Cały ZPL etykiety, włącznie z danymi wrażliwymi, jest wysyłany przez sieć.', previewNoticePrivacyLink: 'Informacje o prywatności Labelary', previewNoticeAcknowledge: 'Rozumiem, kontynuuj', }, diff --git a/src/locales/pt.ts b/src/locales/pt.ts index 3eac66f..e668ac9 100644 --- a/src/locales/pt.ts +++ b/src/locales/pt.ts @@ -97,6 +97,7 @@ const pt = { newDesign: 'Novo design', addPage: 'Adicionar página', cancel: 'Cancelar', + close: 'Fechar', deletePage: 'Eliminar página', deletePageConfirm: 'Eliminar a página atual?', openDesign: 'Abrir design', @@ -122,7 +123,7 @@ const pt = { previewEmpty: 'A pré-visualização aparece\napós alterações', previewProvider: 'Pré-visualização via api.labelary.com', previewNoticeTitle: 'Aviso de privacidade', - previewNoticeBody: 'A pré-visualização é gerada pelo serviço externo api.labelary.com. O ZPL completo da etiqueta, incluindo dados sensíveis, é enviado pela rede.', + previewNoticeBody: 'A pré-visualização e a impressão são geradas pelo serviço externo api.labelary.com. O ZPL completo da etiqueta, incluindo dados sensíveis, é enviado pela rede.', previewNoticePrivacyLink: 'Informações de privacidade da Labelary', previewNoticeAcknowledge: 'Entendi, continuar', }, diff --git a/src/locales/ro.ts b/src/locales/ro.ts index 2ece619..ccc8498 100644 --- a/src/locales/ro.ts +++ b/src/locales/ro.ts @@ -97,6 +97,7 @@ const ro = { newDesign: 'Design nou', addPage: 'Adaugă pagină', cancel: 'Anulează', + close: 'Închide', deletePage: 'Șterge pagina', deletePageConfirm: 'Ștergeți pagina curentă?', openDesign: 'Deschide design', @@ -122,7 +123,7 @@ const ro = { previewEmpty: 'Previzualizarea apare\ndupă modificări', previewProvider: 'Previzualizare prin api.labelary.com', previewNoticeTitle: 'Notificare de confidențialitate', - previewNoticeBody: 'Previzualizarea este generată de serviciul extern api.labelary.com. Întregul ZPL al etichetei, inclusiv datele sensibile, este trimis prin rețea.', + previewNoticeBody: 'Previzualizarea și imprimarea sunt generate de serviciul extern api.labelary.com. Întregul ZPL al etichetei, inclusiv datele sensibile, este trimis prin rețea.', previewNoticePrivacyLink: 'Informații despre confidențialitate Labelary', previewNoticeAcknowledge: 'Am înțeles, continuă', }, diff --git a/src/locales/sk.ts b/src/locales/sk.ts index df3315c..1f70360 100644 --- a/src/locales/sk.ts +++ b/src/locales/sk.ts @@ -97,6 +97,7 @@ const sk = { newDesign: 'Nový návrh', addPage: 'Pridať stránku', cancel: 'Zrušiť', + close: 'Zavrieť', deletePage: 'Odstrániť stránku', deletePageConfirm: 'Odstrániť aktuálnu stránku?', openDesign: 'Otvoriť návrh', @@ -122,7 +123,7 @@ const sk = { previewEmpty: 'Náhľad sa zobrazí\npo úpravách', previewProvider: 'Náhľad cez api.labelary.com', previewNoticeTitle: 'Upozornenie o ochrane údajov', - previewNoticeBody: 'Náhľad sa generuje pomocou externej služby api.labelary.com. Celý ZPL štítku, vrátane citlivých údajov, sa odosiela cez sieť.', + previewNoticeBody: 'Náhľad a tlač sa generujú pomocou externej služby api.labelary.com. Celý ZPL štítku, vrátane citlivých údajov, sa odosiela cez sieť.', previewNoticePrivacyLink: 'Informácie o ochrane údajov Labelary', previewNoticeAcknowledge: 'Rozumiem, pokračovať', }, diff --git a/src/locales/sl.ts b/src/locales/sl.ts index 8ce35eb..84f9aa9 100644 --- a/src/locales/sl.ts +++ b/src/locales/sl.ts @@ -97,6 +97,7 @@ const sl = { newDesign: 'Nov dizajn', addPage: 'Dodaj stran', cancel: 'Prekliči', + close: 'Zapri', deletePage: 'Izbriši stran', deletePageConfirm: 'Izbrišem trenutno stran?', openDesign: 'Odpri dizajn', @@ -122,7 +123,7 @@ const sl = { previewEmpty: 'Predogled se prikaže\npo spremembah', previewProvider: 'Predogled prek api.labelary.com', previewNoticeTitle: 'Obvestilo o zasebnosti', - previewNoticeBody: 'Predogled ustvari zunanja storitev api.labelary.com. Celoten ZPL etikete, vključno z občutljivimi podatki, se pošlje po omrežju.', + previewNoticeBody: 'Predogled in tiskanje ustvari zunanja storitev api.labelary.com. Celoten ZPL etikete, vključno z občutljivimi podatki, se pošlje po omrežju.', previewNoticePrivacyLink: 'Informacije o zasebnosti Labelary', previewNoticeAcknowledge: 'Razumem, nadaljuj', }, diff --git a/src/locales/sr.ts b/src/locales/sr.ts index 1f66a19..7bcfa35 100644 --- a/src/locales/sr.ts +++ b/src/locales/sr.ts @@ -97,6 +97,7 @@ const sr = { newDesign: 'Нови дизајн', addPage: 'Додај страницу', cancel: 'Откажи', + close: 'Затвори', deletePage: 'Обриши страницу', deletePageConfirm: 'Обрисати тренутну страницу?', openDesign: 'Отвори дизајн', @@ -122,7 +123,7 @@ const sr = { previewEmpty: 'Pregled se prikazuje\nnakon promena', previewProvider: 'Преглед преко api.labelary.com', previewNoticeTitle: 'Обавештење о приватности', - previewNoticeBody: 'Преглед се приказује спољним сервисом api.labelary.com. Цео ZPL етикете, укључујући осетљиве податке, шаље се преко мреже.', + previewNoticeBody: 'Преглед и штампање приказује спољни сервис api.labelary.com. Цео ZPL етикете, укључујући осетљиве податке, шаље се преко мреже.', previewNoticePrivacyLink: 'Информације о приватности Labelary', previewNoticeAcknowledge: 'Разумем, настави', }, diff --git a/src/locales/sv.ts b/src/locales/sv.ts index fcfe937..01b1fda 100644 --- a/src/locales/sv.ts +++ b/src/locales/sv.ts @@ -97,6 +97,7 @@ const sv = { newDesign: 'Nytt design', addPage: 'Lägg till sida', cancel: 'Avbryt', + close: 'Stäng', deletePage: 'Ta bort sida', deletePageConfirm: 'Ta bort aktuell sida?', openDesign: 'Öppna design', @@ -122,7 +123,7 @@ const sv = { previewEmpty: 'Förhandsvisning visas\nefter ändringar', previewProvider: 'Förhandsgranskning via api.labelary.com', previewNoticeTitle: 'Integritetsmeddelande', - previewNoticeBody: 'Förhandsgranskningen renderas av den externa tjänsten api.labelary.com. Hela etikettens ZPL, inklusive känsliga data, skickas över nätverket.', + previewNoticeBody: 'Förhandsgranskning och utskrift renderas av den externa tjänsten api.labelary.com. Hela etikettens ZPL, inklusive känsliga data, skickas över nätverket.', previewNoticePrivacyLink: 'Labelarys integritetsinformation', previewNoticeAcknowledge: 'Uppfattat, fortsätt', }, diff --git a/src/locales/tr.ts b/src/locales/tr.ts index ff375fc..e83465f 100644 --- a/src/locales/tr.ts +++ b/src/locales/tr.ts @@ -97,6 +97,7 @@ const tr = { newDesign: 'Yeni Tasarım', addPage: 'Sayfa ekle', cancel: 'İptal', + close: 'Kapat', deletePage: 'Sayfayı sil', deletePageConfirm: 'Geçerli sayfa silinsin mi?', openDesign: 'Tasarım Aç', @@ -122,7 +123,7 @@ const tr = { previewEmpty: 'Önizleme değişikliklerden\nsonra görüntülenir', previewProvider: 'api.labelary.com üzerinden önizleme', previewNoticeTitle: 'Gizlilik bildirimi', - previewNoticeBody: 'Önizleme, harici api.labelary.com hizmeti tarafından oluşturulur. Hassas veriler dahil etiketin tamamı ZPL olarak ağ üzerinden gönderilir.', + previewNoticeBody: 'Önizleme ve yazdırma, harici api.labelary.com hizmeti tarafından oluşturulur. Hassas veriler dahil etiketin tamamı ZPL olarak ağ üzerinden gönderilir.', previewNoticePrivacyLink: 'Labelary gizlilik bilgileri', previewNoticeAcknowledge: 'Anladım, devam et', }, diff --git a/src/locales/zh-hans.ts b/src/locales/zh-hans.ts index f7e242c..20a6eb7 100644 --- a/src/locales/zh-hans.ts +++ b/src/locales/zh-hans.ts @@ -97,6 +97,7 @@ const zhHans = { newDesign: '新建设计', addPage: '添加页面', cancel: '取消', + close: '关闭', deletePage: '删除页面', deletePageConfirm: '删除当前页面?', openDesign: '打开设计', @@ -122,7 +123,7 @@ const zhHans = { previewEmpty: '更改后显示预览', previewProvider: '通过 api.labelary.com 预览', previewNoticeTitle: '隐私提示', - previewNoticeBody: '预览由外部服务 api.labelary.com 生成。完整的标签 ZPL(包括敏感数据)将通过网络发送。', + previewNoticeBody: '预览和打印由外部服务 api.labelary.com 生成。完整的标签 ZPL(包括敏感数据)将通过网络发送。', previewNoticePrivacyLink: 'Labelary 隐私信息', previewNoticeAcknowledge: '知道了,继续', }, diff --git a/src/locales/zh-hant.ts b/src/locales/zh-hant.ts index 8a4fd1f..0f504d1 100644 --- a/src/locales/zh-hant.ts +++ b/src/locales/zh-hant.ts @@ -97,6 +97,7 @@ const zhHant = { newDesign: '新增設計', addPage: '新增頁面', cancel: '取消', + close: '關閉', deletePage: '刪除頁面', deletePageConfirm: '刪除目前頁面?', openDesign: '開啟設計', @@ -122,7 +123,7 @@ const zhHant = { previewEmpty: '變更後顯示預覽', previewProvider: '透過 api.labelary.com 預覽', previewNoticeTitle: '隱私聲明', - previewNoticeBody: '預覽由外部服務 api.labelary.com 產生。完整的標籤 ZPL(包含敏感資料)會透過網路傳送。', + previewNoticeBody: '預覽和列印由外部服務 api.labelary.com 產生。完整的標籤 ZPL(包含敏感資料)會透過網路傳送。', previewNoticePrivacyLink: 'Labelary 隱私資訊', previewNoticeAcknowledge: '了解,繼續', }, diff --git a/src/store/labelStore.ts b/src/store/labelStore.ts index 956c5f9..121a9e1 100644 --- a/src/store/labelStore.ts +++ b/src/store/labelStore.ts @@ -114,8 +114,10 @@ export const currentObjects = (state: PageState): LabelObject[] => state.pages[state.currentPageIndex]?.objects ?? []; /** True when a Labelary network call is permitted: the gate is on AND the - * user has seen the privacy notice. Single source of truth so every UI - * consumer (Preview, Print, …) stays in lockstep. */ + * user has seen the privacy notice. Kept as a documented invariant; UI + * buttons read `thirdParty.labelary` and `labelaryNoticeAcknowledged` + * separately because they need to distinguish "hide" (gate off) from + * "show notice first" (gate on, not yet acknowledged). */ export const canCallLabelary = (s: LabelState): boolean => s.thirdParty.labelary && s.labelaryNoticeAcknowledged; diff --git a/src/store/labelStoreEnv.test.ts b/src/store/labelStoreEnv.test.ts new file mode 100644 index 0000000..050a85b --- /dev/null +++ b/src/store/labelStoreEnv.test.ts @@ -0,0 +1,41 @@ +import { describe, it, expect, vi, afterEach } from 'vitest'; + +/** Verifies that VITE_THIRD_PARTY_LABELARY=false flips the Labelary gate + * off at store init. The UI gates Print/Preview buttons on + * `thirdParty.labelary` directly, so a false default keeps both buttons + * hidden on Tauri/Docker builds — even though the user can still + * acknowledge the notice (in-memory) for the lifetime of the session. + * + * Lives in a dedicated file because each case needs to re-import the + * store module after stubbing import.meta.env. */ +describe('thirdParty defaults from env', () => { + afterEach(() => { + vi.unstubAllEnvs(); + vi.resetModules(); + }); + + it('defaults Labelary gate to true when env is unset', async () => { + vi.stubEnv('VITE_THIRD_PARTY_LABELARY', ''); + vi.resetModules(); + const { useLabelStore } = await import('./labelStore'); + expect(useLabelStore.getState().thirdParty.labelary).toBe(true); + }); + + it('defaults Labelary gate to false when env is "false"', async () => { + vi.stubEnv('VITE_THIRD_PARTY_LABELARY', 'false'); + vi.resetModules(); + const { useLabelStore, canCallLabelary } = await import('./labelStore'); + const s = useLabelStore.getState(); + expect(s.thirdParty.labelary).toBe(false); + // Acknowledgement alone must not unlock Labelary when the gate is off. + s.acknowledgeLabelaryNotice(); + expect(canCallLabelary(useLabelStore.getState())).toBe(false); + }); + + it('treats other env values as "enabled" (only "false" disables)', async () => { + vi.stubEnv('VITE_THIRD_PARTY_LABELARY', 'true'); + vi.resetModules(); + const { useLabelStore } = await import('./labelStore'); + expect(useLabelStore.getState().thirdParty.labelary).toBe(true); + }); +});