diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer index 94b1c6398602..106a71c4cebd 100644 --- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer @@ -12,9 +12,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -xml=application/xml,text/xml -json=application/json +xml=application/xml,text/xml,application/*+xml +json=application/json,application/*+json text=text/plain csv=text/csv avro=avro/binary,application/avro-binary,application/avro+binary -yaml=text/x-yaml,text/yaml,text/yml,application/x-yaml,application/x-yml,application/yaml,application/yml \ No newline at end of file +yaml=text/x-yaml,text/yaml,text/yml,application/x-yaml,application/x-yml,application/yaml,application/yml,application/*+yaml \ No newline at end of file diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/content-viewer/feature/content-viewer.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/content-viewer/feature/content-viewer.component.ts index e56fdbbd2d1c..7d7984f5b405 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/content-viewer/feature/content-viewer.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/content-viewer/feature/content-viewer.component.ts @@ -255,7 +255,7 @@ export class ContentViewerComponent implements OnInit, OnDestroy { const supportedContentViewer = this.supportedContentViewerLookup.get(supportedMimeTypeId); if (supportedContentViewer) { const supportsMimeType = supportedContentViewer.supportedMimeTypes.mimeTypes.some( - (supportedMimeType) => mimeType.startsWith(supportedMimeType) + (supportedMimeType) => this.isMediaTypeCompatible(mimeType, supportedMimeType) ); if (supportsMimeType) { @@ -269,6 +269,34 @@ export class ContentViewerComponent implements OnInit, OnDestroy { return null; } + /** + * Checks if a MIME type is compatible with a supported media type pattern. + * Supports patterns like "application/*+xml" which match "application/fhir+xml". + */ + private isMediaTypeCompatible(mimeType: string, supportedMimeType: string): boolean { + // Check for exact match or startsWith match + if (mimeType === supportedMimeType || mimeType.startsWith(supportedMimeType)) { + return true; + } + + // Check for wildcard patterns like "application/*+xml" + if (supportedMimeType.includes('/*+')) { + // Parse pattern: "application/*+xml" -> type="application", suffix="+xml" + const patternMatch = supportedMimeType.match(/^([^/]+)\/\*(\+.+)$/); + if (patternMatch) { + const [, patternType, patternSuffix] = patternMatch; + // Parse mimeType: "application/fhir+xml" -> type="application", suffix="+xml" + const mimeMatch = mimeType.match(/^([^/]+)\/[^+]+(\+.+)$/); + if (mimeMatch) { + const [, mimeTypeType, mimeTypeSuffix] = mimeMatch; + return patternType === mimeTypeType && patternSuffix === mimeTypeSuffix; + } + } + } + + return false; + } + viewAsChanged(event: MatSelectChange): void { this.loadContentViewer(Number(event.value)); }