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
10 changes: 7 additions & 3 deletions blocks/display/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,16 +475,20 @@ async def compute(self):

class EntityList(Widget):

parameters = [Parameter('entities', type='List[T]'), Parameter('fields', type='List[T]')]
parameters = [Parameter('entities', type='List[T]'),
Parameter('fields', type='List[T]'),
Parameter('actions', type='List[T]')]
outputs = [Output('entities', type='List[T]')]
render_attributes = ['entities', 'fields']
render_attributes = ['entities', 'fields', 'actions']

def on_setup(self, **services):
super(EntityList, self).on_setup(**services)
self.entities = None
self.fields = None
self.actions = None


async def compute(self):
self.entities, self.fields = await self.pull_items_data('entities', 'fields')
self.entities, self.fields, self.actions = await self.pull_items_data('entities', 'fields', 'actions')
await self.display_container.render()
return {'entities': self.entities}
31 changes: 0 additions & 31 deletions blocks/layout/entities/product/product-create.yaml

This file was deleted.

45 changes: 0 additions & 45 deletions blocks/layout/entities/product/product-edit.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion blocks/layout/entities/product/product-form.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ blocks:
class: data/dict.py:GetDictValue
constant:
key: data.name
default: '123'
default: ''
parameters:
dict: $product_entity
-
Expand Down
45 changes: 42 additions & 3 deletions blocks/layout/entities/product/product-list.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# TODO this subpipeline should return two outputs:
# - the entities list
# - the selected item for edit
# Since our subpipelines currently don't support that we'll hack the `product-crud.yaml`
# pipeline for now, by moving all this logic inside that yaml. Once this subpipeline
# feature is implemented we can switch back to integrating this yaml.
# :shrug:

alias: ProductList
parameters:
-
name: on_click_navigate_to
type: str
name: on_select_navigate_to
type: string
default: ""

blocks:
-
Expand All @@ -23,7 +32,10 @@ blocks:
component: EntityList
attributes:
image_fit: contain
connect: product_list
connect:
edit: edit_entity
list: product_list
delete: delete_entity
children:
# get list of entities
-
Expand All @@ -32,6 +44,25 @@ blocks:
constant:
type: product

-
alias: edit_entity
class: display/widget.py:Selection
-
#alias: delete
sequence:
-
alias: delete_entity
class: display/widget.py:Selection
-
class: data/dict.py:GetDictValue
constant:
key: id
incoming:
dict: [delete_entity]
-
class: storage/entity/delete.yaml:DeleteEntity
compute: on_push

# render list
-
alias: product_list
Expand All @@ -47,6 +78,14 @@ blocks:
-
key: description
level: body
actions:
-
name: Edit
action: edit
onSelectNavigateTo: edit
-
name: Delete
action: delete
incoming:
entities: [entities_list]

Expand Down
17 changes: 17 additions & 0 deletions blocks/storage/entity/delete.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
alias: DeleteEntity
description: "Delete a single entity from the persistent storage, by it's (temp-mock) identifier"
parameters:
-
name: type
type: str
default: product
-
name: identifier
type: Any

blocks:
-
class: storage/memory.py:Delete
parameters:
key: $identifier
store: $type

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<div *ngIf="!entityList.length" class="no-items">No items here. Carry on!</div>

<cai-entity *ngFor="let entity of entityList" [type]="entity.type" [entity]="entity.data" [imageUrl]="entity.image" [fields]="fields"
[imageFit]="imageFit"></cai-entity>
<cai-entity *ngFor="let entity of entityList" [entity]="entity" [fields]="fields" [imageFit]="imageFit" [actions]="actions"
(action)="onAction($event)"></cai-entity>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
grid-gap: $space-base;
}

cai-entity {
cursor: pointer;
}

.no-items {
text-align: center;
}
30 changes: 21 additions & 9 deletions frontend/src/app/widgets/entity-list/entity-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ import {
Input,
OnInit,
OnChanges,
SimpleChanges
SimpleChanges,
Output,
EventEmitter,
Optional
} from '@angular/core';
import { isEmpty } from 'lodash';
import { Widget } from '../widget.model';
import { EntityField } from './entity-field.interface';

interface Entity {
// id: number;
type: string;
data: any[];
image?: string;
}
import { Entity, EntityField, EntityAction } from './entity.interface';
import { NavigatorComponent } from '../navigator/navigator.component';

@Component({
selector: 'cai-entity-list',
Expand All @@ -25,10 +23,14 @@ export class EntityListComponent implements Widget, OnInit, OnChanges {
@Input() entities: any[];
@Input() fields: EntityField[];
@Input() imageFit: 'contain' | 'cover' = 'contain';
@Input() actions: EntityAction[];
@Output() action = new EventEmitter<{ bid: string; item: Entity }>();

// hold transformed entity data structure - we can receive this data shape from the be in future
entityList: Entity[] = [];

constructor(@Optional() private navigator: NavigatorComponent) {}

ngOnInit() {
this.updateList();
}
Expand All @@ -39,9 +41,19 @@ export class EntityListComponent implements Widget, OnInit, OnChanges {
}
}

onAction({ action, entity }) {
// we get the entity from the original list we got from the BE and pass that
const item = this.entities.find(e => e.id === entity.id);
this.action.emit({ bid: action.action, item: item });
if (this.navigator && action.onSelectNavigateTo) {
this.navigator.goToState(action.onSelectNavigateTo);
}
}

private updateList() {
this.entityList = (this.entities || []).map(entity => {
return {
id: entity.id,
type: entity.type,
data: entity.data,
image: this.getImage(entity.links)
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/app/widgets/entity-list/entity.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<mat-card class="entity">
<img *ngIf="imageUrl" [src]="imageUrl" [ngClass]="['image', imageFit]">
<div class="data">
<cai-text *ngFor="let field of fields" [text]="entity[field.key]" [level]="field.level"></cai-text>
<img *ngIf="entity.image" [src]="entity.image" [ngClass]="['image', imageFit]">
<div class="contents">
<div class="data">
<cai-text *ngFor="let field of fields" [text]="entity.data[field.key]" [level]="field.level"></cai-text>
</div>
<div class="actions">
<cai-button *ngFor="let action of actions" [innerText]="action.name" buttonType="mat-raised-button" (buttonClick)="onAction(action)"></cai-button>
</div>
</div>
</mat-card>
9 changes: 8 additions & 1 deletion frontend/src/app/widgets/entity-list/entity.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@
object-fit: cover;
}
}
.data {
.contents {
flex: 6;
@include inset-space($space-base);
display: flex;
flex-direction: column;
justify-content: space-between;

.actions {
display: flex;
}
}
}
}
17 changes: 12 additions & 5 deletions frontend/src/app/widgets/entity-list/entity.component.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { Component, Input } from '@angular/core';
import { EntityField } from './entity-field.interface';
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Entity, EntityField, EntityAction } from './entity.interface';

@Component({
selector: 'cai-entity',
templateUrl: './entity.component.html',
styleUrls: ['./entity.component.scss']
})
export class EntityComponent {
@Input() entity: { [key: string]: any };
@Input() entity;
@Input() fields: EntityField[];
@Input() imageUrl: string;
@Input() imageFit: 'contain' | 'cover' = 'contain';
@Input() type: string;
@Input() actions: EntityAction[];
@Output() action = new EventEmitter<{ action: EntityAction; entity: any }>();

onAction(action) {
this.action.next({
action: action,
entity: this.entity
});
}
}
18 changes: 18 additions & 0 deletions frontend/src/app/widgets/entity-list/entity.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface Entity {
id: number;
type: string;
data: any[];
image?: string;
}

export interface EntityAction {
name: string;
action: string;
onSelectNavigateTo?: string;
}

export interface EntityField {
key: string;
level: 'base' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';
weight: 'light' | 'regular' | 'medium' | 'bold';
}
Loading