mirror of
https://github.com/ceph/ceph
synced 2026-08-02 07:03:18 +00:00
Merge pull request #66607 from rhcs-dashboard/carbonized-import-modal
mgr/dashboard: carbonized-import-modal Reviewed-by: Nizamudeen A <nia@redhat.com> Reviewed-by: Devika Babrekar <devika.babrekar@ibm.com>
This commit is contained in:
commit
df499f3134
@ -194,9 +194,7 @@ export class RgwMultisiteDetailsComponent extends CdForm implements OnDestroy, O
|
||||
const initialState = {
|
||||
multisiteInfo: this.multisiteInfo
|
||||
};
|
||||
this.bsModalRef = this.modalService.show(RgwMultisiteImportComponent, initialState, {
|
||||
size: 'lg'
|
||||
});
|
||||
this.cdsModalService.show(RgwMultisiteImportComponent, initialState);
|
||||
}
|
||||
|
||||
openExportModal() {
|
||||
|
||||
@ -1,155 +1,157 @@
|
||||
<cd-modal [modalRef]="activeModal">
|
||||
<ng-container
|
||||
i18n="form title"
|
||||
class="modal-title"
|
||||
>Import Multi-site Token</ng-container
|
||||
>
|
||||
<cds-modal
|
||||
size="lg"
|
||||
[open]="open"
|
||||
[hasScrollingContent]="true"
|
||||
(overlaySelected)="closeModal()"
|
||||
>
|
||||
<cds-modal-header (closeSelect)="closeModal()">
|
||||
<h3
|
||||
cdsModalHeaderHeading
|
||||
i18n
|
||||
>
|
||||
Import multi-site tokens
|
||||
</h3>
|
||||
</cds-modal-header>
|
||||
|
||||
<ng-container class="modal-content">
|
||||
<div
|
||||
cdsModalContent
|
||||
[hasForm]="true"
|
||||
>
|
||||
<form
|
||||
name="importTokenForm"
|
||||
#frm="ngForm"
|
||||
[formGroup]="importTokenForm"
|
||||
novalidate
|
||||
>
|
||||
<div class="modal-body">
|
||||
<cd-alert-panel
|
||||
type="info"
|
||||
spacingClass="mb-3"
|
||||
>
|
||||
<div class="form-item">
|
||||
<cd-alert-panel type="info">
|
||||
<ul>
|
||||
<li>
|
||||
<li i18n>
|
||||
This feature allows you to configure a connection between your primary and secondary
|
||||
Ceph clusters for data replication. By importing a token, you establish a link between
|
||||
the clusters, enabling data synchronization.
|
||||
</li>
|
||||
<li>
|
||||
<li i18n>
|
||||
To obtain the token, generate it from your primary Ceph cluster. This token includes
|
||||
encoded information about the primary cluster's endpoint, access key, and secret key.
|
||||
</li>
|
||||
<li>
|
||||
<li i18n>
|
||||
The secondary zone represents the destination cluster where your data will be
|
||||
replicated.
|
||||
</li>
|
||||
</ul>
|
||||
</cd-alert-panel>
|
||||
<legend i18n>Zone Details</legend>
|
||||
<div class="form-group row">
|
||||
<label
|
||||
class="cd-col-form-label required"
|
||||
for="realmToken"
|
||||
i18n
|
||||
>Token
|
||||
</label>
|
||||
<div class="cd-col-form-input">
|
||||
<input
|
||||
id="realmToken"
|
||||
name="realmToken"
|
||||
class="form-control"
|
||||
type="text"
|
||||
formControlName="realmToken"
|
||||
/>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('realmToken', frm, 'required')"
|
||||
i18n
|
||||
>This field is required.</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label
|
||||
class="cd-col-form-label required"
|
||||
for="zoneName"
|
||||
i18n
|
||||
>Secondary Zone Name</label
|
||||
>
|
||||
<div class="cd-col-form-input">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
placeholder="Zone name..."
|
||||
id="zoneName"
|
||||
name="zoneName"
|
||||
formControlName="zoneName"
|
||||
/>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('zoneName', frm, 'required')"
|
||||
i18n
|
||||
>This field is required.</span
|
||||
>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('zoneName', frm, 'uniqueName')"
|
||||
i18n
|
||||
>The chosen zone name is already in use.</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="cd-col-form-offset">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="archive_zone"
|
||||
type="checkbox"
|
||||
formControlName="archive_zone"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label cds-ml-2"
|
||||
for="archive_zone"
|
||||
i18n
|
||||
>Archive</label
|
||||
>
|
||||
<cd-helper i18n>
|
||||
<span
|
||||
>Enable archival storage to keep all object versions and protect data from
|
||||
deletion or corruption.</span
|
||||
>
|
||||
</cd-helper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<legend i18n>Service Details</legend>
|
||||
<div class="form-group row">
|
||||
<div class="cd-col-form-offset">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="unmanaged"
|
||||
type="checkbox"
|
||||
formControlName="unmanaged"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label cds-ml-2"
|
||||
for="unmanaged"
|
||||
i18n
|
||||
>Unmanaged</label
|
||||
>
|
||||
<cd-helper i18n
|
||||
>If set to true, the orchestrator will not start nor stop any daemon associated with
|
||||
this service. Placement and all other properties will be ignored.</cd-helper
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<legend
|
||||
class="cd-header"
|
||||
i18n
|
||||
>
|
||||
Zone Details
|
||||
</legend>
|
||||
<div class="form-item">
|
||||
<cds-text-label
|
||||
labelInputID="realmToken"
|
||||
[invalid]="realmTokenRef.isInvalid"
|
||||
[invalidText]="realmTokenError"
|
||||
cdRequiredField="Token"
|
||||
i18n
|
||||
>Token
|
||||
<input
|
||||
cdsText
|
||||
cdValidate
|
||||
#realmTokenRef="cdValidate"
|
||||
type="text"
|
||||
id="realmToken"
|
||||
name="realmToken"
|
||||
formControlName="realmToken"
|
||||
modal-primary-focus
|
||||
[invalid]="realmTokenRef.isInvalid"
|
||||
/>
|
||||
</cds-text-label>
|
||||
<ng-template #realmTokenError>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
validationErrors;
|
||||
context: { control: importTokenForm.get('realmToken') }
|
||||
"
|
||||
></ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<!-- Placement -->
|
||||
<div
|
||||
*ngIf="!importTokenForm.controls.unmanaged.value"
|
||||
class="form-group row"
|
||||
<div class="form-item">
|
||||
<cds-text-label
|
||||
labelInputID="zoneName"
|
||||
[invalid]="zoneNameRef.isInvalid"
|
||||
[invalidText]="zoneNameError"
|
||||
cdRequiredField="Secondary Zone Name"
|
||||
i18n
|
||||
>Secondary Zone Name
|
||||
<input
|
||||
cdsText
|
||||
cdValidate
|
||||
#zoneNameRef="cdValidate"
|
||||
type="text"
|
||||
placeholder="Zone name..."
|
||||
id="zoneName"
|
||||
name="zoneName"
|
||||
formControlName="zoneName"
|
||||
[invalid]="zoneNameRef.isInvalid"
|
||||
/>
|
||||
</cds-text-label>
|
||||
<ng-template #zoneNameError>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
validationErrors;
|
||||
context: { control: importTokenForm.get('zoneName') }
|
||||
"
|
||||
></ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div class="form-item">
|
||||
<cds-checkbox
|
||||
id="archive_zone"
|
||||
formControlName="archive_zone"
|
||||
>
|
||||
<label
|
||||
class="cd-col-form-label"
|
||||
for="placement"
|
||||
i18n
|
||||
>Placement</label
|
||||
<span i18n>Archive</span>
|
||||
<cd-help-text i18n
|
||||
>Enable archival storage to keep all object versions and protect data from deletion or
|
||||
corruption.</cd-help-text
|
||||
>
|
||||
<div class="cd-col-form-input">
|
||||
<select
|
||||
id="placement"
|
||||
class="form-select"
|
||||
</cds-checkbox>
|
||||
</div>
|
||||
|
||||
<legend
|
||||
class="cd-header"
|
||||
i18n
|
||||
>
|
||||
Service Details
|
||||
</legend>
|
||||
<div class="form-item">
|
||||
<cds-checkbox
|
||||
id="unmanaged"
|
||||
formControlName="unmanaged"
|
||||
>
|
||||
<span i18n>Unmanaged</span>
|
||||
<cd-help-text i18n
|
||||
>If set to true, the orchestrator will not start nor stop any daemon associated with
|
||||
this service. Placement and all other properties will be ignored.</cd-help-text
|
||||
>
|
||||
</cds-checkbox>
|
||||
</div>
|
||||
|
||||
<!-- Placement -->
|
||||
@if (!importTokenForm.controls.unmanaged.value) {
|
||||
<div
|
||||
class="form-item"
|
||||
cdsRow
|
||||
>
|
||||
<div cdsCol>
|
||||
<cds-select
|
||||
formControlName="placement"
|
||||
label="Placement"
|
||||
i18n-label
|
||||
id="placement"
|
||||
>
|
||||
<option
|
||||
i18n
|
||||
@ -163,151 +165,158 @@
|
||||
>
|
||||
Label
|
||||
</option>
|
||||
</select>
|
||||
</cds-select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Label -->
|
||||
<!-- Label -->
|
||||
@if (
|
||||
!importTokenForm.controls.unmanaged.value &&
|
||||
importTokenForm.controls.placement.value === 'label'
|
||||
) {
|
||||
<div
|
||||
*ngIf="
|
||||
!importTokenForm.controls.unmanaged.value &&
|
||||
importTokenForm.controls.placement.value === 'label'
|
||||
"
|
||||
class="form-group row"
|
||||
class="form-item"
|
||||
cdsRow
|
||||
>
|
||||
<label
|
||||
i18n
|
||||
class="cd-col-form-label"
|
||||
for="label"
|
||||
>Label</label
|
||||
>
|
||||
<div class="cd-col-form-input">
|
||||
<input
|
||||
id="label"
|
||||
class="form-control"
|
||||
type="text"
|
||||
<div cdsCol>
|
||||
<cds-combo-box
|
||||
label="Label"
|
||||
type="single"
|
||||
formControlName="label"
|
||||
[ngbTypeahead]="searchLabels"
|
||||
(focus)="labelFocus.next($any($event).target.value)"
|
||||
(click)="labelClick.next($any($event).target.value)"
|
||||
/>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('label', frm, 'required')"
|
||||
i18n
|
||||
>This field is required.</span
|
||||
i18n-label
|
||||
[items]="labels"
|
||||
[appendInline]="true"
|
||||
id="label"
|
||||
[invalid]="importTokenForm.showError('label', frm)"
|
||||
[invalidText]="labelError"
|
||||
selectionFeedback="top-after-reopen"
|
||||
placeholder="Select label..."
|
||||
i18n-placeholder
|
||||
>
|
||||
<cds-dropdown-list></cds-dropdown-list>
|
||||
</cds-combo-box>
|
||||
<ng-template #labelError>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
validationErrors;
|
||||
context: { control: importTokenForm.get('label') }
|
||||
"
|
||||
></ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Hosts -->
|
||||
<!-- Hosts -->
|
||||
@if (
|
||||
!importTokenForm.controls.unmanaged.value &&
|
||||
importTokenForm.getValue('placement') === 'hosts'
|
||||
) {
|
||||
<div
|
||||
*ngIf="
|
||||
!importTokenForm.controls.unmanaged.value &&
|
||||
importTokenForm.controls.placement.value === 'hosts'
|
||||
"
|
||||
class="form-group row"
|
||||
class="form-item"
|
||||
cdsRow
|
||||
>
|
||||
<label
|
||||
class="cd-col-form-label"
|
||||
for="hosts"
|
||||
i18n
|
||||
>Hosts</label
|
||||
>
|
||||
<div class="cd-col-form-input">
|
||||
<cd-select-badges
|
||||
<div cdsCol>
|
||||
<cds-combo-box
|
||||
label="Hosts"
|
||||
type="multi"
|
||||
formControlName="hosts"
|
||||
id="hosts"
|
||||
[data]="importTokenForm.controls.hosts.value"
|
||||
[options]="hosts.options"
|
||||
[messages]="hosts.messages"
|
||||
name="hosts"
|
||||
[items]="hosts"
|
||||
[appendInline]="true"
|
||||
selectionFeedback="top-after-reopen"
|
||||
(selected)="multiSelector($event)"
|
||||
placeholder="Select hosts..."
|
||||
i18n-placeholder
|
||||
>
|
||||
</cd-select-badges>
|
||||
<cds-dropdown-list></cds-dropdown-list>
|
||||
</cds-combo-box>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- count -->
|
||||
<!-- count -->
|
||||
@if (!importTokenForm.controls.unmanaged.value) {
|
||||
<div
|
||||
*ngIf="!importTokenForm.controls.unmanaged.value"
|
||||
class="form-group row"
|
||||
class="form-item"
|
||||
cdsRow
|
||||
>
|
||||
<label
|
||||
class="cd-col-form-label"
|
||||
for="count"
|
||||
>
|
||||
<span i18n>Count</span>
|
||||
<cd-helper i18n>Only that number of daemons will be created.</cd-helper>
|
||||
</label>
|
||||
<div class="cd-col-form-input">
|
||||
<input
|
||||
id="count"
|
||||
class="form-control"
|
||||
type="number"
|
||||
<div cdsCol>
|
||||
<cds-number
|
||||
cdValidate
|
||||
#countRef="cdValidate"
|
||||
formControlName="count"
|
||||
min="1"
|
||||
/>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('count', frm, 'min')"
|
||||
i18n
|
||||
>The value must be at least 1.</span
|
||||
>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('count', frm, 'pattern')"
|
||||
i18n
|
||||
>The entered value needs to be a number.</span
|
||||
>
|
||||
label="Count"
|
||||
i18n-label
|
||||
[min]="1"
|
||||
[invalid]="countRef.isInvalid"
|
||||
[invalidText]="countError"
|
||||
[helperText]="countHelper"
|
||||
></cds-number>
|
||||
<ng-template #countHelper>
|
||||
<span i18n>Only that number of daemons will be created.</span>
|
||||
</ng-template>
|
||||
<ng-template #countError>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
validationErrors;
|
||||
context: { control: importTokenForm.get('count') }
|
||||
"
|
||||
></ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- RGW -->
|
||||
<ng-container *ngIf="!importTokenForm.controls.unmanaged.value">
|
||||
<!-- rgw_frontend_port -->
|
||||
<div class="form-group row">
|
||||
<label
|
||||
i18n
|
||||
class="cd-col-form-label"
|
||||
for="rgw_frontend_port"
|
||||
>Port</label
|
||||
>
|
||||
<div class="cd-col-form-input">
|
||||
<input
|
||||
id="rgw_frontend_port"
|
||||
class="form-control"
|
||||
type="number"
|
||||
formControlName="rgw_frontend_port"
|
||||
min="1"
|
||||
max="65535"
|
||||
/>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('rgw_frontend_port', frm, 'pattern')"
|
||||
i18n
|
||||
>The entered value needs to be a number.</span
|
||||
>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('rgw_frontend_port', frm, 'min')"
|
||||
i18n
|
||||
>The value must be at least 1.</span
|
||||
>
|
||||
<span
|
||||
class="invalid-feedback"
|
||||
*ngIf="importTokenForm.showError('rgw_frontend_port', frm, 'max')"
|
||||
i18n
|
||||
>The value cannot exceed 65535.</span
|
||||
>
|
||||
</div>
|
||||
<!-- RGW -->
|
||||
<ng-container *ngIf="!importTokenForm.controls.unmanaged.value">
|
||||
<!-- rgw_frontend_port -->
|
||||
<div
|
||||
class="form-item"
|
||||
cdsRow
|
||||
>
|
||||
<div cdsCol>
|
||||
<cds-number
|
||||
cdValidate
|
||||
#portRef="cdValidate"
|
||||
formControlName="rgw_frontend_port"
|
||||
label="Port"
|
||||
i18n-label
|
||||
[min]="1"
|
||||
[max]="65535"
|
||||
[invalid]="portRef.isInvalid"
|
||||
[invalidText]="portError"
|
||||
></cds-number>
|
||||
<ng-template #portError>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
validationErrors;
|
||||
context: { control: importTokenForm.get('rgw_frontend_port') }
|
||||
"
|
||||
></ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<cd-form-button-panel
|
||||
(submitActionEvent)="onSubmit()"
|
||||
[submitText]="actionLabels.IMPORT"
|
||||
[form]="importTokenForm"
|
||||
></cd-form-button-panel>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</form>
|
||||
</ng-container>
|
||||
</cd-modal>
|
||||
</div>
|
||||
<cd-form-button-panel
|
||||
(submitActionEvent)="onSubmit()"
|
||||
[submitText]="actionLabels.IMPORT"
|
||||
[form]="importTokenForm"
|
||||
[modalForm]="true"
|
||||
></cd-form-button-panel>
|
||||
|
||||
<ng-template
|
||||
#validationErrors
|
||||
let-control="control"
|
||||
>
|
||||
@if (control?.errors) {
|
||||
@for (err of control.errors | keyvalue; track err.key) {
|
||||
<span class="invalid-feedback">{{ INVALID_TEXTS[err.key] }}</span>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
</cds-modal>
|
||||
|
||||
@ -3,7 +3,15 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import {
|
||||
ButtonModule,
|
||||
CheckboxModule,
|
||||
ComboBoxModule,
|
||||
InputModule,
|
||||
ModalModule,
|
||||
NumberModule,
|
||||
SelectModule
|
||||
} from 'carbon-components-angular';
|
||||
import { SharedModule } from '~/app/shared/shared.module';
|
||||
|
||||
import { RgwMultisiteImportComponent } from './rgw-multisite-import.component';
|
||||
@ -14,7 +22,19 @@ describe('RgwMultisiteImportComponent', () => {
|
||||
let fixture: ComponentFixture<RgwMultisiteImportComponent>;
|
||||
|
||||
configureTestBed({
|
||||
imports: [SharedModule, ReactiveFormsModule, RouterTestingModule, HttpClientTestingModule],
|
||||
imports: [
|
||||
SharedModule,
|
||||
ReactiveFormsModule,
|
||||
RouterTestingModule,
|
||||
HttpClientTestingModule,
|
||||
ModalModule,
|
||||
InputModule,
|
||||
CheckboxModule,
|
||||
ComboBoxModule,
|
||||
SelectModule,
|
||||
NumberModule,
|
||||
ButtonModule
|
||||
],
|
||||
declarations: [RgwMultisiteImportComponent],
|
||||
providers: [NgbActiveModal]
|
||||
});
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BaseModal } from 'carbon-components-angular';
|
||||
import { FormControl, Validators } from '@angular/forms';
|
||||
import { NgbActiveModal, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { RgwRealmService } from '~/app/shared/api/rgw-realm.service';
|
||||
import { ComboBoxItem } from '~/app/shared/models/combo-box.model';
|
||||
import { HostService } from '~/app/shared/api/host.service';
|
||||
import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
|
||||
import { NotificationType } from '~/app/shared/enum/notification-type.enum';
|
||||
import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
|
||||
@ -9,11 +12,6 @@ import { CdValidators } from '~/app/shared/forms/cd-validators';
|
||||
import { NotificationService } from '~/app/shared/services/notification.service';
|
||||
import { RgwZone } from '../models/rgw-multisite';
|
||||
import _ from 'lodash';
|
||||
import { SelectMessages } from '~/app/shared/components/select/select-messages.model';
|
||||
import { HostService } from '~/app/shared/api/host.service';
|
||||
import { SelectOption } from '~/app/shared/components/select/select-option.model';
|
||||
import { Observable, Subject, merge } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'cd-rgw-multisite-import',
|
||||
@ -21,22 +19,26 @@ import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'
|
||||
styleUrls: ['./rgw-multisite-import.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class RgwMultisiteImportComponent implements OnInit {
|
||||
export class RgwMultisiteImportComponent extends BaseModal implements OnInit {
|
||||
readonly endpoints = /^((https?:\/\/)|(www.))(?:([a-zA-Z]+)|(\d+\.\d+.\d+.\d+)):\d{2,4}$/;
|
||||
readonly ipv4Rgx =
|
||||
/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i;
|
||||
readonly ipv6Rgx = /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;
|
||||
@ViewChild(NgbTypeahead, { static: false })
|
||||
typeahead: NgbTypeahead;
|
||||
|
||||
importTokenForm: CdFormGroup;
|
||||
multisiteInfo: object[] = [];
|
||||
zoneList: RgwZone[] = [];
|
||||
zoneNames: string[];
|
||||
hosts: any;
|
||||
labels: string[];
|
||||
labelClick = new Subject<string>();
|
||||
labelFocus = new Subject<string>();
|
||||
hosts: ComboBoxItem[] = [];
|
||||
labels: ComboBoxItem[] = [];
|
||||
selectedHosts: string[] = [];
|
||||
|
||||
INVALID_TEXTS = {
|
||||
required: $localize`This field is required.`,
|
||||
uniqueName: $localize`The chosen zone name is already in use.`,
|
||||
min: $localize`The value must be at least 1.`,
|
||||
max: $localize`The value cannot exceed 65535.`,
|
||||
pattern: $localize`The entered value needs to be a number.`
|
||||
};
|
||||
|
||||
constructor(
|
||||
public activeModal: NgbActiveModal,
|
||||
@ -46,13 +48,7 @@ export class RgwMultisiteImportComponent implements OnInit {
|
||||
public actionLabels: ActionLabelsI18n,
|
||||
public notificationService: NotificationService
|
||||
) {
|
||||
this.hosts = {
|
||||
options: [],
|
||||
messages: new SelectMessages({
|
||||
empty: $localize`There are no hosts.`,
|
||||
filter: $localize`Filter hosts`
|
||||
})
|
||||
};
|
||||
super();
|
||||
this.createForm();
|
||||
}
|
||||
ngOnInit(): void {
|
||||
@ -64,17 +60,24 @@ export class RgwMultisiteImportComponent implements OnInit {
|
||||
return zone['name'];
|
||||
});
|
||||
this.hostService.getAllHosts().subscribe((resp: object[]) => {
|
||||
const options: SelectOption[] = [];
|
||||
const options: ComboBoxItem[] = [];
|
||||
_.forEach(resp, (host: object) => {
|
||||
if (_.get(host, 'sources.orchestrator', false)) {
|
||||
const option = new SelectOption(false, _.get(host, 'hostname'), '');
|
||||
options.push(option);
|
||||
const hostname = _.get(host, 'hostname');
|
||||
options.push({ content: hostname, selected: false, name: hostname });
|
||||
}
|
||||
});
|
||||
this.hosts.options = [...options];
|
||||
|
||||
this.hosts = [...options];
|
||||
});
|
||||
this.hostService.getLabels().subscribe((resp: string[]) => {
|
||||
this.labels = resp;
|
||||
this.labels = resp.map((label) => {
|
||||
return {
|
||||
content: label,
|
||||
selected: false,
|
||||
name: label
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -92,7 +95,12 @@ export class RgwMultisiteImportComponent implements OnInit {
|
||||
]
|
||||
}),
|
||||
rgw_frontend_port: new FormControl(null, {
|
||||
validators: [Validators.required, Validators.pattern('^[0-9]*$')]
|
||||
validators: [
|
||||
CdValidators.requiredIf({
|
||||
unmanaged: false
|
||||
}),
|
||||
Validators.pattern('^[0-9]*$')
|
||||
]
|
||||
}),
|
||||
placement: new FormControl('hosts'),
|
||||
label: new FormControl(null, [
|
||||
@ -108,6 +116,10 @@ export class RgwMultisiteImportComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
multiSelector(event: ComboBoxItem[]) {
|
||||
this.selectedHosts = event.map((host: ComboBoxItem) => host.content);
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
const values = this.importTokenForm.value;
|
||||
const placementSpec: object = {
|
||||
@ -117,18 +129,21 @@ export class RgwMultisiteImportComponent implements OnInit {
|
||||
if (!values['unmanaged']) {
|
||||
switch (values['placement']) {
|
||||
case 'hosts':
|
||||
if (values['hosts'].length > 0) {
|
||||
placementSpec['placement']['hosts'] = values['hosts'];
|
||||
if (this.selectedHosts.length > 0) {
|
||||
placementSpec['placement']['hosts'] = this.selectedHosts;
|
||||
}
|
||||
break;
|
||||
case 'label':
|
||||
placementSpec['placement']['label'] = values['label'];
|
||||
if (!_.isEmpty(values['label'])) {
|
||||
placementSpec['placement']['label'] = values['label']?.content;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (_.isNumber(values['count']) && values['count'] > 0) {
|
||||
placementSpec['placement']['count'] = values['count'];
|
||||
}
|
||||
}
|
||||
|
||||
this.rgwRealmService
|
||||
.importRealmToken(
|
||||
values['realmToken'],
|
||||
@ -143,25 +158,11 @@ export class RgwMultisiteImportComponent implements OnInit {
|
||||
NotificationType.success,
|
||||
$localize`Realm token import successfull`
|
||||
);
|
||||
this.activeModal.close();
|
||||
this.closeModal();
|
||||
},
|
||||
() => {
|
||||
this.importTokenForm.setErrors({ cdSubmitButton: true });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
searchLabels = (text$: Observable<string>) => {
|
||||
return merge(
|
||||
text$.pipe(debounceTime(200), distinctUntilChanged()),
|
||||
this.labelFocus,
|
||||
this.labelClick.pipe(filter(() => !this.typeahead.isPopupOpen()))
|
||||
).pipe(
|
||||
map((value) =>
|
||||
this.labels
|
||||
.filter((label: string) => label.toLowerCase().indexOf(value.toLowerCase()) > -1)
|
||||
.slice(0, 10)
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user