]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.ts
import 15.2.5
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / datatable / table-actions / table-actions.component.ts
1 import { Component, Input, OnInit } from '@angular/core';
2
3 import * as _ from 'lodash';
4
5 import { Icons } from '../../../shared/enum/icons.enum';
6 import { CdTableAction } from '../../models/cd-table-action';
7 import { CdTableSelection } from '../../models/cd-table-selection';
8 import { Permission } from '../../models/permissions';
9
10 @Component({
11 selector: 'cd-table-actions',
12 templateUrl: './table-actions.component.html',
13 styleUrls: ['./table-actions.component.scss']
14 })
15 export class TableActionsComponent implements OnInit {
16 @Input()
17 permission: Permission;
18 @Input()
19 selection: CdTableSelection;
20 @Input()
21 tableActions: CdTableAction[];
22 @Input()
23 btnColor = 'secondary';
24
25 // Use this if you just want to display a drop down button,
26 // labeled with the given text, with all actions in it.
27 // This disables the main action button.
28 @Input()
29 dropDownOnly?: string;
30
31 // Array with all visible actions
32 dropDownActions: CdTableAction[] = [];
33
34 icons = Icons;
35
36 constructor() {}
37
38 ngOnInit() {
39 this.removeActionsWithNoPermissions();
40 this.updateDropDownActions();
41 }
42
43 toClassName(name: string): string {
44 return name
45 .replace(/ /g, '-')
46 .replace(/[^a-z-]/gi, '')
47 .toLowerCase();
48 }
49
50 /**
51 * Removes all actions from 'tableActions' that need a permission the user doesn't have.
52 */
53 private removeActionsWithNoPermissions() {
54 if (!this.permission) {
55 this.tableActions = [];
56 return;
57 }
58 const permissions = Object.keys(this.permission).filter((key) => this.permission[key]);
59 this.tableActions = this.tableActions.filter((action) =>
60 permissions.includes(action.permission)
61 );
62 }
63
64 private updateDropDownActions() {
65 this.dropDownActions = this.tableActions.filter((action) =>
66 action.visible ? action.visible(this.selection) : action
67 );
68 }
69
70 /**
71 * Finds the next action that is used as main action for the button
72 *
73 * The order of the list is crucial to get the right main action.
74 *
75 * Default button conditions of actions:
76 * - 'create' actions can be used with no or multiple selections
77 * - 'update' and 'delete' actions can be used with one selection
78 *
79 * @returns {CdTableAction}
80 */
81 getCurrentButton(): CdTableAction {
82 if (this.dropDownOnly) {
83 return undefined;
84 }
85 let buttonAction = this.dropDownActions.find((tableAction) => this.showableAction(tableAction));
86 if (!buttonAction && this.dropDownActions.length > 0) {
87 buttonAction = this.dropDownActions[0];
88 }
89 return buttonAction;
90 }
91
92 /**
93 * Determines if action can be used for the button
94 *
95 * @param {CdTableAction} action
96 * @returns {boolean}
97 */
98 private showableAction(action: CdTableAction): boolean {
99 const condition = action.canBePrimary;
100 const singleSelection = this.selection.hasSingleSelection;
101 const defaultCase = action.permission === 'create' ? !singleSelection : singleSelection;
102 return (condition && condition(this.selection)) || (!condition && defaultCase);
103 }
104
105 useRouterLink(action: CdTableAction): string {
106 if (!action.routerLink || this.disableSelectionAction(action)) {
107 return undefined;
108 }
109 return _.isString(action.routerLink) ? action.routerLink : action.routerLink();
110 }
111
112 /**
113 * Determines if an action should be disabled
114 *
115 * Default disable conditions of 'update' and 'delete' actions:
116 * - If no or multiple selections are made
117 * - If one selection is made, but a task is executed on that item
118 *
119 * @param {CdTableAction} action
120 * @returns {Boolean}
121 */
122 disableSelectionAction(action: CdTableAction): Boolean {
123 const disable = action.disable;
124 if (disable) {
125 return Boolean(disable(this.selection));
126 }
127 const permission = action.permission;
128 const selected = this.selection.hasSingleSelection && this.selection.first();
129 return Boolean(
130 ['update', 'delete'].includes(permission) && (!selected || selected.cdExecuting)
131 );
132 }
133
134 showDropDownActions() {
135 this.updateDropDownActions();
136 return this.dropDownActions.length > 1;
137 }
138
139 useClickAction(action: CdTableAction) {
140 /**
141 * In order to show tooltips for deactivated menu items, the class
142 * 'pointer-events: auto;' has been added to the .scss file which also
143 * re-activates the click-event.
144 * To prevent calling the click-event on deactivated elements we also have
145 * to check here if it's disabled.
146 */
147 return !this.disableSelectionAction(action) && action.click && action.click();
148 }
149
150 useDisableDesc(action: CdTableAction) {
151 return action.disableDesc && action.disableDesc(this.selection);
152 }
153 }