UI: General resources
This commit is contained in:
parent
b9a9348eac
commit
055a1ae56d
@ -299,9 +299,7 @@ export class EntityService {
|
|||||||
entityIds);
|
entityIds);
|
||||||
break;
|
break;
|
||||||
case EntityType.TB_RESOURCE:
|
case EntityType.TB_RESOURCE:
|
||||||
observable = this.getEntitiesByIdsObservable(
|
observable = this.resourceService.getResourcesByIds(entityIds, config);
|
||||||
(id) => this.resourceService.getResource(id, config),
|
|
||||||
entityIds);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return observable;
|
return observable;
|
||||||
@ -478,7 +476,7 @@ export class EntityService {
|
|||||||
break;
|
break;
|
||||||
case EntityType.TB_RESOURCE:
|
case EntityType.TB_RESOURCE:
|
||||||
pageLink.sortOrder.property = 'title';
|
pageLink.sortOrder.property = 'title';
|
||||||
entitiesObservable = this.resourceService.getTenantResources(pageLink, subType as ResourceType, config);
|
entitiesObservable = this.resourceService.getResources(pageLink, subType as ResourceType, null, config);
|
||||||
break;
|
break;
|
||||||
case EntityType.QUEUE_STATS:
|
case EntityType.QUEUE_STATS:
|
||||||
pageLink.sortOrder.property = 'createdTime';
|
pageLink.sortOrder.property = 'createdTime';
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import { Resource, ResourceInfo, ResourceSubType, ResourceType, TBResourceScope
|
|||||||
import { catchError, mergeMap } from 'rxjs/operators';
|
import { catchError, mergeMap } from 'rxjs/operators';
|
||||||
import { isNotEmptyStr } from '@core/utils';
|
import { isNotEmptyStr } from '@core/utils';
|
||||||
import { ResourcesService } from '@core/services/resources.service';
|
import { ResourcesService } from '@core/services/resources.service';
|
||||||
|
import { NotificationTarget } from "@shared/models/notification.models";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -47,12 +48,8 @@ export class ResourceService {
|
|||||||
return this.http.get<PageData<ResourceInfo>>(url, defaultHttpOptionsFromConfig(config));
|
return this.http.get<PageData<ResourceInfo>>(url, defaultHttpOptionsFromConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTenantResources(pageLink: PageLink, resourceType?: ResourceType, config?: RequestConfig): Observable<PageData<ResourceInfo>> {
|
public getTenantResources(pageLink: PageLink, config?: RequestConfig): Observable<PageData<ResourceInfo>> {
|
||||||
let url = `/api/resource${pageLink.toQuery()}`;
|
return this.http.get<PageData<ResourceInfo>>(`/api/resource/tenant${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config))
|
||||||
if (isNotEmptyStr(resourceType)) {
|
|
||||||
url += `&resourceType=${resourceType}`;
|
|
||||||
}
|
|
||||||
return this.http.get<PageData<ResourceInfo>>(url, defaultHttpOptionsFromConfig(config));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getResource(resourceId: string, config?: RequestConfig): Observable<Resource> {
|
public getResource(resourceId: string, config?: RequestConfig): Observable<Resource> {
|
||||||
@ -98,4 +95,9 @@ export class ResourceService {
|
|||||||
return this.http.delete(`/api/resource/${resourceId}?force=${force}`, defaultHttpOptionsFromConfig(config));
|
return this.http.delete(`/api/resource/${resourceId}?force=${force}`, defaultHttpOptionsFromConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getResourcesByIds(ids: string[], config?: RequestConfig): Observable<Array<ResourceInfo>> {
|
||||||
|
return this.http.get<Array<ResourceInfo>>(`/api/resource?resourceIds=${ids.join(',')}`,
|
||||||
|
defaultHttpOptionsFromConfig(config));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,8 +32,8 @@
|
|||||||
<tb-resources-library #resourcesComponent
|
<tb-resources-library #resourcesComponent
|
||||||
[standalone]="true"
|
[standalone]="true"
|
||||||
[entity]="resources"
|
[entity]="resources"
|
||||||
[defaultResourceType]="ResourceType.TEXT"
|
[defaultResourceType]="ResourceType.GENERAL"
|
||||||
[resourceTypes]="[ResourceType.TEXT]"
|
[resourceTypes]="[ResourceType.GENERAL]"
|
||||||
[isEdit]="true">
|
[isEdit]="true">
|
||||||
</tb-resources-library>
|
</tb-resources-library>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -106,6 +106,9 @@ export class ResourcesDialogComponent extends DialogComponent<ResourcesDialogCom
|
|||||||
map((response) => response[0])
|
map((response) => response[0])
|
||||||
).subscribe(result => this.dialogRef.close(result));
|
).subscribe(result => this.dialogRef.close(result));
|
||||||
} else {
|
} else {
|
||||||
|
if (resource.resourceType !== ResourceType.GENERAL) {
|
||||||
|
delete resource.descriptor;
|
||||||
|
}
|
||||||
this.resourceService.saveResource(resource).subscribe(result => this.dialogRef.close(result));
|
this.resourceService.saveResource(resource).subscribe(result => this.dialogRef.close(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,14 +48,16 @@
|
|||||||
<div class="mat-padding flex flex-col">
|
<div class="mat-padding flex flex-col">
|
||||||
<form [formGroup]="entityForm">
|
<form [formGroup]="entityForm">
|
||||||
<fieldset [disabled]="(isLoading$ | async) || !isEdit">
|
<fieldset [disabled]="(isLoading$ | async) || !isEdit">
|
||||||
<mat-form-field class="mat-block">
|
@if (resourceTypes.length > 1) {
|
||||||
<mat-label translate>resource.resource-type</mat-label>
|
<mat-form-field class="mat-block">
|
||||||
<mat-select formControlName="resourceType" required>
|
<mat-label translate>resource.resource-type</mat-label>
|
||||||
<mat-option *ngFor="let resourceType of resourceTypes" [value]="resourceType">
|
<mat-select formControlName="resourceType" required>
|
||||||
{{ resourceTypesTranslationMap.get(resourceType) | translate }}
|
<mat-option *ngFor="let resourceType of resourceTypes" [value]="resourceType">
|
||||||
</mat-option>
|
{{ resourceTypesTranslationMap.get(resourceType) | translate }}
|
||||||
</mat-select>
|
</mat-option>
|
||||||
</mat-form-field>
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
}
|
||||||
<mat-form-field class="mat-block" *ngIf="entityForm.get('resourceType').value !== resourceType.LWM2M_MODEL || !isAdd">
|
<mat-form-field class="mat-block" *ngIf="entityForm.get('resourceType').value !== resourceType.LWM2M_MODEL || !isAdd">
|
||||||
<mat-label translate>resource.title</mat-label>
|
<mat-label translate>resource.title</mat-label>
|
||||||
<input matInput formControlName="title" required>
|
<input matInput formControlName="title" required>
|
||||||
@ -66,26 +68,29 @@
|
|||||||
{{ 'resource.title-max-length' | translate }}
|
{{ 'resource.title-max-length' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<tb-file-input *ngIf="isAdd"
|
@if (isAdd || ((isAdd || isEdit) && entityForm.get('resourceType').value === resourceType.GENERAL)) {
|
||||||
formControlName="data"
|
<tb-file-input formControlName="data"
|
||||||
required
|
required
|
||||||
label="{{ (entityForm.get('resourceType').value === resourceType.LWM2M_MODEL ? 'resource.resource-files' : 'resource.resource-file') | translate }}"
|
label="{{ (entityForm.get('resourceType').value === resourceType.LWM2M_MODEL ? 'resource.resource-files' : 'resource.resource-file') | translate }}"
|
||||||
[readAsBinary]="true"
|
[readAsBinary]="true"
|
||||||
[maxSizeByte]="maxResourceSize"
|
[maxSizeByte]="maxResourceSize"
|
||||||
[allowedExtensions]="getAllowedExtensions()"
|
[allowedExtensions]="getAllowedExtensions()"
|
||||||
[contentConvertFunction]="convertToBase64File"
|
[contentConvertFunction]="convertToBase64File"
|
||||||
[accept]="getAcceptType()"
|
[accept]="getAcceptType()"
|
||||||
[multipleFile]="entityForm.get('resourceType').value === resourceType.LWM2M_MODEL"
|
[multipleFile]="entityForm.get('resourceType').value === resourceType.LWM2M_MODEL"
|
||||||
dropLabel="{{'resource.drop-resource-file-or' | translate}}"
|
dropLabel="{{'resource.drop-resource-file-or' | translate}}"
|
||||||
[existingFileName]="entityForm.get('fileName')?.value"
|
[existingFileName]="entityForm.get('fileName')?.value"
|
||||||
(fileNameChanged)="entityForm?.get('fileName').patchValue($event)">
|
(mediaTypeChanged)="mediaTypeChange($event)"
|
||||||
</tb-file-input>
|
(fileNameChanged)="entityForm?.get('fileName').patchValue($event)">
|
||||||
<div *ngIf="!isAdd" class="flex flex-row xs:flex-col sm:gap-2 md:flex-col gt-md:gap-2">
|
</tb-file-input>
|
||||||
<mat-form-field class="flex-1">
|
} @else {
|
||||||
<mat-label translate>resource.file-name</mat-label>
|
<div class="flex flex-row xs:flex-col sm:gap-2 md:flex-col gt-md:gap-2">
|
||||||
<input matInput formControlName="fileName" type="text">
|
<mat-form-field class="flex-1">
|
||||||
</mat-form-field>
|
<mat-label translate>resource.file-name</mat-label>
|
||||||
</div>
|
<input matInput formControlName="fileName" type="text">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -44,7 +44,7 @@ export class ResourcesLibraryComponent extends EntityComponent<Resource> impleme
|
|||||||
standalone = false;
|
standalone = false;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
resourceTypes = [ResourceType.LWM2M_MODEL, ResourceType.PKCS_12, ResourceType.JKS, ResourceType.TEXT];
|
resourceTypes = [ResourceType.LWM2M_MODEL, ResourceType.PKCS_12, ResourceType.JKS, ResourceType.GENERAL];
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
defaultResourceType = ResourceType.LWM2M_MODEL;
|
defaultResourceType = ResourceType.LWM2M_MODEL;
|
||||||
@ -90,10 +90,19 @@ export class ResourcesLibraryComponent extends EntityComponent<Resource> impleme
|
|||||||
title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]],
|
title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]],
|
||||||
resourceType: [entity?.resourceType ? entity.resourceType : ResourceType.LWM2M_MODEL, Validators.required],
|
resourceType: [entity?.resourceType ? entity.resourceType : ResourceType.LWM2M_MODEL, Validators.required],
|
||||||
fileName: [entity ? entity.fileName : null, Validators.required],
|
fileName: [entity ? entity.fileName : null, Validators.required],
|
||||||
data: [entity ? entity.data : null, this.isAdd ? [Validators.required] : []]
|
data: [entity ? entity.data : null, this.isAdd ? [Validators.required] : []],
|
||||||
|
descriptor: this.fb.group({
|
||||||
|
mediaType: ['']
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mediaTypeChange(mediaType: string): void {
|
||||||
|
if (this.entityForm.get('resourceType').value === ResourceType.GENERAL) {
|
||||||
|
this.entityForm.get('descriptor').get('mediaType').patchValue(mediaType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateForm(entity: Resource): void {
|
updateForm(entity: Resource): void {
|
||||||
this.entityForm.patchValue(entity);
|
this.entityForm.patchValue(entity);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,7 +76,7 @@
|
|||||||
placeholderText="{{ 'rule-node-config.ai.ai-resources' | translate }}"
|
placeholderText="{{ 'rule-node-config.ai.ai-resources' | translate }}"
|
||||||
[inlineField]="true"
|
[inlineField]="true"
|
||||||
[entityType]="EntityType.TB_RESOURCE"
|
[entityType]="EntityType.TB_RESOURCE"
|
||||||
[subType]="ResourceType.TEXT"
|
[subType]="ResourceType.GENERAL"
|
||||||
(createNew)="createAiResources($event, 'resourceIds')"
|
(createNew)="createAiResources($event, 'resourceIds')"
|
||||||
formControlName="resourceIds">
|
formControlName="resourceIds">
|
||||||
</tb-entity-list>
|
</tb-entity-list>
|
||||||
|
|||||||
@ -129,7 +129,7 @@ export class AiConfigComponent extends RuleNodeConfigurationComponent {
|
|||||||
disableClose: true,
|
disableClose: true,
|
||||||
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
||||||
data: {
|
data: {
|
||||||
resources: {title: name, resourceType: ResourceType.TEXT},
|
resources: {title: name, resourceType: ResourceType.GENERAL},
|
||||||
isAdd: true
|
isAdd: true
|
||||||
}
|
}
|
||||||
}).afterClosed()
|
}).afterClosed()
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import { PageLink } from '@shared/models/page/page-link';
|
|||||||
})
|
})
|
||||||
export class ResourcesTableHeaderComponent extends EntityTableHeaderComponent<Resource, PageLink, ResourceInfo> {
|
export class ResourcesTableHeaderComponent extends EntityTableHeaderComponent<Resource, PageLink, ResourceInfo> {
|
||||||
|
|
||||||
readonly resourceTypes = [ResourceType.LWM2M_MODEL, ResourceType.PKCS_12, ResourceType.JKS, ResourceType.TEXT];
|
readonly resourceTypes = [ResourceType.LWM2M_MODEL, ResourceType.PKCS_12, ResourceType.JKS, ResourceType.GENERAL];
|
||||||
readonly resourceTypesTranslationMap = ResourceTypeTranslationMap;
|
readonly resourceTypesTranslationMap = ResourceTypeTranslationMap;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>) {
|
constructor(protected store: Store<AppState>) {
|
||||||
|
|||||||
@ -129,10 +129,15 @@ export class FileInputComponent extends PageComponent implements AfterViewInit,
|
|||||||
@Output()
|
@Output()
|
||||||
fileNameChanged = new EventEmitter<string|string[]>();
|
fileNameChanged = new EventEmitter<string|string[]>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
mediaTypeChanged = new EventEmitter<string>();
|
||||||
|
|
||||||
fileName: string | string[];
|
fileName: string | string[];
|
||||||
fileContent: any;
|
fileContent: any;
|
||||||
files: File[];
|
files: File[];
|
||||||
|
|
||||||
|
mediaType: string;
|
||||||
|
|
||||||
@ViewChild('flow', {static: true})
|
@ViewChild('flow', {static: true})
|
||||||
flow: FlowDirective;
|
flow: FlowDirective;
|
||||||
|
|
||||||
@ -180,6 +185,7 @@ export class FileInputComponent extends PageComponent implements AfterViewInit,
|
|||||||
this.fileContent = files[0].fileContent;
|
this.fileContent = files[0].fileContent;
|
||||||
this.fileName = files[0].fileName;
|
this.fileName = files[0].fileName;
|
||||||
this.files = files[0].files;
|
this.files = files[0].files;
|
||||||
|
this.mediaType = files[0].mediaType;
|
||||||
this.updateModel();
|
this.updateModel();
|
||||||
} else if (files.length > 1) {
|
} else if (files.length > 1) {
|
||||||
this.fileContent = files.map(content => content.fileContent);
|
this.fileContent = files.map(content => content.fileContent);
|
||||||
@ -203,6 +209,7 @@ export class FileInputComponent extends PageComponent implements AfterViewInit,
|
|||||||
let fileName = null;
|
let fileName = null;
|
||||||
let fileContent = null;
|
let fileContent = null;
|
||||||
let files = null;
|
let files = null;
|
||||||
|
let mediaType = null;
|
||||||
if (reader.readyState === reader.DONE) {
|
if (reader.readyState === reader.DONE) {
|
||||||
if (!this.workFromFileObj) {
|
if (!this.workFromFileObj) {
|
||||||
fileContent = reader.result;
|
fileContent = reader.result;
|
||||||
@ -211,16 +218,18 @@ export class FileInputComponent extends PageComponent implements AfterViewInit,
|
|||||||
fileContent = this.contentConvertFunction(fileContent);
|
fileContent = this.contentConvertFunction(fileContent);
|
||||||
}
|
}
|
||||||
fileName = fileContent ? file.name : null;
|
fileName = fileContent ? file.name : null;
|
||||||
|
mediaType = file?.file?.type || null;
|
||||||
}
|
}
|
||||||
} else if (file.name || file.file){
|
} else if (file.name || file.file){
|
||||||
files = file.file;
|
files = file.file;
|
||||||
fileName = file.name;
|
fileName = file.name;
|
||||||
|
mediaType = file.file.type || null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolve({fileContent, fileName, files});
|
resolve({fileContent, fileName, files, mediaType});
|
||||||
};
|
};
|
||||||
reader.onerror = () => {
|
reader.onerror = () => {
|
||||||
resolve({fileContent: null, fileName: null, files: null});
|
resolve({fileContent: null, fileName: null, files: null, mediaType: null});
|
||||||
};
|
};
|
||||||
if (this.readAsBinary) {
|
if (this.readAsBinary) {
|
||||||
reader.readAsBinaryString(file.file);
|
reader.readAsBinaryString(file.file);
|
||||||
@ -283,6 +292,7 @@ export class FileInputComponent extends PageComponent implements AfterViewInit,
|
|||||||
this.propagateChange(this.files);
|
this.propagateChange(this.files);
|
||||||
} else {
|
} else {
|
||||||
this.propagateChange(this.fileContent);
|
this.propagateChange(this.fileContent);
|
||||||
|
this.mediaTypeChanged.emit(this.mediaType);
|
||||||
this.fileNameChanged.emit(this.fileName);
|
this.fileNameChanged.emit(this.fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export enum ResourceType {
|
|||||||
PKCS_12 = 'PKCS_12',
|
PKCS_12 = 'PKCS_12',
|
||||||
JKS = 'JKS',
|
JKS = 'JKS',
|
||||||
JS_MODULE = 'JS_MODULE',
|
JS_MODULE = 'JS_MODULE',
|
||||||
TEXT = 'TEXT',
|
GENERAL = 'GENERAL',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ResourceSubType {
|
export enum ResourceSubType {
|
||||||
@ -59,7 +59,7 @@ export const ResourceTypeTranslationMap = new Map<ResourceType, string>(
|
|||||||
[ResourceType.PKCS_12, 'resource.type.pkcs-12'],
|
[ResourceType.PKCS_12, 'resource.type.pkcs-12'],
|
||||||
[ResourceType.JKS, 'resource.type.jks'],
|
[ResourceType.JKS, 'resource.type.jks'],
|
||||||
[ResourceType.JS_MODULE, 'resource.type.js-module'],
|
[ResourceType.JS_MODULE, 'resource.type.js-module'],
|
||||||
[ResourceType.TEXT, 'resource.type.text'],
|
[ResourceType.GENERAL, 'resource.type.general'],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -4489,7 +4489,7 @@
|
|||||||
"js-module": "JS module",
|
"js-module": "JS module",
|
||||||
"lwm2m-model": "LWM2M model",
|
"lwm2m-model": "LWM2M model",
|
||||||
"pkcs-12": "PKCS #12",
|
"pkcs-12": "PKCS #12",
|
||||||
"text": "Text"
|
"general": "General"
|
||||||
},
|
},
|
||||||
"resource-sub-type": "Sub-type",
|
"resource-sub-type": "Sub-type",
|
||||||
"sub-type": {
|
"sub-type": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user