feat(FN-1208): reorder task form attachments above dependencies

- Move the Attachments form section to render before Dependencies in TaskForm
- Keep existing screenshot attach/remove interactions intact while changing layout order
- Add NewTaskModal test coverage asserting Attachments appears before Dependencies in DOM order
This commit is contained in:
gsxdsm
2026-04-08 05:21:07 -07:00
parent 844d43c017
commit eb6676eee0
2 changed files with 59 additions and 47 deletions

View File

@@ -490,6 +490,54 @@ export function TaskForm({
</div>
)}
{/* Attachments */}
<div className="form-group">
<label>Attachments</label>
{pendingImages.length > 0 && (
<div className="inline-create-previews">
{pendingImages.map((img, i) => (
<div key={img.previewUrl} className="inline-create-preview">
<img src={img.previewUrl} alt={img.file.name} />
<button
type="button"
className="inline-create-preview-remove"
onClick={() => removeImage(i)}
disabled={disabled}
title="Remove image"
>
×
</button>
</div>
))}
</div>
)}
<input
ref={fileInputRef}
type="file"
accept="image/*"
onChange={(e) => {
const file = e.target.files?.[0];
if (file) {
onImagesChange([
...pendingImages,
{ file, previewUrl: URL.createObjectURL(file) },
]);
e.target.value = "";
}
}}
style={{ display: "none" }}
/>
<button
type="button"
className="btn btn-sm"
onClick={() => fileInputRef.current?.click()}
disabled={disabled}
>
Attach Screenshot
</button>
<small>You can also paste images or drag & drop</small>
</div>
{/* Dependencies */}
<div className="form-group">
<label>Dependencies</label>
@@ -792,53 +840,6 @@ export function TaskForm({
)}
</div>
{/* Attachments */}
<div className="form-group">
<label>Attachments</label>
{pendingImages.length > 0 && (
<div className="inline-create-previews">
{pendingImages.map((img, i) => (
<div key={img.previewUrl} className="inline-create-preview">
<img src={img.previewUrl} alt={img.file.name} />
<button
type="button"
className="inline-create-preview-remove"
onClick={() => removeImage(i)}
disabled={disabled}
title="Remove image"
>
×
</button>
</div>
))}
</div>
)}
<input
ref={fileInputRef}
type="file"
accept="image/*"
onChange={(e) => {
const file = e.target.files?.[0];
if (file) {
onImagesChange([
...pendingImages,
{ file, previewUrl: URL.createObjectURL(file) },
]);
e.target.value = "";
}
}}
style={{ display: "none" }}
/>
<button
type="button"
className="btn btn-sm"
onClick={() => fileInputRef.current?.click()}
disabled={disabled}
>
Attach Screenshot
</button>
<small>You can also paste images or drag & drop</small>
</div>
</div>
);
}

View File

@@ -81,6 +81,17 @@ describe("NewTaskModal", () => {
expect(screen.getByRole("button", { name: "Cancel" })).toBeTruthy();
});
it("renders attachments before dependencies in form order", () => {
renderNewTaskModal();
const attachmentsLabel = screen.getByText("Attachments");
const dependenciesLabel = screen.getByText("Dependencies");
expect(
attachmentsLabel.compareDocumentPosition(dependenciesLabel) & Node.DOCUMENT_POSITION_FOLLOWING,
).toBe(Node.DOCUMENT_POSITION_FOLLOWING);
});
it("focuses description textarea when modal opens", async () => {
renderNewTaskModal();