static planning
This commit is contained in:
4
ressources.csv
Normal file
4
ressources.csv
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ressource,profil,7/14/2025,7/15/2025,7/16/2025,7/17/2025,7/18/2025,7/19/2025,7/20/2025,7/21/2025,7/22/2025
|
||||||
|
Simon BOYER,dev,0,0.5,0.5,0.5,0.5,0,0.5,0.5,0.5
|
||||||
|
Fatima BROUM,dev,0,1,1,1,1,0,1,1,1
|
||||||
|
Need Dev,dev,0,0,0,0,0,0,1,1,1
|
||||||
|
46
svar-gantt-app/scripts/init-db.js
Normal file
46
svar-gantt-app/scripts/init-db.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// scripts/init-db.ts
|
||||||
|
import Database from 'better-sqlite3';
|
||||||
|
import { mkdirSync, existsSync } from 'fs';
|
||||||
|
|
||||||
|
if (!existsSync('data')) {
|
||||||
|
mkdirSync('data');
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = new Database('data.db');
|
||||||
|
|
||||||
|
db.exec(`
|
||||||
|
DROP TABLE IF EXISTS tasks;
|
||||||
|
DROP TABLE IF EXISTS links;
|
||||||
|
|
||||||
|
CREATE TABLE tasks (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
start TEXT NOT NULL,
|
||||||
|
end TEXT NOT NULL,
|
||||||
|
duration INTEGER,
|
||||||
|
progress INTEGER,
|
||||||
|
type TEXT,
|
||||||
|
parent INTEGER,
|
||||||
|
lazy BOOLEAN DEFAULT 0 -- ✅ Ajout ici
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE links (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
source INTEGER,
|
||||||
|
target INTEGER,
|
||||||
|
type TEXT
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
// table pour les ressources
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS resource_planning (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
ressource TEXT NOT NULL,
|
||||||
|
profil TEXT NOT NULL,
|
||||||
|
date TEXT NOT NULL,
|
||||||
|
disponibilite REAL NOT NULL
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
|
||||||
|
console.log('✅ Base de données initialisée avec succès.');
|
||||||
127
svar-gantt-app/src/routes/planning/+page.svelte
Normal file
127
svar-gantt-app/src/routes/planning/+page.svelte
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Papa from 'papaparse';
|
||||||
|
import { writable, get } from 'svelte/store';
|
||||||
|
|
||||||
|
const planning = writable<any[]>([]);
|
||||||
|
const dates = writable<string[]>([]);
|
||||||
|
|
||||||
|
let file: File | null = null;
|
||||||
|
|
||||||
|
const joursFeries = [
|
||||||
|
'2025-01-01', '2025-04-21', '2025-05-01', '2025-05-08', '2025-05-29',
|
||||||
|
'2025-07-14', '2025-08-15', '2025-11-01', '2025-11-11', '2025-12-25'
|
||||||
|
];
|
||||||
|
|
||||||
|
function isWeekend(date: string) {
|
||||||
|
const d = new Date(date);
|
||||||
|
return d.getDay() === 0 || d.getDay() === 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isJourFerie(date: string) {
|
||||||
|
return joursFeries.includes(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateFr(dateStr: string) {
|
||||||
|
const d = new Date(dateStr);
|
||||||
|
return d.toLocaleDateString('fr-FR', {
|
||||||
|
weekday: 'short',
|
||||||
|
day: '2-digit',
|
||||||
|
month: 'short'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFileUpload() {
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
Papa.parse(file, {
|
||||||
|
header: true,
|
||||||
|
skipEmptyLines: true,
|
||||||
|
complete: (result) => {
|
||||||
|
const rows = result.data as any[];
|
||||||
|
|
||||||
|
const colonnesDates = Object.keys(rows[0]).filter(k => /^\d/.test(k));
|
||||||
|
dates.set(colonnesDates);
|
||||||
|
|
||||||
|
planning.set(rows.map(row => ({
|
||||||
|
ressource: row.ressource,
|
||||||
|
profil: row.profil,
|
||||||
|
disponibilites: colonnesDates.reduce((acc, date) => {
|
||||||
|
acc[date] = parseFloat(row[date] || 0);
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<string, number>)
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCell(rowIndex: number, date: string, value: string) {
|
||||||
|
const val = parseFloat(value);
|
||||||
|
if (![0, 0.5, 1].includes(val)) return;
|
||||||
|
|
||||||
|
planning.update(current => {
|
||||||
|
current[rowIndex].disponibilites[date] = val;
|
||||||
|
return current;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function totalByDate(date: string) {
|
||||||
|
const rows = get(planning);
|
||||||
|
return rows.reduce((sum, r) => sum + (r.disponibilites[date] || 0), 0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<h1 class="text-xl font-bold mb-4">📅 Planning Ressources</h1>
|
||||||
|
|
||||||
|
<input type="file" accept=".csv" on:change={(e) => file = e.target.files?.[0]} />
|
||||||
|
<button on:click={handleFileUpload} class="ml-2 bg-blue-600 text-white px-3 py-1 rounded">Charger</button>
|
||||||
|
|
||||||
|
{#if $planning.length > 0}
|
||||||
|
<table class="mt-6 border-collapse border w-full text-sm text-center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="border px-2 py-1 bg-white text-left">Ressource</th>
|
||||||
|
<th class="border px-2 py-1 bg-white text-left">Profil</th>
|
||||||
|
{#each $dates as date}
|
||||||
|
<th
|
||||||
|
class="border px-2 py-1"
|
||||||
|
class:bg-red-100={isJourFerie(date)}
|
||||||
|
class:bg-gray-100={!isJourFerie(date) && isWeekend(date)}
|
||||||
|
>
|
||||||
|
{formatDateFr(date)}
|
||||||
|
</th>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each $planning as row, i}
|
||||||
|
<tr>
|
||||||
|
<td class="border px-2 py-1 text-left">{row.ressource}</td>
|
||||||
|
<td class="border px-2 py-1 text-left">{row.profil}</td>
|
||||||
|
{#each $dates as date}
|
||||||
|
<td class="border p-0">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
step="0.5"
|
||||||
|
value={row.disponibilites[date]}
|
||||||
|
class="w-full text-center py-1 bg-transparent"
|
||||||
|
on:change={(e) => updateCell(i, date, e.target.value)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td class="border font-semibold text-right px-2 py-1" colspan="2">Total</td>
|
||||||
|
{#each $dates as date}
|
||||||
|
<td class="border px-2 py-1 font-semibold">
|
||||||
|
{totalByDate(date)}
|
||||||
|
</td>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
{/if}
|
||||||
Reference in New Issue
Block a user