if (!apps || apps.length === 0) {
return;
}
- cy.get('.float-left.mr-2.select-menu-edit').click();
+ cy.get('.float-start.me-2.select-menu-edit').click();
cy.get('.popover-body').should('be.visible');
apps.forEach((app) => cy.get('.select-menu-item-content').contains(app).click());
}
"dev": true
},
"@ng-bootstrap/ng-bootstrap": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-10.0.0.tgz",
- "integrity": "sha512-Sz+QaxjuyJYJ+zyUbf0TevgcgVesCPQiiFiggEzxKjzY5R+Hvq3YgryLdXf2r/ryePL+C3FXCcmmKpTM5bfczQ==",
+ "version": "12.1.2",
+ "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-12.1.2.tgz",
+ "integrity": "sha512-p27c+mYVdHiJMYrj5hwClVJxLdiZxafAqlbw1sdJh2xJ1rGOe+H/kCf5YDRbhlHqRN+34Gr0RQqIUeD1I2V8hg==",
"requires": {
- "tslib": "^2.1.0"
+ "tslib": "^2.3.0"
}
},
"@ngtools/webpack": {
"read-package-json-fast": "^2.0.1"
}
},
+ "@popperjs/core": {
+ "version": "2.10.2",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
+ "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ=="
+ },
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
"dev": true
},
"bootstrap": {
- "version": "4.6.1",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz",
- "integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og=="
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0.tgz",
+ "integrity": "sha512-tmhPET9B9qCl8dCofvHeiIhi49iBt0EehmIsziZib65k1erBW1rHhj2s/2JsuQh5Pq+xz2E9bEbzp9B7xHG+VA=="
},
"brace-expansion": {
"version": "1.1.11",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
+ "esbuild-android-arm64": {
+ "version": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.11.tgz",
+ "integrity": "sha512-/hDubOg7BHOhUUsT8KUIU7GfZm5bihqssvqK5PfO4apag7YuObZRZSzViyEKcFn2tPeHx7RKbSBXvAopSHDZJQ=="
+ },
+ "esbuild-darwin-64": {
+ "version": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.11.tgz",
+ "integrity": "sha512-1DqHD0ms3AhiwkKnjRUzmiW7JnaJJr5FKrPiR7xuyMwnjDqvNWDdMq4rKSD9OC0piFNK6n0LghsglNMe2MwJtA=="
+ },
+ "esbuild-darwin-arm64": {
+ "version": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.11.tgz",
+ "integrity": "sha512-OMzhxSbS0lwwrW40HHjRCeVIJTURdXFA8c3GU30MlHKuPCcvWNUIKVucVBtNpJySXmbkQMDJdJNrXzNDyvoqvQ=="
+ },
+ "esbuild-freebsd-64": {
+ "version": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.11.tgz",
+ "integrity": "sha512-8dKP26r0/Qyez8nTCwpq60QbuYKOeBygdgOAWGCRalunyeqWRoSZj9TQjPDnTTI9joxd3QYw3UhVZTKxO9QdRg=="
+ },
+ "esbuild-freebsd-arm64": {
+ "version": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.11.tgz",
+ "integrity": "sha512-aSGiODiukLGGnSg/O9+cGO2QxEacrdCtCawehkWYTt5VX1ni2b9KoxpHCT9h9Y6wGqNHmXFnB47RRJ8BIqZgmQ=="
+ },
+ "esbuild-linux-32": {
+ "version": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.11.tgz",
+ "integrity": "sha512-lsrAfdyJBGx+6aHIQmgqUonEzKYeBnyfJPkT6N2dOf1RoXYYV1BkWB6G02tjsrz1d5wZzaTc3cF+TKmuTo/ZwA=="
+ },
+ "esbuild-linux-arm": {
+ "version": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.11.tgz",
+ "integrity": "sha512-TJllTVk5aSyqPFvvcHTvf6Wu1ZKhWpJ/qNmZO8LL/XeB+LXCclm7HQHNEIz6MT7IX8PmlC1BZYrOiw2sXSB95A=="
+ },
+ "esbuild-linux-arm64": {
+ "version": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.11.tgz",
+ "integrity": "sha512-uhcXiTwTmD4OpxJu3xC5TzAAw6Wzf9O1XGWL448EE9bqGjgV1j+oK3lIHAfsHnuIn8K4nDW8yjX0Sv5S++oRuw=="
+ },
+ "esbuild-linux-mips64le": {
+ "version": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.11.tgz",
+ "integrity": "sha512-WD61y/R1M4BLe4gxXRypoQ0Ci+Vjf714QYzcPNkiYv5I8K8WDz2ZR8Bm6cqKxd6rD+e/rZgPDbhQ9PCf7TMHmA=="
+ },
+ "esbuild-linux-ppc64le": {
+ "version": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.11.tgz",
+ "integrity": "sha512-JVleZS9oPVLTlBhPTWgOwxFWU/wMUdlBwTbGA4GF8c38sLbS13cupj+C8bLq929jU7EMWry4SaL+tKGIaTlqKg=="
+ },
+ "esbuild-linux-riscv64": {
+ "version": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.11.tgz",
+ "integrity": "sha512-9aLIalZ2HFHIOZpmVU11sEAS9F8TnHw49daEjcgMpBXHFF57VuT9f9/9LKJhw781Gda0P9jDkuCWJ0tFbErvJw=="
+ },
+ "esbuild-linux-s390x": {
+ "version": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.11.tgz",
+ "integrity": "sha512-sZHtiXXOKsLI3XGBGoYO4qKBzJlb8xNsWmvFiwFMHFzA4AXgDP1KDp7Dawe9C2pavTRBDvl+Ok4n/DHQ59oaTg=="
+ },
+ "esbuild-netbsd-64": {
+ "version": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.11.tgz",
+ "integrity": "sha512-hUC9yN06K9sg7ju4Vgu9ChAPdsEgtcrcLfyNT5IKwKyfpLvKUwCMZSdF+gRD3WpyZelgTQfJ+pDx5XFbXTlB0A=="
+ },
+ "esbuild-openbsd-64": {
+ "version": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.11.tgz",
+ "integrity": "sha512-0bBo9SQR4t66Wd91LGMAqmWorzO0TTzVjYiifwoFtel8luFeXuPThQnEm5ztN4g0fnvcp7AnUPPzS/Depf17wQ=="
+ },
+ "esbuild-sunos-64": {
+ "version": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.11.tgz",
+ "integrity": "sha512-EuBdTGlsMTjEl1sQnBX2jfygy7iR6CKfvOzi+gEOfhDqbHXsmY1dcpbVtcwHAg9/2yUZSfMJHMAgf1z8M4yyyw=="
+ },
+ "esbuild-windows-32": {
+ "version": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.11.tgz",
+ "integrity": "sha512-O0/Wo1Wk6dc0rZSxkvGpmTNIycEznHmkObTFz2VHBhjPsO4ZpCgfGxNkCpz4AdAIeMczpTXt/8d5vdJNKEGC+Q=="
+ },
+ "esbuild-windows-64": {
+ "version": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.11.tgz",
+ "integrity": "sha512-x977Q4HhNjnHx00b4XLAnTtj5vfbdEvkxaQwC1Zh5AN8g5EX+izgZ6e5QgqJgpzyRNJqh4hkgIJF1pyy1be0mQ=="
+ },
+ "esbuild-windows-arm64": {
+ "version": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.11.tgz",
+ "integrity": "sha512-VwUHFACuBahrvntdcMKZteUZ9HaYrBRODoKe4tIWxguQRvvYoYb7iu5LrcRS/FQx8KPZNaa72zuqwVtHeXsITw=="
+ },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"@angular/platform-browser-dynamic": "13.3.11",
"@angular/router": "13.3.11",
"@circlon/angular-tree-component": "10.0.0",
- "@ng-bootstrap/ng-bootstrap": "10.0.0",
+ "@ng-bootstrap/ng-bootstrap": "12.1.2",
+ "@popperjs/core": "2.10.2",
"@swimlane/ngx-datatable": "18.0.0",
"@types/file-saver": "2.0.1",
"async-mutex": "0.2.4",
- "bootstrap": "4.6.1",
+ "bootstrap": "5.0.0",
"chart.js": "2.9.4",
"detect-browser": "5.2.0",
"file-saver": "2.0.2",
},
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
+ },
+ "overrides": {
+ "autoprefixer": "10.4.5"
}
}
type="password"
autocomplete="new-password">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="password">
- </button>
- <cd-copy-2-clipboard-button source="password">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="password">
+ </button>
+ <cd-copy-2-clipboard-button source="password">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="discoveryForm.showError('password', formDir, 'required')"
type="password"
autocomplete="new-password">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="mutual_password">
- </button>
- <cd-copy-2-clipboard-button source="mutual_password">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="mutual_password">
+ </button>
+ <cd-copy-2-clipboard-button source="mutual_password">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="discoveryForm.showError('mutual_password', formDir, 'required')"
name="target_iqn"
formControlName="target_iqn"
cdTrim />
- <span class="input-group-append">
- <button class="btn btn-light"
- id="ecp-info-button"
- type="button"
- (click)="targetSettingsModal()">
- <i [ngClass]="[icons.deepCheck]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ id="ecp-info-button"
+ type="button"
+ (click)="targetSettingsModal()">
+ <i [ngClass]="[icons.deepCheck]"
+ aria-hidden="true"></i>
+ </button>
</div>
<span class="invalid-feedback"
type="text"
[value]="portal"
disabled />
- <span class="input-group-append">
- <button class="btn btn-light"
- type="button"
- (click)="removePortal(i, portal)">
- <i [ngClass]="[icons.destroy]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ type="button"
+ (click)="removePortal(i, portal)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
</div>
</ng-container>
[options]="portalsSelections"
[messages]="messages.portals"
(selection)="onPortalSelection($event)"
- elemClass="btn btn-light float-right">
+ elemClass="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add portal</ng-container>
</cd-select>
type="text"
[value]="image"
disabled />
- <span class="input-group-append">
- <div class="input-group-text"
- *ngIf="api_version >= 1">lun: {{ imagesSettings[image]['lun'] }}</div>
- <button class="btn btn-light"
- type="button"
- (click)="imageSettingsModal(image)">
- <i [ngClass]="[icons.deepCheck]"
- aria-hidden="true"></i>
- </button>
- <button class="btn btn-light"
- type="button"
- (click)="removeImage(i, image)">
- <i [ngClass]="[icons.destroy]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <div class="input-group-text"
+ *ngIf="api_version >= 1">lun: {{ imagesSettings[image]['lun'] }}</div>
+ <button class="btn btn-light"
+ type="button"
+ (click)="imageSettingsModal(image)">
+ <i [ngClass]="[icons.deepCheck]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeImage(i, image)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
</div>
[options]="imagesSelections"
[messages]="messages.images"
(selection)="onImageSelection($event)"
- elemClass="btn btn-light float-right">
+ elemClass="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add image</ng-container>
</cd-select>
id="target_password"
name="target_password"
formControlName="password" />
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="target_password">
- </button>
- <cd-copy-2-clipboard-button source="target_password">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="target_password">
+ </button>
+ <cd-copy-2-clipboard-button source="target_password">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
name="target_mutual_password"
formControlName="mutual_password" />
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="target_mutual_password">
- </button>
- <cd-copy-2-clipboard-button source="target_mutual_password">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="target_mutual_password">
+ </button>
+ <cd-copy-2-clipboard-button source="target_mutual_password">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
<div class="card-header">
<ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }}
<button type="button"
- class="close"
+ class="btn-close float-end"
(click)="removeInitiator(ii)">
- <i [ngClass]="[icons.destroy]"></i>
</button>
</div>
<div class="card-body">
autocomplete="new-password"
type="password">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- [cdPasswordButton]="'password' + ii">
- </button>
- <cd-copy-2-clipboard-button [source]="'password' + ii">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ [cdPasswordButton]="'password' + ii">
+ </button>
+ <cd-copy-2-clipboard-button [source]="'password' + ii">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="initiator.showError('password', formDir, 'required')"
autocomplete="new-password"
type="password">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- [cdPasswordButton]="'mutual_password' + ii">
- </button>
- <cd-copy-2-clipboard-button [source]="'mutual_password' + ii">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ [cdPasswordButton]="'mutual_password' + ii">
+ </button>
+ <cd-copy-2-clipboard-button [source]="'mutual_password' + ii">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="initiator.showError('mutual_password', formDir, 'required')"
type="text"
[value]="image"
disabled />
- <span class="input-group-append">
- <button class="btn btn-light"
- type="button"
- (click)="removeInitiatorImage(initiator, li, ii, image)">
- <i [ngClass]="[icons.destroy]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeInitiatorImage(initiator, li, ii, image)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
</div>
</ng-container>
<cd-select [data]="initiator.getValue('luns')"
[options]="imagesInitiatorSelections[ii]"
[messages]="messages.initiatorImage"
- elemClass="btn btn-light float-right">
+ elemClass="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add image</ng-container>
</cd-select>
i18n>No items added.</span>
<button (click)="addInitiator(); false"
- class="btn btn-light float-right">
+ class="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add initiator</ng-container>
</button>
<div class="card-header">
<ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }}
<button type="button"
- class="close"
+ class="btn-close float-end"
(click)="removeGroup(gi)">
- <i [ngClass]="[icons.destroy]"></i>
</button>
</div>
<div class="card-body">
type="text"
[value]="member"
disabled />
- <span class="input-group-append">
- <button class="btn btn-light"
- type="button"
- (click)="removeGroupInitiator(group, i, gi)">
- <i [ngClass]="[icons.destroy]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeGroupInitiator(group, i, gi)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
</div>
</ng-container>
[options]="groupMembersSelections[gi]"
[messages]="messages.groupInitiator"
(selection)="onGroupMemberSelection($event, gi)"
- elemClass="btn btn-light float-right">
+ elemClass="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add initiator</ng-container>
</cd-select>
type="text"
[value]="disk"
disabled />
- <span class="input-group-append">
- <button class="btn btn-light"
- type="button"
- (click)="removeGroupDisk(group, i, gi)">
- <i [ngClass]="[icons.destroy]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ type="button"
+ (click)="removeGroupDisk(group, i, gi)">
+ <i [ngClass]="[icons.destroy]"
+ aria-hidden="true"></i>
+ </button>
</div>
</ng-container>
<cd-select [data]="group.getValue('disks')"
[options]="groupDiskSelections[gi]"
[messages]="messages.initiatorImage"
- elemClass="btn btn-light float-right">
+ elemClass="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add image</ng-container>
</cd-select>
i18n>No items added.</span>
<button (click)="addGroup(); false"
- class="btn btn-light float-right">
+ class="btn btn-light float-end">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add group</ng-container>
</button>
i18n>Backstore</label>
<select id="backstore"
name="backstore"
- class="form-control"
+ class="form-select"
formControlName="backstore">
<option *ngFor="let bs of backstores"
[value]="bs">{{ bs | iscsiBackstore }}</option>
<cd-iscsi-tabs></cd-iscsi-tabs>
<legend i18n>Gateways</legend>
-<cd-table [data]="gateways"
- (fetchData)="refresh()"
- [columns]="gatewaysColumns">
-</cd-table>
+<div>
+ <cd-table [data]="gateways"
+ (fetchData)="refresh()"
+ [columns]="gatewaysColumns">
+ </cd-table>
+</div>
<legend i18n>Images</legend>
-<cd-table [data]="images"
- [columns]="imagesColumns">
-</cd-table>
+<div>
+ <cd-table [data]="images"
+ [columns]="imagesColumns">
+ </cd-table>
+</div>
<ng-template #iscsiSparklineTpl
let-row="row"
i18n>At least one pool is required.</span>
</div>
- <cd-submit-button class="mb-4 float-right"
+ <cd-submit-button class="mb-4 float-end"
i18n
[form]="createBootstrapForm"
(submitAction)="generate()">Generate</cd-submit-button>
readonly>
</textarea>
</div>
- <cd-copy-2-clipboard-button class="float-right"
+ <cd-copy-2-clipboard-button class="float-end"
source="token">
</cd-copy-2-clipboard-button>
</div>
-<div class="row">
- <div class="col-md-12">
- <form name="rbdmirroringForm"
- #formDir="ngForm"
- [formGroup]="rbdmirroringForm"
- novalidate>
-
- <div class="d-flex flex-row">
- <label class="col-form-label"
- for="siteName"
- i18n>Site Name</label>
+<form name="rbdmirroringForm"
+ #formDir="ngForm"
+ [formGroup]="rbdmirroringForm"
+ novalidate>
+ <div class="row mb-3">
+ <div class="col-md-auto">
+ <label class="col-form-label"
+ for="siteName"
+ i18n>Site Name</label></div>
- <div class="col-md-4 input-group mb-3 mr-auto">
- <input type="text"
- class="form-control"
- id="siteName"
- name="siteName"
- formControlName="siteName"
- [attr.disabled]="!editing ? true : null">
- <div class="input-group-append">
- <button class="btn btn-light"
- id="editSiteName"
- (click)="updateSiteName()"
- [attr.title]="editing ? 'Save' : 'Edit'">
- <i [ngClass]="icons.edit"
- *ngIf="!editing"></i>
- <i [ngClass]="icons.check"
- *ngIf="editing"></i>
- </button>
- <cd-copy-2-clipboard-button [source]="siteName"
- [byId]="false">
- </cd-copy-2-clipboard-button>
- </div>
- </div>
- <cd-table-actions class="table-actions"
- [permission]="permission"
- [selection]="selection"
- [tableActions]="tableActions">
- </cd-table-actions>
- </div>
- </form>
+ <div class="col-sm-4 d-flex">
+ <input type="text"
+ class="form-control"
+ id="siteName"
+ name="siteName"
+ formControlName="siteName"
+ [attr.disabled]="!editing ? true : null">
+ <button class="btn btn-light"
+ id="editSiteName"
+ (click)="updateSiteName()"
+ [attr.title]="editing ? 'Save' : 'Edit'">
+ <i [ngClass]="icons.edit"
+ *ngIf="!editing"></i>
+ <i [ngClass]="icons.check"
+ *ngIf="editing"></i>
+ </button>
+ <cd-copy-2-clipboard-button [source]="siteName"
+ [byId]="false">
+ </cd-copy-2-clipboard-button>
+ </div>
+ <div class="col">
+ <cd-table-actions class="table-actions float-end"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
+ </div>
</div>
-</div>
+</form>
<div class="row">
<div class="col-sm-6">
<legend i18n>Daemons</legend>
-
- <cd-mirroring-daemons>
- </cd-mirroring-daemons>
+ <div>
+ <cd-mirroring-daemons>
+ </cd-mirroring-daemons>
+ </div>
</div>
<div class="col-sm-6">
<legend i18n>Pools</legend>
- <cd-mirroring-pools>
- </cd-mirroring-pools>
+ <div>
+ <cd-mirroring-pools>
+ </cd-mirroring-pools>
+ </div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<legend i18n>Images</legend>
- <cd-mirroring-images>
- </cd-mirroring-images>
+ <div>
+ <cd-mirroring-images>
+ </cd-mirroring-images>
+ </div>
</div>
</div>
</label>
<select id="mirrorMode"
name="mirrorMode"
- class="form-control"
+ class="form-select"
formControlName="mirrorMode">
<option *ngFor="let mirrorMode of mirrorModes"
[value]="mirrorMode.id">{{ mirrorMode.name }}</option>
cdIops>
</ng-container>
</ng-container>
- <span class="input-group-append">
- <button class="btn btn-light"
- type="button"
- data-toggle="button"
- [ngClass]="{'active': isDisabled(option.name)}"
- title="Remove the local configuration value. The parent configuration value will be inherited and used instead."
- i18n-title
- (click)="reset(option.name)">
- <i [ngClass]="[icons.erase]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ type="button"
+ data-toggle="button"
+ [ngClass]="{'active': isDisabled(option.name)}"
+ title="Remove the local configuration value. The parent configuration value will be inherited and used instead."
+ i18n-title
+ (click)="reset(option.name)">
+ <i [ngClass]="[icons.erase]"
+ aria-hidden="true"></i>
+ </button>
</div>
<span i18n
class="invalid-feedback"
class="bold">Features</td>
<td>
<span *ngFor="let feature of selection.features_name">
- <span class="badge badge-dark mr-2">{{ feature }}</span>
+ <span class="badge badge-dark me-2">{{ feature }}</span>
</span>
</td>
</tr>
*ngIf="mode === 'editing' || !poolPermission.read">
<select id="pool"
name="pool"
- class="form-control"
+ class="form-select"
formControlName="pool"
*ngIf="mode !== 'editing' && poolPermission.read"
(change)="setPoolMirrorMode()">
*ngIf="mode === 'editing' || !poolPermission.read">
<select id="namespace"
name="namespace"
- class="form-control"
+ class="form-select"
formControlName="namespace"
*ngIf="mode !== 'editing' && poolPermission.read">
<option *ngIf="pools === null"
*ngIf="mode === 'editing' || !poolPermission.read">
<select id="dataPool"
name="dataPool"
- class="form-control"
+ class="form-select"
formControlName="dataPool"
(change)="onDataPoolChange($event.target.value)"
*ngIf="mode !== 'editing' && poolPermission.read">
</cd-helper>
</div>
<div *ngIf="mirroring">
- <div class="custom-control custom-radio ml-2"
+ <div class="custom-control custom-radio ms-2"
*ngFor="let option of mirroringOptions">
<input type="radio"
- class="custom-control-input"
+ class="form-check-input"
[id]="option"
[value]="option"
name="mirroringMode"
(change)="setExclusiveLock()"
formControlName="mirroringMode"
[attr.disabled]="(poolMirrorMode === 'pool' && option === 'snapshot') ? true : null">
- <label class="custom-control-label"
+ <label class="form-check-label"
[for]="option">{{ option | titlecase }}</label>
<cd-helper *ngIf="poolMirrorMode === 'pool' && option === 'snapshot'">
<span i18n>You need to enable <b>image mirror mode</b> in the selected pool. Please <a [routerLink]="['/block/mirroring', {outlets: {modal: ['edit', currentPoolName]}}]">click here to select a mode and enable it in this pool.</a></span>
<!-- Advanced -->
<div class="row">
<div class="col-sm-12">
- <a class="float-right margin-right-md"
+ <a class="float-end margin-right-md"
(click)="advancedEnabled = true; false"
*ngIf="!advancedEnabled"
href=""
<div class="cd-col-form-input">
<select id="obj_size"
name="obj_size"
- class="form-control"
+ class="form-select"
formControlName="obj_size">
<option *ngFor="let objectSize of objectSizes"
[value]="objectSize">{{ objectSize }}</option>
<div class="cd-col-form-input">
<select id="stripingUnit"
name="stripingUnit"
- class="form-control"
+ class="form-select"
formControlName="stripingUnit">
<option i18n
[ngValue]="null">-- Select stripe unit --</option>
*ngIf="!poolPermission.read">
<select id="pool"
name="pool"
- class="form-control"
+ class="form-select"
formControlName="pool"
*ngIf="poolPermission.read">
<option *ngIf="pools === null"
<div class="row">
- <div class="col-sm-4 pr-0">
+ <div class="col-sm-4 pe-0">
<div class="card">
<div class="card-header">
<button type="button"
<ng-container ngbNavItem="clients">
<a ngbNavLink>
<ng-container i18n>Clients</ng-container>
- <span class="badge badge-pill badge-tab ml-1">{{ clients.data.length }}</span>
+ <span class="badge badge-pill badge-tab ms-1">{{ clients.data.length }}</span>
</a>
<ng-template ngbNavContent>
<cd-cephfs-clients [id]="id"
<td>
<span *ngFor="let flag of selection.flags">
<span title="{{ flags[flag] }}">
- <span class="badge badge-dark mr-2">{{ flag | uppercase }}</span>
+ <span class="badge badge-dark me-2">{{ flag | uppercase }}</span>
</span>
</span>
</td>
class="bold">Services</td>
<td>
<span *ngFor="let service of selection.services">
- <span class="badge badge-dark mr-2">{{ service }}</span>
+ <span class="badge badge-dark me-2">{{ service }}</span>
</span>
</td>
</tr>
<div class="cd-col-form-input">
<select id="pool"
name="pool"
- class="form-control"
+ class="form-select"
[formControlName]="section">
<option [ngValue]="null"
i18n>-- Default --</option>
<div class="m-4">
<h4 class="text-center"
i18n>Please expand your cluster first</h4>
- <div class="offset-md-2">
+ <div class="text-center">
<button class="btn btn-accent m-2"
name="expand-cluster"
(click)="createCluster()"
<div class="card-body vertical-line">
<ng-container [ngSwitch]="currentStep?.stepIndex">
<div *ngSwitchCase="'1'"
- class="ml-5">
+ class="ms-5">
<h4 class="title"
i18n>Add Hosts</h4>
<br>
[showGeneralActionsOnly]="true"></cd-hosts>
</div>
<div *ngSwitchCase="'2'"
- class="ml-5">
+ class="ms-5">
<h4 class="title"
i18n>Create OSDs</h4>
<div class="alignForm">
</div>
</div>
<div *ngSwitchCase="'3'"
- class="ml-5">
+ class="ms-5">
<h4 class="title"
i18n>Create Services</h4>
<br>
[routedModal]="false"></cd-services>
</div>
<div *ngSwitchCase="'4'"
- class="ml-5">
+ class="ms-5">
<cd-create-cluster-review></cd-create-cluster-review>
</div>
</ng-container>
</div>
</div>
<div class="card-footer">
- <button class="btn btn-accent m-2 float-right"
+ <button class="btn btn-accent m-2 float-end"
(click)="onNextStep()"
aria-label="Next"
i18n>{{ showSubmitButtonLabel() }}</button>
- <cd-back-button class="m-2 float-right"
+ <cd-back-button class="m-2 float-end"
aria-label="Close"
(backAction)="onPreviousStep()"
[name]="showCancelButtonLabel()"></cd-back-button>
</div>
<ng-template #logFiltersTpl>
- <div class="form-inline">
- <div class="form-group">
+ <div class="row mb-3">
+ <div class="col-lg-10 d-flex">
+ <div class="col-sm-1 me-3">
<label for="logs-priority"
+ class="fw-bold"
i18n>Priority:</label>
<select id="logs-priority"
- class="form-control"
+ class="form-select"
[(ngModel)]="priority"
(ngModelChange)="filterLogs()">
<option *ngFor="let prio of priorities"
</select>
</div>
- <div class="form-group">
+ <div class="col-md-3 me-3">
<label for="logs-keyword"
+ class="fw-bold"
i18n>Keyword:</label>
<div class="input-group">
- <div class="input-group-prepend">
- <span class="input-group-text">
- <i [ngClass]="[icons.search]"></i>
- </span>
- </div>
+ <span class="input-group-text">
+ <i [ngClass]="[icons.search]"></i>
+ </span>
<input class="form-control"
id="logs-keyword"
[(ngModel)]="search"
(keyup)="filterLogs()">
- <div class="input-group-append">
- <button type="button"
- class="btn btn-light"
- (click)="clearSearchKey()"
- title="Clear">
- <i class="icon-prepend {{ icons.destroy }}"></i>
- </button>
- </div>
+ <button type="button"
+ class="btn btn-light"
+ (click)="clearSearchKey()"
+ title="Clear">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
</div>
</div>
- <div class="form-group">
+ <div class="col-md-3 me-3">
<label for="logs-date"
+ class="fw-bold"
i18n>Date:</label>
<div class="input-group">
<input class="form-control"
(click)="d.open()"
[(ngModel)]="selectedDate"
(ngModelChange)="filterLogs()">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- (click)="clearDate()"
- title="Clear">
- <i class="icon-prepend {{ icons.destroy }}"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ (click)="clearDate()"
+ title="Clear">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
</div>
</div>
- <div class="form-group">
- <label i18n>Time range:</label>
+ <div class="col-md-5">
+ <label i18n
+ class="fw-bold">Time range:</label>
+ <div class="d-flex">
<ngb-timepicker [spinners]="false"
[(ngModel)]="startTime"
(ngModelChange)="filterLogs()"></ngb-timepicker>
- <span> — </span>
+ <span class="mt-2"> — </span>
<ngb-timepicker [spinners]="false"
[(ngModel)]="endTime"
(ngModelChange)="filterLogs()"></ngb-timepicker>
- </div>
- </div>
+ </div></div>
+ </div></div>
</ng-template>
<ng-template #noEntriesTpl>
formControlName="{{ moduleOption.value.name }}"
*ngIf="moduleOption.value.enum_allowed.length === 0">
<select id="{{ moduleOption.value.name }}"
- class="form-control"
+ class="form-select"
formControlName="{{ moduleOption.value.name }}"
*ngIf="moduleOption.value.enum_allowed.length > 0">
<option *ngFor="let value of moduleOption.value.enum_allowed"
i18n>Status</legend>
<table class="table table-striped"
*ngIf="mon_status">
- <tr>
- <td i18n
- class="bold">Cluster ID</td>
- <td>{{ mon_status.monmap.fsid }}</td>
- </tr>
- <tr>
- <td i18n
- class="bold">monmap modified</td>
- <td>{{ mon_status.monmap.modified | relativeDate }}</td>
- </tr>
- <tr>
- <td i18n
- class="bold">monmap epoch</td>
- <td>{{ mon_status.monmap.epoch }}</td>
- </tr>
- <tr>
- <td i18n
- class="bold">quorum con</td>
- <td>{{ mon_status.features.quorum_con }}</td>
- </tr>
- <tr>
- <td i18n
- class="bold">quorum mon</td>
- <td>{{ mon_status.features.quorum_mon }}</td>
- </tr>
- <tr>
- <td i18n
- class="bold">required con</td>
- <td>{{ mon_status.features.required_con }}</td>
- </tr>
- <tr>
- <td i18n
- class="bold">required mon</td>
- <td>{{ mon_status.features.required_mon }}</td>
- </tr>
+ <tbody>
+ <tr>
+ <td i18n
+ class="bold">Cluster ID</td>
+ <td>{{ mon_status.monmap.fsid }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">monmap modified</td>
+ <td>{{ mon_status.monmap.modified | relativeDate }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">monmap epoch</td>
+ <td>{{ mon_status.monmap.epoch }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">quorum con</td>
+ <td>{{ mon_status.features.quorum_con }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">quorum mon</td>
+ <td>{{ mon_status.features.quorum_mon }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">required con</td>
+ <td>{{ mon_status.features.required_con }}</td>
+ </tr>
+ <tr>
+ <td i18n
+ class="bold">required mon</td>
+ <td>{{ mon_status.features.required_mon }}</td>
+ </tr>
+ </tbody>
</table>
</fieldset>
</div>
<div class="col-lg-8">
<legend i18n
class="in-quorum cd-header">In Quorum</legend>
+ <div>
<cd-table [data]="inQuorum.data"
[columns]="inQuorum.columns">
- </cd-table>
+ </cd-table></div>
<legend i18n
class="in-quorum cd-header">Not In Quorum</legend>
+ <div>
<cd-table [data]="notInQuorum.data"
(fetchData)="refresh()"
[columns]="notInQuorum.columns">
- </cd-table>
+ </cd-table></div>
</div>
</div>
<ng-template #blockClearDevices>
<div class="pb-2 my-2 border-bottom">
<span *ngFor="let filter of appliedFilters">
- <span class="badge badge-dark mr-2">{{ filter.name }}: {{ filter.value.formatted }}</span>
+ <span class="badge badge-dark me-2">{{ filter.name }}: {{ filter.value.formatted }}</span>
</span>
<a class="tc_clearSelections"
href=""
</cd-inventory-devices>
</div>
<div *ngIf="type === 'data'"
- class="float-right">
+ class="float-end">
<span i18n>Raw capacity: {{ capacity | dimlessBinary }}</span>
</div>
</ng-template>
[showTitle]="false">
<ng-container i18n>At least one of these filters must be applied in order to proceed:</ng-container>
<span *ngFor="let filter of requiredFilters"
- class="badge badge-dark ml-2">
+ class="badge badge-dark ms-2">
{{ filter }}
</span>
</cd-alert-panel>
[for]="flag.code"
ng-class="['tc_' + key]">
<strong>{{ flag.name }}</strong>
- <span class="badge badge-hdd ml-2"
+ <span class="badge badge-hdd ms-2"
[ngbTooltip]="clusterWideTooltip"
*ngIf="flag.clusterWide"
i18n>Cluster-wide</span>
<div i18n="form title|Example: Create Pool@@formTitle"
class="card-header"
*ngIf="!hideTitle">{{ action | titlecase }} {{ resource | upperFirst }}</div>
- <div class="card-body ml-2">
+ <div class="card-body ms-2">
<form name="form"
#formDir="ngForm"
[formGroup]="form"
novalidate>
<div class="accordion">
- <div class="card">
- <div class="card-header">
- <h2 class="mb-0">
- <button class="btn btn-link btn-block text-left dropdown-toggle"
- data-toggle="collapse"
- aria-label="toggle deployment options"
- [attr.aria-expanded]="simpleDeployment"
- (click)="emitDeploymentMode()"
- i18n>Deployment Options</button>
- </h2>
- </div>
+ <div class="accordion-item">
+ <h2 class="accordion-header">
+ <button class="accordion-button"
+ type="button"
+ data-toggle="collapse"
+ aria-label="toggle deployment options"
+ [ngClass]="{collapsed: !simpleDeployment}"
+ (click)="emitDeploymentMode()"
+ i18n>Deployment Options</button>
+ </h2>
</div>
- <div class="collapse"
+ <div class="accordion-collapse collapse"
[ngClass]="{show: simpleDeployment}">
- <div class="card-body d-flex flex-column">
+ <div class="accordion-body">
<div class="pt-3 pb-3"
*ngFor="let optionName of optionNames">
- <div class="custom-control custom-radio custom-control-inline">
- <input class="custom-control-input"
+ <div class="custom-control form-check custom-control-inline">
+ <input class="form-check-input"
type="radio"
name="deploymentOption"
[id]="optionName"
formControlName="deploymentOption"
(change)="emitDeploymentSelection()"
[attr.disabled]="!deploymentOptions?.options[optionName].available ? true : null">
- <label class="custom-control-label"
+ <label class="form-check-label"
[id]="'label_' + optionName"
[for]="optionName"
i18n>{{ deploymentOptions?.options[optionName].title }}
</div> -->
</div>
</div>
- <div class="card">
- <div class="card-header">
- <h2 class="mb-0">
- <button class="btn btn-link btn-block text-left dropdown-toggle"
- data-toggle="collapse"
- aria-label="toggle advanced mode"
- [attr.aria-expanded]="!simpleDeployment"
- (click)="emitDeploymentMode()"
- i18n>Advanced Mode</button>
- </h2>
- </div>
+ <div class="accordion-item">
+ <h2 class="accordion-header">
+ <button class="accordion-button"
+ type="button"
+ aria-label="toggle advanced mode"
+ [ngClass]="{collapsed: simpleDeployment}"
+ (click)="emitDeploymentMode()"
+ i18n>Advanced Mode</button>
+ </h2>
</div>
- <div class="collapse"
+ <div class="accordion-collapse collapse"
[ngClass]="{show: !simpleDeployment}">
- <div class="card-body">
+ <div class="accordion-body">
<div class="card-body">
<fieldset>
<cd-osd-devices-selection-groups #dataDeviceSelectionGroups
</div>
<!-- Features -->
- <div class="card">
- <div class="card-header">
- <h2 class="mb-0">
- <button class="btn btn-link btn-block text-left dropdown-toggle"
- data-toggle="collapse"
- aria-label="features"
- aria-expanded="true"
- i18n>Features</button>
- </h2>
- </div>
+ <div class="accordion-item">
+ <h2 class="accordion-header">
+ <button class="accordion-button"
+ type="button"
+ data-toggle="collapse"
+ aria-label="features"
+ aria-expanded="true"
+ i18n>Features</button>
+ </h2>
</div>
- <div class="collapse show">
- <div class="card-body d-flex flex-column">
+ <div class="accordion-collapse collapse show">
+ <div class="accordion-body">
<div class="pt-3 pb-3"
formGroupName="features">
<div class="custom-control custom-checkbox"
{{ actionDescription }}!
</span>
<br>
- <ul class="mb-0 pl-4">
+ <ul class="mb-0 ps-4">
<li *ngIf="active.length > 0"
i18n>
{selection.hasSingleSelection, select, true {} other {{{ active | join }} : }}
<ng-template #flagsTpl
let-row="row">
<span *ngFor="let flag of row.cdClusterFlags;"
- class="badge badge-hdd mr-1">{{ flag }}</span>
+ class="badge badge-hdd me-1">{{ flag }}</span>
<span *ngFor="let flag of row.cdIndivFlags;"
- class="badge badge-info mr-1">{{ flag }}</span>
+ class="badge badge-info me-1">{{ flag }}</span>
</ng-template>
<ng-template #osdUsageTpl
for="priority"
i18n>Priority</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="priority"
id="priority"
(change)="onPriorityChange($event.target.value)">
{
name: $localize`Name`,
prop: 'labels.alertname',
- cellClass: 'font-weight-bold',
+ cellClass: 'fw-bold',
flexGrow: 2
},
{
[routerLinkActiveOptions]="{exact: true}"
i18n>Active Alerts
<small *ngIf="prometheusAlertService.activeCriticalAlerts > 0"
- class="badge badge-danger ml-1">{{ prometheusAlertService.activeCriticalAlerts }}</small>
+ class="badge badge-danger ms-1">{{ prometheusAlertService.activeCriticalAlerts }}</small>
<small *ngIf="prometheusAlertService.activeWarningAlerts > 0"
- class="badge badge-warning ml-1">{{ prometheusAlertService.activeWarningAlerts }}</small></a>
+ class="badge badge-warning ms-1">{{ prometheusAlertService.activeWarningAlerts }}</small></a>
</li>
<li class="nav-item">
<a class="nav-link"
ngOnInit() {
super.ngOnInit();
this.columns = [
- { prop: 'name', name: $localize`Name`, cellClass: 'font-weight-bold', flexGrow: 2 },
+ { prop: 'name', name: $localize`Name`, cellClass: 'fw-bold', flexGrow: 2 },
{
prop: 'labels.severity',
name: $localize`Severity`,
let-index="index">
<div class="input-group my-2">
<ng-container *ngFor="let config of matcherConfig">
- <div class="input-group-prepend">
- <span class="input-group-text"
- *ngIf="config.attribute === 'isRegex'"
- [ngbTooltip]="config.tooltip">
- <i *ngIf="matcher[config.attribute]">~</i>
- <i *ngIf="!matcher[config.attribute]">=</i>
- </span>
- </div>
+ <span class="input-group-text"
+ *ngIf="config.attribute === 'isRegex'"
+ [ngbTooltip]="config.tooltip">
+ <i *ngIf="matcher[config.attribute]">~</i>
+ <i *ngIf="!matcher[config.attribute]">=</i>
+ </span>
<ng-container *ngIf="config.attribute !== 'isRegex'">
<input type="text"
</ng-container>
<!-- Matcher actions -->
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- id="matcher-edit-{{index}}"
- i18n-ngbTooltip
- ngbTooltip="Edit"
- (click)="showMatcherModal(index)">
- <i [ngClass]="[icons.edit]"></i>
- </button>
- <button type="button"
- class="btn btn-light"
- id="matcher-delete-{{index}}"
- i18n-ngbTooltip
- ngbTooltip="Delete"
- (click)="deleteMatcher(index)">
- <i [ngClass]="[icons.trash]"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ id="matcher-edit-{{index}}"
+ i18n-ngbTooltip
+ ngbTooltip="Edit"
+ (click)="showMatcherModal(index)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light"
+ id="matcher-delete-{{index}}"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteMatcher(index)">
+ <i [ngClass]="[icons.trash]"></i>
+ </button>
</div>
<span class="help-block"></span>
</ng-template>
<div class="col-12">
<button type="button"
id="add-matcher"
- class="btn btn-light float-right my-3"
+ class="btn btn-light float-end my-3"
[ngClass]="{'btn-warning': formDir.submitted && matchers.length === 0 }"
(click)="showMatcherModal()">
<i [ngClass]="[icons.add]"></i>
for="name"
i18n>Name</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="name"
formControlName="name"
name="name">
<input id="value"
(focus)="valueFocus.next($any($event).target.value)"
(click)="valueClick.next($any($event).target.value)"
- container="body"
class="form-control"
type="text"
[ngbTypeahead]="search"
- formControlName="value">
+ formControlName="value"
+ #instance="ngbTypeahead">
<span *ngIf="form.showError('value', formDir, 'required')"
class="help-block"
i18n>This field is required!</span>
<div class="cd-col-form-input">
<select id="service_type"
name="service_type"
- class="form-control"
+ class="form-select"
formControlName="service_type"
(change)="getServiceIds($event.target.value)">
<option i18n
<div class="cd-col-form-input">
<select id="backend_service"
name="backend_service"
- class="form-control"
+ class="form-select"
formControlName="backend_service"
(change)="prePopulateId()">
<option *ngIf="services === null"
i18n>Placement</label>
<div class="cd-col-form-input">
<select id="placement"
- class="form-control"
+ class="form-select"
formControlName="placement">
<option i18n
value="hosts">Hosts</option>
<div class="cd-col-form-input">
<select id="pool"
name="pool"
- class="form-control"
+ class="form-select"
formControlName="pool">
<option *ngIf="pools === null"
[ngValue]="null"
type="password"
autocomplete="new-password"
formControlName="api_password">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="api_password">
- </button>
- <cd-copy-2-clipboard-button source="api_password">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="api_password">
+ </button>
+ <cd-copy-2-clipboard-button source="api_password">
+ </cd-copy-2-clipboard-button>
<span class="invalid-feedback"
*ngIf="serviceForm.showError('api_password', frm, 'required')"
i18n>This field is required.</span>
<div class="cd-col-form-input">
<select id="snmp_version"
name="snmp_version"
- class="form-control"
+ class="form-select"
formControlName="snmp_version"
(change)="clearValidations()">
<option i18n
<div class="cd-col-form-input">
<select id="auth_protocol"
name="auth_protocol"
- class="form-control"
+ class="form-select"
formControlName="auth_protocol">
<option i18n
[ngValue]="null">-- Select auth protocol --</option>
<div class="cd-col-form-input">
<select id="privacy_protocol"
name="privacy_protocol"
- class="form-control"
+ class="form-select"
formControlName="privacy_protocol">
<option i18n
[ngValue]="null">-- Select privacy protocol --</option>
<div class="row">
- <div class="info-group-title"
- [ngbPopover]="popInfoTemplate"
- #popInfo="ngbPopover"
- triggers="">
+ <div class="info-group-title">
<span>{{ groupTitle }}</span>
- <button type="button"
- class="popover-icon btn btn-link p-0"
- (click)="popInfo.toggle()"
- aria-label="learn more"
- i18n-aria-label>
- <i [ngClass]="[icons.infoCircle, icons.large]"></i>
- </button>
+ <cd-helper iconClass="fa fa-info-circle fa-2xs">
+ <div class="text-center"
+ i18n>For an overview of {{ groupTitle|lowercase }} widgets click
+ <cd-doc section="dashboard-landing-page-{{ groupTitle|lowercase }}"
+ docText="here"
+ i18n-docText></cd-doc>
+ </div>
+ </cd-helper>
</div>
</div>
<div class="row">
<ng-content></ng-content>
</div>
-
-<ng-template #popInfoTemplate>
- <div class="text-center"
- i18n>For an overview of {{ groupTitle|lowercase }} widgets click
- <cd-doc section="dashboard-landing-page-{{ groupTitle|lowercase }}"
- docText="here"
- i18n-docText></cd-doc>
- </div>
-</ng-template>
.info-group-title {
font-size: 1.75rem;
- margin: 0 0 0.5vw 0.5vw;
+ margin: 0 0 0.5vw;
}
.popover-icon {
[formGroup]="item">
<div class="card-header">
{{ (index + 1) | ordinal }}
- <span class="float-right clickable"
+ <span class="float-end clickable"
name="remove_client"
(click)="removeClient(index)"
ngbTooltip="Remove">×</span>
class="cd-col-form-label"
for="access_type">Access Type</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
name="access_type"
id="access_type"
formControlName="access_type">
<ng-container *ngTemplateOutlet="squashHelperTpl"></ng-container>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
name="squash"
id="squash"
formControlName="squash">
</div>
</ng-container>
- <div class="row">
+ <div class="row my-2">
<div class="col-12">
- <div class="float-right">
+ <div class="float-end">
<button class="btn btn-light "
(click)="addClient()"
name="add_client">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="cluster_id"
name="cluster_id"
id="cluster_id">
for="name"
i18n>Storage Backend</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="name"
name="name"
id="name"
for="fs_name"
i18n>Volume</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="fs_name"
name="fs_name"
id="fs_name"
for="access_type"
i18n>Access Type</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="access_type"
name="access_type"
id="access_type"
<ng-container *ngTemplateOutlet="squashHelper"></ng-container>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
name="squash"
formControlName="squash"
id="squash">
<span class="required"></span>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="root"
name="root"
formControlName="root">
<span class="required"></span>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="failure_domain"
name="failure_domain"
formControlName="failure_domain">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="device_class"
name="device_class"
formControlName="device_class">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="plugin"
name="plugin"
formControlName="plugin">
class="form-control"
placeholder="Helper chunks..."
formControlName="d">
- <span class="input-group-append">
- <button class="btn btn-light"
- id="d-calc-btn"
- ngbTooltip="Set d manually or use the plugin's default calculation that maximizes d."
- i18n-ngbTooltip
- type="button"
- (click)="toggleDCalc()">
- <i [ngClass]="dCalc ? icons.unlock : icons.lock"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ id="d-calc-btn"
+ ngbTooltip="Set d manually or use the plugin's default calculation that maximizes d."
+ i18n-ngbTooltip
+ type="button"
+ (click)="toggleDCalc()">
+ <i [ngClass]="dCalc ? icons.unlock : icons.lock"
+ aria-hidden="true"></i>
+ </button>
</div>
<span class="form-text text-muted"
*ngIf="dCalc"
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="crushFailureDomain"
name="crushFailureDomain"
formControlName="crushFailureDomain">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="crushLocality"
name="crushLocality"
formControlName="crushLocality">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="scalar_mds"
name="scalar_mds"
formControlName="scalar_mds">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="technique"
name="technique"
formControlName="technique">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="crushRoot"
name="crushRoot"
formControlName="crushRoot">
</cd-helper>
</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="crushDeviceClass"
name="crushDeviceClass"
formControlName="crushDeviceClass">
for="poolType"
i18n>Pool type</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="poolType"
formControlName="poolType"
name="poolType">
class="cd-col-form-label"
for="pgAutoscaleMode">PG Autoscale</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="pgAutoscaleMode"
name="pgAutoscaleMode"
formControlName="pgAutoscaleMode">
class="cd-col-form-label"
for="erasureProfile">Erasure code profile</label>
<div class="cd-col-form-input">
- <div class="input-group">
- <select class="form-control"
+ <div class="input-group mb-1">
+ <select class="form-select"
id="erasureProfile"
name="erasureProfile"
formControlName="erasureProfile">
{{ ecp.name }}
</option>
</select>
- <span class="input-group-append">
- <button class="btn btn-light"
- [ngClass]="{'active': data.erasureInfo}"
- id="ecp-info-button"
- type="button"
- (click)="data.erasureInfo = !data.erasureInfo">
- <i [ngClass]="[icons.questionCircle]"
- aria-hidden="true"></i>
- </button>
- <button class="btn btn-light"
- type="button"
- *ngIf="!editing"
- (click)="addErasureCodeProfile()">
- <i [ngClass]="[icons.add]"
- aria-hidden="true"></i>
- </button>
- <button class="btn btn-light"
- type="button"
- *ngIf="!editing"
- ngbTooltip="This profile can't be deleted as it is in use."
- i18n-ngbTooltip
- triggers="manual"
- #ecpDeletionBtn="ngbTooltip"
- (click)="deleteErasureCodeProfile()">
- <i [ngClass]="[icons.trash]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ [ngClass]="{'active': data.erasureInfo}"
+ id="ecp-info-button"
+ type="button"
+ (click)="data.erasureInfo = !data.erasureInfo">
+ <i [ngClass]="[icons.questionCircle]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ *ngIf="!editing"
+ (click)="addErasureCodeProfile()">
+ <i [ngClass]="[icons.add]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ *ngIf="!editing"
+ ngbTooltip="This profile can't be deleted as it is in use."
+ i18n-ngbTooltip
+ triggers="manual"
+ #ecpDeletionBtn="ngbTooltip"
+ (click)="deleteErasureCodeProfile()">
+ <i [ngClass]="[icons.trash]"
+ aria-hidden="true"></i>
+ </button>
</div>
<span class="form-text text-muted"
id="ecp-info-block"
</ng-template>
<div *ngIf="current.rules.length > 0; else noRules">
<div class="input-group">
- <select class="form-control"
+ <select class="form-select"
id="crushRule"
formControlName="crushRule"
name="crushSet">
{{ rule.rule_name }}
</option>
</select>
- <span class="input-group-append">
- <button class="btn btn-light"
- [ngClass]="{'active': data.crushInfo}"
- id="crush-info-button"
- type="button"
- ngbTooltip="Placement and
- replication strategies or distribution policies that allow to
- specify how CRUSH places data replicas."
- i18n-ngbTooltip
- (click)="data.crushInfo = !data.crushInfo">
- <i [ngClass]="[icons.questionCircle]"
- aria-hidden="true"></i>
- </button>
- <button class="btn btn-light"
- type="button"
- *ngIf="isReplicated && !editing"
- (click)="addCrushRule()">
- <i [ngClass]="[icons.add]"
- aria-hidden="true"></i>
- </button>
- <button class="btn btn-light"
- *ngIf="isReplicated && !editing"
- type="button"
- ngbTooltip="This rule can't be deleted as it is in use."
- i18n-ngbTooltip
- triggers="manual"
- #crushDeletionBtn="ngbTooltip"
- (click)="deleteCrushRule()">
- <i [ngClass]="[icons.trash]"
- aria-hidden="true"></i>
- </button>
- </span>
+ <button class="btn btn-light"
+ [ngClass]="{'active': data.crushInfo}"
+ id="crush-info-button"
+ type="button"
+ ngbTooltip="Placement and
+ replication strategies or distribution policies that allow to
+ specify how CRUSH places data replicas."
+ i18n-ngbTooltip
+ (click)="data.crushInfo = !data.crushInfo">
+ <i [ngClass]="[icons.questionCircle]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ type="button"
+ *ngIf="isReplicated && !editing"
+ (click)="addCrushRule()">
+ <i [ngClass]="[icons.add]"
+ aria-hidden="true"></i>
+ </button>
+ <button class="btn btn-light"
+ *ngIf="isReplicated && !editing"
+ type="button"
+ ngbTooltip="This rule can't be deleted as it is in use."
+ i18n-ngbTooltip
+ triggers="manual"
+ #crushDeletionBtn="ngbTooltip"
+ (click)="deleteCrushRule()">
+ <i [ngClass]="[icons.trash]"
+ aria-hidden="true"></i>
+ </button>
</div>
<div class="form-text text-muted"
class="cd-col-form-label"
for="mode">Mode</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="mode"
name="mode"
formControlName="mode">
class="cd-col-form-label"
for="algorithm">Algorithm</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
id="algorithm"
name="algorithm"
formControlName="algorithm">
<div class="cd-col-form-input">
<select id="owner"
name="owner"
- class="form-control"
+ class="form-select"
formControlName="owner"
[autofocus]="editing">
<option i18n
<select id="placement-target"
name="placement-target"
formControlName="placement-target"
- class="form-control">
+ class="form-select">
<option i18n
*ngIf="placementTargets === null"
[ngValue]="null">Loading...</option>
for="lock_mode"
i18n>Mode</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="lock_mode"
name="lock_mode"
id="lock_mode">
<div class="form-group row">
<div class="cd-col-form-offset">
<div class="custom-control custom-checkbox">
- <input class="custom-control-input"
+ <input class="form-check-input"
id="encryption_enabled"
name="encryption_enabled"
formControlName="encryption_enabled"
type="checkbox"
[attr.disabled]="!kmsVaultConfig && !s3VaultConfig ? true : null">
- <label class="custom-control-label"
+ <label class="form-check-label"
for="encryption_enabled"
i18n>Encryption</label>
<cd-helper>
<div *ngIf="bucketForm.getValue('encryption_enabled')">
<div class="form-group row">
<div class="cd-col-form-offset">
- <div class="custom-control custom-radio custom-control-inline pl-5">
- <input class="custom-control-input"
+ <div class="custom-control custom-radio custom-control-inline ps-5">
+ <input class="form-check-input"
formControlName="encryption_type"
id="sse_S3_enabled"
type="radio"
name="encryption_type"
value="AES256"
[attr.disabled]="!s3VaultConfig ? true : null">
- <label class="custom-control-label"
+ <label class="form-control-label"
for="sse_S3_enabled"
i18n>SSE-S3 Encryption</label>
</div>
<div class="form-group row">
<div class="cd-col-form-offset">
- <div class="custom-control custom-radio custom-control-inline pl-5">
- <input class="custom-control-input"
+ <div class="custom-control custom-radio custom-control-inline ps-5">
+ <input class="form-check-input"
formControlName="encryption_type"
id="kms_enabled"
name="encryption_type"
value="aws:kms"
[attr.disabled]="!kmsVaultConfig ? true : null"
type="radio">
- <label class="custom-control-label"
+ <label class="form-control-label"
for="kms_enabled"
i18n>Connect to an external key management service</label>
</div>
<div class="cd-col-form-input">
<select id="kms_provider"
name="kms_provider"
- class="form-control"
+ class="form-select"
formControlName="kms_provider"
[autofocus]="editing">
<option i18n
<div class="cd-col-form-input">
<select id="kms_provider"
name="kms_provider"
- class="form-control"
+ class="form-select"
formControlName="kms_provider">
<option i18n
*ngIf="kmsProviders !== null"
<div class="cd-col-form-input">
<select id="auth_method"
name="auth_method"
- class="form-control"
+ class="form-select"
formControlName="auth_method">
<option i18n
*ngIf="authMethods !== null"
<div class="cd-col-form-input">
<select id="secret_engine"
name="secret_engine"
- class="form-control"
+ class="form-select"
formControlName="secret_engine">
<option i18n
*ngIf="secretEngines !== null"
[readonly]="true"
formControlName="type">
<select id="type"
- class="form-control"
+ class="form-select"
formControlName="type"
*ngIf="!editing"
autofocus>
i18n>Permission</label>
<div class="cd-col-form-input">
<select id="perm"
- class="form-control"
+ class="form-select"
formControlName="perm">
<option i18n
[ngValue]="null">-- Select a permission --</option>
for="max_buckets_mode"
i18n>Max. buckets</label>
<div class="cd-col-form-input">
- <select class="form-control"
+ <select class="form-select"
formControlName="max_buckets_mode"
name="max_buckets_mode"
id="max_buckets_mode"
class="form-control"
type="password"
formControlName="access_key">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="access_key">
- </button>
- <cd-copy-2-clipboard-button source="access_key">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="access_key">
+ </button>
+ <cd-copy-2-clipboard-button source="access_key">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="userForm.showError('access_key', frm, 'required')"
class="form-control"
type="password"
formControlName="secret_key">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="secret_key">
- </button>
- <cd-copy-2-clipboard-button source="secret_key">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="userForm.showError('secret_key', frm, 'required')"
<span *ngFor="let subuser of subusers; let i=index;">
<div class="input-group">
- <div class="input-group-prepend">
- <span class="input-group-text">
- <i class="{{ icons.user }}"></i>
- </span>
- </div>
+ <span class="input-group-text">
+ <i class="{{ icons.user }}"></i>
+ </span>
<input type="text"
class="cd-form-control"
value="{{ subuser.id }}"
readonly>
- <div class="input-group-prepend border-left-0 border-right-0">
- <span class="input-group-text">
- <i class="{{ icons.share }}"></i>
- </span>
- </div>
+ <span class="input-group-text">
+ <i class="{{ icons.share }}"></i>
+ </span>
<input type="text"
class="cd-form-control"
value="{{ ('full-control' === subuser.permissions) ? 'full' : subuser.permissions }}"
readonly>
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light tc_showSubuserButton"
- i18n-ngbTooltip
- ngbTooltip="Edit"
- (click)="showSubuserModal(i)">
- <i [ngClass]="[icons.edit]"></i>
- </button>
- <button type="button"
- class="btn btn-light tc_deleteSubuserButton"
- i18n-ngbTooltip
- ngbTooltip="Delete"
- (click)="deleteSubuser(i)">
- <i [ngClass]="[icons.destroy]"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light tc_showSubuserButton"
+ i18n-ngbTooltip
+ ngbTooltip="Edit"
+ (click)="showSubuserModal(i)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteSubuserButton"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteSubuser(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
</div>
<span class="form-text text-muted"></span>
</span>
- <div class="row">
+ <div class="row my-2">
<div class="col-12">
<button type="button"
- class="btn btn-light float-right tc_addSubuserButton"
+ class="btn btn-light float-end tc_addSubuserButton"
(click)="showSubuserModal()">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>{{ actionLabels.CREATE | titlecase }}
<span *ngFor="let key of s3Keys; let i=index;">
<div class="input-group">
- <div class="input-group-prepend">
- <div class="input-group-text">
- <i class="{{ icons.key }}"></i>
- </div>
+ <div class="input-group-text">
+ <i class="{{ icons.key }}"></i>
</div>
<input type="text"
class="cd-form-control"
value="{{ key.user }}"
readonly>
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light tc_showS3KeyButton"
- i18n-ngbTooltip
- ngbTooltip="Show"
- (click)="showS3KeyModal(i)">
- <i [ngClass]="[icons.show]"></i>
- </button>
- <button type="button"
- class="btn btn-light tc_deleteS3KeyButton"
- i18n-ngbTooltip
- ngbTooltip="Delete"
- (click)="deleteS3Key(i)">
- <i [ngClass]="[icons.destroy]"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light tc_showS3KeyButton"
+ i18n-ngbTooltip
+ ngbTooltip="Show"
+ (click)="showS3KeyModal(i)">
+ <i [ngClass]="[icons.show]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteS3KeyButton"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteS3Key(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
</div>
<span class="form-text text-muted"></span>
</span>
- <div class="row">
+ <div class="row my-2">
<div class="col-12">
<button type="button"
- class="btn btn-light float-right tc_addS3KeyButton"
+ class="btn btn-light float-end tc_addS3KeyButton"
(click)="showS3KeyModal()">
<i [ngClass]="[icons.add]"></i>
<ng-container i18n>{{ actionLabels.CREATE | titlecase }}
<span *ngFor="let key of swiftKeys; let i=index;">
<div class="input-group">
- <div class="input-group-prepend">
- <span class="input-group-text">
- <i class="{{ icons.key }}"></i>
- </span>
- </div>
+ <span class="input-group-text">
+ <i class="{{ icons.key }}"></i>
+ </span>
<input type="text"
class="cd-form-control"
value="{{ key.user }}"
readonly>
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light tc_showSwiftKeyButton"
- i18n-ngbTooltip
- ngbTooltip="Show"
- (click)="showSwiftKeyModal(i)">
- <i [ngClass]="[icons.show]"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light tc_showSwiftKeyButton"
+ i18n-ngbTooltip
+ ngbTooltip="Show"
+ (click)="showSwiftKeyModal(i)">
+ <i [ngClass]="[icons.show]"></i>
+ </button>
</div>
<span class="form-text text-muted"></span>
</span>
<span *ngFor="let cap of capabilities; let i=index;">
<div class="input-group">
- <span class="input-group-prepend">
- <div class="input-group-text">
- <i class="{{ icons.share }}"></i>
- </div>
- </span>
+ <div class="input-group-text">
+ <i class="{{ icons.share }}"></i>
+ </div>
<input type="text"
class="cd-form-control"
value="{{ cap.type }}:{{ cap.perm }}"
readonly>
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light tc_editCapButton"
- i18n-ngbTooltip
- ngbTooltip="Edit"
- (click)="showCapabilityModal(i)">
- <i [ngClass]="[icons.edit]"></i>
- </button>
- <button type="button"
- class="btn btn-light tc_deleteCapButton"
- i18n-ngbTooltip
- ngbTooltip="Delete"
- (click)="deleteCapability(i)">
- <i [ngClass]="[icons.destroy]"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light tc_editCapButton"
+ i18n-ngbTooltip
+ ngbTooltip="Edit"
+ (click)="showCapabilityModal(i)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteCapButton"
+ i18n-ngbTooltip
+ ngbTooltip="Delete"
+ (click)="deleteCapability(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
</div>
<span class="form-text text-muted"></span>
</span>
- <div class="row">
+ <div class="row my-2">
<div class="col-12">
<button type="button"
- class="btn btn-light float-right tc_addCapButton"
+ class="btn btn-light float-end tc_addCapButton"
[disabled]="capabilities | pipeFunction:hasAllCapabilities"
i18n-ngbTooltip
ngbTooltip="All capabilities are already added."
type="password"
[readonly]="viewing"
formControlName="access_key">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="access_key">
- </button>
- <cd-copy-2-clipboard-button source="access_key">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="access_key">
+ </button>
+ <cd-copy-2-clipboard-button source="access_key">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="formGroup.showError('access_key', frm, 'required')"
type="password"
[readonly]="viewing"
formControlName="secret_key">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="secret_key">
- </button>
- <cd-copy-2-clipboard-button source="secret_key">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="formGroup.showError('secret_key', frm, 'required')"
i18n>Permission</label>
<div class="cd-col-form-input">
<select id="perm"
- class="form-control"
+ class="form-select"
formControlName="perm">
<option i18n
[ngValue]="null">-- Select a permission --</option>
class="form-control"
type="password"
formControlName="secret_key">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="secret_key">
- </button>
- <cd-copy-2-clipboard-button source="secret_key">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
</div>
<span class="invalid-feedback"
*ngIf="formGroup.showError('secret_key', frm, 'required')"
type="password"
[(ngModel)]="secret_key"
[readonly]="true">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="secret_key">
- </button>
- <cd-copy-2-clipboard-button source="secret_key">
- </cd-copy-2-clipboard-button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="secret_key">
+ </button>
+ <cd-copy-2-clipboard-button source="secret_key">
+ </cd-copy-2-clipboard-button>
</div>
</div>
</div>
<ng-template #readableDaemons
let-daemons="daemons">
<ng-container *ngFor="let daemon of daemons">
- <cd-label class="mr-1"
+ <cd-label class="me-1"
[value]="daemon"></cd-label>
</ng-container>
</ng-template>
i18n>Feedback module is not enabled. Please enable it from <a (click)="redirect()">Cluster-> Manager Modules.</a>
</cd-alert-panel>
<!-- api_key -->
- <div class="form-group row"
+ <div class="form-group row mt-3"
*ngIf="!isAPIKeySet">
<label class="cd-col-form-label required"
for="api_key"
formControlName="oldpassword"
autocomplete="new-password"
autofocus>
- <span class="input-group-append">
- <button class="btn btn-outline-light btn-password"
- cdPasswordButton="oldpassword">
- </button>
- </span>
+ <button class="btn btn-outline-light btn-password"
+ cdPasswordButton="oldpassword">
+ </button>
</div>
<span class="invalid-feedback"
*ngIf="userForm.showError('oldpassword', frm, 'required')"
id="newpassword"
autocomplete="new-password"
formControlName="newpassword">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-outline-light btn-password"
- cdPasswordButton="newpassword">
- </button>
- </span>
+ <button type="button"
+ class="btn btn-outline-light btn-password"
+ cdPasswordButton="newpassword">
+ </button>
</div>
<div class="password-strength-level">
<div class="{{ passwordStrengthLevelClass }}"
placeholder="Confirm new password..."
id="confirmnewpassword"
formControlName="confirmnewpassword">
- <span class="input-group-append">
- <button class="btn btn-outline-light btn-password"
- cdPasswordButton="confirmnewpassword">
- </button>
- </span>
+ <button class="btn btn-outline-light btn-password"
+ cdPasswordButton="confirmnewpassword">
+ </button>
</div>
<span class="invalid-feedback"
*ngIf="userForm.showError('confirmnewpassword', frm, 'required')"
<!-- Username -->
<div class="form-group has-feedback d-flex flex-column py-3">
- <label class="placeholder pl-4"
+ <label class="placeholder ps-3"
for="username"
i18n>Username</label>
<input id="username"
type="text"
[attr.aria-invalid]="username.invalid"
aria-labelledby="username"
- class="form-control pl-4"
+ class="form-control ps-3"
required
autofocus>
- <div class="invalid-feedback pl-4"
+ <div class="invalid-feedback ps-3"
*ngIf="(loginForm.submitted || username.dirty) && username.invalid"
i18n>Username is required</div>
</div>
id="password-div">
<div class="input-group d-flex flex-nowrap">
<div class="d-flex flex-column flex-grow-1 py-3">
- <label class="placeholder pl-4"
+ <label class="placeholder ps-3"
for="password"
i18n>Password</label>
<input id="password"
type="password"
[attr.aria-invalid]="password.invalid"
aria-labelledby="password"
- class="form-control pl-4"
+ class="form-control ps-3"
required>
- <div class="invalid-feedback pl-4"
+ <div class="invalid-feedback ps-3"
*ngIf="(loginForm.submitted || password.dirty) && password.invalid"
i18n>Password is required</div>
</div>
name="password"
autocomplete="new-password"
formControlName="password">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="password">
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="password">
+ </button>
</div>
<div class="password-strength-level">
<div class="{{ passwordStrengthLevelClass }}"
name="confirmpassword"
autocomplete="new-password"
formControlName="confirmpassword">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="confirmpassword">
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="confirmpassword">
+ </button>
<span class="invalid-feedback"
*ngIf="userForm.showError('confirmpassword', formDir, 'match')"
i18n>Password confirmation doesn't match the password.</span>
#p="ngbPopover"
(click)="p.open()"
(keypress)="p.close()">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- (click)="clearExpirationDate()">
- <i class="icon-prepend {{ icons.destroy }}"></i>
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ (click)="clearExpirationDate()">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
<span class="invalid-feedback"
*ngIf="userForm.showError('pwdExpirationDate', formDir, 'required')"
i18n>This field is required.</span>
formControlName="oldpassword"
autocomplete="new-password"
autofocus>
- <span class="input-group-append">
- <button class="btn btn-light"
- cdPasswordButton="oldpassword">
- </button>
- </span>
+ <button class="btn btn-light"
+ cdPasswordButton="oldpassword">
+ </button>
</div>
<span class="invalid-feedback"
*ngIf="userForm.showError('oldpassword', frm, 'required')"
id="newpassword"
autocomplete="new-password"
formControlName="newpassword">
- <span class="input-group-append">
- <button type="button"
- class="btn btn-light"
- cdPasswordButton="newpassword">
- </button>
- </span>
+ <button type="button"
+ class="btn btn-light"
+ cdPasswordButton="newpassword">
+ </button>
</div>
<div class="password-strength-level">
<div class="{{ passwordStrengthLevelClass }}"
placeholder="Confirm new password..."
id="confirmnewpassword"
formControlName="confirmnewpassword">
- <span class="input-group-append">
- <button class="btn btn-light"
- cdPasswordButton="confirmnewpassword">
- </button>
- </span>
+ <button class="btn btn-light"
+ cdPasswordButton="confirmnewpassword">
+ </button>
</div>
<span class="invalid-feedback"
*ngIf="userForm.showError('confirmnewpassword', frm, 'required')"
<ng-container *ngIf="{ ftMap: featureToggleMap$ | async, daemons: rgwDaemonService.daemons$ | async, selectedDaemon: rgwDaemonService.selectedDaemon$ | async } as data">
<ng-container *ngIf="data.ftMap && data.ftMap.rgw && permissions.rgw.read && isRgwRoute && data.daemons.length > 1">
<div class="cd-context-bar pt-3 pb-3">
- <span class="mr-1"
+ <span class="me-1"
i18n>Selected Object Gateway:</span>
<div ngbDropdown
placement="bottom-left"
- class="d-inline-block ml-2">
+ class="d-inline-block ms-2">
<button ngbDropdownToggle
class="btn btn-outline-info ctx-bar-selected-rgw-daemon"
i18n-title
.list-inline {
margin-bottom: 0;
- margin-left: 20%;
+ margin-left: 17%;
}
a {
<div class="about-container">
<div class="modal-header">
<button type="button"
- class="close float-right"
+ class="btn-close float-end"
aria-label="Close"
(click)="activeModal.close()">
- <span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
</a>
<div ngbDropdownMenu>
<a ngbDropdownItem
+ class="nav-link text-capitalize"
[ngClass]="{'disabled': !docsUrl}"
- class="text-capitalize"
href="{{ docsUrl }}"
target="_blank"
i18n>documentation</a>
- <a ngbDropdownItem
- routerLink="/api-docs"
- target="_blank"
- i18n>API</a>
+ <button ngbDropdownItem
+ routerLink="/api-docs"
+ target="_blank"
+ i18n>API</button>
<button ngbDropdownItem
(click)="openAboutModal()"
i18n>About</button>
<cd-notifications-sidebar></cd-notifications-sidebar>
<div class="cd-navbar-top">
<nav class="navbar navbar-expand-md navbar-dark cd-navbar-brand">
- <button class="btn btn-link py-0"
+ <button class="btn btn-link py-0 ms-3"
(click)="showMenuSidebar = !showMenuSidebar"
aria-label="toggle sidebar visibility">
<i class="fa fa-bars fa-2x"
aria-hidden="true"></i>
</button>
- <a class="navbar-brand ml-2"
+ <a class="navbar-brand ms-2"
href="#">
<img src="assets/Ceph_Ceph_Logo_with_text_white.svg"
alt="Ceph" />
<a routerLink="/monitoring">
<ng-container i18n>Monitoring</ng-container>
<small *ngIf="prometheusAlertService.activeCriticalAlerts > 0"
- class="badge badge-danger ml-1">{{ prometheusAlertService.activeCriticalAlerts }}</small>
+ class="badge badge-danger ms-1">{{ prometheusAlertService.activeCriticalAlerts }}</small>
<small *ngIf="prometheusAlertService.activeWarningAlerts > 0"
- class="badge badge-warning ml-1">{{ prometheusAlertService.activeWarningAlerts }}</small>
+ class="badge badge-warning ms-1">{{ prometheusAlertService.activeWarningAlerts }}</small>
</a>
</li>
</ul>
content: '\f054';
font-family: 'ForkAwesome';
font-size: 1rem;
+ margin-top: 2px;
position: absolute;
right: 20px;
transition: transform 0.3s ease-in-out;
[placeholder]="option.additionalTypeInfo.humanReadable"
[formControlName]="option.name"
[step]="getStep(option.type, optionsForm.getValue(option.name))">
- <div class="input-group-append"
- *ngIf="optionsFormShowReset">
- <button class="btn btn-light"
- type="button"
- data-toggle="button"
- title="Remove the custom configuration value. The default configuration will be inherited and used instead."
- (click)="resetValue(option.name)"
- i18n-title>
- <i [ngClass]="[icons.erase]"
- aria-hidden="true"></i>
- </button>
- </div>
+ <button class="btn btn-light"
+ type="button"
+ data-toggle="button"
+ title="Remove the custom configuration value. The default configuration will be inherited and used instead."
+ (click)="resetValue(option.name)"
+ i18n-title
+ *ngIf="optionsFormShowReset">
+ <i [ngClass]="[icons.erase]"
+ aria-hidden="true"></i>
+ </button>
</div>
<span class="invalid-feedback"
*ngIf="optionsForm.showError(option.name, optionsFormDir, 'pattern')">
[formControlName]="field.name"
cdDimlessBinary>
<select *ngIf="field.type === 'select'"
- class="form-control"
+ class="form-select"
[id]="field.name"
[formControlName]="field.name">
<option *ngIf="field?.typeConfig?.placeholder"
<cd-doc section="grafana"></cd-doc> on how to add dashboards to Grafana.</cd-alert-panel>
<ng-container *ngIf="grafanaExist && dashboardExist">
- <div class="row">
- <div class="col">
- <div class="form-inline timepicker">
+ <div class="row mb-3">
+ <div class="col-lg-4 d-flex">
+ <div class="col-md-3 timepicker">
<label for="timepicker"
- class="ml-1 my-1"
- i18n>Grafana Time Picker</label>
-
+ class="mt-2"
+ i18n>Grafana Time Picker</label></div>
+ <div class="col-md-4">
<select id="timepicker"
name="timepicker"
- class="custom-select my-1 mx-3"
+ class="form-select"
[(ngModel)]="time"
(ngModelChange)="onTimepickerChange($event)">
<option *ngFor="let key of grafanaTimes"
[ngValue]="key.value">{{ key.name }}
</option>
- </select>
+ </select></div>
+ <div class="col-md-3">
- <button class="btn btn-light my-1"
+ <button class="btn btn-light ms-3"
i18n-title
title="Reset Settings"
(click)="reset()">
<i [ngClass]="[icons.undo]"></i>
</button>
- <button class="btn btn-light my-1 ml-3"
+ <button class="btn btn-light ms-3"
i18n-title
title="Show hidden information"
(click)="showMessage = !showMessage">
</div>
<div class="row">
- <div class="col my-3"
+ <div class="col my-2"
*ngIf="showMessage">
<cd-alert-panel type="info"
class="mb-3"
</div>
<ng-content></ng-content>
</ng-template>
-<i [ngClass]="[icons.questionCircle]"
+<i [ngClass]="iconClass ? iconClass : [icons.questionCircle]"
aria-hidden="true"
[ngbPopover]="popoverTpl"
(click)="$event.preventDefault();">
@Input()
class: string;
+ @Input()
+ iconClass = '';
+
@Input()
html: any;
<strong>
<i [ngClass]="[icons.spinner, icons.spin]"
aria-hidden="true"
- class="mr-2"></i>
+ class="me-2"></i>
</strong>
<ng-content></ng-content>
</ngb-alert>
<div [ngClass]="pageURL ? 'modal-dialog' : ''">
<div class="modal-content">
<div class="modal-header">
- <h4 class="modal-title float-left">
+ <h4 class="modal-title float-start">
<ng-content select=".modal-title"></ng-content>
</h4>
<button type="button"
- class="close float-right"
+ class="btn-close float-end"
aria-label="Close"
(click)="close()">
- <span aria-hidden="true">×</span>
</button>
</div>
</div>
<p class="card-text text-muted">
- <small class="date float-left">
+ <small class="date float-start">
{{ executingTask.begin_time | cdDate }}
</small>
- <span class="float-right">
+ <span class="float-end">
{{ executingTask.progress || 0 }} %
</span>
</p>
</div>
<div class="col-md-10">
<div class="card-body p-1">
- <button class="btn btn-link float-right mt-0 pt-0"
+ <button class="btn btn-link float-end mt-0 pt-0"
title="Remove notification"
i18n-title
(click)="remove(i); $event.stopPropagation()">
<i [ngClass]="[icons.trash]"></i>
</button>
<button *ngIf="notification.application == 'Prometheus' && notification.type != 2 && !notification.alertSilenced"
- class="btn btn-link float-right text-muted mute"
+ class="btn btn-link float-end text-muted mute m-0 p-0"
title="Silence Alert"
i18n-title
(click)="silence(notification)">
<i [ngClass]="[icons.mute]"></i>
</button>
<button *ngIf="notification.application == 'Prometheus' && notification.type != 2 && notification.alertSilenced"
- class="btn btn-link float-right text-muted mute"
+ class="btn btn-link float-end text-muted mute m-0 p-0"
title="Expire Silence"
i18n-title
(click)="expire(notification)">
</ng-container>
<small class="date"
[title]="notification.timestamp | cdDate">{{ notification.timestamp | relativeDate }}</small>
- <i class="float-right custom-icon"
+ <i class="float-end custom-icon"
[ngClass]="[notification.applicationClass]"
[title]="notification.application"></i>
</p>
<div class="card-header">
<ng-container i18n>Tasks and Notifications</ng-container>
- <button class="close float-right"
+ <button class="btn-close float-end"
tabindex="-1"
type="button"
title="close"
(click)="closeSidebar()">
- <span>
- <i [ngClass]="icons.close"></i>
- </span>
</button>
</div>
margin-bottom: 2px;
margin-top: 2px;
}
-
-.card-text {
- margin-right: 15px;
-}
-
-.mute {
- margin-right: -17px;
- margin-top: -4px;
-}
<div class="container-fluid">
<div class="row">
- <div class="col d-flex justify-content-end">
- <form class="form-inline">
+ <form>
+ <div class="col-sm-1 d-flex float-end">
<label for="refreshInterval"
- class="col-form-label my-0 mx-2"
+ class="col-form-label my-0 mx-2 float-end"
i18n>Refresh</label>
<select id="refreshInterval"
name="refreshInterval"
- class="form-control"
+ class="form-select float-end"
(change)="changeRefreshInterval($event.target.value)"
[(ngModel)]="selectedInterval">
<option *ngFor="let key of intervalKeys"
[value]="intervalList[key]">{{ key }}</option>
</select>
- </form>
- </div>
+ </div>
+ </form>
</div>
</div>
[selectionLimit]="selectionLimit"
[customBadges]="customBadges"
[customBadgeValidators]="customBadgeValidators"
- elemClass="mr-2 select-menu-edit"
+ elemClass="me-2 select-menu-edit"
(selection)="selection.emit($event)">
<i [ngClass]="[icons.edit]"></i>
</cd-select>
<span *ngFor="let dataItem of data">
- <span class="badge badge-dark mr-2">
- <span class="mr-2">{{ dataItem }}</span>
+ <span class="badge badge-dark me-2">
+ <span class="me-2">{{ dataItem }}</span>
<a class="badge-remove"
(click)="cdSelect.removeItem(dataItem)">
<i [ngClass]="[icons.destroy]"
</div>
</ng-template>
-<a class="select-menu-edit float-left"
+<a class="select-menu-edit float-start"
[ngClass]="elemClass"
[ngbPopover]="popTemplate"
data-testid="select-menu-edit"
<ng-content></ng-content>
</a>
-<span class="form-text text-muted float-left"
+<span class="form-text text-muted float-start"
*ngIf="data.length === 0 && !(!customBadges && options.length === 0)">
{{ messages.empty }}
</span>
-<span class="form-text text-muted float-left"
+<span class="form-text text-muted float-start"
*ngIf="!customBadges && options.length === 0">
{{ messages.noOptions }}
</span>
<!-- search -->
<div class="input-group search"
*ngIf="searchField">
- <span class="input-group-prepend">
- <span class="input-group-text">
- <i [ngClass]="[icons.search]"></i>
- </span>
+ <span class="input-group-text">
+ <i [ngClass]="[icons.search]"></i>
</span>
<input aria-label="search"
class="form-control"
type="text"
[(ngModel)]="search"
(keyup)="updateFilter()">
- <div class="input-group-append">
- <button type="button"
- class="btn btn-light"
- title="Clear"
- (click)="onClearSearch()">
- <i class="icon-prepend {{ icons.destroy }}"></i>
- </button>
- </div>
+ <button type="button"
+ class="btn btn-light"
+ title="Clear"
+ (click)="onClearSearch()">
+ <i class="icon-prepend {{ icons.destroy }}"></i>
+ </button>
</div>
<!-- end search -->
<div class="filter-chips">
<span *ngFor="let filter of columnFilters">
<span *ngIf="filter.value"
- class="badge badge-info mr-2">
- <span class="mr-2">{{ filter.column.name }}: {{ filter.value.formatted }}</span>
+ class="badge badge-info me-2">
+ <span class="me-2">{{ filter.column.name }}: {{ filter.value.formatted }}</span>
<a class="badge-remove"
(click)="onChangeFilter(filter); false">
<i [ngClass]="[icons.destroy]"
import {
- ComponentFactoryResolver,
Directive,
Input,
TemplateRef,
export class FormLoadingDirective {
constructor(
private templateRef: TemplateRef<any>,
- private viewContainer: ViewContainerRef,
- private componentFactoryResolver: ComponentFactoryResolver
+ private viewContainer: ViewContainerRef
) {}
@Input('cdFormLoading') set cdFormLoading(condition: LoadingStatus) {
- let factory: any;
let content: any;
this.viewContainer.clear();
switch (condition) {
case LoadingStatus.Loading:
- factory = this.componentFactoryResolver.resolveComponentFactory(LoadingPanelComponent);
content = this.resolveNgContent($localize`Loading form data...`);
- this.viewContainer.createComponent(factory, null, null, content);
+ this.viewContainer.createComponent(LoadingPanelComponent, {projectableNodes: content});
break;
case LoadingStatus.Ready:
this.viewContainer.createEmbeddedView(this.templateRef);
break;
case LoadingStatus.Error:
- factory = this.componentFactoryResolver.resolveComponentFactory(AlertPanelComponent);
content = this.resolveNgContent($localize`Form data could not be loaded.`);
- const componentRef = this.viewContainer.createComponent(factory, null, null, content);
+ const componentRef = this.viewContainer.createComponent(AlertPanelComponent, {projectableNodes: content});
(<AlertPanelComponent>componentRef.instance).type = 'error';
break;
}
service.show(NotificationType.info, 'Some info');
expect(toastr.info).toHaveBeenCalledWith(
`<small class="date">${time}</small>` +
- '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>',
+ '<i class="float-end custom-icon ceph-icon" title="Ceph"></i>',
'Some info',
undefined
);
expect(toastr.error).toHaveBeenCalledWith(
'Some operation failed<br>' +
`<small class="date">${time}</small>` +
- '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>',
+ '<i class="float-end custom-icon ceph-icon" title="Ceph"></i>',
'Some error',
undefined
);
expect(toastr.success).toHaveBeenCalledWith(
'Some alert resolved<br>' +
`<small class="date">${time}</small>` +
- '<i class="float-right custom-icon prometheus-icon" title="Prometheus"></i>',
+ '<i class="float-end custom-icon prometheus-icon" title="Prometheus"></i>',
'Alert resolved',
undefined
);
renderTimeAndApplicationHtml(notification: CdNotification): string {
return `<small class="date">${this.cdDatePipe.transform(
notification.timestamp
- )}</small><i class="float-right custom-icon ${notification.applicationClass}" title="${
+ )}</small><i class="float-end custom-icon ${notification.applicationClass}" title="${
notification.application
}"></i>`;
}
pointer-events: none;
}
+a {
+ &:hover {
+ text-decoration: underline;
+ }
+}
+
.clickable,
a {
cursor: pointer;
+ text-decoration: none;
+}
+
+a.nav-link,
+a.btn-light {
+ text-decoration: none;
+}
+
+// Overrides the badge to rounded-pill
+.badge {
+ @extend .badge, .rounded-pill, .mb-1;
+}
+
+// Overriding badges to match the class name of badges in Bootstrap v5
+.badge-primary {
+ @extend .badge, .bg-primary;
+}
+
+.badge-secondary {
+ @extend .badge, .bg-secondary;
+}
+
+.badge-success {
+ @extend .badge, .bg-success;
+}
+
+.badge-danger {
+ @extend .badge, .bg-danger;
+}
+
+.badge-info {
+ @extend .badge, .bg-primary;
+}
+
+.badge-warning {
+ @extend .badge, .bg-warning, .text-dark;
+}
+
+.badge-light {
+ @extend .badge, .bg-light, .text-dark;
+}
+
+.badge-dark {
+ @extend .badge, .bg-dark;
}
.card-body {
.card-title {
- @extend .pl-2;
+ @extend .ps-2;
}
.card-text {
}
.btn-toolbar cd-table-actions.btn-group {
- @extend .mr-2;
+ @extend .me-2;
}
cd-table {
cd-logs {
label {
- @extend .mr-2;
+ @extend .me-2;
}
.form-inline > .form-group {
- @extend .mr-3;
+ @extend .me-3;
@extend .mb-3;
}
}
dt {
@extend .col-4;
- @extend .font-weight-bold;
+ @extend .fw-bold;
}
dd {
@extend .fa-fw;
}
-pre:not(cd-api-docs *) {
- @extend .card;
- @extend .bg-light;
- @extend .p-2;
-}
border-left: 1px solid vv.$gray-400;
}
-.accordion {
- .card {
- border: 0;
- }
-
- .card-header {
- border: 0;
- border-bottom: 3px solid vv.$white;
- padding-left: 0;
-
- .btn:focus,
- .btn.focus {
- box-shadow: none;
- }
-
- button.dropdown-toggle {
- position: relative;
-
- &::after {
- border: 0;
- content: '\f054';
- font-family: 'ForkAwesome';
- font-size: 1rem;
- position: absolute;
- right: 20px;
- transition: transform 0.3s ease-in-out;
- }
-
- &[aria-expanded='true']::after {
- transform: rotate(90deg);
- }
- }
- }
-}
-
a.nav-link {
color: vv.$primary;
}
@use './src/styles/vendor/variables' as vv;
/* Reset checkbox success color */
-.was-validated .custom-control-input:valid,
-.custom-control-input.is-valid {
- ~ .custom-control-label {
+.was-validated .form-check-input:valid,
+.form-check-input.is-valid {
+ border-color: rgba(vv.$primary, 0.8);
+
+ &:checked{
+ background-color: vv.$primary;
+ border-color: rgba(vv.$primary, 0.8);
+ box-shadow: 0 0 3px 2px rgba(vv.$primary, 0.5);
+ }
+
+ &:focus {
+ border-color: rgba(vv.$primary, 0.8);
+ box-shadow: 0 0 3px 2px rgba(vv.$primary, 0.5);
+ }
+
+ ~ .form-check-label {
color: initial;
}
- &:checked ~ .custom-control-label::before {
+ &:checked ~ .form-check-label::before {
background-color: $component-active-bg;
- border-color: $custom-control-indicator-checked-border-color;
}
- ~ .custom-control-label::before {
- border-color: $custom-control-indicator-border-color;
+ ~ .form-check-label::before {
+ border-color: rgba(vv.$primary, 0.8);
}
&:focus ~ .custom-control-label::before {
- box-shadow: $custom-control-indicator-focus-box-shadow;
+ box-shadow: 0 0 3px 2px rgba(vv.$primary, 0.5);
}
&:focus:not(:checked) ~ .custom-control-label::before {
- border-color: $custom-control-indicator-focus-border-color;
+ border-color: rgba(vv.$primary, 0.8);
}
}
}
}
+.btn-primary {
+ @extend .btn-accent;
+}
+
// We have some inputs that don't have a corresponding formControlName,
// to be able to get the same styling and no JS errors we need use a different
// class name
.card-footer button.btn:not(:first-child) {
margin-left: 5px;
}
+
+button {
+ &.disabled {
+ pointer-events: none !important;
+ }
+}
width: 100%;
}
-.form-control {
+.form-control,
+.form-select {
display: table-cell;
&:focus {
}
.custom-checkbox {
+ @extend .form-check;
padding-top: 7px;
+
+ .custom-control-input {
+ @extend .form-check-input;
+ }
+
+ .custom-control-label {
+ @extend .form-check-label;
+ }
}
.custom-radio {
+ @extend .form-check;
padding-top: 5px;
}
.invalid-feedback {
display: block;
}
+
+.form-group{
+ @extend .mb-3;
+}
+
+.custom-control-label {
+ @extend .form-label;
+}
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
-$dark: #777 !default;
+$dark: $gray-800 !default;
//badges colors
$green-300: #6ec664;
$theme-colors: (
'accent': $accent,
- 'warning-dark': $warning-dark
+ 'warning-dark': $warning-dark,
+ 'primary': $accent,
+ 'secondary': $secondary,
+ 'success': $success,
+ 'info': $info,
+ 'warning': $warning,
+ 'danger': $danger,
+ 'light': $light,
+ 'dark': $dark
) !default;
// Body