]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html
01cc1fbc8d92d01995340e976e2661020ce001f6
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / datatable / table / table.component.html
1 <div class="dataTables_wrapper">
2
3 <div *ngIf="onlyActionHeader"
4 class="dataTables_header clearfix">
5 <div class="cd-datatable-actions">
6 <ng-content select=".only-table-actions"></ng-content>
7 </div>
8 </div>
9 <div class="dataTables_header clearfix"
10 *ngIf="toolHeader">
11 <!-- actions -->
12 <div class="cd-datatable-actions">
13 <ng-content select=".table-actions"></ng-content>
14 </div>
15 <!-- end actions -->
16
17 <!-- column filters -->
18 <div *ngIf="columnFilters.length !== 0"
19 class="btn-group widget-toolbar">
20 <div ngbDropdown
21 placement="bottom-right"
22 class="tc_filter_name">
23 <button ngbDropdownToggle
24 class="btn btn-light"
25 title="Filter">
26 <i [ngClass]="[icons.large, icons.filter]"></i>
27 {{ selectedFilter.column.name }}
28 </button>
29 <div ngbDropdownMenu>
30 <ng-container *ngFor="let filter of columnFilters">
31 <button ngbDropdownItem
32 (click)="onSelectFilter(filter); false">{{ filter.column.name }}</button>
33 </ng-container>
34 </div>
35 </div>
36
37 <div ngbDropdown
38 placement="bottom-right"
39 class="tc_filter_option">
40 <button ngbDropdownToggle
41 class="btn btn-light"
42 [class.disabled]="selectedFilter.options.length === 0">
43 {{ selectedFilter.value ? selectedFilter.value.formatted: 'Any' }}
44 </button>
45 <div ngbDropdownMenu>
46 <ng-container *ngFor="let option of selectedFilter.options">
47 <button ngbDropdownItem
48 (click)="onChangeFilter(selectedFilter, option); false">
49 {{ option.formatted }}
50 <i *ngIf="selectedFilter.value !== undefined && (selectedFilter.value.raw === option.raw)"
51 [ngClass]="[icons.check]"></i>
52 </button>
53 </ng-container>
54 </div>
55 </div>
56 </div>
57 <!-- end column filters -->
58
59 <!-- search -->
60 <div class="input-group search"
61 *ngIf="searchField">
62 <span class="input-group-text">
63 <i [ngClass]="[icons.search]"></i>
64 </span>
65 <input aria-label="search"
66 class="form-control"
67 type="text"
68 [(ngModel)]="search"
69 (keyup)="updateFilter()">
70 <button type="button"
71 class="btn btn-light"
72 title="Clear"
73 (click)="onClearSearch()">
74 <i class="icon-prepend {{ icons.destroy }}"></i>
75 </button>
76 </div>
77 <!-- end search -->
78
79 <!-- pagination limit -->
80 <div class="input-group dataTables_paginate"
81 *ngIf="limit">
82 <input aria-label="table pagination"
83 class="form-control"
84 type="number"
85 min="1"
86 max="9999"
87 [value]="userConfig.limit"
88 (click)="setLimit($event)"
89 (keyup)="setLimit($event)"
90 (blur)="setLimit($event)">
91 </div>
92 <!-- end pagination limit-->
93
94 <!-- show hide columns -->
95 <div class="widget-toolbar">
96 <div ngbDropdown
97 autoClose="outside"
98 class="tc_menuitem">
99 <button ngbDropdownToggle
100 class="btn btn-light tc_columnBtn"
101 title="toggle columns">
102 <i [ngClass]="[icons.large, icons.table]"></i>
103 </button>
104 <div ngbDropdownMenu>
105 <ng-container *ngFor="let column of columns">
106 <button ngbDropdownItem
107 *ngIf="column.name !== ''"
108 (click)="toggleColumn(column); false;">
109 <div class="custom-control custom-checkbox py-0">
110 <input class="custom-control-input"
111 type="checkbox"
112 [name]="column.prop"
113 id="{{ column.prop }}{{ tableName }}"
114 [checked]="!column.isHidden">
115 <label class="custom-control-label"
116 for="{{ column.prop }}{{ tableName }}">{{ column.name }}</label>
117 </div>
118 </button>
119 </ng-container>
120 </div>
121 </div>
122 </div>
123 <!-- end show hide columns -->
124
125 <!-- refresh button -->
126 <div class="widget-toolbar tc_refreshBtn"
127 *ngIf="fetchData.observers.length > 0">
128
129 <button type="button"
130 [class]="'btn btn-' + status.type"
131 [ngbTooltip]="status.msg"
132 (click)="refreshBtn()"
133 title="Refresh">
134 <i [ngClass]="[icons.large, icons.refresh]"
135 [class.fa-spin]="updating || loadingIndicator"></i>
136 </button>
137 </div>
138 <!-- end refresh button -->
139 </div>
140 <div class="dataTables_header clearfix"
141 *ngIf="toolHeader && columnFiltered">
142 <!-- filter chips for column filters -->
143 <div class="filter-chips">
144 <span *ngFor="let filter of columnFilters">
145 <span *ngIf="filter.value"
146 class="badge badge-info me-2">
147 <span class="me-2">{{ filter.column.name }}: {{ filter.value.formatted }}</span>
148 <a class="badge-remove"
149 (click)="onChangeFilter(filter); false">
150 <i [ngClass]="[icons.destroy]"
151 aria-hidden="true"></i>
152 </a>
153 </span>
154 </span>
155 <a class="tc_clearSelections"
156 href=""
157 (click)="onClearFilters(); false">
158 <ng-container i18n>Clear filters</ng-container>
159 </a>
160 </div>
161 <!-- end filter chips for column filters -->
162 </div>
163 <ngx-datatable #table
164 class="bootstrap cd-datatable"
165 [cssClasses]="paginationClasses"
166 [selectionType]="selectionType"
167 [selected]="selection.selected"
168 (select)="onSelect($event)"
169 [sorts]="userConfig.sorts"
170 (sort)="changeSorting($event)"
171 [columns]="tableColumns"
172 [columnMode]="columnMode"
173 [rows]="rows"
174 [rowClass]="getRowClass()"
175 [headerHeight]="header ? 'auto' : 0"
176 [footerHeight]="footer ? 'auto' : 0"
177 [count]="count"
178 [externalPaging]="serverSide"
179 [externalSorting]="serverSide"
180 [limit]="userConfig.limit > 0 ? userConfig.limit : undefined"
181 [offset]="userConfig.offset >= 0 ? userConfig.offset : 0"
182 (page)="changePage($event)"
183 [loadingIndicator]="loadingIndicator"
184 [rowIdentity]="rowIdentity()"
185 [rowHeight]="'auto'">
186
187 <!-- Row Selection Template-->
188 <ng-template #rowSelectionTpl
189 let-value="value"
190 let-isSelected="isSelected"
191 ngx-datatable-cell-template>
192 <input type="checkbox"
193 [attr.aria-label]="isSelected ? 'selected' : 'select'"
194 [checked]="isSelected"
195 class="cd-datatable-checkbox" />
196 </ng-template>
197
198 <!-- Row Detail Template -->
199 <ngx-datatable-row-detail rowHeight="auto"
200 #detailRow>
201 <ng-template let-row="row"
202 let-expanded="expanded"
203 ngx-datatable-row-detail-template>
204 <!-- Table Details -->
205 <ng-content select="[cdTableDetail]"></ng-content>
206 </ng-template>
207 </ngx-datatable-row-detail>
208
209 <ngx-datatable-footer>
210 <ng-template ngx-datatable-footer-template
211 let-rowCount="rowCount"
212 let-pageSize="pageSize"
213 let-selectedCount="selectedCount"
214 let-curPage="curPage"
215 let-offset="offset"
216 let-isVisible="isVisible">
217 <div class="page-count">
218 <span *ngIf="selectionType">
219 {{ selectedCount }} <ng-container i18n="X selected">selected</ng-container> /
220 </span>
221
222 <!-- rowCount might have different semantics with or without serverSide.
223 We treat serverSide (backend-driven tables) as a specific case.
224 -->
225 <span *ngIf="!serverSide else serverSideTpl">
226 <span *ngIf="rowCount != data?.length">
227 {{ rowCount }} <ng-container i18n="X found">found</ng-container> /
228 </span>
229 {{ data?.length || 0 }} <ng-container i18n="X total">total</ng-container>
230 </span>
231
232 <ng-template #serverSideTpl>
233 <span>
234 {{ data?.length || 0 }} <ng-container i18n="X found">found</ng-container> /
235 {{ rowCount }} <ng-container i18n="X total">total</ng-container>
236 </span>
237 </ng-template>
238 </div>
239 <cd-table-pagination [page]="curPage"
240 [size]="pageSize"
241 [count]="rowCount"
242 [hidden]="!((rowCount / pageSize) > 1)"
243 (pageChange)="table.onFooterPage($event)"></cd-table-pagination>
244 </ng-template>
245 </ngx-datatable-footer>
246 </ngx-datatable>
247 </div>
248
249 <!-- cell templates that can be accessed from outside -->
250 <ng-template #tableCellBoldTpl
251 let-value="value">
252 <strong>{{ value }}</strong>
253 </ng-template>
254
255 <ng-template #sparklineTpl
256 let-row="row"
257 let-value="value">
258 <cd-sparkline [data]="value"
259 [isBinary]="row.cdIsBinary"></cd-sparkline>
260 </ng-template>
261
262 <ng-template #routerLinkTpl
263 let-row="row"
264 let-value="value">
265 <a [routerLink]="[row.cdLink]"
266 [queryParams]="row.cdParams">{{ value }}</a>
267 </ng-template>
268
269 <ng-template #checkIconTpl
270 let-value="value">
271 <i [ngClass]="[icons.check]"
272 [hidden]="!(value | boolean)"></i>
273 </ng-template>
274
275 <ng-template #perSecondTpl
276 let-row="row"
277 let-value="value">
278 {{ value | dimless }} /s
279 </ng-template>
280
281 <ng-template #executingTpl
282 let-column="column"
283 let-row="row"
284 let-value="value">
285 <i [ngClass]="[icons.spinner, icons.spin]"
286 *ngIf="row.cdExecuting"></i>
287 <span [ngClass]="column?.customTemplateConfig?.valueClass">
288 {{ value }}
289 </span>
290 <span *ngIf="row.cdExecuting"
291 [ngClass]="column?.customTemplateConfig?.executingClass ? column.customTemplateConfig.executingClass : 'text-muted italic'">({{ row.cdExecuting }})</span>
292 </ng-template>
293
294 <ng-template #classAddingTpl
295 let-value="value">
296 <span class="{{ value | pipeFunction:useCustomClass:this }}">{{ value }}</span>
297 </ng-template>
298
299 <ng-template #badgeTpl
300 let-column="column"
301 let-value="value">
302 <span *ngFor="let item of (value | array); last as last">
303 <span class="badge"
304 [ngClass]="(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.class) ? column.customTemplateConfig.map[item].class : (column?.customTemplateConfig?.class ? column.customTemplateConfig.class : 'badge-primary')"
305 *ngIf="(column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.value) ? column.customTemplateConfig.map[item].value : column?.customTemplateConfig?.prefix ? column.customTemplateConfig.prefix + item : item">
306 {{ (column?.customTemplateConfig?.map && column?.customTemplateConfig?.map[item]?.value) ? column.customTemplateConfig.map[item].value : column?.customTemplateConfig?.prefix ? column.customTemplateConfig.prefix + item : item }}
307 </span>
308 <span *ngIf="!last">&nbsp;</span>
309 </span>
310 </ng-template>
311
312 <ng-template #mapTpl
313 let-column="column"
314 let-value="value">
315 <span>{{ value | map:column?.customTemplateConfig }}</span>
316 </ng-template>
317
318 <ng-template #truncateTpl
319 let-column="column"
320 let-value="value">
321 <span data-toggle="tooltip"
322 [title]="value">{{ value | truncate:column?.customTemplateConfig?.length:column?.customTemplateConfig?.omission }}</span>
323 </ng-template>
324
325 <ng-template #rowDetailsTpl
326 let-row="row"
327 let-isExpanded="expanded"
328 ngx-datatable-cell-template>
329 <a href="javascript:void(0)"
330 [class.expand-collapse-icon-right]="!isExpanded"
331 [class.expand-collapse-icon-down]="isExpanded"
332 class="expand-collapse-icon tc_expand-collapse"
333 title="Expand/Collapse Row"
334 i18n-title
335 (click)="toggleExpandRow(row, isExpanded, $event)">
336 </a>
337 </ng-template>
338
339 <ng-template #timeAgoTpl
340 let-value="value">
341 <span data-toggle="tooltip"
342 [title]="value | cdDate">{{ value | relativeDate }}</span>
343 </ng-template>
344
345 <ng-template #pathTpl
346 let-value="value">
347 <span data-toggle="tooltip"
348 [title]="value"
349 class="font-monospace">{{ value | path }}
350 <cd-copy-2-clipboard-button *ngIf="value"
351 [source]="value"
352 [byId]="false"
353 [showIconOnly]="true">
354 </cd-copy-2-clipboard-button>
355 </span>
356 </ng-template>