Skip to content

Commit 26b856f

Browse files
committed
fix map symbology and clean up
1 parent 510c945 commit 26b856f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+650
-3428
lines changed

web-app/admin/src/app/admin/admin-event/admin-event-form/admin-event-form.module.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import { MatTabsModule } from '@angular/material/tabs';
99
import { MatCardModule } from '@angular/material/card';
1010
import { MatIconModule } from '@angular/material/icon';
1111
import { MatTooltipModule } from '@angular/material/tooltip';
12+
import { MatFormFieldModule } from '@angular/material/form-field';
13+
import { MatInputModule } from '@angular/material/input';
1214
import { CoreModule } from 'admin/src/app/core/core.module';
1315

1416
import { AdminEventFormPreviewComponent } from './admin-event-form-preview/admin-event-form-preview.component';
1517
import { AdminEventFormPreviewDialogComponent } from './admin-event-form-preview/form-preview-dialog/admin-event-form-preview-dialog.component';
1618
import { ObservationModule } from '../../../observation/observation.module';
1719
import { FormDetailsComponent } from './form-details/form-details.component';
1820
import { FieldDialogComponent } from './form-details/field-dialog/field-dialog.component';
21+
import { SymbologyDialogComponent } from './form-details/symbology-dialog/symbology-dialog.component';
1922
import { FieldsListComponent } from './fields-list/fields-list.component';
2023
import { AdminBreadcrumbModule } from '../../admin-breadcrumb/admin-breadcrumb.module';
2124

@@ -25,6 +28,7 @@ import { AdminBreadcrumbModule } from '../../admin-breadcrumb/admin-breadcrumb.m
2528
AdminEventFormPreviewDialogComponent,
2629
FormDetailsComponent,
2730
FieldDialogComponent,
31+
SymbologyDialogComponent,
2832
FieldsListComponent
2933
],
3034
imports: [
@@ -40,6 +44,8 @@ import { AdminBreadcrumbModule } from '../../admin-breadcrumb/admin-breadcrumb.m
4044
MatCardModule,
4145
MatIconModule,
4246
MatTooltipModule,
47+
MatFormFieldModule,
48+
MatInputModule,
4349
ObservationModule,
4450
AdminBreadcrumbModule
4551
],

web-app/admin/src/app/admin/admin-event/admin-event-form/fields-list/fields-list.component.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
<ng-template #itemTemplate let-field>
77
<div class="field-content-detailed">
88
<div class="field-header">
9-
<i class="fa {{ getFieldTypeIcon(field.type) }} field-icon"></i>
109
<h4 class="field-title">{{ field.title || 'No title set' }}</h4>
1110
</div>
1211
<div class="field-details">

web-app/admin/src/app/admin/admin-event/admin-event-form/fields-list/fields-list.component.ts

Lines changed: 1 addition & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { Component, Input, Output, EventEmitter } from '@angular/core';
22
import { MatDialog } from '@angular/material/dialog';
33
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
4-
import { Field } from '../form-details/observation-feed-helper';
4+
import { Field } from '../../helpers/observation-feed-helper';
55
import { FieldDialogComponent, FieldDialogData } from '../form-details/field-dialog/field-dialog.component';
6-
import { CoreModule } from "admin/src/app/core/core.module";
76

87
export interface FieldType {
98
name: string;
@@ -16,10 +15,6 @@ export interface AttachmentType {
1615
title: string;
1716
}
1817

19-
/**
20-
* Reusable component for managing form fields.
21-
* Can be used in both create form and edit form contexts.
22-
*/
2318
@Component({
2419
selector: 'mage-fields-list',
2520
templateUrl: './fields-list.component.html',
@@ -34,9 +29,6 @@ export class FieldsListComponent {
3429

3530
constructor(private dialog: MatDialog) { }
3631

37-
/**
38-
* Opens dialog to add a new field
39-
*/
4032
addField(): void {
4133
const dialogRef = this.dialog.open(FieldDialogComponent, {
4234
width: '600px',
@@ -49,7 +41,6 @@ export class FieldsListComponent {
4941

5042
dialogRef.afterClosed().subscribe((result: Field | undefined) => {
5143
if (result) {
52-
// Generate a unique field name
5344
const fieldName = result.title.toLowerCase().replace(/\s+/g, '_').replace(/[^a-z0-9_]/g, '');
5445
result.name = fieldName;
5546
result.id = this.getNextFieldId();
@@ -59,9 +50,6 @@ export class FieldsListComponent {
5950
});
6051
}
6152

62-
/**
63-
* Opens dialog to edit an existing field
64-
*/
6553
editField(field: Field): void {
6654
const dialogRef = this.dialog.open(FieldDialogComponent, {
6755
width: '600px',
@@ -76,16 +64,12 @@ export class FieldsListComponent {
7664

7765
dialogRef.afterClosed().subscribe((result: Field | undefined) => {
7866
if (result) {
79-
// Update the field in place
8067
Object.assign(field, result);
8168
this.fieldsChange.emit(this.fields);
8269
}
8370
});
8471
}
8572

86-
/**
87-
* Removes a field from the list (permanently deletes)
88-
*/
8973
removeField(field: Field): void {
9074
if (!this.canRemoveField()) {
9175
return;
@@ -97,117 +81,62 @@ export class FieldsListComponent {
9781
this.fieldsChange.emit(this.fields);
9882
}
9983

100-
/**
101-
* Checks if a field can be removed (must have at least one active field)
102-
*/
10384
canRemoveField(): boolean {
10485
return this.showDetailedView && this.getActiveFields().length > 1;
10586
}
10687

107-
/**
108-
* Moves a field up in the list
109-
*/
11088
moveFieldUp(field: Field): void {
11189
const activeFields = this.getActiveFields();
11290
const index = activeFields.findIndex(f => f.id === field.id);
11391
if (index > 0) {
114-
// Swap IDs to reorder
11592
const temp = activeFields[index].id;
11693
activeFields[index].id = activeFields[index - 1].id;
11794
activeFields[index - 1].id = temp;
11895
this.fieldsChange.emit(this.fields);
11996
}
12097
}
12198

122-
/**
123-
* Moves a field down in the list
124-
*/
12599
moveFieldDown(field: Field): void {
126100
const activeFields = this.getActiveFields();
127101
const index = activeFields.findIndex(f => f.id === field.id);
128102
if (index >= 0 && index < activeFields.length - 1) {
129-
// Swap IDs to reorder
130103
const temp = activeFields[index].id;
131104
activeFields[index].id = activeFields[index + 1].id;
132105
activeFields[index + 1].id = temp;
133106
this.fieldsChange.emit(this.fields);
134107
}
135108
}
136109

137-
/**
138-
* Handles drag and drop reordering
139-
*/
140110
onFieldDrop(event: CdkDragDrop<Field[]>): void {
141111
const activeFields = this.getActiveFields();
142112
moveItemInArray(activeFields, event.previousIndex, event.currentIndex);
143113

144-
// Update IDs to reflect new order
145114
activeFields.forEach((field, index) => {
146115
field.id = index;
147116
});
148117

149118
this.fieldsChange.emit(this.fields);
150119
}
151120

152-
/**
153-
* Handles items reordered from draggable-list component
154-
*/
155121
onItemsReordered(reorderedFields: Field[]): void {
156-
// Sync the reordered active fields back to the full fields array
157122
const archivedFields = this.fields.filter(f => f.archived);
158123
this.fields = [...reorderedFields, ...archivedFields];
159124
this.fieldsChange.emit(this.fields);
160125
}
161126

162-
/**
163-
* Gets the display label for a field type
164-
*/
165127
getFieldTypeLabel(type: string): string {
166128
const fieldType = this.fieldTypes.find(ft => ft.name === type);
167129
return fieldType?.title || type;
168130
}
169131

170-
/**
171-
* Gets the icon for a field type
172-
*/
173-
getFieldTypeIcon(type: string): string {
174-
const iconMap: { [key: string]: string } = {
175-
'textfield': 'fa-font',
176-
'textarea': 'fa-align-left',
177-
'numberfield': 'fa-hashtag',
178-
'email': 'fa-envelope',
179-
'password': 'fa-lock',
180-
'radio': 'fa-dot-circle-o',
181-
'dropdown': 'fa-caret-square-o-down',
182-
'multiselectdropdown': 'fa-list-ul',
183-
'date': 'fa-calendar',
184-
'datetime': 'fa-clock-o',
185-
'geometry': 'fa-map-marker',
186-
'attachment': 'fa-paperclip',
187-
'checkbox': 'fa-check-square-o',
188-
'userDropdown': 'fa-user',
189-
'multiSelectUserDropdown': 'fa-users'
190-
};
191-
return iconMap[type] || 'fa-file-text-o';
192-
}
193-
194-
/**
195-
* Gets active (non-archived) fields
196-
*/
197132
getActiveFields(): Field[] {
198133
return this.fields.filter(f => !f.archived);
199134
}
200135

201-
/**
202-
* Checks if field type has options/choices
203-
*/
204136
showAddOptions(field: Field): boolean {
205137
return field.type === 'radio' || field.type === 'dropdown' || field.type === 'multiselectdropdown';
206138
}
207139

208-
/**
209-
* Gets display string for allowed attachment types
210-
*/
211140
getAttachmentTypesDisplay(field: Field): string {
212141
if (!field.allowedAttachmentTypes || field.allowedAttachmentTypes.length === 0) {
213142
return 'All types';
@@ -220,24 +149,15 @@ export class FieldsListComponent {
220149
.join(', ');
221150
}
222151

223-
/**
224-
* Checks if a field is a member/user field
225-
*/
226152
isMemberField(field: Field): boolean {
227153
return field.type === 'userDropdown' || field.type === 'multiSelectUserDropdown';
228154
}
229155

230-
/**
231-
* Gets the next available field ID
232-
*/
233156
private getNextFieldId(): number {
234157
if (this.fields.length === 0) return 0;
235158
return Math.max(...this.fields.map(f => f.id || 0)) + 1;
236159
}
237160

238-
/**
239-
* TrackBy function for ngFor optimization
240-
*/
241161
trackByFieldId(index: number, field: Field): any {
242162
return field.id;
243163
}

web-app/admin/src/app/admin/admin-event/admin-event-form/form-details/field-dialog/field-dialog.component.html

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
77
<strong>Field Type</strong>
88
</div>
99
<div class="config-inline-control">
10-
<select class="form-input" [(ngModel)]="field.type" name="fieldType" [disabled]="isEditMode">
10+
<select class="form-input" [(ngModel)]="field.type" name="fieldType">
1111
<option *ngFor="let type of data.fieldTypes" [value]="type.name">
1212
{{ type.title }}
1313
</option>
@@ -28,7 +28,22 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
2828
</div>
2929
</div>
3030

31-
<!-- Attachment Field Configuration -->
31+
<div *ngIf="field.type === 'dropdown' && !data.isMemberField" class="checkbox-section">
32+
<label class="checkbox-label">
33+
<input type="checkbox" [(ngModel)]="field.multiselect" name="fieldMultiselect">
34+
<span>Allow Multiple Selections</span>
35+
</label>
36+
<p class="field-hint">Allow users to select multiple options from the list.</p>
37+
</div>
38+
39+
<div *ngIf="field.type === 'userDropdown'" class="checkbox-section">
40+
<label class="checkbox-label">
41+
<input type="checkbox" [(ngModel)]="field.multiselect" name="fieldMultiselectUser">
42+
<span>Allow Multiple Selections</span>
43+
</label>
44+
<p class="field-hint">Allow users to select multiple users from the list.</p>
45+
</div>
46+
3247
<div *ngIf="field.type === 'attachment'">
3348
<div class="config-inline-item">
3449
<div class="config-inline-label">
@@ -77,7 +92,6 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
7792
</div>
7893
</div>
7994

80-
<!-- Number Field Configuration -->
8195
<div *ngIf="field.type === 'numberfield'">
8296
<div class="config-inline-item">
8397
<div class="config-inline-label">
@@ -110,7 +124,6 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
110124
</div>
111125
</div>
112126

113-
<!-- Default Value for Text Fields -->
114127
<div *ngIf="field.type === 'textfield' || field.type === 'email' || field.type === 'hidden'"
115128
class="config-inline-item">
116129
<div class="config-inline-label">
@@ -122,7 +135,6 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
122135
</div>
123136
</div>
124137

125-
<!-- Default Value for Text Area -->
126138
<div *ngIf="field.type === 'textarea'" class="config-inline-item">
127139
<div class="config-inline-label">
128140
<strong>Default Value</strong>
@@ -133,15 +145,13 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
133145
</div>
134146
</div>
135147

136-
<!-- Default Value for Checkbox -->
137148
<div *ngIf="field.type === 'checkbox'" class="checkbox-section">
138149
<label class="checkbox-label">
139150
<input type="checkbox" [(ngModel)]="field.value" name="fieldValue">
140151
<span>Default Value</span>
141152
</label>
142153
</div>
143154

144-
<!-- Field Options for Select/Radio Fields -->
145155
<div *ngIf="showAddOptions() && !data.isMemberField" class="config-inline-item">
146156
<div class="config-inline-label">
147157
<strong>Field Options</strong>
@@ -175,8 +185,7 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
175185
</div>
176186
</div>
177187

178-
<!-- Default Value for Dropdown (single select) -->
179-
<div *ngIf="field.type === 'dropdown' && !data.isMemberField" class="config-inline-item">
188+
<div *ngIf="field.type === 'dropdown' && !field.multiselect && !data.isMemberField" class="config-inline-item">
180189
<div class="config-inline-label">
181190
<strong>Default Value</strong>
182191
</div>
@@ -190,6 +199,21 @@ <h2 mat-dialog-title>{{ isEditMode ? 'Edit Field' : 'Add New Field' }}</h2>
190199
</div>
191200
</div>
192201

202+
<div *ngIf="field.type === 'dropdown' && field.multiselect && !data.isMemberField" class="config-inline-item">
203+
<div class="config-inline-label">
204+
<strong>Default Values</strong>
205+
</div>
206+
<div class="config-inline-control">
207+
<div class="checkbox-group">
208+
<label class="checkbox-label" *ngFor="let choice of field.choices">
209+
<input type="checkbox" [checked]="field.value && field.value.includes(choice.title)"
210+
(change)="toggleDefaultValue(choice.title, $any($event.target).checked)">
211+
<span>{{ choice.title }}</span>
212+
</label>
213+
</div>
214+
</div>
215+
</div>
216+
193217
<div class="checkbox-section"
194218
*ngIf="field.name !== 'timestamp' && field.name !== 'geometry' && field.type !== 'attachment'">
195219
<label class="checkbox-label">

0 commit comments

Comments
 (0)