Skip to content

Commit 9c5fbd0

Browse files
authored
Merge pull request #173 from CloudInn/edit-view-options
Add option to open edit screen in an iframe pop up
2 parents 6fcfa00 + 85304dd commit 9c5fbd0

File tree

4 files changed

+59
-24
lines changed

4 files changed

+59
-24
lines changed

projects/crud/src/lib/components/listing/listing.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ <h2 mat-dialog-title style="padding:10px;" class="separated" *ngIf="viewConfig.d
9393
{{ column.header }}
9494
</mat-header-cell>
9595
<mat-cell *matCellDef="let row">
96-
<span #customElement></span>
96+
<span #customElement></span>
9797
</mat-cell>
9898
</ng-container>
9999

@@ -105,7 +105,7 @@ <h2 mat-dialog-title style="padding:10px;" class="separated" *ngIf="viewConfig.d
105105
<mat-cell id="{{'cell-'+i}}" *matCellDef="let row"
106106
[ngStyle]="column.cellStyle? column.cellStyle[column.cell(row)]: {}">
107107
<ng-container #normal>
108-
<a class="clickable" [routerLink]="row?.id"
108+
<a class="clickable" (click)="openEditView(row?.id)"
109109
*ngIf="(mode !== 'pick' && column.clickable); else normalCell">
110110
<ng-container *ngIf="(isString(column.cell(row)) && column?.isTranslated); else otherTypes">
111111
{{ column.cell(row) | translate }}
@@ -165,5 +165,5 @@ <h2 mat-dialog-title style="padding:10px;" class="separated" *ngIf="viewConfig.d
165165
(page)="onChange($event)">
166166
</mat-paginator>
167167
<ng-container *ngIf="openComponent">
168-
<div #customComponent></div>
168+
<div #customComponent></div>
169169
</ng-container>

projects/crud/src/lib/components/listing/listing.component.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import { MatTableDataSource } from '@angular/material/table';
99

1010
import { ApiService } from '../../services/api.service';
11-
import { ListViewer } from '../../models/views';
11+
import { IFrameMode, ListViewer } from '../../models/views';
1212
import { HttpParams, HttpErrorResponse } from '@angular/common/http';
1313
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
1414
import { MatPaginator, PageEvent } from '@angular/material/paginator';
@@ -17,6 +17,7 @@ import { IframeModalComponent } from '../iframe-modal/iframe-modal.component';
1717
import { CustomEncoder } from '../../custom-encode';
1818
import { SearchDialogComponent } from '../../containers/search-dialog/search-dialog.component';
1919
import { ListingDialogComponent } from '../../containers/listing-dialog/listing-dialog.component';
20+
import { ActivatedRoute, Router } from '@angular/router';
2021

2122
@Component({
2223
selector: 'ng-crud-listing',
@@ -52,7 +53,10 @@ export class ListingComponent implements OnInit, AfterViewInit {
5253
private viewContainerRef: ViewContainerRef,
5354
private dialog: MatDialog,
5455
private resolver: ComponentFactoryResolver,
55-
private listingDialogRef: MatDialogRef<ListingDialogComponent>) { }
56+
private listingDialogRef: MatDialogRef<ListingDialogComponent>,
57+
private router: Router,
58+
private activeRoute: ActivatedRoute
59+
) { }
5660

5761
ngOnInit() {
5862
if (this.viewConfig.pagination.enabled) {
@@ -177,8 +181,8 @@ export class ListingComponent implements OnInit, AfterViewInit {
177181
this.searchParams = this.searchParams.append('sort[]', this.viewConfig.metadata.sortBy);
178182
}
179183
const foreignKeyMultipleFields = this.viewConfig.metadata.fields.filter(f => f.keyOnSearch).map(f => f.name);
180-
if (defaultFilter && defaultFilter.length > 0) {
181-
defaultFilter.forEach(f => {
184+
if (defaultFilter && defaultFilter.length > 0) {
185+
defaultFilter.forEach(f => {
182186
this.defaultFilters[f.filter] = f.value;
183187
if (f.value && f.value !== '') {
184188
if (f.value.id) {
@@ -214,17 +218,34 @@ export class ListingComponent implements OnInit, AfterViewInit {
214218
}
215219
}
216220

221+
openEditView(id: number): void {
222+
if (this.viewConfig.iframeMode === IFrameMode.POP_UP) {
223+
const src = `${this.viewConfig.external_link.link}` + `${id}/?` + `${this.viewConfig.external_link.params.join('&')}`;
224+
this.dialog.open(IframeModalComponent, {
225+
height: '95vh',
226+
width: '100vw',
227+
data: {
228+
'src': `${src}`,
229+
'title': this.viewConfig?.title,
230+
'color': 'grey'
231+
}
232+
});
233+
} else {
234+
this.router.navigate([id], { relativeTo: this.activeRoute });
235+
}
236+
}
237+
217238
fetch() {
218239
this.api.fetch(this.viewConfig.metadata.api, this.searchParams).subscribe(res => {
219240
let newItems = [];
220241
if (this.viewConfig.pagination.enabled) {
221-
const keys = this.viewConfig.search.search_key;
222-
let value = res.results ? res.results[keys[0]] : res[keys[0]];
223-
for (let i = 1; i < keys.length; i++) {
224-
value = value[keys[i]];
225-
}
226-
newItems = value;
227-
this.resultsCount = res.count;
242+
const keys = this.viewConfig.search.search_key;
243+
let value = res.results ? res.results[keys[0]] : res[keys[0]];
244+
for (let i = 1; i < keys.length; i++) {
245+
value = value[keys[i]];
246+
}
247+
newItems = value;
248+
this.resultsCount = res.count;
228249
} else {
229250
newItems = res;
230251
this.resultsCount = newItems.length;
@@ -249,7 +270,7 @@ export class ListingComponent implements OnInit, AfterViewInit {
249270
}
250271

251272
addCustomElementColumnsToTemplate(): void {
252-
const customElementField = this.viewConfig.metadata.fields.find(f => f.type === 'custom_element');
273+
const customElementField = this.viewConfig.metadata.fields.find(f => f.type === 'custom_element');
253274
this.customElement?.changes.subscribe(element => {
254275
element.forEach((item, index) => {
255276
this.viewContainerRef.clear();

projects/crud/src/lib/components/model-form/model-form.component.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { CustomDateAdapter, MY_FORMATS } from '../../custom-date-adapter';
2626
providers: [
2727
{ provide: DateAdapter, useClass: CustomDateAdapter },
2828
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS }
29-
]
29+
]
3030
})
3131
export class ModelFormComponent implements OnInit, OnDestroy {
3232

@@ -98,7 +98,7 @@ export class ModelFormComponent implements OnInit, OnDestroy {
9898
}
9999

100100
appendIframeSrc(id?) {
101-
this.iframeSrc = `${this.viewConfig.external_link.link}` + `${this.id}/?` + `${this.viewConfig.external_link.params.join('&')}`;
101+
this.iframeSrc = `${this.viewConfig.external_link.link}` + `${this.id}/?` + `${this.viewConfig.external_link.params.join('&')}`;
102102
}
103103

104104
toggleExpansion() {
@@ -112,6 +112,8 @@ export class ModelFormComponent implements OnInit, OnDestroy {
112112
this.iframeModal.close();
113113
this.editForm(this.id);
114114
}
115+
} else if (typeof message.data === 'string' && message.data?.includes('refreshForm')) {
116+
this._submitSearchFormWithFilters();
115117
}
116118
});
117119
}
@@ -347,19 +349,23 @@ export class ModelFormComponent implements OnInit, OnDestroy {
347349
this.displayError(error.error);
348350
});
349351
} else {
350-
this.initialLoading = false;
352+
this._submitSearchFormWithFilters();
353+
}
354+
} else {
355+
this.initialLoading = false;
356+
this.getFormErrors();
357+
}
358+
}
359+
360+
private _submitSearchFormWithFilters(): void {
361+
this.initialLoading = false;
351362
const contains_ctrl = this.viewConfig.controls.filter(ctrl => ctrl.iContains);
352363
this.viewConfig.controls.forEach(ctrl => {
353364
if (ctrl.showInListing === false && this.formGroup.value.hasOwnProperty(ctrl.name)) {
354365
delete this.formGroup.value[ctrl.name];
355366
}
356367
});
357368
this.submit.emit({ ...this.formGroup.value, iContains: contains_ctrl });
358-
}
359-
} else {
360-
this.initialLoading = false;
361-
this.getFormErrors();
362-
}
363369
}
364370

365371
changeFieldsBeforeSending() {

projects/crud/src/lib/models/views.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Type, Optional } from '@angular/core';
1+
import { Type } from '@angular/core';
22
import { ListingComponent } from '../components/listing/listing.component';
33
import { ModelFormComponent } from '../components/model-form/model-form.component';
44
import { Metadata, FieldConfig } from './metadata';
@@ -8,6 +8,7 @@ export interface ViewConfig {
88
breadcrumbs: any[];
99
metadata: Metadata;
1010
component: Type<any>;
11+
iframeMode?: IFrameMode;
1112
}
1213

1314
export interface ListViewer extends ViewConfig {
@@ -51,6 +52,11 @@ export interface IframeOptions {
5152
};
5253
viewMode: string;
5354
}
55+
56+
export enum IFrameMode {
57+
POP_UP = 'pop_up',
58+
NEW_PAGE = 'new_page'
59+
}
5460
export class FormView implements FormViewer {
5561
title = this.metadata.label;
5662
breadcrumbs = [];
@@ -90,6 +96,7 @@ export interface ViewSettingsObj {
9096
enabled: boolean,
9197
pageSize: number,
9298
};
99+
iframeMode?: IFrameMode;
93100
}
94101

95102
export class ListingView implements ListViewer {
@@ -113,6 +120,7 @@ export class ListingView implements ListViewer {
113120
pageSize: 0
114121
};
115122
defaults = {};
123+
iframeMode = this.viewSettings.iframeMode;
116124
constructor(
117125
public metadata: Metadata,
118126
public viewSettings: ViewSettingsObj) {

0 commit comments

Comments
 (0)