Skip to content

Commit

Permalink
Merge pull request #13 from guillotinaweb/better-demo
Browse files Browse the repository at this point in the history
Better demo
  • Loading branch information
ebrehault authored May 25, 2020
2 parents b4cccc8 + 8c32daf commit 6a6f097
Show file tree
Hide file tree
Showing 16 changed files with 177 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 1.3.0 (2020-05-24)

### Feature
- Allow to get or update context transparently, keeping state and backend in sync

# 1.2.1 (2020-05-03)

### Improvement
Expand Down
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ import { Grange } from 'grange';
constructor(private grange: Grange) {}
```

### The Grange service itself

The `grange` service provides handy methods for the most common needs.

`getContext()`: returns an Observable with the current traversed context.

`updateContext(changes)`: update the current context with the provided changes.
The update will be performed in the state immediately, and the corresponding PATCH will be done on the backend.
If the backend call fails, a GET call is done to update the state with the actual value.

#### The Traverser service

`this.grange.traverser`
Expand Down Expand Up @@ -247,6 +257,43 @@ Grange uses ngx-schema-form to render any JSON Schema as a dynamic form. The for

TO BE COMPLETED

## Guillotina

Useful Guillotina operations:

- create an app container for a new project
```
curl -XPOST --user root:root http://127.0.0.1:8081/db -d '{
"@type": "Container",
"id": "my-app"
}'
```
- create a user
```
curl -XPOST --user root:root http://127.0.0.1:8081/db/site/users -d '{
"@type": "User",
"id": "inewton",
"username": "inewton",
"name": "Isaac Newton",
"email": "isaac@newton.org",
"password": "inewton",
"user_roles": ["guillotina.Member"]
}'
```
- give reader access to a user
```
curl -XPOST --user root:root http://127.0.0.1:8081/db/site/@sharing -d '{
"prinrole": [
{
"principal": "inewton",
"role": "guillotina.Reader",
"setting": "Allow"
}
]
}'
```


## Developers

If we want to run Grange into an Anugular project using the GitHub master branches of all the dependencies, we need to use mrs-developer:
Expand Down
1 change: 1 addition & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
}
],
"styles": [
"projects/demo/src/pastanaga.scss",
"projects/demo/src/styles.scss"
],
"scripts": []
Expand Down
12 changes: 12 additions & 0 deletions g-api/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ databases:
pool_size: 100
store_json: true
allow_register: true
jwk:
k: hGplrewNAVxULSApZavdXuxdiR_2Ner73oc-2Z7TVVY
kty: oct
cache:
driver: guillotina.contrib.redis
updates_channel: guillotina
Expand Down Expand Up @@ -99,6 +102,15 @@ behaviors:
title: Text
default: Hello
contents:
canvas:
title: Canvas
inherited_interface: guillotina.interfaces.IItem
inherited_class: guillotina.content.Item
add_permission: guillotina.AddContent
properties:
points:
type: guillotina.schema.JSONField
title: Points
mydoc:
title: My Doc
inherited_interface: guillotina.interfaces.IFolder
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"test": "jest",
"lint": "ng lint",
"test:watch": "jest --watch",
"guillotina": "docker-compose -f g-api/docker-compose.yaml up",
"get_version": "cat ./projects/grange/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]'"
},
"private": true,
Expand Down
2 changes: 2 additions & 0 deletions projects/demo/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { GrangeViews, Grange } from '../../../grange/src';
import { CanvasComponent } from './canvas/canvas.component';

@Component({
selector: 'app-root',
Expand All @@ -14,6 +15,7 @@ export class AppComponent {
) {
this.views.initialize();
this.grange.core.auth.isAuthenticated.subscribe(auth => this.isAuthenticated = auth.state);
this.grange.traverser.addView('view', 'canvas', CanvasComponent);
}

logout() {
Expand Down
4 changes: 3 additions & 1 deletion projects/demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NgModule } from '@angular/core';
import { environment } from '../environments/environment';

import { AppComponent } from './app.component';
import { CanvasComponent } from './canvas/canvas.component';
import { GrangeRootModule } from '../../../grange/src';
import { TraversalModule } from 'angular-traversal';
import { StoreModule } from '@ngrx/store';
Expand All @@ -12,7 +13,8 @@ import { AngularSvgIconModule } from 'angular-svg-icon';

@NgModule({
declarations: [
AppComponent
AppComponent,
CanvasComponent,
],
imports: [
BrowserModule,
Expand Down
7 changes: 7 additions & 0 deletions projects/demo/src/app/canvas/canvas.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<grange-actions></grange-actions>
<div *ngFor="let row of (canvas | async); let x = index"
class="row">
<div *ngFor="let cell of row; let y = index"
[class.fill]="cell"
(click)="toggle(x, y, cell)"></div>
</div>
12 changes: 12 additions & 0 deletions projects/demo/src/app/canvas/canvas.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.row {
height: 20px;
div {
display: inline-block;
height: 20px;
width: 20px;
background-color: grey;
&.fill {
background-color: pink;
}
}
}
39 changes: 39 additions & 0 deletions projects/demo/src/app/canvas/canvas.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, OnInit } from '@angular/core';
import { Grange } from '../../../../grange/src';
import { select } from '@ngrx/store';
import { TraverserSelectors } from '@guillotinaweb/ngx-state-traverser';
import { map, tap, concatMap } from 'rxjs/operators';
import { Observable } from 'rxjs';

@Component({
selector: 'app-canvas',
templateUrl: 'canvas.component.html',
styleUrls: ['./canvas.component.scss'],
})

export class CanvasComponent implements OnInit {
points = this.grange.getContext().pipe(
tap(context => {
this.path = context['@id'];
}),
map(context => context.points || {}),
);
canvas: Observable<boolean[][]> = this.points.pipe(
map((points: {[coord: string]: boolean}) => Object.entries(points).reduce((all, [coordStr, value]) => {
const coord = coordStr.split('-').map(x => parseInt(x, 10));
all[coord[0]][coord[1]] = value;
return all;
}, Array.from(new Array(10), x => Array.from(new Array(10), () => false)))
),
);
path?: string;

constructor(private grange: Grange) { }

ngOnInit() {}

toggle(x: number, y: number, current: boolean) {
const coord = `${x}-${y}`;
return this.grange.updateContext({points: {[coord]: !current}});
}
}
7 changes: 7 additions & 0 deletions projects/demo/src/pastanaga.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import "~@guillotinaweb/pastanaga-angular/lib/styles/common-reset";
$font-path: "~@guillotinaweb/pastanaga-angular/lib/assets/fonts";
@import "~@guillotinaweb/pastanaga-angular/lib/styles/fonts";

html, body {
overflow: auto;
}
3 changes: 0 additions & 3 deletions projects/demo/src/styles.scss
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
@import "../../../node_modules/@guillotinaweb/pastanaga-angular/lib/styles/common-reset";
$font-path: "../../../node_modules/@guillotinaweb/pastanaga-angular/lib/assets/fonts";
@import "../../../node_modules/@guillotinaweb/pastanaga-angular/lib/styles/fonts";
2 changes: 1 addition & 1 deletion projects/grange/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@guillotinaweb/grange",
"version": "1.2.1",
"version": "1.3.0",
"license": "MIT",
"author": {
"name": "Eric Brehault",
Expand Down
18 changes: 17 additions & 1 deletion projects/grange/src/lib/grange.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Store, select } from '@ngrx/store';
import { Traverser } from 'angular-traversal';
import { GrangeCore } from '@guillotinaweb/grange-core';
import { GrangeState } from './state/state';
import { PastanagaService } from '@guillotinaweb/pastanaga-angular';
import { Observable } from 'rxjs';
import { TraverserSelectors, TraverserActions } from '@guillotinaweb/ngx-state-traverser';
import { take } from 'rxjs/operators';

@Injectable({
providedIn: 'root'
Expand All @@ -18,4 +21,17 @@ export class Grange {
) {
this.store.dispatch({ type: '[Traversing] Watch'});
}

getContext(): Observable<any> {
return this.store.pipe(select(TraverserSelectors.getContext));
}

updateContext(changes: any) {
this.getContext().pipe(
take(1)
).subscribe(context => this.store.dispatch(new TraverserActions.UpdateTraverserResource({
path: this.core.api.getPath(context['@id']),
changes
})));
}
}
25 changes: 23 additions & 2 deletions projects/grange/src/lib/state/effects.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { tap } from 'rxjs/operators';
import { TraverserActions } from '@guillotinaweb/ngx-state-traverser';
import { tap, switchMap, take, concatMap, filter, catchError, map } from 'rxjs/operators';
import { TraverserActions, TraverserSelectors } from '@guillotinaweb/ngx-state-traverser';
import { select, Store } from '@ngrx/store';
import { GrangeState } from './state';
import { GrangeCore } from '@guillotinaweb/grange-core';
import { EMPTY, of } from 'rxjs';

@Injectable()
export class GrangeEffects {
Expand All @@ -12,7 +16,24 @@ export class GrangeEffects {
tap(() => window.scrollTo(0, 0))
);

@Effect()
updateResource = this.actions.pipe(
ofType<TraverserActions.UpdateTraverserResource>(TraverserActions.Types.UpdateTraverserResource),
switchMap(action => this.store.pipe(
select(TraverserSelectors.getObjectByPath(action.payload.path)),
take(1),
filter(resource => !!resource['@id']),
concatMap(resource => this.core.resource.update(resource['@id'], resource).pipe(
map(() => EMPTY),
// if error on update, we traverse the resource in order to put the backend version in our local state
catchError(() => of(new TraverserActions.Traverse(this.core.api.getPath(resource['@id']))))
)),
)),
);

constructor(
private readonly actions: Actions,
private readonly store: Store<GrangeState>,
private core: GrangeCore,
) {}
}
4 changes: 0 additions & 4 deletions src/pastanaga-overrides.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
$labels-text-transform: none;

html, body {
overflow: auto;
}

0 comments on commit 6a6f097

Please sign in to comment.