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