diff --git a/ui/core/.template-lintrc.js b/ui/core/.template-lintrc.js
index 61df6a727..4db5af2b0 100644
--- a/ui/core/.template-lintrc.js
+++ b/ui/core/.template-lintrc.js
@@ -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'] }
}
};
diff --git a/ui/core/app/components/doc-link/index.hbs b/ui/core/app/components/doc-link/index.hbs
new file mode 100644
index 000000000..e654aac4a
--- /dev/null
+++ b/ui/core/app/components/doc-link/index.hbs
@@ -0,0 +1,8 @@
+
+
+
diff --git a/ui/core/app/helpers/company-copyright.js b/ui/core/app/helpers/company-copyright.js
new file mode 100644
index 000000000..f4e799954
--- /dev/null
+++ b/ui/core/app/helpers/company-copyright.js
@@ -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}`;
+});
diff --git a/ui/core/app/helpers/company-name.js b/ui/core/app/helpers/company-name.js
new file mode 100644
index 000000000..78d99f2e7
--- /dev/null
+++ b/ui/core/app/helpers/company-name.js
@@ -0,0 +1,6 @@
+import { helper } from '@ember/component/helper';
+import config from '../config/environment';
+
+export default helper(function companyName() {
+ return config.companyName;
+});
diff --git a/ui/core/app/helpers/doc-url.js b/ui/core/app/helpers/doc-url.js
new file mode 100644
index 000000000..e31e4932a
--- /dev/null
+++ b/ui/core/app/helpers/doc-url.js
@@ -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}`;
+});
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set.js
index 91a502f82..4d88c52b1 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set.js
@@ -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',
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js
index 1cfa23223..da1ca0685 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js
@@ -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',
diff --git a/ui/core/app/templates/application.hbs b/ui/core/app/templates/application.hbs
index fa96053b4..ac4f0eac3 100644
--- a/ui/core/app/templates/application.hbs
+++ b/ui/core/app/templates/application.hbs
@@ -59,11 +59,13 @@
-
- {{t "hashicorp.copyright"}}
- {{t "hashicorp.product"}}
+
+ {{company-copyright}}
+ {{app-name}}
- {{t "hashicorp.documentation.title"}}
+
+ {{t "titles.documentation"}}
+
diff --git a/ui/core/app/templates/scopes/scope/auth-methods/auth-method/-header.hbs b/ui/core/app/templates/scopes/scope/auth-methods/auth-method/-header.hbs
index bd1bc825e..98ab86788 100644
--- a/ui/core/app/templates/scopes/scope/auth-methods/auth-method/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/auth-methods/auth-method/-header.hbs
@@ -1,4 +1,7 @@
-
{{t "resources.auth-method.title"}}
+
+ {{t "resources.auth-method.title"}}
+
+
{{t "resources.auth-method.description"}}
{{t "resources.account.title"}}
+
+ {{t "resources.account.title"}}
+
+
- {{t "resources.auth-method.title_plural"}}
+
+ {{t "resources.auth-method.title_plural"}}
+
+
{{t "resources.auth-method.description"}}
diff --git a/ui/core/app/templates/scopes/scope/groups/group/-header.hbs b/ui/core/app/templates/scopes/scope/groups/group/-header.hbs
index ae241529b..ad843f83a 100644
--- a/ui/core/app/templates/scopes/scope/groups/group/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/groups/group/-header.hbs
@@ -1,4 +1,7 @@
-{{t "resources.group.title"}}
+
+ {{t "resources.group.title"}}
+
+
{{t "resources.group.description"}}
- {{t "resources.group.title_plural"}}
+
+ {{t "resources.group.title_plural"}}
+
+
{{t "resources.group.description"}}
diff --git a/ui/core/app/templates/scopes/scope/orgs/index.hbs b/ui/core/app/templates/scopes/scope/orgs/index.hbs
index 30c211450..efe5f0a59 100644
--- a/ui/core/app/templates/scopes/scope/orgs/index.hbs
+++ b/ui/core/app/templates/scopes/scope/orgs/index.hbs
@@ -5,7 +5,10 @@
- {{t "resources.org.title_plural"}}
+
+ {{t "resources.org.title_plural"}}
+
+
{{#if @model}}
{{t "resources.org.description"}}
{{/if}}
diff --git a/ui/core/app/templates/scopes/scope/projects/index.hbs b/ui/core/app/templates/scopes/scope/projects/index.hbs
index 6173aeffb..fca7f0fae 100644
--- a/ui/core/app/templates/scopes/scope/projects/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/index.hbs
@@ -5,7 +5,10 @@
- {{t "resources.project.title_plural"}}
+
+ {{t "resources.project.title_plural"}}
+
+
{{#if @model}}
{{t "resources.project.description"}}
{{/if}}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-header.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-header.hbs
index 647741ad9..f4d885fae 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-header.hbs
@@ -1,4 +1,7 @@
-{{t "resources.host-catalog.title"}}
+
+ {{t "resources.host-catalog.title"}}
+
+
{{t "resources.host-catalog.description"}}
{{t "resources.host-set.title"}}
+
+ {{t "resources.host-set.title"}}
+
+
{{t "resources.host-set.description"}}
{{t "resources.host.title"}}
+
+ {{t "resources.host.title"}}
+
+
{{t "resources.host.description"}}
- {{t "resources.host-catalog.title_plural"}}
+
+ {{t "resources.host-catalog.title_plural"}}
+
+
{{t "resources.host-catalog.description"}}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/index.hbs
index 0de5bb65c..4cb31e30a 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/index.hbs
@@ -5,7 +5,10 @@
- {{t "resources.project.title"}}
+
+ {{t "resources.project.title"}}
+
+
{{t "resources.project.description"}}
- {{t "resources.session.title_plural"}}
+
+ {{t "resources.session.title_plural"}}
+
+
{{t "resources.session.description"}}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs
index 2cb938f29..9615a7c2d 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs
@@ -5,7 +5,10 @@
- {{t "resources.target.title_plural"}}
+
+ {{t "resources.target.title_plural"}}
+
+
{{#if @model}}
{{t "resources.target.description"}}
{{/if}}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/-header.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/-header.hbs
index b6f507ea4..b94a925a8 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/-header.hbs
@@ -1,4 +1,7 @@
-{{t "resources.target.title"}}
+
+ {{t "resources.target.title"}}
+
+
{{t "resources.target.description"}}
- {{t "resources.role.title_plural"}}
+
+ {{t "resources.role.title_plural"}}
+
+
{{#if @model}}
{{t "resources.role.description"}}
{{/if}}
diff --git a/ui/core/app/templates/scopes/scope/roles/role/-header.hbs b/ui/core/app/templates/scopes/scope/roles/role/-header.hbs
index 03164c9b2..a04e5edc1 100644
--- a/ui/core/app/templates/scopes/scope/roles/role/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/roles/role/-header.hbs
@@ -1,4 +1,7 @@
-{{t "resources.role.title"}}
+
+ {{t "resources.role.title"}}
+
+
{{t "resources.role.description"}}
{{t "resources.role.title"}}
+
+ {{t "resources.role.title"}}
+
+
{{t "resources.role.grant.description"}}
{{@model.id}}
-
\ No newline at end of file
+
diff --git a/ui/core/app/templates/scopes/scope/roles/role/principals/-header.hbs b/ui/core/app/templates/scopes/scope/roles/role/principals/-header.hbs
index 499d7ff96..63c44f53c 100644
--- a/ui/core/app/templates/scopes/scope/roles/role/principals/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/roles/role/principals/-header.hbs
@@ -1,4 +1,7 @@
-{{t "resources.role.title"}}
+
+ {{t "resources.role.title"}}
+
+
{{t "resources.role.principal.description"}}
- {{t "resources.user.title_plural"}}
+
+ {{t "resources.user.title_plural"}}
+
+
{{#if @model}}
{{t "resources.user.description"}}
{{/if}}
diff --git a/ui/core/app/templates/scopes/scope/users/user/-header.hbs b/ui/core/app/templates/scopes/scope/users/user/-header.hbs
index d67b6c679..1f80dcfc5 100644
--- a/ui/core/app/templates/scopes/scope/users/user/-header.hbs
+++ b/ui/core/app/templates/scopes/scope/users/user/-header.hbs
@@ -1,4 +1,7 @@
-{{t "resources.user.title"}}
+
+ {{t "resources.user.title"}}
+
+
{{t "resources.user.description"}}
`);
+ assert.ok(find('.doc-link .rose-icon.large'));
+ });
+});
diff --git a/ui/core/tests/integration/helpers/app-name-test.js b/ui/core/tests/integration/helpers/app-name-test.js
index 0dc7fbb09..cd86480cf 100644
--- a/ui/core/tests/integration/helpers/app-name-test.js
+++ b/ui/core/tests/integration/helpers/app-name-test.js
@@ -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');
});
diff --git a/ui/core/tests/integration/helpers/company-copyright-test.js b/ui/core/tests/integration/helpers/company-copyright-test.js
new file mode 100644
index 000000000..87b468e2f
--- /dev/null
+++ b/ui/core/tests/integration/helpers/company-copyright-test.js
@@ -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`);
+ });
+});
diff --git a/ui/core/tests/integration/helpers/company-name-test.js b/ui/core/tests/integration/helpers/company-name-test.js
new file mode 100644
index 000000000..0599a936e
--- /dev/null
+++ b/ui/core/tests/integration/helpers/company-name-test.js
@@ -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');
+ });
+});
diff --git a/ui/core/tests/integration/helpers/doc-url-test.js b/ui/core/tests/integration/helpers/doc-url-test.js
new file mode 100644
index 000000000..d91c9eeed
--- /dev/null
+++ b/ui/core/tests/integration/helpers/doc-url-test.js
@@ -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.');
+ });
+
+});
diff --git a/ui/core/translations/actions/en-us.yaml b/ui/core/translations/actions/en-us.yaml
index 9b1fa9751..d2a680549 100644
--- a/ui/core/translations/actions/en-us.yaml
+++ b/ui/core/translations/actions/en-us.yaml
@@ -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
diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml
index 84b842579..4441f333c 100644
--- a/ui/core/translations/en-us.yaml
+++ b/ui/core/translations/en-us.yaml
@@ -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