diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs
index 2413fd29f..27e5abe80 100644
--- a/ui/admin/app/components/form/storage-bucket/index.hbs
+++ b/ui/admin/app/components/form/storage-bucket/index.hbs
@@ -60,9 +60,9 @@
as |F|
>
{{t 'resources.storage-bucket.form.scope.label'}}
- {{t
- 'resources.storage-bucket.form.scope.help'
- }}
+
+ {{t 'resources.storage-bucket.form.scope.help'}}
+
{{#each @scopes as |scope|}}
@@ -187,30 +187,32 @@
{{/if}}
-
- {{t
- 'resources.storage-bucket.form.secret_access_key.label'
- }}
- {{t
- 'resources.storage-bucket.form.secret_access_key.help'
- }}
- {{#if @model.errors.secret_access_key}}
-
- {{#each @model.errors.secret_access_key as |error|}}
- {{error.message}}
- {{/each}}
-
- {{/if}}
-
+ {{#if @model.isNew}}
+
+ {{t
+ 'resources.storage-bucket.form.secret_access_key.label'
+ }}
+ {{t
+ 'resources.storage-bucket.form.secret_access_key.help'
+ }}
+ {{#if @model.errors.secret_access_key}}
+
+ {{#each @model.errors.secret_access_key as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
+
+ {{/if}}
({ model: scope }));
- if (currentScope.id === 'global') {
- scopes = [{ model: currentScope }, ...orgScopes];
- } else {
- scopes = [
- { model: this.store.peekRecord('scope', 'global') },
- ...orgScopes,
- ];
- }
+ scopes = [
+ { model: this.store.peekRecord('scope', 'global') },
+ ...orgScopes,
+ ];
this.scopes = scopes;
}
diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js
index 687ffc78a..e2a7c1f89 100644
--- a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js
+++ b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js
@@ -4,5 +4,33 @@
*/
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
-export default class ScopesScopeStorageBucketsStorageBucketIndexRoute extends Route {}
+export default class ScopesScopeStorageBucketsStorageBucketIndexRoute extends Route {
+ // =services
+
+ @service store;
+
+ // =methods
+
+ async afterModel() {
+ let scopes;
+ const orgScopes = (
+ await this.store.query('scope', { scope_id: 'global' })
+ ).map((scope) => ({ model: scope }));
+ scopes = [
+ { model: this.store.peekRecord('scope', 'global') },
+ ...orgScopes,
+ ];
+ this.scopes = scopes;
+ }
+
+ /**
+ * Adds available global and org scopes to the context.
+ * @param {Controller} controller
+ */
+ setupController(controller) {
+ super.setupController(...arguments);
+ controller.set('scopes', this.scopes);
+ }
+}
diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs
index 3faf92ead..1ce337527 100644
--- a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs
+++ b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs
@@ -1,4 +1,41 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: MPL-2.0
-}}
\ No newline at end of file
+}}
+
+
+
+
+
+
+
+
+ {{t 'resources.storage-bucket.title'}}
+
+
+
+ {{@model.id}}
+
+
+
+
+
+
+ {{t 'titles.details'}}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/admin/tests/acceptance/storage-buckets/update-test.js b/ui/admin/tests/acceptance/storage-buckets/update-test.js
new file mode 100644
index 000000000..2b016ccb5
--- /dev/null
+++ b/ui/admin/tests/acceptance/storage-buckets/update-test.js
@@ -0,0 +1,98 @@
+import { module, test } from 'qunit';
+import { visit, click, fillIn } from '@ember/test-helpers';
+import { setupApplicationTest } from 'ember-qunit';
+import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
+import { Response } from 'miragejs';
+import {
+ authenticateSession,
+ // These are left here intentionally for future reference.
+ //currentSession,
+ //invalidateSession,
+} from 'ember-simple-auth/test-support';
+
+module('Acceptance | storage-buckets | update', function (hooks) {
+ setupApplicationTest(hooks);
+ setupMirage(hooks);
+
+ let features;
+
+ const instances = {
+ scopes: {
+ global: null,
+ },
+ storageBucket: null,
+ };
+
+ const urls = {
+ globalScope: null,
+ storageBuckets: null,
+ storageBucket: null,
+ };
+
+ hooks.beforeEach(function () {
+ instances.scopes.global = this.server.create('scope', { id: 'global' });
+ instances.storageBucket = this.server.create('storage-bucket', {
+ scope: instances.scopes.global,
+ });
+ urls.globalScope = `/scopes/global`;
+ urls.storageBuckets = `${urls.globalScope}/storage-buckets`;
+ (urls.storageBucket = `${urls.storageBuckets}/${instances.storageBucket.id}`),
+ (features = this.owner.lookup('service:features'));
+ features.enable('session-recording');
+ authenticateSession({});
+ });
+
+ test('can save changes to an existing storage-bucket', async function (assert) {
+ assert.expect(2);
+ await visit(urls.storageBucket);
+ await click('form [type="button"]', 'Click edit mode');
+ await fillIn('[name="name"]', 'Updated storage-bucket name');
+ await click('.rose-form-actions [type="submit"]');
+ assert.dom(`[href="${urls.storageBucket}"]`).isVisible();
+ assert
+ .dom('input[name="name"]')
+ .hasValue('Updated storage-bucket name');
+ });
+
+ test('can cancel changes to an existing storage-bucket', async function (assert) {
+ assert.expect(1);
+ const name = instances.storageBucket.name;
+ await visit(urls.storageBucket);
+ await click('form [type="button"]', 'Click edit mode');
+ await fillIn('[name="name"]', 'Updated storage-bucket name');
+ await click('.rose-form-actions [type="button"]');
+ await assert.dom('input[name="name"]').hasValue(`${name}`);
+ });
+
+ test('saving an existing storage-bucket with invalid fields will display error messages', async function (assert) {
+ assert.expect(2);
+ await visit(urls.storageBuckets);
+ this.server.patch('/storage-buckets/:id', () => {
+ return new Response(
+ 400,
+ {},
+ {
+ status: 400,
+ code: 'invalid_argument',
+ message: 'The request was invalid.',
+ details: {
+ request_fields: [
+ {
+ name: 'region',
+ description: 'Region is required.',
+ },
+ ],
+ },
+ }
+ );
+ });
+
+ await click(`[href="${urls.storageBucket}"]`);
+ await click('.rose-form-actions [type="button"]', 'Activate edit mode');
+ await fillIn('[name="region"]', 'random string');
+ await click('[type="submit"]');
+
+ assert.dom('[role="alert"] div').hasText('The request was invalid.');
+ assert.dom('.hds-form-error__message').hasText('Region is required.');
+ });
+});
diff --git a/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js
new file mode 100644
index 000000000..d924847b6
--- /dev/null
+++ b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js
@@ -0,0 +1,16 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'admin/tests/helpers';
+
+module(
+ 'Unit | Controller | scopes/scope/storage-buckets/storage-bucket',
+ function (hooks) {
+ setupTest(hooks);
+
+ test('it exists', function (assert) {
+ let controller = this.owner.lookup(
+ 'controller:scopes/scope/storage-buckets/storage-bucket'
+ );
+ assert.ok(controller);
+ });
+ }
+);