]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
27ff4bbc65005917cb434ca28366764966876be5
[ceph.git] /
1 import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
2 import { CdTableColumn } from '../../models/cd-table-column';
3 import { CdFormGroup } from '../../forms/cd-form-group';
4 import _ from 'lodash';
5
6 @Component({
7   selector: 'cd-checked-table-form',
8   templateUrl: './checked-table-form.component.html',
9   styleUrls: ['./checked-table-form.component.scss']
10 })
11 export class CheckedTableFormComponent implements OnInit {
12   @Input() data: Array<any>;
13   @Input() columns: CdTableColumn[];
14   @Input() form: CdFormGroup;
15   @Input() inputField: string;
16   @Input() scopes: Array<string> = [];
17   @Input() isTableForOctalMode = false;
18   @Input() initialValue: any = {
19     owner: ['read', 'write', 'execute'],
20     group: ['read', 'execute'],
21     others: ['read', 'execute']
22   };
23
24   @ViewChild('headerPermissionCheckboxTpl', { static: true })
25   headerPermissionCheckboxTpl: TemplateRef<any>;
26   @ViewChild('cellScopeCheckboxTpl', { static: true })
27   cellScopeCheckboxTpl: TemplateRef<any>;
28   @ViewChild('cellPermissionCheckboxTpl', { static: true })
29   cellPermissionCheckboxTpl: TemplateRef<any>;
30
31   constructor() {}
32
33   ngOnInit(): void {
34     this.columns.forEach((column) => {
35       if (column.name === 'All') {
36         column.cellTemplate = this.cellScopeCheckboxTpl;
37         column.headerTemplate = this.headerPermissionCheckboxTpl;
38       } else {
39         column.cellTemplate = this.cellPermissionCheckboxTpl;
40         column.headerTemplate = this.headerPermissionCheckboxTpl;
41       }
42     });
43     this.listenToChanges();
44     this.form.get(this.inputField).setValue(this.initialValue);
45   }
46
47   listenToChanges() {
48     // Create/Update the data which is used by the data table to display the
49     // scopes/permissions every time the form field value has been changed.
50     this.form.get(this.inputField).valueChanges.subscribe((value) => {
51       const scopesPermissions: any[] = [];
52       _.each(this.scopes, (scope) => {
53         // Set the defaults values.
54         const scopePermission: any = { read: false, write: false, execute: false };
55         scopePermission['scope'] = scope;
56         // Apply settings from the given value if they exist.
57         if (scope in value) {
58           _.each(value[scope], (permission) => {
59             scopePermission[permission] = true;
60           });
61         }
62         scopesPermissions.push(scopePermission);
63       });
64       this.data = scopesPermissions;
65     });
66   }
67
68   /**
69    * Checks if the specified row checkbox needs to be rendered as checked.
70    * @param {string} scope The scope to be checked, e.g. 'cephfs', 'grafana',
71    *   'osd', 'pool' ...
72    * @return Returns true if all permissions (read, create, update, delete)
73    *   are checked for the specified scope, otherwise false.
74    */
75   isRowChecked(scope: string) {
76     const scope_permission = _.find(this.data, (o) => {
77       return o['scope'] === scope;
78     });
79     if (_.isUndefined(scope_permission)) {
80       return false;
81     }
82     if (this.isTableForOctalMode) {
83       return scope_permission['read'] && scope_permission['write'] && scope_permission['execute'];
84     }
85     return (
86       scope_permission['read'] &&
87       scope_permission['create'] &&
88       scope_permission['update'] &&
89       scope_permission['delete']
90     );
91   }
92
93   /**
94    * Checks if the specified header checkbox needs to be rendered as checked.
95    * @param {string} property The property/permission (read, create,
96    *   update, delete) to be checked. If 'scope' is given, all permissions
97    *   are checked.
98    * @return Returns true if specified property/permission is selected
99    *   for all scopes, otherwise false.
100    */
101   isHeaderChecked(property: string) {
102     let permissions = [property];
103     if ('scope' === property && this.isTableForOctalMode) {
104       permissions = ['read', 'write', 'execute'];
105     } else if ('scope' === property) {
106       permissions = ['read', 'create', 'update', 'delete'];
107     }
108     return permissions.every((permission) => {
109       return this.data.every((scope_permission) => {
110         return scope_permission[permission];
111       });
112     });
113   }
114
115   onClickCellCheckbox(scope: string, property: string, event: any = null) {
116     // Use a copy of the form field data to do not trigger the redrawing of the
117     // data table with every change.
118     const scopes_permissions = _.cloneDeep(this.form.getValue(this.inputField));
119     let permissions = [property];
120     if ('scope' === property && this.isTableForOctalMode) {
121       permissions = ['read', 'write', 'execute'];
122     } else if ('scope' === property) {
123       permissions = ['read', 'create', 'update', 'delete'];
124     }
125     if (!(scope in scopes_permissions)) {
126       scopes_permissions[scope] = [];
127     }
128     // Add or remove the given permission(s) depending on the click event or if no
129     // click event is given then add/remove them if they are absent/exist.
130     if (
131       (event && event.target['checked']) ||
132       !_.isEqual(permissions.sort(), _.intersection(scopes_permissions[scope], permissions).sort())
133     ) {
134       scopes_permissions[scope] = _.union(scopes_permissions[scope], permissions);
135     } else {
136       scopes_permissions[scope] = _.difference(scopes_permissions[scope], permissions);
137       if (_.isEmpty(scopes_permissions[scope])) {
138         _.unset(scopes_permissions, scope);
139       }
140     }
141     this.form.get(this.inputField).setValue(scopes_permissions);
142   }
143
144   onClickHeaderCheckbox(property: string, event: any) {
145     // Use a copy of the form field data to do not trigger the redrawing of the
146     // data table with every change.
147     const scopes_permissions = _.cloneDeep(this.form.getValue(this.inputField));
148     let permissions = [property];
149     if ('scope' === property && this.isTableForOctalMode) {
150       permissions = ['read', 'write', 'execute'];
151     } else if ('scope' === property) {
152       permissions = ['read', 'create', 'update', 'delete'];
153     }
154     _.each(permissions, (permission) => {
155       _.each(this.scopes, (scope) => {
156         if (event.target['checked']) {
157           scopes_permissions[scope] = _.union(scopes_permissions[scope], [permission]);
158         } else {
159           scopes_permissions[scope] = _.difference(scopes_permissions[scope], [permission]);
160           if (_.isEmpty(scopes_permissions[scope])) {
161             _.unset(scopes_permissions, scope);
162           }
163         }
164       });
165     });
166     this.form.get(this.inputField).setValue(scopes_permissions);
167   }
168 }