Skip to content

NIFI-15854 - Support asset property types for connectors#11193

Open
rfellows wants to merge 4 commits intoapache:mainfrom
rfellows:NIFI-15854
Open

NIFI-15854 - Support asset property types for connectors#11193
rfellows wants to merge 4 commits intoapache:mainfrom
rfellows:NIFI-15854

Conversation

@rfellows
Copy link
Copy Markdown
Contributor

@rfellows rfellows commented May 1, 2026

Summary

NIFI-15854

Connector property descriptors of type ASSET and ASSET_LIST previously rendered as
plain text inputs in the connector configuration wizard, with no way to upload, browse,
or remove files. Users could not configure connectors that require uploaded assets
(keystores, credentials JSON, certificates, etc.) without manually constructing value
references. This change adds a first-class asset-upload experience to the wizard so
those property types can be configured end-to-end from the UI.

Changes

  • New AssetUpload component (libs/shared/src/components/asset-upload/) — a reusable,
    reactive-form-friendly file upload control that presents a drop zone, a Browse button,
    the list of uploaded assets, in-flight upload progress bars, and a dismiss affordance
    for failed uploads. Implements ControlValueAccessor so it can be bound directly with
    [formControl]. Supports both single-file and multi-file modes via a multiple input
    and accepts optional allowedFileTypes and maxFileSize constraints.
  • New DragAndDropDirective (libs/shared/src/directives/drag-and-drop/) — applies
    drop-allowed / drop-invalid host classes during dragover, validates dropped file
    count, type, and size against the host's configured constraints, and emits
    filesDropped (FileList) and invalidDrop (string) events. File-extension matching is
    case-insensitive.
  • ConnectorPropertyInput now renders <asset-upload> for property descriptors of
    type ASSET (single) and ASSET_LIST (multi). Two predicates (shouldUseAssetUpload
    and isMultipleAssets) drive the conditional render, and three forwarder methods
    (onAssetFilesSelected, onAssetDeleteRequested, onDismissFailedUpload) re-emit the
    child events on the component's existing outputs so the parent
    connector-configuration-step can drive uploads via the existing UploadService and
    ConnectorConfigurationService.createAssetUploadRequest.
  • The asset block surfaces validation through bare <mat-error> elements for the
    existing required, assetContentMissing, and verificationError validators, plus a
    <mat-hint> for the property description. The description hint is suppressed while a
    touched validation error is visible to avoid duplicated guidance.
  • Dead shouldUseTextInput() helper removed from ConnectorPropertyInput.
  • Barrel exports added in libs/shared/src/components/index.ts and
    libs/shared/src/directives/index.ts.

Out of scope

This change is purely the wizard UI surface for asset properties. It deliberately does
not touch:

  • The POST /connectors/{id}/assets HTTP contract — already handled by UploadService.
  • The wizard store — addAsset, removeAsset, currentAssets, and
    assetUploadProgress were already in place.
  • The serialization of form values to ConnectorValueReference in
    value-reference.helper.ts.
  • The assetContentMissing validator in connector-validation.utils.ts.
  • The parent template wiring in connector-configuration-step.component.html, which
    already binds the asset-related inputs and outputs.

@rfellows rfellows added the ui Pull requests for work relating to the user interface label May 1, 2026
@scottyaslan
Copy link
Copy Markdown
Contributor

Reviewing...

Comment on lines +66 to +70
.upload-icon {
color: var(--mat-sys-on-surface-variant);
font-size: 18px;
line-height: 1;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.upload-icon {
color: var(--mat-sys-on-surface-variant);
font-size: 18px;
line-height: 1;
}

@if (assets.length === 0 && uploadProgress.length === 0) {
<div class="flex flex-col items-center justify-center gap-3 p-2">
<div class="flex items-center gap-2">
<i class="fa fa-cloud-upload upload-icon" aria-hidden="true"></i>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<i class="fa fa-cloud-upload upload-icon" aria-hidden="true"></i>
<i class="fa fa-cloud-upload" aria-hidden="true"></i>

(invalidDrop)="onInvalidDrop($event)"
data-qa="asset-drop-zone">
@if (assets.length === 0 && uploadProgress.length === 0) {
<div class="flex flex-col items-center justify-center gap-3 p-2">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<div class="flex flex-col items-center justify-center gap-3 p-2">
<div class="flex flex-col items-center justify-center gap-3">

[class.progress-bar-critical]="progress.status === 'error'">
</mat-progress-bar>
@if (progress.status === 'active') {
<span class="text-sm mr-2 whitespace-nowrap">{{ progress.percentComplete }}%</span>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the other mat-progress-bar usages throughout nifi:

Suggested change
<span class="text-sm mr-2 whitespace-nowrap">{{ progress.percentComplete }}%</span>
<span class="tertiary-color font-medium">{{ progress.percentComplete }}%</span>

Comment on lines +72 to +78
.progress-item.error {
border-color: var(--mat-sys-error);
}

.mat-mdc-progress-bar.progress-bar-critical {
--mdc-linear-progress-active-indicator-color: var(--mat-sys-error);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use mat-progress-bar color input instead.

Suggested change
.progress-item.error {
border-color: var(--mat-sys-error);
}
.mat-mdc-progress-bar.progress-bar-critical {
--mdc-linear-progress-active-indicator-color: var(--mat-sys-error);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that while we do have the mat-progress-bar in our design system toolbox here we do NOT have any success, caution, and error theming.

I was trying to work around this by leveraging the color input but as you said that is a no-op because we are using M3 and it's tokens and the theming mixins etc.

I also see that you attempted to do something similar with a mat-progress-bar in the connector-verification-progress-dialog.component.scss and template.

We need to clean up these styles. It is obvious we have a need to add support for a success, caution, and error state to the mat-progress-bar design system component. Something like:

@use '@angular/material' as mat;

@mixin generate-material-theme() {
    :root {
        .progress-bar-success {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-primary),
            ));
        }

        .progress-bar-caution {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--nf-caution-default),
            ));
        }

        .progress-bar-error {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-error),
            ));
        }
    }

    .darkMode {
        .progress-bar-success {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-primary),
            ));
        }

        .progress-bar-caution {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--nf-caution-default),
            ));
        }

        .progress-bar-error {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-error),
            ));
        }
    }
}

somewhere towards the bottom of _app.scss generate-material-theme() mixin.

Comment on lines +72 to +78
.progress-item.error {
border-color: var(--mat-sys-error);
}

.mat-mdc-progress-bar.progress-bar-critical {
--mdc-linear-progress-active-indicator-color: var(--mat-sys-error);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that while we do have the mat-progress-bar in our design system toolbox here we do NOT have any success, caution, and error theming.

I was trying to work around this by leveraging the color input but as you said that is a no-op because we are using M3 and it's tokens and the theming mixins etc.

I also see that you attempted to do something similar with a mat-progress-bar in the connector-verification-progress-dialog.component.scss and template.

We need to clean up these styles. It is obvious we have a need to add support for a success, caution, and error state to the mat-progress-bar design system component. Something like:

@use '@angular/material' as mat;

@mixin generate-material-theme() {
    :root {
        .progress-bar-success {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-primary),
            ));
        }

        .progress-bar-caution {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--nf-caution-default),
            ));
        }

        .progress-bar-error {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-error),
            ));
        }
    }

    .darkMode {
        .progress-bar-success {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-primary),
            ));
        }

        .progress-bar-caution {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--nf-caution-default),
            ));
        }

        .progress-bar-error {
            @include mat.progress-bar-overrides((
                active-indicator-color: var(--mat-sys-error),
            ));
        }
    }
}

somewhere towards the bottom of _app.scss generate-material-theme() mixin.

rfellows added 2 commits May 5, 2026 14:54
…ng a failed upload by reconciling form-shape unsaved values against API-shape AssetReferences in initializeForm.
Copy link
Copy Markdown
Contributor

@scottyaslan scottyaslan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more minor things.

background-color: var(--nf-caution-default);
}

/* progress-bar status overrides */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but could you please move these down? There are some other component overrides towards the bottom for mat-select and mat-option. This belongs there.

data-qa="property-input-asset-upload">
</asset-upload>
@if (prop.description && (!parentControl?.invalid || !parentControl?.touched)) {
<mat-hint class="text-xs">{{ prop.description }}</mat-hint>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mat-hint should already adhere to the design system

Suggested change
<mat-hint class="text-xs">{{ prop.description }}</mat-hint>
<mat-hint>{{ prop.description }}</mat-hint>

<mat-hint class="text-xs">{{ prop.description }}</mat-hint>
}
@if (parentControl?.hasError('required') && parentControl?.touched) {
<mat-error class="error-color text-xs" data-qa="property-input-asset-required-error">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't mat-error already colored correctly?

Suggested change
<mat-error class="error-color text-xs" data-qa="property-input-asset-required-error">
<mat-error data-qa="property-input-asset-required-error">

</mat-error>
}
@if (parentControl?.hasError('assetContentMissing') && parentControl?.touched) {
<mat-error class="error-color text-xs" data-qa="property-input-asset-missing-error">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mat-error should already adhere to the design system

Suggested change
<mat-error class="error-color text-xs" data-qa="property-input-asset-missing-error">
<mat-error data-qa="property-input-asset-missing-error">

</mat-error>
}
@if (parentControl?.hasError('verificationError')) {
<mat-error class="error-color text-xs" data-qa="property-input-asset-verification-error">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<mat-error class="error-color text-xs" data-qa="property-input-asset-verification-error">
<mat-error data-qa="property-input-asset-verification-error">

Comment on lines +51 to +56
<div
class="asset-item-missing-content caution-color-background flex items-center justify-between gap-3 px-3 py-2 border rounded-md min-h-[44px]"
data-qa="uploaded-asset-missing-content">
<div class="flex items-start gap-2 min-w-0 flex-1">
<i
class="fa fa-warning caution-color shrink-0"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue here now is that the caution-color-background and the caution-color are defined in _app.scss as:

.caution-color {
        color: var(--nf-caution-default);
        fill: var(--nf-caution-default);
    }

    .caution-color-background {
        background-color: var(--nf-caution-default);
    }

So here the icon will be the same color as the background. Typically in nifi we do not color text or surfaces with really anything outside of what the design system provides. Is it necessary here? Do you need the caution-color-background applied to the container? Typically in our listings when we show the fa-warning icon for an invalid extension for example the icon is caution-colored but the surface is uncustomized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui Pull requests for work relating to the user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants