Merge branch 'develop' into chore-more-docs
This commit is contained in:
37 files changed
+63
-50
No files matched your search
@@ -46,8 +46,6 @@ export default class GroupModel extends GeneratedGroupModel {
|
||||
memberIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
@@ -71,8 +69,6 @@ export default class GroupModel extends GeneratedGroupModel {
|
||||
memberIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
|
||||
@@ -53,8 +53,6 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
principalIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
@@ -78,8 +76,6 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
principalIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
|
||||
@@ -52,8 +52,6 @@ export default class TargetModel extends GeneratedTargetModel {
|
||||
hostSetIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
@@ -77,8 +75,6 @@ export default class TargetModel extends GeneratedTargetModel {
|
||||
hostSetIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
|
||||
@@ -33,8 +33,6 @@ export default class UserModel extends GeneratedUserModel {
|
||||
accountIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
@@ -58,8 +56,6 @@ export default class UserModel extends GeneratedUserModel {
|
||||
accountIDs,
|
||||
};
|
||||
// There is no "deep merge" in ES.
|
||||
// All of this nonsense is here to ensure we get
|
||||
// a decent merge of `adapterOptions`.
|
||||
return this.save({
|
||||
...options,
|
||||
adapterOptions: {
|
||||
|
||||
@@ -37,8 +37,11 @@ export default class ApplicationSerializer extends RESTSerializer {
|
||||
* @param {String} key
|
||||
* @param {Object} attribute
|
||||
*/
|
||||
serializeAttribute(snapshot, json, key, { options }) {
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const { type, options } = attribute;
|
||||
let value = super.serializeAttribute(...arguments);
|
||||
// Convert empty strings to null.
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Version is sent only if it has a non-nullish value
|
||||
|
||||
@@ -70,6 +70,21 @@ module('Unit | Serializer | application', function (hooks) {
|
||||
});
|
||||
});
|
||||
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('user', {
|
||||
name: '',
|
||||
description: '',
|
||||
version: null,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
name: null,
|
||||
description: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('it serializes non-nullish version fields', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Rose::Form
|
||||
class="full-width"
|
||||
@onSubmit={{fn this.submit @submit}}
|
||||
@onSubmit={{fn this.submit @submit this.currentPassword this.newPassword}}
|
||||
@cancel={{fn this.cancel @cancel}}
|
||||
@disabled={{@model.isSaving}}
|
||||
@error={{@model.errors.base}}
|
||||
|
||||
@@ -2,7 +2,7 @@ import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { computed } from '@ember/object';
|
||||
import { action } from '@ember/object';
|
||||
import { next } from '@ember/runloop';
|
||||
import { run } from '@ember/runloop';
|
||||
|
||||
export default class FormAccountPasswordChangePasswordIndexComponent extends Component {
|
||||
|
||||
@@ -50,13 +50,13 @@ export default class FormAccountPasswordChangePasswordIndexComponent extends Com
|
||||
* Call passed submit function with passwords.
|
||||
* Unset passwords before callack.
|
||||
* @param {function} fn
|
||||
* @param {string} currentPassword
|
||||
* @param {string} newPassword
|
||||
*/
|
||||
@action
|
||||
submit(fn) {
|
||||
const currentPassword = this.currentPassword;
|
||||
const newPassword = this.newPassword;
|
||||
next(() => this.resetPasswords());
|
||||
fn(currentPassword, newPassword);
|
||||
submit(fn, currentPassword, newPassword) {
|
||||
run(() => this.resetPasswords());
|
||||
run(() => fn(currentPassword, newPassword));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<Rose::Form
|
||||
@onSubmit={{fn this.submit @submit}}
|
||||
@onSubmit={{fn this.submit @submit this.password}}
|
||||
@disabled={{@model.isSaving}}
|
||||
@error={{@model.errors.base}}
|
||||
as |form|
|
||||
|
||||
@@ -2,7 +2,7 @@ import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { computed } from '@ember/object';
|
||||
import { action } from '@ember/object';
|
||||
import { next } from '@ember/runloop';
|
||||
import { run } from '@ember/runloop';
|
||||
|
||||
export default class FormAccountPasswordSetPasswordIndexComponent extends Component {
|
||||
// =properties
|
||||
@@ -36,11 +36,11 @@ export default class FormAccountPasswordSetPasswordIndexComponent extends Compon
|
||||
* Submit with password value when it is allowed.
|
||||
* Callback with no arguments otherwise.
|
||||
* @param {function} fn
|
||||
* @param {string} password
|
||||
*/
|
||||
@action
|
||||
submit(fn) {
|
||||
const password = this.password;
|
||||
next(() => this.resetPassword());
|
||||
fn(password);
|
||||
submit(fn, password) {
|
||||
run(() => this.resetPassword());
|
||||
run(() => fn(password));
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@
|
||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/core.css">
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="{{rootURL}}logo-app.svg">
|
||||
|
||||
{{content-for "head-footer"}}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
<layout.header>
|
||||
<Rose::Header class="{{if (is-loading) " loading"}}" as |header|>
|
||||
<header.brand @logo="logo-boundary" @text={{app-name}} />
|
||||
<header.brand @logo="logo-app" @text={{app-name}} />
|
||||
|
||||
{{#if this.session.isAuthenticated}}
|
||||
<header.nav as |nav|>
|
||||
<nav.dropdown
|
||||
@text={{this.scope.displayName}}
|
||||
@icon="boundary-icons/org" as |dropdown|
|
||||
@icon="app-icons/org" as |dropdown|
|
||||
>
|
||||
{{#if this.session.data.authenticated.isGlobal}}
|
||||
<dropdown.link @route="scopes.scope" @model="global">
|
||||
@@ -35,7 +35,7 @@
|
||||
<header.utilities as |utilities|>
|
||||
<utilities.dropdown
|
||||
@text={{this.session.data.authenticated.username}}
|
||||
@icon="boundary-icons/user-profile" as |dropdown|
|
||||
@icon="app-icons/user-profile" as |dropdown|
|
||||
>
|
||||
<dropdown.link @route="account.change-password">
|
||||
{{t 'actions.change-password'}}
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
<layout.footer>
|
||||
<Rose::Footer as |footer|>
|
||||
<footer.brand @logo="logo-hashi" @text={{company-name}} />
|
||||
<footer.brand @logo="logo-company" @text={{company-name}} />
|
||||
<footer.text>{{company-copyright}}</footer.text>
|
||||
<footer.text>{{app-name}}</footer.text>
|
||||
<footer.nav as |nav|>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<Rose::Nav::Sidebar @title={{t "titles.general"}} as |nav|>
|
||||
<nav.link @route="scopes.scope.projects">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/project"
|
||||
@name="app-icons/project"
|
||||
@size="medium" />
|
||||
{{t "resources.project.title_plural"}}
|
||||
</nav.link>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<Rose::Nav::Sidebar @title={{t "titles.iam"}} as |nav|>
|
||||
<nav.link @route="scopes.scope.users">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/users"
|
||||
@name="app-icons/users"
|
||||
@size="medium" />
|
||||
{{t "resources.user.title_plural"}}
|
||||
</nav.link>
|
||||
<nav.link @route="scopes.scope.groups">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/group"
|
||||
@name="app-icons/group"
|
||||
@size="medium" />
|
||||
{{t "resources.group.title_plural"}}
|
||||
</nav.link>
|
||||
<nav.link @route="scopes.scope.roles">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/roles"
|
||||
@name="app-icons/roles"
|
||||
@size="medium" />
|
||||
{{t "resources.role.title_plural"}}
|
||||
</nav.link>
|
||||
<nav.link @route="scopes.scope.auth-methods">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/auth-method"
|
||||
@name="app-icons/auth-method"
|
||||
@size="medium" />
|
||||
{{t "resources.auth-method.title_plural"}}
|
||||
</nav.link>
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
{{title (t "resources.auth-method.title_plural")}}
|
||||
|
||||
{{outlet}}
|
||||
@@ -1 +1,3 @@
|
||||
{{outlet}}
|
||||
{{title @model.displayName}}
|
||||
|
||||
{{outlet}}
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
{{title (t 'actions.set-password')}}
|
||||
|
||||
<Form::Account::Password::SetPassword
|
||||
@model={{@model}}
|
||||
@submit={{route-action "setPassword" @model}}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
@title={{org.name}}
|
||||
@description={{org.description}}
|
||||
@id={{org.id}}
|
||||
@icon="boundary-icons/org"
|
||||
@icon="app-icons/org"
|
||||
@route="scopes.scope"
|
||||
@model={{org.id}}
|
||||
/>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
@title={{project.name}}
|
||||
@description={{project.description}}
|
||||
@id={{project.id}}
|
||||
@icon="boundary-icons/project"
|
||||
@icon="app-icons/project"
|
||||
@route="scopes.scope.projects.project"
|
||||
@model={{project.id}}
|
||||
/>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<Rose::Nav::Sidebar @title={{t "titles.resources"}} as |nav|>
|
||||
<nav.link @route="scopes.scope.projects.project.sessions">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/action-session"
|
||||
@name="app-icons/action-session"
|
||||
@size="medium" />
|
||||
{{t "resources.session.title_plural"}}
|
||||
</nav.link>
|
||||
<nav.link @route="scopes.scope.projects.project.targets">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/target"
|
||||
@name="app-icons/target"
|
||||
@size="medium" />
|
||||
{{t "resources.target.title_plural"}}
|
||||
</nav.link>
|
||||
<nav.link @route="scopes.scope.projects.project.host-catalogs">
|
||||
<Rose::Icon
|
||||
@name="boundary-icons/host-catalogs"
|
||||
@name="app-icons/host-catalogs"
|
||||
@size="medium" />
|
||||
{{t "resources.host-catalog.title_plural"}}
|
||||
</nav.link>
|
||||
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
{{outlet}}
|
||||
{{title @model.displayName}}
|
||||
|
||||
{{outlet}}
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
{{outlet}}
|
||||
{{title @model.displayName}}
|
||||
|
||||
{{outlet}}
|
||||
@@ -4,9 +4,9 @@
|
||||
</h2>
|
||||
<p>{{t "resources.role.principal.description"}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@text={{@model.role.id}}
|
||||
@buttonText={{t "actions.copy-to-clipboard"}}
|
||||
@acknowledgeText={{t "states.copied"}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
<code>{{@model.role.id}}</code>
|
||||
</Copyable>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.278 9.313a2.021 2.021 0 0 1-2.01-.951c-.552-.928-.224-2.115.732-2.65.956-.536 2.179-.218 2.732.71.407.684.346 1.54-.155 2.164l2.354 3.955c2.02-.731 4.352.038 5.466 1.91 1.242 2.087.504 4.76-1.647 5.964a4.608 4.608 0 0 1-3.51.41l.474-1.383c.77.204 1.594.1 2.286-.288 1.434-.804 1.925-2.583 1.098-3.975a3.006 3.006 0 0 0-2.193-1.429 3.059 3.059 0 0 0-2.507.807l-3.12-5.244zm3.367 6.592a2.003 2.003 0 0 1 1.855-1.213c1.104 0 2 .87 2 1.94 0 1.072-.896 1.94-2 1.941-.815 0-1.549-.48-1.855-1.213h-4.707C10.58 19.424 8.728 21 6.5 21c-2.484 0-4.5-1.957-4.5-4.366 0-1.24.533-2.358 1.389-3.153l.997 1.088a2.859 2.859 0 0 0-.886 2.065c0 1.607 1.343 2.91 3 2.91.928 0 1.803-.417 2.371-1.128a2.844 2.844 0 0 0 .534-2.51h6.24zm-7.568-.49c.501.623.562 1.479.155 2.164-.553.927-1.775 1.245-2.732.71-.956-.536-1.284-1.723-.732-2.65a2.022 2.022 0 0 1 2.01-.953l2.354-3.955c-1.664-1.332-2.143-3.676-1.03-5.548C9.345 3.096 12.1 2.38 14.25 3.585a4.37 4.37 0 0 1 2.12 2.744l-1.47.293a2.915 2.915 0 0 0-1.4-1.777c-1.435-.802-3.269-.326-4.098 1.065a2.835 2.835 0 0 0-.179 2.557 2.973 2.973 0 0 0 1.974 1.704l-3.12 5.243z" fill="currentColor"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
Reference in new issue
Block a user