@2sic.com/dnn-sxc-angular
Advanced tools
Comparing version 8.0.4 to 8.0.5
@@ -124,4 +124,5 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { | ||
// If we've reached the end of the timer sequence, polling did likely not succeeed | ||
if (x == asyncInitAttempts - 1) | ||
console.log("Polling for $.ServicesFramework did not succeed after 3 seconds."); | ||
if (x === asyncInitAttempts - 1) { | ||
console.log('Polling for $.ServicesFramework did not succeed after 3 seconds.'); | ||
} | ||
} | ||
@@ -137,3 +138,3 @@ }); | ||
// Important: settings.sxc = settings.sxc.recreate(); <-- does not work | ||
settings.sxc.serviceRoot = sf.getServiceRoot("2sxc"); // <-- works | ||
settings.sxc.serviceRoot = sf.getServiceRoot('2sxc'); // <-- works | ||
// Provide sxc after sf has been initialized because it also depends on it | ||
@@ -157,3 +158,3 @@ this.sxcSubject.next(settings.sxc); | ||
// console.log('edition', this.edition$.value); | ||
// this.afTokenSubject.pipe(take(1), tap(x => console.log('aft', x))).subscribe(); | ||
// this.afTokenSubject.pipe(take(1), tap(x => console.log('aft', x))).subscribe(); | ||
}; | ||
@@ -163,4 +164,5 @@ Context.prototype.initFromAppTag = function (el, attribute, target) { | ||
var value = el.nativeElement.getAttribute(attribute); | ||
if (value) | ||
if (value) { | ||
target.next(value); | ||
} | ||
}; | ||
@@ -167,0 +169,0 @@ Context.decorators = [ |
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; | ||
import { Observable } from "rxjs"; | ||
import { Context } from "../context/context.service"; | ||
import { Observable } from 'rxjs'; | ||
import { Context } from '../context/context.service'; | ||
export declare class Interceptor implements HttpInterceptor { | ||
@@ -5,0 +5,0 @@ private context; |
import { Injectable } from '@angular/core'; | ||
import { Context } from "../context/context.service"; | ||
import { Context } from '../context/context.service'; | ||
import { take, mergeMap } from 'rxjs/operators'; | ||
var appRoute = '/app/auto/'; | ||
var appApi = 'api'; | ||
var appApiRoute = appRoute + appApi + '/'; | ||
import { routeRoot, routeApi, apiRouteName } from '../contants'; | ||
var Interceptor = /** @class */ (function () { | ||
@@ -15,12 +13,16 @@ function Interceptor(context) { | ||
var url = req.url; | ||
if (ctx.sxc) | ||
if (ctx.sxc) { | ||
url = ctx.sxc.resolveServiceUrl(req.url); | ||
else if (!["//", "http://", "https://", "/"].find(function (s) { return url.toLowerCase().startsWith(s); })) | ||
} | ||
else if (!['//', 'http://', 'https://', '/'].find(function (s) { return url.toLowerCase().startsWith(s); })) { | ||
url = ctx.path + url; | ||
} | ||
// change to use api of an edition, if an edition was specified | ||
// but only do this on api-routes, the others don't support editions | ||
if (ctx.apiEdition) | ||
url = url.replace(appApiRoute, appRoute + ctx.apiEdition + '/' + appApi + '/'); | ||
if (ctx.appNameInPath) | ||
url = url.replace(appRoute, "/app/" + ctx.appNameInPath + "/"); | ||
if (ctx.apiEdition) { | ||
url = url.replace(routeApi, routeRoot + ctx.apiEdition + '/' + apiRouteName); | ||
} | ||
if (ctx.appNameInPath) { | ||
url = url.replace(routeRoot, "app/" + ctx.appNameInPath + "/"); | ||
} | ||
// Clone the request and update the url with 2sxc params. | ||
@@ -34,3 +36,3 @@ var newReq = req.clone({ | ||
ContentBlockId: ctx.contentBlockId.toString(), | ||
RequestVerificationToken: ctx.antiForgeryToken ? ctx.antiForgeryToken : "" | ||
RequestVerificationToken: ctx.antiForgeryToken ? ctx.antiForgeryToken : '' | ||
} : {}, | ||
@@ -37,0 +39,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
[{"__symbolic":"module","version":4,"metadata":{"Interceptor":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":10,"character":1}}],"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../context/context.service","name":"Context","line":13,"character":21}]}],"intercept":[{"__symbolic":"method"}]}}}}] | ||
[{"__symbolic":"module","version":4,"metadata":{"Interceptor":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":7,"character":1}}],"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../context/context.service","name":"Context","line":10,"character":21}]}],"intercept":[{"__symbolic":"method"}]}}}}] |
import { HttpClient, HttpParams } from '@angular/common/http'; | ||
import { Observable } from 'rxjs'; | ||
export declare class Api<T> { | ||
export declare class Api { | ||
private http; | ||
@@ -8,9 +8,9 @@ private controller; | ||
/** | ||
* will call a 2sxc api controller method | ||
* GET a 2sxc api controller method | ||
*/ | ||
get(method: string, params?: HttpParams): Observable<T>; | ||
get<T>(method: string, params?: HttpParams): Observable<T>; | ||
/** | ||
* will post to a 2sxc api controller method | ||
* POST to a 2sxc api controller method | ||
*/ | ||
post(method: string, body: any, params?: HttpParams): Observable<T>; | ||
post<T>(method: string, body: any, params?: HttpParams): Observable<T>; | ||
} |
@@ -0,1 +1,2 @@ | ||
import { routeApi } from '../contants'; | ||
var Api = /** @class */ (function () { | ||
@@ -5,16 +6,15 @@ function Api(http, controller) { | ||
this.controller = controller; | ||
console.warn("important: 2sxc-data.api isn't fully tested yet."); | ||
} | ||
/** | ||
* will call a 2sxc api controller method | ||
* GET a 2sxc api controller method | ||
*/ | ||
Api.prototype.get = function (method, params) { | ||
var url = "app/auto/api/" + this.controller + "/" + method; | ||
var url = routeApi + "/" + this.controller + "/" + method; | ||
return this.http.get(url, { params: params }); | ||
}; | ||
/** | ||
* will post to a 2sxc api controller method | ||
* POST to a 2sxc api controller method | ||
*/ | ||
Api.prototype.post = function (method, body, params) { | ||
var url = "app/auto/api/" + this.controller + "/" + method; | ||
var url = routeApi + "/" + this.controller + "/" + method; | ||
return this.http.post(url, body, { params: params }); | ||
@@ -21,0 +21,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
[{"__symbolic":"module","version":4,"metadata":{"Api":{"__symbolic":"class","arity":1,"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/common/http","name":"HttpClient","line":7,"character":18},{"__symbolic":"reference","name":"string"}]}],"get":[{"__symbolic":"method"}],"post":[{"__symbolic":"method"}]}}}}] | ||
[{"__symbolic":"module","version":4,"metadata":{"Api":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/common/http","name":"HttpClient","line":6,"character":18},{"__symbolic":"reference","name":"string"}]}],"get":[{"__symbolic":"method"}],"post":[{"__symbolic":"method"}]}}}}] |
@@ -1,1 +0,1 @@ | ||
{"moduleName":null,"summaries":[{"symbol":{"__symbol":0,"members":[]},"metadata":{"__symbolic":"class","arity":1,"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbol":1,"members":[]},null]}],"get":[{"__symbolic":"method"}],"post":[{"__symbolic":"method"}]}}}],"symbols":[{"__symbol":0,"name":"Api","filePath":"./api"},{"__symbol":1,"name":"HttpClient","filePath":"@angular/common/http/http"}]} | ||
{"moduleName":null,"summaries":[{"symbol":{"__symbol":0,"members":[]},"metadata":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbol":1,"members":[]},null]}],"get":[{"__symbolic":"method"}],"post":[{"__symbolic":"method"}]}}}],"symbols":[{"__symbol":0,"name":"Api","filePath":"./api"},{"__symbol":1,"name":"HttpClient","filePath":"@angular/common/http/http"}]} |
import { HttpClient } from '@angular/common/http'; | ||
import { Observable } from 'rxjs'; | ||
/** | ||
* A helper to access content from 2sxc | ||
* @class Content | ||
* @template T Type which the system will return | ||
*/ | ||
export declare class Content<T> { | ||
@@ -7,5 +12,8 @@ private http; | ||
constructor(http: HttpClient, contentType: string); | ||
/** Get all items of this type */ | ||
get(): Observable<T[]>; | ||
/** get the specific item with the ID */ | ||
get(id: number): Observable<T>; | ||
post(id: number, data: any): Observable<T>; | ||
/** This method doesn't exist yet - maybe one day we'll enhance for creating data-items */ | ||
post(): Observable<T>; | ||
} |
@@ -0,1 +1,7 @@ | ||
import { routeContent } from '../contants'; | ||
/** | ||
* A helper to access content from 2sxc | ||
* @class Content | ||
* @template T Type which the system will return | ||
*/ | ||
var Content = /** @class */ (function () { | ||
@@ -6,5 +12,6 @@ function Content(http, contentType) { | ||
} | ||
/** internal implementation with/without ID */ | ||
Content.prototype.get = function (id) { | ||
if (id === void 0) { id = null; } | ||
var url = "app/auto/content/" + this.contentType; | ||
var url = routeContent + "/" + this.contentType; | ||
if (id) { | ||
@@ -16,3 +23,4 @@ url += "/" + id; | ||
}; | ||
Content.prototype.post = function (id, data) { | ||
/** This method doesn't exist yet - maybe one day we'll enhance for creating data-items */ | ||
Content.prototype.post = function () { | ||
throw new Error('not implemented yet'); | ||
@@ -19,0 +27,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
[{"__symbolic":"module","version":4,"metadata":{"Content":{"__symbolic":"class","arity":1,"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/common/http","name":"HttpClient","line":7,"character":18},{"__symbolic":"reference","name":"string"}]}],"get":[{"__symbolic":"method"},{"__symbolic":"method"},{"__symbolic":"method"}],"post":[{"__symbolic":"method"}]}}}}] | ||
[{"__symbolic":"module","version":4,"metadata":{"Content":{"__symbolic":"class","arity":1,"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/common/http","name":"HttpClient","line":11,"character":18},{"__symbolic":"reference","name":"string"}]}],"get":[{"__symbolic":"method"},{"__symbolic":"method"},{"__symbolic":"method"}],"post":[{"__symbolic":"method"}]}}}}] |
@@ -27,2 +27,3 @@ import { Api } from './api'; | ||
* @param id optional id of a single item | ||
* @returns an observable containing a single item (if ID is provided) or an array of these items | ||
*/ | ||
@@ -47,14 +48,14 @@ content$<T>(contentType: string, id?: number): Observable<T>; | ||
* get an api object to then start api-calls | ||
* usually you'll be better off using the observable stream api$, this is included primarily for consistency in the api | ||
* usually you'll be better off using the quick observable stream api$, this is included primarily for consistency in the api | ||
* @param controller the api controller | ||
* @returns a query object with a .get() | ||
* @returns an API object with a .get<T>() method | ||
*/ | ||
api<T>(controller: string): Api<T>; | ||
api(controller: string): Api; | ||
/** | ||
* retrieve a api stream from the server | ||
* @param name the method name | ||
* @param apiName controller/method | ||
* @param params optional parameters-object | ||
* @returns a typed observable which will give you the query | ||
*/ | ||
api$<T>(name: string, params?: HttpParams): Observable<T>; | ||
api$<T>(apiName: string, params?: HttpParams): Observable<T>; | ||
} |
@@ -30,2 +30,3 @@ import { Api } from './api'; | ||
* @param id optional id of a single item | ||
* @returns an observable containing a single item (if ID is provided) or an array of these items | ||
*/ | ||
@@ -58,5 +59,5 @@ Data.prototype.content$ = function (contentType, id) { | ||
* get an api object to then start api-calls | ||
* usually you'll be better off using the observable stream api$, this is included primarily for consistency in the api | ||
* usually you'll be better off using the quick observable stream api$, this is included primarily for consistency in the api | ||
* @param controller the api controller | ||
* @returns a query object with a .get() | ||
* @returns an API object with a .get<T>() method | ||
*/ | ||
@@ -68,8 +69,14 @@ Data.prototype.api = function (controller) { | ||
* retrieve a api stream from the server | ||
* @param name the method name | ||
* @param apiName controller/method | ||
* @param params optional parameters-object | ||
* @returns a typed observable which will give you the query | ||
*/ | ||
Data.prototype.api$ = function (name, params) { | ||
return new Api(this.http, name).get(name, params); | ||
Data.prototype.api$ = function (apiName, params) { | ||
var separator = apiName.indexOf('/'); | ||
if (separator === -1) { | ||
throw new Error("Trying to get api$ but only got '" + apiName + "' - expected something in the format of 'controller/method'"); | ||
} | ||
var method = apiName.substr(separator + 1); | ||
apiName = apiName.substr(0, separator); | ||
return new Api(this.http, apiName).get(method, params); | ||
}; | ||
@@ -76,0 +83,0 @@ Data.decorators = [ |
import { HttpParams } from '@angular/common/http'; | ||
import { map } from 'rxjs/operators'; | ||
import { routeQuery } from '../contants'; | ||
var Query = /** @class */ (function () { | ||
@@ -15,13 +16,17 @@ function Query(http, name) { | ||
Query.prototype.get = function (params, streams) { | ||
if (streams === undefined) | ||
if (streams === undefined) { | ||
streams = [this.defaultStreamName]; | ||
if (typeof streams === 'string') | ||
} | ||
if (typeof streams === 'string') { | ||
streams = streams.split(','); | ||
if (streams) | ||
} | ||
if (streams) { | ||
params = this.setStreamParam(params, streams); | ||
var url = "app/auto/query/" + this.name; | ||
} | ||
var url = routeQuery + "/" + this.name; | ||
var observable = this.http.get(url, { params: params }); | ||
// If only one stream is requested, directly return the stream in the returned observable | ||
if (streams && streams.length === 1) | ||
if (streams && streams.length === 1) { | ||
observable = observable.pipe(map(function (queryResult) { return queryResult[streams[0]]; })); | ||
} | ||
return observable; | ||
@@ -35,4 +40,3 @@ }; | ||
Query.prototype.setStreamParam = function (params, streams) { | ||
if (!params) | ||
params = new HttpParams(); | ||
params = params || new HttpParams(); | ||
params = params.set(this.streamParamKey, streams.join(',')); | ||
@@ -39,0 +43,0 @@ return params; |
@@ -1,1 +0,1 @@ | ||
[{"__symbolic":"module","version":4,"metadata":{"Query":{"__symbolic":"class","arity":1,"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/common/http","name":"HttpClient","line":8,"character":18},{"__symbolic":"reference","name":"string"}]}],"get":[{"__symbolic":"method"}],"setStreamParam":[{"__symbolic":"method"}]}}}}] | ||
[{"__symbolic":"module","version":4,"metadata":{"Query":{"__symbolic":"class","arity":1,"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/common/http","name":"HttpClient","line":7,"character":18},{"__symbolic":"reference","name":"string"}]}],"get":[{"__symbolic":"method"}],"setStreamParam":[{"__symbolic":"method"}]}}}}] |
{ | ||
"name": "@2sic.com/dnn-sxc-angular", | ||
"version": "8.0.4", | ||
"version": "8.0.5", | ||
"author": "2sic.com - daniel mettler and raphael müller", | ||
@@ -12,3 +12,3 @@ "bugs": { | ||
"dsa-copy:2dm": "cpx \"{,!(node_modules|dist)/**/}*.*\" \"../app-Directory/node_modules/@2sic.com/dnn-sxc-angular\" -w -v", | ||
"dsa-copy:template-ng8": "cpx \"dist/{,**/}*.*\" \"../app-template-angular8/ng/node_modules/@2sic.com/dnn-sxc-angular\" -w -v", | ||
"dsa-copy:template-ng8": "cpx \"dist/{,**/}*.*\" \"../app-template-angular8/ng/node_modules/@2sic.com/dnn-sxc-angular/dist\" -w -v", | ||
@@ -15,0 +15,0 @@ "dsa-test": "echo \"Error: no test specified\" && exit 1", |
# dnn-sxc-angular - Connecting Angular to DNN and/or 2sxc | ||
Connector for angular 8+ ([git](https://github.com/angular/angular) | [web](https://angular.io/)) for developers using | ||
This is a connector for angular 8+ ([git](https://github.com/angular/angular) | [web](https://angular.io/)) for developers using | ||
1. the open source platform DNN 7+ ([git](https://github.com/dnnsoftware/Dnn.Platform) | [web](http://dnnsoftware.com/)) | ||
1. and/or the open source CMS 2sxc 7+ ([git](https://github.com/2sic/2sxc/) | [web](https://2sxc.org/)) | ||
1. and/or the open source CMS 2sxc 10+ ([git](https://github.com/2sic/2sxc/) | [web](https://2sxc.org/)) | ||
This is a helper which | ||
This connector does | ||
1. allows you to develop from local while running with hot-reload on a DNN, even on the production site | ||
1. automatically provides all important dnn-parameters (module ID, security token, etc.) to angular | ||
2. adds an Http Interceptor for the HttpClient which automatically applies these parameters to all requests | ||
3. prevents the enter-key from causing DNN form submits (optional, you can override this) | ||
1. adds an Http Interceptor for the HttpClient which automatically applies these parameters to all requests | ||
1. gives you quick commands like `data.query$` to get data with little effort from the server | ||
1. prevents the enter-key from causing DNN form submits (optional, you can override this) | ||
It uses **observables** to make it happen, thereby avoiding timing / async problems common in this scenario. | ||
## Setup | ||
## Setup & Discover Dnn-Sxc-Angular | ||
It's published on [npm](https://www.npmjs.com/package/@2sic.com/dnn-sxc-angular), so the most common way is to get it using npm with | ||
`npm install "@2sic.com/dnn-sxc-angular" --save`. | ||
`npm install "@2sic.com/dnn-sxc-angular" --save`. But we recommend that you follow the quick-start guide. | ||
1. Start discovery using the [tutorial app](https://2sxc.org/en/apps/app/tutorial-angular-8) - ideally using the [getting started recipe](https://azing.org/2sxc/r/oCmPBI3p) | ||
1. If you've already mastered the basics and wish to build your own, you can | ||
1. [Rename the tutorial app](https://azing.org/2sxc/r/S-VS0nPH) and continue working with that | ||
1. or modify an existing app to work with the same conventions | ||
## How To Use | ||
### Setup | ||
1. Follow the [quickstart guide](https://azing.org/2sxc/r/9qdbjvl_) to start using dnn-sxc-angular. | ||
1. To develop locally using `ng serve` follow [these instructions](https://azing.org/2sxc/r/VLo7GwRo) | ||
### Using WebAPIs inside DNN | ||
This will now work automatically, because all headers etc. are now automatically added by the system. | ||
This will now work automatically, because all headers etc. are now automatically added by the system. So just use your normal http-requests and everything works like magic :) | ||
### Using 2sxc Content-Items, Queries and APIs | ||
This package contains a `Data` object, which provides 3 observable streams | ||
@@ -35,5 +42,6 @@ | ||
To use them, best check out the [tutorial app](todo) or simply work through TypeScript intelisense - we documented all the commands. | ||
To use them, best check out the [tutorial app](https://2sxc.org/en/apps/app/tutorial-angular-8) or simply work through TypeScript intelisense - we documented all the commands. | ||
### Getting ModuleId, TabId, etc. and the `sxc` Instance | ||
There is a `Context` object which provides these properties as streams (observables). Just inject `Context` and access it from there. Note that you almost never need this, as the HttpClient is already configured and ready to go, including the headers it needs. | ||
@@ -46,8 +54,8 @@ | ||
## Internal Notes | ||
## Internal Notes | ||
* read [npm instructions](https://azing.org/2sxc/r/ItPxPh9D) to see how to publish a release | ||
## Todo | ||
* create & test simple app-api access | ||
* enhance the content-manager to provide write commands (ATM read-only) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
168263
116
989
60