Browse Source

Minor UI improvement for roles.

pull/448/head
Sebastian 6 years ago
parent
commit
9241f1e870
  1. 15
      frontend/app/_theme.html
  2. 16
      frontend/app/features/settings/pages/roles/role.component.html
  3. 8
      frontend/app/features/settings/pages/roles/role.component.scss
  4. 9
      frontend/app/features/settings/pages/roles/role.component.ts
  5. 6
      frontend/app/framework/angular/forms/autocomplete.component.html
  6. 6
      frontend/app/framework/angular/forms/autocomplete.component.ts
  7. 7
      frontend/app/framework/angular/forms/focus-on-init.directive.ts
  8. 14
      frontend/app/theme/_forms.scss
  9. 1
      frontend/app/theme/_vars.scss
  10. 75
      frontend/package-lock.json
  11. 1
      frontend/package.json

15
frontend/app/_theme.html

@ -514,6 +514,11 @@
<input type="email" class="form-control" aria-describedby="emailHelp" placeholder="Enter email"> <input type="email" class="form-control" aria-describedby="emailHelp" placeholder="Enter email">
<small class="text-muted form-text">We'll never share your email with anyone else.</small> <small class="text-muted form-text">We'll never share your email with anyone else.</small>
</div> </div>
<div class="form-group">
<label for="underlinedInputHelp">Underlined</label>
<input type="text" class="form-control form-underlined" name="xyz" aria-describedby="underlinedInputHelp" placeholder="Enter text">
<small class="text-muted form-text">Input with just a line.</small>
</div>
<div class="form-group"> <div class="form-group">
<label for="exampleInputPassword1">Password</label> <label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" placeholder="Password"> <input type="password" class="form-control" placeholder="Password">
@ -587,6 +592,11 @@
<label class="control-label" for="disabledInput">Disabled input</label> <label class="control-label" for="disabledInput">Disabled input</label>
<input class="form-control" type="text" placeholder="Disabled input here..." disabled=""> <input class="form-control" type="text" placeholder="Disabled input here..." disabled="">
</fieldset> </fieldset>
<fieldset disabled>
<label class="control-label" for="disabledInput">Disabled underlined input</label>
<input class="form-control form-underlined" type="text" placeholder="Disabled input here..." disabled="">
</fieldset>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -594,6 +604,11 @@
<label class="control-label" for="readOnlyInput">Readonly input</label> <label class="control-label" for="readOnlyInput">Readonly input</label>
<input class="form-control" type="text" placeholder="Readonly input here…" readonly> <input class="form-control" type="text" placeholder="Readonly input here…" readonly>
</fieldset> </fieldset>
<fieldset>
<label class="control-label" for="readOnlyInput">Readonly underlined input</label>
<input class="form-control form-underlined" type="text" placeholder="Readonly input here…" readonly>
</fieldset>
</div> </div>
<div class="form-group has-success"> <div class="form-group has-success">

16
frontend/app/features/settings/pages/roles/role.component.html

@ -38,11 +38,12 @@
</div> </div>
<div class="table-items-row-details-tab"> <div class="table-items-row-details-tab">
<ng-container *ngIf="!role.isDefaultRole; else defaultRole">
<div class="form-group row no-gutters" *ngFor="let control of editForm.controls; let i = index"> <div class="form-group row no-gutters" *ngFor="let control of editForm.controls; let i = index">
<div class="col"> <div class="col">
<sqx-control-errors [for]="control" [fieldName]="'Permission'" [submitted]="editForm.submitted | async"></sqx-control-errors> <sqx-control-errors [for]="control" [fieldName]="'Permission'" [submitted]="editForm.submitted | async"></sqx-control-errors>
<sqx-autocomplete [formControl]="control" [source]="allPermissions"></sqx-autocomplete> <sqx-autocomplete [underlined]="true" [formControl]="control" [source]="allPermissions"></sqx-autocomplete>
</div> </div>
<div class="col-auto pl-1" *ngIf="isEditable"> <div class="col-auto pl-1" *ngIf="isEditable">
<button type="button" class="btn btn-text-danger" (click)="removePermission(i)"> <button type="button" class="btn btn-text-danger" (click)="removePermission(i)">
@ -50,10 +51,21 @@
</button> </button>
</div> </div>
</div> </div>
</ng-container>
<ng-template #defaultRole>
<sqx-form-alert>
{{descriptions[role.name]}}
</sqx-form-alert>
<div class="form-group" *ngFor="let control of editForm.controls">
<input class="form-control form-underlined" [formControl]="control" />
</div>
</ng-template>
<form class="form-group row no-gutters" [formGroup]="addPermissionForm.form" (ngSubmit)="addPermission()" *ngIf="isEditable"> <form class="form-group row no-gutters" [formGroup]="addPermissionForm.form" (ngSubmit)="addPermission()" *ngIf="isEditable">
<div class="col"> <div class="col">
<sqx-autocomplete formControlName="permission" [source]="allPermissions" #addInput></sqx-autocomplete> <sqx-autocomplete [autoFocus]="true" formControlName="permission" [source]="allPermissions" #addInput></sqx-autocomplete>
</div> </div>
<div class="col-auto pl-1"> <div class="col-auto pl-1">
<button type="submit" class="btn btn-success"> <button type="submit" class="btn btn-success">

8
frontend/app/features/settings/pages/roles/role.component.scss

@ -11,6 +11,14 @@
} }
} }
.prefix {
border: 0;
border-bottom: 1px solid $color-input;
padding-left: 0;
padding-right: 0;
color: $color-text-decent;
}
.rule-name { .rule-name {
@include truncate; @include truncate;
} }

9
frontend/app/features/settings/pages/roles/role.component.ts

@ -18,6 +18,13 @@ import {
RolesState RolesState
} from '@app/shared'; } from '@app/shared';
const Descriptions = {
'Developer': 'Can use the API view, edit assets, contents, schemas, rules, workflows and patterns.',
'Editor': 'Can edit assets and contents and view workflows.',
'Owner': 'Can do everything, including deleting the app.',
'Reader': 'Can only read assets and contents.'
};
@Component({ @Component({
selector: 'sqx-role', selector: 'sqx-role',
styleUrls: ['./role.component.scss'], styleUrls: ['./role.component.scss'],
@ -37,6 +44,8 @@ export class RoleComponent implements OnChanges {
@ViewChild('addInput', { static: false }) @ViewChild('addInput', { static: false })
public addPermissionInput: AutocompleteComponent; public addPermissionInput: AutocompleteComponent;
public descriptions = Descriptions;
public isEditing = false; public isEditing = false;
public isEditable = false; public isEditable = false;

6
frontend/app/framework/angular/forms/autocomplete.component.html

@ -1,5 +1,9 @@
<span> <span>
<input type="text" class="form-control" (blur)="blur()" [attr.name]="inputName" (keydown)="onKeyDown($event)" [attr.placeholder]="placeholder" #input <input type="text" class="form-control" (blur)="blur()" (keydown)="onKeyDown($event)"
[sqxFocusOnInit]="autoFocus"
[attr.name]="inputName"
[attr.placeholder]="placeholder" #input
[class.form-underlined]="underlined"
[formControl]="queryInput" [formControl]="queryInput"
autocomplete="off" autocomplete="off"
autocorrect="off" autocorrect="off"

6
frontend/app/framework/angular/forms/autocomplete.component.ts

@ -55,6 +55,12 @@ export class AutocompleteComponent extends StatefulControlComponent<State, any[]
@Input() @Input()
public placeholder = ''; public placeholder = '';
@Input()
public autoFocus = false;
@Input()
public underlined = false;
@ContentChild(TemplateRef, { static: false }) @ContentChild(TemplateRef, { static: false })
public itemTemplate: TemplateRef<any>; public itemTemplate: TemplateRef<any>;

7
frontend/app/framework/angular/forms/focus-on-init.directive.ts

@ -16,12 +16,19 @@ export class FocusOnInitDirective implements AfterViewInit {
@Input() @Input()
public select: boolean; public select: boolean;
@Input('sqxFocusOnInit')
public enabled = true;
constructor( constructor(
private readonly element: ElementRef<HTMLElement> private readonly element: ElementRef<HTMLElement>
) { ) {
} }
public ngAfterViewInit() { public ngAfterViewInit() {
if (!this.enabled) {
return;
}
setTimeout(() => { setTimeout(() => {
if (Types.isFunction(this.element.nativeElement.focus)) { if (Types.isFunction(this.element.nativeElement.focus)) {
this.element.nativeElement.focus(); this.element.nativeElement.focus();

14
frontend/app/theme/_forms.scss

@ -149,7 +149,7 @@
@include border-radius(.25em); @include border-radius(.25em);
@include box-shadow; @include box-shadow;
max-height: 15rem; max-height: 15rem;
border: 1px solid $color-input-border; border: 1px solid $color-input;
background: $color-dark-foreground; background: $color-dark-foreground;
padding: .25rem 0; padding: .25rem 0;
overflow-y: auto; overflow-y: auto;
@ -257,10 +257,8 @@ input {
&.form-underlined { &.form-underlined {
& { & {
@include border-radius(0); @include border-radius(0);
padding-left: 0;
padding-right: 0;
border: 0; border: 0;
border-bottom: 1px solid $color-input-border; border-bottom: 1px solid $color-input;
} }
&:focus, &:focus,
@ -272,6 +270,14 @@ input {
outline: none; outline: none;
} }
&:disabled {
background: none;
}
&[readonly] {
background: none;
}
&.ng-invalid { &.ng-invalid {
&.ng-touched, &.ng-touched,
&.ng-dirty { &.ng-dirty {

1
frontend/app/theme/_vars.scss

@ -40,7 +40,6 @@ $color-theme-info: #5bc0de;
$color-input: #dbe4eb; $color-input: #dbe4eb;
$color-input-background: #fff; $color-input-background: #fff;
$color-input-disabled: $color-theme-secondary; $color-input-disabled: $color-theme-secondary;
$color-input-border: rgba(0, 0, 0, .15);
$color-input-placeholder: lighten($color-text-decent, 20%); $color-input-placeholder: lighten($color-text-decent, 20%);
$color-dark1-background: #2e3842; $color-dark1-background: #2e3842;

75
frontend/package-lock.json

@ -1134,14 +1134,6 @@
"tslib": "^1.9.0" "tslib": "^1.9.0"
} }
}, },
"@angular/http": {
"version": "7.2.15",
"resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.15.tgz",
"integrity": "sha512-TR7PEdmLWNIre3Zn8lvyb4lSrvPUJhKLystLnp4hBMcWsJqq5iK8S3bnlR4viZ9HMlf7bW7+Hm4SI6aB3tdUtw==",
"requires": {
"tslib": "^1.9.0"
}
},
"@angular/platform-browser": { "@angular/platform-browser": {
"version": "8.2.9", "version": "8.2.9",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.2.9.tgz", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.2.9.tgz",
@ -2632,9 +2624,9 @@
}, },
"dependencies": { "dependencies": {
"glob": { "glob": {
"version": "7.1.4", "version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true, "dev": true,
"requires": { "requires": {
"fs.realpath": "^1.0.0", "fs.realpath": "^1.0.0",
@ -2646,9 +2638,9 @@
} }
}, },
"graceful-fs": { "graceful-fs": {
"version": "4.2.2", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
"dev": true "dev": true
}, },
"lru-cache": { "lru-cache": {
@ -4929,9 +4921,9 @@
} }
}, },
"find-cache-dir": { "find-cache-dir": {
"version": "3.0.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.0.0.tgz", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.1.0.tgz",
"integrity": "sha512-t7ulV1fmbxh5G9l/492O1p5+EBbr3uwpt6odhFTMc+nWyhmbloe+ja9BZ8pIBtqFWhOmCWVjx+pTW4zDkFoclw==", "integrity": "sha512-zw+EFiNBNPgI2NTrKkDd1xd7q0cs6wr/iWnr/oUkI0yF9K9GqQ+riIt4aiyFaaqpaWbxPrJXHI+QvmNUQbX+0Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"commondir": "^1.0.1", "commondir": "^1.0.1",
@ -8343,9 +8335,9 @@
"dev": true "dev": true
}, },
"minipass": { "minipass": {
"version": "3.0.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.0.1.tgz", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
"integrity": "sha512-2y5okJ4uBsjoD2vAbLKL9EUQPPkC0YMIp+2mZOXG3nBba++pdfJWRxx2Ewirc0pwAJYu4XtWg2EkVo1nRXuO/w==", "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
"dev": true, "dev": true,
"requires": { "requires": {
"yallist": "^4.0.0" "yallist": "^4.0.0"
@ -11902,13 +11894,13 @@
} }
}, },
"ssri": { "ssri": {
"version": "7.0.1", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-7.0.1.tgz", "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz",
"integrity": "sha512-FfndBvkXL9AHyGLNzU3r9AvYIBBZ7gm+m+kd0p8cT3/v4OliMAyipZAhLVEv1Zi/k4QFq9CstRGVd9pW/zcHFQ==", "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==",
"dev": true, "dev": true,
"requires": { "requires": {
"figgy-pudding": "^3.5.1", "figgy-pudding": "^3.5.1",
"minipass": "^3.0.0" "minipass": "^3.1.1"
} }
}, },
"stable": { "stable": {
@ -12357,18 +12349,18 @@
} }
}, },
"terser-webpack-plugin": { "terser-webpack-plugin": {
"version": "2.1.2", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.1.2.tgz", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.2.1.tgz",
"integrity": "sha512-MF/C4KABwqYOfRDi87f7gG07GP7Wj/kyiX938UxIGIO6l5mkh8XJL7xtS0hX/CRdVQaZI7ThGUPZbznrCjsGpg==", "integrity": "sha512-jwdauV5Al7zopR6OAYvIIRcxXCSvLjZjr7uZE8l2tIWb/ryrGN48sJftqGf5k9z09tWhajx53ldp0XPI080YnA==",
"dev": true, "dev": true,
"requires": { "requires": {
"cacache": "^13.0.0", "cacache": "^13.0.1",
"find-cache-dir": "^3.0.0", "find-cache-dir": "^3.0.0",
"jest-worker": "^24.9.0", "jest-worker": "^24.9.0",
"schema-utils": "^2.4.1", "schema-utils": "^2.5.0",
"serialize-javascript": "^2.1.0", "serialize-javascript": "^2.1.0",
"source-map": "^0.6.1", "source-map": "^0.6.1",
"terser": "^4.3.4", "terser": "^4.3.9",
"webpack-sources": "^1.4.3" "webpack-sources": "^1.4.3"
}, },
"dependencies": { "dependencies": {
@ -12390,6 +12382,12 @@
"integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
"dev": true "dev": true
}, },
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"fast-deep-equal": { "fast-deep-equal": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
@ -12403,15 +12401,26 @@
"dev": true "dev": true
}, },
"schema-utils": { "schema-utils": {
"version": "2.4.1", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz",
"integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"ajv": "^6.10.2", "ajv": "^6.10.2",
"ajv-keywords": "^3.4.1" "ajv-keywords": "^3.4.1"
} }
}, },
"terser": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.4.0.tgz",
"integrity": "sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==",
"dev": true,
"requires": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
"source-map-support": "~0.5.12"
}
},
"uri-js": { "uri-js": {
"version": "4.2.2", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",

1
frontend/package.json

@ -19,7 +19,6 @@
"@angular/common": "8.2.9", "@angular/common": "8.2.9",
"@angular/core": "8.2.9", "@angular/core": "8.2.9",
"@angular/forms": "8.2.9", "@angular/forms": "8.2.9",
"@angular/http": "7.2.15",
"@angular/platform-browser": "8.2.9", "@angular/platform-browser": "8.2.9",
"@angular/platform-browser-dynamic": "8.2.9", "@angular/platform-browser-dynamic": "8.2.9",
"@angular/platform-server": "8.2.9", "@angular/platform-server": "8.2.9",

Loading…
Cancel
Save