scripts/merge-schedule-translations.js
Rama main · réplica de lectura del repositorio original.
const fs = require('fs');
const path = require('path');
const LOCALES_DIR = path.join(__dirname, '..', 'worklenz-frontend', 'public', 'locales');
const SOURCE_LANG = 'en';
const TARGET_LANGS = ['es', 'de', 'pt', 'zh', 'alb'];
function readJson(filePath) {
try {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (e) {
console.error(`Error reading ${filePath}:`, e.message);
return null;
}
}
function writeJson(filePath, obj) {
fs.writeFileSync(filePath, JSON.stringify(obj, null, 2) + '\n');
console.log(`Updated: ${filePath}`);
}
const source = readJson(path.join(LOCALES_DIR, SOURCE_LANG, 'schedule.json'));
if (!source) {
console.error('Could not read English schedule.json');
process.exit(1);
}
const translations = {
es: {
workloadManagement: 'Gestión de Carga de Trabajo',
resourceManagement: 'Gestión de Recursos',
timeTracking: 'Seguimiento de Tiempo',
capacityPlanning: 'Planificación de Capacidad',
loadBalancing: 'Equilibrio de Carga',
overview: 'Resumen',
allocation: 'Asignación de Recursos',
balancing: 'Equilibrio de Carga',
utilization: 'Utilización',
available: 'Disponible',
normal: 'Normal',
fullyAllocated: 'Totalmente Asignado',
overAllocated: 'Sobreasignado',
unknown: 'Desconocido',
actions: 'Acciones',
manage: 'Gestionar',
rebalance: 'Redistribuir',
allocatedHours: 'Horas Asignadas',
percentage: 'Porcentaje',
duration: 'Duración',
notSet: 'No establecido',
rebalanceWorkload: 'Redistribuir Carga de Trabajo',
rebalanceConfirm: 'Esto redistribuirá automáticamente las tareas para optimizar la carga de trabajo. ¿Continuar?',
workloadRebalanced: 'Carga de trabajo redistribuida con éxito',
totalMembers: 'Total Miembros',
refresh: 'Actualizar',
selectMember: 'Seleccionar Miembro',
chooseMember: 'Elegir miembro',
autoBalancing: 'Equilibrio Automático de Carga',
autoBalancingDesc: 'Redistribuir automáticamente la carga de trabajo entre los miembros del equipo para optimizar el uso de recursos.',
rebalanceAll: 'Redistribuir Todo',
previewChanges: 'Vista Previa de Cambios',
balancingRules: 'Reglas de Equilibrio',
maxUtilization: 'Utilización Máxima (%)',
balancingStrategy: 'Estrategia de Equilibrio',
evenDistribution: 'Distribución Uniforme',
skillsBased: 'Basado en Habilidades',
priorityBased: 'Basado en Prioridad',
timeTrackingFeature: 'Función de Seguimiento de Tiempo',
timeTrackingDesc: 'Registra el tiempo dedicado a tareas y proyectos. Visualiza informes detallados y análisis.',
capacityPlanningDesc: 'Planifica la capacidad de recursos para proyectos próximos e identifica posibles cuellos de botella.',
comingSoon: 'Próximamente...',
weekend: 'Fin de semana',
status: 'Estado',
workloadStatus: 'Estado de Carga de Trabajo',
teamOverview: 'Resumen del Equipo',
resourceConflicts: 'Conflictos de Recursos',
scheduleConflicts: 'Conflictos de Horario',
overallocation: 'Sobreasignación',
underutilized: 'Subutilizado',
optimizeWorkload: 'Optimizar Carga de Trabajo',
viewDetails: 'Ver Detalles',
ganttView: 'Vista Gantt',
listView: 'Vista de Lista',
timelineView: 'Vista de Línea de Tiempo',
zoomIn: 'Acercar',
zoomOut: 'Alejar',
fitToScreen: 'Ajustar a Pantalla',
exportSchedule: 'Exportar Horario',
printSchedule: 'Imprimir Horario',
fullscreen: 'Pantalla Completa',
exitFullscreen: 'Salir de Pantalla Completa',
showWeekends: 'Mostrar Fines de Semana',
hideWeekends: 'Ocultar Fines de Semana',
viewSettings: 'Configuración de Vista',
colorLegend: 'Leyenda de Colores',
criticalPath: 'Ruta Crítica',
dependencies: 'Dependencias',
milestones: 'Hitos',
baseline: 'Línea Base',
progress: 'Progreso',
variance: 'Variación',
schedule: 'Horario',
noDataAvailable: 'No hay datos disponibles',
rebalanceError: 'Error al redistribuir la carga de trabajo',
allocationUpdated: 'Asignación actualizada con éxito',
allocationError: 'Error al actualizar la asignación',
zoomLevel: 'Nivel de Zoom',
loadingData: 'Cargando datos...',
loading: 'Cargando...',
previous: 'Anterior',
current: 'Actual',
next: 'Siguiente',
allRoles: 'Rol: Todos los roles',
allMembers: 'Todos los miembros',
allProjects: 'Todos los proyectos',
allClients: 'Todos los clientes',
viewOptions: 'Opciones de vista',
moreFilters: 'Más filtros',
allStatuses: 'Todos los estados',
allPriorities: 'Todas las prioridades',
allCategories: 'Todas las categorías',
noDatesSet: 'Sin fechas establecidas',
loadTooltipTitle: 'Carga',
loadTooltipFormula: 'Total de horas programadas en este proyecto durante el período.',
loadTooltipBar: 'La barra del {{pct}}% es relativa al proyecto más ocupado mostrado aquí, no a un objetivo fijo.',
exceedsWorkingHours: 'Excede las horas de trabajo',
estHoursPerDay: 'Horas Estimadas',
phase: 'Fase',
assignees: 'Asignados',
type: 'Tipo',
projectBlock: 'Bloque de proyecto',
assignee: 'Asignado',
dates: 'Fechas',
workloadSettings: 'Configuración de carga de trabajo',
timelineEmptyFilteredTitle: 'Estás al día aquí',
timelineEmptyTitle: 'Nada que mostrar todavía',
timelineEmptyFilteredDesc: 'No hay proyectos que coincidan con los filtros actuales. Intenta ampliar Proyectos, Estado, Prioridad, Categoría o Clientes.',
timelineEmptyProjectsDesc: 'No hay proyectos para mostrar todavía.',
clearFilters: 'Limpiar filtros',
workloadEmptyFilteredTitle: 'Estás al día aquí',
workloadEmptyTitle: 'Nada que mostrar todavía',
workloadEmptyFilteredDesc: 'Nadie coincide con los filtros actuales. Intenta ampliar Estado del Proyecto, Prioridad o Utilización.',
workloadEmptyMembersDesc: 'No hay miembros del equipo para mostrar todavía.',
workloadEmptyProjectsDesc: 'No hay proyectos para mostrar todavía.',
allProjectStatuses: 'Estado del Proyecto',
allProjectPriorities: 'Prioridad del Proyecto',
allUtilLevels: 'Utilización',
},
de: {
workloadManagement: 'Arbeitsauslastungsverwaltung',
resourceManagement: 'Ressourcenverwaltung',
timeTracking: 'Zeiterfassung',
capacityPlanning: 'Kapazitätsplanung',
loadBalancing: 'Lastverteilung',
overview: 'Übersicht',
allocation: 'Ressourcenverteilung',
balancing: 'Lastausgleich',
utilization: 'Auslastung',
available: 'Verfügbar',
normal: 'Normal',
fullyAllocated: 'Voll ausgelastet',
overAllocated: 'Überlastet',
unknown: 'Unbekannt',
actions: 'Aktionen',
manage: 'Verwalten',
rebalance: 'Neu verteilen',
allocatedHours: 'Zugewiesene Stunden',
percentage: 'Prozentsatz',
duration: 'Dauer',
notSet: 'Nicht festgelegt',
rebalanceWorkload: 'Arbeitsauslastung neu verteilen',
rebalanceConfirm: 'Dadurch werden Aufgaben automatisch neu verteilt, um die Arbeitsauslastung zu optimieren. Fortfahren?',
workloadRebalanced: 'Arbeitsauslastung erfolgreich neu verteilt',
totalMembers: 'Mitglieder insgesamt',
refresh: 'Aktualisieren',
selectMember: 'Mitglied auswählen',
chooseMember: 'Mitglied wählen',
autoBalancing: 'Automatischer Lastausgleich',
autoBalancingDesc: 'Automatische Neuverteilung der Arbeitsauslastung zwischen Teammitgliedern zur Optimierung der Ressourcennutzung.',
rebalanceAll: 'Alle neu verteilen',
previewChanges: 'Änderungen anzeigen',
balancingRules: 'Lastverteilungsregeln',
maxUtilization: 'Maximale Auslastung (%)',
balancingStrategy: 'Lastverteilungsstrategie',
evenDistribution: 'Gleichmäßige Verteilung',
skillsBased: 'Kompetenzbasiert',
priorityBased: 'Prioritätsbasiert',
timeTrackingFeature: 'Zeiterfassungsfunktion',
timeTrackingDesc: 'Erfassen Sie die für Aufgaben und Projekte aufgewendete Zeit. Sehen Sie sich detaillierte Berichte und Analysen an.',
capacityPlanningDesc: 'Planen Sie die Ressourcenkapazität für zukünftige Projekte und identifizieren Sie mögliche Engpässe.',
comingSoon: 'Demnächst...',
weekend: 'Wochenende',
status: 'Status',
workloadStatus: 'Arbeitsauslastungsstatus',
teamOverview: 'Teamübersicht',
resourceConflicts: 'Ressourcenkonflikte',
scheduleConflicts: 'Terminüberschneidungen',
overallocation: 'Überlastung',
underutilized: 'Unterausgelastet',
optimizeWorkload: 'Arbeitsauslastung optimieren',
viewDetails: 'Details anzeigen',
ganttView: 'Gantt-Ansicht',
listView: 'Listenansicht',
timelineView: 'Zeitachsenansicht',
zoomIn: 'Vergrößern',
zoomOut: 'Verkleinern',
fitToScreen: 'An Bildschirm anpassen',
exportSchedule: 'Zeitplan exportieren',
printSchedule: 'Zeitplan drucken',
fullscreen: 'Vollbild',
exitFullscreen: 'Vollbild beenden',
showWeekends: 'Wochenenden anzeigen',
hideWeekends: 'Wochenenden ausblenden',
viewSettings: 'Anzeigeeinstellungen',
colorLegend: 'Farblegende',
criticalPath: 'Kritischer Pfad',
dependencies: 'Abhängigkeiten',
milestones: 'Meilensteine',
baseline: 'Basislinie',
progress: 'Fortschritt',
variance: 'Abweichung',
schedule: 'Zeitplan',
noDataAvailable: 'Keine Daten verfügbar',
rebalanceError: 'Fehler beim Neuverteilen der Arbeitsauslastung',
allocationUpdated: 'Zuweisung erfolgreich aktualisiert',
allocationError: 'Fehler beim Aktualisieren der Zuweisung',
zoomLevel: 'Zoomstufe',
loadingData: 'Daten werden geladen...',
loading: 'Laden...',
previous: 'Zurück',
current: 'Aktuell',
next: 'Weiter',
allRoles: 'Rolle: Alle Rollen',
allMembers: 'Alle Mitglieder',
allProjects: 'Alle Projekte',
allClients: 'Alle Kunden',
viewOptions: 'Anzeigeoptionen',
moreFilters: 'Weitere Filter',
allStatuses: 'Alle Status',
allPriorities: 'Alle Prioritäten',
allCategories: 'Alle Kategorien',
noDatesSet: 'Keine Daten festgelegt',
loadTooltipTitle: 'Last',
loadTooltipFormula: 'Gesamte für dieses Projekt im Zeitraum geplante Stunden.',
loadTooltipBar: 'Der {{pct}}%-Balken bezieht sich auf das hier angezeigte ausgelastetste Projekt, nicht auf ein festes Ziel.',
exceedsWorkingHours: 'Überschreitet die Arbeitsstunden',
estHoursPerDay: 'Geschätzte Stunden',
phase: 'Phase',
assignees: 'Zugewiesene',
type: 'Typ',
projectBlock: 'Projektblock',
assignee: 'Zugewiesene Person',
dates: 'Daten',
workloadSettings: 'Arbeitsauslastungseinstellungen',
timelineEmptyFilteredTitle: 'Du bist auf dem neuesten Stand',
timelineEmptyTitle: 'Noch nichts zu sehen',
timelineEmptyFilteredDesc: 'Keine Projekte entsprechen den aktuellen Filtern. Versuche, Projekte, Status, Priorität, Kategorie oder Kunden zu erweitern.',
timelineEmptyProjectsDesc: 'Noch keine Projekte zum Anzeigen.',
clearFilters: 'Filter löschen',
workloadEmptyFilteredTitle: 'Du bist auf dem neuesten Stand',
workloadEmptyTitle: 'Noch nichts zu sehen',
workloadEmptyFilteredDesc: 'Niemand entspricht den aktuellen Filtern. Versuche, Projektstatus, Priorität oder Auslastung zu erweitern.',
workloadEmptyMembersDesc: 'Noch keine Teammitglieder zum Anzeigen.',
workloadEmptyProjectsDesc: 'Noch keine Projekte zum Anzeigen.',
allProjectStatuses: 'Projektstatus',
allProjectPriorities: 'Projektpriorität',
allUtilLevels: 'Auslastung',
},
pt: {
workloadManagement: 'Gestão de Carga de Trabalho',
resourceManagement: 'Gestão de Recursos',
timeTracking: 'Controlo de Tempo',
capacityPlanning: 'Planeamento de Capacidade',
loadBalancing: 'Balanceamento de Carga',
overview: 'Visão Geral',
allocation: 'Atribuição de Recursos',
balancing: 'Balanceamento',
utilization: 'Utilização',
available: 'Disponível',
normal: 'Normal',
fullyAllocated: 'Totalmente Atribuído',
overAllocated: 'Sobreatribuído',
unknown: 'Desconhecido',
actions: 'Ações',
manage: 'Gerir',
rebalance: 'Redistribuir',
allocatedHours: 'Horas Atribuídas',
percentage: 'Percentagem',
duration: 'Duração',
notSet: 'Não definido',
rebalanceWorkload: 'Redistribuir Carga de Trabalho',
rebalanceConfirm: 'Isto irá redistribuir automaticamente as tarefas para otimizar a carga de trabalho. Continuar?',
workloadRebalanced: 'Carga de trabalho redistribuída com sucesso',
totalMembers: 'Total de Membros',
refresh: 'Atualizar',
selectMember: 'Selecionar Membro',
chooseMember: 'Escolher membro',
autoBalancing: 'Balanceamento Automático de Carga',
autoBalancingDesc: 'Redistribua automaticamente a carga de trabalho entre os membros da equipa para otimizar a utilização de recursos.',
rebalanceAll: 'Redistribuir Tudo',
previewChanges: 'Pré-visualizar Alterações',
balancingRules: 'Regras de Balanceamento',
maxUtilization: 'Utilização Máxima (%)',
balancingStrategy: 'Estratégia de Balanceamento',
evenDistribution: 'Distribuição Uniforme',
skillsBased: 'Baseado em Competências',
priorityBased: 'Baseado em Prioridade',
timeTrackingFeature: 'Funcionalidade de Controlo de Tempo',
timeTrackingDesc: 'Registe o tempo gasto em tarefas e projetos. Visualize relatórios detalhados e análises.',
capacityPlanningDesc: 'Planeie a capacidade de recursos para projetos futuros e identifique possíveis gargalos.',
comingSoon: 'Em breve...',
weekend: 'Fim de semana',
status: 'Estado',
workloadStatus: 'Estado da Carga de Trabalho',
teamOverview: 'Visão Geral da Equipa',
resourceConflicts: 'Conflitos de Recursos',
scheduleConflicts: 'Conflitos de Agenda',
overallocation: 'Sobreatribuição',
underutilized: 'Subutilizado',
optimizeWorkload: 'Otimizar Carga de Trabalho',
viewDetails: 'Ver Detalhes',
ganttView: 'Vista Gantt',
listView: 'Vista de Lista',
timelineView: 'Vista de Cronograma',
zoomIn: 'Aumentar',
zoomOut: 'Diminuir',
fitToScreen: 'Ajustar ao Ecrã',
exportSchedule: 'Exportar Agenda',
printSchedule: 'Imprimir Agenda',
fullscreen: 'Ecrã Inteiro',
exitFullscreen: 'Sair do Ecrã Inteiro',
showWeekends: 'Mostrar Fins de Semana',
hideWeekends: 'Ocultar Fins de Semana',
viewSettings: 'Definições de Visualização',
colorLegend: 'Legenda de Cores',
criticalPath: 'Caminho Crítico',
dependencies: 'Dependências',
milestones: 'Marcos',
baseline: 'Linha de Base',
progress: 'Progresso',
variance: 'Variância',
schedule: 'Agenda',
noDataAvailable: 'Sem dados disponíveis',
rebalanceError: 'Erro ao redistribuir carga de trabalho',
allocationUpdated: 'Atribuição atualizada com sucesso',
allocationError: 'Erro ao atualizar atribuição',
zoomLevel: 'Nível de Zoom',
loadingData: 'A carregar dados...',
loading: 'A carregar...',
previous: 'Anterior',
current: 'Atual',
next: 'Seguinte',
allRoles: 'Função: Todas as funções',
allMembers: 'Todos os membros',
allProjects: 'Todos os projetos',
allClients: 'Todos os clientes',
viewOptions: 'Opções de visualização',
moreFilters: 'Mais filtros',
allStatuses: 'Todos os estados',
allPriorities: 'Todas as prioridades',
allCategories: 'Todas as categorias',
noDatesSet: 'Sem datas definidas',
loadTooltipTitle: 'Carga',
loadTooltipFormula: 'Total de horas agendadas neste projeto durante o período.',
loadTooltipBar: 'A barra de {{pct}}% é relativa ao projeto mais ocupado aqui, não a um alvo fixo.',
exceedsWorkingHours: 'Excede as horas de trabalho',
estHoursPerDay: 'Horas Estimadas',
phase: 'Fase',
assignees: 'Atribuídos',
type: 'Tipo',
projectBlock: 'Bloqueio de projeto',
assignee: 'Atribuído',
dates: 'Datas',
workloadSettings: 'Definições de carga de trabalho',
timelineEmptyFilteredTitle: 'Estás em dia aqui',
timelineEmptyTitle: 'Nada para mostrar ainda',
timelineEmptyFilteredDesc: 'Nenhum projeto corresponde aos filtros atuais. Tenta ampliar Projetos, Estado, Prioridade, Categoria ou Clientes.',
timelineEmptyProjectsDesc: 'Ainda não há projetos para mostrar.',
clearFilters: 'Limpar filtros',
workloadEmptyFilteredTitle: 'Estás em dia aqui',
workloadEmptyTitle: 'Nada para mostrar ainda',
workloadEmptyFilteredDesc: 'Ninguém corresponde aos filtros atuais. Tenta ampliar Estado do Projeto, Prioridade ou Utilização.',
workloadEmptyMembersDesc: 'Ainda não há membros da equipa para mostrar.',
workloadEmptyProjectsDesc: 'Ainda não há projetos para mostrar.',
allProjectStatuses: 'Estado do Projeto',
allProjectPriorities: 'Prioridade do Projeto',
allUtilLevels: 'Utilização',
},
zh: {
workloadManagement: '工作负载管理',
resourceManagement: '资源管理',
timeTracking: '时间跟踪',
capacityPlanning: '产能规划',
loadBalancing: '负载均衡',
overview: '概览',
allocation: '资源分配',
balancing: '负载均衡',
utilization: '利用率',
available: '可用',
normal: '正常',
fullyAllocated: '已满负荷',
overAllocated: '超负荷',
unknown: '未知',
actions: '操作',
manage: '管理',
rebalance: '重新平衡',
allocatedHours: '分配时长',
percentage: '百分比',
duration: '持续时间',
notSet: '未设置',
rebalanceWorkload: '重新平衡工作负载',
rebalanceConfirm: '这将自动重新分配任务以优化工作负载。是否继续?',
workloadRebalanced: '工作负载已成功重新平衡',
totalMembers: '成员总数',
refresh: '刷新',
selectMember: '选择成员',
chooseMember: '选择成员',
autoBalancing: '自动负载均衡',
autoBalancingDesc: '在团队成员之间自动重新分配工作负载,以优化资源利用率。',
rebalanceAll: '全部重新平衡',
previewChanges: '预览更改',
balancingRules: '平衡规则',
maxUtilization: '最大利用率 (%)',
balancingStrategy: '平衡策略',
evenDistribution: '均匀分配',
skillsBased: '基于技能',
priorityBased: '基于优先级',
timeTrackingFeature: '时间跟踪功能',
timeTrackingDesc: '跟踪任务和项目所花费的时间。查看详细报告和分析。',
capacityPlanningDesc: '为即将到来的项目规划资源容量,并识别潜在瓶颈。',
comingSoon: '即将推出...',
weekend: '周末',
status: '状态',
workloadStatus: '工作负载状态',
teamOverview: '团队概览',
resourceConflicts: '资源冲突',
scheduleConflicts: '日程冲突',
overallocation: '超额分配',
underutilized: '利用不足',
optimizeWorkload: '优化工作负载',
viewDetails: '查看详情',
ganttView: '甘特图视图',
listView: '列表视图',
timelineView: '时间线视图',
zoomIn: '放大',
zoomOut: '缩小',
fitToScreen: '适应屏幕',
exportSchedule: '导出日程',
printSchedule: '打印日程',
fullscreen: '全屏',
exitFullscreen: '退出全屏',
showWeekends: '显示周末',
hideWeekends: '隐藏周末',
viewSettings: '视图设置',
colorLegend: '颜色图例',
criticalPath: '关键路径',
dependencies: '依赖关系',
milestones: '里程碑',
baseline: '基线',
progress: '进度',
variance: '偏差',
schedule: '日程',
noDataAvailable: '无可用数据',
rebalanceError: '重新平衡工作负载失败',
allocationUpdated: '分配已成功更新',
allocationError: '更新分配失败',
zoomLevel: '缩放级别',
loadingData: '正在加载数据...',
loading: '正在加载...',
previous: '上一个',
current: '当前',
next: '下一个',
allRoles: '角色:所有角色',
allMembers: '所有成员',
allProjects: '所有项目',
allClients: '所有客户',
viewOptions: '视图选项',
moreFilters: '更多筛选',
allStatuses: '所有状态',
allPriorities: '所有优先级',
allCategories: '所有类别',
noDatesSet: '未设置日期',
loadTooltipTitle: '负载',
loadTooltipFormula: '该周期内此项目安排的总时长。',
loadTooltipBar: '{{pct}}% 的条形图是相对于此处显示的最忙项目,而非固定目标。',
exceedsWorkingHours: '超出工作时长',
estHoursPerDay: '预估工时',
phase: '阶段',
assignees: '指派人员',
type: '类型',
projectBlock: '项目块',
assignee: '指派人员',
dates: '日期',
workloadSettings: '工作负载设置',
timelineEmptyFilteredTitle: '此处已无遗漏',
timelineEmptyTitle: '暂无内容',
timelineEmptyFilteredDesc: '没有项目符合当前筛选条件。请尝试扩大项目、状态、优先级、类别或客户范围。',
timelineEmptyProjectsDesc: '暂无项目可显示。',
clearFilters: '清除筛选',
workloadEmptyFilteredTitle: '此处已无遗漏',
workloadEmptyTitle: '暂无内容',
workloadEmptyFilteredDesc: '没有人员符合当前筛选条件。请尝试扩大项目状态、优先级或利用率范围。',
workloadEmptyMembersDesc: '暂无团队成员可显示。',
workloadEmptyProjectsDesc: '暂无项目可显示。',
allProjectStatuses: '项目状态',
allProjectPriorities: '项目优先级',
allUtilLevels: '利用率',
},
alb: {
workloadManagement: 'Menaxhimi i Ngarkesës së Punës',
resourceManagement: 'Menaxhimi i Burimeve',
timeTracking: 'Ndjekja e Kohës',
capacityPlanning: 'Planifikimi i Kapacitetit',
loadBalancing: 'Balancimi i Ngarkesës',
overview: 'Përmbledhje',
allocation: 'Shpërndarja e Burimeve',
balancing: 'Balancimi',
utilization: 'Përdorimi',
available: 'I disponueshëm',
normal: 'Normal',
fullyAllocated: 'I plotësisht shpërndarë',
overAllocated: 'Mbivendosur',
unknown: 'I panjohur',
actions: 'Veprimet',
manage: 'Menaxho',
rebalance: 'Ribalanso',
allocatedHours: 'Orët e shpërndara',
percentage: 'Përqindja',
duration: 'Kohëzgjatja',
notSet: 'E pacaktuar',
rebalanceWorkload: 'Ribalanso Ngarkesën e Punës',
rebalanceConfirm: 'Kjo do të ridistribojë automatikisht detyrat për të optimizuar ngarkesën e punës. Vazhdoni?',
workloadRebalanced: 'Ngarkesa e punës u ribalansua me sukses',
totalMembers: 'Anëtarët në total',
refresh: 'Rifresko',
selectMember: 'Zgjidh Anëtar',
chooseMember: 'Zgjidh anëtar',
autoBalancing: 'Balancim Automatik i Ngarkesës',
autoBalancingDesc: 'Ridistribuo automatikisht ngarkesën e punës në mes anëtarëve të ekipit për të optimizuar përdorimin e burimeve.',
rebalanceAll: 'Ribalanso të Gjitha',
previewChanges: 'Parashi Ndryshimet',
balancingRules: 'Rregullat e Balancimit',
maxUtilization: 'Përdorimi Maksimum (%)',
balancingStrategy: 'Strategjia e Balancimit',
evenDistribution: 'Shpërndarje E Barabartë',
skillsBased: 'Bazuar në Aftësitë',
priorityBased: 'Bazuar në Prioritet',
timeTrackingFeature: 'Karakteristika e Ndjekjes së Kohës',
timeTrackingDesc: 'Gjuroni kohën e shpenzuar në detyra dhe projekte. Shikoni raporte të detajuara dhe analiza.',
capacityPlanningDesc: 'Planifikoni kapacitetin e burimeve për projektet e ardhshme dhe identifikoni potentialin bllokadesh.',
comingSoon: 'Së shpejti...',
weekend: 'Fundjavë',
status: 'Statusi',
workloadStatus: 'Statusi i Ngarkesës së Punës',
teamOverview: 'Përmbledhja e Ekipit',
resourceConflicts: 'Konflikte të Burimeve',
scheduleConflicts: 'Konflikte të Orarit',
overallocation: 'Mbivendosje',
underutilized: 'I përdorur pak',
optimizeWorkload: 'Optimizo Ngarkesën e Punës',
viewDetails: 'Shiko Detajet',
ganttView: 'Pamja Gantt',
listView: 'Pamja e Listës',
timelineView: 'Pamja e Kohës',
zoomIn: 'Zmadho',
zoomOut: 'Zvogëlo',
fitToScreen: 'Përshtat në Ekran',
exportSchedule: 'Eksporto Orarin',
printSchedule: 'Shtyp Orarin',
fullscreen: 'Ekran i Plotë',
exitFullscreen: 'Dil nga Ekrani i Plotë',
showWeekends: 'Shfaq Fundjavët',
hideWeekends: 'Fshih Fundjavët',
viewSettings: 'Cilësimet e Pamjes',
colorLegend: 'Legjenda e Ngjyrave',
criticalPath: 'Rruga Kritike',
dependencies: 'Varësitë',
milestones: 'Ullesat',
baseline: 'Linja Bazë',
progress: 'Progresi',
variance: 'Varianca',
schedule: 'Orari',
noDataAvailable: 'Nuk ka të dhëna të disponueshme',
rebalanceError: 'Dështoi ribalansimi i ngarkesës së punës',
allocationUpdated: 'Shpërndarja u përditësua me sukses',
allocationError: 'Dështoi përditësimi i shpërndarjes',
zoomLevel: 'Niveli i Zoom-it',
loadingData: 'Duke ngarkuar të dhënat...',
loading: 'Duke ngarkuar...',
previous: 'I mëparshëm',
current: 'Aktual',
next: 'I radhës',
allRoles: 'Roli: Të gjitha rolet',
allMembers: 'Të gjithë anëtarët',
allProjects: 'Të gjitha projektet',
allClients: 'Të gjithë klientët',
viewOptions: 'Opsionet e pamjes',
moreFilters: 'Më shumë filtra',
allStatuses: 'Të gjitha statuset',
allPriorities: 'Të gjitha prioritetet',
allCategories: 'Të gjitha kategoritë',
noDatesSet: 'Nuk ka data të caktuar',
loadTooltipTitle: 'Ngarkesa',
loadTooltipFormula: 'Orët e planifikuara gjithsej për këtë projekt gjatë periudhës.',
loadTooltipBar: 'Shiriti i {{pct}}% është në rajon me projektin më të zënë këtu, jo me një objektiv fiks.',
exceedsWorkingHours: 'Tejkalon orët e punës',
estHoursPerDay: 'Orë të Vlerësuara',
phase: 'Faza',
assignees: 'Përgjegjësit',
type: 'Lloji',
projectBlock: 'Bllok projekt',
assignee: 'Përgjegjësi',
dates: 'Datat',
workloadSettings: 'Cilësimet e ngarkesës së punës',
timelineEmptyFilteredTitle: 'Je gjithcka i përditësuar këtu',
timelineEmptyTitle: 'Asgjë për të treguar ende',
timelineEmptyFilteredDesc: 'Asnjë projekt nuk përputhet me filtrat e tanishëm. Provoni të zgjidhni Projetet, Statusin, Prioritetin, Kategorinë ose Klientët.',
timelineEmptyProjectsDesc: 'Ende nuk ka projekte për të treguar.',
clearFilters: 'Pastro filtrat',
workloadEmptyFilteredTitle: 'Je gjithcka i përditësuar këtu',
workloadEmptyTitle: 'Asgjë për të treguar ende',
workloadEmptyFilteredDesc: 'Asnjëri nuk përputhet me filtrat e tanishëm. Provoni të zgjidhni Statusin e Projektit, Prioritetin ose Përdorimin.',
workloadEmptyMembersDesc: 'Ende nuk ka anëtarë ekipi për të treguar.',
workloadEmptyProjectsDesc: 'Ende nuk ka projekte për të treguar.',
allProjectStatuses: 'Statusi i Projektit',
allProjectPriorities: 'Prioriteti i Projektit',
allUtilLevels: 'Përdorimi',
},
};
for (const lang of TARGET_LANGS) {
const filePath = path.join(LOCALES_DIR, lang, 'schedule.json');
let locale = readJson(filePath);
if (!locale) {
console.error(`Skipping ${lang}: could not read file`);
continue;
}
const trans = translations[lang] || {};
let addedCount = 0;
let updatedCount = 0;
for (const [key, value] of Object.entries(source)) {
if (!(key in locale)) {
locale[key] = trans[key] || value;
addedCount++;
} else if (trans[key] && locale[key] === value) {
locale[key] = trans[key];
updatedCount++;
}
}
// Also remove extra keys not in source
const sourceKeys = Object.keys(source);
let removedCount = 0;
for (const key of Object.keys(locale)) {
if (!sourceKeys.includes(key)) {
delete locale[key];
removedCount++;
}
}
writeJson(filePath, locale);
console.log(` ${lang}: added ${addedCount} keys, updated ${updatedCount} translations, removed ${removedCount} extra keys`);
}
console.log('\nDone!');