Skip to content

Commit

Permalink
Kickstart UI: Refactors Labels Component to Shared TKG Labels (vmware…
Browse files Browse the repository at this point in the history
…-tanzu#2515)

* Issue vmware-tanzu#1620 - TKG Labels

* update lock

* add spaces on imports
  • Loading branch information
mpanchajanya authored and ankeesler committed Jun 14, 2022
1 parent e9b8087 commit bd86b53
Show file tree
Hide file tree
Showing 28 changed files with 1,257 additions and 808 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ hack/providers-sync-tools/**/build
# Build artifacts related to packages
/build
/packages/package-values-sha256.yaml
/packages/**/.imgpkg
/packages/**/.imgpkg
369 changes: 291 additions & 78 deletions pkg/v1/tkg/web/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pkg/v1/tkg/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@clr/icons": "^12.0.7",
"@clr/ui": "^12.0.7",
"@ctrl/ngx-codemirror": "2.2.1",
"@rxweb/reactive-form-validators": "^2.1.6",
"@types/lodash": "^4.14.170",
"@webcomponents/custom-elements": "1.3.2",
"@webcomponents/webcomponentsjs": "^2.6.0",
Expand Down
12 changes: 6 additions & 6 deletions pkg/v1/tkg/web/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

// Third-party imports
import { LogMonitorModule } from 'ngx-log-monitor';
import { CodemirrorModule } from '@ctrl/ngx-codemirror';

import { RxReactiveFormsModule } from '@rxweb/reactive-form-validators';
// Module imports
import { APIClientModule } from './swagger/index';
import { AppRoutingModule } from './app-routing.module';
import { SharedModule } from './shared/shared.module';

// Component imports
import { AppComponent } from './app.component';
import { HeaderBarModule } from './shared/components/header-bar/header-bar.module';
import { ThemeToggleComponent } from './shared/components/theme-toggle/theme-toggle.component';

// Service imports
import { BrandingService } from './shared/service/branding.service';
import { WebsocketService } from './shared/service/websocket.service';
Expand All @@ -42,12 +39,15 @@ import { WebsocketService } from './shared/service/websocket.service';
}
}),
SharedModule,
CodemirrorModule
CodemirrorModule,

RxReactiveFormsModule
],
providers: [
BrandingService,
WebsocketService
],
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {
}
41 changes: 18 additions & 23 deletions pkg/v1/tkg/web/src/app/shared/service/user-data-form.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { BackingObjectMap, FieldMapping, StepMapping } from '../../views/landing/wizard/shared/field-mapping/FieldMapping';
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
import {
BackingObjectMap,
FieldMapping,
StepMapping
} from '../../views/landing/wizard/shared/field-mapping/FieldMapping';
import { AbstractControl, FormGroup } from '@angular/forms';
import AppServices from './appServices';
import { UserDataIdentifier, UserDataService } from './user-data.service';
import { FormUtils } from '../../views/landing/wizard/shared/utils/form-utils';

export class UserDataFormService {
storeFromMapping(wizard, step: string, stepMapping: StepMapping, formGroup: FormGroup) {
AppServices.fieldMapUtilities.getActiveFieldMappings(stepMapping).forEach( fieldMapping => {
AppServices.fieldMapUtilities.getActiveFieldMappings(stepMapping).forEach(fieldMapping => {
if (AppServices.fieldMapUtilities.shouldAutoSave(fieldMapping)) {
this.storeFromFieldMapping(wizard, step, fieldMapping, formGroup);
}
Expand All @@ -15,7 +19,7 @@ export class UserDataFormService {
}

private storeFromFieldMapping(wizard, step: string, fieldMapping: FieldMapping, formGroup: FormGroup) {
const identifier: UserDataIdentifier = { wizard, step, field: fieldMapping.name };
const identifier: UserDataIdentifier = {wizard, step, field: fieldMapping.name};
if (fieldMapping.hasNoDomControl) {
this.storeFieldWithNoDomControl(wizard, step, fieldMapping);
} else if (fieldMapping.isBoolean) {
Expand All @@ -26,8 +30,8 @@ export class UserDataFormService {
this.storeMapField(identifier, formGroup);
} else if (fieldMapping.backingObject) {
this.storeBackingObjectField(identifier, formGroup, fieldMapping.backingObject)
} else {
this.storeInputField(identifier, formGroup);
} else {
this.storeInputField(identifier, formGroup, fieldMapping.displayFunction);
}
}

Expand All @@ -37,7 +41,7 @@ export class UserDataFormService {
return;
}
const value = fieldMapping.retriever(null);
const identifier = { wizard, step, field: fieldMapping.name };
const identifier = {wizard, step, field: fieldMapping.name};
if (fieldMapping.isBoolean) {
AppServices.userDataService.storeBoolean(identifier, value);
} else if (fieldMapping.isMap) {
Expand All @@ -48,12 +52,13 @@ export class UserDataFormService {
}

// convenience methods
storeInputField(identifier: UserDataIdentifier, formGroup: FormGroup): boolean {
storeInputField(identifier: UserDataIdentifier, formGroup: FormGroup, displayFunction?: (f) => string): boolean {
const control = this.getFormControl(identifier, formGroup);
if (!control) {
return false;
}
AppServices.userDataService.store(identifier, { display: control.value, value: control.value });
const displayValue = displayFunction ? displayFunction(control.value) : control.value
AppServices.userDataService.store(identifier, {display: displayValue, value: control.value});
return true;
}

Expand Down Expand Up @@ -83,7 +88,7 @@ export class UserDataFormService {

restoreForm(wizard, step: string, formGroup: FormGroup, stepMapping: StepMapping) {
AppServices.fieldMapUtilities.getFieldMappingsToRestore(stepMapping).forEach(fieldMapping => {
const identifier = { wizard, step, field: fieldMapping.name };
const identifier = {wizard, step, field: fieldMapping.name};
this.restoreField(identifier, fieldMapping, formGroup);

// Re-store the masked field value, so that if there WAS a value for this masked field in local storage,
Expand All @@ -95,25 +100,15 @@ export class UserDataFormService {
// Note: we set the values on the primary trigger fields AFTER all the "regular" fields are restored because the
// handler for the trigger field change may make use the values of the other fields
AppServices.fieldMapUtilities.getPrimaryTriggerMappingsToRestore(stepMapping).forEach(fieldMapping => {
const identifier = { wizard, step, field: fieldMapping.name };
const identifier = {wizard, step, field: fieldMapping.name};
this.restoreField(identifier, fieldMapping, formGroup);
})
}

private buildFormField(formGroup: FormGroup, wizard, step: string, fieldMapping: FieldMapping) {
AppServices.fieldMapUtilities.validateFieldMapping(step, fieldMapping);
const initialValue = AppServices.fieldMapUtilities.getInitialValue(wizard, step, fieldMapping);
const validators = AppServices.fieldMapUtilities.getValidatorArray(fieldMapping);
FormUtils.addControl(
formGroup,
fieldMapping.name,
new FormControl(initialValue, validators)
);
// TODO: figure out why we cannot seem to set the initialValue using the above code: new FormControl(initialValue, validators),
// but putting it into a setTimeout closure seems to "fix" the problem
setTimeout(() => {
formGroup.controls[fieldMapping.name].setValue(initialValue);
});
FormUtils.addDynamicControl(formGroup, initialValue, fieldMapping);
}

private shouldBuildField(fieldMapping: FieldMapping) {
Expand Down Expand Up @@ -165,7 +160,7 @@ export class UserDataFormService {
if (!control) {
return false;
}
AppServices.userDataService.store(identifier, { display: control.value ? UserDataService.MASK : '', value: '' });
AppServices.userDataService.store(identifier, {display: control.value ? UserDataService.MASK : '', value: ''});
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<div class="clr-row mb-20">
<div class="clr-col-12">
<clr-icon
shape="arrow"
dir="left"
size="30"
class="is-info back-link"
role="button"
tabindex="0"
aria-label="back"
(click)="navigate(APP_ROUTES.LANDING)"
keyboardListener
shape="arrow"
dir="left"
size="30"
class="is-info back-link"
role="button"
tabindex="0"
aria-label="back"
(click)="navigate(APP_ROUTES.LANDING)"
keyboardListener
></clr-icon>
<h2 i18n="wizard title" aria-level="1">
<div class="aws-ec2-icon-30 offset-top-2"></div>
Expand Down Expand Up @@ -42,7 +42,7 @@ <h2 i18n="wizard title" aria-level="1">
Deploy {{ clusterTypeDescriptorTitleCase }} Cluster
</button>
<button class="btn btn-outline edit-btn" (click)="reviewConfiguration(false)"
i18n="return to wizard for edit button">
i18n="return to wizard for edit button">
Edit Configuration
</button>
<ng-container *featureToggle="'management-cluster.export-from-confirm'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ describe('AwsWizardComponent', () => {
}),
metadataForm: fb.group({
clusterDescription: [''],
clusterLabels: [new Map()],
clusterLocation: [''],
clusterLabels: [{key: 'a', value: '1'}],
clusterLocation: ['']
}),
networkForm: fb.group({
clusterPodCidr: [''],
Expand Down Expand Up @@ -150,10 +150,7 @@ describe('AwsWizardComponent', () => {
expect(formGroup).toBeTruthy();
formGroup.addControl(fieldName, new FormControl(desiredValue));
});
// NOTE: because cluster labels are pulled from storage (not a DOM control) we have to put the test values in storage
const clusterLabels = new Map<string, string>([['key1', 'value1']]);
const identifierClusterLabels = { wizard: component.wizardName, step: WizardForm.METADATA, field: 'clusterLabels'};
AppServices.userDataService.storeMap(identifierClusterLabels, clusterLabels);

// NOTE: because cluster plan is pulled from storage (not a DOM control) we have to put the test values in storage
const identifierClusterPlan = { wizard: component.wizardName, step: AwsForm.NODESETTING, field: NodeSettingField.CLUSTER_PLAN };
AppServices.userDataService.store(identifierClusterPlan, { display: ClusterPlan.DEV, value: ClusterPlan.DEV });
Expand All @@ -175,9 +172,7 @@ describe('AwsWizardComponent', () => {
clusterPodCIDR: '100.96.0.0/11',
cniType: 'antrea'
});
expect(payload.labels).toEqual({
key1: 'value1'
});
expect(payload.labels).toEqual({});
expect(payload.annotations).toEqual({
description: 'DescriptionEXAMPLE',
location: 'mylocation1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,18 +334,18 @@ export class AwsWizardComponent extends WizardBaseDirective implements OnInit {
return {name: AwsForm.PROVIDER, title: 'IaaS Provider',
description: 'Validate the AWS provider account for ' + this.title,
i18n: {title: 'IaaS provder step name', description: 'IaaS provder step description'},
clazz: AwsProviderStepComponent};
clazz: AwsProviderStepComponent};
}
get AwsNodeSettingForm(): FormDataForHTML {
return { name: AwsForm.NODESETTING, title: FormUtility.titleCase(this.clusterTypeDescriptor) + ' Cluster Settings',
description: `Specify the resources backing the ${this.clusterTypeDescriptor} cluster`,
i18n: {title: 'IaaS provder step name', description: 'IaaS provder step description'},
clazz: NodeSettingStepComponent};
clazz: NodeSettingStepComponent};
}
get AwsVpcForm(): FormDataForHTML {
return {name: AwsForm.VPC, title: 'VPC for AWS', description: 'Specify VPC settings for AWS',
i18n: {title: 'vpc step name', description: 'vpc step description'},
clazz: VpcStepComponent};
i18n: {title: 'vpc step name', description: 'vpc step description'},
clazz: VpcStepComponent};
}
get AwsOsImageForm(): FormDataForHTML {
return this.getOsImageForm(AwsOsImageStepComponent);
Expand All @@ -358,12 +358,12 @@ export class AwsWizardComponent extends WizardBaseDirective implements OnInit {

private subscribeToServices() {
AppServices.messenger.subscribe(TanzuEventType.AWS_REGION_CHANGED, event => {
const region = event.payload;
AppServices.dataServiceRegistrar.trigger([TanzuEventType.AWS_GET_OS_IMAGES], { region });
// NOTE: even though the VPC and AZ endpoints don't take the region as a payload, they DO return different data
// if the user logs in to AWS using a different region. Therefore, we re-fetch that data if the region changes.
AppServices.dataServiceRegistrar.trigger([TanzuEventType.AWS_GET_EXISTING_VPCS, TanzuEventType.AWS_GET_AVAILABILITY_ZONES]);
});
const region = event.payload;
AppServices.dataServiceRegistrar.trigger([TanzuEventType.AWS_GET_OS_IMAGES], { region });
// NOTE: even though the VPC and AZ endpoints don't take the region as a payload, they DO return different data
// if the user logs in to AWS using a different region. Therefore, we re-fetch that data if the region changes.
AppServices.dataServiceRegistrar.trigger([TanzuEventType.AWS_GET_EXISTING_VPCS, TanzuEventType.AWS_GET_AVAILABILITY_ZONES]);
});
}

private registerServices() {
Expand Down
Loading

0 comments on commit bd86b53

Please sign in to comment.