mirror of https://github.com/apache/nifi.git
NIFI-13650: Fixing condition when including References Parameter... o… (#9174)
* NIFI-13650: Fixing condition when including References Parameter option. - Updating property editors to better convey different parameter states. - Updating hint tooltip to indicate that parameters are supported but no parameter context is bound. - Fixing minor layout issue in Processor schedule tab. - Fix combo editor unit tests. * NIFI-13650: Fixing track warning errors when editing Parameter Contexts. * NIFI-13650: Fixing z-index autocomplete issue. This closes #9174
This commit is contained in:
parent
e4ec0cb20d
commit
38f4110521
|
@ -15,10 +15,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
ul.CodeMirror-hints {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
div.el-section {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
<div class="flex gap-x-4">
|
||||
<div class="w-44">
|
||||
<div class="w-1/2">
|
||||
<mat-form-field>
|
||||
<mat-label>
|
||||
Concurrent Tasks
|
||||
|
@ -163,7 +163,7 @@
|
|||
[readonly]="readonly" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="w-44">
|
||||
<div class="w-1/2">
|
||||
<mat-form-field>
|
||||
<mat-label>
|
||||
Run Schedule
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<div class="w-full flex flex-col">
|
||||
<div>Steps To Update Parameters</div>
|
||||
<div class="flex flex-col gap-y-1.5">
|
||||
@for (updateStep of requestEntity.request.updateSteps; track updateStep) {
|
||||
@for (updateStep of requestEntity.request.updateSteps; track updateStep.description) {
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="accent-color font-medium">
|
||||
{{ updateStep.description }}
|
||||
|
|
|
@ -259,6 +259,7 @@ export interface ElFunctionTipInput {
|
|||
export interface PropertyHintTipInput {
|
||||
supportsEl: boolean;
|
||||
supportsParameters: boolean;
|
||||
hasParameterContext: boolean;
|
||||
}
|
||||
|
||||
export interface RestrictionsTipInput {
|
||||
|
@ -372,6 +373,11 @@ export interface ParameterContextReference {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface ParameterConfig {
|
||||
supportsParameters: boolean;
|
||||
parameters: Parameter[] | null;
|
||||
}
|
||||
|
||||
export interface AffectedComponentEntity {
|
||||
permissions: Permissions;
|
||||
id: string;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
@if (parameterReferenceMap == null || parameterReferenceMap.size == 0) {
|
||||
<div class="accent-color font-medium">No referencing components</div>
|
||||
} @else {
|
||||
@for (pg of processGroups; track pg) {
|
||||
@for (pg of processGroups; track pg.id) {
|
||||
<ng-container *ngTemplateOutlet="pgListing; context: { $implicit: pg }"></ng-container>
|
||||
}
|
||||
<ng-template #pgListing let-pg>
|
||||
|
@ -55,7 +55,7 @@
|
|||
<li>
|
||||
<h4 class="accent-color">Processors ({{ references.length }})</h4>
|
||||
<div class="references">
|
||||
@for (reference of references; track reference) {
|
||||
@for (reference of references; track reference.component.id) {
|
||||
<div class="flex items-center gap-x-2">
|
||||
@if (isNonServiceInvalid(reference.component)) {
|
||||
<div
|
||||
|
@ -90,7 +90,7 @@
|
|||
<li>
|
||||
<h4 class="accent-color">Controller Services ({{ references.length }})</h4>
|
||||
<div class="references">
|
||||
@for (service of references; track service) {
|
||||
@for (service of references; track service.component.id) {
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-x-2">
|
||||
@if (isServiceInvalid(service.component)) {
|
||||
|
@ -124,7 +124,7 @@
|
|||
<li>
|
||||
<h4 class="accent-color">Unauthorized ({{ references.length }})</h4>
|
||||
<div class="references">
|
||||
@for (reference of references; track reference) {
|
||||
@for (reference of references; track reference.id) {
|
||||
<div class="flex">
|
||||
<div class="unset surface-color">{{ reference.id }}</div>
|
||||
</div>
|
||||
|
|
|
@ -180,47 +180,50 @@ describe('ComboEditor', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('verify combo with parameter reference', () => {
|
||||
it('verify combo with parameter reference', async () => {
|
||||
if (item) {
|
||||
item.value = '#{one}';
|
||||
|
||||
component.item = item;
|
||||
component.parameters = parameters;
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
await fixture.whenStable();
|
||||
|
||||
const formValue = component.comboEditorForm.get('value')?.value;
|
||||
expect(component.itemLookup.get(formValue)?.value).toEqual(item?.value);
|
||||
expect(component.itemLookup.get(Number(formValue))?.value).toBeNull();
|
||||
expect(component.comboEditorForm.get('parameterReference')).toBeDefined();
|
||||
|
||||
const parameterReferenceValue = component.comboEditorForm.get('parameterReference')?.value;
|
||||
expect(component.itemLookup.get(parameterReferenceValue)?.value).toEqual(item?.value);
|
||||
expect(component.itemLookup.get(Number(parameterReferenceValue))?.value).toEqual(item.value);
|
||||
|
||||
jest.spyOn(component.ok, 'next');
|
||||
component.okClicked();
|
||||
expect(component.ok.next).toHaveBeenCalledWith(item?.value);
|
||||
});
|
||||
expect(component.ok.next).toHaveBeenCalledWith(item.value);
|
||||
}
|
||||
});
|
||||
|
||||
it('verify combo with missing parameter reference', () => {
|
||||
it('verify combo with missing parameter reference', async () => {
|
||||
if (item) {
|
||||
item.value = '#{three}';
|
||||
|
||||
component.item = item;
|
||||
component.parameters = parameters;
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
await fixture.whenStable();
|
||||
|
||||
const formValue = component.comboEditorForm.get('value')?.value;
|
||||
expect(component.itemLookup.get(formValue)?.value).toEqual('#{' + parameters[0].value + '}');
|
||||
expect(component.itemLookup.get(Number(formValue))?.value).toBeNull();
|
||||
expect(component.comboEditorForm.get('parameterReference')).toBeDefined();
|
||||
|
||||
// since the value does not match any parameters it should match the first
|
||||
const firstParameterValue = '#{' + parameters[0].name + '}';
|
||||
|
||||
const parameterReferenceValue = component.comboEditorForm.get('parameterReference')?.value;
|
||||
expect(component.itemLookup.get(parameterReferenceValue)?.value).toEqual(item?.value);
|
||||
expect(component.itemLookup.get(Number(parameterReferenceValue))?.value).toEqual(firstParameterValue);
|
||||
|
||||
jest.spyOn(component.ok, 'next');
|
||||
component.okClicked();
|
||||
expect(component.ok.next).toHaveBeenCalledWith('#{' + parameters[0].value + '}');
|
||||
});
|
||||
expect(component.ok.next).toHaveBeenCalledWith(firstParameterValue);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ import { MatInputModule } from '@angular/material/input';
|
|||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { NgForOf, NgIf, NgTemplateOutlet } from '@angular/common';
|
||||
import { AllowableValue, Parameter, PropertyDescriptor } from '../../../../../state/shared';
|
||||
import { AllowableValue, Parameter, ParameterConfig, PropertyDescriptor } from '../../../../../state/shared';
|
||||
import { MatOptionModule } from '@angular/material/core';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
|
@ -75,10 +75,9 @@ export class ComboEditor {
|
|||
this.initialAllowableValues();
|
||||
}
|
||||
|
||||
@Input() set parameters(parameters: Parameter[]) {
|
||||
this._parameters = parameters;
|
||||
|
||||
this.supportsParameters = parameters != null;
|
||||
@Input() set parameterConfig(parameterConfig: ParameterConfig) {
|
||||
this.parameters = parameterConfig.parameters;
|
||||
this.supportsParameters = parameterConfig.supportsParameters;
|
||||
this.initialAllowableValues();
|
||||
}
|
||||
@Input() width!: number;
|
||||
|
@ -105,7 +104,7 @@ export class ComboEditor {
|
|||
|
||||
itemSet = false;
|
||||
configuredValue: string | null = null;
|
||||
_parameters!: Parameter[];
|
||||
parameters: Parameter[] | null = null;
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
|
@ -181,14 +180,13 @@ export class ComboEditor {
|
|||
this.allowableValueChanged(this.referencesParametersId);
|
||||
}
|
||||
|
||||
const parameters: Parameter[] = this._parameters;
|
||||
if (parameters.length > 0) {
|
||||
if (this.parameters !== null && this.parameters.length > 0) {
|
||||
// capture the value of i which will be the id of the first
|
||||
// parameter
|
||||
this.configuredParameterId = i;
|
||||
|
||||
// create allowable values for each parameter
|
||||
parameters.forEach((parameter) => {
|
||||
this.parameters.forEach((parameter) => {
|
||||
const parameterItem: AllowableValueItem = {
|
||||
id: i++,
|
||||
displayName: parameter.name,
|
||||
|
|
|
@ -26,7 +26,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
|
|||
import { NgTemplateOutlet } from '@angular/common';
|
||||
import { NifiTooltipDirective, Resizable } from '@nifi/shared';
|
||||
import { PropertyHintTip } from '../../../tooltips/property-hint-tip/property-hint-tip.component';
|
||||
import { Parameter, PropertyHintTipInput } from '../../../../../state/shared';
|
||||
import { Parameter, ParameterConfig, PropertyHintTipInput } from '../../../../../state/shared';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { CodemirrorModule } from '@ctrl/ngx-codemirror';
|
||||
import { NfEl } from './modes/nfel';
|
||||
|
@ -74,8 +74,9 @@ export class NfEditor implements OnDestroy {
|
|||
this.loadParameters();
|
||||
}
|
||||
|
||||
@Input() set parameters(parameters: Parameter[] | null) {
|
||||
this._parameters = parameters;
|
||||
@Input() set parameterConfig(parameterConfig: ParameterConfig) {
|
||||
this.parameters = parameterConfig.parameters;
|
||||
this.supportsParameters = parameterConfig.supportsParameters;
|
||||
|
||||
this.getParametersSet = true;
|
||||
this.loadParameters();
|
||||
|
@ -98,7 +99,7 @@ export class NfEditor implements OnDestroy {
|
|||
blank = false;
|
||||
|
||||
mode!: string;
|
||||
_parameters!: Parameter[] | null;
|
||||
parameters: Parameter[] | null = null;
|
||||
|
||||
editor!: Editor;
|
||||
|
||||
|
@ -137,10 +138,8 @@ export class NfEditor implements OnDestroy {
|
|||
this.nfpr.setViewContainerRef(this.viewContainerRef, this.renderer);
|
||||
|
||||
if (this.getParametersSet) {
|
||||
if (this._parameters) {
|
||||
this.supportsParameters = true;
|
||||
|
||||
const parameters: Parameter[] = this._parameters;
|
||||
if (this.parameters) {
|
||||
const parameters: Parameter[] = this.parameters;
|
||||
if (this.supportsEl) {
|
||||
this.nfel.enableParameters();
|
||||
this.nfel.setParameters(parameters);
|
||||
|
@ -151,8 +150,6 @@ export class NfEditor implements OnDestroy {
|
|||
this.nfpr.configureAutocomplete();
|
||||
}
|
||||
} else {
|
||||
this.supportsParameters = false;
|
||||
|
||||
this.nfel.disableParameters();
|
||||
this.nfpr.disableParameters();
|
||||
|
||||
|
@ -187,7 +184,8 @@ export class NfEditor implements OnDestroy {
|
|||
getPropertyHintTipData(): PropertyHintTipInput {
|
||||
return {
|
||||
supportsEl: this.supportsEl,
|
||||
supportsParameters: this.supportsParameters
|
||||
supportsParameters: this.supportsParameters,
|
||||
hasParameterContext: this.parameters !== null
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@
|
|||
@if (hasAllowableValues(editorItem)) {
|
||||
<combo-editor
|
||||
[item]="editorItem"
|
||||
[parameters]="editorParameters || []"
|
||||
[parameterConfig]="editorParameterConfig"
|
||||
[width]="editorWidth"
|
||||
[readonly]="isDisabled"
|
||||
(ok)="savePropertyValue(editorItem, $event)"
|
||||
|
@ -188,7 +188,7 @@
|
|||
} @else {
|
||||
<nf-editor
|
||||
[item]="editorItem"
|
||||
[parameters]="editorParameters"
|
||||
[parameterConfig]="editorParameterConfig"
|
||||
[width]="editorWidth"
|
||||
[readonly]="isDisabled"
|
||||
(ok)="savePropertyValue(editorItem, $event)"
|
||||
|
|
|
@ -38,6 +38,7 @@ import {
|
|||
InlineServiceCreationRequest,
|
||||
InlineServiceCreationResponse,
|
||||
Parameter,
|
||||
ParameterConfig,
|
||||
ParameterContextEntity,
|
||||
Property,
|
||||
PropertyDependency,
|
||||
|
@ -136,7 +137,7 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
editorOpen = false;
|
||||
editorTrigger: any = null;
|
||||
editorItem!: PropertyItem;
|
||||
editorParameters: Parameter[] | null = [];
|
||||
editorParameterConfig!: ParameterConfig;
|
||||
editorWidth = 0;
|
||||
editorOffsetX = 0;
|
||||
editorOffsetY = 0;
|
||||
|
@ -318,11 +319,18 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
this.initFilter();
|
||||
}
|
||||
|
||||
private getParameterConfig(propertyItem: PropertyItem): ParameterConfig {
|
||||
return {
|
||||
supportsParameters: this.supportsParameters,
|
||||
parameters: this.getParametersForItem(propertyItem)
|
||||
};
|
||||
}
|
||||
|
||||
private getParametersForItem(propertyItem: PropertyItem): Parameter[] | null {
|
||||
if (!this.supportsParameters) {
|
||||
if (!this.supportsParameters || !this.parameterContext) {
|
||||
return null;
|
||||
}
|
||||
if (this.parameterContext?.permissions.canRead) {
|
||||
if (this.parameterContext.permissions.canRead) {
|
||||
return this.parameterContext.component.parameters
|
||||
.map((parameterEntity) => parameterEntity.parameter)
|
||||
.filter((parameter: Parameter) => parameter.sensitive == propertyItem.descriptor.sensitive);
|
||||
|
@ -450,7 +458,7 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
|
||||
this.editorPositions.pop();
|
||||
this.editorItem = item;
|
||||
this.editorParameters = this.getParametersForItem(this.editorItem);
|
||||
this.editorParameterConfig = this.getParameterConfig(this.editorItem);
|
||||
this.editorTrigger = editorTrigger;
|
||||
this.editorOpen = true;
|
||||
|
||||
|
|
|
@ -43,12 +43,18 @@
|
|||
<div class="fa fa-check"></div>
|
||||
<div class="flex flex-col">
|
||||
<div class="font-bold">Parameters (PARAM) supported</div>
|
||||
@if (data?.hasParameterContext) {
|
||||
<div>
|
||||
After beginning with the start delimiter
|
||||
<span class="hint-pattern font-normal">#{</span> use the keystroke
|
||||
<span class="hint-keystroke font-light">control+space</span> to see a list of available
|
||||
parameters.
|
||||
</div>
|
||||
} @else {
|
||||
<div>
|
||||
Parameters are supported but no Parameter Context is currently bound to this Process Group.
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
|
|
@ -255,7 +255,7 @@
|
|||
background: if($is-dark, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.5));
|
||||
}
|
||||
|
||||
.cm-s-nifi .CodeMirror-hints {
|
||||
.CodeMirror-hints {
|
||||
z-index: 1000 !important;
|
||||
overflow-y: scroll !important;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue