11import { Component , Input , Output , EventEmitter } from '@angular/core' ;
22import { MatDialog } from '@angular/material/dialog' ;
33import { CdkDragDrop , moveItemInArray } from '@angular/cdk/drag-drop' ;
4- import { Field } from '../form-details /observation-feed-helper' ;
4+ import { Field } from '../../helpers /observation-feed-helper' ;
55import { FieldDialogComponent , FieldDialogData } from '../form-details/field-dialog/field-dialog.component' ;
6- import { CoreModule } from "admin/src/app/core/core.module" ;
76
87export 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 - z 0 - 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 }
0 commit comments