Skip to content

Commit

Permalink
Arc admin attribute form (#227)
Browse files Browse the repository at this point in the history
* updated arc admin attributes html and added a reactive form for the data

* binding fixes

* updated tests

* moved form def to constructor, populated form with config, on cancel form re-populates with config

* replaced the frozen default config with a hardcoded mock in showcase

---------

Co-authored-by: Katherine Brown <[email protected]>
Co-authored-by: Katherine Brown <[email protected]>
  • Loading branch information
3 people authored Oct 29, 2024
1 parent d945ed2 commit 1766fc9
Show file tree
Hide file tree
Showing 10 changed files with 425 additions and 272 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

section {
>* {
margin-inline-start: 1em;
margin-inline-start: 0em;
}

header {
Expand Down Expand Up @@ -50,20 +50,6 @@ section {
}
}

.attributes-table {
tr {
th {
font-weight: normal;
}

td {
padding-left: 20px;
opacity: 0.5;
font-size: 0.9em;
}
}
}

.fieldOverrides {
margin-top: 20px;
}
Expand Down Expand Up @@ -193,3 +179,18 @@ section {
line-height: inherit;
width: inherit;
}


.mat-form-field {
width: 100%;
margin-bottom: 32px;
}

mat-card {
margin-bottom: 8px;
}

.hint {
font-size: 75%;
padding: 0 1em;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { MatDialog } from '@angular/material/dialog'
import { AttributeConfig, AttributeConcatenationConfig, AttributeDefaultConfig, AttributeValueConfig } from '../ArcGISConfig';
import { ArcGISPluginConfig, defaultArcGISPluginConfig } from '../ArcGISPluginConfig'
import { ArcService, Form, MageEvent } from '../arc.service'
import { Subject } from 'rxjs';
import { Subject, first } from 'rxjs';
import { FormGroup, FormBuilder } from '@angular/forms';

@Component({
selector: 'arc-admin',
Expand Down Expand Up @@ -52,10 +53,27 @@ export class ArcAdminComponent implements OnInit {
@ViewChild('editAttributeConfigDialog', { static: true })
private editAttributeConfigTemplate: TemplateRef<unknown>

constructor(private arcService: ArcService, private dialog: MatDialog) {
attributesForm: FormGroup;

constructor(private arcService: ArcService, private dialog: MatDialog, private fb: FormBuilder) {
this.config = defaultArcGISPluginConfig;
this.editConfig = defaultArcGISPluginConfig;
this.editFieldMappings = false;
this.attributesForm = this.fb.group({
observationIdField: [''],
idSeparator: [''],
eventIdField: [''],
lastEditedDateField: [''],
eventNameField: [''],
userIdField: [''],
usernameField: [''],
userDisplayNameField: [''],
deviceIdField: [''],
createdAtField: [''],
lastModifiedField: [''],
geometryType: ['']
});

arcService.fetchArcConfig().subscribe(x => {
this.config = x;
if (!this.config.baseUrl) {
Expand All @@ -71,12 +89,95 @@ export class ArcAdminComponent implements OnInit {
}

ngOnInit(): void {
this.arcService.fetchArcConfig().pipe(first()).subscribe({
next: config => {
if (config) {
// Populate form with values from config
this.attributesForm.patchValue({
observationIdField: config.observationIdField || '',
idSeparator: config.idSeparator || '',
eventIdField: config.eventIdField || '',
lastEditedDateField: config.lastEditedDateField || '',
eventNameField: config.eventNameField || '',
userIdField: config.userIdField || '',
usernameField: config.usernameField || '',
userDisplayNameField: config.userDisplayNameField || '',
deviceIdField: config.deviceIdField || '',
createdAtField: config.createdAtField || '',
lastModifiedField: config.lastModifiedField || '',
geometryType: config.geometryType || ''
});
console.log('Form initialized with server config:', config);
}
},
error: error => {
console.error('Failed to fetch config:', error);
}
});
}

//Save attributes form. If left blank, assign default value
onSubmit(): void {
console.log('submitting form...');

if (this.attributesForm.valid) {
const formValue = this.attributesForm.value;
this.editConfig = {
...this.editConfig,
observationIdField: formValue.observationIdField || this.editConfig.observationIdField,
idSeparator: formValue.idSeparator || this.editConfig.idSeparator,
eventIdField: formValue.eventIdField || this.editConfig.eventIdField,
lastEditedDateField: formValue.lastEditedDateField || this.editConfig.lastEditedDateField,
eventNameField: formValue.eventNameField || this.editConfig.eventNameField,
userIdField: formValue.userIdField || this.editConfig.userIdField,
usernameField: formValue.usernameField || this.editConfig.usernameField,
userDisplayNameField: formValue.userDisplayNameField || this.editConfig.userDisplayNameField,
deviceIdField: formValue.deviceIdField || this.editConfig.deviceIdField,
createdAtField: formValue.createdAtField || this.editConfig.createdAtField,
lastModifiedField: formValue.lastModifiedField || this.editConfig.lastModifiedField,
geometryType: formValue.geometryType || this.editConfig.geometryType
};

console.log('Form Submitted:', this.editConfig);
console.log('formValue: ', formValue);

this.editConfig = this.copyConfig();
}
else{
console.log('Form is invalid, please correct the errors.')
}
}

onCancel(): void {
console.log('Cancel selected');
this.arcService.fetchArcConfig().pipe(first()).subscribe({
next: config => {
if (config) {
this.attributesForm.patchValue({
observationIdField: config.observationIdField || '',
idSeparator: config.idSeparator || '',
eventIdField: config.eventIdField || '',
lastEditedDateField: config.lastEditedDateField || '',
eventNameField: config.eventNameField || '',
userIdField: config.userIdField || '',
usernameField: config.usernameField || '',
userDisplayNameField: config.userDisplayNameField || '',
deviceIdField: config.deviceIdField || '',
createdAtField: config.createdAtField || '',
lastModifiedField: config.lastModifiedField || '',
geometryType: config.geometryType || ''
});
console.log('Form reloaded with server config:', config);
}
},
error: error => {
console.error('Failed to reload config from server:', error);
}
});
}

handleEventResults(x: MageEvent[]) {
this.events = x
}

onDeleteLayer(layerUrl: string) {
let index = 0;
for (const featureServiceConfig of this.config.featureServices) {
Expand All @@ -96,11 +197,6 @@ export class ArcAdminComponent implements OnInit {
this.dialog.open<unknown, unknown, string>(this.editProcessingTemplate)
}

onEditAttributes() {
this.editConfig = this.copyConfig()
this.dialog.open<unknown, unknown, string>(this.editAttributesTemplate)
}

setField(field: string, value: any) {
if (value != undefined && value.length == 0) {
value = undefined
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<div class="arc-event">
<mat-card appearance="outlined">
<mat-card-header>
<mat-card-title>
Events
</mat-card-title>
<mat-card-subtitle>Change the ArcGIS layers each MAGE event sends its observations to.</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<section class="arc-event-sync">
<header>
<h2>Events</h2>
<p class="subheading">Change the ArcGIS layers each MAGE event sends its observations to.</p>
</header>
<div class="arcEvents" *ngIf="!model.events.length">
<div class="arcEvent">
There are no events synchronizing to ArcGIS layers.
Expand Down Expand Up @@ -32,7 +36,9 @@ <h2>Events</h2>
</ng-container>
</div>
</section>
</div>
</mat-card-content>
</mat-card>

<ng-template #editEventDialog let-data>
<h2 matDialogTitle>ArcGIS layers that MAGE event named {{currentEditingEvent.name}} is synchronizing</h2>
<mat-dialog-content>
Expand All @@ -48,4 +54,5 @@ <h2 matDialogTitle>ArcGIS layers that MAGE event named {{currentEditingEvent.nam
<button mat-flat-button color="primary" matDialogClose
(click)="saveChanges()">SAVE</button>
</mat-dialog-actions>
</ng-template>
</ng-template>
</div>
Original file line number Diff line number Diff line change
@@ -1,29 +1,40 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { MatDialogRef } from '@angular/material/dialog';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { HttpClientModule } from '@angular/common/http';
import { MatDialogModule } from '@angular/material/dialog';
import { ArcLayerDeleteDialogComponent } from './arc-layer-delete-dialog.component';
import { ArcService } from '../arc.service'

describe('Arc Layer Delete Dialog', () => {
let component: ArcLayerDeleteDialogComponent;
let fixture: ComponentFixture<ArcLayerDeleteDialogComponent>;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HttpClientModule, MatDialogModule],
declarations: [ArcLayerDeleteDialogComponent],
imports: [HttpClientTestingModule],
providers: [{
provide: MatDialogRef,
useValue: {}
},]
providers: [
{
provide: MatDialogRef,
useValue: {
close: jasmine.createSpy('close')
}
},
{
provide: MAT_DIALOG_DATA,
useValue: {}
},
ArcService
]
}).compileComponents();
}));
});

beforeEach(() => {
fixture = TestBed.createComponent(ArcLayerDeleteDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


it('should create', () => {
expect(component).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,40 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { MatDialogRef } from '@angular/material/dialog';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { HttpClientModule } from '@angular/common/http';
import { MatDialogModule } from '@angular/material/dialog';
import { ArcLayerDialogComponent } from './arc-layer-dialog.component';
import { ArcService } from '../arc.service';

describe('Arc Layer Dialog', () => {
let component: ArcLayerDialogComponent;
let fixture: ComponentFixture<ArcLayerDialogComponent>;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HttpClientModule, MatDialogModule],
declarations: [ArcLayerDialogComponent],
imports: [HttpClientTestingModule],
providers: [{
provide: MatDialogRef,
useValue: {}
},]
providers: [
{
provide: MatDialogRef,
useValue: {
close: jasmine.createSpy('close')
}
},
{
provide: MAT_DIALOG_DATA,
useValue: {}
},
ArcService
]
}).compileComponents();
}));
});

beforeEach(() => {
fixture = TestBed.createComponent(ArcLayerDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


it('should create', () => {
expect(component).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div class="arc-layer">
<mat-card appearance="outlined">
<section class="arc-service">
<header>
<h2>Feature Layers</h2>
Expand Down Expand Up @@ -34,4 +35,5 @@ <h2>Feature Layers</h2>
</div>
</div>
</section>
</mat-card>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,8 @@ section {
height: inherit;
line-height: inherit;
width: inherit;
}
}

mat-card {
margin-bottom: 16px;
}
Loading

0 comments on commit 1766fc9

Please sign in to comment.