packages/data/src/lib/entry-pop/entry-pop.component.ts
Entry Pop is an extension of Pop component to host an entry-form.
You can use it like a normal pop but with the extra handling of an entry form inside.
You can call edit with an entry object to edit an entry, or just call show.
It is also possible to bind an entry directly which will then be bound to the form.
changeDetection | ChangeDetectionStrategy.OnPush |
selector | ec-entry-pop |
styleUrls | ./entry-pop.component.scss |
templateUrl | ./entry-pop.component.html |
Properties |
|
Methods |
|
Inputs |
Outputs |
HostBindings |
HostListeners |
constructor(popService: PopService, auth: AuthService, formService: FormService, symbol: SymbolService, elementRef: ElementRef, cdr: ChangeDetectorRef)
|
|||||||||||||||||||||
Parameters :
|
config | |
Type : CrudConfig<EntryResource>
|
|
Default value : {}
|
|
CrudConfig for customizing the entry-form and the pop. |
createRoute | |
Type : string
|
|
Route that should be headed to when an entry is created. |
editRoute | |
Type : string
|
|
Route that should be headed to when an entry is edited. Navigates to route/:entryID |
entry | |
Type : EntryResource
|
|
The entry that should be used in the form. Is also set by edit. |
model | |
Type : string
|
|
The model that should be edited/created |
active | |
Type : boolean
|
|
Inherited from
PopComponent
|
|
Defined in
PopComponent:28
|
|
If true, .ec-pop is part of the DOM (*ngIf) + .active is set on .ec-pop-container. |
hideOnClickOutside | |
Default value : false
|
|
Inherited from
PopComponent
|
|
Defined in
PopComponent:34
|
|
If set to true, the pop will hide when a click happens outside the pop. |
hideOnEscape | |
Default value : true
|
|
Inherited from
PopComponent
|
|
Defined in
PopComponent:36
|
|
If set to false, esc will not close the pop |
type | |
Type : string
|
|
Inherited from
PopComponent
|
|
Defined in
PopComponent:32
|
|
The used type on the host element |
deleted | |
Type : EventEmitter<Form<EntryResource>>
|
|
Emits when the resource has been deleted. |
submitted | |
Type : EventEmitter<Form<EntryResource>>
|
|
Emits when the entry-form is submitted. |
toggle | |
Type : EventEmitter<boolean>
|
|
Inherited from
PopComponent
|
|
Defined in
PopComponent:38
|
class |
Default value : 'ec-entry-pop modal-wrapper modal-wrapper_backdrop'
|
Set host class to make sure the type is used |
document:click |
Arguments : '$event'
|
document:click($event)
|
Inherited from
PopComponent
|
Defined in
PopComponent:43
|
Listens for document:click and hides |
create |
create()
|
Opens the pop after deleting the current bound entry from the instance.
Returns :
void
|
Public deletedEntry |
deletedEntry()
|
Fires when the resource has been deleted.
Returns :
void
|
edit | ||||||
edit(entry: EntryResource)
|
||||||
Edit the given entry.
Parameters :
Returns :
void
|
editEntry | ||||||
editEntry(resource: EntryResource)
|
||||||
Parameters :
Returns :
Promise<EntryResource>
|
escapeRegExp | ||||
escapeRegExp(str)
|
||||
escapes the given string to be usable in a regex
Parameters :
Returns :
any
|
formSubmitted | ||||||
formSubmitted(form: Form
|
||||||
Called when the form has been submitted and saved
Parameters :
Returns :
void
|
getHeader | ||||
getHeader(form)
|
||||
Returns header for current form
Parameters :
Returns :
any
|
Public hasMethod | ||||||
hasMethod(method: string)
|
||||||
Returns true if the given method is part of the methods array (or if there is no methods array)
Parameters :
Returns :
boolean
|
Public log | ||||
log(form)
|
||||
Logs the current form (Developer help).
Parameters :
Returns :
void
|
Public maySave | ||||||
maySave(form: EntryFormComponent)
|
||||||
Determines if the current form can be saved, based on the allowed method (edit/update).
Parameters :
Returns :
boolean
|
ngOnInit |
ngOnInit()
|
Initialize the allowed methods to determine which buttons should be shown.
Returns :
void
|
pathRegExp | ||||
pathRegExp(path)
|
||||
Parameters :
Returns :
any
|
Public hide |
hide()
|
Inherited from
PopComponent
|
Defined in
PopComponent:88
|
Hides the pop. Sets active false and removes pop from popService.stack
Returns :
void
|
isOutside | ||||
isOutside(element)
|
||||
Inherited from
PopComponent
|
||||
Defined in
PopComponent:58
|
||||
yields true if the given element is outside the pop / or is the wrapper element itself (the backdrop)
Parameters :
Returns :
boolean
|
Public show | ||||
show(e?)
|
||||
Inherited from
PopComponent
|
||||
Defined in
PopComponent:72
|
||||
Shows the pop. Sets active true and adds pop to popService.stack
Parameters :
Returns :
void
|
Public toggle | ||||
toggle(e?)
|
||||
Inherited from
PopComponent
|
||||
Defined in
PopComponent:63
|
||||
Shows if not active, hides if active.
Parameters :
Returns :
void
|
Public auth |
Type : AuthService
|
Public cdr |
Type : ChangeDetectorRef
|
Public elementRef |
Type : ElementRef
|
form |
Type : EntryFormComponent
|
Decorators :
@ViewChild(EntryFormComponent)
|
The entry form inside the view |
Public formService |
Type : FormService
|
Public popService |
Type : PopService
|
Public symbol |
Type : SymbolService
|
activated |
Default value : false
|
Inherited from
PopComponent
|
Defined in
PopComponent:30
|
Flip and stays true after first show |
clickEvent |
Inherited from
PopComponent
|
Defined in
PopComponent:40
|
Public elementRef |
Type : ElementRef
|
Inherited from
PopComponent
|
Defined in
PopComponent:55
|
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostBinding,
Input,
OnInit,
Output,
ViewChild,
} from '@angular/core';
import { Form } from '@ec.components/core';
import { FormService, PopComponent, PopService, SymbolService } from '@ec.components/ui';
import EntryResource from 'ec.sdk/lib/resources/publicAPI/EntryResource';
import { AuthService } from '../auth/auth.service';
import { CrudConfig } from '../crud/crud-config.interface';
import { EntryFormComponent } from '../entry-form/entry-form.component';
/** Entry Pop is an extension of Pop component to host an entry-form.
* You can use it like a normal pop but with the extra handling of an entry form inside.
* You can call edit with an entry object to edit an entry, or just call show.
* It is also possible to bind an entry directly which will then be bound to the form.
* <example-url>https://components.entrecode.de/entries/entry-pop/muffin/create?e=1</example-url>
* */
@Component({
selector: 'ec-entry-pop',
templateUrl: './entry-pop.component.html',
styleUrls: ['./entry-pop.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EntryPopComponent extends PopComponent implements OnInit {
/** CrudConfig for customizing the entry-form and the pop.*/
@Input() config: CrudConfig<EntryResource> = {};
/** The entry form inside the view */
@ViewChild(EntryFormComponent) form: EntryFormComponent;
/** The model that should be edited/created*/
@Input() model: string;
/** The entry that should be used in the form. Is also set by edit.*/
@Input() entry: EntryResource;
/** Route that should be headed to when an entry is edited. Navigates to route/:entryID */
@Input() editRoute: string;
/** Route that should be headed to when an entry is created. */
@Input() createRoute: string;
/** Emits when the entry-form is submitted. */
@Output() submitted: EventEmitter<Form<EntryResource>> = new EventEmitter();
/** Emits when the resource has been deleted. */
@Output() deleted: EventEmitter<Form<EntryResource>> = new EventEmitter();
/** Set host class to make sure the type is used */
@HostBinding('class') class = 'ec-entry-pop modal-wrapper modal-wrapper_backdrop';
constructor(
public popService: PopService,
public auth: AuthService,
public formService: FormService,
public symbol: SymbolService,
public elementRef: ElementRef,
public cdr: ChangeDetectorRef,
) {
super(popService, elementRef, cdr);
}
/** Returns true if the given method is part of the methods array (or if there is no methods array) */
public hasMethod(method: string) {
return this.config.methods && this.config.methods.indexOf(method) !== -1;
}
/** Determines if the current form can be saved, based on the allowed method (edit/update). */
public maySave(form: EntryFormComponent) {
const edit = form.isEditing();
return (!edit && this.hasMethod('post')) || (edit && this.hasMethod('put'));
}
/* public getUrlUntil(url: string, stop: string[]): string {
const parts = url.split('/');
return parts.reduce((state, part) => {
if (state.done || [this.editRoute, this.createRoute].includes(part)) {
state.done = true;
return state;
}
state.url += part;
return state;
}, { url: '', done: false }).url;
} */
/** escapes the given string to be usable in a regex */
escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}
pathRegExp(path) {
return path
.split('/')
.map((subpath) => this.escapeRegExp(subpath))
.join('/');
}
/** Edit the given entry. */
edit(entry: EntryResource) {
if (this.editRoute) {
// TODO: find solution for automatic routing
/* const matcher = '(' + this.pathRegExp(this.editRoute) + '|' + this.pathRegExp(this.createRoute) + ').*';
const trimmed = this.router.url.replace(new RegExp(matcher, 'g'), '');
this.router.navigate([trimmed, this.editRoute, entry.id]); */
}
this.editEntry(entry).then((preparedEntry: EntryResource) => {
this.entry = preparedEntry;
this.show();
});
}
editEntry(resource: EntryResource): Promise<EntryResource> {
if (this.config && this.config.onEdit) {
return Promise.resolve(this.config.onEdit(resource));
}
return Promise.resolve(resource);
}
/** Opens the pop after deleting the current bound entry from the instance. */
create() {
delete this.entry;
/* if (this.createRoute) {
const matcher = '(' + this.pathRegExp(this.editRoute) + '|' + this.pathRegExp(this.createRoute) + ').*';
const trimmed = this.router.url.replace(new RegExp(matcher, 'g'), '');
this.router.navigate([trimmed, this.createRoute]);
} */
if (this.form) {
// clears form if already used before
this.form.create();
}
this.show();
}
/** Initialize the allowed methods to determine which buttons should be shown. */
ngOnInit() {
this.auth.getAllowedModelMethods(this.model, this.config.methods).then((methods) => {
this.cdr.markForCheck();
this.config.methods = methods;
});
}
/** Logs the current form (Developer help). */
public log(form) {
console.dir(form);
}
/** Called when the form has been submitted and saved */
formSubmitted(form: Form<EntryResource>) {
this.submitted.next(form);
if (!this.config.keepPopOpen) {
this.hide();
}
}
/** Fires when the resource has been deleted. */
public deletedEntry() {
this.hide();
this.deleted.emit(this.form.form);
}
/** Returns header for current form */
getHeader(form) {
const label = this.config.singularLabel || form.model;
return this.formService.getFormLabel(form, label);
}
}
<div class="modal" *ngIf="active" [attr.data-col]="config?.popColumns || popService.defaultColumns">
<button (click)="hide()" type="button" class="modal__dismiss">
<ec-icon name="close"></ec-icon>
</button>
<div class="modal__header">
{{ getHeader(crudForm) }}
</div>
<div class="modal__body">
<ec-entry-form
[model]="model"
[submitButton]="false"
[loader]="popLoader"
[config]="config"
(submitted)="formSubmitted($event)"
[entry]="entry"
(deleted)="hide()"
#crudForm
></ec-entry-form>
</div>
<footer class="modal__footer">
<ul class="nav">
<li class="nav__item" *ngIf="config?.develop">
<!--TODO placeholder config for 'code'-->
<button (click)="log(crudForm)" class="btn btn_square">
<ec-icon name="code"></ec-icon>
</button>
</li>
<li class="nav__item" *ngIf="hasMethod('delete') && crudForm.isEditing()">
<!--TODO placeholder config for 'löschen'-->
<button (click)="delete.confirm(entry)" class="btn ec-btn_delete" type="button">
<span>delete</span>
</button>
</li>
<li class="nav__item" *ngIf="maySave(crudForm)">
<!--TODO placeholder config for 'speichern'-->
<button
(click)="crudForm.submit()"
[disabled]="crudForm.group?.invalid"
type="button"
class="btn ec-btn_save"
[class.is-disabled]="crudForm.group?.invalid"
>
<span>save</span>
</button>
</li>
</ul>
</footer>
<ec-loader #popLoader class="ec-loader loader is-global"></ec-loader>
<ec-resource-delete-pop (deleted)="deletedEntry()" [relation]="'model.' + model" #delete></ec-resource-delete-pop>
</div>
./entry-pop.component.scss
:host {
align-items: flex-start;
}