mirror of https://github.com/apache/nifi.git
[NIFI-13177] ensure consistent typography rendering (#8786)
* [NIFI-13177] ensure consistent rendering of component type, name, and icon * ensure font-size consistency with .refresh-container and .mat-mdc-paginator * attempt at unifying how component context is displayed (#6) * use drop icon by default * final touches --------- Co-authored-by: Rob Fellows <rob.fellows@gmail.com> This closes #8786
This commit is contained in:
parent
c09144051f
commit
6b48e61295
|
@ -56,23 +56,11 @@
|
|||
<div class="flex justify-between items-center">
|
||||
<form [formGroup]="policyForm">
|
||||
<div class="flex gap-x-2">
|
||||
<div class="flex gap-x-1 -mt-2">
|
||||
<div class="operation-context-logo flex flex-col">
|
||||
<i class="accent-color icon" [class]="getContextIcon()"></i>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="operation-context-name">
|
||||
{{
|
||||
policyComponentState.label
|
||||
? policyComponentState.label
|
||||
: resourceIdentifier
|
||||
}}
|
||||
</div>
|
||||
<div class="operation-context-type primary-color">
|
||||
{{ getContextType() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<component-context
|
||||
[type]="getContextType()"
|
||||
[name]="
|
||||
policyComponentState.label ? policyComponentState.label : resourceIdentifier
|
||||
"></component-context>
|
||||
<div class="policy-select">
|
||||
<mat-form-field>
|
||||
<mat-label>Policy</mat-label>
|
||||
|
|
|
@ -25,18 +25,4 @@
|
|||
width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-context-logo {
|
||||
.icon {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-context-name {
|
||||
font-size: 18px;
|
||||
width: 370px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -337,27 +337,27 @@ export class ComponentAccessPolicies implements OnInit, OnDestroy {
|
|||
return 'icon-group';
|
||||
}
|
||||
|
||||
getContextType(): string {
|
||||
getContextType(): ComponentType | string | null {
|
||||
switch (this.resource) {
|
||||
case 'processors':
|
||||
return 'Processor';
|
||||
return ComponentType.Processor;
|
||||
case 'input-ports':
|
||||
return 'Input Ports';
|
||||
return ComponentType.InputPort;
|
||||
case 'output-ports':
|
||||
return 'Output Ports';
|
||||
return ComponentType.OutputPort;
|
||||
case 'funnels':
|
||||
return 'Funnel';
|
||||
return ComponentType.Funnel;
|
||||
case 'labels':
|
||||
return 'Label';
|
||||
return ComponentType.Label;
|
||||
case 'remote-process-groups':
|
||||
return 'Remote Process Group';
|
||||
return ComponentType.RemoteProcessGroup;
|
||||
case 'parameter-contexts':
|
||||
return 'Parameter Contexts';
|
||||
return 'Parameter Context';
|
||||
case 'parameter-providers':
|
||||
return 'Parameter Provider';
|
||||
return ComponentType.ParameterProvider;
|
||||
}
|
||||
|
||||
return 'Process Group';
|
||||
return ComponentType.ProcessGroup;
|
||||
}
|
||||
|
||||
policyActionChanged(value: string): void {
|
||||
|
|
|
@ -29,6 +29,7 @@ import { NifiTooltipDirective } from '../../../../ui/common/tooltips/nifi-toolti
|
|||
import { PolicyTable } from '../common/policy-table/policy-table.component';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { ErrorBanner } from '../../../../ui/common/error-banner/error-banner.component';
|
||||
import { ComponentContext } from '../../../../ui/common/component-context/component-context.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ComponentAccessPolicies],
|
||||
|
@ -45,7 +46,8 @@ import { ErrorBanner } from '../../../../ui/common/error-banner/error-banner.com
|
|||
NifiTooltipDirective,
|
||||
PolicyTable,
|
||||
MatButtonModule,
|
||||
ErrorBanner
|
||||
ErrorBanner,
|
||||
ComponentContext
|
||||
]
|
||||
})
|
||||
export class ComponentAccessPoliciesModule {}
|
||||
|
|
|
@ -33,20 +33,10 @@
|
|||
@if (!operationCollapsed) {
|
||||
@if (canvasUtils.getSelection(); as selection) {
|
||||
<div class="w-72 px-2.5 pb-2.5 flex flex-col gap-y-2">
|
||||
<div class="operation-context flex flex-col gap-y-1">
|
||||
<div class="flex gap-x-1">
|
||||
<div class="operation-context-logo flex flex-col">
|
||||
<i class="icon accent-color" [class]="getContextIcon(selection)"></i>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="operation-context-name">{{ getContextName(selection) }}</div>
|
||||
<div class="operation-context-type primary-color">
|
||||
{{ getContextType(selection) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="operation-context-id accent-color">{{ getContextId(selection) }}</div>
|
||||
</div>
|
||||
<component-context
|
||||
[type]="getContextType(selection)"
|
||||
[name]="getContextName(selection)"
|
||||
[id]="getContextId(selection)"></component-context>
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<div class="flex gap-x-1">
|
||||
<button
|
||||
|
|
|
@ -36,32 +36,4 @@ div.operation-control {
|
|||
font-size: 12px;
|
||||
letter-spacing: 0.05rem;
|
||||
}
|
||||
|
||||
.operation-context-logo {
|
||||
text-align: start;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
|
||||
.icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-context-name {
|
||||
font-size: 15px;
|
||||
height: 20px;
|
||||
width: 225px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.operation-context-type {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.operation-context-id {
|
||||
height: 18px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,14 @@ import * as d3 from 'd3';
|
|||
import { CanvasView } from '../../../../service/canvas-view.service';
|
||||
import { Client } from '../../../../../../service/client.service';
|
||||
import { CanvasActionsService } from '../../../../service/canvas-actions.service';
|
||||
import { ComponentContext } from '../../../../../../ui/common/component-context/component-context.component';
|
||||
import { ComponentType } from '../../../../../../state/shared';
|
||||
|
||||
@Component({
|
||||
selector: 'operation-control',
|
||||
standalone: true,
|
||||
templateUrl: './operation-control.component.html',
|
||||
imports: [MatButtonModule],
|
||||
imports: [MatButtonModule, ComponentContext],
|
||||
styleUrls: ['./operation-control.component.scss']
|
||||
})
|
||||
export class OperationControl {
|
||||
|
@ -136,29 +138,29 @@ export class OperationControl {
|
|||
}
|
||||
}
|
||||
|
||||
getContextType(selection: d3.Selection<any, any, any, any>): string {
|
||||
getContextType(selection: d3.Selection<any, any, any, any>): ComponentType | null {
|
||||
if (selection.size() === 0) {
|
||||
return 'Process Group';
|
||||
return ComponentType.ProcessGroup;
|
||||
} else if (selection.size() > 1) {
|
||||
return '';
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.canvasUtils.isProcessor(selection)) {
|
||||
return 'Processor';
|
||||
return ComponentType.Processor;
|
||||
} else if (this.canvasUtils.isInputPort(selection)) {
|
||||
return 'Input Port';
|
||||
return ComponentType.InputPort;
|
||||
} else if (this.canvasUtils.isOutputPort(selection)) {
|
||||
return 'Output Port';
|
||||
return ComponentType.OutputPort;
|
||||
} else if (this.canvasUtils.isFunnel(selection)) {
|
||||
return 'Funnel';
|
||||
return ComponentType.Funnel;
|
||||
} else if (this.canvasUtils.isLabel(selection)) {
|
||||
return 'Label';
|
||||
return ComponentType.Label;
|
||||
} else if (this.canvasUtils.isProcessGroup(selection)) {
|
||||
return 'Process Group';
|
||||
return ComponentType.ProcessGroup;
|
||||
} else if (this.canvasUtils.isRemoteProcessGroup(selection)) {
|
||||
return 'Remote Process Group';
|
||||
return ComponentType.RemoteProcessGroup;
|
||||
} else {
|
||||
return 'Connection';
|
||||
return ComponentType.Connection;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,3 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.refresh-container {
|
||||
line-height: normal;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
.refresh-container {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.manage-remote-ports-table {
|
||||
.listing-table {
|
||||
@include mat.table-density(-4);
|
||||
|
|
|
@ -14,7 +14,3 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.refresh-container {
|
||||
line-height: normal;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import { ComponentType } from '../state/shared';
|
|||
standalone: true
|
||||
})
|
||||
export class ComponentTypeNamePipe implements PipeTransform {
|
||||
transform(type: ComponentType): string {
|
||||
transform(type: ComponentType | string): string {
|
||||
switch (type) {
|
||||
case ComponentType.Connection:
|
||||
return 'Connection';
|
||||
|
@ -54,7 +54,7 @@ export class ComponentTypeNamePipe implements PipeTransform {
|
|||
case ComponentType.ReportingTask:
|
||||
return 'Reporting Task';
|
||||
default:
|
||||
return '';
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,17 +17,19 @@
|
|||
|
||||
<div class="component-context flex flex-col">
|
||||
<div class="flex gap-x-1 items-center">
|
||||
<div class="component-context-logo flex flex-col">
|
||||
<div class="context-logo flex flex-col">
|
||||
<i class="icon accent-color" [class]="componentIconClass"></i>
|
||||
</div>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="component-context-name w-full">{{ name }}</div>
|
||||
<div class="component-context-type primary-color w-full">
|
||||
{{ type | componentTypeName }}
|
||||
<div class="context-name w-full">{{ name }}</div>
|
||||
<div class="context-type pt-1 primary-color w-full">
|
||||
@if (type) {
|
||||
{{ type | componentTypeName }}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (id) {
|
||||
<div class="component-context-id accent-color">{{ id }}</div>
|
||||
<div class="context-id accent-color">{{ id }}</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -14,28 +14,3 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
.component-context {
|
||||
.component-context-logo {
|
||||
text-align: start;
|
||||
|
||||
.icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.component-context-name {
|
||||
font-size: 15px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.component-context-type {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.component-context-id {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,22 +27,25 @@ import { ComponentTypeNamePipe } from '../../../pipes/component-type-name.pipe';
|
|||
styleUrl: './component-context.component.scss'
|
||||
})
|
||||
export class ComponentContext {
|
||||
private _componentType: ComponentType = ComponentType.Processor;
|
||||
private _componentType: ComponentType | string | null = ComponentType.Processor;
|
||||
componentIconClass: string = '';
|
||||
|
||||
@Input() set type(type: ComponentType) {
|
||||
@Input() set type(type: ComponentType | string | null) {
|
||||
this._componentType = type;
|
||||
this.componentIconClass = this.getIconClassName(type);
|
||||
}
|
||||
|
||||
get type(): ComponentType {
|
||||
get type(): ComponentType | string | null {
|
||||
return this._componentType;
|
||||
}
|
||||
|
||||
@Input() id: string | null = null;
|
||||
@Input() name: string = '';
|
||||
|
||||
private getIconClassName(type: ComponentType) {
|
||||
private getIconClassName(type: ComponentType | string | null) {
|
||||
if (type === null) {
|
||||
return 'icon-drop';
|
||||
}
|
||||
switch (type) {
|
||||
case ComponentType.Connection:
|
||||
return 'icon-connect';
|
||||
|
@ -61,7 +64,7 @@ export class ComponentContext {
|
|||
case ComponentType.RemoteProcessGroup:
|
||||
return 'icon-group-remote';
|
||||
default:
|
||||
return 'icon-connect';
|
||||
return 'icon-drop';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
<th mat-header-cell *matHeaderCellDef>Property</th>
|
||||
<td mat-cell *matCellDef="let item" [class.font-bold]="item.descriptor.required">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="whitespace-nowrap overflow-hidden text-ellipsis leading-normal" [title]="item.descriptor.displayName">
|
||||
<div
|
||||
class="whitespace-nowrap overflow-hidden text-ellipsis leading-normal"
|
||||
[title]="item.descriptor.displayName">
|
||||
{{ item.descriptor.displayName }}
|
||||
</div>
|
||||
<i
|
||||
|
@ -81,7 +83,9 @@
|
|||
</ng-template>
|
||||
<ng-template #nonBlank let-resolvedValue>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="whitespace-nowrap overflow-hidden text-ellipsis leading-normal" [title]="resolvedValue">
|
||||
<div
|
||||
class="whitespace-nowrap overflow-hidden text-ellipsis leading-normal"
|
||||
[title]="resolvedValue">
|
||||
{{ resolvedValue }}
|
||||
</div>
|
||||
@if (hasExtraWhitespace(resolvedValue)) {
|
||||
|
|
|
@ -65,6 +65,41 @@
|
|||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.context-logo {
|
||||
text-align: start;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
|
||||
.icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.context-name {
|
||||
font-size: 15px;
|
||||
line-height: 15px;
|
||||
height: 15px;
|
||||
width: 225px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.context-type {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.context-id {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.refresh-container {
|
||||
line-height: normal;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue