@meshmakers/octo-ui 3.5.100 → 3.5.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ChangeDetectionStrategy, Component, Injectable, Input, EventEmitter, Output, LOCALE_ID, ElementRef, forwardRef, ViewChild, signal, computed, input, model, output, effect, untracked, Directive, booleanAttribute, viewChild, afterEveryRender, InjectionToken, HostListener, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { inject, ChangeDetectionStrategy, Component, Injectable, Input, EventEmitter, Output, Injector, LOCALE_ID, ElementRef, forwardRef, ViewChild, signal, computed, input, model, output, effect, untracked, Directive, booleanAttribute, viewChild, afterEveryRender, InjectionToken, HostListener, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
|
4
|
-
import { AttributeSelectorService, AttributeValueTypeDto as AttributeValueTypeDto$1, CkTypeSelectorService, CkTypeAttributeService, toSecretState, secretStateFromAttribute, isSecretValueType, isSecretStateObject, secretStatusOf, formatSecretStatus, GetEntitiesByCkTypeDtoGQL, RuntimeEntitySelectDataSource, RuntimeEntityDialogDataSource, SearchFilterTypesDto, SortOrdersDto, FieldFilterOperatorsDto, GetCkTypesDtoGQL, GetCkModelByIdDtoGQL, GraphDirectionDto, CkTypeMetaData, AssociationModOptionsDto, GraphQL, isSecretAttributeCandidate, toUniqueCamelCaseNames, toCamelCaseAttributeName, DeleteStrategiesDto, CommunicationService, provideOctoServices } from '@meshmakers/octo-services';
|
|
4
|
+
import { AttributeSelectorService, AttributeValueTypeDto as AttributeValueTypeDto$1, CkTypeSelectorService, CkTypeAttributeService, toSecretState, secretStateFromAttribute, isSecretValueType, FileDownloadService, isSecretStateObject, secretStatusOf, formatSecretStatus, GetEntitiesByCkTypeDtoGQL, RuntimeEntitySelectDataSource, RuntimeEntityDialogDataSource, SearchFilterTypesDto, SortOrdersDto, FieldFilterOperatorsDto, GetCkTypesDtoGQL, GetCkModelByIdDtoGQL, GraphDirectionDto, CkTypeMetaData, AssociationModOptionsDto, GraphQL, BinaryDownloadUnavailableError, isSecretAttributeCandidate, toUniqueCamelCaseNames, toCamelCaseAttributeName, DeleteStrategiesDto, CommunicationService, provideOctoServices } from '@meshmakers/octo-services';
|
|
5
5
|
import { Roles, provideMmSharedAuth } from '@meshmakers/shared-auth';
|
|
6
6
|
import { WindowStateService, EntitySelectInputComponent, DataSourceTyped, HierarchyDataSourceBase, NotificationDisplayService, TreeComponent, ListViewComponent, FetchResultTyped, DataSourceBase, MM_ACTION_ICONS, ConfirmationService, InputService, BaseTreeDetailComponent, provideMmSharedUi } from '@meshmakers/shared-ui';
|
|
7
7
|
import * as i1$2 from '@angular/common';
|
|
@@ -2077,6 +2077,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
2077
2077
|
type: Output
|
|
2078
2078
|
}] } });
|
|
2079
2079
|
|
|
2080
|
+
/**
|
|
2081
|
+
* Hands a binary download request to the host when one listens on `emitter`, otherwise downloads
|
|
2082
|
+
* the clicked value itself with the user's bearer through `FileDownloadService` (AB#6179).
|
|
2083
|
+
*
|
|
2084
|
+
* The service is resolved lazily at click time so that merely rendering a property grid never
|
|
2085
|
+
* requires `HttpClient` / `CONFIGURATION_SERVICE` to be provided.
|
|
2086
|
+
*/
|
|
2087
|
+
function emitOrDownloadBinary(emitter, event, injector) {
|
|
2088
|
+
if (emitter.observed) {
|
|
2089
|
+
emitter.emit(event);
|
|
2090
|
+
return;
|
|
2091
|
+
}
|
|
2092
|
+
let downloads;
|
|
2093
|
+
try {
|
|
2094
|
+
downloads = injector.get(FileDownloadService);
|
|
2095
|
+
}
|
|
2096
|
+
catch (error) {
|
|
2097
|
+
console.error('Cannot download binary: FileDownloadService is not available', error);
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
downloads.downloadBinary(event).catch(error => {
|
|
2101
|
+
console.error('Binary download failed:', error);
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2080
2105
|
/**
|
|
2081
2106
|
* A secret record member as projected by the server (AB#5528): the marker `{ isSet }` (optionally
|
|
2082
2107
|
* with `keyMissing` / `setAt`), or a normalised `SecretState`. Nothing else has exactly these keys.
|
|
@@ -2097,6 +2122,7 @@ class PropertyValueDisplayComponent {
|
|
|
2097
2122
|
// Expansion state
|
|
2098
2123
|
isExpanded = false;
|
|
2099
2124
|
windowService = inject(WindowService);
|
|
2125
|
+
injector = inject(Injector);
|
|
2100
2126
|
locale = inject(LOCALE_ID);
|
|
2101
2127
|
/** Non-null when the value is a secret state (SECRET value type or record member marker). */
|
|
2102
2128
|
secretStatus = null;
|
|
@@ -2541,25 +2567,27 @@ class PropertyValueDisplayComponent {
|
|
|
2541
2567
|
return `${size.toFixed(unitIndex > 0 ? 1 : 0)} ${units[unitIndex]}`;
|
|
2542
2568
|
}
|
|
2543
2569
|
/**
|
|
2544
|
-
* Handle download button click
|
|
2570
|
+
* Handle download button click.
|
|
2571
|
+
*
|
|
2572
|
+
* Emits {@link binaryDownload} with the clicked value when a host listens. Without a listener the
|
|
2573
|
+
* component downloads the value itself through `FileDownloadService` — an authenticated blob
|
|
2574
|
+
* download with the user's bearer, never `window.open(rawUrl)`, which carries no token (AB#6179).
|
|
2545
2575
|
*/
|
|
2546
2576
|
onDownload() {
|
|
2547
2577
|
if (!this.value || typeof this.value !== 'object') {
|
|
2548
2578
|
return;
|
|
2549
2579
|
}
|
|
2550
2580
|
const binaryValue = this.value;
|
|
2551
|
-
if (binaryValue.downloadUri) {
|
|
2552
|
-
window.open(binaryValue.downloadUri, '_blank', 'noopener,noreferrer');
|
|
2581
|
+
if (!binaryValue.downloadUri && !binaryValue.binaryId) {
|
|
2553
2582
|
return;
|
|
2554
2583
|
}
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
}
|
|
2584
|
+
const event = {
|
|
2585
|
+
binaryId: binaryValue.binaryId,
|
|
2586
|
+
filename: binaryValue.filename,
|
|
2587
|
+
contentType: binaryValue.contentType,
|
|
2588
|
+
downloadUri: binaryValue.downloadUri
|
|
2589
|
+
};
|
|
2590
|
+
emitOrDownloadBinary(this.binaryDownload, event, this.injector);
|
|
2563
2591
|
}
|
|
2564
2592
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PropertyValueDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2565
2593
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: PropertyValueDisplayComponent, isStandalone: true, selector: "mm-property-value-display", inputs: { value: "value", type: "type", displayMode: "displayMode", attributeName: "attributeName" }, outputs: { binaryDownload: "binaryDownload" }, usesOnChanges: true, ngImport: i0, template: `
|
|
@@ -2885,6 +2913,7 @@ class PropertyGridComponent {
|
|
|
2885
2913
|
propertyChange = new EventEmitter();
|
|
2886
2914
|
saveRequested = new EventEmitter();
|
|
2887
2915
|
binaryDownload = new EventEmitter();
|
|
2916
|
+
injector = inject(Injector);
|
|
2888
2917
|
// Component state
|
|
2889
2918
|
filteredData = [];
|
|
2890
2919
|
searchTerm = '';
|
|
@@ -3019,10 +3048,11 @@ class PropertyGridComponent {
|
|
|
3019
3048
|
this.propertyChange.emit(changeEvent);
|
|
3020
3049
|
}
|
|
3021
3050
|
/**
|
|
3022
|
-
* Handle binary download request from property value display
|
|
3051
|
+
* Handle binary download request from property value display: forwarded to the host when it binds
|
|
3052
|
+
* `(binaryDownload)`, otherwise downloaded here with the user's bearer (AB#6179).
|
|
3023
3053
|
*/
|
|
3024
3054
|
onBinaryDownload(event) {
|
|
3025
|
-
this.binaryDownload.
|
|
3055
|
+
emitOrDownloadBinary(this.binaryDownload, event, this.injector);
|
|
3026
3056
|
}
|
|
3027
3057
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PropertyGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3028
3058
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: PropertyGridComponent, isStandalone: true, selector: "mm-property-grid", inputs: { data: "data", config: "config", showTypeColumn: "showTypeColumn", messages: "messages" }, outputs: { propertyChange: "propertyChange", saveRequested: "saveRequested", binaryDownload: "binaryDownload" }, usesOnChanges: true, ngImport: i0, template: `
|
|
@@ -9759,41 +9789,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
9759
9789
|
}]
|
|
9760
9790
|
}], ctorParameters: () => [{ type: i1$3.Apollo }] });
|
|
9761
9791
|
|
|
9762
|
-
const GetBinaryInfoDocumentDto = gql `
|
|
9763
|
-
query getBinaryInfo($rtId: OctoObjectId!) {
|
|
9764
|
-
runtime {
|
|
9765
|
-
systemReportingFileSystemItem(rtId: $rtId) {
|
|
9766
|
-
items {
|
|
9767
|
-
rtId
|
|
9768
|
-
ckTypeId
|
|
9769
|
-
name
|
|
9770
|
-
content {
|
|
9771
|
-
binaryId
|
|
9772
|
-
size
|
|
9773
|
-
contentType
|
|
9774
|
-
filename
|
|
9775
|
-
downloadUri
|
|
9776
|
-
}
|
|
9777
|
-
}
|
|
9778
|
-
}
|
|
9779
|
-
}
|
|
9780
|
-
}
|
|
9781
|
-
`;
|
|
9782
|
-
class GetBinaryInfoDtoGQL extends i1$3.Query {
|
|
9783
|
-
document = GetBinaryInfoDocumentDto;
|
|
9784
|
-
constructor(apollo) {
|
|
9785
|
-
super(apollo);
|
|
9786
|
-
}
|
|
9787
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: GetBinaryInfoDtoGQL, deps: [{ token: i1$3.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
9788
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: GetBinaryInfoDtoGQL, providedIn: 'root' });
|
|
9789
|
-
}
|
|
9790
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: GetBinaryInfoDtoGQL, decorators: [{
|
|
9791
|
-
type: Injectable,
|
|
9792
|
-
args: [{
|
|
9793
|
-
providedIn: 'root'
|
|
9794
|
-
}]
|
|
9795
|
-
}], ctorParameters: () => [{ type: i1$3.Apollo }] });
|
|
9796
|
-
|
|
9797
9792
|
class EntityAssociationsDataSourceDirective extends OctoGraphQlDataSource {
|
|
9798
9793
|
getAssociationsGQL = inject(GetRuntimeEntityAssociationsByIdDtoGQL);
|
|
9799
9794
|
rtId = null;
|
|
@@ -9983,7 +9978,7 @@ const DEFAULT_RUNTIME_BROWSER_MESSAGES = {
|
|
|
9983
9978
|
copiedToClipboard: 'copied to clipboard',
|
|
9984
9979
|
failedToCopyToClipboard: 'Failed to copy to clipboard',
|
|
9985
9980
|
downloadNotAvailable: 'Download not available for this file',
|
|
9986
|
-
failedToLoadDownloadInfo: 'Failed to
|
|
9981
|
+
failedToLoadDownloadInfo: 'Failed to download the file',
|
|
9987
9982
|
missingRequiredIdentifiers: 'Missing required identifiers to create an entity.',
|
|
9988
9983
|
failedToCreateEntity: 'Failed to create entity. Please try again.',
|
|
9989
9984
|
failedToUpdateEntity: 'Failed to update entity. Please try again.',
|
|
@@ -10332,7 +10327,7 @@ class EntityDetailViewComponent {
|
|
|
10332
10327
|
associationsDataSource;
|
|
10333
10328
|
notificationService = inject(NotificationService);
|
|
10334
10329
|
propertyConverter = inject(PropertyConverterService);
|
|
10335
|
-
|
|
10330
|
+
fileDownloadService = inject(FileDownloadService);
|
|
10336
10331
|
_messages = {
|
|
10337
10332
|
...DEFAULT_RUNTIME_BROWSER_MESSAGES,
|
|
10338
10333
|
};
|
|
@@ -10547,25 +10542,20 @@ class EntityDetailViewComponent {
|
|
|
10547
10542
|
}
|
|
10548
10543
|
/**
|
|
10549
10544
|
* Handle binary download request from property grid.
|
|
10550
|
-
*
|
|
10545
|
+
*
|
|
10546
|
+
* Downloads the clicked attribute's own value — whatever CK type owns it (Basic File,
|
|
10547
|
+
* System.Communication binaries, FileSystemItem, …) and whether or not the tenant has
|
|
10548
|
+
* System.Reporting. The value is the stored binary info `{ binaryId, filename, contentType, size }`
|
|
10549
|
+
* (plus `downloadUri` when a typed query supplied one); `FileDownloadService` fetches it with the
|
|
10550
|
+
* user's bearer and saves it under its real file name (AB#6179, decision D9).
|
|
10551
10551
|
*/
|
|
10552
|
-
async onBinaryDownload(
|
|
10553
|
-
if (!this.entity?.rtId) {
|
|
10554
|
-
console.warn('Cannot download: no entity rtId available');
|
|
10555
|
-
return;
|
|
10556
|
-
}
|
|
10552
|
+
async onBinaryDownload(event) {
|
|
10557
10553
|
try {
|
|
10558
|
-
|
|
10559
|
-
|
|
10560
|
-
|
|
10561
|
-
|
|
10562
|
-
|
|
10563
|
-
if (item?.content?.downloadUri) {
|
|
10564
|
-
// Open download in new tab
|
|
10565
|
-
window.open(item.content.downloadUri, '_blank', 'noopener,noreferrer');
|
|
10566
|
-
}
|
|
10567
|
-
else {
|
|
10568
|
-
console.warn('No downloadUri found for binary');
|
|
10554
|
+
await this.fileDownloadService.downloadBinary(event);
|
|
10555
|
+
}
|
|
10556
|
+
catch (error) {
|
|
10557
|
+
if (error instanceof BinaryDownloadUnavailableError) {
|
|
10558
|
+
console.warn('Binary download not available:', error.message);
|
|
10569
10559
|
this.notificationService.show({
|
|
10570
10560
|
content: this._messages.downloadNotAvailable,
|
|
10571
10561
|
type: { style: 'warning', icon: true },
|
|
@@ -10573,10 +10563,9 @@ class EntityDetailViewComponent {
|
|
|
10573
10563
|
hideAfter: 3000,
|
|
10574
10564
|
animation: { type: 'fade', duration: 400 },
|
|
10575
10565
|
});
|
|
10566
|
+
return;
|
|
10576
10567
|
}
|
|
10577
|
-
|
|
10578
|
-
catch (error) {
|
|
10579
|
-
console.error('Failed to load binary info:', error);
|
|
10568
|
+
console.error('Binary download failed:', error);
|
|
10580
10569
|
this.notificationService.show({
|
|
10581
10570
|
content: this._messages.failedToLoadDownloadInfo,
|
|
10582
10571
|
type: { style: 'error', icon: true },
|