mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-09-02 08:09:19 +08:00
Implement ClassicView
Add FrontEnd api calls - Add api method to retrieve classic view html - Add apiUrl endpoint environment configuration - Add Resolver to ClassicView routes Implement FrontEnd component - Add html and js rendering to classic view. Add Classic View api-platform Entity and data provider - Add ClassicViewData Dto with resource definition - Add Classic controller with dummy html - Declare controller in the services.yaml
This commit is contained in:
parent
ece6ae6377
commit
58281a6b64
11 changed files with 329 additions and 19 deletions
|
@ -1,6 +1,7 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {Routes, RouterModule} from '@angular/router';
|
||||
import {ClassicViewUiComponent} from '../components/classic-view/classic-view.component';
|
||||
import {ClassicViewUiComponent} from '@components/classic-view/classic-view.component';
|
||||
import {ClassicViewResolver} from '@services/api/resolvers/classic-view.resolver';
|
||||
|
||||
import {AuthGuard} from '../services/auth/auth-guard.service';
|
||||
|
||||
|
@ -20,17 +21,20 @@ const routes: Routes = [
|
|||
{
|
||||
path: ':module',
|
||||
component: ClassicViewUiComponent,
|
||||
canActivate: [AuthGuard]
|
||||
canActivate: [AuthGuard],
|
||||
resolve: {view: ClassicViewResolver}
|
||||
},
|
||||
{
|
||||
path: ':module/:action',
|
||||
component: ClassicViewUiComponent,
|
||||
canActivate: [AuthGuard]
|
||||
canActivate: [AuthGuard],
|
||||
resolve: {view: ClassicViewResolver}
|
||||
},
|
||||
{
|
||||
path: ':module/:action/:record',
|
||||
component: ClassicViewUiComponent,
|
||||
canActivate: [AuthGuard]
|
||||
canActivate: [AuthGuard],
|
||||
resolve: {view: ClassicViewResolver}
|
||||
},
|
||||
{path: '**', redirectTo: 'Login'},
|
||||
];
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
<div class="alert alert-warning" role="alert">
|
||||
You have reached the classic view.
|
||||
</div>
|
||||
<div #dataContainer></div>
|
|
@ -1,10 +1,5 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
import {AuthService} from '../../services/auth/auth.service';
|
||||
import {LoginResponseModel} from '../../services/auth/login-response-model';
|
||||
import {MessageService} from '../../services/message/message.service';
|
||||
import {ApiService} from '../../services/api/api.service';
|
||||
import {Component, ViewChild, ElementRef} from '@angular/core';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-classic-view-ui',
|
||||
|
@ -12,5 +7,25 @@ import {ApiService} from '../../services/api/api.service';
|
|||
styleUrls: []
|
||||
})
|
||||
export class ClassicViewUiComponent {
|
||||
data: any;
|
||||
|
||||
@ViewChild('dataContainer', {static:true}) dataContainer: ElementRef;
|
||||
public element: any;
|
||||
|
||||
renderHtml(data) {
|
||||
this.element = this.dataContainer.nativeElement;
|
||||
const fragment = document.createRange().createContextualFragment(data.html);
|
||||
this.element.appendChild(fragment);
|
||||
}
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.data = this.route.snapshot.data;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.renderHtml(this.data.view);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import {ClassicViewUiRoutes} from './classic-view.routes';
|
|||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ClassicViewUiComponent
|
||||
ClassicViewUiComponent,
|
||||
],
|
||||
exports: [
|
||||
ClassicViewUiComponent
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
production: false,
|
||||
apiUrl: './api'
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {KeyValue} from '@angular/common';
|
||||
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
|
||||
import {Router} from '@angular/router';
|
||||
import {HttpClient, HttpErrorResponse, HttpParams} from '@angular/common/http';
|
||||
import {ParamMap, Router} from '@angular/router';
|
||||
import {Observable} from 'rxjs';
|
||||
import * as hash from 'object-hash';
|
||||
import {MessageService} from '../message/message.service';
|
||||
|
@ -13,6 +13,11 @@ import {LoginResponseModel} from '../auth/login-response-model';
|
|||
import {ApiAccessTokenResponseEmpty} from './api-access-token-response-empty';
|
||||
import {ListViewData, ListViewDataModel} from '../../components/list-view/list-view-data-model';
|
||||
|
||||
import {environment} from '@base/environments/environment';
|
||||
|
||||
// we can now access environment.apiUrl
|
||||
const API_URL = environment.apiUrl;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
@ -332,4 +337,30 @@ export class ApiService {
|
|||
return false;
|
||||
}
|
||||
|
||||
getClassicView(routeParams: ParamMap): Observable<any> {
|
||||
|
||||
let url = API_URL
|
||||
let module = routeParams.get('module') || '';
|
||||
url += '/classic-views/' + module;
|
||||
|
||||
let params = new HttpParams();
|
||||
routeParams.keys.forEach((name) => {
|
||||
let value = routeParams.get(name);
|
||||
|
||||
if (name = 'module'){
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == null || value == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
params = params.set(name, value);
|
||||
});
|
||||
|
||||
return this.http.get(url, {
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
21
core/app/src/services/api/resolvers/classic-view.resolver.ts
Normal file
21
core/app/src/services/api/resolvers/classic-view.resolver.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {
|
||||
Resolve,
|
||||
ActivatedRouteSnapshot,
|
||||
RouterStateSnapshot
|
||||
} from '@angular/router';
|
||||
|
||||
|
||||
import {ApiService} from "../api.service";
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class ClassicViewResolver implements Resolve<any> {
|
||||
|
||||
constructor(private apiService: ApiService) {
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
|
||||
return this.apiService.getClassicView(route.paramMap);
|
||||
}
|
||||
}
|
|
@ -12,8 +12,14 @@
|
|||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"../../node_modules/@types"
|
||||
"../../../node_modules/@types"
|
||||
],
|
||||
"paths": {
|
||||
"@app/*": ["./src/app/*"],
|
||||
"@base/*": ["./src/*"],
|
||||
"@services/*": ["./src/services/*"],
|
||||
"@components/*": ["./src/components/*"]
|
||||
},
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
|
|
45
core/src/DataProvider/ClassicViewItemDataProvider.php
Normal file
45
core/src/DataProvider/ClassicViewItemDataProvider.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace App\DataProvider;
|
||||
|
||||
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
|
||||
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
|
||||
use App\Entity\ClassicView;
|
||||
|
||||
/**
|
||||
* Class ClassicViewItemDataProvider
|
||||
* @package App\DataProvider
|
||||
*/
|
||||
final class ClassicViewItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
|
||||
{
|
||||
/**
|
||||
* Defined supported resources
|
||||
* @param string $resourceClass
|
||||
* @param string|null $operationName
|
||||
* @param array $context
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
|
||||
{
|
||||
return ClassicView::class === $resourceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Item
|
||||
* @param string $resourceClass
|
||||
* @param array|int|string $id
|
||||
* @param string|null $operationName
|
||||
* @param array $context
|
||||
* @return ClassicView|null
|
||||
*/
|
||||
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?ClassicView
|
||||
{
|
||||
$output = new ClassicView();
|
||||
$output->setId('123');
|
||||
|
||||
$html = '<h1>HTML working</h1><script>alert(\'JS Working\');</script><button onClick="alert(\'JS Working\');">Click Me</button>';
|
||||
$output->setHtml($html);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
185
core/src/Entity/ClassicView.php
Normal file
185
core/src/Entity/ClassicView.php
Normal file
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Core\Annotation\ApiProperty;
|
||||
use ApiPlatform\Core\Annotation\ApiResource;
|
||||
|
||||
/**
|
||||
* @ApiResource(
|
||||
* description="Classic view html",
|
||||
* itemOperations={
|
||||
* "get"={
|
||||
* "method"="GET",
|
||||
* "openapi_context"= {
|
||||
* "summary"= "Retrieves the classic view html.",
|
||||
* "description"= "Retrieves the classic view html",
|
||||
* "parameters"= {
|
||||
* {
|
||||
* "in"= "path",
|
||||
* "name"= "id",
|
||||
* "required" = "true",
|
||||
* "type"= "string",
|
||||
* "example"="Accounts"
|
||||
* },
|
||||
* {
|
||||
* "name" = "action",
|
||||
* "in" = "query",
|
||||
* "type" = "string"
|
||||
* },
|
||||
* {
|
||||
* "name" = "record",
|
||||
* "in" = "query",
|
||||
* "type" = "string"
|
||||
* }
|
||||
* },
|
||||
* },
|
||||
* },
|
||||
* },
|
||||
* collectionOperations={
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
class ClassicView
|
||||
{
|
||||
|
||||
/**
|
||||
* The module
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @ApiProperty(
|
||||
* identifier=true,
|
||||
* attributes={
|
||||
* "openapi_context"={
|
||||
* "type"="string",
|
||||
* "description"="The module.",
|
||||
* "example"="Accounts"
|
||||
* }
|
||||
* },
|
||||
*
|
||||
* )
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* The action
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @ApiProperty(
|
||||
* attributes={
|
||||
* "openapi_context"={
|
||||
* "type"="string",
|
||||
* "description"="The action.",
|
||||
* "example"="DetailView",
|
||||
* },
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
protected $action;
|
||||
|
||||
/**
|
||||
* The record.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @ApiProperty(
|
||||
* attributes={
|
||||
* "openapi_context"={
|
||||
* "type"="string",
|
||||
* "description"="The record id."
|
||||
* },
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
protected $record;
|
||||
|
||||
/**
|
||||
* The view html.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @ApiProperty(
|
||||
* attributes={
|
||||
* "openapi_context"={
|
||||
* "type"="string",
|
||||
* "description"="The view html."
|
||||
* },
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
protected $html;
|
||||
|
||||
/**
|
||||
* Set Id
|
||||
* @param string $id
|
||||
*/
|
||||
public function setId(string $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Id
|
||||
* @return string
|
||||
*/
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action
|
||||
* @param string $action
|
||||
*/
|
||||
public function setAction(string $action): void
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAction(): ?string
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Record
|
||||
* @param string $record
|
||||
*/
|
||||
public function setRecord(string $record): void
|
||||
{
|
||||
$this->record = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Record
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRecord(): ?string
|
||||
{
|
||||
return $this->record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Html
|
||||
* @param string $html
|
||||
*/
|
||||
public function setHtml(string $html): void
|
||||
{
|
||||
$this->html = $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Hmtl
|
||||
* @return string|null
|
||||
*/
|
||||
public function getHtml(): ?string
|
||||
{
|
||||
return $this->html;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue