Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c868086c64 | ||
|
|
316c5627dc | ||
|
|
faae34ccf5 | ||
|
|
015b034feb | ||
|
|
f1e1603502 | ||
|
|
df2d5d688e | ||
|
|
a0227720a8 | ||
|
|
d07407e881 | ||
|
|
7be2dc6d03 | ||
|
|
1321df3265 | ||
|
|
8ad462288f | ||
|
|
16e83b7428 | ||
|
|
f705a386f0 | ||
|
|
5589cdd8d5 | ||
|
|
53d5a77631 | ||
|
|
357df84c22 | ||
|
|
557076276b | ||
|
|
09894ed376 | ||
|
|
d5bf053b41 | ||
|
|
8f11765b96 | ||
|
|
4ad88d1dcd | ||
|
|
92572395bb | ||
|
|
e389494a3b | ||
|
|
aa9694cae2 | ||
|
|
c462fa4c51 | ||
|
|
f7d3dfdac0 | ||
|
|
6df7624afc | ||
|
|
fe9ce25ed0 | ||
|
|
a3ee4d02e8 | ||
|
|
7988eee93d | ||
|
|
57fb26f37d | ||
|
|
f956f95e78 | ||
|
|
e613d55dcb | ||
|
|
f75529b5c4 | ||
|
|
75ed3b816b | ||
|
|
c7c54daaad | ||
|
|
6458f928b9 | ||
|
|
865e36c03c | ||
|
|
af87d85a34 | ||
|
|
9808e9a9d3 | ||
|
|
b22ea6fa79 | ||
|
|
0bda47ec29 | ||
|
|
0742987874 | ||
|
|
6b485b9f93 | ||
|
|
1978b1c08e | ||
|
|
bce44de8e0 | ||
|
|
0bdd1a1f04 | ||
|
|
255d727ffb | ||
|
|
7bfa3da53d | ||
|
|
28ebc93179 | ||
|
|
547330821f | ||
|
|
cf70ea3e01 | ||
|
|
52afb56057 | ||
|
|
df32a8eb4b | ||
|
|
14190fdf67 | ||
|
|
0459cab9ed | ||
|
|
db5b97fbda | ||
|
|
cf85826ff8 | ||
|
|
46f33aba17 | ||
|
|
177f96876c | ||
|
|
50b0aee33c | ||
|
|
73002a38c4 | ||
|
|
17bd4c69b6 | ||
|
|
a6b2557cd5 | ||
|
|
9a5110aa71 | ||
|
|
caf85c57ec | ||
|
|
878f3be747 | ||
|
|
af9555e7f3 | ||
|
|
4afdc77f4c | ||
|
|
7ea772ca31 | ||
|
|
10fb5c8265 | ||
|
|
6c58749a6e | ||
|
|
e6b99e1418 | ||
|
|
6babacd0bc | ||
|
|
4423c53cc4 | ||
|
|
451c1e861b | ||
|
|
157dda4f8e | ||
|
|
929f22a48b | ||
|
|
d8aca33fcd | ||
|
|
144c7d13ee | ||
|
|
2bbbceb9d9 | ||
|
|
cb948fb640 | ||
|
|
6d8d28e1b4 | ||
|
|
99e24500d3 | ||
|
|
0a8f1d4405 | ||
|
|
f32311def3 | ||
|
|
e2b0c3ad13 | ||
|
|
b454efe41f | ||
|
|
e778847375 | ||
|
|
eb5d4b2289 | ||
|
|
4bae0296cf | ||
|
|
594f951ca7 | ||
|
|
87938d968c | ||
|
|
372f8d5b96 | ||
|
|
f8f7831cc3 | ||
|
|
b08f228c9b | ||
|
|
6367f3a9bc | ||
|
|
b96510de65 | ||
|
|
e0d3b25be2 | ||
|
|
4b77732fd6 | ||
|
|
0b83b4bd85 | ||
|
|
0ed506a111 | ||
|
|
1a97472c04 | ||
|
|
551619dfaa | ||
|
|
a1528be4fd | ||
|
|
fbba6571db | ||
|
|
57de78e672 | ||
|
|
43cd357e9a | ||
|
|
5e6a3e9d9a | ||
|
|
aea3e6f3ca | ||
|
|
eac0ee6b53 | ||
|
|
9e8d7c9cae | ||
|
|
273b5c8df6 | ||
|
|
4b430f1a7f | ||
|
|
66b40e5318 | ||
|
|
42283596b2 | ||
|
|
cfd3fe468e | ||
|
|
7c0366c790 | ||
|
|
5c2540d22b | ||
|
|
a68d94161f | ||
|
|
6be0a2a17d | ||
|
|
fdfa88e089 | ||
|
|
b1a34115a5 | ||
|
|
5a1192ed2e | ||
|
|
5644e57fc5 | ||
|
|
f097eab53a | ||
|
|
ce7d743f81 | ||
|
|
166b35860a | ||
|
|
2bbc12ddea | ||
|
|
c36030c12d | ||
|
|
521d70a4bb | ||
|
|
13794c7bf8 | ||
|
|
5f8042a551 | ||
|
|
0ab5ff8370 | ||
|
|
9f28484bd7 | ||
|
|
57b9e86562 | ||
|
|
40a5e221e7 | ||
|
|
165e4aec75 | ||
|
|
2448c03b27 | ||
|
|
57ca18670f | ||
|
|
e7b553efda | ||
|
|
b27fe14dbc | ||
|
|
726f6d31e2 | ||
|
|
1fb3e466c6 | ||
|
|
2a8d42eaba | ||
|
|
32c69624f9 | ||
|
|
04af1a431f | ||
|
|
a6b7837af1 | ||
|
|
9343121f23 | ||
|
|
e76bc73c11 | ||
|
|
f344d73f32 | ||
|
|
eb185279b2 | ||
|
|
0dd0e16783 | ||
|
|
cb18e011a9 | ||
|
|
09d9432825 | ||
|
|
3ae2423aa4 | ||
|
|
ab1a642f66 | ||
|
|
d94c4921c8 | ||
|
|
910c0e4316 | ||
|
|
4f74f8578e | ||
|
|
77b1ca477d | ||
|
|
e291956c1b | ||
|
|
8b51bcf95b | ||
|
|
ce286964d1 | ||
|
|
c971d6d2ce | ||
|
|
064c857d20 | ||
|
|
161cf3cd53 | ||
|
|
2d1475d211 | ||
|
|
fc4dab606e | ||
|
|
3a3fdf2396 | ||
|
|
c82269c960 | ||
|
|
87619dc9dc | ||
|
|
99baefaffc | ||
|
|
40c2acd6ab | ||
|
|
4eaceabb00 | ||
|
|
a1cfa84919 | ||
|
|
350c4f5f70 | ||
|
|
7fb4110a1b | ||
|
|
a400892790 | ||
|
|
dae42c7288 | ||
|
|
8ad6664a10 | ||
|
|
b5fdb850f6 | ||
|
|
b2f11f712b | ||
|
|
b4d36438a4 | ||
|
|
1017295a85 | ||
|
|
b0326e0c99 | ||
|
|
fc1d5ff0ca | ||
|
|
a54ae21858 | ||
|
|
30cc58cd56 | ||
|
|
59934559a5 | ||
|
|
b8e99ce389 | ||
|
|
7d96d9125f | ||
|
|
4a0f1d04f2 | ||
|
|
1165d21ef6 | ||
|
|
2fff4ab587 | ||
|
|
2da521d643 | ||
|
|
c10838234a | ||
|
|
b652f759c8 | ||
|
|
0fc32bcbf7 | ||
|
|
329cf802d8 | ||
|
|
05178cc3a5 | ||
|
|
689fc249d8 | ||
|
|
03e06a22a4 | ||
|
|
39b71aa526 | ||
|
|
0053b09285 | ||
|
|
1e1387700c | ||
|
|
f6016453f1 | ||
|
|
afccd0a9f7 | ||
|
|
a79ec87954 | ||
|
|
ec7e66160f | ||
|
|
cb0c03264f | ||
|
|
ababc5812d | ||
|
|
46160aad6f | ||
|
|
d881b57b87 | ||
|
|
f510d2f4fe | ||
|
|
01e8b22a92 | ||
|
|
876fc0c71f | ||
|
|
858a3420e1 | ||
|
|
d7735bd402 | ||
|
|
0232570831 | ||
|
|
3fd8d2d01f | ||
|
|
73db666f43 | ||
|
|
3506b34863 | ||
|
|
7d08d69db0 | ||
|
|
bdb38a5324 | ||
|
|
c3381bc6fc | ||
|
|
8118781d06 | ||
|
|
10a133b2af | ||
|
|
ee5b346275 | ||
|
|
f6aa9ef7cf | ||
|
|
e7db3cb327 | ||
|
|
9794116562 | ||
|
|
7c377506c8 | ||
|
|
5a1e3e235a | ||
|
|
3c83375d84 | ||
|
|
4256c7e552 | ||
|
|
6cbde9c982 | ||
|
|
4659b54e9e | ||
|
|
f22922ee60 | ||
|
|
7fd7613c30 | ||
|
|
7478aa8f09 | ||
|
|
128f963d47 | ||
|
|
884a0ebbc5 | ||
|
|
eba1c7ad57 | ||
|
|
64928feef2 | ||
|
|
22156bdead | ||
|
|
50eb86b736 | ||
|
|
4b039c9f59 | ||
|
|
1846eae462 | ||
|
|
25228d3855 | ||
|
|
4f471c9799 | ||
|
|
12d063a440 | ||
|
|
79c90b5183 | ||
|
|
1f0d79aac3 | ||
|
|
2d35037365 | ||
|
|
5cdc7af588 | ||
|
|
6b9c8192a9 | ||
|
|
c84b561a58 | ||
|
|
e248bbe200 | ||
|
|
5ce8355a2a | ||
|
|
c9b90db36d | ||
|
|
7f022fc64c | ||
|
|
2d32726207 | ||
|
|
3d4bd2adf9 | ||
|
|
485f11cb01 | ||
|
|
2545753c2c | ||
|
|
c1654180c4 | ||
|
|
025297c619 | ||
|
|
39ec40d488 | ||
|
|
ce01358a7e | ||
|
|
4ed0178c7a | ||
|
|
4b84eec59d | ||
|
|
40168fa8c4 | ||
|
|
044fe778af | ||
|
|
3a1416e2ff | ||
|
|
dc0e866796 | ||
|
|
fe3b5e905f | ||
|
|
42bc4c1777 | ||
|
|
59565cf194 | ||
|
|
8cfcf47900 | ||
|
|
15522f31af | ||
|
|
da04a190e6 | ||
|
|
3cc5456bde | ||
|
|
f98bfc2130 | ||
|
|
168e7fbac6 | ||
|
|
7e29d47b70 | ||
|
|
a03983e2f3 | ||
|
|
b5b2f61cbe | ||
|
|
84fe240c1f | ||
|
|
27f8be2213 | ||
|
|
382c4cbc7e | ||
|
|
3b1837999b | ||
|
|
a1c4d00eed | ||
|
|
c2ffe19d44 | ||
|
|
14d96a4a8a | ||
|
|
5284514a05 | ||
|
|
a39752d1c9 | ||
|
|
b0bd9b6808 | ||
|
|
2cca6fe005 | ||
|
|
455b1a29b0 | ||
|
|
cdb9761be6 | ||
|
|
0ac657e378 | ||
|
|
00b62a6f50 | ||
|
|
f57619d1fc | ||
|
|
2d24617dba | ||
|
|
abc9687261 | ||
|
|
24c62fbd46 | ||
|
|
951f69d4b2 | ||
|
|
55ead33b4a | ||
|
|
8adf4bb95b | ||
|
|
6c7483cbf2 | ||
|
|
bf2e267696 | ||
|
|
d8de56ecf4 | ||
|
|
59932f52db | ||
|
|
dffc236860 | ||
|
|
d76a4b0055 | ||
|
|
3728e4cd51 | ||
|
|
b7bd40c688 | ||
|
|
47d4366397 | ||
|
|
9abb540d7f | ||
|
|
155ed7a6be | ||
|
|
699672218d | ||
|
|
8bfd9bd7a3 | ||
|
|
a1f428550d | ||
|
|
3fa6332ab4 | ||
|
|
9f6cfe4edb | ||
|
|
7cde048ac1 | ||
|
|
ee390a6fea | ||
|
|
7e3096f849 | ||
|
|
16c03a088b | ||
|
|
28e2b67aa8 | ||
|
|
b69f964b43 | ||
|
|
84bb640340 | ||
|
|
dbc06a4e0a | ||
|
|
3d900f5a2b | ||
|
|
e50ea4b555 | ||
|
|
119cbbe815 | ||
|
|
6e95686b9a | ||
|
|
4f5c0a3e98 | ||
|
|
0c9ba7e7a7 | ||
|
|
b78726caff | ||
|
|
d10de61fb4 | ||
|
|
aced3207f3 | ||
|
|
14f6b30b26 | ||
|
|
fb85869e2c | ||
|
|
03ce03bebf | ||
|
|
1e04c696ad | ||
|
|
89055089a3 | ||
|
|
f4e20b87c7 | ||
|
|
f402819945 | ||
|
|
cd2523bc20 | ||
|
|
7f994e9597 | ||
|
|
07e16ef71b | ||
|
|
74df923775 | ||
|
|
839962186f | ||
|
|
86fbbe7cdf | ||
|
|
7b51d15ba4 | ||
|
|
e376bb8e20 | ||
|
|
48dc8a392d |
No files matched your search
@@ -0,0 +1,37 @@
|
||||
import { Ability } from 'ember-can';
|
||||
|
||||
/**
|
||||
* Generic ability provides abilities common to all models in the API.
|
||||
*/
|
||||
export default class CollectionAbility extends Ability {
|
||||
// =permissions
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canList() {
|
||||
return this.hasAuthorizedCollectionAction('list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canCreate() {
|
||||
return this.hasAuthorizedCollectionAction('create');
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Returns true if the given action is contained in the ability model's
|
||||
* `authorized_collection_actions` array.
|
||||
* @param {string} action
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasAuthorizedCollectionAction(action) {
|
||||
const authorized_collection_actions =
|
||||
(this.model || {}).authorized_collection_actions || {};
|
||||
const collection = this.collection || {};
|
||||
return authorized_collection_actions[collection]?.includes(action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Ability } from 'ember-can';
|
||||
|
||||
/**
|
||||
* Generic ability provides abilities common to all models in the API.
|
||||
*/
|
||||
export default class ModelAbility extends Ability {
|
||||
// =permissions
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canRead() {
|
||||
return this.hasAuthorizedAction('read');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canUpdate() {
|
||||
return this.hasAuthorizedAction('update');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canDelete() {
|
||||
return this.hasAuthorizedAction('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* To save an existing model (already persisted to the API), it must contain
|
||||
* the the `update` authorized action.
|
||||
*
|
||||
* For now, new models _always_ have this ability. The reason is because the
|
||||
* `create` action is authorized on collections, not individual records. So
|
||||
* this function can't actually tell from a model instance if create
|
||||
* is allowed.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canSave() {
|
||||
if (this.model.isNew || (!this.model.isNew && this.canUpdate)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Returns true if the given action is contained in the ability model's
|
||||
* `authorized_actions` array.
|
||||
* @param {string} action
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasAuthorizedAction(action) {
|
||||
return this.model.authorized_actions?.includes(action);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import Model from '@ember-data/model';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
import { computed } from '@ember/object';
|
||||
|
||||
@@ -35,6 +36,17 @@ export default class BaseModel extends Model {
|
||||
|
||||
// =attributes
|
||||
|
||||
@attr({
|
||||
readOnly: true,
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
authorized_actions;
|
||||
|
||||
@attr({
|
||||
readOnly: true,
|
||||
})
|
||||
authorized_collection_actions;
|
||||
|
||||
set scopeModel(model) {
|
||||
if (model) {
|
||||
const json = model.serialize();
|
||||
@@ -45,7 +57,7 @@ export default class BaseModel extends Model {
|
||||
|
||||
/**
|
||||
* Convenience for getting and setting the parent scope ID.
|
||||
* @type {string
|
||||
* @type {string}
|
||||
*/
|
||||
@computed('scope.scope_id')
|
||||
get scopeID() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/abilities/collection';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/abilities/model';
|
||||
@@ -1,7 +1,15 @@
|
||||
import factory from '../generated/factories/account';
|
||||
import { random, internet } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('account') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
attributes() {
|
||||
switch (this.type) {
|
||||
case 'password':
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
import factory from '../generated/factories/auth-method';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
const types = ['password', 'oidc'];
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('auth-method') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
authorized_collection_actions: () => {
|
||||
return {
|
||||
accounts: ['create', 'list'],
|
||||
};
|
||||
},
|
||||
id: (i) => `auth-method-id-${i}`,
|
||||
|
||||
// Cycle through available types
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import factory from '../generated/factories/credential-library';
|
||||
import { random, system } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
const types = ['vault'];
|
||||
|
||||
@@ -7,6 +8,14 @@ export default factory.extend({
|
||||
id: (i) => `credential-library-id-${i}`,
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('credential-library') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
|
||||
attributes() {
|
||||
switch (this.type) {
|
||||
case 'vault':
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
import factory from '../generated/factories/credential-store';
|
||||
import { random, internet, datatype } from 'faker';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
const types = ['vault'];
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('credential-store') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
authorized_collection_actions: () => {
|
||||
return {
|
||||
'credential-libraries': ['create', 'list'],
|
||||
};
|
||||
},
|
||||
id: (i) => `credential-store-id-${i}`,
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import factory from '../generated/factories/group';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('group') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
id: (i) => `group-${i}`,
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import factory from '../generated/factories/host-catalog';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('host-catalog') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
authorized_collection_actions: () => {
|
||||
return {
|
||||
hosts: ['create', 'list'],
|
||||
'host-sets': ['create', 'list'],
|
||||
};
|
||||
},
|
||||
withChildren: trait({
|
||||
afterCreate(hostCatalog, server) {
|
||||
const { scope } = hostCatalog;
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import factory from '../generated/factories/host-set';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('host-set') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
id: (i) => `host-set-id-${i}`,
|
||||
});
|
||||
@@ -1,5 +1,13 @@
|
||||
import factory from '../generated/factories/host';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('host') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
id: (i) => `host-id-${i}`,
|
||||
});
|
||||
@@ -1,7 +1,15 @@
|
||||
import factory from '../generated/factories/role';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('role') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
// eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects
|
||||
grant_strings: () => [
|
||||
'id=*;action=*',
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
import factory from '../generated/factories/scope';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
type: 'global',
|
||||
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('scope') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
|
||||
authorized_collection_actions: () => {
|
||||
return {
|
||||
scopes: ['create', 'list'],
|
||||
users: ['create', 'list'],
|
||||
sessions: ['list'],
|
||||
groups: ['create', 'list'],
|
||||
roles: ['create', 'list'],
|
||||
targets: ['create', 'list'],
|
||||
'credential-stores': ['create', 'list'],
|
||||
'auth-methods': ['create', 'list'],
|
||||
'host-catalogs': ['create', 'list'],
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates realistic-ish IDs while still being deterministic.
|
||||
*/
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import factory from '../generated/factories/target';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import { random, datatype } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
const randomBoolean = (chance = 0.5) => Math.random() < chance;
|
||||
const hostSetChance = 0.3;
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('target') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
/**
|
||||
* -1 means "unlimited" and we want to generate these on occasion.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import factory from '../generated/factories/user';
|
||||
import permissions from '../helpers/permissions';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('user') || [
|
||||
'no-op',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
],
|
||||
id: (i) => `user-${i}`,
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import { copy } from 'ember-copy';
|
||||
|
||||
/**
|
||||
* Allows development-time toggling of resource permissions via the window
|
||||
* querystring. Pass a JSON object into the query to toggle permissions.
|
||||
* Note that the value must be a valid JSON object in order to be parsed.
|
||||
*
|
||||
* @example
|
||||
* ?authorized_actions={"account": ["read"]}
|
||||
*
|
||||
* Within a Mirage factory, pass the actions into the mock:
|
||||
*
|
||||
* @example
|
||||
* import { Factory } from 'ember-cli-mirage';
|
||||
* import permissions from '../helpers/permissions';
|
||||
*
|
||||
* export default Factory.extend({
|
||||
* authorized_actions: () =>
|
||||
* permissions.authorizedActionsFor('account') ||
|
||||
* ['no-op', 'read', 'update', 'delete']
|
||||
* });
|
||||
*/
|
||||
class ToggledCapabilities {
|
||||
// =attributes
|
||||
|
||||
// Get the query string and drop the leading '?'
|
||||
#rawQuery = window.location.search.substring(1);
|
||||
|
||||
// Split the querystring into key/value pairs
|
||||
#queryPairs = this.#rawQuery.split('&').map((item) => item.split('='));
|
||||
|
||||
// Find the value of a pair with key `authorized_actions`
|
||||
// Safe-ish when the item is not present
|
||||
#rawAuthorizedActions = (this.#queryPairs.find(
|
||||
(item) => item[0] === 'authorized_actions'
|
||||
) || [])[1];
|
||||
|
||||
// Safe-ish when the value is not present
|
||||
#authorizedActions =
|
||||
JSON.parse(
|
||||
decodeURIComponent(this.#rawAuthorizedActions || '') || 'null'
|
||||
) || {};
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Returns authorized actions for the specified field, if any are defined
|
||||
* in the `authorized_actions` query. Returns undefined otherwise.
|
||||
* @return {?string[]}
|
||||
*/
|
||||
authorizedActionsFor(field) {
|
||||
if (this.#authorizedActions[field]) {
|
||||
return copy(this.#authorizedActions[field], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new ToggledCapabilities();
|
||||
@@ -47,8 +47,9 @@ export default function (server) {
|
||||
// Other resources
|
||||
server.schema.scopes.where({ type: 'project' }).models.forEach((scope) => {
|
||||
server.createList('host-catalog', 2, { scope }, 'withChildren');
|
||||
server.createList('session', 4, { scope }, 'withAssociations');
|
||||
server.createList('credential-store', 3, { scope }, 'withAssociations');
|
||||
server.createList('target', 2, { scope }, 'withAssociations');
|
||||
// Sessions have target data. Create it after targets.
|
||||
server.createList('session', 4, { scope }, 'withAssociations');
|
||||
});
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
"doc:toc": "doctoc README.md"
|
||||
},
|
||||
"dependencies": {
|
||||
"ember-can": "^3.1.0",
|
||||
"ember-cli-babel": "^7.23.0",
|
||||
"ember-cli-htmlbars": "^5.3.1",
|
||||
"ember-cli-mirage": "^1.1.8",
|
||||
@@ -40,7 +41,7 @@
|
||||
"broccoli-asset-rev": "^3.0.0",
|
||||
"doctoc": "^2.0.0",
|
||||
"ember-auto-import": "^1.10.1",
|
||||
"ember-cli": "~3.27.0",
|
||||
"ember-cli": "~3.28.0",
|
||||
"ember-cli-dependency-checker": "^3.2.0",
|
||||
"ember-cli-inject-live-reload": "^2.1.0",
|
||||
"ember-cli-sri": "^2.1.1",
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Abilities | Collection', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it reflects when a resource may be listed based on authorized_collection_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_collection_actions: {
|
||||
foobars: ['list'],
|
||||
},
|
||||
};
|
||||
assert.ok(service.can('list collection', model, { collection: 'foobars' }));
|
||||
model.authorized_collection_actions.foobars = [];
|
||||
assert.notOk(
|
||||
service.can('list collection', model, { collection: 'foobars' })
|
||||
);
|
||||
});
|
||||
|
||||
test('it reflects when a resource may be created based on authorized_collection_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_collection_actions: {
|
||||
foobars: ['create'],
|
||||
},
|
||||
};
|
||||
assert.ok(
|
||||
service.can('create collection', model, { collection: 'foobars' })
|
||||
);
|
||||
model.authorized_collection_actions.foobars = [];
|
||||
assert.notOk(
|
||||
service.can('create collection', model, { collection: 'foobars' })
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Abilities | Model', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it reflects when a given model may be read based on authorized_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_actions: ['read'],
|
||||
};
|
||||
assert.ok(service.can('read model', model));
|
||||
model.authorized_actions = [];
|
||||
assert.notOk(service.can('read model', model));
|
||||
});
|
||||
|
||||
test('it reflects when a given model may be updated based on authorized_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_actions: ['update'],
|
||||
};
|
||||
assert.ok(service.can('update model', model));
|
||||
model.authorized_actions = [];
|
||||
assert.notOk(service.can('update model', model));
|
||||
});
|
||||
|
||||
test('it reflects when a given model may be saved based on isNew and authorized_actions', function (assert) {
|
||||
assert.expect(4);
|
||||
const service = this.owner.lookup('service:can');
|
||||
let model = {
|
||||
isNew: false,
|
||||
authorized_actions: ['update'],
|
||||
};
|
||||
assert.ok(service.can('save model', model));
|
||||
model = {
|
||||
isNew: false,
|
||||
authorized_actions: [],
|
||||
};
|
||||
assert.notOk(service.can('save model', model));
|
||||
// Model instances are always saveable at this level when isNew is true.
|
||||
// In practice, the ability to _create_ a resource depends not on instance
|
||||
// authorization, but on collection authorization, which is
|
||||
// tested separately.
|
||||
model = {
|
||||
isNew: true,
|
||||
authorized_actions: ['update'],
|
||||
};
|
||||
assert.ok(service.can('save model', model));
|
||||
model = {
|
||||
isNew: true,
|
||||
authorized_actions: [],
|
||||
};
|
||||
assert.ok(service.can('save model', model));
|
||||
});
|
||||
|
||||
test('it reflects when a given model may be deleted based on authorized_actions', function (assert) {
|
||||
assert.expect(2);
|
||||
const service = this.owner.lookup('service:can');
|
||||
const model = {
|
||||
authorized_actions: ['delete'],
|
||||
};
|
||||
assert.ok(service.can('delete model', model));
|
||||
model.authorized_actions = [];
|
||||
assert.notOk(service.can('delete model', model));
|
||||
});
|
||||
});
|
||||
@@ -170,6 +170,7 @@ module('Unit | Serializer | application', function (hooks) {
|
||||
id: '1',
|
||||
type: 'user',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'User 1',
|
||||
account_ids: [],
|
||||
scope: { scope_id: 'o_123' },
|
||||
@@ -200,6 +201,7 @@ module('Unit | Serializer | application', function (hooks) {
|
||||
id: '1',
|
||||
type: 'target',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Target 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
host_sets: [],
|
||||
|
||||
@@ -66,6 +66,7 @@ module('Unit | Serializer | group', function (hooks) {
|
||||
id: '1',
|
||||
type: 'group',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Group 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
member_ids: [],
|
||||
|
||||
@@ -67,6 +67,7 @@ module('Unit | Serializer | host set', function (hooks) {
|
||||
id: '1',
|
||||
type: 'host-set',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Host Set 1',
|
||||
host_ids: [{ value: '1' }, { value: '2' }, { value: '3' }],
|
||||
},
|
||||
@@ -96,6 +97,7 @@ module('Unit | Serializer | host set', function (hooks) {
|
||||
id: '1',
|
||||
type: 'host-set',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Host Set 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
host_ids: [],
|
||||
|
||||
@@ -67,6 +67,7 @@ module('Unit | Serializer | role', function (hooks) {
|
||||
id: '1',
|
||||
type: 'role',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Role 1',
|
||||
grant_strings: ['*', '*'],
|
||||
principals: [],
|
||||
@@ -93,6 +94,7 @@ module('Unit | Serializer | role', function (hooks) {
|
||||
id: '1',
|
||||
type: 'role',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Role 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
principals: [],
|
||||
|
||||
@@ -110,6 +110,7 @@ module('Unit | Serializer | target', function (hooks) {
|
||||
id: '1',
|
||||
type: 'target',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Target 1',
|
||||
host_sets: [
|
||||
{ host_set_id: '1', host_catalog_id: '2' },
|
||||
@@ -143,6 +144,7 @@ module('Unit | Serializer | target', function (hooks) {
|
||||
id: '1',
|
||||
type: 'target',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Target 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
host_sets: [],
|
||||
|
||||
@@ -62,6 +62,7 @@ module('Unit | Serializer | user', function (hooks) {
|
||||
id: '1',
|
||||
type: 'user',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'user 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
account_ids: [],
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"core": "*",
|
||||
"doctoc": "^2.0.0",
|
||||
"ember-auto-import": "^1.10.1",
|
||||
"ember-cli": "~3.27.0",
|
||||
"ember-cli": "~3.28.0",
|
||||
"ember-cli-dependency-checker": "^3.2.0",
|
||||
"ember-cli-inject-live-reload": "^2.1.0",
|
||||
"ember-cli-sri": "^2.1.1",
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
title={{t "actions.get-topic-help"}}>
|
||||
<Rose::Icon @name="help-circle-outline" @size={{@iconSize}} />
|
||||
<Rose::Icon @name="flight-icons/help-24" @size={{@iconSize}} />
|
||||
</a>
|
||||
@@ -27,13 +27,12 @@ export default class ErrorMessageComponent extends MessageComponent {
|
||||
@computed('args.status')
|
||||
get icon() {
|
||||
switch (this.args.status) {
|
||||
case '404':
|
||||
return 'flight-icons/help-16';
|
||||
case '401':
|
||||
case '403':
|
||||
return 'disabled';
|
||||
case '404':
|
||||
return 'help-circle-outline';
|
||||
default:
|
||||
return 'alert-circle-outline';
|
||||
return 'flight-icons/alert-circle-16';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
|
||||
module.exports = {
|
||||
name: require('./package').name,
|
||||
|
||||
included(app) {
|
||||
this._super.included.apply(this, arguments);
|
||||
this.includePublic(app);
|
||||
this.setupSVGO(app);
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds the public folder and includes it into the ember-inline-svg addon.
|
||||
*/
|
||||
includePublic(app) {
|
||||
const publicPath = path.resolve('public');
|
||||
const dummyPublicPath = path.resolve('tests/dummy/public');
|
||||
|
||||
app.options.svg = app.options.svg || {};
|
||||
app.options.svg.paths = app.options.svg.paths || [];
|
||||
|
||||
app.options.svg.paths.push(publicPath);
|
||||
if (this.isDevelopingAddon()) app.options.svg.paths.push(dummyPublicPath);
|
||||
|
||||
this.addons.forEach((addon) => {
|
||||
if (addon.name === 'ember-inline-svg') addon.included(app);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust SVG optimizer defaults (used by ember-inline-svg).
|
||||
*/
|
||||
setupSVGO(app) {
|
||||
app.options.svg = app.options.svg || {};
|
||||
app.options.svg.optimize = app.options.svg.optimize || {};
|
||||
app.options.svg.optimize.plugins = app.options.svg.optimize.plugins || [];
|
||||
app.options.svg.optimize.plugins.push({ removeViewBox: false });
|
||||
},
|
||||
};
|
||||
@@ -50,7 +50,7 @@
|
||||
"broccoli-asset-rev": "^3.0.0",
|
||||
"doctoc": "^2.0.0",
|
||||
"ember-auto-import": "^1.10.1",
|
||||
"ember-cli": "~3.27.0",
|
||||
"ember-cli": "~3.28.0",
|
||||
"ember-cli-dependency-checker": "^3.2.0",
|
||||
"ember-cli-inject-live-reload": "^2.1.0",
|
||||
"ember-cli-sri": "^2.1.1",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.97503 7.25H10.0232C9.83952 5.33678 9.13836 3.52559 7.99998 2.00183C6.85742 3.53084 6.15589 5.3466 5.97503 7.25ZM10.025 8.75C9.84413 10.6534 9.14259 12.4692 8.00003 13.9982C6.86166 12.4744 6.16049 10.6632 5.97679 8.75H10.025ZM11.5309 8.75H14.4572C14.1478 11.4433 12.1921 13.6359 9.62187 14.296C10.707 12.6405 11.3662 10.7347 11.5309 8.75ZM14.4572 7.25H11.5293C11.3619 5.25743 10.7034 3.35494 9.62165 1.70392C12.192 2.36401 14.1478 4.55661 14.4572 7.25ZM4.46913 7.25H1.5428C1.85224 4.55668 3.80789 2.36413 6.37814 1.70397C5.29298 3.35946 4.63378 5.2653 4.46913 7.25ZM4.47076 8.75H1.5428C1.85224 11.4434 3.808 13.636 6.37836 14.2961C5.29662 12.6451 4.63811 10.7426 4.47076 8.75ZM0 8C0 3.58172 3.58172 0 8 0L8.00195 3.05531e-06C12.4193 0.00105872 16 3.58237 16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8Z" fill="currentColor"/>
|
||||
</svg>
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0, 0)">
|
||||
<path d="M8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0ZM6.1281 1.77359C3.76051 2.48438 1.96114 4.50867 1.57645 7L4.06861 7C4.28628 5.12647 4.99696 3.33655 6.1281 1.77359ZM9.8719 1.77359C11.003 3.33655 11.7137 5.12647 11.9314 7L14.4236 7C14.0389 4.50867 12.2395 2.48438 9.8719 1.77359ZM10.4196 7C10.1652 5.12363 9.33287 3.33469 8 1.8356C6.66712 3.33469 5.83478 5.12363 5.58044 7L10.4196 7ZM5.52655 8.5L10.4734 8.5C10.3086 10.5575 9.45081 12.5327 8 14.1644C6.54919 12.5327 5.6914 10.5575 5.52655 8.5ZM4.02241 8.5L1.51894 8.5C1.7257 11.2179 3.60398 13.4686 6.1281 14.2264C4.89671 12.5249 4.16361 10.5545 4.02241 8.5ZM9.8719 14.2264C11.1033 12.5249 11.8364 10.5545 11.9776 8.5L14.4811 8.5C14.2743 11.2179 12.396 13.4686 9.8719 14.2264Z" fill-rule="EVENODD"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 990 B After Width: | Height: | Size: 973 B |
@@ -1,3 +1,12 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.15625 12.1875H5V16H0V0H12V5.125H15.5V16H12H10.5H7.15625V12.1875ZM10.5 14.5H8.65625V10.6875H3.5V14.5H1.5V1.5H10.5V5.125V14.5ZM12 14.5H14V6.625H12V14.5ZM3 3H4.88235V5H3V3ZM4.88235 7H3V9H4.88235V7ZM7 3H8.88235V5H7V3ZM8.88235 7H7V9H8.88235V7Z" fill="currentColor"/>
|
||||
</svg>
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(1, 1)">
|
||||
<path d="M0 2.25C0 1.00736 1.00736 0 2.25 0L8.75 0C9.99264 0 11 1.00736 11 2.25L11 4.36218L13.0506 5.81469C13.6461 6.23651 14.0001 6.92096 14.0001 7.65074L14.0001 12.7501C14.0001 13.4404 13.4404 14.0001 12.7501 14.0001L10.2501 14.0001C10.0421 14.0001 9.85396 13.9154 9.71811 13.7788C9.5833 13.6432 9.5 13.4563 9.5 13.25L9.5 2.25C9.5 1.83579 9.16421 1.5 8.75 1.5L2.25 1.5C1.83579 1.5 1.5 1.83579 1.5 2.25L1.5 13.25C1.5 13.6642 1.16421 14 0.75 14C0.335786 14 0 13.6642 0 13.25L0 2.25ZM11 12.5001L11 6.20036L12.1836 7.03872C12.3821 7.17933 12.5001 7.40748 12.5001 7.65074L12.5001 12.5001L11 12.5001Z" fill-rule="EVENODD"></path>
|
||||
<path d="M3.75005 9.5498C3.36345 9.5498 3.05005 9.8632 3.05005 10.2498L3.05005 13.2498C3.05005 13.6364 3.36345 13.9498 3.75005 13.9498C4.13665 13.9498 4.45005 13.6364 4.45005 13.2498L4.45005 10.9498L6.55005 10.9498L6.55005 13.2498C6.55005 13.6364 6.86345 13.9498 7.25005 13.9498C7.63665 13.9498 7.95005 13.6364 7.95005 13.2498L7.95005 10.2498C7.95005 9.8632 7.63665 9.5498 7.25005 9.5498L3.75005 9.5498Z" fill-rule="NONZERO"></path>
|
||||
<path d="M3.25 3.75C3.25 3.33579 3.58579 3 4 3L4.25 3C4.66421 3 5 3.33579 5 3.75C5 4.16421 4.66421 4.5 4.25 4.5L4 4.5C3.58579 4.5 3.25 4.16421 3.25 3.75Z" fill-rule="NONZERO"></path>
|
||||
<path d="M6.75 3C6.33579 3 6 3.33579 6 3.75C6 4.16421 6.33579 4.5 6.75 4.5L7 4.5C7.41421 4.5 7.75 4.16421 7.75 3.75C7.75 3.33579 7.41421 3 7 3L6.75 3Z" fill-rule="NONZERO"></path>
|
||||
<path d="M3.25 5.75C3.25 5.33579 3.58579 5 4 5L4.25 5C4.66421 5 5 5.33579 5 5.75C5 6.16421 4.66421 6.5 4.25 6.5L4 6.5C3.58579 6.5 3.25 6.16421 3.25 5.75Z" fill-rule="NONZERO"></path>
|
||||
<path d="M6.75 5C6.33579 5 6 5.33579 6 5.75C6 6.16421 6.33579 6.5 6.75 6.5L7 6.5C7.41421 6.5 7.75 6.16421 7.75 5.75C7.75 5.33579 7.41421 5 7 5L6.75 5Z" fill-rule="NONZERO"></path>
|
||||
<path d="M3.25 7.75C3.25 7.33579 3.58579 7 4 7L4.25 7C4.66421 7 5 7.33579 5 7.75C5 8.16421 4.66421 8.5 4.25 8.5L4 8.5C3.58579 8.5 3.25 8.16421 3.25 7.75Z" fill-rule="NONZERO"></path>
|
||||
<path d="M6.75 7C6.33579 7 6 7.33579 6 7.75C6 8.16421 6.33579 8.5 6.75 8.5L7 8.5C7.41421 8.5 7.75 8.16421 7.75 7.75C7.75 7.33579 7.41421 7 7 7L6.75 7Z" fill-rule="NONZERO"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 2.3 KiB |
@@ -1,3 +1,8 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 1.5H5.50461V5.63615H1.5V1.5ZM0 7.13615V0H7.00461V7.13615H0ZM1.5 10.3639H5.50461V14.5H1.5V10.3639ZM0 16V8.86386H7.00461V16H0ZM14.5 1.5H10.4954V5.63615H14.5V1.5ZM8.99536 0V7.13615H16V0H8.99536ZM10.4954 10.3639H14.5V14.5H10.4954V10.3639ZM8.99536 16V8.86386H16V16H8.99536Z" fill="currentColor"/>
|
||||
</svg>
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(1, 1)">
|
||||
<path d="M1.25 0C0.559644 0 0 0.559644 0 1.25L0 4.75C0 5.44036 0.559644 6 1.25 6L4.75 6C5.44036 6 6 5.44036 6 4.75L6 1.25C6 0.559644 5.44036 0 4.75 0L1.25 0ZM1.5 4.5L1.5 1.5L4.5 1.5L4.5 4.5L1.5 4.5Z" fill-rule="EVENODD"></path>
|
||||
<path d="M9.25 0C8.55964 0 8 0.559644 8 1.25L8 4.75C8 5.44036 8.55964 6 9.25 6L12.75 6C13.4404 6 14 5.44036 14 4.75L14 1.25C14 0.559644 13.4404 0 12.75 0L9.25 0ZM9.5 4.5L9.5 1.5L12.5 1.5L12.5 4.5L9.5 4.5Z" fill-rule="EVENODD"></path>
|
||||
<path d="M8 9.25C8 8.55964 8.55964 8 9.25 8L12.75 8C13.4404 8 14 8.55964 14 9.25L14 12.75C14 13.4404 13.4404 14 12.75 14L9.25 14C8.55964 14 8 13.4404 8 12.75L8 9.25ZM9.5 9.5L9.5 12.5L12.5 12.5L12.5 9.5L9.5 9.5Z" fill-rule="EVENODD"></path>
|
||||
<path d="M1.25 8C0.559644 8 0 8.55964 0 9.25L0 12.75C0 13.4404 0.559644 14 1.25 14L4.75 14C5.44036 14 6 13.4404 6 12.75L6 9.25C6 8.55964 5.44036 8 4.75 8L1.25 8ZM1.5 12.5L1.5 9.5L4.5 9.5L4.5 12.5L1.5 12.5Z" fill-rule="EVENODD"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 1.1 KiB |
@@ -34,3 +34,5 @@ change-origin: Change Origin URL
|
||||
change-state: Change State
|
||||
close: Close
|
||||
toggle-secret: Toggle secret visibility
|
||||
minimize: Minimize
|
||||
fullscreen: Fullscreen
|
||||
@@ -32,6 +32,8 @@ titles:
|
||||
descriptions:
|
||||
empty-set: There are no items to display yet. You may be able to add items or try back later.
|
||||
origin-initialization: To get started, please enter your origin URL
|
||||
create-but-not-list: You do not have permission to list {resource}, but you can create new instances.
|
||||
neither-list-nor-create: You do not have permission to list or create {resource}.
|
||||
questions:
|
||||
delete-confirm: Are you sure you want to delete this resource?
|
||||
remove-confirm: Are you sure you want to remove this association?
|
||||
|
||||
@@ -346,3 +346,8 @@ credential-library:
|
||||
help: The body of the HTTP request the library sends to Vault when requesting credentials. Only allowed when HTTP method is set to POST.
|
||||
types:
|
||||
vault: Vault
|
||||
scope:
|
||||
title: Scope
|
||||
title_plural: Scopes
|
||||
messages:
|
||||
cannot_read: While you do not have permission to read this scope, you may have permission to view resources within it.
|
||||
@@ -13,7 +13,7 @@ When style definition isn't supplied, a default style will be supplied.
|
||||
Styles: outline, dark, informational, informational-outline, success, success-outline, error, error-outline, warning, warning-outline, alert, alert-outline
|
||||
|
||||
```html
|
||||
<Rose::Badge @style="outline" @icon="user-organization">Badge</Rose::Badge>
|
||||
<Rose::Badge @style="outline" @icon="flight-icons/org-16">Badge</Rose::Badge>
|
||||
```
|
||||
|
||||
<Preview>
|
||||
@@ -43,11 +43,9 @@ Styles: outline, dark, informational, informational-outline, success, success-ou
|
||||
'none'
|
||||
),
|
||||
icon: select('icon', {
|
||||
'user-organization': 'user-organization',
|
||||
'partner': 'partner',
|
||||
'gift-fill': 'gift-fill',
|
||||
'flight-icons/org-16': 'flight-icons/org-16',
|
||||
},
|
||||
'user-organization'
|
||||
'flight-icons/org-16'
|
||||
),
|
||||
}
|
||||
}}</Story>
|
||||
@@ -58,7 +56,7 @@ Styles: outline, dark, informational, informational-outline, success, success-ou
|
||||
template: hbs`
|
||||
<Rose::Badge>default style</Rose::Badge>
|
||||
<Rose::Badge @style="outline">outline</Rose::Badge>
|
||||
<Rose::Badge @icon="user-organization">default style with icon</Rose::Badge>
|
||||
<Rose::Badge @icon="flight-icons/org-16">default style with icon</Rose::Badge>
|
||||
<Rose::Badge @style="dark">dark</Rose::Badge>
|
||||
<Rose::Badge @style="informational">informational</Rose::Badge>
|
||||
<Rose::Badge @style="informational-outline">informational-outline</Rose::Badge>
|
||||
|
||||
@@ -12,7 +12,7 @@ to trigger actions or to submit forms. Avoid using buttons as simple links to
|
||||
other routes. For accessibility, use links instead.
|
||||
|
||||
```htmlbars
|
||||
<Rose::Button @style="primary" @iconRight="chevron-right">
|
||||
<Rose::Button @style="primary" @iconRight="flight-icons/entry-point-16">
|
||||
Action
|
||||
</Rose::Button>
|
||||
```
|
||||
@@ -49,23 +49,18 @@ other routes. For accessibility, use links instead.
|
||||
iconLeft: select(
|
||||
'iconLeft',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'check-circle-outline'
|
||||
'flight-icons/check-circle-16'
|
||||
),
|
||||
iconRight: select(
|
||||
'iconRight',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'chevron-right',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'chevron-right'
|
||||
'flight-icons/clipboard-copy-16'
|
||||
),
|
||||
onClick: action('clicked'),
|
||||
},
|
||||
@@ -86,12 +81,10 @@ button in this case for accessibility.
|
||||
iconOnly: select(
|
||||
'iconOnly',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'check-circle-outline'
|
||||
'flight-icons/check-circle-16'
|
||||
),
|
||||
},
|
||||
}}</Story>
|
||||
|
||||
@@ -13,7 +13,7 @@ Card link component wraps content with `LinkTo` component. Supports title and de
|
||||
@title='Card title'
|
||||
@description='Card description'
|
||||
@id='resource_id_1234'
|
||||
@icon='user-organization'
|
||||
@icon='flight-icons/org-16'
|
||||
@route='about'/>
|
||||
```
|
||||
|
||||
@@ -32,11 +32,9 @@ Card link component wraps content with `LinkTo` component. Supports title and de
|
||||
description: text('description', 'Card description'),
|
||||
id: text('id', 'resource_id_1234'),
|
||||
icon: select('icon', {
|
||||
'user-organization': 'user-organization',
|
||||
'partner': 'partner',
|
||||
'gift-fill': 'gift-fill',
|
||||
'flight-icons/org-16': 'flight-icons/org-16',
|
||||
},
|
||||
'user-organization'
|
||||
'flight-icons/org-16'
|
||||
),
|
||||
},
|
||||
}}</Story>
|
||||
|
||||
@@ -18,35 +18,35 @@ A set of cards arranged side-by-side.
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
<cards.link
|
||||
@route="index"
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
<cards.link
|
||||
@route="index"
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
<cards.link
|
||||
@route="index"
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
<cards.link
|
||||
@route="index"
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
</Rose::Cards>
|
||||
`,
|
||||
@@ -62,14 +62,14 @@ A set of cards arranged side-by-side.
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
<cards.link
|
||||
@route="index"
|
||||
@title="Card Title"
|
||||
@description="Description"
|
||||
@id="resource_id_1234"
|
||||
@icon="user-organization"
|
||||
@icon="flight-icons/org-16"
|
||||
/>
|
||||
</Rose::Cards>
|
||||
```
|
||||
@@ -27,7 +27,7 @@
|
||||
title={{@dismissButtonText}}
|
||||
{{on "click" (fn this.dismiss @dismiss)}}
|
||||
>
|
||||
<Rose::Icon @name="cancel-plain" @size="small" />
|
||||
<Rose::Icon @name="flight-icons/x-16" @size="small" />
|
||||
</button>
|
||||
|
||||
</header>
|
||||
@@ -62,7 +62,7 @@
|
||||
title={{@dismissButtonText}}
|
||||
{{on "click" (fn this.dismiss @dismiss)}}
|
||||
>
|
||||
<Rose::Icon @name="cancel-plain" @size="small" />
|
||||
<Rose::Icon @name="flight-icons/x-16" @size="small" />
|
||||
</button>
|
||||
|
||||
</header>
|
||||
|
||||
@@ -36,12 +36,10 @@ A dialog component with optional modal capabilities.
|
||||
icon: select(
|
||||
'icon',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less'
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'check-circle-outline'
|
||||
'flight-icons/check-circle-16'
|
||||
),
|
||||
style: select(
|
||||
'style',
|
||||
@@ -60,7 +58,7 @@ A dialog component with optional modal capabilities.
|
||||
<Rose::Dialog
|
||||
@modal={{true}}
|
||||
@dismiss={{@dismissFn}}
|
||||
@icon="check-circle-outline"
|
||||
@icon="flight-icons/check-circle-16"
|
||||
@heading="Heading"
|
||||
@dismissButtonText="Dismiss"
|
||||
as |dialog|>
|
||||
|
||||
@@ -11,7 +11,7 @@ A simple dropdown component with support for links and buttons.
|
||||
<Preview>
|
||||
<Story name="Basic Dropdown" height="7rem">{{
|
||||
template: hbs`
|
||||
<Rose::Dropdown @text="Choose One…" @icon="user-organization" @showCaret={{showCaret}} as |dropdown|>
|
||||
<Rose::Dropdown @text="Choose One…" @icon="flight-icons/org-16" @showCaret={{showCaret}} as |dropdown|>
|
||||
<dropdown.link @route="index">Menu item</dropdown.link>
|
||||
<dropdown.link @route="about">Menu item</dropdown.link>
|
||||
<dropdown.separator />
|
||||
@@ -31,7 +31,7 @@ A simple dropdown component with support for links and buttons.
|
||||
<Preview>
|
||||
<Story name="Icon-only Dropdown" height="5rem">{{
|
||||
template: hbs`
|
||||
<Rose::Dropdown @text="Choose One…" @icon="user-organization" @iconOnly={{true}} as |dropdown|>
|
||||
<Rose::Dropdown @text="Choose One…" @icon="flight-icons/org-16" @iconOnly={{true}} as |dropdown|>
|
||||
<dropdown.link @route="index">Menu item</dropdown.link>
|
||||
<dropdown.link @route="about">Menu item</dropdown.link>
|
||||
<dropdown.separator />
|
||||
@@ -117,7 +117,7 @@ Dropdown supports `danger` styling through `style` attribute.
|
||||
Dropdown indicator can be hidden using `showCaret` attribute.
|
||||
|
||||
```html
|
||||
<Rose::Dropdown @showCaret={{true}} @icon="more-horizontal" as |dropdown|>
|
||||
<Rose::Dropdown @showCaret={{true}} @icon="flight-icons/more-horizontal-16" as |dropdown|>
|
||||
<dropdown.link @route="index">Menu item</dropdown.link>
|
||||
<dropdown.button>Button menu item</dropdown.button>
|
||||
</Rose::Dropdown>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<p class="rose-form-error-message" ...attributes>
|
||||
<Rose::Icon @name="cancel-square-fill" @size="medium" />
|
||||
<Rose::Icon @name="flight-icons/x-square-16" @size="medium" />
|
||||
{{yield}}
|
||||
</p>
|
||||
@@ -68,12 +68,10 @@ Renders a form radiofield group.
|
||||
firstFieldIcon: select(
|
||||
'first icon',
|
||||
{
|
||||
'user-organization': 'user-organization',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/org-16': 'flight-icons/org-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'user-organization'
|
||||
'flight-icons/org-16'
|
||||
),
|
||||
secondFieldLabel: text('second label', 'Maybe'),
|
||||
secondFieldValue: text('second value', 'maybe'),
|
||||
|
||||
@@ -44,10 +44,8 @@ Renders a form radiofield.
|
||||
'icon',
|
||||
{
|
||||
'none': null,
|
||||
'user-organization': 'user-organization',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/org-16': 'flight-icons/org-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
null
|
||||
),
|
||||
@@ -111,14 +109,12 @@ Renders a form radiofield.
|
||||
'icon',
|
||||
{
|
||||
'none': null,
|
||||
'user-organization': 'user-organization',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/org-16': 'flight-icons/org-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
null
|
||||
),
|
||||
inline: boolean('inline', false)
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
</Preview>
|
||||
@@ -27,7 +27,7 @@ A header component that allows three distinct sections to be configured: brand,
|
||||
<utilities.dropdown
|
||||
@text="user@example.net"
|
||||
@iconOnly={{true}}
|
||||
@icon="user-square-fill" as |dropdown|
|
||||
@icon="flight-icons/user-circle-16" as |dropdown|
|
||||
>
|
||||
<dropdown.link @route="index">Menu item</dropdown.link>
|
||||
<dropdown.link @route="about">Menu item</dropdown.link>
|
||||
@@ -69,13 +69,11 @@ A header component that allows three distinct sections to be configured: brand,
|
||||
dropdownIcon: select(
|
||||
'dropdownIcon',
|
||||
{
|
||||
'user-square-fill': 'user-square-fill',
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/user-circle-16': 'flight-icons/user-circle-16',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'user-square-fill'
|
||||
'flight-icons/user-circle-16'
|
||||
),
|
||||
},
|
||||
}}</Story>
|
||||
|
||||
@@ -7,9 +7,7 @@ import { text, boolean, select } from '@storybook/addon-knobs';
|
||||
|
||||
# Icon
|
||||
|
||||
Renders a simple icon from [Structure Icons][structure-icons].
|
||||
|
||||
[structure-icons]: https://github.com/hashicorp/structure-icons
|
||||
Renders a simple icon.
|
||||
|
||||
```htmlbars
|
||||
<Rose::Icon @name={{name}} @size={{size}} />
|
||||
@@ -24,12 +22,10 @@ Renders a simple icon from [Structure Icons][structure-icons].
|
||||
name: select(
|
||||
'name',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'unfold-less': 'unfold-less',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'check-circle-outline'
|
||||
'flight-icons/check-circle-16'
|
||||
),
|
||||
}
|
||||
}}</Story>
|
||||
|
||||
@@ -12,7 +12,7 @@ Styles supported: primary, secondary, warning, and ghost.
|
||||
Disabling link button is not supported as it is an action on form components only.
|
||||
|
||||
```html
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconRight="chevron-right">
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconRight="flight-icons/entry-point-16">
|
||||
Content
|
||||
</Rose::LinkButton>
|
||||
```
|
||||
@@ -45,21 +45,18 @@ Disabling link button is not supported as it is an action on form components onl
|
||||
iconLeft: select(
|
||||
'iconLeft',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'copy-action': 'copy-action',
|
||||
'unfold-more': 'unfold-more',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'copy-action'
|
||||
'flight-icons/clipboard-copy-16'
|
||||
),
|
||||
iconRight: select(
|
||||
'iconRight',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'chevron-right': 'chevron-right',
|
||||
'copy-action': 'copy-action',
|
||||
'search': 'search',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/clipboard-copy-16': 'flight-icons/clipboard-copy-16',
|
||||
},
|
||||
'chevron-right'
|
||||
'flight-icons/clipboard-copy-16'
|
||||
),
|
||||
},
|
||||
}}</Story>
|
||||
@@ -68,7 +65,7 @@ Disabling link button is not supported as it is an action on form components onl
|
||||
Similar to `Rose::Button`, icon only link button is supported.
|
||||
|
||||
```html
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconOnly="help-circle-outline" />
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconOnly="flight-icons/help-16" />
|
||||
```
|
||||
|
||||
<Preview>
|
||||
@@ -91,12 +88,10 @@ Similar to `Rose::Button`, icon only link button is supported.
|
||||
iconOnly: select(
|
||||
'iconOnly',
|
||||
{
|
||||
'check-circle-outline': 'check-circle-outline',
|
||||
'help-circle-outline': 'help-circle-outline',
|
||||
'plus-circle-fill': 'plus-circle-fill',
|
||||
'user-square-outline': 'user-square-outline',
|
||||
'flight-icons/check-circle-16': 'flight-icons/check-circle-16',
|
||||
'flight-icons/help-16': 'flight-icons/help-16',
|
||||
},
|
||||
'help-circle-outline'
|
||||
'flight-icons/help-16'
|
||||
),
|
||||
},
|
||||
}}</Story>
|
||||
|
||||
@@ -46,7 +46,7 @@ A simple key/value list with support for embedded form fields and buttons.
|
||||
<input.field />
|
||||
</item.cell>
|
||||
<item.cell>
|
||||
<Rose::Button @style="secondary" @iconOnly="trash" title="Remove">Remove</Rose::Button>
|
||||
<Rose::Button @style="secondary" @iconOnly="flight-icons/trash-16" title="Remove">Remove</Rose::Button>
|
||||
</item.cell>
|
||||
</list.item>
|
||||
</Rose::Form::Input>
|
||||
@@ -94,7 +94,7 @@ A simple key/value list with support for embedded form fields and buttons.
|
||||
<input.field />
|
||||
</item.cell>
|
||||
<item.cell>
|
||||
<Rose::Button @style="secondary" @iconOnly="trash" title="Remove">Remove</Rose::Button>
|
||||
<Rose::Button @style="secondary" @iconOnly="flight-icons/trash-16" title="Remove">Remove</Rose::Button>
|
||||
</item.cell>
|
||||
</list.item>
|
||||
</Rose::Form::Input>
|
||||
|
||||
@@ -18,7 +18,7 @@ Title can be configured with optional icon and subtitle.
|
||||
{{description}}
|
||||
</message.description>
|
||||
<message.link @route="index">
|
||||
<Rose::Icon @name="chevron-left" />
|
||||
<Rose::Icon @name="flight-icons/chevron-left-16" />
|
||||
Go back
|
||||
</message.link>
|
||||
<message.link @route="index">
|
||||
@@ -33,24 +33,23 @@ Title can be configured with optional icon and subtitle.
|
||||
icon: select(
|
||||
'icon',
|
||||
{
|
||||
'alert-circle-outline': 'alert-circle-outline',
|
||||
'help-circle-outline': 'help-circle-outline',
|
||||
'disabled': 'disabled',
|
||||
'flight-icons/alert-circle-16': 'flight-icons/alert-circle-16',
|
||||
'flight-icons/help-16': 'flight-icons/help-16',
|
||||
},
|
||||
'help-circle-outline'
|
||||
'flight-icons/help-16'
|
||||
),
|
||||
},
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
```html
|
||||
<Rose::Message @title="Page not found" @subtitle="Error 404" @icon="disabled" as |message|>
|
||||
<Rose::Message @title="Page not found" @subtitle="Error 404" @icon="flight-icons/alert-circle-16" as |message|>
|
||||
<message.description>
|
||||
You must be granted permissions to view this data. Ask your administrator
|
||||
if you think you should have access.
|
||||
</message.description>
|
||||
<message.link @route="index">
|
||||
<Rose::Icon @name="chevron-left" />
|
||||
<Rose::Icon @name="flight-icons/chevron-left-16" />
|
||||
Go back
|
||||
</message.link>
|
||||
<message.link @route="index">Need help?</message.link>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
{{on "click" @dismiss}}
|
||||
>
|
||||
<Rose::Icon
|
||||
@name="cancel-plain"
|
||||
@name="flight-icons/x-16"
|
||||
@size="medium" />
|
||||
<span class="rose-notification-dismiss-text">
|
||||
{{@dismissText}}
|
||||
|
||||
@@ -8,17 +8,17 @@ export default class RoseNotificationComponent extends Component {
|
||||
*/
|
||||
@computed('style')
|
||||
get icon() {
|
||||
let icon = 'info-circle-fill';
|
||||
let icon = 'flight-icons/info-16';
|
||||
|
||||
switch (this.style) {
|
||||
case 'error':
|
||||
icon = 'cancel-square-fill';
|
||||
icon = 'flight-icons/x-square-16';
|
||||
break;
|
||||
case 'success':
|
||||
icon = 'check-circle-fill';
|
||||
icon = 'flight-icons/check-circle-16';
|
||||
break;
|
||||
case 'warning':
|
||||
icon = 'alert-triangle';
|
||||
icon = 'flight-icons/alert-triangle-16';
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ Cell shrink should be applied to all the cells in a row. Otherwise the bigger ce
|
||||
</Rose::Form::Input>
|
||||
</row.cell>
|
||||
<row.cell @shrink={{true}} @alignRight={{true}}>
|
||||
<Rose::Button @style="secondary" @iconOnly="trash" title="Remove">Remove</Rose::Button>
|
||||
<Rose::Button @style="secondary" @iconOnly="flight-icons/trash-16" title="Remove">Remove</Rose::Button>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
<body.row as |row|>
|
||||
|
||||
@@ -10,7 +10,7 @@ module.exports = {
|
||||
this._super.included.apply(this, arguments);
|
||||
|
||||
this.includeStyles(app);
|
||||
this.includeIcons(app);
|
||||
this.includeFlightIcons(app);
|
||||
this.includePublic(app);
|
||||
this.setupSVGO(app);
|
||||
},
|
||||
@@ -45,8 +45,10 @@ module.exports = {
|
||||
* Finds the structure-icons folder and includes it into the
|
||||
* ember-inline-svg addon.
|
||||
*/
|
||||
includeIcons(app) {
|
||||
const iconPackagePath = require.resolve('@hashicorp/structure-icons');
|
||||
includeFlightIcons(app) {
|
||||
const iconPackagePath = path.resolve(
|
||||
'../../node_modules/@hashicorp/flight-icons'
|
||||
);
|
||||
const iconsPath = path.resolve(iconPackagePath, '..');
|
||||
|
||||
app.options.svg = app.options.svg || {};
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"@ember/test-helpers": "^2.2.8",
|
||||
"@glimmer/component": "^1.0.3",
|
||||
"@glimmer/tracking": "^1.0.3",
|
||||
"@hashicorp/structure-icons": "^1.9.0-0",
|
||||
"@hashicorp/flight-icons": "0.0.6-beta",
|
||||
"@storybook/addon-actions": "^6.3.1",
|
||||
"@storybook/addon-docs": "^6.3.1",
|
||||
"@storybook/addon-knobs": "^6.3.0",
|
||||
@@ -53,7 +53,7 @@
|
||||
"broccoli-asset-rev": "^3.0.0",
|
||||
"doctoc": "^2.0.0",
|
||||
"ember-auto-import": "^1.10.1",
|
||||
"ember-cli": "~3.27.0",
|
||||
"ember-cli": "~3.28.0",
|
||||
"ember-cli-dependency-checker": "^3.2.0",
|
||||
"ember-cli-inject-live-reload": "^2.1.0",
|
||||
"ember-cli-sass": "^10.0.1",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<utilities.dropdown
|
||||
@text="user@example.net"
|
||||
@iconOnly={{true}}
|
||||
@icon="user-square-fill" as |dropdown|
|
||||
@icon="flight-icons/user-circle-16" as |dropdown|
|
||||
>
|
||||
<dropdown.link @route="index">Menu item</dropdown.link>
|
||||
<dropdown.link @route="about">Menu item</dropdown.link>
|
||||
@@ -82,7 +82,7 @@
|
||||
<input.field />
|
||||
</item.cell>
|
||||
<item.cell>
|
||||
<Rose::Button @style="secondary" @iconOnly="trash" title="Remove">Remove</Rose::Button>
|
||||
<Rose::Button @style="secondary" @iconOnly="flight-icons/trash-16" title="Remove">Remove</Rose::Button>
|
||||
</item.cell>
|
||||
</list.item>
|
||||
</Rose::Form::Input>
|
||||
|
||||
@@ -17,7 +17,7 @@ module('Integration | Component | rose/badge', function (hooks) {
|
||||
});
|
||||
|
||||
test('it renders an icon using @icon', async function (assert) {
|
||||
await render(hbs`<Rose::Badge @icon="chevron-right" />`);
|
||||
await render(hbs`<Rose::Badge @icon="flight-icons/entry-point-16" />`);
|
||||
assert.ok(find('.rose-icon'));
|
||||
});
|
||||
|
||||
|
||||
@@ -34,14 +34,20 @@ module('Integration | Component | rose/button', function (hooks) {
|
||||
});
|
||||
|
||||
test('it supports left and right icons', async function (assert) {
|
||||
await render(hbs`<Rose::Button @iconLeft="chevron-left" />`);
|
||||
await render(
|
||||
hbs`<Rose::Button @iconLeft="flight-icons/chevron-left-16" />`
|
||||
);
|
||||
assert.ok(find('.has-icon-left .rose-icon'));
|
||||
await render(hbs`<Rose::Button @iconRight="chevron-left" />`);
|
||||
await render(
|
||||
hbs`<Rose::Button @iconRight="flight-icons/chevron-left-16" />`
|
||||
);
|
||||
assert.ok(find('.has-icon-right .rose-icon'));
|
||||
});
|
||||
|
||||
test('it supports an icon-only type', async function (assert) {
|
||||
await render(hbs`<Rose::Button @iconOnly="chevron-left" />`);
|
||||
await render(
|
||||
hbs`<Rose::Button @iconOnly="flight-icons/chevron-left-16" />`
|
||||
);
|
||||
assert.ok(find('.has-icon-only .rose-icon'));
|
||||
});
|
||||
});
|
||||
@@ -42,7 +42,7 @@ module('Integration | Component | rose/card/link', function (hooks) {
|
||||
|
||||
test('it renders with @icon', async function (assert) {
|
||||
await render(
|
||||
hbs`<Rose::Card::Link @title="foo" @icon="alert-circle-outline" />`
|
||||
hbs`<Rose::Card::Link @title="foo" @icon="flight-icons/alert-circle-16" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ module('Integration | Component | rose/dropdown', function (hooks) {
|
||||
});
|
||||
|
||||
test('it supports an icon', async function (assert) {
|
||||
await render(hbs`<Rose::Dropdown @icon="user-square-fill" />`);
|
||||
await render(hbs`<Rose::Dropdown @icon="flight-icons/user-circle-16" />`);
|
||||
assert.ok(find('svg'));
|
||||
});
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ module('Integration | Component | rose/dropdown/button', function (hooks) {
|
||||
});
|
||||
|
||||
test('it supports an icon-only type', async function (assert) {
|
||||
await render(hbs`<Rose::Dropdown::Button @iconOnly="chevron-left" />`);
|
||||
await render(
|
||||
hbs`<Rose::Dropdown::Button @iconOnly="flight-icons/chevron-left-16" />`
|
||||
);
|
||||
assert.ok(find('.has-icon-only .rose-icon'));
|
||||
});
|
||||
});
|
||||
@@ -18,7 +18,9 @@ module('Integration | Component | rose/form/radio/radio', function (hooks) {
|
||||
});
|
||||
|
||||
test('it supports an icon', async function (assert) {
|
||||
await render(hbs`<Rose::Form::Radio::Radio @icon="user-square-fill" />`);
|
||||
await render(
|
||||
hbs`<Rose::Form::Radio::Radio @icon="flight-icons/user-circle-16" />`
|
||||
);
|
||||
assert.ok(find('svg'));
|
||||
});
|
||||
|
||||
|
||||
@@ -7,12 +7,14 @@ module('Integration | Component | rose/icon', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Icon @name="unfold-more" />`);
|
||||
await render(hbs`<Rose::Icon @name="flight-icons/globe-16" />`);
|
||||
assert.ok(find('svg'));
|
||||
});
|
||||
|
||||
test('it supports optional @size', async function (assert) {
|
||||
await render(hbs`<Rose::Icon @name="unfold-more" @size="small" />`);
|
||||
await render(
|
||||
hbs`<Rose::Icon @name="flight-icons/globe-16" @size="small" />`
|
||||
);
|
||||
assert.ok(find('.small'));
|
||||
});
|
||||
});
|
||||
@@ -35,7 +35,7 @@ module('Integration | Component | rose/link-button', function (hooks) {
|
||||
|
||||
test('it supports left icon with @iconLeft', async function (assert) {
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index" @iconLeft="chevron-left" />`
|
||||
hbs`<Rose::LinkButton @route="index" @iconLeft="flight-icons/chevron-left-16" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
assert.ok(find('.has-icon-left'));
|
||||
@@ -43,7 +43,7 @@ module('Integration | Component | rose/link-button', function (hooks) {
|
||||
|
||||
test('it supports left icon with @iconRight', async function (assert) {
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index" @iconRight="chevron-right" />`
|
||||
hbs`<Rose::LinkButton @route="index" @iconRight="flight-icons/entry-point-16" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
assert.ok(find('.has-icon-right'));
|
||||
@@ -51,7 +51,7 @@ module('Integration | Component | rose/link-button', function (hooks) {
|
||||
|
||||
test('it supports only icon with @iconOnly', async function (assert) {
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index" @iconOnly="help-circle-outline" />`
|
||||
hbs`<Rose::LinkButton @route="index" @iconOnly="flight-icons/help-16" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
assert.ok(find('.has-icon-only'));
|
||||
|
||||
+3
-1
@@ -75,7 +75,9 @@
|
||||
"mem": "^4.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"normalize-url": "^4.5.1",
|
||||
"glob-parent": "^5.1.2"
|
||||
"glob-parent": "^5.1.2",
|
||||
"tar": "^6.1.9",
|
||||
"path-parse": "^1.0.7"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import CollectionAbility from 'api/abilities/collection';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class OverrideCollectionAbility extends CollectionAbility {
|
||||
// =services
|
||||
|
||||
@service features;
|
||||
|
||||
// =permissions
|
||||
|
||||
/**
|
||||
* Navigating to a resource is allowed if either list or create grants
|
||||
* are present.
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canNavigate() {
|
||||
return this.canList || this.canCreate;
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* If the capabilities feature flag is disabled, actions are always
|
||||
* authorized. This mimics pre-capabilities behavior.
|
||||
*/
|
||||
hasAuthorizedCollectionAction() {
|
||||
if (!this.features.isEnabled('capabilities')) return true;
|
||||
return super.hasAuthorizedCollectionAction(...arguments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import ModelAbility from 'api/abilities/model';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class OverrideModelAbility extends ModelAbility {
|
||||
// =services
|
||||
|
||||
@service features;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* If the capabilities feature flag is disabled, actions are always
|
||||
* authorized. This mimics pre-capabilities behavior.
|
||||
*/
|
||||
hasAuthorizedAction() {
|
||||
if (!this.features.isEnabled('capabilities')) return true;
|
||||
return super.hasAuthorizedAction(...arguments);
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ export default class CopyableComponent extends Component {
|
||||
id = generateComponentID();
|
||||
copyableButtonId = `copyable-button-${this.id}`;
|
||||
|
||||
actionIcon = 'copy-action';
|
||||
successIcon = 'copy-success';
|
||||
actionIcon = 'flight-icons/clipboard-copy-16';
|
||||
successIcon = 'flight-icons/clipboard-checked-16';
|
||||
actionText = this.args.buttonText;
|
||||
successText = this.args.acknowledgeText;
|
||||
|
||||
|
||||
@@ -117,11 +117,13 @@
|
||||
</form.input>
|
||||
{{/if}}
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
</Rose::Form>
|
||||
@@ -91,11 +91,13 @@
|
||||
</form.input>
|
||||
{{/if}}
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
</Rose::Form>
|
||||
@@ -6,7 +6,6 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@@ -178,7 +177,7 @@
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='warning'
|
||||
@iconOnly='trash'
|
||||
@iconOnly='flight-icons/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
@@ -279,7 +278,7 @@
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='warning'
|
||||
@iconOnly='trash'
|
||||
@iconOnly='flight-icons/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
@@ -369,7 +368,7 @@
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='warning'
|
||||
@iconOnly='trash'
|
||||
@iconOnly='flight-icons/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
@@ -478,7 +477,7 @@
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='warning'
|
||||
@iconOnly='trash'
|
||||
@iconOnly='flight-icons/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
@@ -579,7 +578,7 @@
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='warning'
|
||||
@iconOnly='trash'
|
||||
@iconOnly='flight-icons/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
@@ -678,11 +677,12 @@
|
||||
@disabled={{true}}
|
||||
/>
|
||||
{{/unless}}
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -51,11 +51,12 @@
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -118,10 +118,13 @@
|
||||
</form.textarea>
|
||||
{{/if}}
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
</Rose::Form>
|
||||
@@ -233,11 +233,12 @@
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -49,7 +49,7 @@
|
||||
{{t 'resources.group.messages.no-members.description'}}
|
||||
</message.description>
|
||||
<message.link @route='scopes.scope.groups.group.members'>
|
||||
<Rose::Icon @name='chevron-left' />
|
||||
<Rose::Icon @name='flight-icons/chevron-left-16' />
|
||||
{{t 'actions.back'}}
|
||||
</message.link>
|
||||
</Rose::Message>
|
||||
|
||||
@@ -46,11 +46,12 @@
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -45,12 +45,12 @@
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -55,7 +55,7 @@
|
||||
<message.link
|
||||
@route='scopes.scope.host-catalogs.host-catalog.host-sets.host-set.hosts'
|
||||
>
|
||||
<Rose::Icon @name='chevron-left' />
|
||||
<Rose::Icon @name='flight-icons/chevron-left-16' />
|
||||
{{t 'actions.back'}}
|
||||
</message.link>
|
||||
</Rose::Message>
|
||||
|
||||
@@ -52,12 +52,12 @@
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -71,12 +71,12 @@
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -58,7 +58,7 @@
|
||||
{{t 'resources.role.principal.messages.none.description'}}
|
||||
</message.description>
|
||||
<message.link @route='scopes.scope.roles.role.principals'>
|
||||
<Rose::Icon @name='chevron-left' />
|
||||
<Rose::Icon @name='flight-icons/chevron-left-16' />
|
||||
{{t 'actions.back'}}
|
||||
</message.link>
|
||||
</Rose::Message>
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<item.cell>
|
||||
<Rose::Button
|
||||
@style='secondary'
|
||||
@iconOnly='trash'
|
||||
@iconOnly='flight-icons/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
{{on 'click' (fn @removeGrant grant.value)}}
|
||||
>
|
||||
|
||||
@@ -69,9 +69,11 @@
|
||||
@text={{this.selectedGrantScope.displayName}}
|
||||
@icon={{if
|
||||
this.selectedGrantScope.isProject
|
||||
'app-icons/project'
|
||||
'flight-icons/grid-16'
|
||||
(if
|
||||
this.selectedGrantScope.isOrg 'app-icons/org' 'app-icons/global'
|
||||
this.selectedGrantScope.isOrg
|
||||
'flight-icons/org-16'
|
||||
'flight-icons/globe-16'
|
||||
)
|
||||
}}
|
||||
as |dropdown|
|
||||
@@ -119,12 +121,12 @@
|
||||
</form.radioGroup>
|
||||
</fieldset>
|
||||
{{/unless}}
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -46,11 +46,13 @@
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
</Rose::Form>
|
||||
@@ -55,7 +55,7 @@
|
||||
{{t 'resources.target.credential-library.messages.none.description'}}
|
||||
</message.description>
|
||||
<message.link @route='scopes.scope.targets.target.credential-libraries'>
|
||||
<Rose::Icon @name='chevron-left' />
|
||||
<Rose::Icon @name='flight-icons/chevron-left-16' />
|
||||
{{t 'actions.back'}}
|
||||
</message.link>
|
||||
</Rose::Message>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
{{t 'resources.target.host-set.messages.none.description'}}
|
||||
</message.description>
|
||||
<message.link @route='scopes.scope.targets.target.host-sets'>
|
||||
<Rose::Icon @name='chevron-left' />
|
||||
<Rose::Icon @name='flight-icons/chevron-left-16' />
|
||||
{{t 'actions.back'}}
|
||||
</message.link>
|
||||
</Rose::Message>
|
||||
|
||||
@@ -111,12 +111,12 @@
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -59,7 +59,7 @@
|
||||
{{t 'resources.user.messages.no-accounts.description'}}
|
||||
</message.description>
|
||||
<message.link @route='scopes.scope.users.user.accounts'>
|
||||
<Rose::Icon @name='chevron-left' />
|
||||
<Rose::Icon @name='flight-icons/chevron-left-16' />
|
||||
{{t 'actions.back'}}
|
||||
</message.link>
|
||||
</Rose::Message>
|
||||
|
||||
@@ -46,11 +46,12 @@
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
@submitText={{t 'actions.save'}}
|
||||
@cancelText={{t 'actions.cancel'}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Form>
|
||||
@@ -11,6 +11,7 @@ export default class ScopesScopeAuthMethodsRoute extends Route {
|
||||
@service intl;
|
||||
@service notify;
|
||||
@service session;
|
||||
@service can;
|
||||
|
||||
// =methods
|
||||
|
||||
@@ -26,8 +27,13 @@ export default class ScopesScopeAuthMethodsRoute extends Route {
|
||||
* @return {Promise[AuthMethodModel]}
|
||||
*/
|
||||
async model() {
|
||||
const { id: scope_id } = this.modelFor('scopes.scope');
|
||||
return this.store.query('auth-method', { scope_id });
|
||||
const scope = this.modelFor('scopes.scope');
|
||||
const { id: scope_id } = scope;
|
||||
if (
|
||||
this.can.can('list collection', scope, { collection: 'auth-methods' })
|
||||
) {
|
||||
return this.store.query('auth-method', { scope_id });
|
||||
}
|
||||
}
|
||||
|
||||
// =actions
|
||||
@@ -54,10 +60,14 @@ export default class ScopesScopeAuthMethodsRoute extends Route {
|
||||
)
|
||||
async save(authMethod) {
|
||||
await authMethod.save();
|
||||
await this.transitionTo(
|
||||
'scopes.scope.auth-methods.auth-method',
|
||||
authMethod
|
||||
);
|
||||
if (this.can.can('read model', authMethod)) {
|
||||
await this.transitionTo(
|
||||
'scopes.scope.auth-methods.auth-method',
|
||||
authMethod
|
||||
);
|
||||
} else {
|
||||
await this.transitionTo('scopes.scope.auth-methods');
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route
|
||||
|
||||
@service intl;
|
||||
@service notify;
|
||||
|
||||
@service can;
|
||||
// =methods
|
||||
|
||||
/**
|
||||
@@ -18,10 +18,15 @@ export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route
|
||||
* @return {Promise{[AccountModel]}}
|
||||
*/
|
||||
model() {
|
||||
const { id: auth_method_id } = this.modelFor(
|
||||
'scopes.scope.auth-methods.auth-method'
|
||||
);
|
||||
return this.store.query('account', { auth_method_id });
|
||||
const authMethod = this.modelFor('scopes.scope.auth-methods.auth-method');
|
||||
const { id: auth_method_id } = authMethod;
|
||||
if (
|
||||
this.can.can('list collection', authMethod, {
|
||||
collection: 'accounts',
|
||||
})
|
||||
) {
|
||||
return this.store.query('account', { auth_method_id });
|
||||
}
|
||||
}
|
||||
|
||||
// =actions
|
||||
@@ -55,10 +60,14 @@ export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route
|
||||
adapterOptions.password = password;
|
||||
}
|
||||
await account.save({ adapterOptions });
|
||||
await this.transitionTo(
|
||||
'scopes.scope.auth-methods.auth-method.accounts.account',
|
||||
account
|
||||
);
|
||||
if (this.can.can('read model', account)) {
|
||||
await this.transitionTo(
|
||||
'scopes.scope.auth-methods.auth-method.accounts.account',
|
||||
account
|
||||
);
|
||||
} else {
|
||||
await this.transitionTo('scopes.scope.auth-methods.auth-method.accounts');
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodAccountsAccountIndexRoute extends Route {}
|
||||
export default class ScopesScopeAuthMethodsAuthMethodAccountsAccountIndexRoute extends Route {
|
||||
// setupController(controller) {
|
||||
// const authMethod = this.modelFor(
|
||||
// 'scopes.scope.auth-methods.auth-method'
|
||||
// );
|
||||
// super.setupController(...arguments);
|
||||
// controller.setProperties({ authMethod });
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeAuthMethodsAuthMethodAccountsIndexRoute extends Route {
|
||||
setupController(controller) {
|
||||
const authMethod = this.modelFor('scopes.scope.auth-methods.auth-method');
|
||||
super.setupController(...arguments);
|
||||
controller.setProperties({ authMethod });
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import loading from 'ember-loading/decorator';
|
||||
import { confirm } from 'core/decorators/confirm';
|
||||
@@ -6,14 +7,21 @@ import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
|
||||
export default class ScopesScopeCredentialStoresRoute extends Route {
|
||||
// =methods
|
||||
|
||||
@service can;
|
||||
/**
|
||||
* Load all credential stores under current scope
|
||||
* @returns {Promise[CredentialStoreModel]}
|
||||
*/
|
||||
async model() {
|
||||
const { id: scope_id } = this.modelFor('scopes.scope');
|
||||
return this.store.query('credential-store', { scope_id });
|
||||
const scope = this.modelFor('scopes.scope');
|
||||
const { id: scope_id } = scope;
|
||||
if (
|
||||
this.can.can('list collection', scope, {
|
||||
collection: 'credential-stores',
|
||||
})
|
||||
) {
|
||||
return this.store.query('credential-store', { scope_id });
|
||||
}
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
+21
-6
@@ -3,19 +3,28 @@ import { action } from '@ember/object';
|
||||
import loading from 'ember-loading/decorator';
|
||||
import { confirm } from 'core/decorators/confirm';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeCredentialStoresCredentialStoreCredentialLibrariesRoute extends Route {
|
||||
// =methods
|
||||
@service can;
|
||||
|
||||
/**
|
||||
* Loads all credential libraries under the current credential store.
|
||||
* @return {Promise{[CredentialLibraryModel]}}
|
||||
*/
|
||||
model() {
|
||||
const { id: credential_store_id } = this.modelFor(
|
||||
const credentialStore = this.modelFor(
|
||||
'scopes.scope.credential-stores.credential-store'
|
||||
);
|
||||
return this.store.query('credential-library', { credential_store_id });
|
||||
const { id: credential_store_id } = credentialStore;
|
||||
if (
|
||||
this.can.can('list collection', credentialStore, {
|
||||
collection: 'credential-libraries',
|
||||
})
|
||||
) {
|
||||
return this.store.query('credential-library', { credential_store_id });
|
||||
}
|
||||
}
|
||||
|
||||
// =actions
|
||||
@@ -46,10 +55,16 @@ export default class ScopesScopeCredentialStoresCredentialStoreCredentialLibrari
|
||||
)
|
||||
async save(credentialLibrary) {
|
||||
await credentialLibrary.save();
|
||||
await this.transitionTo(
|
||||
'scopes.scope.credential-stores.credential-store.credential-libraries.credential-library',
|
||||
credentialLibrary
|
||||
);
|
||||
if (this.can.can('read model', credentialLibrary)) {
|
||||
await this.transitionTo(
|
||||
'scopes.scope.credential-stores.credential-store.credential-libraries.credential-library',
|
||||
credentialLibrary
|
||||
);
|
||||
} else {
|
||||
await this.transitionTo(
|
||||
'scopes.scope.credential-stores.credential-store.credential-libraries'
|
||||
);
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -1,3 +1,13 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeCredentialStoresCredentialStoreCredentialLibrariesIndexRoute extends Route {}
|
||||
export default class ScopesScopeCredentialStoresCredentialStoreCredentialLibrariesIndexRoute extends Route {
|
||||
// =methods
|
||||
|
||||
setupController(controller) {
|
||||
const credentialStore = this.modelFor(
|
||||
'scopes.scope.credential-stores.credential-store'
|
||||
);
|
||||
super.setupController(...arguments);
|
||||
controller.setProperties({ credentialStore });
|
||||
}
|
||||
}
|
||||
Loaded 100 of 265 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user