File

packages/data/src/lib/entry-pop/entry-pop.component.ts

Description

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. https://components.entrecode.de/entries/entry-pop/muffin/create?e=1

Extends

PopComponent

Implements

OnInit

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector ec-entry-pop
styleUrls ./entry-pop.component.scss
templateUrl ./entry-pop.component.html

Index

Properties
Methods
Inputs
Outputs
HostBindings
HostListeners

Constructor

constructor(popService: PopService, auth: AuthService, formService: FormService, symbol: SymbolService, elementRef: ElementRef, cdr: ChangeDetectorRef)
Parameters :
Name Type Optional
popService PopService No
auth AuthService No
formService FormService No
symbol SymbolService No
elementRef ElementRef No
cdr ChangeDetectorRef No

Inputs

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

Outputs

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

HostBindings

class
Default value : 'ec-entry-pop modal-wrapper modal-wrapper_backdrop'

Set host class to make sure the type is used

HostListeners

document:click
Arguments : '$event'
document:click($event)
Inherited from PopComponent
Defined in PopComponent:43

Listens for document:click and hides

Methods

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 :
Name Type Optional
entry EntryResource No
Returns : void
editEntry
editEntry(resource: EntryResource)
Parameters :
Name Type Optional
resource EntryResource No
Returns : Promise<EntryResource>
escapeRegExp
escapeRegExp(str)

escapes the given string to be usable in a regex

Parameters :
Name Optional
str No
Returns : any
formSubmitted
formSubmitted(form: Form)

Called when the form has been submitted and saved

Parameters :
Name Type Optional
form Form<EntryResource> No
Returns : void
getHeader
getHeader(form)

Returns header for current form

Parameters :
Name Optional
form No
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 :
Name Type Optional
method string No
Returns : boolean
Public log
log(form)

Logs the current form (Developer help).

Parameters :
Name Optional
form No
Returns : void
Public maySave
maySave(form: EntryFormComponent)

Determines if the current form can be saved, based on the allowed method (edit/update).

Parameters :
Name Type Optional
form EntryFormComponent No
Returns : boolean
ngOnInit
ngOnInit()

Initialize the allowed methods to determine which buttons should be shown.

Returns : void
pathRegExp
pathRegExp(path)
Parameters :
Name Optional
path No
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 :
Name Optional
element No
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 :
Name Optional
e Yes
Returns : void
Public toggle
toggle(e?)
Inherited from PopComponent
Defined in PopComponent:63

Shows if not active, hides if active.

Parameters :
Name Optional
e Yes
Returns : void

Properties

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;
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""