Correction affichage edition
Signed-off-by: Gato <cedric@goutailler-olivier.fr>
This commit is contained in:
@@ -138,6 +138,23 @@
|
||||
}
|
||||
|
||||
/* Description */
|
||||
.description-action-btn {
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
color: #6b7280;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.description-action-btn:hover {
|
||||
color: #111827;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.description-textarea {
|
||||
min-height: 40rem;
|
||||
resize: vertical;
|
||||
@@ -145,7 +162,6 @@
|
||||
|
||||
.description-preview {
|
||||
min-height: 7rem;
|
||||
white-space: pre-wrap;
|
||||
font-size: 0.9rem;
|
||||
color: #374151;
|
||||
cursor: text;
|
||||
|
||||
@@ -176,7 +176,12 @@
|
||||
|
||||
<!-- Description -->
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header section-header">Description</div>
|
||||
<div class="card-header section-header d-flex align-items-center justify-content-between">
|
||||
<span>Description</span>
|
||||
@if (!editingDescription) {
|
||||
<button type="button" class="description-action-btn" (click)="startEditDescription()">Modifier</button>
|
||||
}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (editingDescription) {
|
||||
<textarea
|
||||
@@ -184,13 +189,17 @@
|
||||
class="form-control border-0 shadow-none p-0 description-textarea"
|
||||
placeholder="Ajouter une description..."
|
||||
[(ngModel)]="issue.description"
|
||||
(blur)="editingDescription = false; saveIssue()"
|
||||
(keydown.escape)="cancelEditDescription()"
|
||||
(paste)="onDescriptionPaste($event)"
|
||||
></textarea>
|
||||
<div class="d-flex gap-2 mt-2">
|
||||
<button type="button" class="btn btn-sm btn-primary" (click)="saveDescription()">Enregistrer</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" (click)="cancelEditDescription()">Annuler</button>
|
||||
</div>
|
||||
} @else {
|
||||
<div
|
||||
class="description-preview"
|
||||
(click)="editingDescription = true"
|
||||
(click)="startEditDescription()"
|
||||
title="Cliquer pour éditer"
|
||||
>
|
||||
@if (issue.description) {
|
||||
|
||||
@@ -519,6 +519,32 @@ describe('IssueDetail — existing issue', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('description edit flow', () => {
|
||||
it('startEditDescription sets editingDescription to true and stores original text', () => {
|
||||
(component as any).issue.description = 'original';
|
||||
(component as any).startEditDescription();
|
||||
expect((component as any).editingDescription).toBe(true);
|
||||
expect((component as any)._descriptionBeforeEdit).toBe('original');
|
||||
});
|
||||
|
||||
it('saveDescription exits edit mode and persists the description', async () => {
|
||||
(component as any).issue.description = 'updated';
|
||||
(component as any).editingDescription = true;
|
||||
await (component as any).saveDescription();
|
||||
expect((component as any).editingDescription).toBe(false);
|
||||
expect(store.getById(1)?.description).toBe('updated');
|
||||
});
|
||||
|
||||
it('cancelEditDescription restores the original description and exits edit mode', () => {
|
||||
(component as any).issue.description = 'original';
|
||||
(component as any).startEditDescription();
|
||||
(component as any).issue.description = 'changed mid-edit';
|
||||
(component as any).cancelEditDescription();
|
||||
expect((component as any).issue.description).toBe('original');
|
||||
expect((component as any).editingDescription).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onDescriptionPaste', () => {
|
||||
afterEach(() => vi.unstubAllGlobals());
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ export class IssueDetail {
|
||||
protected showAddDependency = false;
|
||||
protected selectedCandidateId: number | null = null;
|
||||
protected editingDescription = false;
|
||||
private _descriptionBeforeEdit = '';
|
||||
protected showAddToEpic = false;
|
||||
protected selectedEpicCandidateId: number | null = null;
|
||||
protected showCreateInEpic = false;
|
||||
@@ -237,6 +238,21 @@ export class IssueDetail {
|
||||
return !!this.issue.epic;
|
||||
}
|
||||
|
||||
protected startEditDescription(): void {
|
||||
this._descriptionBeforeEdit = this.issue.description;
|
||||
this.editingDescription = true;
|
||||
}
|
||||
|
||||
protected async saveDescription(): Promise<void> {
|
||||
this.editingDescription = false;
|
||||
await this.saveIssue();
|
||||
}
|
||||
|
||||
protected cancelEditDescription(): void {
|
||||
this.issue.description = this._descriptionBeforeEdit;
|
||||
this.editingDescription = false;
|
||||
}
|
||||
|
||||
protected onDescriptionPaste(event: ClipboardEvent): void {
|
||||
const ta = event.target as HTMLTextAreaElement;
|
||||
const start = ta.selectionStart;
|
||||
|
||||
Reference in New Issue
Block a user