@object-ui/i18n 17.1.0 → 17.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # @object-ui/i18n
2
2
 
3
+ ## 17.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a889e31: A record's approval band now shows the quorum / per-group tally the server already computes.
8
+
9
+ The showcase's `showcase_committee_quorum` node declares `behavior: 'quorum'` with
10
+ `minApprovals: 2` over three approvers, and even ships a pre-rendered
11
+ `"Committee Sign-off (2 of 3)"` label; `showcase_expense_signoff` declares
12
+ `per_group` (会签) with named manager / finance groups. On the business record
13
+ the approval band rendered none of it — the lock badge, the recall button and
14
+ the approve/reject actions were all correct, but a two-of-three committee step
15
+ looked exactly like a one-approver step. An approver could not see whether their
16
+ own click finalized the node or was one of three, which is the single fact a
17
+ quorum node exists to express (objectstack#4478).
18
+
19
+ Nothing was wrong on the wire, and nothing here papers over the server. The
20
+ framework computes `decision_progress` — `{ behavior, got, need, groups? }`,
21
+ derived from the node's own `node_config_json` snapshot, so the count a client
22
+ shows is the count the engine will enforce. **It attaches that block in
23
+ `getRequest` only**: `listRequests` deliberately skips it, because the
24
+ `sys_approval_action` tally it costs is per row and a list read may return
25
+ hundreds. The record header's `useRecordApprovals` reads
26
+ `GET /approvals/requests?object=…&recordId=…` — the list route — so the
27
+ enrichment was never in the payload it had. The hook now follows up with one
28
+ single read for the ONE pending row and folds the result onto it; a failed or
29
+ mismatched follow-up leaves the row exactly as the list sent it, so a display-only
30
+ enrichment can never take the approval panel down and no tally is ever invented.
31
+
32
+ `InlineEditProvider` carries the block through as `approvalProgress`, and the
33
+ DetailView approval band renders it beside the existing badge: a labelled
34
+ `role="progressbar"` with one tick per required approval for `quorum` /
35
+ `unanimous`, and for `per_group` a chip per group marking which have signed
36
+ (`finance 1/1` ✓, `manager 0/1`). Group names come from the flow author's own
37
+ config, so they need no locale strings; the three new label keys are added to all
38
+ ten packs. `first_response` nodes carry no `decision_progress` and are unchanged —
39
+ one decision is the whole step there, and a "1 of 1" bar would be noise.
40
+
41
+ Scored `minor` rather than `patch`: this is new observable rendering plus a new
42
+ public `approvalProgress` prop / `ApprovalProgress` type on `@object-ui/react`,
43
+ not a behavior correction inside an existing surface.
44
+
45
+ ### Patch Changes
46
+
47
+ - 4b470b9: Localize the environment entitlement dialog and read cloud's nested error envelope.
48
+
49
+ The free-plan "Development environments are a paid feature" prompt was built from
50
+ English string literals in `entitlements.ts` — including the lowercase `your free
51
+ plan` sentence users reported (cloud#959). Both spec builders now take a translator
52
+ and resolve `environment.entitlement.*`; all ten locale packs carry the strings.
53
+ `entitlements.ts` stays dependency-free: `t` is passed in, not imported, and
54
+ defaults to the English copy with local `{{token}}` interpolation.
55
+
56
+ The dialog now renders the Console's own copy rather than the server's prose — a
57
+ control plane upgrades independently and only localizes these messages from
58
+ cloud#959 on, so preferring the server string left the reactive path English
59
+ against every older deployment.
60
+
61
+ Also fixes the reactive dialog not firing at all: cloud#948 moved coded errors into
62
+ a nested envelope (`{ success, error: { code, … } }`), and
63
+ `entitlementDialogFromError` read `code` off the top level — returning `null` for
64
+ every entitlement 403, so the upgrade dialog degraded to a generic red error toast.
65
+ Both shapes are read now.
66
+
3
67
  ## 17.1.0
4
68
 
5
69
  ### Minor Changes
@@ -820,6 +820,9 @@ declare const ar: {
820
820
  writeStrippedByState: string;
821
821
  approvalPendingEditable: string;
822
822
  approvalPendingTooltip: string;
823
+ approvalProgress: string;
824
+ approvalProgressGroups: string;
825
+ approvalProgressLabel: string;
823
826
  cancelApproval: string;
824
827
  cancelApprovalInFlight: string;
825
828
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const ar: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -822,6 +822,9 @@ const ar = {
822
822
  writeStrippedByState: "غير قابلة للتعديل في الحالة الحالية لهذا السجل، لذلك لم يتم حفظها: {{fields}}",
823
823
  approvalPendingEditable: "قيد الموافقة · قابل للتعديل",
824
824
  approvalPendingTooltip: "يحتوي هذا السجل على طلب موافقة معلق، لكن هذه الخطوة لا تزال تسمح بالتعديل",
825
+ approvalProgress: "الموافقات — {{got}} من {{need}}",
826
+ approvalProgressGroups: "التوقيعات — {{got}} من {{need}} مجموعات",
827
+ approvalProgressLabel: "تقدّم الموافقة",
825
828
  cancelApproval: "إلغاء الموافقة",
826
829
  cancelApprovalInFlight: "جارٍ الإلغاء…",
827
830
  cancelApprovalTooltip: "إلغاء طلب الموافقة المعلق لفتح قفل السجل",
@@ -2567,6 +2570,20 @@ const ar = {
2567
2570
  addEnvironment: "إضافة بيئة",
2568
2571
  setUpProduction: "إعداد بيئة الإنتاج",
2569
2572
  addDevelopment: "إضافة بيئة تطوير",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "لديك بالفعل بيئة الإنتاج الخاصة بك",
2576
+ productionLimitBody: "تتضمّن كل مؤسسة بيئة إنتاج واحدة فقط. أنشئ مؤسسة منفصلة للحصول على بيئة أخرى، أو تواصل معنا بشأن ترتيبات الخطة المؤسسية.",
2577
+ planLockedTitle: "بيئات التطوير ميزة مدفوعة",
2578
+ planLockedBody: "تتضمّن {{plan}} بيئة إنتاج واحدة. قم بالترقية لإضافة بيئات تطوير — أنشئ في بيئة التطوير ثم انشر إلى الإنتاج.",
2579
+ limitTitle: "تم بلوغ الحد الأقصى لبيئات التطوير",
2580
+ limitBody: "تزداد السعة مع مقاعد الذكاء الاصطناعي. أضف مقعدًا، أو أرشف بيئة تطوير غير مستخدمة لتحرير مكان.",
2581
+ limitBodyWithCount: "تستخدم {{used}} من أصل {{limit}} بيئة تطوير. تزداد السعة مع مقاعد الذكاء الاصطناعي — أضف مقعدًا، أو أرشف بيئة تطوير غير مستخدمة.",
2582
+ freePlan: "الخطة المجانية",
2583
+ namedPlan: "خطة {{plan}}",
2584
+ upgradeCta: "ترقية الخطة",
2585
+ contactSalesCta: "تواصل مع المبيعات",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "جارٍ التحقق من الاتصال…",
@@ -818,6 +818,9 @@ declare const de: {
818
818
  writeStrippedByState: string;
819
819
  approvalPendingEditable: string;
820
820
  approvalPendingTooltip: string;
821
+ approvalProgress: string;
822
+ approvalProgressGroups: string;
823
+ approvalProgressLabel: string;
821
824
  cancelApproval: string;
822
825
  cancelApprovalInFlight: string;
823
826
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const de: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -820,6 +820,9 @@ const de = {
820
820
  writeStrippedByState: "Im aktuellen Status dieses Datensatzes nicht bearbeitbar und daher nicht gespeichert: {{fields}}",
821
821
  approvalPendingEditable: "In Genehmigung · bearbeitbar",
822
822
  approvalPendingTooltip: "Dieser Datensatz hat eine ausstehende Genehmigungsanfrage; dieser Schritt erlaubt weiterhin die Bearbeitung",
823
+ approvalProgress: "Genehmigungen — {{got}} von {{need}}",
824
+ approvalProgressGroups: "Freigabe — {{got}} von {{need}} Gruppen",
825
+ approvalProgressLabel: "Genehmigungsfortschritt",
823
826
  cancelApproval: "Genehmigung zurückziehen",
824
827
  cancelApprovalInFlight: "Zurückziehen…",
825
828
  cancelApprovalTooltip: "Ausstehende Genehmigungsanfrage zurückziehen, um den Datensatz zu entsperren",
@@ -2567,6 +2570,20 @@ const de = {
2567
2570
  addEnvironment: "Umgebung hinzufügen",
2568
2571
  setUpProduction: "Produktionsumgebung einrichten",
2569
2572
  addDevelopment: "Entwicklungsumgebung hinzufügen",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "Sie haben bereits Ihre Produktionsumgebung",
2576
+ productionLimitBody: "Jede Organisation enthält genau eine Produktionsumgebung. Erstellen Sie für eine weitere eine separate Organisation, oder sprechen Sie uns auf eine Enterprise-Vereinbarung an.",
2577
+ planLockedTitle: "Entwicklungsumgebungen sind eine kostenpflichtige Funktion",
2578
+ planLockedBody: "Ihr {{plan}} enthält eine Produktionsumgebung. Führen Sie ein Upgrade durch, um Entwicklungsumgebungen hinzuzufügen — entwickeln Sie in der Entwicklungsumgebung und veröffentlichen Sie dann in der Produktion.",
2579
+ limitTitle: "Limit für Entwicklungsumgebungen erreicht",
2580
+ limitBody: "Die Kapazität wächst mit den KI-Lizenzen. Fügen Sie eine KI-Lizenz hinzu oder archivieren Sie eine ungenutzte Entwicklungsumgebung, um Platz zu schaffen.",
2581
+ limitBodyWithCount: "Sie nutzen {{used}} von {{limit}} Entwicklungsumgebungen. Die Kapazität wächst mit den KI-Lizenzen — fügen Sie eine KI-Lizenz hinzu oder archivieren Sie eine ungenutzte Entwicklungsumgebung.",
2582
+ freePlan: "kostenloser Tarif",
2583
+ namedPlan: "Tarif {{plan}}",
2584
+ upgradeCta: "Tarif upgraden",
2585
+ contactSalesCta: "Vertrieb kontaktieren",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "Verbindung wird geprüft…",
@@ -717,6 +717,9 @@ declare const en: {
717
717
  readonly writeStrippedByState: "Not editable in this record's current state, so it was not saved: {{fields}}";
718
718
  readonly approvalPendingEditable: "In approval · editable";
719
719
  readonly approvalPendingTooltip: "This record has a pending approval request; this step still allows editing";
720
+ readonly approvalProgress: "Approvals — {{got}} of {{need}}";
721
+ readonly approvalProgressGroups: "Sign-off — {{got}} of {{need}} groups";
722
+ readonly approvalProgressLabel: "Approval progress";
720
723
  readonly cancelApproval: "Recall approval";
721
724
  readonly cancelApprovalInFlight: "Recalling…";
722
725
  readonly cancelApprovalTooltip: "Recall the pending approval request to unlock this record";
@@ -2608,6 +2611,19 @@ declare const en: {
2608
2611
  readonly addEnvironment: "Add environment";
2609
2612
  readonly setUpProduction: "Set up your production environment";
2610
2613
  readonly addDevelopment: "Add development environment";
2614
+ readonly entitlement: {
2615
+ readonly productionLimitTitle: "You already have your production environment";
2616
+ readonly productionLimitBody: "Each organization includes exactly one production environment. Create a separate organization for another, or contact us about an Enterprise arrangement.";
2617
+ readonly planLockedTitle: "Development environments are a paid feature";
2618
+ readonly planLockedBody: "Your {{plan}} includes one production environment. Upgrade to add development environments — build in dev, then publish to production.";
2619
+ readonly limitTitle: "Development environment limit reached";
2620
+ readonly limitBody: "Capacity scales with AI seats. Add an AI seat, or archive an unused development environment to free one up.";
2621
+ readonly limitBodyWithCount: "You are using {{used}} of {{limit}} development environments. Capacity scales with AI seats — add an AI seat, or archive an unused development environment to free one up.";
2622
+ readonly freePlan: "free plan";
2623
+ readonly namedPlan: "{{plan}} plan";
2624
+ readonly upgradeCta: "Upgrade plan";
2625
+ readonly contactSalesCta: "Contact sales";
2626
+ };
2611
2627
  };
2612
2628
  readonly cloudConnection: {
2613
2629
  readonly checking: "Checking connection…";
@@ -721,6 +721,9 @@ const en = {
721
721
  writeStrippedByState: "Not editable in this record's current state, so it was not saved: {{fields}}",
722
722
  approvalPendingEditable: 'In approval · editable',
723
723
  approvalPendingTooltip: 'This record has a pending approval request; this step still allows editing',
724
+ approvalProgress: 'Approvals — {{got}} of {{need}}',
725
+ approvalProgressGroups: 'Sign-off — {{got}} of {{need}} groups',
726
+ approvalProgressLabel: 'Approval progress',
724
727
  cancelApproval: 'Recall approval',
725
728
  cancelApprovalInFlight: 'Recalling…',
726
729
  cancelApprovalTooltip: 'Recall the pending approval request to unlock this record',
@@ -2648,6 +2651,21 @@ const en = {
2648
2651
  addEnvironment: 'Add environment',
2649
2652
  setUpProduction: 'Set up your production environment',
2650
2653
  addDevelopment: 'Add development environment',
2654
+ // Plan/capacity dialog (EnvironmentEntitlementDialog). Shown on a paid
2655
+ // conversion path, so it must read in the user's language — cloud#959.
2656
+ entitlement: {
2657
+ productionLimitTitle: 'You already have your production environment',
2658
+ productionLimitBody: 'Each organization includes exactly one production environment. Create a separate organization for another, or contact us about an Enterprise arrangement.',
2659
+ planLockedTitle: 'Development environments are a paid feature',
2660
+ planLockedBody: 'Your {{plan}} includes one production environment. Upgrade to add development environments — build in dev, then publish to production.',
2661
+ limitTitle: 'Development environment limit reached',
2662
+ limitBody: 'Capacity scales with AI seats. Add an AI seat, or archive an unused development environment to free one up.',
2663
+ limitBodyWithCount: 'You are using {{used}} of {{limit}} development environments. Capacity scales with AI seats — add an AI seat, or archive an unused development environment to free one up.',
2664
+ freePlan: 'free plan',
2665
+ namedPlan: '{{plan}} plan',
2666
+ upgradeCta: 'Upgrade plan',
2667
+ contactSalesCta: 'Contact sales',
2668
+ },
2651
2669
  },
2652
2670
  cloudConnection: {
2653
2671
  checking: 'Checking connection…',
@@ -818,6 +818,9 @@ declare const es: {
818
818
  writeStrippedByState: string;
819
819
  approvalPendingEditable: string;
820
820
  approvalPendingTooltip: string;
821
+ approvalProgress: string;
822
+ approvalProgressGroups: string;
823
+ approvalProgressLabel: string;
821
824
  cancelApproval: string;
822
825
  cancelApprovalInFlight: string;
823
826
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const es: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -820,6 +820,9 @@ const es = {
820
820
  writeStrippedByState: "No editable en el estado actual de este registro, por lo que no se guardó: {{fields}}",
821
821
  approvalPendingEditable: "En aprobación · editable",
822
822
  approvalPendingTooltip: "Este registro tiene una solicitud de aprobación pendiente; este paso todavía permite la edición",
823
+ approvalProgress: "Aprobaciones — {{got}} de {{need}}",
824
+ approvalProgressGroups: "Firmas — {{got}} de {{need}} grupos",
825
+ approvalProgressLabel: "Progreso de la aprobación",
823
826
  cancelApproval: "Cancelar aprobación",
824
827
  cancelApprovalInFlight: "Cancelando…",
825
828
  cancelApprovalTooltip: "Cancelar la solicitud de aprobación pendiente para desbloquear el registro",
@@ -2567,6 +2570,20 @@ const es = {
2567
2570
  addEnvironment: "Añadir entorno",
2568
2571
  setUpProduction: "Configure su entorno de producción",
2569
2572
  addDevelopment: "Añadir entorno de desarrollo",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "Ya tiene su entorno de producción",
2576
+ productionLimitBody: "Cada organización incluye exactamente un entorno de producción. Cree una organización aparte para tener otro, o contáctenos para conocer un acuerdo Enterprise.",
2577
+ planLockedTitle: "Los entornos de desarrollo son una función de pago",
2578
+ planLockedBody: "Su {{plan}} incluye un entorno de producción. Mejore su plan para añadir entornos de desarrollo: construya en desarrollo y luego publique en producción.",
2579
+ limitTitle: "Límite de entornos de desarrollo alcanzado",
2580
+ limitBody: "La capacidad crece con los puestos de IA. Añada un puesto de IA, o archive un entorno de desarrollo sin usar para liberar espacio.",
2581
+ limitBodyWithCount: "Está usando {{used}} de {{limit}} entornos de desarrollo. La capacidad crece con los puestos de IA: añada un puesto de IA, o archive un entorno de desarrollo sin usar.",
2582
+ freePlan: "plan gratuito",
2583
+ namedPlan: "plan {{plan}}",
2584
+ upgradeCta: "Mejorar plan",
2585
+ contactSalesCta: "Contactar con ventas",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "Comprobando la conexión…",
@@ -820,6 +820,9 @@ declare const fr: {
820
820
  writeStrippedByState: string;
821
821
  approvalPendingEditable: string;
822
822
  approvalPendingTooltip: string;
823
+ approvalProgress: string;
824
+ approvalProgressGroups: string;
825
+ approvalProgressLabel: string;
823
826
  cancelApproval: string;
824
827
  cancelApprovalInFlight: string;
825
828
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const fr: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -822,6 +822,9 @@ const fr = {
822
822
  writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non enregistré : {{fields}}",
823
823
  approvalPendingEditable: "En approbation · modifiable",
824
824
  approvalPendingTooltip: "Cet enregistrement a une demande d'approbation en attente ; cette étape autorise encore la modification",
825
+ approvalProgress: "Approbations — {{got}} sur {{need}}",
826
+ approvalProgressGroups: "Validation — {{got}} sur {{need}} groupes",
827
+ approvalProgressLabel: "Progression de l'approbation",
825
828
  cancelApproval: "Annuler l'approbation",
826
829
  cancelApprovalInFlight: "Annulation…",
827
830
  cancelApprovalTooltip: "Annuler la demande d'approbation en attente pour déverrouiller l'enregistrement",
@@ -2567,6 +2570,20 @@ const fr = {
2567
2570
  addEnvironment: "Ajouter un environnement",
2568
2571
  setUpProduction: "Configurer votre environnement de production",
2569
2572
  addDevelopment: "Ajouter un environnement de développement",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "Vous avez déjà votre environnement de production",
2576
+ productionLimitBody: "Chaque organisation comprend exactement un environnement de production. Créez une organisation distincte pour en avoir un autre, ou contactez-nous au sujet d'une offre Enterprise.",
2577
+ planLockedTitle: "Les environnements de développement sont une fonctionnalité payante",
2578
+ planLockedBody: "Votre {{plan}} comprend un environnement de production. Passez à une offre supérieure pour ajouter des environnements de développement — développez en dev, puis publiez en production.",
2579
+ limitTitle: "Limite d'environnements de développement atteinte",
2580
+ limitBody: "La capacité évolue avec les sièges IA. Ajoutez un siège IA, ou archivez un environnement de développement inutilisé pour libérer une place.",
2581
+ limitBodyWithCount: "Vous utilisez {{used}} environnements de développement sur {{limit}}. La capacité évolue avec les sièges IA — ajoutez un siège IA, ou archivez un environnement de développement inutilisé.",
2582
+ freePlan: "offre gratuite",
2583
+ namedPlan: "offre {{plan}}",
2584
+ upgradeCta: "Changer d'offre",
2585
+ contactSalesCta: "Contacter le service commercial",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "Vérification de la connexion…",
@@ -729,6 +729,9 @@ export declare const builtInLocales: {
729
729
  readonly writeStrippedByState: "Not editable in this record's current state, so it was not saved: {{fields}}";
730
730
  readonly approvalPendingEditable: "In approval · editable";
731
731
  readonly approvalPendingTooltip: "This record has a pending approval request; this step still allows editing";
732
+ readonly approvalProgress: "Approvals — {{got}} of {{need}}";
733
+ readonly approvalProgressGroups: "Sign-off — {{got}} of {{need}} groups";
734
+ readonly approvalProgressLabel: "Approval progress";
732
735
  readonly cancelApproval: "Recall approval";
733
736
  readonly cancelApprovalInFlight: "Recalling…";
734
737
  readonly cancelApprovalTooltip: "Recall the pending approval request to unlock this record";
@@ -2620,6 +2623,19 @@ export declare const builtInLocales: {
2620
2623
  readonly addEnvironment: "Add environment";
2621
2624
  readonly setUpProduction: "Set up your production environment";
2622
2625
  readonly addDevelopment: "Add development environment";
2626
+ readonly entitlement: {
2627
+ readonly productionLimitTitle: "You already have your production environment";
2628
+ readonly productionLimitBody: "Each organization includes exactly one production environment. Create a separate organization for another, or contact us about an Enterprise arrangement.";
2629
+ readonly planLockedTitle: "Development environments are a paid feature";
2630
+ readonly planLockedBody: "Your {{plan}} includes one production environment. Upgrade to add development environments — build in dev, then publish to production.";
2631
+ readonly limitTitle: "Development environment limit reached";
2632
+ readonly limitBody: "Capacity scales with AI seats. Add an AI seat, or archive an unused development environment to free one up.";
2633
+ readonly limitBodyWithCount: "You are using {{used}} of {{limit}} development environments. Capacity scales with AI seats — add an AI seat, or archive an unused development environment to free one up.";
2634
+ readonly freePlan: "free plan";
2635
+ readonly namedPlan: "{{plan}} plan";
2636
+ readonly upgradeCta: "Upgrade plan";
2637
+ readonly contactSalesCta: "Contact sales";
2638
+ };
2623
2639
  };
2624
2640
  readonly cloudConnection: {
2625
2641
  readonly checking: "Checking connection…";
@@ -3724,6 +3740,9 @@ export declare const builtInLocales: {
3724
3740
  readonly writeStrippedByState: "以下字段在记录当前状态下不可编辑,未保存:{{fields}}";
3725
3741
  readonly approvalPendingEditable: "审批中 · 可编辑";
3726
3742
  readonly approvalPendingTooltip: "该记录有待审批的请求,但当前审批节点仍允许编辑";
3743
+ readonly approvalProgress: "审批 — 已通过 {{got}} / 共需 {{need}}";
3744
+ readonly approvalProgressGroups: "会签 — 已完成 {{got}} / 共 {{need}} 个组";
3745
+ readonly approvalProgressLabel: "审批进度";
3727
3746
  readonly cancelApproval: "撤回审批";
3728
3747
  readonly cancelApprovalInFlight: "撤回中…";
3729
3748
  readonly cancelApprovalTooltip: "撤回当前的待审批请求以解除记录锁定";
@@ -5611,6 +5630,19 @@ export declare const builtInLocales: {
5611
5630
  readonly addEnvironment: "新建环境";
5612
5631
  readonly setUpProduction: "创建你的生产环境";
5613
5632
  readonly addDevelopment: "新建开发环境";
5633
+ readonly entitlement: {
5634
+ readonly productionLimitTitle: "你已经有生产环境了";
5635
+ readonly productionLimitBody: "每个组织只包含一个生产环境。如果还需要,可以新建一个组织,或者联系我们了解企业版方案。";
5636
+ readonly planLockedTitle: "开发环境是付费功能";
5637
+ readonly planLockedBody: "{{plan}}包含一个生产环境。升级后即可添加开发环境 —— 先在开发环境里搭建,确认无误再发布到生产环境。";
5638
+ readonly limitTitle: "开发环境数量已达上限";
5639
+ readonly limitBody: "容量随 AI 席位增长。增加一个 AI 席位,或归档一个不再使用的开发环境来腾出名额。";
5640
+ readonly limitBodyWithCount: "开发环境已使用 {{used}}/{{limit}} 个。容量随 AI 席位增长 —— 增加一个 AI 席位,或归档一个不再使用的开发环境来腾出名额。";
5641
+ readonly freePlan: "免费版";
5642
+ readonly namedPlan: "{{plan}} 版";
5643
+ readonly upgradeCta: "升级套餐";
5644
+ readonly contactSalesCta: "联系销售";
5645
+ };
5614
5646
  };
5615
5647
  readonly cloudConnection: {
5616
5648
  readonly checking: "正在检查连接…";
@@ -6826,6 +6858,9 @@ export declare const builtInLocales: {
6826
6858
  writeStrippedByState: string;
6827
6859
  approvalPendingEditable: string;
6828
6860
  approvalPendingTooltip: string;
6861
+ approvalProgress: string;
6862
+ approvalProgressGroups: string;
6863
+ approvalProgressLabel: string;
6829
6864
  cancelApproval: string;
6830
6865
  cancelApprovalInFlight: string;
6831
6866
  cancelApprovalTooltip: string;
@@ -8562,6 +8597,19 @@ export declare const builtInLocales: {
8562
8597
  addEnvironment: string;
8563
8598
  setUpProduction: string;
8564
8599
  addDevelopment: string;
8600
+ entitlement: {
8601
+ productionLimitTitle: string;
8602
+ productionLimitBody: string;
8603
+ planLockedTitle: string;
8604
+ planLockedBody: string;
8605
+ limitTitle: string;
8606
+ limitBody: string;
8607
+ limitBodyWithCount: string;
8608
+ freePlan: string;
8609
+ namedPlan: string;
8610
+ upgradeCta: string;
8611
+ contactSalesCta: string;
8612
+ };
8565
8613
  };
8566
8614
  cloudConnection: {
8567
8615
  checking: string;
@@ -9802,6 +9850,9 @@ export declare const builtInLocales: {
9802
9850
  writeStrippedByState: string;
9803
9851
  approvalPendingEditable: string;
9804
9852
  approvalPendingTooltip: string;
9853
+ approvalProgress: string;
9854
+ approvalProgressGroups: string;
9855
+ approvalProgressLabel: string;
9805
9856
  cancelApproval: string;
9806
9857
  cancelApprovalInFlight: string;
9807
9858
  cancelApprovalTooltip: string;
@@ -11549,6 +11600,19 @@ export declare const builtInLocales: {
11549
11600
  addEnvironment: string;
11550
11601
  setUpProduction: string;
11551
11602
  addDevelopment: string;
11603
+ entitlement: {
11604
+ productionLimitTitle: string;
11605
+ productionLimitBody: string;
11606
+ planLockedTitle: string;
11607
+ planLockedBody: string;
11608
+ limitTitle: string;
11609
+ limitBody: string;
11610
+ limitBodyWithCount: string;
11611
+ freePlan: string;
11612
+ namedPlan: string;
11613
+ upgradeCta: string;
11614
+ contactSalesCta: string;
11615
+ };
11552
11616
  };
11553
11617
  cloudConnection: {
11554
11618
  checking: string;
@@ -12789,6 +12853,9 @@ export declare const builtInLocales: {
12789
12853
  writeStrippedByState: string;
12790
12854
  approvalPendingEditable: string;
12791
12855
  approvalPendingTooltip: string;
12856
+ approvalProgress: string;
12857
+ approvalProgressGroups: string;
12858
+ approvalProgressLabel: string;
12792
12859
  cancelApproval: string;
12793
12860
  cancelApprovalInFlight: string;
12794
12861
  cancelApprovalTooltip: string;
@@ -14536,6 +14603,19 @@ export declare const builtInLocales: {
14536
14603
  addEnvironment: string;
14537
14604
  setUpProduction: string;
14538
14605
  addDevelopment: string;
14606
+ entitlement: {
14607
+ productionLimitTitle: string;
14608
+ productionLimitBody: string;
14609
+ planLockedTitle: string;
14610
+ planLockedBody: string;
14611
+ limitTitle: string;
14612
+ limitBody: string;
14613
+ limitBodyWithCount: string;
14614
+ freePlan: string;
14615
+ namedPlan: string;
14616
+ upgradeCta: string;
14617
+ contactSalesCta: string;
14618
+ };
14539
14619
  };
14540
14620
  cloudConnection: {
14541
14621
  checking: string;
@@ -15778,6 +15858,9 @@ export declare const builtInLocales: {
15778
15858
  writeStrippedByState: string;
15779
15859
  approvalPendingEditable: string;
15780
15860
  approvalPendingTooltip: string;
15861
+ approvalProgress: string;
15862
+ approvalProgressGroups: string;
15863
+ approvalProgressLabel: string;
15781
15864
  cancelApproval: string;
15782
15865
  cancelApprovalInFlight: string;
15783
15866
  cancelApprovalTooltip: string;
@@ -17523,6 +17606,19 @@ export declare const builtInLocales: {
17523
17606
  addEnvironment: string;
17524
17607
  setUpProduction: string;
17525
17608
  addDevelopment: string;
17609
+ entitlement: {
17610
+ productionLimitTitle: string;
17611
+ productionLimitBody: string;
17612
+ planLockedTitle: string;
17613
+ planLockedBody: string;
17614
+ limitTitle: string;
17615
+ limitBody: string;
17616
+ limitBodyWithCount: string;
17617
+ freePlan: string;
17618
+ namedPlan: string;
17619
+ upgradeCta: string;
17620
+ contactSalesCta: string;
17621
+ };
17526
17622
  };
17527
17623
  cloudConnection: {
17528
17624
  checking: string;
@@ -18763,6 +18859,9 @@ export declare const builtInLocales: {
18763
18859
  writeStrippedByState: string;
18764
18860
  approvalPendingEditable: string;
18765
18861
  approvalPendingTooltip: string;
18862
+ approvalProgress: string;
18863
+ approvalProgressGroups: string;
18864
+ approvalProgressLabel: string;
18766
18865
  cancelApproval: string;
18767
18866
  cancelApprovalInFlight: string;
18768
18867
  cancelApprovalTooltip: string;
@@ -20510,6 +20609,19 @@ export declare const builtInLocales: {
20510
20609
  addEnvironment: string;
20511
20610
  setUpProduction: string;
20512
20611
  addDevelopment: string;
20612
+ entitlement: {
20613
+ productionLimitTitle: string;
20614
+ productionLimitBody: string;
20615
+ planLockedTitle: string;
20616
+ planLockedBody: string;
20617
+ limitTitle: string;
20618
+ limitBody: string;
20619
+ limitBodyWithCount: string;
20620
+ freePlan: string;
20621
+ namedPlan: string;
20622
+ upgradeCta: string;
20623
+ contactSalesCta: string;
20624
+ };
20513
20625
  };
20514
20626
  cloudConnection: {
20515
20627
  checking: string;
@@ -21752,6 +21864,9 @@ export declare const builtInLocales: {
21752
21864
  writeStrippedByState: string;
21753
21865
  approvalPendingEditable: string;
21754
21866
  approvalPendingTooltip: string;
21867
+ approvalProgress: string;
21868
+ approvalProgressGroups: string;
21869
+ approvalProgressLabel: string;
21755
21870
  cancelApproval: string;
21756
21871
  cancelApprovalInFlight: string;
21757
21872
  cancelApprovalTooltip: string;
@@ -23497,6 +23612,19 @@ export declare const builtInLocales: {
23497
23612
  addEnvironment: string;
23498
23613
  setUpProduction: string;
23499
23614
  addDevelopment: string;
23615
+ entitlement: {
23616
+ productionLimitTitle: string;
23617
+ productionLimitBody: string;
23618
+ planLockedTitle: string;
23619
+ planLockedBody: string;
23620
+ limitTitle: string;
23621
+ limitBody: string;
23622
+ limitBodyWithCount: string;
23623
+ freePlan: string;
23624
+ namedPlan: string;
23625
+ upgradeCta: string;
23626
+ contactSalesCta: string;
23627
+ };
23500
23628
  };
23501
23629
  cloudConnection: {
23502
23630
  checking: string;
@@ -24750,6 +24878,9 @@ export declare const builtInLocales: {
24750
24878
  writeStrippedByState: string;
24751
24879
  approvalPendingEditable: string;
24752
24880
  approvalPendingTooltip: string;
24881
+ approvalProgress: string;
24882
+ approvalProgressGroups: string;
24883
+ approvalProgressLabel: string;
24753
24884
  cancelApproval: string;
24754
24885
  cancelApprovalInFlight: string;
24755
24886
  cancelApprovalTooltip: string;
@@ -26484,6 +26615,19 @@ export declare const builtInLocales: {
26484
26615
  addEnvironment: string;
26485
26616
  setUpProduction: string;
26486
26617
  addDevelopment: string;
26618
+ entitlement: {
26619
+ productionLimitTitle: string;
26620
+ productionLimitBody: string;
26621
+ planLockedTitle: string;
26622
+ planLockedBody: string;
26623
+ limitTitle: string;
26624
+ limitBody: string;
26625
+ limitBodyWithCount: string;
26626
+ freePlan: string;
26627
+ namedPlan: string;
26628
+ upgradeCta: string;
26629
+ contactSalesCta: string;
26630
+ };
26487
26631
  };
26488
26632
  cloudConnection: {
26489
26633
  checking: string;
@@ -27726,6 +27870,9 @@ export declare const builtInLocales: {
27726
27870
  writeStrippedByState: string;
27727
27871
  approvalPendingEditable: string;
27728
27872
  approvalPendingTooltip: string;
27873
+ approvalProgress: string;
27874
+ approvalProgressGroups: string;
27875
+ approvalProgressLabel: string;
27729
27876
  cancelApproval: string;
27730
27877
  cancelApprovalInFlight: string;
27731
27878
  cancelApprovalTooltip: string;
@@ -29471,6 +29618,19 @@ export declare const builtInLocales: {
29471
29618
  addEnvironment: string;
29472
29619
  setUpProduction: string;
29473
29620
  addDevelopment: string;
29621
+ entitlement: {
29622
+ productionLimitTitle: string;
29623
+ productionLimitBody: string;
29624
+ planLockedTitle: string;
29625
+ planLockedBody: string;
29626
+ limitTitle: string;
29627
+ limitBody: string;
29628
+ limitBodyWithCount: string;
29629
+ freePlan: string;
29630
+ namedPlan: string;
29631
+ upgradeCta: string;
29632
+ contactSalesCta: string;
29633
+ };
29474
29634
  };
29475
29635
  cloudConnection: {
29476
29636
  checking: string;
@@ -829,6 +829,9 @@ declare const ja: {
829
829
  writeStrippedByState: string;
830
830
  approvalPendingEditable: string;
831
831
  approvalPendingTooltip: string;
832
+ approvalProgress: string;
833
+ approvalProgressGroups: string;
834
+ approvalProgressLabel: string;
832
835
  cancelApproval: string;
833
836
  cancelApprovalInFlight: string;
834
837
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const ja: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -831,6 +831,9 @@ const ja = {
831
831
  writeStrippedByState: "次の項目はこのレコードの現在の状態では編集できないため保存されませんでした: {{fields}}",
832
832
  approvalPendingEditable: "承認中 · 編集可能",
833
833
  approvalPendingTooltip: "このレコードには承認待ちのリクエストがありますが、このステップでは編集できます",
834
+ approvalProgress: "承認 — {{need}} 件中 {{got}} 件",
835
+ approvalProgressGroups: "合議 — {{need}} グループ中 {{got}} グループ",
836
+ approvalProgressLabel: "承認の進捗",
834
837
  cancelApproval: "承認を取り消す",
835
838
  cancelApprovalInFlight: "取り消し中…",
836
839
  cancelApprovalTooltip: "承認待ちリクエストを取り消してレコードのロックを解除する",
@@ -2567,6 +2570,20 @@ const ja = {
2567
2570
  addEnvironment: "環境を追加",
2568
2571
  setUpProduction: "本番環境をセットアップ",
2569
2572
  addDevelopment: "開発環境を追加",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "本番環境はすでに作成済みです",
2576
+ productionLimitBody: "各組織に含まれる本番環境は 1 つだけです。もう 1 つ必要な場合は別の組織を作成するか、エンタープライズ契約についてお問い合わせください。",
2577
+ planLockedTitle: "開発環境は有料機能です",
2578
+ planLockedBody: "{{plan}}には本番環境が 1 つ含まれます。アップグレードすると開発環境を追加できます(開発環境で構築し、本番環境に公開します)。",
2579
+ limitTitle: "開発環境の上限に達しました",
2580
+ limitBody: "上限は AI シート数に応じて増えます。AI シートを追加するか、使用していない開発環境をアーカイブして空きを作ってください。",
2581
+ limitBodyWithCount: "開発環境を {{used}}/{{limit}} 使用中です。上限は AI シート数に応じて増えます。AI シートを追加するか、使用していない開発環境をアーカイブしてください。",
2582
+ freePlan: "無料プラン",
2583
+ namedPlan: "{{plan}} プラン",
2584
+ upgradeCta: "プランをアップグレード",
2585
+ contactSalesCta: "営業に問い合わせる",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "接続を確認しています…",
@@ -818,6 +818,9 @@ declare const ko: {
818
818
  writeStrippedByState: string;
819
819
  approvalPendingEditable: string;
820
820
  approvalPendingTooltip: string;
821
+ approvalProgress: string;
822
+ approvalProgressGroups: string;
823
+ approvalProgressLabel: string;
821
824
  cancelApproval: string;
822
825
  cancelApprovalInFlight: string;
823
826
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const ko: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -820,6 +820,9 @@ const ko = {
820
820
  writeStrippedByState: "다음 필드는 이 레코드의 현재 상태에서 편집할 수 없으므로 저장되지 않았습니다: {{fields}}",
821
821
  approvalPendingEditable: "승인 진행 중 · 편집 가능",
822
822
  approvalPendingTooltip: "이 레코드에 대기 중인 승인 요청이 있지만 이 단계에서는 편집할 수 있습니다",
823
+ approvalProgress: "승인 — {{need}}건 중 {{got}}건",
824
+ approvalProgressGroups: "합의 — {{need}}개 그룹 중 {{got}}개",
825
+ approvalProgressLabel: "승인 진행 상황",
823
826
  cancelApproval: "승인 취소",
824
827
  cancelApprovalInFlight: "취소 중…",
825
828
  cancelApprovalTooltip: "대기 중인 승인 요청을 취소하여 레코드 잠금 해제",
@@ -2567,6 +2570,20 @@ const ko = {
2567
2570
  addEnvironment: "환경 추가",
2568
2571
  setUpProduction: "프로덕션 환경 설정",
2569
2572
  addDevelopment: "개발 환경 추가",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "이미 프로덕션 환경이 있습니다",
2576
+ productionLimitBody: "조직마다 프로덕션 환경은 하나만 포함됩니다. 하나 더 필요하면 별도의 조직을 만들거나 엔터프라이즈 계약에 대해 문의해 주세요.",
2577
+ planLockedTitle: "개발 환경은 유료 기능입니다",
2578
+ planLockedBody: "{{plan}}에는 프로덕션 환경 하나가 포함됩니다. 업그레이드하면 개발 환경을 추가할 수 있습니다 — 개발 환경에서 만들고 프로덕션에 게시하세요.",
2579
+ limitTitle: "개발 환경 한도에 도달했습니다",
2580
+ limitBody: "한도는 AI 좌석 수에 따라 늘어납니다. AI 좌석을 추가하거나 사용하지 않는 개발 환경을 보관하여 자리를 확보하세요.",
2581
+ limitBodyWithCount: "개발 환경을 {{used}}/{{limit}}개 사용 중입니다. 한도는 AI 좌석 수에 따라 늘어납니다 — AI 좌석을 추가하거나 사용하지 않는 개발 환경을 보관하세요.",
2582
+ freePlan: "무료 요금제",
2583
+ namedPlan: "{{plan}} 요금제",
2584
+ upgradeCta: "요금제 업그레이드",
2585
+ contactSalesCta: "영업팀 문의",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "연결을 확인하는 중…",
@@ -820,6 +820,9 @@ declare const pt: {
820
820
  writeStrippedByState: string;
821
821
  approvalPendingEditable: string;
822
822
  approvalPendingTooltip: string;
823
+ approvalProgress: string;
824
+ approvalProgressGroups: string;
825
+ approvalProgressLabel: string;
823
826
  cancelApproval: string;
824
827
  cancelApprovalInFlight: string;
825
828
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const pt: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -822,6 +822,9 @@ const pt = {
822
822
  writeStrippedByState: "Não editável no estado atual deste registro, portanto não foi salvo: {{fields}}",
823
823
  approvalPendingEditable: "Em aprovação · editável",
824
824
  approvalPendingTooltip: "Este registro tem uma solicitação de aprovação pendente; esta etapa ainda permite a edição",
825
+ approvalProgress: "Aprovações — {{got}} de {{need}}",
826
+ approvalProgressGroups: "Assinaturas — {{got}} de {{need}} grupos",
827
+ approvalProgressLabel: "Progresso da aprovação",
825
828
  cancelApproval: "Cancelar aprovação",
826
829
  cancelApprovalInFlight: "Cancelando…",
827
830
  cancelApprovalTooltip: "Cancelar a solicitação de aprovação pendente para desbloquear o registro",
@@ -2567,6 +2570,20 @@ const pt = {
2567
2570
  addEnvironment: "Adicionar ambiente",
2568
2571
  setUpProduction: "Configure seu ambiente de produção",
2569
2572
  addDevelopment: "Adicionar ambiente de desenvolvimento",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "Você já tem seu ambiente de produção",
2576
+ productionLimitBody: "Cada organização inclui exatamente um ambiente de produção. Crie uma organização separada para ter outro, ou fale conosco sobre um acordo Enterprise.",
2577
+ planLockedTitle: "Ambientes de desenvolvimento são um recurso pago",
2578
+ planLockedBody: "Seu {{plan}} inclui um ambiente de produção. Faça upgrade para adicionar ambientes de desenvolvimento — construa em desenvolvimento e depois publique em produção.",
2579
+ limitTitle: "Limite de ambientes de desenvolvimento atingido",
2580
+ limitBody: "A capacidade cresce com os assentos de IA. Adicione um assento de IA, ou arquive um ambiente de desenvolvimento sem uso para liberar espaço.",
2581
+ limitBodyWithCount: "Você está usando {{used}} de {{limit}} ambientes de desenvolvimento. A capacidade cresce com os assentos de IA — adicione um assento de IA, ou arquive um ambiente de desenvolvimento sem uso.",
2582
+ freePlan: "plano gratuito",
2583
+ namedPlan: "plano {{plan}}",
2584
+ upgradeCta: "Fazer upgrade do plano",
2585
+ contactSalesCta: "Falar com vendas",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "Verificando a conexão…",
@@ -831,6 +831,9 @@ declare const ru: {
831
831
  writeStrippedByState: string;
832
832
  approvalPendingEditable: string;
833
833
  approvalPendingTooltip: string;
834
+ approvalProgress: string;
835
+ approvalProgressGroups: string;
836
+ approvalProgressLabel: string;
834
837
  cancelApproval: string;
835
838
  cancelApprovalInFlight: string;
836
839
  cancelApprovalTooltip: string;
@@ -2565,6 +2568,19 @@ declare const ru: {
2565
2568
  addEnvironment: string;
2566
2569
  setUpProduction: string;
2567
2570
  addDevelopment: string;
2571
+ entitlement: {
2572
+ productionLimitTitle: string;
2573
+ productionLimitBody: string;
2574
+ planLockedTitle: string;
2575
+ planLockedBody: string;
2576
+ limitTitle: string;
2577
+ limitBody: string;
2578
+ limitBodyWithCount: string;
2579
+ freePlan: string;
2580
+ namedPlan: string;
2581
+ upgradeCta: string;
2582
+ contactSalesCta: string;
2583
+ };
2568
2584
  };
2569
2585
  cloudConnection: {
2570
2586
  checking: string;
@@ -833,6 +833,9 @@ const ru = {
833
833
  writeStrippedByState: "Поля недоступны для редактирования в текущем состоянии записи, поэтому не сохранены: {{fields}}",
834
834
  approvalPendingEditable: "На согласовании · редактирование доступно",
835
835
  approvalPendingTooltip: "У этой записи есть ожидающий запрос на согласование, но этот шаг всё ещё разрешает редактирование",
836
+ approvalProgress: "Согласования — {{got}} из {{need}}",
837
+ approvalProgressGroups: "Подписи — {{got}} из {{need}} групп",
838
+ approvalProgressLabel: "Ход согласования",
836
839
  cancelApproval: "Отменить согласование",
837
840
  cancelApprovalInFlight: "Отмена…",
838
841
  cancelApprovalTooltip: "Отмените ожидающий запрос на согласование, чтобы разблокировать запись",
@@ -2567,6 +2570,20 @@ const ru = {
2567
2570
  addEnvironment: "Добавить окружение",
2568
2571
  setUpProduction: "Настройте продакшн-окружение",
2569
2572
  addDevelopment: "Добавить окружение разработки",
2573
+ // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2574
+ entitlement: {
2575
+ productionLimitTitle: "У вас уже есть продакшн-окружение",
2576
+ productionLimitBody: "Каждая организация включает ровно одно продакшн-окружение. Создайте отдельную организацию для ещё одного или свяжитесь с нами по поводу условий Enterprise.",
2577
+ planLockedTitle: "Окружения разработки — платная возможность",
2578
+ planLockedBody: "{{plan}} включает одно продакшн-окружение. Перейдите на платный тариф, чтобы добавить окружения разработки: создавайте в разработке, затем публикуйте в продакшн.",
2579
+ limitTitle: "Достигнут лимит окружений разработки",
2580
+ limitBody: "Лимит растёт вместе с числом AI-мест. Добавьте AI-место или заархивируйте неиспользуемое окружение разработки, чтобы освободить место.",
2581
+ limitBodyWithCount: "Используется {{used}} из {{limit}} окружений разработки. Лимит растёт вместе с числом AI-мест — добавьте AI-место или заархивируйте неиспользуемое окружение разработки.",
2582
+ freePlan: "Бесплатный тариф",
2583
+ namedPlan: "Тариф {{plan}}",
2584
+ upgradeCta: "Сменить тариф",
2585
+ contactSalesCta: "Связаться с отделом продаж",
2586
+ },
2570
2587
  },
2571
2588
  cloudConnection: {
2572
2589
  checking: "Проверка подключения…",
@@ -721,6 +721,9 @@ declare const zh: {
721
721
  readonly writeStrippedByState: "以下字段在记录当前状态下不可编辑,未保存:{{fields}}";
722
722
  readonly approvalPendingEditable: "审批中 · 可编辑";
723
723
  readonly approvalPendingTooltip: "该记录有待审批的请求,但当前审批节点仍允许编辑";
724
+ readonly approvalProgress: "审批 — 已通过 {{got}} / 共需 {{need}}";
725
+ readonly approvalProgressGroups: "会签 — 已完成 {{got}} / 共 {{need}} 个组";
726
+ readonly approvalProgressLabel: "审批进度";
724
727
  readonly cancelApproval: "撤回审批";
725
728
  readonly cancelApprovalInFlight: "撤回中…";
726
729
  readonly cancelApprovalTooltip: "撤回当前的待审批请求以解除记录锁定";
@@ -2608,6 +2611,19 @@ declare const zh: {
2608
2611
  readonly addEnvironment: "新建环境";
2609
2612
  readonly setUpProduction: "创建你的生产环境";
2610
2613
  readonly addDevelopment: "新建开发环境";
2614
+ readonly entitlement: {
2615
+ readonly productionLimitTitle: "你已经有生产环境了";
2616
+ readonly productionLimitBody: "每个组织只包含一个生产环境。如果还需要,可以新建一个组织,或者联系我们了解企业版方案。";
2617
+ readonly planLockedTitle: "开发环境是付费功能";
2618
+ readonly planLockedBody: "{{plan}}包含一个生产环境。升级后即可添加开发环境 —— 先在开发环境里搭建,确认无误再发布到生产环境。";
2619
+ readonly limitTitle: "开发环境数量已达上限";
2620
+ readonly limitBody: "容量随 AI 席位增长。增加一个 AI 席位,或归档一个不再使用的开发环境来腾出名额。";
2621
+ readonly limitBodyWithCount: "开发环境已使用 {{used}}/{{limit}} 个。容量随 AI 席位增长 —— 增加一个 AI 席位,或归档一个不再使用的开发环境来腾出名额。";
2622
+ readonly freePlan: "免费版";
2623
+ readonly namedPlan: "{{plan}} 版";
2624
+ readonly upgradeCta: "升级套餐";
2625
+ readonly contactSalesCta: "联系销售";
2626
+ };
2611
2627
  };
2612
2628
  readonly cloudConnection: {
2613
2629
  readonly checking: "正在检查连接…";
@@ -733,6 +733,9 @@ const zh = {
733
733
  writeStrippedByState: '以下字段在记录当前状态下不可编辑,未保存:{{fields}}',
734
734
  approvalPendingEditable: '审批中 · 可编辑',
735
735
  approvalPendingTooltip: '该记录有待审批的请求,但当前审批节点仍允许编辑',
736
+ approvalProgress: '审批 — 已通过 {{got}} / 共需 {{need}}',
737
+ approvalProgressGroups: '会签 — 已完成 {{got}} / 共 {{need}} 个组',
738
+ approvalProgressLabel: '审批进度',
736
739
  cancelApproval: '撤回审批',
737
740
  cancelApprovalInFlight: '撤回中…',
738
741
  cancelApprovalTooltip: '撤回当前的待审批请求以解除记录锁定',
@@ -2648,6 +2651,19 @@ const zh = {
2648
2651
  addEnvironment: '新建环境',
2649
2652
  setUpProduction: '创建你的生产环境',
2650
2653
  addDevelopment: '新建开发环境',
2654
+ entitlement: {
2655
+ productionLimitTitle: '你已经有生产环境了',
2656
+ productionLimitBody: '每个组织只包含一个生产环境。如果还需要,可以新建一个组织,或者联系我们了解企业版方案。',
2657
+ planLockedTitle: '开发环境是付费功能',
2658
+ planLockedBody: '{{plan}}包含一个生产环境。升级后即可添加开发环境 —— 先在开发环境里搭建,确认无误再发布到生产环境。',
2659
+ limitTitle: '开发环境数量已达上限',
2660
+ limitBody: '容量随 AI 席位增长。增加一个 AI 席位,或归档一个不再使用的开发环境来腾出名额。',
2661
+ limitBodyWithCount: '开发环境已使用 {{used}}/{{limit}} 个。容量随 AI 席位增长 —— 增加一个 AI 席位,或归档一个不再使用的开发环境来腾出名额。',
2662
+ freePlan: '免费版',
2663
+ namedPlan: '{{plan}} 版',
2664
+ upgradeCta: '升级套餐',
2665
+ contactSalesCta: '联系销售',
2666
+ },
2651
2667
  },
2652
2668
  cloudConnection: {
2653
2669
  checking: '正在检查连接…',
@@ -185,6 +185,23 @@ export function useObjectLabel() {
185
185
  ? [`reports.${reportName}.${tail}`, `reports.${base}.${tail}`]
186
186
  : [`reports.${reportName}.${tail}`];
187
187
  };
188
+ /**
189
+ * Build suffix candidates for a list-view scoped key.
190
+ *
191
+ * The runtime uses qualified view ids (`<objectName>.<viewName>`) in URLs
192
+ * and metadata records, while translation bundles are keyed by the authored
193
+ * view name under `_views`. Resolve the unqualified name first so every
194
+ * surface can pass its canonical id without leaking the metadata fallback.
195
+ */
196
+ const viewSuffixes = (objectName, viewName, tail) => {
197
+ const objectNames = [objectName, stripNamespace(objectName)];
198
+ const matchedPrefix = objectNames
199
+ .map((name) => `${name}.`)
200
+ .find((prefix) => viewName.startsWith(prefix));
201
+ const shortViewName = matchedPrefix ? viewName.slice(matchedPrefix.length) : viewName;
202
+ const viewNames = shortViewName === viewName ? [viewName] : [shortViewName, viewName];
203
+ return viewNames.flatMap((name) => objectSuffixes(objectName, `_views.${name}.${tail}`));
204
+ };
188
205
  return {
189
206
  /**
190
207
  * Resolve translated object label, falling back to objectDef.label.
@@ -294,14 +311,14 @@ export function useObjectLabel() {
294
311
  * Resolve translated list-view label.
295
312
  * Convention (per @objectstack/spec): `{ns}.objects.{objectName}._views.{viewName}.label`.
296
313
  */
297
- viewLabel: (objectName, viewName, fallback) => resolve(objectSuffixes(objectName, `_views.${viewName}.label`), fallback),
314
+ viewLabel: (objectName, viewName, fallback) => resolve(viewSuffixes(objectName, viewName, 'label'), fallback),
298
315
  /**
299
316
  * Resolve translated list-view description.
300
317
  * Convention: `{ns}.objects.{objectName}._views.{viewName}.description`.
301
318
  */
302
319
  viewDescription: (objectName, viewName, fallback) => {
303
320
  const fb = fallback ?? '';
304
- const resolved = resolve(objectSuffixes(objectName, `_views.${viewName}.description`), fb);
321
+ const resolved = resolve(viewSuffixes(objectName, viewName, 'description'), fb);
305
322
  return resolved || undefined;
306
323
  },
307
324
  /**
@@ -314,10 +331,10 @@ export function useObjectLabel() {
314
331
  if (!fallback)
315
332
  return undefined;
316
333
  const title = fallback.title
317
- ? resolve(objectSuffixes(objectName, `_views.${viewName}.emptyState.title`), fallback.title)
334
+ ? resolve(viewSuffixes(objectName, viewName, 'emptyState.title'), fallback.title)
318
335
  : fallback.title;
319
336
  const message = fallback.message
320
- ? resolve(objectSuffixes(objectName, `_views.${viewName}.emptyState.message`), fallback.message)
337
+ ? resolve(viewSuffixes(objectName, viewName, 'emptyState.message'), fallback.message)
321
338
  : fallback.message;
322
339
  return { ...fallback, title, message };
323
340
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/i18n",
3
- "version": "17.1.0",
3
+ "version": "17.2.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",