refactor: 💡 add global settings link (#2093)
refactor: 💡 add global settings link (#2093)
This commit is contained in:
1 parent
c48fdb2017
commit
9e0467cbf0
7 files changed
+112
-23
No files matched your search
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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|>
|
||||
|
||||
@@ -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'}}
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user