refactor: 💡 add global settings link (#2093)

refactor: 💡 add global settings link (#2093)
This commit is contained in:
Lisbet Alvarez authored and GitHub committed 2024-01-17 08:37:09 -08:00
1 parent c48fdb2017
commit 9e0467cbf0
7 files changed
+112 -23

No files matched your search

+14 -9
View File
@@ -11,15 +11,20 @@ import generateId from '../helpers/id';
export default factory.extend({
type: 'global',
authorized_actions: () =>
permissions.authorizedActionsFor('scope') || [
'no-op',
'read',
'update',
'delete',
'attach-storage-policy',
'detach-storage-policy',
],
authorized_actions() {
const authorizedActions = ['no-op', 'read', 'update'];
// Storage policies can only be attatched to global and org scopes.
if (this.type === 'global' || this.type === 'org') {
authorizedActions.push('attach-storage-policy', 'detach-storage-policy');
}
if (this.type === 'org' || this.type === 'project') {
authorizedActions.push('delete');
}
return permissions.authorizedActionsFor('scope') || authorizedActions;
},
authorized_collection_actions() {
const collectionActions = {
@@ -326,6 +326,12 @@ session:
address-port: Address & port
ssh: SSH
shell: Shell
global:
title: Global
description: The global scope is the outermost scope. There is always a single global scope and it cannot be deleted.
messages:
settings:
title: Global Settings
org:
title: Org
title_plural: Orgs
+1 -1
View File
@@ -51,7 +51,7 @@
{{/if}}
</Hds::Form::Textarea::Field>
{{#if (can 'save model' @model)}}
{{#if (and (can 'save model' @model) (not @model.isGlobal))}}
<form.actions
@enableEditText={{t 'actions.edit-form'}}
@submitText={{t 'actions.save'}}
@@ -17,25 +17,18 @@ export default class ScopesScopeAddStoragePolicyIndexRoute extends Route {
// =methods
/**
* Load polcies from global and current scope
* Load policies from current scope
* @param {Model} model
*/
async afterModel() {
const { id: scope_id } = this.modelFor('scopes.scope');
//fetch policies from global scope
const globalScopePolicies = await this.store.query('policy', {
scope_id: 'global',
});
//fetch policies from org scope
//fetch policies from current scope
const orgScopePolicies = await this.store.query('policy', {
scope_id,
});
const policyList = [...globalScopePolicies, ...orgScopePolicies];
this.policyList = policyList;
this.policyList = orgScopePolicies;
}
/**
+10
View File
@@ -199,6 +199,16 @@
{{/unless}}
</Rose::Nav::Sidebar>
{{#if (and @model.isGlobal (feature-flag 'ssh-session-recording'))}}
{{#if this.session.data.authenticated.isGlobal}}
<Rose::Nav::Sidebar @title={{t 'titles.settings'}} as |nav|>
<nav.link @route='scopes.scope.edit'>
{{t 'resources.global.messages.settings.title'}}
</nav.link>
</Rose::Nav::Sidebar>
{{/if}}
{{/if}}
{{#if @model.isOrg}}
{{#if this.session.data.authenticated.isGlobal}}
<Rose::Nav::Sidebar @title={{t 'titles.settings'}} as |nav|>
+18 -1
View File
@@ -3,6 +3,16 @@
SPDX-License-Identifier: MPL-2.0
}}
{{#if @model.isGlobal}}
{{page-title (t 'resources.global.title')}}
<Breadcrumbs::Item
@text={{t 'resources.global.title'}}
@icon='globe'
@route='scopes.scope.edit'
@model={{@model.id}}
/>
{{/if}}
<Rose::Layout::Page as |page|>
<page.breadcrumbs>
@@ -10,6 +20,13 @@
</page.breadcrumbs>
<page.header>
{{#if @model.isGlobal}}
<h2>
{{t 'resources.global.title'}}
{{! TODO: Add doc link }}
</h2>
<p>{{t 'resources.global.description'}}</p>
{{/if}}
{{#if @model.isOrg}}
<h2>
{{t 'resources.org.title'}}
@@ -43,7 +60,7 @@
</page.navigation>
{{/if}}
{{#if (can 'delete model' @model)}}
{{#if (and (can 'delete model' @model) (not @model.isGlobal))}}
<page.actions>
<Rose::Dropdown
@text={{t 'actions.manage'}}
+60 -2
View File
@@ -19,6 +19,15 @@ module('Acceptance | scopes | read', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
let features;
let featureEdition;
const FORM_SELECTOR = 'main .rose-form';
const FORM_ACTIONS_SELECTOR = '.rose-form-actions';
const DELETE_DROPDOWN_SELECTOR =
'.rose-layout-page-actions .rose-dropdown-button-danger';
const STORAGE_POLICY_SIDEBAR = '.policy-sidebar';
const instances = {
scopes: {
global: null,
@@ -26,6 +35,8 @@ module('Acceptance | scopes | read', function (hooks) {
},
};
const urls = {
globalScope: null,
globalScopeEdit: null,
orgScope: null,
orgScopeEdit: null,
};
@@ -38,8 +49,12 @@ module('Acceptance | scopes | read', function (hooks) {
scope: { id: 'global', type: 'global' },
});
// Generate route URLs for resources
urls.globalScope = `/scopes/global/scopes`;
urls.globalScopeEdit = `/scopes/global/edit`;
urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`;
urls.orgScopeEdit = `/scopes/${instances.scopes.org.id}/edit`;
features = this.owner.lookup('service:features');
featureEdition = this.owner.lookup('service:featureEdition');
authenticateSession({ isGlobal: true });
});
@@ -51,7 +66,50 @@ module('Acceptance | scopes | read', function (hooks) {
await a11yAudit();
assert.strictEqual(currentURL(), urls.orgScopeEdit);
assert.dom('main .rose-form').exists();
assert.dom(FORM_SELECTOR).exists();
assert.dom(FORM_ACTIONS_SELECTOR).exists();
assert.dom(DELETE_DROPDOWN_SELECTOR).exists();
});
test('visiting global scope settings when feature flag is enabled', async function (assert) {
features.enable('ssh-session-recording');
await visit(urls.globalScope);
await a11yAudit();
await click(`[href="${urls.globalScopeEdit}"]`);
await a11yAudit();
assert.strictEqual(currentURL(), urls.globalScopeEdit);
assert.dom(FORM_SELECTOR).exists();
assert.dom(FORM_ACTIONS_SELECTOR).doesNotExist();
assert.dom(DELETE_DROPDOWN_SELECTOR).doesNotExist();
});
test('user cannot visit global scope settings when feature flag is not enabled', async function (assert) {
await visit(urls.globalScope);
assert.strictEqual(currentURL(), urls.globalScope);
assert.dom(`[href="${urls.globalScopeEdit}"]`).doesNotExist();
});
test('user can attatch a storage policy to a scope in enterprise edition', async function (assert) {
featureEdition.setEdition('enterprise', ['ssh-session-recording']);
await visit(urls.globalScope);
await click(`[href="${urls.globalScopeEdit}"]`);
assert.strictEqual(currentURL(), urls.globalScopeEdit);
assert.dom(STORAGE_POLICY_SIDEBAR).exists();
});
test('user can attatch a storage policy to a scope in hcp edition', async function (assert) {
featureEdition.setEdition('hcp', ['ssh-session-recording']);
await visit(urls.globalScope);
await click(`[href="${urls.globalScopeEdit}"]`);
assert.strictEqual(currentURL(), urls.globalScopeEdit);
assert.dom(STORAGE_POLICY_SIDEBAR).exists();
});
test('visiting org scope edit without read permission results in no form displayed', async function (assert) {
@@ -64,6 +122,6 @@ module('Acceptance | scopes | read', function (hooks) {
await click(`[href="${urls.orgScopeEdit}"]`);
assert.strictEqual(currentURL(), urls.orgScopeEdit);
assert.dom('main .rose-form').doesNotExist();
assert.dom(FORM_SELECTOR).doesNotExist();
});
});