chore: final pre-submission polish for JOSS
- Add CITATION.cff for GitHub citation support and Zenodo/JOSS integration - Fix ossim reference URL in references.bib (was pointing to unrelated repo) - Remove broken favicon reference from index.html (no public/ directory exists) - Add meta description to index.html - Fix sidebar title inconsistency: "Process Simulator" → "Process Scheduler Simulator" - Rebuild dist.tar.gz with production assets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
fa009102eb
commit
22925578b1
34 files changed
+304
-255
No files matched your search
@@ -56,7 +56,7 @@ const ProcessCard = ({ process, onEdit, onRemove }: ProcessCardProps) => {
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
label={`Editar ${process.name}`}
|
||||
label={`Edit ${process.name}`}
|
||||
onClick={() => onEdit(process)}
|
||||
>
|
||||
<Pencil size={13} />
|
||||
@@ -64,7 +64,7 @@ const ProcessCard = ({ process, onEdit, onRemove }: ProcessCardProps) => {
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
label={`Remover ${process.name}`}
|
||||
label={`Remove ${process.name}`}
|
||||
onClick={() => onRemove(process.id)}
|
||||
className="hover:text-red-400 hover:bg-red-900/20"
|
||||
>
|
||||
|
||||
@@ -69,16 +69,16 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
|
||||
const validate = (): boolean => {
|
||||
const errs: string[] = [];
|
||||
if (!name.trim()) errs.push('Nome é obrigatório');
|
||||
if (name.trim().length > 8) errs.push('Nome deve ter no máximo 8 caracteres');
|
||||
if (arrivalTime < 0) errs.push('Arrival Time deve ser ≥ 0');
|
||||
if (priority < 1 || priority > 10) errs.push('Priority deve estar entre 1 e 10');
|
||||
if (bursts.length === 0) errs.push('Deve haver ao menos 1 burst CPU');
|
||||
if (bursts[0]?.type !== 'cpu') errs.push('O primeiro burst deve ser CPU');
|
||||
if (bursts.at(-1)?.type !== 'cpu') errs.push('O último burst deve ser CPU');
|
||||
if (!name.trim()) errs.push('Name is required');
|
||||
if (name.trim().length > 8) errs.push('Name must be at most 8 characters');
|
||||
if (arrivalTime < 0) errs.push('Arrival Time must be ≥ 0');
|
||||
if (priority < 1 || priority > 10) errs.push('Priority must be between 1 and 10');
|
||||
if (bursts.length === 0) errs.push('There must be at least 1 CPU burst');
|
||||
if (bursts[0]?.type !== 'cpu') errs.push('The first burst must be CPU');
|
||||
if (bursts.at(-1)?.type !== 'cpu') errs.push('The last burst must be CPU');
|
||||
bursts.forEach((b, i) => {
|
||||
if (b.duration < 1) errs.push(`Burst ${i + 1}: duração deve ser ≥ 1`);
|
||||
if (i > 0 && bursts[i - 1]?.type === b.type) errs.push(`Bursts ${i} e ${i + 1} não podem ser do mesmo tipo (alternar CPU/IO)`);
|
||||
if (b.duration < 1) errs.push(`Burst ${i + 1}: duration must be ≥ 1`);
|
||||
if (i > 0 && bursts[i - 1]?.type === b.type) errs.push(`Bursts ${i} and ${i + 1} cannot be the same type (alternate CPU/IO)`);
|
||||
});
|
||||
setErrors(errs);
|
||||
return errs.length === 0;
|
||||
@@ -108,9 +108,9 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
<div className="bg-slate-800/60 rounded-xl border border-slate-600 shadow-xl p-4 space-y-4" data-testid="process-form">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-sm font-semibold text-slate-200">
|
||||
{isEditing ? 'Editar Processo' : 'Novo Processo'}
|
||||
{isEditing ? 'Edit Process' : 'New Process'}
|
||||
</h3>
|
||||
<IconButton size="sm" variant="ghost" label="Fechar" onClick={onClose}>
|
||||
<IconButton size="sm" variant="ghost" label="Close" onClick={onClose}>
|
||||
<X size={14} />
|
||||
</IconButton>
|
||||
</div>
|
||||
@@ -120,7 +120,7 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
<div className="col-span-2 flex gap-3">
|
||||
{/* Name */}
|
||||
<div className="flex-1">
|
||||
<label className={labelCls} htmlFor="pf-name">Nome</label>
|
||||
<label className={labelCls} htmlFor="pf-name">Name</label>
|
||||
<input
|
||||
id="pf-name"
|
||||
type="text"
|
||||
@@ -129,19 +129,19 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
onChange={e => setName(e.target.value)}
|
||||
placeholder="P1"
|
||||
className={inputCls}
|
||||
aria-label="Nome do processo"
|
||||
aria-label="Process name"
|
||||
/>
|
||||
</div>
|
||||
{/* Color */}
|
||||
<div>
|
||||
<label className={labelCls} htmlFor="pf-color">Cor</label>
|
||||
<label className={labelCls} htmlFor="pf-color">Color</label>
|
||||
<input
|
||||
id="pf-color"
|
||||
type="color"
|
||||
value={color}
|
||||
onChange={e => setColor(e.target.value)}
|
||||
className="h-8.5 w-12 rounded-md border border-slate-600 bg-slate-700 cursor-pointer"
|
||||
aria-label="Cor do processo"
|
||||
aria-label="Process color"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -156,7 +156,7 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
value={arrivalTime}
|
||||
onChange={e => setArrivalTime(Number(e.target.value))}
|
||||
className={inputCls}
|
||||
aria-label="Tempo de chegada"
|
||||
aria-label="Arrival time"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -171,7 +171,7 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
value={priority}
|
||||
onChange={e => setPriority(Number(e.target.value))}
|
||||
className={inputCls}
|
||||
aria-label="Prioridade do processo"
|
||||
aria-label="Process priority"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,7 +180,7 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<label className="text-xs text-slate-400 font-medium">Bursts (CPU → I/O → CPU…)</label>
|
||||
<IconButton size="sm" variant="ghost" label="Adicionar burst" onClick={addBurst}>
|
||||
<IconButton size="sm" variant="ghost" label="Add burst" onClick={addBurst}>
|
||||
<Plus size={13} />
|
||||
</IconButton>
|
||||
</div>
|
||||
@@ -203,13 +203,13 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
value={burst.duration}
|
||||
onChange={e => updateBurstDuration(idx, Number(e.target.value))}
|
||||
className="w-full rounded bg-slate-700/60 border border-slate-600/50 text-slate-200 text-xs px-2 py-0.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
||||
aria-label={`Duração do burst ${idx + 1}`}
|
||||
aria-label={`Burst ${idx + 1} duration`}
|
||||
/>
|
||||
<span className="text-[10px] text-slate-500">ticks</span>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
label={`Remover burst ${idx + 1}`}
|
||||
label={`Remove burst ${idx + 1}`}
|
||||
onClick={() => removeBurst(idx)}
|
||||
disabled={bursts.length <= 1}
|
||||
className="hover:text-red-400"
|
||||
@@ -235,17 +235,17 @@ const ProcessForm = ({ editingProcess, onClose }: ProcessFormProps) => {
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
className="flex-1 flex items-center justify-center gap-1.5 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium py-1.5 rounded-lg transition-colors"
|
||||
aria-label={isEditing ? 'Salvar processo' : 'Criar processo'}
|
||||
aria-label={isEditing ? 'Save process' : 'Create process'}
|
||||
>
|
||||
<Check size={15} />
|
||||
{isEditing ? 'Salvar' : 'Criar'}
|
||||
{isEditing ? 'Save' : 'Create'}
|
||||
</button>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="px-4 bg-slate-700 hover:bg-slate-600 text-slate-300 text-sm rounded-lg transition-colors"
|
||||
aria-label="Cancelar"
|
||||
aria-label="Cancel"
|
||||
>
|
||||
Cancelar
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -47,13 +47,13 @@ const ProcessList = ({ onEditProcess, onAddNew }: ProcessListProps) => {
|
||||
{/* List header */}
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-xs text-slate-400">
|
||||
{processes.length}/{MAX_PROCESSES} processos
|
||||
{processes.length}/{MAX_PROCESSES} processes
|
||||
</span>
|
||||
<div className="flex gap-1">
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
label="Gerar processo aleatório"
|
||||
label="Generate random process"
|
||||
onClick={handleRandomize}
|
||||
disabled={!canAdd}
|
||||
>
|
||||
@@ -62,7 +62,7 @@ const ProcessList = ({ onEditProcess, onAddNew }: ProcessListProps) => {
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
label="Limpar todos os processos"
|
||||
label="Clear all processes"
|
||||
onClick={clearProcesses}
|
||||
disabled={processes.length === 0}
|
||||
className="hover:text-red-400 hover:bg-red-900/20"
|
||||
@@ -76,8 +76,8 @@ const ProcessList = ({ onEditProcess, onAddNew }: ProcessListProps) => {
|
||||
<div className="space-y-2 max-h-64 overflow-y-auto pr-0.5 scrollbar-hide">
|
||||
{processes.length === 0 ? (
|
||||
<div className="flex flex-col items-center justify-center gap-2 text-slate-500 text-sm py-8 border border-dashed border-slate-700 rounded-lg">
|
||||
<span>Nenhum processo adicionado</span>
|
||||
<span className="text-xs">Clique em + para criar</span>
|
||||
<span>No processes added</span>
|
||||
<span className="text-xs">Click + to create</span>
|
||||
</div>
|
||||
) : (
|
||||
processes.map(p => (
|
||||
@@ -95,11 +95,11 @@ const ProcessList = ({ onEditProcess, onAddNew }: ProcessListProps) => {
|
||||
{canAdd && (
|
||||
<button
|
||||
onClick={onAddNew}
|
||||
aria-label="Adicionar novo processo"
|
||||
aria-label="Add new process"
|
||||
className="mt-2 w-full flex items-center justify-center gap-2 py-2 rounded-lg border border-dashed border-slate-600 text-slate-500 hover:border-blue-500 hover:text-blue-400 text-xs transition-colors"
|
||||
>
|
||||
<Plus size={14} />
|
||||
Adicionar Processo
|
||||
Add Process
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -24,10 +24,10 @@ const ProcessPanel = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<section aria-label="Painel de Processos">
|
||||
<section aria-label="Processes Panel">
|
||||
<div className="flex items-center gap-2 mb-3 text-slate-300">
|
||||
<ListTree size={18} className="text-blue-400" />
|
||||
<h2 className="font-semibold uppercase text-xs tracking-wider">Processos</h2>
|
||||
<h2 className="font-semibold uppercase text-xs tracking-wider">Processes</h2>
|
||||
</div>
|
||||
|
||||
{showForm ? (
|
||||
|
||||
Reference in new issue
Block a user