File

packages/data/src/lib/resource-pop/resource-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.

Extends

PopComponent

Metadata

selector ec-resource-pop
templateUrl ./resource-pop.component.html

Index

Properties
Methods
Inputs
Outputs
HostBindings
HostListeners

Constructor

constructor(popService: PopService, auth: AuthService, router: Router, route: ActivatedRoute, sdk: SdkService, formService: FormService, symbol: SymbolService, elementRef: ElementRef, cdr: ChangeDetectorRef)
Parameters :
Name Type Optional
popService PopService No
auth AuthService No
router Router No
route ActivatedRoute No
sdk SdkService No
formService FormService No
symbol SymbolService No
elementRef ElementRef No
cdr ChangeDetectorRef No

Inputs

api
Type : Core

The API Connector that possesses the resource list, see https://entrecode.github.io/ec.sdk/#api-connectors

config
Type : CrudConfig<Resource>
Default value : {}

CrudConfig for customizing the entry-form and the pop.

relation
Type : string

The name of the resource. If given, the generic ListResource loading will be used (api.resourceList)

resource
Type : Resource

The entry that should be used in the form. Is also set by edit.

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<ResourceForm | Form>

Emits when the resource has been deleted.

submitted
Type : EventEmitter<ResourceForm>

Route that should be headed to when a resource is edited. Navigates to route/:entryID

toggle
Type : EventEmitter<boolean>
Inherited from PopComponent
Defined in PopComponent:38

HostBindings

class
Default value : 'ec-resource-pop modal-wrapper'

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 deletedResource
deletedResource()

Fires when the resource has been deleted.

Returns : void
edit
edit(resource: Resource, config?: CrudConfig)

Edit the given entry.

Parameters :
Name Type Optional
resource Resource No
config CrudConfig<Resource> Yes
Returns : void
editResource
editResource(resource: Resource)
Parameters :
Name Type Optional
resource Resource No
Returns : Promise<Resource>
escapeRegExp
escapeRegExp(str)

escapes the given string to be usable in a regex

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

Is called when the nested form was submitted

Parameters :
Name Type Optional
form ResourceForm 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
initMethods
initMethods(form: ResourceFormComponent)

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

Parameters :
Name Type Optional
form ResourceFormComponent No
Returns : void
Private log
log(form)

Logs the current form (Developer help).

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

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

Parameters :
Name Type Optional
form ResourceFormComponent No
Returns : boolean
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 cdr
Type : ChangeDetectorRef
Public elementRef
Type : ElementRef
form
Type : ResourceFormComponent
Decorators :
@ViewChild(ResourceFormComponent)

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 {
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  HostBinding,
  Input,
  Output,
  ViewChild,
} from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Form } from '@ec.components/core';
import { FormService, PopComponent, PopService, SymbolService } from '@ec.components/ui';
import Core from 'ec.sdk/lib/Core';
import Resource from 'ec.sdk/lib/resources/Resource';
import { AuthService } from '../auth/auth.service';
import { CrudConfig } from '../crud/crud-config.interface';
import { ResourceForm } from '../resource-form/resource-form';
import { ResourceFormComponent } from '../resource-form/resource-form.component';
import { SdkService } from '../sdk/sdk.service';

/** 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.
 * */
@Component({
  selector: 'ec-resource-pop',
  templateUrl: './resource-pop.component.html',
})
export class ResourcePopComponent extends PopComponent {
  /** CrudConfig for customizing the entry-form and the pop.*/
  @Input() config: CrudConfig<Resource> = {};
  /** The entry form inside the view */
  @ViewChild(ResourceFormComponent) form: ResourceFormComponent;
  /** The API Connector that possesses the resource list, see https://entrecode.github.io/ec.sdk/#api-connectors */
  @Input() api: Core; // sdk api connector
  /** The name of the resource. If given, the generic ListResource loading will be used (api.resourceList) */
  @Input() relation: string;
  /** The entry that should be used in the form. Is also set by edit.*/
  @Input() resource: Resource;
  /** Route that should be headed to when a resource is edited. Navigates to route/:entryID */
  /* @Input() editRoute: string; */
  /** Route that should be headed to when a resource is created. */
  /* @Input() createRoute: string; */
  /** Emits when the entry-form is submitted. */
  @Output() submitted: EventEmitter<ResourceForm> = new EventEmitter();
  /** Emits when the resource has been deleted. */
  @Output() deleted: EventEmitter<ResourceForm | Form<Resource>> = new EventEmitter();
  /** Set host class to make sure the type is used */
  @HostBinding('class') class = 'ec-resource-pop modal-wrapper';

  constructor(
    public popService: PopService,
    private auth: AuthService,
    private router: Router,
    private route: ActivatedRoute,
    private sdk: SdkService,
    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 && 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: ResourceFormComponent) {
    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(resource: Resource, config?: CrudConfig<Resource>) {
    if (config) {
      this.config = Object.assign(this.config, config);
    }
    /* if (this.editRoute) {
            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.editResource(resource).then((preparedResource: Resource) => {
      this.resource = preparedResource;
      this.show();
    });
  }

  editResource(resource: Resource): Promise<Resource> {
    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.resource;
    /* 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. */
  initMethods(form: ResourceFormComponent) {
    if (!form || !this.relation) {
      return;
    }
    const variables = form.config.identifier
      ? {
          [form.config.identifier]: form.form.id(),
        }
      : {};
    // TODO: find a way to resolve parent resource variables e.g. dm:<dataManagerID>:model:entries:<modelID>
    this.auth
      .getAllowedResourceMethods(this.relation, variables, this.config.methods) // this.config.methods
      .then((methods) => (this.config.methods = methods));
  }

  /** Fires when the resource has been deleted. */
  public deletedResource() {
    this.hide();
    this.deleted.emit(this.form.form);
  }

  /** Logs the current form (Developer help). */
  private log(form) {
    console.dir(form);
  }
  /** Is called when the nested form was submitted */
  formSubmitted(form: ResourceForm) {
    this.submitted.next(form);
    if (!this.config.keepPopOpen) {
      this.hide();
    }
  }

  /** Returns header for current form */
  getHeader(form) {
    const label = this.config.singularLabel || form.relation || this.symbol.resolve('resource.generic');
    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(resourceForm) }}
  </div>
  <div class="modal__body">
    <ec-resource-form
      (ready)="initMethods($event)"
      [api]="api"
      [relation]="relation"
      [submitButton]="false"
      [config]="config"
      [loader]="popLoader"
      [value]="resource"
      (deleted)="hide()"
      (submitted)="formSubmitted($event)"
      #resourceForm
    ></ec-resource-form>
  </div>
  <footer class="modal__footer">
    <ul class="nav">
      <li class="nav__item" *ngIf="hasMethod('delete') && resourceForm.isEditing()">
        <button (click)="delete.confirm(resource)" class="btn ec-btn_delete" type="button">
          <!-- TODO add config for label -->
          delete
        </button>
      </li>
      <li class="nav__item" *ngIf="maySave(resourceForm)">
        <button
          (click)="resourceForm.submit()"
          [disabled]="resourceForm.group?.invalid"
          type="button"
          class="btn ec-btn_save"
          [class.is-disabled]="resourceForm.group?.invalid"
        >
          <!-- TODO add config for label -->
          save
        </button>
      </li>
      <!-- TODO check if used -->
      <li class="nav__item">
        <ng-content></ng-content>
      </li>
    </ul>
  </footer>
  <ec-loader #popLoader class="ec-loader loader is-global"></ec-loader>
  <ec-resource-delete-pop (deleted)="deletedResource()" [relation]="relation" #delete></ec-resource-delete-pop>
</div>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""