Skip to content

Commit

Permalink
va-file-input: show modal to confirm file delete (#1192)
Browse files Browse the repository at this point in the history
* changes made to component

* add tests

* bump version
  • Loading branch information
it-harrison authored Jun 18, 2024
1 parent 68bad0f commit d22625f
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/web-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@department-of-veterans-affairs/web-components",
"version": "9.1.4",
"version": "9.2.0",
"description": "Stencil Component Starter",
"main": "dist/index.cjs.js",
"module": "dist/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,106 @@ describe('va-file-input', () => {

await axeCheck(page);
});

// this test usually passes but it is too flaky to enable
it.skip('v3 opens a modal when delete button clicked and lets user remove or keep file', async () => {
const page = await newE2EPage();
await page.setContent(`<va-file-input buttonText="Upload a file" uswds />`);

const filePath = path.relative(process.cwd(), __dirname + '/1x1.png');

const input = (
await page.waitForFunction(() =>
document
.querySelector('va-file-input')
.shadowRoot.querySelector('input[type=file]'),
)
).asElement();

expect(input).not.toBeNull();

await input
.uploadFile(filePath)
.catch(e => console.log('uploadFile error', e));

// get delete button
const [_, deleteButton] = await page.findAll('va-file-input >>> va-button-icon');
deleteButton.click();
await page.waitForTimeout(100);

// make sure modal opens
const modalCheck = await page.find('va-file-input >>> va-modal[visible]');

expect(modalCheck).not.toBeNull();

const noButton = (
await page.waitForFunction(() =>
document.querySelector('va-file-input').shadowRoot.querySelector('va-modal').shadowRoot.querySelector('va-button[secondary]')
)
).asElement();

//don't delete
noButton.click();

await page.waitForTimeout(100);

const modalCheck2 = await page.find('va-file-input >>> va-modal[visible]');

//modal now closed
expect(modalCheck2).toBeNull();

// get buttons again
const [__, deleteButton2] = await page.findAll('va-file-input >>> va-button-icon');

// file not deleted because delete option still here
expect(deleteButton2).not.toBeNull();
});

// this test usually passes but it is too flaky to enable
it.skip('v3 opens a modal when delete button clicked and lets user remove the file', async () => {
const page = await newE2EPage();
await page.setContent(`<va-file-input buttonText="Upload a file" uswds />`);

const filePath = path.relative(process.cwd(), __dirname + '/1x1.png');

const input = (
await page.waitForFunction(() =>
document
.querySelector('va-file-input')
.shadowRoot.querySelector('input[type=file]'),
)
).asElement();

expect(input).not.toBeNull();

await input
.uploadFile(filePath)
.catch(e => console.log('uploadFile error', e));

// get delete button
const [_, deleteButton] = await page.findAll('va-file-input >>> va-button-icon');
deleteButton.click();
await page.waitForTimeout(100);

// make sure modal opens
const modalCheck = await page.find('va-file-input >>> va-modal[visible]');

expect(modalCheck).not.toBeNull();

const yesButton = (
await page.waitForFunction(() =>
document.querySelector('va-file-input').shadowRoot.querySelector('va-modal').shadowRoot.querySelector('va-button')
)
).asElement();

// yes we want to remove the file
yesButton.click();
await page.waitForTimeout(100);

// get buttons again
const btns = await page.findAll('va-file-input >>> va-button-icon');

// buttons are gone because file has been deleted
expect(btns).toHaveLength(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class VaFileInput {
@State() file?: File;
@State() fileContents?: string;
@State() internalError?: string;
@State() showModal: boolean = false;

/**
* The label for the file input.
Expand Down Expand Up @@ -154,12 +155,28 @@ export class VaFileInput {
};

private removeFile = () => {
this.closeModal();
this.file = null;
this.vaChange.emit({ files: [this.file] });
this.uploadStatus = 'idle';
this.internalError = null;
};

private openModal = () => {
// set the status attribute here not in markup or it will have no effect
const modal = this.el.shadowRoot.querySelector('va-modal');
modal.setAttribute('status', 'warning');
this.showModal = true;
}

private closeModal = () => {
this.showModal = false;
// wait a tick for modal to close before setting focus
setTimeout(() => {
this.fileInputRef.focus();
}, 0);
}

private changeFile = () => {
if (this.fileInputRef) {
this.fileInputRef.click();
Expand Down Expand Up @@ -418,10 +435,21 @@ export class VaFileInput {
></va-button-icon>
<va-button-icon
buttonType="delete"
onClick={this.removeFile}
onClick={this.openModal}
label="Delete"
></va-button-icon>
</div>
<va-modal
modalTitle='Are you sure you want to remove this file?'
visible={this.showModal}
primaryButtonText='Yes, remove this'
secondaryButtonText='No, keep this'
onCloseEvent={this.closeModal}
onPrimaryButtonClick={this.removeFile}
onSecondaryButtonClick={this.closeModal}
>
We'll remove the uploaded document <span class="file-label">{file.name}</span>
</va-modal>
</div>
)}
</va-card>
Expand Down

0 comments on commit d22625f

Please sign in to comment.