feat: 🎸 Add more features to the credential stores list
Add breadcrumb functionality. Add detail route. Add acceptance test to
load the page. Add some styling improvements
✅ Closes: \
This commit is contained in:
1 parent
986cde5941
commit
75f45a134d
9 files changed
+178
-52
No files matched your search
@@ -0,0 +1,17 @@
|
||||
import Controller from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeCredentialStoresController extends Controller {
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
|
||||
// = attributes
|
||||
/**
|
||||
* Translated breadcrumb
|
||||
* @type {string}
|
||||
*/
|
||||
get breadCrumb() {
|
||||
return this.intl.t('resources.credential-store.title_plural');
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,9 @@ Router.map(function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
this.route('credential-stores', function () {});
|
||||
this.route('credential-stores', function () {
|
||||
this.route('credential-store', { path: ':credential_store_id' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeCredentialStoresCredentialStoreRoute extends Route {
|
||||
/**
|
||||
* Load a specific credential store in current scope
|
||||
* @return {Promise[CredentialStoreModel]}
|
||||
*/
|
||||
async model({ credential_store_id }) {
|
||||
return this.route.findRecord('credential-store', credential_store_id);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,3 @@
|
||||
<Rose::Layout::Page as |page|>
|
||||
{{! <page.breadcrumbs>
|
||||
<BreadCrumbs />
|
||||
</page.breadcrumbs> }}
|
||||
{{page-title (t 'resources.credential-store.title_plural')}}
|
||||
|
||||
<page.header>
|
||||
<h2>
|
||||
{{t 'resources.credential-store.title_plural'}}
|
||||
</h2>
|
||||
{{t 'resources.credential-store.description'}}
|
||||
</page.header>
|
||||
|
||||
{{!-- <page.actions>
|
||||
{{#if @model}}
|
||||
<Rose::LinkButton
|
||||
@route='scopes.scope.credential-stores.new'
|
||||
@style='primary'
|
||||
>
|
||||
{{t 'titles.new'}}
|
||||
</Rose::LinkButton>
|
||||
{{/if}}
|
||||
</page.actions> --}}
|
||||
|
||||
<page.body>
|
||||
{{#if @model}}
|
||||
<Rose::Table as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell>{{t 'form.name.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.type.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.id.label'}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
|
||||
<table.body as |body|>
|
||||
{{#each @model as |credentialStore|}}
|
||||
<body.row as |row|>
|
||||
<row.headerCell>
|
||||
{{credentialStore.displayName}}
|
||||
<p>{{credentialStore.description}}</p>
|
||||
</row.headerCell>
|
||||
<row.cell>{{credentialStore.type}}</row.cell>
|
||||
<row.cell>{{credentialStore.id}}</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
{{/if}}
|
||||
</page.body>
|
||||
</Rose::Layout::Page>
|
||||
{{outlet}}
|
||||
@@ -0,0 +1,2 @@
|
||||
{{page-title 'CredentialStore'}}
|
||||
{{outlet}}
|
||||
@@ -1,2 +1,65 @@
|
||||
{{page-title 'Index'}}
|
||||
{{outlet}}
|
||||
<Rose::Layout::Page as |page|>
|
||||
<page.breadcrumbs>
|
||||
<BreadCrumbs />
|
||||
</page.breadcrumbs>
|
||||
|
||||
<page.header>
|
||||
<h2>
|
||||
{{t 'resources.credential-store.title_plural'}}
|
||||
</h2>
|
||||
{{t 'resources.credential-store.description'}}
|
||||
</page.header>
|
||||
|
||||
{{!-- <page.actions>
|
||||
{{#if @model}}
|
||||
<Rose::LinkButton
|
||||
@route='scopes.scope.credential-stores.new'
|
||||
@style='primary'
|
||||
>
|
||||
{{t 'titles.new'}}
|
||||
</Rose::LinkButton>
|
||||
{{/if}}
|
||||
</page.actions> --}}
|
||||
|
||||
<page.body>
|
||||
{{#if @model}}
|
||||
<Rose::Table as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell>{{t 'form.name.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.type.label'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'form.id.label'}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
|
||||
<table.body as |body|>
|
||||
{{#each @model as |credentialStore|}}
|
||||
<body.row as |row|>
|
||||
<row.headerCell>
|
||||
<LinkTo
|
||||
@route='scopes.scope.credential-stores.credential-store'
|
||||
@model={{credentialStore.id}}
|
||||
>
|
||||
{{credentialStore.displayName}}
|
||||
</LinkTo>
|
||||
<p>{{credentialStore.description}}</p>
|
||||
</row.headerCell>
|
||||
<row.cell>
|
||||
<Rose::Badge>{{credentialStore.type}}</Rose::Badge>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<Copyable
|
||||
@text={{credentialStore.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{credentialStore.id}}</code>
|
||||
</Copyable>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
{{/if}}
|
||||
</page.body>
|
||||
</Rose::Layout::Page>
|
||||
@@ -0,0 +1,48 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { visit, currentURL } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
|
||||
module('Acceptance | credential-stores', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
project: null,
|
||||
},
|
||||
};
|
||||
|
||||
const urls = {
|
||||
globalScope: null,
|
||||
credentialStores: null,
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
// Generate resources
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.scopes.org = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: { id: 'global', type: 'global' },
|
||||
});
|
||||
instances.scopes.project = this.server.create('scope', {
|
||||
type: 'project',
|
||||
scope: { id: instances.scopes.org.id, type: 'org' },
|
||||
});
|
||||
// Generate route URLs for resources
|
||||
urls.globalScope = `/scopes/global/scopes`;
|
||||
urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`;
|
||||
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
|
||||
urls.credentialStores = `${urls.projectScope}/credential-stores`;
|
||||
});
|
||||
|
||||
test('visiting /credential-stores', async function (assert) {
|
||||
assert.expect(1);
|
||||
await visit(urls.credentialStores);
|
||||
await a11yAudit();
|
||||
assert.equal(currentURL(), urls.credentialStores);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Controller | scopes/scope/credential-stores', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup(
|
||||
'controller:scopes/scope/credential-stores'
|
||||
);
|
||||
assert.ok(controller);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/credential-stores/credential-store',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
'route:scopes/scope/credential-stores/credential-store'
|
||||
);
|
||||
assert.ok(route);
|
||||
});
|
||||
}
|
||||
);
|
||||
Reference in new issue
Block a user