Merge branch 'main' into checkbox-style-updates

This commit is contained in:
Dharini Jeeva authored and GitHub committed 2021-11-11 10:52:46 -08:00
commit 6d8fddc3cb
30 files changed
+404 -19

No files matched your search

+8
View File
@@ -5,6 +5,14 @@ import { A } from '@ember/array';
export default class ManagedGroupModel extends GeneratedManagedGroupModel {
// =attributes
// =error attributes
// These attributes exist solely to capture errors on nested fields.
// See the application adapter's error normalization method for
// more information.
@attr('string', { readOnly: true }) attributes_filter;
/**
* Members is read-only under normal circumstances. But members can
* be persisted via calls to `addMembers()` or `removeMembers()`.
+3
View File
@@ -521,6 +521,9 @@ export default function () {
return managedGroups.where({ authMethodId });
}
);
this.get('/managed-groups/:id');
this.del('/managed-groups/:id');
this.post('/managed-groups');
/* Uncomment the following line and the Response import above
* Then change the response code to simulate error responses.
+3 -1
View File
@@ -34,7 +34,9 @@ export default factory.extend({
user.update({ accountIds: [id] });
});
server.createList('managed-group', 2, { scope, authMethod });
if (type === 'oidc') {
server.createList('managed-group', 2, { scope, authMethod });
}
},
}),
});
@@ -1,8 +1,12 @@
import factory from '../generated/factories/managed-group';
import { random } from 'faker';
import permissions from '../helpers/permissions';
const types = ['oidc'];
export default factory.extend({
id: (i) => `managed-groups-id-${i}`,
type: (i) => types[i % types.length],
authorized_actions: () =>
permissions.authorizedActionsFor('managed-group') || [
@@ -11,4 +15,13 @@ export default factory.extend({
'update',
'delete',
],
attributes() {
switch (this.type) {
case 'oidc':
return {
filter: random.words(),
};
}
},
});
@@ -11,15 +11,4 @@ export default Factory.extend({
created_time: () => date.recent(),
updated_time: () => date.recent(),
version: () => datatype.number(),
type: 'oidc',
attributes: function () {
switch (this.type) {
case 'oidc':
return {
filter: random.words(),
};
default:
return;
}
},
});
+1 -1
View File
@@ -22,7 +22,7 @@ export default function (server) {
// Auth
const globalAuthMethods = server.createList(
'auth-method',
1,
4,
{ scope: globalScope },
'withAccountsAndUsersAndManagedGroups'
);
+3
View File
@@ -115,3 +115,6 @@ value:
callback_url:
label: Callback URL
help: The URL to which the third-party provider sends the authentication response. Paste this into the provider configuration.
filter:
label: Filter
help: A boolean expression defining a filter run against the provided information.
@@ -354,3 +354,7 @@ scope:
managed-group:
title: Managed Group
title_plural: Managed Groups
description: A managed group represents a collection of accounts.
actions:
delete: Delete Managed Group
create: Create Managed Group
@@ -0,0 +1,79 @@
<Rose::Form
@onSubmit={{@submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
@error={{@model.errors.base}}
@showEditToggle={{if @model.isNew false true}}
as |form|
>
<form.input
@value={{@model.type}}
@label={{t 'form.type.label'}}
readonly={{true}}
@disabled={{true}}
/>
<form.input
@name='name'
@type='name'
@value={{@model.name}}
@label={{t 'form.name.label'}}
@helperText={{t 'form.name.help'}}
@error={{@model.error.name}}
readonly={{false}}
as |field|
>
{{#if @model.errors.name}}
<field.errors as |errors|>
{{#each @model.errors.name as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
<form.textarea
@name='description'
@type='description'
@value={{@model.description}}
@label={{t 'form.description.label'}}
@error={{@model.errors.description}}
@helperText={{t 'form.description.help'}}
disabled={{@model.isSaving}}
readonly={{false}}
as |field|
>
{{#if @model.errors.description}}
<field.errors as |errors|>
{{#each @model.errors.description as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.textarea>
<form.input
@name='filter'
@type='text'
@value={{@model.attributes.filter}}
@label={{t 'form.filter.label'}}
@error={{@model.errors.attributes_filter}}
@helperText={{t 'form.filter.help'}}
as |field|
>
{{#if @model.errors.filter}}
<field.errors as |errors|>
{{#each @model.errors.filter as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
<form.actions
@disabled={{if @model.cannotSave @model.cannotSave}}
@enableEditText={{t 'actions.edit-form'}}
@submitText={{t 'actions.save'}}
@cancelText={{t 'actions.cancel'}}
/>
</Rose::Form>
+8 -1
View File
@@ -55,7 +55,14 @@ Router.map(function () {
});
this.route('new');
});
this.route('managed-groups', function () {});
this.route('managed-groups', function () {
this.route(
'managed-group',
{ path: ':managed_group_id' },
function () {}
);
this.route('new');
});
});
this.route('new');
});
@@ -1,6 +1,19 @@
import Route from '@ember/routing/route';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import loading from 'ember-loading/decorator';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsRoute extends Route {
// =services
@service intl;
@service notify;
@service can;
//=methods
/**
*
* @returns {Promise{[ManagedGroupsModel]}}
@@ -10,4 +23,53 @@ export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsRoute extends
const { id: auth_method_id } = authMethod;
return this.store.query('managed-group', { auth_method_id });
}
// =actions
/**
* Rollback changes on a managed group.
* @param {ManagedGroupModel} managedGroup
*/
@action
cancel(managedGroup) {
const { isNew } = managedGroup;
managedGroup.rollbackAttributes();
if (isNew) {
this.transitionTo('scopes.scope.auth-methods.auth-method.managed-groups');
}
}
/**
* Save a managed group in current scope.
* @param {ManagedGroupModel} managedGroup
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) =>
isNew ? 'notifications.create-success' : 'notifications.save-success'
)
async save(managedGroup) {
await managedGroup.save();
await this.transitionTo(
'scopes.scope.auth-methods.auth-method.managed-groups'
);
this.refresh();
}
/**
* Delete a managed group in current scope and redirect to index
* @param {ManagedGroupModel} managed group
*/
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async deleteManagedGroup(managedGroup) {
await managedGroup.destroyRecord();
await this.replaceWith(
'scopes.scope.auth-methods.auth-method.managed-groups'
);
this.refresh();
}
}
@@ -1,3 +1,9 @@
import Route from '@ember/routing/route';
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsIndexRoute extends Route {}
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsIndexRoute extends Route {
setupController(controller) {
const authMethod = this.modelFor('scopes.scope.auth-methods.auth-method');
super.setupController(...arguments);
controller.setProperties({ authMethod });
}
}
@@ -0,0 +1,49 @@
import Route from '@ember/routing/route';
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsManagedGroupRoute extends Route {
// =methods
/**
* Load managed group by ID.
* @param {object} params
* @param {string} params.managed_group_id
* @returns {ManagedGroupModel}
*/
model({ managed_group_id }) {
return this.store.findRecord('managed-group', managed_group_id, {
reload: true,
});
}
/**
* Render the route-set specific page sections
* @override
*/
renderTemplate() {
super.renderTemplate(...arguments);
this.render(
'scopes/scope/auth-methods/auth-method/managed-groups/managed-group/-header',
{
into: 'scopes/scope/auth-methods/auth-method',
outlet: 'header',
}
);
this.render(
'scopes/scope/auth-methods/auth-method/managed-groups/managed-group/-actions',
{
into: 'scopes/scope/auth-methods/auth-method',
outlet: 'actions',
}
);
this.render(
'scopes/scope/auth-methods/auth-method/managed-groups/managed-group/-navigation',
{
into: 'scopes/scope/auth-methods/auth-method',
outlet: 'navigation',
}
);
}
}
@@ -0,0 +1,3 @@
import Route from '@ember/routing/route';
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsManagedGroupIndexRoute extends Route {}
@@ -0,0 +1,36 @@
import Route from '@ember/routing/route';
export default class ScopesScopeAuthMethodsAuthMethodManagedGroupsNewRoute extends Route {
// =methods
model() {
const { id: auth_method_id, type } = this.modelFor(
'scopes.scope.auth-methods.auth-method'
);
return this.store.createRecord('managed-group', {
type,
auth_method_id,
});
}
renderTemplate() {
super.renderTemplate(...arguments);
this.render(
'scopes/scope/auth-methods/auth-method/managed-groups/new/-header',
{
into: 'scopes/scope/auth-methods/auth-method',
outlet: 'header',
}
);
this.render('_empty', {
into: 'scopes/scope/auth-methods/auth-method',
outlet: 'actions',
});
this.render('_empty', {
into: 'scopes/scope/auth-methods/auth-method',
outlet: 'navigation',
});
}
}
@@ -67,6 +67,18 @@
</dropdown.link>
{{/if}}
{{#if (feature-flag 'managed-groups')}}
{{! TODO: Add capabilities }}
{{#if @model.isOIDC}}
<dropdown.link
@route='scopes.scope.auth-methods.auth-method.managed-groups.new'
@model={{@model}}
>
{{t 'resources.managed-group.actions.create'}}
</dropdown.link>
{{/if}}
{{/if}}
{{#if (can 'delete model' @model)}}
<dropdown.separator />
<dropdown.button
@@ -10,8 +10,10 @@
{{/if}}
{{#if (feature-flag 'managed-groups')}}
<nav.link @route='scopes.scope.auth-methods.auth-method.managed-groups'>
{{t 'resources.managed-group.title_plural'}}
</nav.link>
{{#if @model.isOIDC}}
<nav.link @route='scopes.scope.auth-methods.auth-method.managed-groups'>
{{t 'resources.managed-group.title_plural'}}
</nav.link>
{{/if}}
{{/if}}
</Rose::Nav::Tabs>
@@ -12,7 +12,18 @@
<table.body as |body|>
{{#each @model as |managed-group|}}
<body.row as |row|>
<row.headerCell>{{managed-group.name}}</row.headerCell>
<row.headerCell>
{{#if (can 'read model' managed-group)}}
<LinkTo
@route='scopes.scope.auth-methods.auth-method.managed-groups.managed-group'
@model={{managed-group.id}}
>
{{managed-group.displayName}}
</LinkTo>
{{else}}
{{managed-group.displayName}}
{{/if}}
</row.headerCell>
<row.cell>{{managed-group.description}}</row.cell>
<row.cell>
<Rose::Badge>{{managed-group.type}}</Rose::Badge>
@@ -0,0 +1,2 @@
{{page-title 'ManagedGroup'}}
{{outlet}}
@@ -0,0 +1,15 @@
{{#if (can 'delete model' @model)}}
<Rose::Dropdown
@text={{t 'actions.manage'}}
@dropdownRight={{true}}
as |dropdown|
>
<dropdown.button
@style='danger'
@disabled={{@model.canSave}}
{{on 'click' (route-action 'deleteManagedGroup' @model)}}
>
{{t 'resources.managed-group.actions.delete'}}
</dropdown.button>
</Rose::Dropdown>
{{/if}}
@@ -0,0 +1,12 @@
<h2>
{{t 'resources.managed-group.title'}}
<DocLink @doc='managed-groups' @iconSize='large' />
</h2>
<p>{{t 'resources.managed-group.description'}}</p>
<Copyable
@text={{@model.id}}
@buttonText={{t 'actions.copy-to-clipboard'}}
@acknowledgeText={{t 'states.copied'}}
>
<code>{{@model.id}}</code>
</Copyable>
@@ -0,0 +1,7 @@
<Rose::Nav::Tabs as |nav|>
<nav.link
@route='scopes.scope.auth-methods.auth-method.managed-groups.managed-group.index'
>
{{t 'titles.details'}}
</nav.link>
</Rose::Nav::Tabs>
@@ -0,0 +1 @@
<Form::ManagedGroup @model={{@model}} />
@@ -0,0 +1,5 @@
<Form::ManagedGroup
@model={{@model}}
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
/>
@@ -0,0 +1,5 @@
<h2>
{{t 'titles.new'}}
{{! TODO: change the icon link }}
<DocLink @doc='account.new' @iconSize='large' />
</h2>
+1
View File
@@ -48,6 +48,7 @@ module.exports = function (environment) {
account: '/accounts',
'account.new': '/accounts/new',
'auth-method': '/auth-methods',
'managed-groups': '/managed-groups',
group: '/groups',
'group.add-members': '/groups/add-members',
'host-catalog': '/host-catalogs',
@@ -0,0 +1,16 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/managed-group',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/auth-methods/auth-method/managed-groups/managed-group'
);
assert.ok(route);
});
}
);
@@ -0,0 +1,16 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/managed-group/index',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/auth-methods/auth-method/managed-groups/managed-group/index'
);
assert.ok(route);
});
}
);
@@ -0,0 +1,16 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/auth-methods/auth-method/managed-groups/new',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/auth-methods/auth-method/managed-groups/new'
);
assert.ok(route);
});
}
);