Merge branch 'main' into target-credential-library-api-modeling

This commit is contained in:
Susmitha Girumala authored and GitHub committed 2021-07-22 11:38:13 -04:00
commit 9dac6fc446
15 files changed
+241 -8

No files matched your search

+1
View File
@@ -485,6 +485,7 @@ export default function () {
this.get('/credential-stores/:id');
this.post('/credential-stores');
this.patch('/credential-stores/:id');
this.del('/credential-stores/:id');
// credential-libraries
@@ -271,6 +271,8 @@ credential-store:
title: Credential Store
title_plural: Credential Stores
description: A credential stores is a collection of credentials and credential libraries.
actions:
delete: Delete Credential Store
credential-library:
title: Credential Library
title_plural: Credential Libraries
@@ -278,4 +280,6 @@ credential-library:
messages:
none:
title: No Credential Libraries Available
description: No Credential Libraries available in this credential store.
description: No Credential Libraries available in this credential store.
actions:
create: New Credential Library
@@ -1,4 +1,4 @@
<div class="rose-form-checkbox{{if @error " error"}}">
<div class="rose-form-checkbox{{if @error " error"}} {{if @inline " inline"}}">
<Input
...attributes
@@ -68,3 +68,61 @@ Renders a form input checkbox.
}
}}</Story>
</Preview>
```htmlbars
<Rose::Form::Checkbox
@name="boolean-value"
@label="Yes?"
@checked={{false}}
@error={{false}}
@disabled={{false}}
@inline={{false}}
/>
```
<Preview>
<Story name="Checkbox with inline style" height="10rem">{{
template: hbs`
<Rose::Form::Checkbox
@name='checkbox-1'
@label='Checkbox1 🛎'
@description={{description}}
@helperText={{helperText}}
@checked={{checked}}
@error={{error}}
@disabled={{disabled}}
@inline={{inline}}
/>
<Rose::Form::Checkbox
@name='checkbox-2'
@label='Checkbox2 🛎'
@description={{description}}
@helperText={{helperText}}
@checked={{checked}}
@error={{error}}
@disabled={{disabled}}
@inline={{inline}}
/>
<Rose::Form::Checkbox
@name='checkbox-3'
@label='Checkbox3 🛎'
@description={{description}}
@helperText={{helperText}}
@checked={{checked}}
@error={{error}}
@disabled={{disabled}}
@inline={{inline}}
/>
`,
context: {
description: text('description', 'Short description in label'),
helperText: text('helperText', 'This is an optional help text.'),
checked: boolean('checked', false),
error: boolean('error', false),
disabled: boolean('disabled', false),
inline: boolean('inline', false)
}
}}</Story>
</Preview>
@@ -1,3 +1,3 @@
{{yield (hash
radio=(component 'rose/form/radio/radio' name=@name selectedValue=@selectedValue disabled=@disabled changed=@changed)
)}}
radio=(component 'rose/form/radio/radio' name=@name selectedValue=@selectedValue disabled=@disabled changed=@changed inline=@inline)
)}}
@@ -15,6 +15,7 @@ Renders a form radiofield group.
@name={{name}}
@selectedValue="disagree"
@changed={{fn}}
@inline={{false}}
as |radioGroup|
>
<radioGroup.radio
@@ -39,6 +40,7 @@ Renders a form radiofield group.
@name={{name}}
@selectedValue={{selectedValue}}
@changed={{changed}}
@inline={{inline}}
as |radioGroup|
>
<radioGroup.radio
@@ -59,6 +61,7 @@ Renders a form radiofield group.
context: {
name: text('name', 'mustagree'),
disabled: boolean('disabled', false),
inline: boolean('inline', true),
selectedValue: text('selectedValue', 'disagree'),
firstFieldLabel: text('first label', 'Agree'),
firstFieldValue: text('first value', 'agree'),
@@ -1,4 +1,4 @@
<div class="rose-form-radio{{if @error " error"}}">
<div class="rose-form-radio{{if @error " error"}} {{if @inline "inline"}}">
<RadioButton
...attributes
@@ -54,3 +54,71 @@ Renders a form radiofield.
}
}}</Story>
</Preview>
```htmlbars
<Rose::Form::Radio::Radio
@label="Yes"
@error={{false}}
@value="yes-agree"
@selectedValue="yes-agree"
@disabled={{false}}
@changed={{fn}}
@inline={{true}}
/>
```
<Preview>
<Story name="Radio with inline style" height="10rem">{{
template: hbs`
<Rose::Form::Radio::Radio
@label='Radiofield1'
@error={{error}}
@value={{value}}
@selectedValue={{selectedValue}}
@disabled={{disabled}}
@icon={{icon}}
@inline={{inline}}
/>
<Rose::Form::Radio::Radio
@label='Radiofield2'
@error={{error}}
@value={{value}}
@selectedValue={{selectedValue}}
@disabled={{disabled}}
@icon={{icon}}
@inline={{inline}}
/>
<Rose::Form::Radio::Radio
@label='Radiofield3'
@error={{error}}
@value={{value}}
@selectedValue={{selectedValue}}
@disabled={{disabled}}
@icon={{icon}}
@inline={{inline}}
/>
`,
context: {
error: boolean('error', false),
value: text('value', 'value and selectedValue must match to select radiofield'),
selectedValue: text(
'selectedValue',
'value and selectedValue must match to select radiofield'
),
disabled: boolean('disabled', false),
icon: select(
'icon',
{
'none': null,
'user-organization': 'user-organization',
'copy-action': 'copy-action',
'unfold-more': 'unfold-more',
'unfold-less': 'unfold-less',
},
null
),
inline: boolean('inline', false)
}
}}</Story>
</Preview>
@@ -2,6 +2,10 @@
@use '../../utilities/type';
.rose-form-checkbox {
&.inline {
display: inline-block;
margin-right: sizing.rems(s);
}
@include type.type(m);
position: relative;
margin-bottom: sizing.rems(m);
@@ -21,8 +21,13 @@ $radio-svg: (
);
$data-svg-prefix: 'data:image/svg+xml;utf-8,';
.rose-form-radio {
&.inline {
display: inline-block;
.rose-form-radio-label {
margin-right: sizing.rems(s);
}
}
@include type.type(m);
position: relative;
margin-bottom: sizing.rems(xs);
@@ -1,6 +1,7 @@
import Route from '@ember/routing/route';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeCredentialStoresRoute extends Route {
@@ -44,4 +45,19 @@ export default class ScopesScopeCredentialStoresRoute extends Route {
credentialStore.rollbackAttributes();
if (isNew) this.transitionTo('scopes.scope.credential-stores');
}
/**
* Deletes the credential store and redirects to index
* @param {CredentialStoreModel} credentialStore
*/
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(credentialStore) {
await credentialStore.destroyRecord();
await this.replaceWith('scopes.scope.credential-stores');
this.refresh();
}
}
@@ -10,7 +10,7 @@ export default class ScopesScopeCredentialStoresCredentialStoreRoute extends Rou
}
/**
* Render credential store header and navigation page sections.
* Render credential store header, navigation and actions page sections.
* @override
*/
renderTemplate() {
@@ -25,5 +25,10 @@ export default class ScopesScopeCredentialStoresCredentialStoreRoute extends Rou
into: 'scopes/scope/credential-stores/credential-store',
outlet: 'navigation',
});
this.render('scopes/scope/credential-stores/credential-store/-actions', {
into: 'scopes/scope/credential-stores/credential-store',
outlet: 'actions',
});
}
}
@@ -15,7 +15,7 @@
</page.navigation>
<page.actions>
{{!-- {{outlet 'actions'}} --}}
{{outlet 'actions'}}
</page.actions>
<page.body>
@@ -0,0 +1,17 @@
<Rose::Dropdown
@text={{t 'actions.manage'}}
@dropdownRight={{true}}
as |dropdown|
>
{{!-- <dropdown.link @route='scopes.scope.credential-stores.new' @model={{@model}}>
{{t 'resources.credential-library.actions.create'}}
</dropdown.link>
<dropdown.separator /> --}}
<dropdown.button
@style='danger'
@disabled={{@model.canSave}}
{{on 'click' (route-action 'delete' @model)}}
>
{{t 'resources.credential-store.actions.delete'}}
</dropdown.button>
</Rose::Dropdown>
@@ -5,6 +5,8 @@ import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
import { authenticateSession } from 'ember-simple-auth/test-support';
import { Response } from 'miragejs';
import { resolve, reject } from 'rsvp';
import sinon from 'sinon';
module('Acceptance | credential-stores', function (hooks) {
setupApplicationTest(hooks);
@@ -236,4 +238,54 @@ module('Acceptance | credential-stores', function (hooks) {
);
}
});
test('can delete credential store', async function (assert) {
assert.expect(1);
const count = getCredentialStoresCount();
await visit(urls.credentialStore);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(getCredentialStoresCount(), count - 1);
});
test('can accept delete credential store via dialog', async function (assert) {
assert.expect(2);
const confirmService = this.owner.lookup('service:confirm');
confirmService.enabled = true;
confirmService.confirm = sinon.fake.returns(resolve());
const count = getCredentialStoresCount();
await visit(urls.credentialStore);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(getCredentialStoresCount(), count - 1);
assert.ok(confirmService.confirm.calledOnce);
});
test('cannot cancel delete credential store via dialog', async function (assert) {
assert.expect(2);
const confirmService = this.owner.lookup('service:confirm');
confirmService.enabled = true;
confirmService.confirm = sinon.fake.returns(reject());
const count = getCredentialStoresCount();
await visit(urls.credentialStore);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(getCredentialStoresCount(), count);
assert.ok(confirmService.confirm.calledOnce);
});
test('deleting a credential store which errors displays error messages', async function (assert) {
assert.expect(1);
this.server.del('/credential-stores/:id', () => {
return new Response(
490,
{},
{
status: 490,
code: 'error',
message: 'Oops.',
}
);
});
await visit(urls.credentialStore);
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
});
});