Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/30512-plugin-sharing-assignment-rule-locales.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@objectstack/plugin-sharing': patch
---

i18n(plugin-sharing): the assignment rule object ships in all eleven platform languages

Clause-②: no
Metadata-protocol: none

`sys_assignment_rule`, the object an organization authors its own assignment rules in, now carries its label, description, field labels and help, option labels and its "By Object" view name in `zh-CN`, `ja-JP`, `es-ES`, `zh-Hant`, `ar`, `fr`, `pt-BR`, `ru`, `de` and `ko`, so an administrator in any platform language reads Setup → Assignment Rules in their own language instead of English. The object is now listed in the package's extract config, so the existing `check:i18n` bundle check covers it. Its recipient options read the same words as the queue and sharing objects in each language. Part of #30512.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
*/

import { defineStack, type ObjectStackDefinition } from '@objectstack/spec';
import { SysRecordShare, SysSharingRule, SysShareLink, SysQueue, SysQueueMember } from '../src/objects/index.js';
import { SysRecordShare, SysSharingRule, SysShareLink, SysQueue, SysQueueMember, SysAssignmentRule } from '../src/objects/index.js';
import { enObjects } from '../src/translations/en.objects.generated.js';
import { zhCNObjects } from '../src/translations/zh-CN.objects.generated.js';
import { jaJPObjects } from '../src/translations/ja-JP.objects.generated.js';
Expand Down Expand Up @@ -73,7 +73,7 @@ import { sharingPageTranslations } from '../src/translations/pages.js';
* precision: the annotated type is the function's own return type.
*/
const config: ObjectStackDefinition = defineStack({
objects: [SysRecordShare, SysSharingRule, SysShareLink, SysQueue, SysQueueMember] as any,
objects: [SysRecordShare, SysSharingRule, SysShareLink, SysQueue, SysQueueMember, SysAssignmentRule] as any,
pages: [SysQueueDetailPage],
translations: [
{ en: { objects: enObjects, pages: sharingPageTranslations.en } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,5 +343,71 @@ export const arObjects: NonNullable<TranslationData['objects']> = {
label: "حسب قائمة الانتظار"
}
}
},
sys_assignment_rule: {
label: "قاعدة الإسناد",
pluralLabel: "قواعد الإسناد",
description: "ترسل كل سجل جديد يطابق شرطًا إلى قائمة انتظار أو إلى شخص.",
fields: {
organization_id: {
label: "المؤسسة",
help: "المؤسسة التي تنتمي إليها هذه القاعدة."
},
name: {
label: "الاسم",
help: "يعرّف القاعدة. أحرف لاتينية صغيرة وأرقام وشرطات سفلية فقط، ولا يجوز أن يكون اسم قاعدة يوفرها تطبيق مثبّت."
},
label: {
label: "التسمية المعروضة"
},
description: {
label: "الوصف"
},
object_name: {
label: "الكائن",
help: "الكائن الذي ترسل هذه القاعدة سجلاته الجديدة. لا يمكن الإسناد إلا في الكائنات التي لسجلاتها مالك."
},
criteria: {
label: "الشرط",
help: "السجلات الجديدة التي تأخذها هذه القاعدة؛ اتركه فارغًا لتأخذ كل سجل جديد لم تأخذه قاعدة سابقة. يُكتب تعبيرًا على السجل، مثل record.priority == \"high\"."
},
sort_order: {
label: "الترتيب",
help: "عندما يمكن لأكثر من قاعدة من قواعدك أن تأخذ السجل نفسه، تُجرَّب القاعدة ذات الترتيب الأدنى أولًا. تُجرَّب قواعدك دائمًا قبل القواعد التي توفرها التطبيقات المثبّتة."
},
recipient_type: {
label: "الإسناد إلى",
help: "أرسل السجل إلى قائمة انتظار يمكن لأعضائها أخذه، أو مباشرة إلى شخص واحد.",
options: {
queue: "قائمة الانتظار",
user: "المستخدم"
}
},
recipient_id: {
label: "قائمة الانتظار أو المستخدم",
help: "قائمة الانتظار أو الشخص الذي يذهب إليه السجل. يجب أن يكون الشخص عضوًا نشطًا في هذه المؤسسة."
},
strategy: {
label: "اختيار عضو",
help: "لقائمة انتظار: أعطِ السجل مباشرة لعضو واحد، بالتناوب أو باختيار من لديه أقل عمل مفتوح. اتركه فارغًا لإبقاء السجل في قائمة الانتظار حتى يأخذه عضو.",
options: {
round_robin: "بالتناوب",
least_loaded: "الأقل عبئًا"
}
},
load: {
label: "العمل المفتوح",
help: "مطلوب مع «الأقل عبئًا»: السجلات التي تُحتسب عملًا مفتوحًا للعضو، ويُكتب تعبيرًا على السجل، مثل record.status != \"closed\"."
},
active: {
label: "نشِط",
help: "أوقفه لتتوقف هذه القاعدة عن إسناد السجلات الجديدة دون حذفها."
}
},
_views: {
by_object: {
label: "حسب الكائن"
}
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const OWNED_OBJECTS = new Set([
'sys_share_link',
'sys_queue',
'sys_queue_member',
'sys_assignment_rule',
]);

describe('objects translation bundle ownership (ADR-0029 D8)', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,5 +343,71 @@ export const deObjects: NonNullable<TranslationData['objects']> = {
label: "Nach Warteschlange"
}
}
},
sys_assignment_rule: {
label: "Zuweisungsregel",
pluralLabel: "Zuweisungsregeln",
description: "Sendet jeden neuen Datensatz, der eine Bedingung erfüllt, an eine Warteschlange oder an eine Person.",
fields: {
organization_id: {
label: "Organisation",
help: "Die Organisation, zu der diese Regel gehört."
},
name: {
label: "Name",
help: "Kennzeichnet die Regel. Nur Kleinbuchstaben, Ziffern und Unterstriche, und nicht der Name einer Regel, die eine installierte App bereitstellt."
},
label: {
label: "Anzeigebezeichnung"
},
description: {
label: "Beschreibung"
},
object_name: {
label: "Objekt",
help: "Das Objekt, dessen neue Datensätze diese Regel weiterleitet. Zuweisen lassen sich nur Objekte, deren Datensätze einen Besitzer haben."
},
criteria: {
label: "Bedingung",
help: "Welche neuen Datensätze diese Regel übernimmt; leer lassen, um jeden neuen Datensatz zu übernehmen, den keine frühere Regel übernommen hat. Geschrieben als Ausdruck über den Datensatz, zum Beispiel record.priority == \"high\"."
},
sort_order: {
label: "Reihenfolge",
help: "Wenn mehrere Ihrer Regeln denselben Datensatz übernehmen könnten, wird die mit der niedrigsten Reihenfolge zuerst versucht. Ihre Regeln werden immer vor den Regeln installierter Apps versucht."
},
recipient_type: {
label: "Zuweisen an",
help: "Sendet den Datensatz an eine Warteschlange, aus der ihre Mitglieder ihn übernehmen können, oder direkt an eine Person.",
options: {
queue: "Warteschlange",
user: "Benutzer"
}
},
recipient_id: {
label: "Warteschlange oder Benutzer",
help: "Die Warteschlange oder die Person, an die der Datensatz geht. Eine Person muss ein aktives Mitglied dieser Organisation sein."
},
strategy: {
label: "Mitglied auswählen",
help: "Für eine Warteschlange: gibt den Datensatz direkt einem Mitglied, reihum oder dem Mitglied mit der wenigsten offenen Arbeit. Leer lassen, damit der Datensatz in der Warteschlange bleibt, bis ein Mitglied ihn übernimmt.",
options: {
round_robin: "Reihum",
least_loaded: "Geringste Auslastung"
}
},
load: {
label: "Offene Arbeit",
help: "Erforderlich bei „Geringste Auslastung“: welche Datensätze als offene Arbeit eines Mitglieds zählen, geschrieben als Ausdruck über den Datensatz, zum Beispiel record.status != \"closed\"."
},
active: {
label: "Aktiv",
help: "Ausschalten, damit diese Regel keine neuen Datensätze mehr zuweist, ohne sie zu löschen."
}
},
_views: {
by_object: {
label: "Nach Objekt"
}
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

export const deGeneratedSourceHashes: Readonly<Record<string, string>> = {
"objects.sys_assignment_rule.fields.name.label": "5274417ff1ccaf01",
"objects.sys_queue.fields.name.label": "5274417ff1ccaf01",
"objects.sys_queue_member.fields.recipient_type.options.position": "9a24c02e441eb0b4",
"objects.sys_queue_member.fields.recipient_type.options.team": "42b87165ac826b2b",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,5 +343,71 @@ export const enObjects: NonNullable<TranslationData['objects']> = {
label: "By Queue"
}
}
},
sys_assignment_rule: {
label: "Assignment Rule",
pluralLabel: "Assignment Rules",
description: "Sends each new record that matches a condition to a queue or a person.",
fields: {
organization_id: {
label: "Organization",
help: "The organization this rule belongs to."
},
name: {
label: "Name",
help: "Identifies the rule. Lowercase letters, digits and underscores only, and not the name of a rule an installed app provides."
},
label: {
label: "Display Label"
},
description: {
label: "Description"
},
object_name: {
label: "Object",
help: "The object whose new records this rule sends somewhere. Only objects whose records have an owner can be assigned."
},
criteria: {
label: "Condition",
help: "Which new records this rule takes; leave it empty to take every new record that no earlier rule took. Written as an expression over the record — for example record.priority == \"high\"."
},
sort_order: {
label: "Order",
help: "When several of your rules could take the same record, the one with the lowest order is tried first. Your rules are always tried before the rules installed apps provide."
},
recipient_type: {
label: "Assign To",
help: "Send the record to a queue, where its members can take it, or straight to one person.",
options: {
queue: "Queue",
user: "User"
}
},
recipient_id: {
label: "Queue or User",
help: "The queue, or the person, the record goes to. A person must be an active member of this organization."
},
strategy: {
label: "Pick a Member",
help: "For a queue: give the record straight to one member, taking turns or choosing whoever has the least open work. Leave it empty to leave the record in the queue until a member takes it.",
options: {
round_robin: "Round robin",
least_loaded: "Least loaded"
}
},
load: {
label: "Open Work",
help: "Required for \"Least loaded\": which records count as a member's open work, written as an expression over the record — for example record.status != \"closed\"."
},
active: {
label: "Active",
help: "Turn off to stop this rule from assigning new records, without deleting it."
}
},
_views: {
by_object: {
label: "By Object"
}
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -343,5 +343,71 @@ export const esESObjects: NonNullable<TranslationData['objects']> = {
label: "By Queue"
}
}
},
sys_assignment_rule: {
label: "Regla de asignación",
pluralLabel: "Reglas de asignación",
description: "Envía cada registro nuevo que cumple una condición a una cola o a una persona.",
fields: {
organization_id: {
label: "Organización",
help: "La organización a la que pertenece esta regla."
},
name: {
label: "Nombre",
help: "Identifica la regla. Solo letras minúsculas, dígitos y guiones bajos, y no puede ser el nombre de una regla que proporcione una aplicación instalada."
},
label: {
label: "Nombre visible"
},
description: {
label: "Descripción"
},
object_name: {
label: "Objeto",
help: "El objeto cuyos registros nuevos envía esta regla. Solo se pueden asignar los objetos cuyos registros tienen propietario."
},
criteria: {
label: "Condición",
help: "Qué registros nuevos toma esta regla; déjela vacía para tomar todos los registros nuevos que ninguna regla anterior haya tomado. Se escribe como una expresión sobre el registro, por ejemplo record.priority == \"high\"."
},
sort_order: {
label: "Orden",
help: "Cuando varias de sus reglas pueden tomar el mismo registro, se prueba primero la de menor orden. Sus reglas siempre se prueban antes que las que proporcionan las aplicaciones instaladas."
},
recipient_type: {
label: "Asignar a",
help: "Envía el registro a una cola, donde sus miembros pueden tomarlo, o directamente a una persona.",
options: {
queue: "Cola",
user: "Usuario"
}
},
recipient_id: {
label: "Cola o usuario",
help: "La cola, o la persona, a la que va el registro. Una persona debe ser un miembro activo de esta organización."
},
strategy: {
label: "Elegir un miembro",
help: "Para una cola: entrega el registro directamente a un miembro, por turnos o eligiendo a quien tenga menos trabajo abierto. Déjelo vacío para que el registro permanezca en la cola hasta que un miembro lo tome.",
options: {
round_robin: "Por turnos",
least_loaded: "Menor carga"
}
},
load: {
label: "Trabajo abierto",
help: "Obligatorio con «Menor carga»: qué registros cuentan como trabajo abierto de un miembro, escrito como una expresión sobre el registro, por ejemplo record.status != \"closed\"."
},
active: {
label: "Activo",
help: "Desactívela para que esta regla deje de asignar registros nuevos, sin eliminarla."
}
},
_views: {
by_object: {
label: "Por objeto"
}
}
}
};
Loading
Loading