Merge pull request #284 from hashicorp/feature-doc-links

feat: 🎸 add doc-url helper and doc-link component
This commit is contained in:
Susmitha Girumala authored and GitHub committed 2020-10-05 19:44:49 -04:00
commit ecf74b73ac
41 files changed
+232 -41

No files matched your search

+2 -2
View File
@@ -4,7 +4,7 @@ module.exports = {
extends: 'octane',
rules: {
'no-bare-strings': true,
'no-curly-component-invocation': { allow: ['app-name'] },
'no-implicit-this': { allow: ['app-name'] }
'no-curly-component-invocation': { allow: ['app-name', 'company-name', 'company-copyright'] },
'no-implicit-this': { allow: ['app-name', 'company-name', 'company-copyright', 'doc-url'] }
}
};
@@ -0,0 +1,8 @@
<a
class="doc-link"
href={{doc-url @doc}}
target="_blank"
rel="noreferrer noopener"
title={{t "actions.get-topic-help"}}>
<Rose::Icon @name="help-circle-outline" @size={{@iconSize}} />
</a>
+7
View File
@@ -0,0 +1,7 @@
import { helper } from '@ember/component/helper';
import config from '../config/environment';
export default helper(function companyCopyright() {
const currentYear = new Date().getFullYear();
return `© ${currentYear} ${config.companyName}`;
});
+6
View File
@@ -0,0 +1,6 @@
import { helper } from '@ember/component/helper';
import config from '../config/environment';
export default helper(function companyName() {
return config.companyName;
});
+18
View File
@@ -0,0 +1,18 @@
import { helper } from '@ember/component/helper';
import { get } from '@ember/object';
import { assert } from '@ember/debug';
import config from '../config/environment';
export default helper(function docUrl(params/*, hash*/) {
const baseURL = config.documentation.baseURL;
const docKey = params[0] || '';
const configuredPath = get(config.documentation, docKey);
if (docKey) {
assert(`
Documentation for "${docKey}" could not be found. Please ensure that
this key exists under "documentation" in your app config.
`, configuredPath);
}
const path = configuredPath || '';
return `${baseURL}${path}`;
});
@@ -23,7 +23,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
super.renderTemplate(...arguments);
this.render(
'scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/-header',
'scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/-header',
{
into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
outlet: 'header',
@@ -32,7 +32,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
);
this.render(
'scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/-navigation',
'scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/-navigation',
{
into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
outlet: 'navigation',
@@ -41,7 +41,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
);
this.render(
'scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/-actions',
'scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/-actions',
{
into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
outlet: 'actions',
@@ -23,7 +23,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsHostR
super.renderTemplate(...arguments);
this.render(
'scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-header',
'scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/-header',
{
into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
outlet: 'header',
@@ -32,7 +32,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsHostR
);
this.render(
'scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-navigation',
'scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/-navigation',
{
into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
outlet: 'navigation',
@@ -41,7 +41,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsHostR
);
this.render(
'scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-actions',
'scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/-actions',
{
into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
outlet: 'actions',
+6 -4
View File
@@ -59,11 +59,13 @@
<layout.footer>
<Rose::Footer as |footer|>
<footer.brand @logo="logo-hashi" @text={{t "hashicorp.title"}} />
<footer.text>{{t "hashicorp.copyright"}}</footer.text>
<footer.text>{{t "hashicorp.product"}}</footer.text>
<footer.brand @logo="logo-hashi" @text={{company-name}} />
<footer.text>{{company-copyright}}</footer.text>
<footer.text>{{app-name}}</footer.text>
<footer.nav as |nav|>
<nav.link @href={{t "hashicorp.documentation.link"}}>{{t "hashicorp.documentation.title"}}</nav.link>
<nav.link @href={{doc-url}}>
{{t "titles.documentation"}}
</nav.link>
</footer.nav>
</Rose::Footer>
</layout.footer>
@@ -1,4 +1,7 @@
<h2>{{t "resources.auth-method.title"}}</h2>
<h2>
{{t "resources.auth-method.title"}}
<DocLink @doc="topics.auth-method" @iconSize="large" />
</h2>
<p>{{t "resources.auth-method.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.account.title"}}</h2>
<h2>
{{t "resources.account.title"}}
<DocLink @doc="topics.account" @iconSize="large" />
</h2>
<Copyable
@text={{@model.id}}
@buttonText={{t "actions.copy-to-clipboard"}}
@@ -1,6 +1,9 @@
<Rose::Layout::Page as |page|>
<page.header>
<h2>{{t "resources.auth-method.title_plural"}}</h2>
<h2>
{{t "resources.auth-method.title_plural"}}
<DocLink @doc="topics.auth-method" @iconSize="large" />
</h2>
<p>{{t "resources.auth-method.description"}}</p>
</page.header>
@@ -1,4 +1,7 @@
<h2>{{t "resources.group.title"}}</h2>
<h2>
{{t "resources.group.title"}}
<DocLink @doc="topics.group" @iconSize="large" />
</h2>
<p>{{t "resources.group.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.group.title_plural"}}</h2>
<h2>
{{t "resources.group.title_plural"}}
<DocLink @doc="topics.group" @iconSize="large" />
</h2>
<p>{{t "resources.group.description"}}</p>
</page.header>
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.org.title_plural"}}</h2>
<h2>
{{t "resources.org.title_plural"}}
<DocLink @doc="topics.org" @iconSize="large" />
</h2>
{{#if @model}}
<p>{{t "resources.org.description"}}</p>
{{/if}}
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.project.title_plural"}}</h2>
<h2>
{{t "resources.project.title_plural"}}
<DocLink @doc="topics.project" @iconSize="large" />
</h2>
{{#if @model}}
<p>{{t "resources.project.description"}}</p>
{{/if}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.host-catalog.title"}}</h2>
<h2>
{{t "resources.host-catalog.title"}}
<DocLink @doc="topics.host-catalog" @iconSize="large" />
</h2>
<p>{{t "resources.host-catalog.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.host-set.title"}}</h2>
<h2>
{{t "resources.host-set.title"}}
<DocLink @doc="topics.host-set" @iconSize="large" />
</h2>
<p>{{t "resources.host-set.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.host.title"}}</h2>
<h2>
{{t "resources.host.title"}}
<DocLink @doc="topics.host" @iconSize="large" />
</h2>
<p>{{t "resources.host.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.host-catalog.title_plural"}}</h2>
<h2>
{{t "resources.host-catalog.title_plural"}}
<DocLink @doc="topics.host-catalog" @iconSize="large" />
</h2>
<p>{{t "resources.host-catalog.description"}}</p>
</page.header>
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.project.title"}}</h2>
<h2>
{{t "resources.project.title"}}
<DocLink @doc="topics.project" @iconSize="large" />
</h2>
<p>{{t "resources.project.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.session.title_plural"}}</h2>
<h2>
{{t "resources.session.title_plural"}}
<DocLink @doc="topics.session" @iconSize="large" />
</h2>
<p>{{t "resources.session.description"}}</p>
</page.header>
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.target.title_plural"}}</h2>
<h2>
{{t "resources.target.title_plural"}}
<DocLink @doc="topics.target" @iconSize="large" />
</h2>
{{#if @model}}
<p>{{t "resources.target.description"}}</p>
{{/if}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.target.title"}}</h2>
<h2>
{{t "resources.target.title"}}
<DocLink @doc="topics.target" @iconSize="large" />
</h2>
<p>{{t "resources.target.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.role.title_plural"}}</h2>
<h2>
{{t "resources.role.title_plural"}}
<DocLink @doc="topics.role" @iconSize="large" />
</h2>
{{#if @model}}
<p>{{t "resources.role.description"}}</p>
{{/if}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.role.title"}}</h2>
<h2>
{{t "resources.role.title"}}
<DocLink @doc="topics.role" @iconSize="large" />
</h2>
<p>{{t "resources.role.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.role.title"}}</h2>
<h2>
{{t "resources.role.title"}}
<DocLink @doc="topics.role" @iconSize="large" />
</h2>
<p>{{t "resources.role.grant.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -6,4 +9,4 @@
@acknowledgeText={{t "states.copied"}}
>
<code>{{@model.id}}</code>
</Copyable>
</Copyable>
@@ -1,4 +1,7 @@
<h2>{{t "resources.role.title"}}</h2>
<h2>
{{t "resources.role.title"}}
<DocLink @doc="topics.role" @iconSize="large" />
</h2>
<p>{{t "resources.role.principal.description"}}</p>
<Copyable
@text={{@model.id}}
@@ -5,7 +5,10 @@
</page.breadcrumbs>
<page.header>
<h2>{{t "resources.user.title_plural"}}</h2>
<h2>
{{t "resources.user.title_plural"}}
<DocLink @doc="topics.user" @iconSize="large" />
</h2>
{{#if @model}}
<p>{{t "resources.user.description"}}</p>
{{/if}}
@@ -1,4 +1,7 @@
<h2>{{t "resources.user.title"}}</h2>
<h2>
{{t "resources.user.title"}}
<DocLink @doc="topics.user" @iconSize="large" />
</h2>
<p>{{t "resources.user.description"}}</p>
<Copyable
@text={{@model.id}}
+19
View File
@@ -32,11 +32,30 @@ module.exports = function (environment) {
},
appName: APP_NAME,
companyName: 'HashiCorp',
notifyTimeout: 4000,
sessionPollingTimeoutSeconds: 2.5,
enableConfirmService: true,
documentation: {
baseURL: 'https://boundaryproject.io/help/admin-ui',
topics: {
org: '/org',
project: '/project',
account: '/account',
'auth-method': '/auth-method',
group: '/group',
'host-catalog': '/host-catalog',
'host-set': '/host-set',
host: '/host',
role: '/role',
session: '/session',
target: '/target',
user: '/user'
}
},
contentSecurityPolicyHeader: 'Content-Security-Policy',
contentSecurityPolicyMeta: true,
contentSecurityPolicy: {
@@ -0,0 +1,14 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | doc-link', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
assert.expect(1);
await render(hbs`<DocLink @doc="topics.account" @iconSize="large" />`);
assert.ok(find('.doc-link .rose-icon.large'));
});
});
@@ -7,6 +7,7 @@ module('Integration | Helper | app-name', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
assert.expect(1);
await render(hbs`{{app-name}}`);
assert.equal(this.element.textContent.trim(), 'Boundary');
});
@@ -0,0 +1,15 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Helper | company-copyright', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
assert.expect(1);
const currentYear = new Date().getFullYear();
await render(hbs`{{company-copyright}}`);
assert.equal(this.element.textContent.trim(), `© ${currentYear} HashiCorp`);
});
});
@@ -0,0 +1,14 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Helper | company-name', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
assert.expect(1);
await render(hbs`{{company-name}}`);
assert.equal(this.element.textContent.trim(), 'HashiCorp');
});
});
@@ -0,0 +1,29 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import config from 'ember-get-config';
module('Integration | Helper | doc-url', function(hooks) {
setupRenderingTest(hooks);
test('it renders a URL generated from the documentation config', async function(assert) {
assert.expect(3);
const baseURL = config.documentation.baseURL;
const path = config.documentation.topics.account;
await render(hbs`{{doc-url 'topics.account'}}`);
assert.ok(baseURL);
assert.ok(path);
assert.equal(this.element.textContent.trim(), `${baseURL}${path}`);
});
test('it throws an error if the specified documentation path cannot be found', async function(assert) {
assert.expect(2);
const helper = this.owner.lookup('helper:doc-url');
assert.ok(helper.compute(['topics.account']), 'Specified document exists.')
assert.throws(() => {
helper.compute(['no.such.doc']);
}, 'Specified documentation was not found, so the helper threw an error.');
});
});
+1
View File
@@ -7,6 +7,7 @@ save: Save
manage: Manage
help: Need help?
back: Back
get-topic-help: Get help for this topic
copy-to-clipboard: Copy to Clipboard
authenticate: Authenticate
deauthenticate: Deauthenticate
+1 -7
View File
@@ -16,15 +16,9 @@ titles:
empty-set: No Items Yet
global: Global
actions: Actions
documentation: Documentation
descriptions:
empty-set: There are no items to display yet. You may be able to add items or try back later.
questions:
delete-confirm: Are you sure you want to delete this resource?
remove-confirm: Are you sure you want to remove this association?
hashicorp:
title: HashiCorp
copyright: © 2020 HashiCorp
product: Boundary v0.1
documentation:
title: Documentation
link: https://boundaryproject.io