Skip to content

Commit

Permalink
NIFI-13632: Addressing review feedback.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcgilman committed Aug 30, 2024
1 parent 524d810 commit 91c94b4
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
<form [formGroup]="viewerForm">
<mat-form-field subscriptSizing="dynamic" class="w-72">
<mat-label>View</mat-label>
<mat-select formControlName="viewAs" (selectionChange)="viewAsChanged($event)">
<mat-select
formControlName="viewAs"
(selectionChange)="viewAsChanged($event)"
[panelWidth]="panelWidth">
@for (groupOption of viewAsOptions; track groupOption.text) {
@if (groupOption.options.length > 1) {
<mat-optgroup [label]="groupOption.text">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { loadContentViewerOptions, resetContentViewerOptions } from '../state/vi
import { FormBuilder, FormGroup } from '@angular/forms';
import { selectBundledViewerOptions, selectViewerOptions } from '../state/viewer-options/viewer-options.selectors';
import { ContentViewer, HEX_VIEWER_URL, SupportedMimeTypes } from '../state/viewer-options';
import { isDefinedAndNotNull, SelectGroup, SelectOption, selectQueryParams } from '@nifi/shared';
import { isDefinedAndNotNull, NiFiCommon, SelectGroup, SelectOption, selectQueryParams } from '@nifi/shared';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { concatLatestFrom } from '@ngrx/operators';
import { navigateToBundledContentViewer, resetContent, setRef } from '../state/content/content.actions';
Expand All @@ -31,6 +31,12 @@ import { loadAbout } from '../../../state/about/about.actions';
import { selectAbout } from '../../../state/about/about.selectors';
import { filter, map, switchMap, take } from 'rxjs';
import { navigateToExternalViewer } from '../state/external-viewer/external-viewer.actions';
import { snackBarError } from '../../../state/error';

interface SupportedContentViewer {
supportedMimeTypes: SupportedMimeTypes;
contentViewer: ContentViewer;
}

@Component({
selector: 'content-viewer',
Expand All @@ -40,24 +46,27 @@ import { navigateToExternalViewer } from '../state/external-viewer/external-view
export class ContentViewerComponent implements OnInit, OnDestroy {
viewerForm: FormGroup;
viewAsOptions: SelectGroup[] = [];
panelWidth: string | null = 'auto';

private supportedMimeTypeId = 0;
private supportedMimeTypeLookup: Map<number, SupportedMimeTypes> = new Map<number, SupportedMimeTypes>();
private supportedMimeTypeContentViewerLookup: Map<number, ContentViewer> = new Map<number, ContentViewer>();
private mimeTypeDisplayNameLookup: Map<number, string> = new Map<number, string>();
private supportedContentViewerLookup: Map<number, SupportedContentViewer> = new Map<
number,
SupportedContentViewer
>();
private mimeTypeIdsSupportedByBundledUis: Set<number> = new Set<number>();

private defaultSupportedMimeTypeId: number | null = null;

viewerSelected: boolean = false;
private mimeType: string | undefined;
mimeType: string | undefined;
private clientId: string | undefined;

private queryParamsLoaded = false;
private viewerOptionsLoaded = false;

constructor(
private store: Store<NiFiState>,
private nifiCommon: NiFiCommon,
private formBuilder: FormBuilder
) {
this.viewerForm = this.formBuilder.group({ viewAs: null });
Expand All @@ -70,72 +79,90 @@ export class ContentViewerComponent implements OnInit, OnDestroy {
takeUntilDestroyed()
)
.subscribe(([externalViewerOptions, bundledViewerOptions]) => {
this.supportedMimeTypeLookup.clear();
this.supportedMimeTypeContentViewerLookup.clear();
this.supportedContentViewerLookup.clear();
this.mimeTypeIdsSupportedByBundledUis.clear();
this.mimeTypeDisplayNameLookup.clear();

// maps a given content (by display name) to the supported mime type id
// which can be used to look up the corresponding content viewer
const supportedMimeTypeMapping = new Map<string, number[]>();

// process all external viewer options
externalViewerOptions.forEach((contentViewer) => {
contentViewer.supportedMimeTypes.forEach((supportedMimeType) => {
contentViewer.supportedMimeTypes.forEach((supportedMimeTypes) => {
const supportedMimeTypeId = this.supportedMimeTypeId++;

if (!supportedMimeTypeMapping.has(supportedMimeType.displayName)) {
supportedMimeTypeMapping.set(supportedMimeType.displayName, []);
if (!supportedMimeTypeMapping.has(supportedMimeTypes.displayName)) {
supportedMimeTypeMapping.set(supportedMimeTypes.displayName, []);
}
supportedMimeTypeMapping.get(supportedMimeType.displayName)?.push(supportedMimeTypeId);
supportedMimeTypeMapping.get(supportedMimeTypes.displayName)?.push(supportedMimeTypeId);

this.supportedMimeTypeLookup.set(supportedMimeTypeId, supportedMimeType);
this.supportedMimeTypeContentViewerLookup.set(supportedMimeTypeId, contentViewer);
this.supportedContentViewerLookup.set(supportedMimeTypeId, {
supportedMimeTypes,
contentViewer
});
});
});

// process all bundled options
bundledViewerOptions.forEach((contentViewer) => {
contentViewer.supportedMimeTypes.forEach((supportedMimeType) => {
contentViewer.supportedMimeTypes.forEach((supportedMimeTypes) => {
const supportedMimeTypeId = this.supportedMimeTypeId++;

if (contentViewer.uri === HEX_VIEWER_URL) {
this.defaultSupportedMimeTypeId = supportedMimeTypeId;
}

if (!supportedMimeTypeMapping.has(supportedMimeType.displayName)) {
supportedMimeTypeMapping.set(supportedMimeType.displayName, []);
if (!supportedMimeTypeMapping.has(supportedMimeTypes.displayName)) {
supportedMimeTypeMapping.set(supportedMimeTypes.displayName, []);
}
supportedMimeTypeMapping.get(supportedMimeType.displayName)?.push(supportedMimeTypeId);
supportedMimeTypeMapping.get(supportedMimeTypes.displayName)?.push(supportedMimeTypeId);

this.mimeTypeIdsSupportedByBundledUis.add(supportedMimeTypeId);
this.supportedMimeTypeLookup.set(supportedMimeTypeId, supportedMimeType);
this.supportedMimeTypeContentViewerLookup.set(supportedMimeTypeId, contentViewer);
this.supportedContentViewerLookup.set(supportedMimeTypeId, {
supportedMimeTypes,
contentViewer
});
});
});

const newViewAsOptions: SelectGroup[] = [];
supportedMimeTypeMapping.forEach((contentViewers, displayName) => {
const options: SelectOption[] = [];
contentViewers.forEach((contentViewerId) => {
this.mimeTypeDisplayNameLookup.set(contentViewerId, displayName);

const contentViewer = this.supportedMimeTypeContentViewerLookup.get(contentViewerId);
if (contentViewer) {
contentViewers.forEach((supportedMimeTypeId) => {
const supportedContentViewer = this.supportedContentViewerLookup.get(supportedMimeTypeId);
if (supportedContentViewer) {
const option: SelectOption = {
text: contentViewer.displayName,
value: String(contentViewerId)
text: supportedContentViewer.contentViewer.displayName,
value: String(supportedMimeTypeId)
};
options.push(option);
}
});

// if there is more than one content viewer for this mime type we sent the panel
// width to null which will allow the select menu to expand to the width of
// the content which will be a lengthy nar version string
if (options.length > 1) {
this.panelWidth = null;
}

// sort by option text
options.sort((a, b) => {
return this.nifiCommon.compareString(a.text, b.text);
});

const groupOption: SelectGroup = {
text: displayName,
options
};
newViewAsOptions.push(groupOption);
});

// sort by option text
newViewAsOptions.sort((a, b) => {
return this.nifiCommon.compareString(a.text, b.text);
});

this.viewAsOptions = newViewAsOptions;
this.viewerOptionsLoaded = true;

Expand Down Expand Up @@ -197,16 +224,22 @@ export class ContentViewerComponent implements OnInit, OnDestroy {
if (!this.viewerSelected) {
if (this.mimeType) {
const compatibleViewerOption = this.getCompatibleViewer(this.mimeType);
if (Number.isNaN(compatibleViewerOption)) {
if (!Number.isNaN(this.defaultSupportedMimeTypeId)) {
if (compatibleViewerOption === null) {
if (this.defaultSupportedMimeTypeId !== null) {
this.viewerForm.get('viewAs')?.setValue(String(this.defaultSupportedMimeTypeId));
this.loadBundledContentViewer(this.defaultSupportedMimeTypeId);
}

this.store.dispatch(
snackBarError({
error: `No compatible content viewer found for mime type [${this.mimeType}]`
})
);
} else {
this.viewerForm.get('viewAs')?.setValue(String(compatibleViewerOption));
this.loadBundledContentViewer(compatibleViewerOption);
}
} else if (!Number.isNaN(this.defaultSupportedMimeTypeId)) {
} else if (this.defaultSupportedMimeTypeId !== null) {
this.viewerForm.get('viewAs')?.setValue(String(this.defaultSupportedMimeTypeId));
this.loadBundledContentViewer(this.defaultSupportedMimeTypeId);
}
Expand All @@ -217,10 +250,10 @@ export class ContentViewerComponent implements OnInit, OnDestroy {
for (const group of this.viewAsOptions) {
for (const option of group.options) {
const supportedMimeTypeId: number = Number(option.value);
if (!Number.isNaN(supportedMimeTypeId)) {
const supportedMimeType = this.supportedMimeTypeLookup.get(supportedMimeTypeId);
if (supportedMimeType) {
if (supportedMimeType.mimeTypes.includes(mimeType)) {
if (Number.isInteger(supportedMimeTypeId)) {
const supportedContentViewer = this.supportedContentViewerLookup.get(supportedMimeTypeId);
if (supportedContentViewer) {
if (supportedContentViewer.supportedMimeTypes.mimeTypes.includes(mimeType)) {
return supportedMimeTypeId;
}
}
Expand All @@ -237,9 +270,11 @@ export class ContentViewerComponent implements OnInit, OnDestroy {

loadBundledContentViewer(value: number | null): void {
if (value !== null) {
const viewer = this.supportedMimeTypeContentViewerLookup.get(value);
const supportedContentViewer = this.supportedContentViewerLookup.get(value);

if (supportedContentViewer) {
const viewer = supportedContentViewer.contentViewer;

if (viewer) {
this.viewerSelected = true;

if (this.mimeTypeIdsSupportedByBundledUis.has(value)) {
Expand All @@ -249,18 +284,15 @@ export class ContentViewerComponent implements OnInit, OnDestroy {
})
);
} else {
const mimeTypeDisplayName = this.mimeTypeDisplayNameLookup.get(value);
if (mimeTypeDisplayName) {
this.store.dispatch(
navigateToExternalViewer({
request: {
url: viewer.uri,
mimeTypeDisplayName,
clientId: this.clientId
}
})
);
}
this.store.dispatch(
navigateToExternalViewer({
request: {
url: viewer.uri,
mimeTypeDisplayName: supportedContentViewer.supportedMimeTypes.displayName,
clientId: this.clientId
}
})
);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export class StandardContentViewer {
if (this.ref && this.mimeTypeDisplayName) {
this.setMode(this.mimeTypeDisplayName);

this.contentLoaded = false;

const formatted: string = this.contentFormGroup.get('formatted')?.value;
this.contentViewerService
.getContent(this.ref, this.mimeTypeDisplayName, formatted, this.clientId)
Expand Down Expand Up @@ -110,7 +112,7 @@ export class StandardContentViewer {
this.mode = 'application/xml';
break;
case 'yaml':
this.mode = 'application/yaml';
this.mode = 'text/x-yaml';
break;
case 'text':
this.mode = 'text/plain';
Expand Down

0 comments on commit 91c94b4

Please sign in to comment.