Refactor layout and styling: update HTML structure and apply Bootstrap for improved responsiveness
This commit is contained in:
+1
-19
@@ -1,25 +1,7 @@
|
||||
:host {
|
||||
display: block;
|
||||
min-height: 100vh;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f6f8fb;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-columns: 240px 1fr;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
-5
@@ -1,8 +1,12 @@
|
||||
<main class="layout">
|
||||
<app-menu />
|
||||
<main class="container-fluid min-vh-100">
|
||||
<div class="row min-vh-100">
|
||||
<aside class="col-12 col-md-3 col-lg-2 p-0">
|
||||
<app-menu />
|
||||
</aside>
|
||||
|
||||
<section class="content" aria-live="polite">
|
||||
<router-outlet />
|
||||
</section>
|
||||
<section class="col-12 col-md-9 col-lg-10 p-4" aria-live="polite">
|
||||
<router-outlet />
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -2,35 +2,3 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
margin: 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
margin: 0.5rem 0 1.5rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 0.75rem;
|
||||
padding: 1rem;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.card p {
|
||||
margin: 0;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
+30
-18
@@ -1,21 +1,33 @@
|
||||
<header class="page-header">
|
||||
<h1>Accueil</h1>
|
||||
<p>Bienvenue sur Bonsai Webapp.</p>
|
||||
</header>
|
||||
<div class="mb-4">
|
||||
<h1 class="h2 mb-2">Accueil</h1>
|
||||
<p class="text-secondary mb-0">Bienvenue sur Bonsai Webapp.</p>
|
||||
</div>
|
||||
|
||||
<section class="cards">
|
||||
<article class="card">
|
||||
<h2>Statistiques</h2>
|
||||
<p>Resume rapide des activites recentes.</p>
|
||||
</article>
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card h-100 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title">Statistiques</h2>
|
||||
<p class="card-text text-secondary mb-0">Resume rapide des activites recentes.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article class="card">
|
||||
<h2>Notifications</h2>
|
||||
<p>Consultez les dernieres mises a jour de l'equipe.</p>
|
||||
</article>
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card h-100 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title">Notifications</h2>
|
||||
<p class="card-text text-secondary mb-0">Consultez les dernieres mises a jour de l'equipe.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article class="card">
|
||||
<h2>Taches en cours</h2>
|
||||
<p>Suivi des priorites de la semaine.</p>
|
||||
</article>
|
||||
</section>
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card h-100 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title">Taches en cours</h2>
|
||||
<p class="card-text text-secondary mb-0">Suivi des priorites de la semaine.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<header class="page-header">
|
||||
<header class="page-header mb-4">
|
||||
<div>
|
||||
<h1>Detail de l'issue</h1>
|
||||
<p>Informations de creation et de suivi de l'issue.</p>
|
||||
</div>
|
||||
<div class="header-meta">
|
||||
<div class="status-inline">
|
||||
<div class="header-meta d-flex align-items-start gap-3 flex-wrap justify-content-end">
|
||||
<div class="status-inline d-flex align-items-center gap-2 bg-white border rounded-3 px-3 py-2 shadow-sm">
|
||||
<span class="status-label">Status</span>
|
||||
<select
|
||||
class="status-select"
|
||||
class="status-select form-select form-select-sm w-auto"
|
||||
[ngModel]="issue.status"
|
||||
(ngModelChange)="updateStatus($event)"
|
||||
>
|
||||
@@ -17,13 +17,13 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="header-actions">
|
||||
<div class="header-actions d-flex gap-2 flex-wrap justify-content-end">
|
||||
<div class="more-wrapper">
|
||||
<button type="button" class="more-button" (click)="toggleMoreMenu()">More ▾</button>
|
||||
<button type="button" class="more-button btn btn-outline-secondary btn-sm dropdown-toggle" (click)="toggleMoreMenu()">More</button>
|
||||
|
||||
@if (moreMenuOpen) {
|
||||
<div class="more-menu">
|
||||
<button type="button" class="more-menu-item delete-action" (click)="deleteIssue()">
|
||||
<div class="more-menu dropdown-menu show position-absolute end-0 mt-2 p-1 shadow">
|
||||
<button type="button" class="more-menu-item delete-action dropdown-item text-danger" (click)="deleteIssue()">
|
||||
Supprimer
|
||||
</button>
|
||||
</div>
|
||||
@@ -33,8 +33,8 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="detail-card" aria-label="Informations de l'issue">
|
||||
<table>
|
||||
<section class="detail-card card shadow-sm" aria-label="Informations de l'issue">
|
||||
<table class="table table-borderless align-middle mb-0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
@@ -43,13 +43,13 @@
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<td>
|
||||
<input type="text" [(ngModel)]="issue.name" (blur)="saveIssue()" />
|
||||
<input class="form-control form-control-sm" type="text" [(ngModel)]="issue.name" (blur)="saveIssue()" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<td>
|
||||
<select [(ngModel)]="issueTypeValue" (change)="saveIssue()">
|
||||
<select class="form-select form-select-sm" [(ngModel)]="issueTypeValue" (change)="saveIssue()">
|
||||
@for (type of typeOptions; track type) {
|
||||
<option [value]="type">{{ type }}</option>
|
||||
}
|
||||
@@ -60,7 +60,7 @@
|
||||
<tr>
|
||||
<th>Epic</th>
|
||||
<td>
|
||||
<select [(ngModel)]="issue.epic" (change)="saveIssue()">
|
||||
<select class="form-select form-select-sm" [(ngModel)]="issue.epic" (change)="saveIssue()">
|
||||
<option value="">-</option>
|
||||
@for (epicIssue of epicIssues; track epicIssue.id) {
|
||||
<option [value]="epicIssue.name">{{ epicIssue.name }}</option>
|
||||
@@ -72,7 +72,7 @@
|
||||
<tr>
|
||||
<th>Depend de</th>
|
||||
<td>
|
||||
<select multiple [(ngModel)]="dependencyIds" class="dependency-multiselect" (change)="saveIssue()">
|
||||
<select multiple class="dependency-multiselect form-select form-select-sm" [(ngModel)]="dependencyIds" (change)="saveIssue()">
|
||||
@for (candidate of dependencyCandidates; track candidate.id) {
|
||||
<option [ngValue]="candidate.id">
|
||||
#{{ candidate.id }} - {{ candidate.name || 'Sans nom' }}
|
||||
@@ -84,31 +84,31 @@
|
||||
<tr>
|
||||
<th>Assignee</th>
|
||||
<td>
|
||||
<input type="text" [(ngModel)]="issue.assignee" (blur)="saveIssue()" />
|
||||
<input class="form-control form-control-sm" type="text" [(ngModel)]="issue.assignee" (blur)="saveIssue()" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Date d'echeance</th>
|
||||
<td>
|
||||
<input type="date" [(ngModel)]="issue.dueDate" (blur)="saveIssue()" />
|
||||
<input class="form-control form-control-sm" type="date" [(ngModel)]="issue.dueDate" (blur)="saveIssue()" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Temps estimé</th>
|
||||
<td>
|
||||
<input type="number" min="0" step="0.5" [(ngModel)]="estimatedTimeValue" (blur)="saveIssue()" />
|
||||
<input class="form-control form-control-sm" type="number" min="0" step="0.5" [(ngModel)]="estimatedTimeValue" (blur)="saveIssue()" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>
|
||||
<textarea rows="4" [(ngModel)]="issue.description" (blur)="saveIssue()"></textarea>
|
||||
<textarea class="form-control form-control-sm" rows="4" [(ngModel)]="issue.description" (blur)="saveIssue()"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Priorite</th>
|
||||
<td>
|
||||
<select [(ngModel)]="issue.priority" (change)="saveIssue()">
|
||||
<select class="form-select form-select-sm" [(ngModel)]="issue.priority" (change)="saveIssue()">
|
||||
<option value="Basse">Basse</option>
|
||||
<option value="Moyenne">Moyenne</option>
|
||||
<option value="Haute">Haute</option>
|
||||
@@ -118,7 +118,7 @@
|
||||
<tr>
|
||||
<th>Progression</th>
|
||||
<td>
|
||||
<input type="number" min="0" max="100" [(ngModel)]="issue.progress" (blur)="saveIssue()" />
|
||||
<input class="form-control form-control-sm" type="number" min="0" max="100" [(ngModel)]="issue.progress" (blur)="saveIssue()" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -126,23 +126,25 @@
|
||||
</section>
|
||||
|
||||
@if (isEpicIssue) {
|
||||
<section class="epic-issues-card" aria-label="Issues composant cet epic">
|
||||
<div class="epic-issues-header">
|
||||
<h2>Issues composant cet Epic</h2>
|
||||
<span>{{ composedIssues.length }}</span>
|
||||
<section class="epic-issues-card card shadow-sm mt-4" aria-label="Issues composant cet epic">
|
||||
<div class="epic-issues-header card-header d-flex align-items-center justify-content-between">
|
||||
<h2 class="h5 mb-0">Issues composant cet Epic</h2>
|
||||
<span class="badge text-bg-primary">{{ composedIssues.length }}</span>
|
||||
</div>
|
||||
|
||||
@if (composedIssues.length === 0) {
|
||||
<p class="epic-empty">Aucune issue ne compose encore cet Epic.</p>
|
||||
<div class="card-body">
|
||||
<p class="epic-empty mb-0 text-secondary">Aucune issue ne compose encore cet Epic.</p>
|
||||
</div>
|
||||
} @else {
|
||||
<ul class="epic-issues-list">
|
||||
<ul class="epic-issues-list list-group list-group-flush">
|
||||
@for (composedIssue of composedIssues; track composedIssue.id) {
|
||||
<li class="epic-issue-item">
|
||||
<div>
|
||||
<li class="epic-issue-item list-group-item d-flex justify-content-between align-items-start gap-3">
|
||||
<div class="grow">
|
||||
<strong>#{{ composedIssue.id }} - {{ composedIssue.name || 'Sans nom' }}</strong>
|
||||
<p>{{ composedIssue.type }} · {{ composedIssue.status }}</p>
|
||||
<p class="mb-0 text-secondary">{{ composedIssue.type }} · {{ composedIssue.status }}</p>
|
||||
</div>
|
||||
<span>{{ composedIssue.assignee || 'Non assigné' }}</span>
|
||||
<span class="text-secondary fw-semibold text-nowrap">{{ composedIssue.assignee || 'Non assigné' }}</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
@@ -2,68 +2,6 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
margin: 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
margin: 0.5rem 0 1.5rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.create-button {
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #2563eb;
|
||||
color: #ffffff;
|
||||
padding: 0.65rem 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.create-button:hover {
|
||||
background-color: #1d4ed8;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 0.75rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 0.85rem 1rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
th {
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
color: #6b7280;
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.clickable-row {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -77,9 +15,4 @@ tbody tr:last-child td {
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+35
-35
@@ -1,39 +1,39 @@
|
||||
<header class="page-header">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between gap-3 mb-4">
|
||||
<div>
|
||||
<h1>Issues</h1>
|
||||
<p>Suivi des tickets et anomalies du projet.</p>
|
||||
<h1 class="h2 mb-2">Issues</h1>
|
||||
<p class="text-secondary mb-0">Suivi des tickets et anomalies du projet.</p>
|
||||
</div>
|
||||
<button type="button" class="create-button" (click)="createIssue()">
|
||||
Creer
|
||||
</button>
|
||||
</header>
|
||||
<button type="button" class="btn btn-primary" (click)="createIssue()">Creer</button>
|
||||
</div>
|
||||
|
||||
<section class="table-wrapper" aria-label="Tableau des issues">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Titre</th>
|
||||
<th>Type</th>
|
||||
<th>Priorite</th>
|
||||
<th>Statut</th>
|
||||
<th>Assignee</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (issue of issues(); track issue.id) {
|
||||
<tr
|
||||
class="clickable-row"
|
||||
tabindex="0"
|
||||
(click)="openIssue(issue.id)"
|
||||
(keydown.enter)="openIssue(issue.id)"
|
||||
>
|
||||
<td>{{ issue.name }}</td>
|
||||
<td>{{ issue.type }}</td>
|
||||
<td>{{ issue.priority }}</td>
|
||||
<td>{{ issue.status }}</td>
|
||||
<td>{{ issue.assignee }}</td>
|
||||
<div class="card shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Titre</th>
|
||||
<th>Type</th>
|
||||
<th>Priorite</th>
|
||||
<th>Statut</th>
|
||||
<th>Assignee</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (issue of issues(); track issue.id) {
|
||||
<tr
|
||||
class="clickable-row"
|
||||
tabindex="0"
|
||||
(click)="openIssue(issue.id)"
|
||||
(keydown.enter)="openIssue(issue.id)"
|
||||
>
|
||||
<td>{{ issue.name }}</td>
|
||||
<td><span class="badge text-bg-secondary">{{ issue.type }}</span></td>
|
||||
<td>{{ issue.priority }}</td>
|
||||
<td>{{ issue.status }}</td>
|
||||
<td>{{ issue.assignee }}</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,25 +88,6 @@ export class IssuesStore {
|
||||
return ids.length > 0 ? Math.max(...ids) + 1 : 1;
|
||||
}
|
||||
|
||||
createDraftIssue(): IssueEntity {
|
||||
const draftIssue: IssueEntity = this.normalizeIssue({
|
||||
id: this.getNextId(),
|
||||
type: 'Story',
|
||||
assignee: '',
|
||||
epic: '',
|
||||
name: '',
|
||||
dueDate: '',
|
||||
description: '',
|
||||
estimatedTime: null,
|
||||
dependsOnIds: [],
|
||||
priority: 'Moyenne',
|
||||
status: 'draft',
|
||||
progress: 0,
|
||||
});
|
||||
|
||||
this.upsert(draftIssue);
|
||||
return draftIssue;
|
||||
}
|
||||
|
||||
upsert(issue: IssueEntity): void {
|
||||
const normalizedIssue = this.normalizeIssue(issue);
|
||||
|
||||
@@ -3,50 +3,4 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-color: #111827;
|
||||
color: #f9fafb;
|
||||
padding: 1.5rem 1rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
margin: 0 0 1rem;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.65rem 0.75rem;
|
||||
text-align: left;
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.menu-item:hover {
|
||||
background-color: #1f2937;
|
||||
}
|
||||
|
||||
.menu-item.active {
|
||||
background-color: #2563eb;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-17
@@ -1,19 +1,24 @@
|
||||
<aside class="sidebar" aria-label="Menu principal">
|
||||
<aside class="bg-dark text-white min-vh-100 p-3" aria-label="Menu principal">
|
||||
<div class="d-flex flex-column gap-3">
|
||||
<div>
|
||||
<h2 class="h5 mb-0">Menu</h2>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<ul class="menu-list">
|
||||
@for (item of menuItems; track item.path) {
|
||||
<li>
|
||||
<a
|
||||
class="menu-item"
|
||||
[routerLink]="item.path"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</nav>
|
||||
<nav>
|
||||
<ul class="nav nav-pills flex-column gap-2">
|
||||
@for (item of menuItems; track item.path) {
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link text-white"
|
||||
[routerLink]="item.path"
|
||||
routerLinkActive="active bg-primary"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -2,70 +2,3 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
margin: 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
margin: 0.5rem 0 1.5rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.create-button {
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #2563eb;
|
||||
color: #ffffff;
|
||||
padding: 0.65rem 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.create-button:hover {
|
||||
background-color: #1d4ed8;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 0.75rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 0.85rem 1rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
th {
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
color: #6b7280;
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
<header class="page-header">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between gap-3 mb-4">
|
||||
<div>
|
||||
<h1>Projets</h1>
|
||||
<p>Vue d'ensemble des projets actifs.</p>
|
||||
<h1 class="h2 mb-2">Projets</h1>
|
||||
<p class="text-secondary mb-0">Vue d'ensemble des projets actifs.</p>
|
||||
</div>
|
||||
<button type="button" class="create-button" (click)="createProject()">
|
||||
<button type="button" class="btn btn-primary" (click)="createProject()">
|
||||
Nouveau projet
|
||||
</button>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<section class="table-wrapper" aria-label="Tableau des projets">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<th>Responsable</th>
|
||||
<th>Statut</th>
|
||||
<th>Progression</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (project of projects(); track project.id) {
|
||||
<div class="card shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<td>{{ project.name }}</td>
|
||||
<td>{{ project.owner }}</td>
|
||||
<td>{{ project.status }}</td>
|
||||
<td>{{ project.progress }}%</td>
|
||||
<th>Nom</th>
|
||||
<th>Responsable</th>
|
||||
<th>Statut</th>
|
||||
<th>Progression</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (project of projects(); track project.id) {
|
||||
<tr>
|
||||
<td>{{ project.name }}</td>
|
||||
<td>{{ project.owner }}</td>
|
||||
<td>{{ project.status }}</td>
|
||||
<td>{{ project.progress }}%</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user