mirror of https://github.com/apache/nifi.git
NIFI-13112: (#8711)
- Fixing linking to non canvas items. - Adding a tooltip to render search match details. This closes #8711
This commit is contained in:
parent
0e373e9c21
commit
2c43a706f8
|
@ -128,7 +128,6 @@
|
|||
}
|
||||
"></ng-container>
|
||||
}
|
||||
<!-- TODO - Handling linking to Controller Services, Parameter Providers, Parameter Contexts, and Parameters -->
|
||||
@if (controllerServiceNodeResults.length > 0) {
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
|
@ -186,31 +185,81 @@
|
|||
#searchInput="cdkOverlayOrigin"
|
||||
formControlName="searchBar" />
|
||||
<ng-template #renderResults let-results let-header="header" let-icon="icon" let-path="path">
|
||||
<li class="flex items-center">
|
||||
<span class="icon mr-1" [class]="icon"></span>
|
||||
<span class="font-medium">{{ header }}</span>
|
||||
</li>
|
||||
<!-- TODO - Consider showing more context of match like existing UI -->
|
||||
@for (result of results; track result) {
|
||||
<li class="ml-2 py-1">
|
||||
@if (!result.parentGroup) {
|
||||
<a [routerLink]="['/process-groups', result.id]">
|
||||
{{ result.name }}
|
||||
</a>
|
||||
} @else {
|
||||
@if (result.parentGroup.id == currentProcessGroupId) {
|
||||
@if (results.length > 0) {
|
||||
<li class="flex items-center">
|
||||
<span class="icon mr-1 accent-color" [class]="icon"></span>
|
||||
<span class="font-medium">{{ header }}</span>
|
||||
</li>
|
||||
@for (result of results; track result) {
|
||||
<li class="ml-4 py-1 flex gap-x-2 items-center">
|
||||
<i
|
||||
class="fa fa-info-circle on-surface-medium"
|
||||
nifiTooltip
|
||||
[tooltipComponentType]="SearchMatchTip"
|
||||
[tooltipInputData]="getSearchMatchTipInput(result)"
|
||||
[delayClose]="false"></i>
|
||||
@if (header === 'Parameters') {
|
||||
<a
|
||||
(click)="componentLinkClicked(path, result.id)"
|
||||
[routerLink]="['/process-groups', result.parentGroup.id, path, result.id]">
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
[title]="result.name"
|
||||
[routerLink]="['/parameter-contexts', result.parentGroup.id]">
|
||||
{{ result.name }}
|
||||
</a>
|
||||
} @else if (header === 'Parameter Contexts') {
|
||||
<a
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
[title]="result.name"
|
||||
[routerLink]="['/parameter-contexts', result.id]">
|
||||
{{ result.name }}
|
||||
</a>
|
||||
} @else if (header === 'Parameter Providers') {
|
||||
<a
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
[title]="result.name"
|
||||
[routerLink]="['/settings', 'parameter-providers', result.parentGroup.id]">
|
||||
{{ result.name }}
|
||||
</a>
|
||||
} @else if (header === 'Controller Services') {
|
||||
<a
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
[title]="result.name"
|
||||
[routerLink]="[
|
||||
'/process-groups',
|
||||
result.parentGroup.id,
|
||||
'controller-services',
|
||||
result.id
|
||||
]">
|
||||
{{ result.name ? result.name : result.id }}
|
||||
</a>
|
||||
} @else {
|
||||
<a [routerLink]="['/process-groups', result.parentGroup.id, path, result.id]">
|
||||
{{ result.name ? result.name : result.id }}
|
||||
</a>
|
||||
@if (!result.parentGroup) {
|
||||
<a
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
[title]="result.name"
|
||||
[routerLink]="['/process-groups', result.id]">
|
||||
{{ result.name }}
|
||||
</a>
|
||||
} @else {
|
||||
@if (result.parentGroup.id == currentProcessGroupId) {
|
||||
<a
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
(click)="componentLinkClicked(path, result.id)"
|
||||
[title]="result.name"
|
||||
[routerLink]="['/process-groups', result.parentGroup.id, path, result.id]">
|
||||
{{ result.name ? result.name : result.id }}
|
||||
</a>
|
||||
} @else {
|
||||
<a
|
||||
class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap"
|
||||
[title]="result.name"
|
||||
[routerLink]="['/process-groups', result.parentGroup.id, path, result.id]">
|
||||
{{ result.name ? result.name : result.id }}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</li>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
</form>
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
OriginConnectionPosition,
|
||||
OverlayConnectionPosition
|
||||
} from '@angular/cdk/overlay';
|
||||
import { ComponentType } from '../../../../../../state/shared';
|
||||
import { ComponentType, SearchMatchTipInput } from '../../../../../../state/shared';
|
||||
import { NgTemplateOutlet } from '@angular/common';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
|
@ -37,6 +37,8 @@ import { Store } from '@ngrx/store';
|
|||
import { centerSelectedComponents, setAllowTransition } from '../../../../state/flow/flow.actions';
|
||||
import { selectCurrentRoute } from '../../../../../../state/router/router.selectors';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { NifiTooltipDirective } from '../../../../../../ui/common/tooltips/nifi-tooltip.directive';
|
||||
import { SearchMatchTip } from '../../../../../../ui/common/tooltips/search-match-tip/search-match-tip.component';
|
||||
|
||||
@Component({
|
||||
selector: 'search',
|
||||
|
@ -50,11 +52,13 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|||
NgTemplateOutlet,
|
||||
RouterLink,
|
||||
MatFormFieldModule,
|
||||
MatInputModule
|
||||
MatInputModule,
|
||||
NifiTooltipDirective
|
||||
]
|
||||
})
|
||||
export class Search implements OnInit {
|
||||
protected readonly ComponentType = ComponentType;
|
||||
protected readonly SearchMatchTip = SearchMatchTip;
|
||||
|
||||
@Input() currentProcessGroupId: string = initialState.id;
|
||||
@ViewChild('searchInput') searchInput!: CdkOverlayOrigin;
|
||||
|
@ -190,6 +194,12 @@ export class Search implements OnInit {
|
|||
this.parameterResults = [];
|
||||
}
|
||||
|
||||
getSearchMatchTipInput(result: ComponentSearchResult): SearchMatchTipInput {
|
||||
return {
|
||||
matches: result.matches
|
||||
};
|
||||
}
|
||||
|
||||
componentLinkClicked(componentType: ComponentType, id: string): void {
|
||||
if (componentType == this.selectedComponentType && id == this.selectedComponentId) {
|
||||
this.store.dispatch(centerSelectedComponents({ request: { allowTransition: true } }));
|
||||
|
|
|
@ -229,6 +229,10 @@ export interface UnorderedListTipInput {
|
|||
items: string[];
|
||||
}
|
||||
|
||||
export interface SearchMatchTipInput {
|
||||
matches: string[];
|
||||
}
|
||||
|
||||
export interface ControllerServiceApi {
|
||||
type: string;
|
||||
bundle: Bundle;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<div class="tooltip">
|
||||
Search matched:
|
||||
<ul>
|
||||
@for (match of data?.matches; track match) {
|
||||
<li>{{ match }}</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchMatchTip } from './search-match-tip.component';
|
||||
|
||||
describe('SearchMatchTip', () => {
|
||||
let component: SearchMatchTip;
|
||||
let fixture: ComponentFixture<SearchMatchTip>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [SearchMatchTip]
|
||||
});
|
||||
fixture = TestBed.createComponent(SearchMatchTip);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { SearchMatchTipInput } from '../../../../state/shared';
|
||||
|
||||
@Component({
|
||||
selector: 'search-match-tip',
|
||||
standalone: true,
|
||||
templateUrl: './search-match-tip.component.html',
|
||||
imports: [],
|
||||
styleUrls: ['./search-match-tip.component.scss']
|
||||
})
|
||||
export class SearchMatchTip {
|
||||
@Input() data: SearchMatchTipInput | undefined;
|
||||
}
|
Loading…
Reference in New Issue