diff --git a/app/adapters/crate.js b/app/adapters/crate.js
index 5dc3b05f122..7f9059690a7 100644
--- a/app/adapters/crate.js
+++ b/app/adapters/crate.js
@@ -25,6 +25,18 @@ export default class CrateAdapter extends ApplicationAdapter {
return `${baseUrl}/${crateName}`;
}
+ /** Adds a `reason` query parameter to the URL, if set in the `adapterOptions`. */
+ urlForDeleteRecord(id, modelName, snapshot) {
+ let url = super.urlForDeleteRecord(...arguments);
+
+ let reason = snapshot.adapterOptions.reason;
+ if (reason) {
+ url += `?reason=${encodeURIComponent(reason)}`;
+ }
+
+ return url;
+ }
+
groupRecordsForFindMany(store, snapshots) {
let result = [];
for (let i = 0; i < snapshots.length; i += BULK_REQUEST_GROUP_SIZE) {
diff --git a/app/controllers/crate/delete.js b/app/controllers/crate/delete.js
index 866acfa2775..cd35fa283fa 100644
--- a/app/controllers/crate/delete.js
+++ b/app/controllers/crate/delete.js
@@ -9,6 +9,7 @@ export default class CrateSettingsController extends Controller {
@service notifications;
@service router;
+ @tracked reason = '';
@tracked isConfirmed;
@action toggleConfirmation() {
@@ -16,8 +17,10 @@ export default class CrateSettingsController extends Controller {
}
deleteTask = task(async () => {
+ let { reason } = this;
+
try {
- await this.model.destroyRecord();
+ await this.model.destroyRecord({ adapterOptions: { reason } });
this.notifications.success(`Crate ${this.model.name} has been successfully deleted.`);
this.router.transitionTo('index');
} catch (error) {
diff --git a/app/routes/crate/delete.js b/app/routes/crate/delete.js
index 5a19c5c9cd1..0e62ac3e984 100644
--- a/app/routes/crate/delete.js
+++ b/app/routes/crate/delete.js
@@ -20,6 +20,7 @@ export default class SettingsRoute extends AuthenticatedRoute {
setupController(controller) {
super.setupController(...arguments);
+ controller.set('reason', '');
controller.set('isConfirmed', false);
}
}
diff --git a/app/styles/crate/delete.module.css b/app/styles/crate/delete.module.css
index 6b73b90732e..5896bfb0f04 100644
--- a/app/styles/crate/delete.module.css
+++ b/app/styles/crate/delete.module.css
@@ -75,6 +75,15 @@
}
}
+.reason {
+ margin-bottom: var(--space-m);
+}
+
+.reason-input {
+ composes: base-input from '../../styles/settings/tokens/new.module.css';
+ width: 100%;
+}
+
.confirmation {
composes: warning-block;
display: block;
diff --git a/app/templates/crate/delete.hbs b/app/templates/crate/delete.hbs
index 3b7bd08f260..6c1a9e317c8 100644
--- a/app/templates/crate/delete.hbs
+++ b/app/templates/crate/delete.hbs
@@ -1,5 +1,5 @@
-
+
+
Reason:
+
+
+
{{/if}}
-
+
\ No newline at end of file
diff --git a/e2e/acceptance/crate-deletion.spec.ts b/e2e/acceptance/crate-deletion.spec.ts
index 72386cc9961..ba349ce25fe 100644
--- a/e2e/acceptance/crate-deletion.spec.ts
+++ b/e2e/acceptance/crate-deletion.spec.ts
@@ -24,6 +24,7 @@ test.describe('Acceptance | crate deletion', { tag: '@acceptance' }, () => {
await expect(page.locator('[data-test-title]')).toHaveText('Delete the foo crate?');
await expect(page.locator('[data-test-delete-button]')).toBeDisabled();
+ await page.fill('[data-test-reason]', "I don't need this crate anymore");
await page.click('[data-test-confirmation-checkbox]');
await expect(page.locator('[data-test-delete-button]')).toBeEnabled();
diff --git a/e2e/routes/crate/delete.spec.ts b/e2e/routes/crate/delete.spec.ts
index 4e67ce4a60d..5bbb99e980d 100644
--- a/e2e/routes/crate/delete.spec.ts
+++ b/e2e/routes/crate/delete.spec.ts
@@ -50,6 +50,7 @@ test.describe('Route: crate.delete', { tag: '@routes' }, () => {
await expect(page.locator('[data-test-title]')).toHaveText('Delete the foo crate?');
await percy.snapshot();
+ await page.fill('[data-test-reason]', "I don't need this crate anymore");
await expect(page.locator('[data-test-delete-button]')).toBeDisabled();
await page.click('[data-test-confirmation-checkbox]');
await expect(page.locator('[data-test-delete-button]')).toBeEnabled();
@@ -72,6 +73,7 @@ test.describe('Route: crate.delete', { tag: '@routes' }, () => {
});
await page.goto('/crates/foo/delete');
+ await page.fill('[data-test-reason]', "I don't need this crate anymore");
await page.click('[data-test-confirmation-checkbox]');
await page.click('[data-test-delete-button]');
await expect(page.locator('[data-test-spinner]')).toBeVisible();
@@ -90,6 +92,7 @@ test.describe('Route: crate.delete', { tag: '@routes' }, () => {
});
await page.goto('/crates/foo/delete');
+ await page.fill('[data-test-reason]', "I don't need this crate anymore");
await page.click('[data-test-confirmation-checkbox]');
await page.click('[data-test-delete-button]');
await expect(page).toHaveURL('/crates/foo/delete');
diff --git a/tests/acceptance/crate-deletion-test.js b/tests/acceptance/crate-deletion-test.js
index 72ea46dbe50..c3664f57d9c 100644
--- a/tests/acceptance/crate-deletion-test.js
+++ b/tests/acceptance/crate-deletion-test.js
@@ -1,4 +1,4 @@
-import { click, currentURL } from '@ember/test-helpers';
+import { click, currentURL, fillIn } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'crates-io/tests/helpers';
@@ -29,6 +29,7 @@ module('Acceptance | crate deletion', function (hooks) {
assert.dom('[data-test-title]').hasText('Delete the foo crate?');
assert.dom('[data-test-delete-button]').isDisabled();
+ await fillIn('[data-test-reason]', "I don't need this crate anymore");
await click('[data-test-confirmation-checkbox]');
assert.dom('[data-test-delete-button]').isEnabled();
diff --git a/tests/routes/crate/delete-test.js b/tests/routes/crate/delete-test.js
index 2cd33a67bb9..dcf232b86da 100644
--- a/tests/routes/crate/delete-test.js
+++ b/tests/routes/crate/delete-test.js
@@ -1,4 +1,4 @@
-import { click, currentURL, waitFor } from '@ember/test-helpers';
+import { click, currentURL, fillIn, waitFor } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { defer } from 'rsvp';
@@ -58,6 +58,7 @@ module('Route: crate.delete', function (hooks) {
assert.dom('[data-test-title]').hasText('Delete the foo crate?');
await percySnapshot(assert);
+ await fillIn('[data-test-reason]', "I don't need this crate anymore");
assert.dom('[data-test-delete-button]').isDisabled();
await click('[data-test-confirmation-checkbox]');
assert.dom('[data-test-delete-button]').isEnabled();
@@ -79,6 +80,7 @@ module('Route: crate.delete', function (hooks) {
this.server.delete('/api/v1/crates/foo', deferred.promise);
await visit('/crates/foo/delete');
+ await fillIn('[data-test-reason]', "I don't need this crate anymore");
await click('[data-test-confirmation-checkbox]');
let clickPromise = click('[data-test-delete-button]');
await waitFor('[data-test-spinner]');
@@ -98,6 +100,7 @@ module('Route: crate.delete', function (hooks) {
this.server.delete('/api/v1/crates/foo', payload, 422);
await visit('/crates/foo/delete');
+ await fillIn('[data-test-reason]', "I don't need this crate anymore");
await click('[data-test-confirmation-checkbox]');
await click('[data-test-delete-button]');
assert.strictEqual(currentURL(), '/crates/foo/delete');