Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AdminEventFormPreviewDialogComponent } from './admin-event-form-preview-dialog.component';
import { AdminEventFormPreviewDialogComponent } from './form-preview-dialog/admin-event-form-preview-dialog.component';

@Component({
selector: 'admin-event-form-preview',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AdminEventFormPreviewDialogComponent } from './admin-event-form-preview-dialog.component';

import { AdminEventFormPreviewComponent } from './admin-event-form-preview.component';
import { AdminEventFormPreviewComponent } from '../admin-event-form-preview.component';

describe('AdminEventFormPreviewComponent', () => {
let component: AdminEventFormPreviewDialogComponent
Expand All @@ -23,13 +23,13 @@ describe('AdminEventFormPreviewComponent', () => {
name: 'field1',
title: 'Field 1',
type: 'textfield'
},{
}, {
id: 3,
archived: false,
name: 'field3',
title: 'Field 3',
type: 'textfield'
},{
}, {
id: 2,
archived: false,
name: 'field2',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,59 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { MatDialogModule } from '@angular/material/dialog';
import { MatButtonModule } from '@angular/material/button';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { CoreModule } from 'admin/src/app/core/core.module';

import { AdminEventFormPreviewComponent } from './admin-event-form-preview/admin-event-form-preview.component';
import { AdminEventFormPreviewDialogComponent } from './admin-event-form-preview/admin-event-form-preview-dialog.component';
import { AdminEventFormPreviewDialogComponent } from './admin-event-form-preview/form-preview-dialog/admin-event-form-preview-dialog.component';
import { ObservationModule } from '../../../observation/observation.module';
import { FormDetailsComponent } from './form-details/form-details.component';
import { FieldDialogComponent } from './form-details/field-dialog/field-dialog.component';
import { SymbologyDialogComponent } from './form-details/symbology-dialog/symbology-dialog.component';
import { FieldsListComponent } from './fields-list/fields-list.component';
import { AdminBreadcrumbModule } from '../../admin-breadcrumb/admin-breadcrumb.module';

@NgModule({
declarations: [
AdminEventFormPreviewComponent,
AdminEventFormPreviewDialogComponent
AdminEventFormPreviewDialogComponent,
FormDetailsComponent,
FieldDialogComponent,
SymbologyDialogComponent,
FieldsListComponent
],
imports: [
CommonModule,
CoreModule,
FormsModule,
ReactiveFormsModule,
DragDropModule,
MatDialogModule,
MatButtonModule,
ObservationModule
MatSnackBarModule,
MatTabsModule,
MatCardModule,
MatIconModule,
MatTooltipModule,
MatFormFieldModule,
MatInputModule,
ObservationModule,
AdminBreadcrumbModule
],
exports: [
AdminEventFormPreviewComponent,
AdminEventFormPreviewDialogComponent
AdminEventFormPreviewDialogComponent,
FormDetailsComponent,
FieldsListComponent
]
})
export class AdminEventFormModule { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<div *ngIf="showDetailedView" class="fields-list-detailed">
<mage-draggable-list [items]="getActiveFields()" [enableDragDrop]="true"
[emptyMessage]="'No fields have been added yet.'" [emptyIcon]="'fa-file-text fa-3x'"
[trackByFunction]="trackByFieldId" (itemsChange)="onItemsReordered($event)">

<ng-template #itemTemplate let-field>
<div class="field-content-detailed">
<div class="field-header">
<h4 class="field-title">{{ field.title || 'No title set' }}</h4>
</div>
<div class="field-details">
<div class="field-row">
<span class="field-label">Type:</span>
<span class="field-value">{{ getFieldTypeLabel(field.type, field) }}</span>
<span class="field-label" *ngIf="field.required" style="margin-left: 1rem;">Required:</span>
<span class="field-value" *ngIf="field.required">Yes</span>
</div>
<div class="field-row"
*ngIf="field.value !== undefined && field.value !== null && field.value !== ''">
<span class="field-label">Default:</span>
<span class="field-value">{{ field.type === 'checkbox' ? (field.value ? 'Checked' :
'Unchecked') : field.value }}</span>
</div>
<div class="field-row"
*ngIf="field.type === 'numberfield' && (field.min !== undefined || field.max !== undefined)">
<span class="field-label">Range:</span>
<span class="field-value">
{{ field.min !== undefined ? field.min : '−∞' }} to {{ field.max !== undefined ? field.max :
'∞' }}
</span>
</div>
<div class="field-row"
*ngIf="field.type === 'attachment' && (field.min !== undefined || field.max !== undefined)">
<span class="field-label">Attachment Count:</span>
<span class="field-value">
{{ field.min !== undefined ? field.min : '0' }} to {{ field.max !== undefined ? field.max :
'∞' }}
</span>
</div>
<div class="field-row"
*ngIf="field.allowedAttachmentTypes && field.allowedAttachmentTypes.length > 0">
<span class="field-label">Allowed Types:</span>
<span class="field-value">{{ getAttachmentTypesDisplay(field) }}</span>
</div>
<div class="field-row" *ngIf="showAddOptions(field) && field.choices && field.choices.length > 0">
<span class="field-label">Options:</span>
<span class="field-value">{{ field.choices.length }} option{{ field.choices.length !== 1 ? 's' :
'' }}</span>
</div>
</div>
</div>
</ng-template>

<ng-template #itemActionsTemplate let-field>
<button mat-icon-button (click)="$event.stopPropagation(); editField(field)" matTooltip="Edit field"
matTooltipPosition="above">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="$event.stopPropagation(); removeField(field)"
[disabled]="!canRemoveField()"
[matTooltip]="canRemoveField() ? 'Delete field' : 'Cannot delete last field'"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</ng-template>
</mage-draggable-list>

<div class="section-save-actions">
<button type="button" class="action-button btn-primary" (click)="addField()">
<i class="fa fa-plus"></i>
Add Field
</button>
</div>
</div>

<div *ngIf="!showDetailedView" class="fields-list-compact">
<mage-draggable-list [items]="getActiveFields()" [enableDragDrop]="true" [emptyMessage]="'No fields added yet'"
[emptyIcon]="'fa-inbox'" [trackByFunction]="trackByFieldId" (itemsChange)="onItemsReordered($event)">

<ng-template #itemTemplate let-field>
<div class="field-content-compact">
<div class="field-info">
<div class="field-title">{{ field.title }}</div>
<div class="field-type">{{ getFieldTypeLabel(field.type, field) }}
<span *ngIf="field.required" class="required-badge">Required</span>
</div>
</div>
</div>
</ng-template>

<ng-template #itemActionsTemplate let-field>
<button mat-icon-button (click)="$event.stopPropagation(); editField(field)" matTooltip="Edit field"
matTooltipPosition="above">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="$event.stopPropagation(); removeField(field)"
[disabled]="!canRemoveField()"
[matTooltip]="canRemoveField() ? 'Delete field' : 'Cannot delete last field'"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</ng-template>
</mage-draggable-list>

<div class="section-save-actions">
<button type="button" class="action-button btn-primary" (click)="addField()">
<i class="fa fa-plus"></i>
Add Field
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
@import '../../event-styles';

.fields-list-detailed,
::ng-deep .cdk-drag-preview {
.field-content-detailed {
flex: 1;
min-width: 0;
}

.field-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.75rem;
}

.field-icon {
color: #999;
font-size: 1.25rem;
width: 1.25rem;
height: 1.25rem;
flex-shrink: 0;
}

.field-title {
margin: 0;
font-size: 1rem;
font-weight: 500;
color: #333;
line-height: 1.25rem;
}

.field-details {
display: flex;
flex-direction: column;
gap: 0.5rem;
}

.field-row {
display: flex;
align-items: center;
font-size: 0.875rem;
}

.field-label {
color: #666;
margin-right: 0.5rem;
}

.field-value {
color: #333;
font-weight: 500;
}
}

.fields-list-detailed {
.add-field-button-container {
display: flex;
justify-content: flex-start;
margin-top: 1.5rem;
}

.drag-handle {
cursor: move;
color: #9e9e9e;
margin-right: 8px;

&:hover {
color: #616161;
}
}

.form-actions {
display: flex;
gap: 8px;
align-items: center;

button {
display: flex;
align-items: center;
justify-content: center;

mat-icon {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
}
}
}
}

.fields-list-compact,
::ng-deep .cdk-drag-preview {
.field-content-compact {
display: flex;
align-items: center;
gap: 0.75rem;
flex: 1;
}

.field-icon {
color: #999;
font-size: 1rem;
}

.field-info {
display: flex;
flex-direction: column;
gap: 0.25rem;
}

.field-title {
font-size: 0.875rem;
font-weight: 500;
color: #333;
}

.field-type {
font-size: 0.8125rem;
color: #757575;
display: flex;
align-items: center;
gap: 0.5rem;
}

.required-badge {
display: inline-block;
padding: 0.125rem 0.375rem;
background-color: #ffebee;
color: #c62828;
border-radius: 3px;
font-size: 0.6875rem;
font-weight: 500;
text-transform: uppercase;
}
}

.fields-list-compact {
display: flex;
flex-direction: column;
gap: 1.25rem;

.add-field-button {
align-self: flex-start;
}

.action-button {
padding: 0.625rem 1.25rem;
font-size: 0.875rem;
font-weight: 500;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
display: inline-flex;
align-items: center;
gap: 0.5rem;

&.btn-primary {
background-color: #1976d2;
color: white;

&:hover {
background-color: #1565c0;
}
}

i {
font-size: 0.875rem;
}
}

.section-save-actions {
display: flex;
justify-content: flex-end;
gap: 0.75rem;
margin-top: 1.5rem;
padding-top: 1.5rem;
border-top: 1px solid #e5e7eb;
}
}
Loading