Skip to content

Commit

Permalink
fix(KTO-441): option to display the ID instead of the description as …
Browse files Browse the repository at this point in the history
…step label
  • Loading branch information
tplevko authored and lordrip committed Jul 26, 2024
1 parent a5c2d33 commit e33d897
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 16 deletions.
7 changes: 7 additions & 0 deletions packages/ui/src/assets/settingsSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
"default": "<empty string>",
"type": "string",
"format": "uri"
},
"nodeLabel": {
"title": "Node label to display in canvas",
"description": "Node label, which will be used for nodes in the canvas. Can be either `description` or `id`. If `description` is selected, it will be displayed only if it is available, otherwise `id` will be displayed by default.",
"default": "description",
"type": "string",
"enum": ["description", "id"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,145 @@ exports[`SettingsForm should render 1`] = `
</div>
</div>
</div>
<div
class="pf-v5-c-form__group"
data-fieldname="nodeLabel"
data-testid="wrapper-field"
options="[object Object],[object Object]"
>
<div
class="pf-v5-c-form__group-label"
>
<label
class="pf-v5-c-form__label"
for="uniforms-0000-0005"
>
<span
class="pf-v5-c-form__label-text"
>
Node label to display in canvas
</span>
</label>
<div
style="display: contents;"
>
<button
aria-disabled="false"
aria-label="More info for field"
class="pf-v5-c-button pf-m-plain field-hint-button"
data-ouia-component-id="OUIA-Generated-Button-plain-2"
data-ouia-component-type="PF5/Button"
data-ouia-safe="true"
data-testid="field-hint-button"
type="button"
>
<svg
aria-hidden="true"
class="pf-v5-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M521.3,576 C627.5,576 713.7,502 713.7,413.7 C713.7,325.4 627.6,253.6 521.3,253.6 C366,253.6 334.5,337.7 329.2,407.2 C329.2,414.3 335.2,416 343.5,416 L445,416 C450.5,416 458,415.5 460.8,406.5 C460.8,362.6 582.9,357.1 582.9,413.6 C582.9,441.9 556.2,470.9 521.3,473 C486.4,475.1 447.3,479.8 447.3,521.7 L447.3,553.8 C447.3,570.8 456.1,576 472,576 C487.9,576 521.3,576 521.3,576 M575.3,751.3 L575.3,655.3 C575.313862,651.055109 573.620137,646.982962 570.6,644 C567.638831,640.947672 563.552355,639.247987 559.3,639.29884 L463.3,639.29884 C459.055109,639.286138 454.982962,640.979863 452,644 C448.947672,646.961169 447.247987,651.047645 447.29884,655.3 L447.29884,751.3 C447.286138,755.544891 448.979863,759.617038 452,762.6 C454.961169,765.652328 459.047645,767.352013 463.3,767.30116 L559.3,767.30116 C563.544891,767.313862 567.617038,765.620137 570.6,762.6 C573.659349,759.643612 575.360354,755.553963 575.3,751.3 M512,896 C300.2,896 128,723.9 128,512 C128,300.3 300.2,128 512,128 C723.8,128 896,300.2 896,512 C896,723.8 723.7,896 512,896 M512.1,0 C229.7,0 0,229.8 0,512 C0,794.2 229.8,1024 512.1,1024 C794.4,1024 1024,794.3 1024,512 C1024,229.7 794.4,0 512.1,0"
/>
</svg>
</button>
</div>
</div>
<div
class="pf-v5-c-form__group-control"
>
<div
class="pf-v5-c-menu-toggle pf-m-full-width pf-m-typeahead"
>
<div
class="pf-v5-c-text-input-group pf-m-plain"
>
<div
autocomplete="off"
class="pf-v5-c-text-input-group__main"
data-testid="create-typeahead-select-input"
id="create-typeahead-select-input"
>
<span
class="pf-v5-c-text-input-group__text"
>
<input
aria-controls="select-create-typeahead-listbox"
aria-expanded="false"
aria-label="Type to filter"
class="pf-v5-c-text-input-group__text-input"
placeholder="Select an option"
role="combobox"
type="text"
value="description"
/>
</span>
</div>
<div
class="pf-v5-c-text-input-group__utilities"
>
<button
aria-disabled="false"
aria-label="Clear input value"
class="pf-v5-c-button pf-m-plain"
data-ouia-component-id="OUIA-Generated-Button-plain-3"
data-ouia-component-type="PF5/Button"
data-ouia-safe="true"
type="button"
>
<svg
aria-hidden="true"
class="pf-v5-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 352 512"
width="1em"
>
<path
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
/>
</svg>
</button>
</div>
</div>
<button
aria-expanded="false"
aria-label="Menu toggle"
class="pf-v5-c-menu-toggle__button"
tabindex="-1"
type="button"
>
<span
class="pf-v5-c-menu-toggle__controls"
>
<span
class="pf-v5-c-menu-toggle__toggle-icon"
>
<svg
aria-hidden="true"
class="pf-v5-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
/>
</svg>
</span>
</span>
</button>
</div>
</div>
</div>
</div>
</form>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
withSelection,
} from '@patternfly/react-topology';
import clsx from 'clsx';
import { FunctionComponent, ReactElement } from 'react';
import { FunctionComponent, ReactElement, useContext } from 'react';
import { AddStepMode } from '../../../models/visualization/base-visual-entity';
import { CanvasDefaults } from '../Canvas/canvas.defaults';
import { CanvasNode } from '../Canvas/canvas.models';
Expand All @@ -26,6 +26,7 @@ import { ItemDisableStep } from './ItemDisableStep';
import { ItemInsertStep } from './ItemInsertStep';
import { ItemReplaceStep } from './ItemReplaceStep';
import { doTruncateLabel } from '../../../utils/truncate-label';
import { SettingsContext } from '../../../providers';

interface CustomNodeProps extends WithSelectionProps {
element: Node<CanvasNode, CanvasNode['data']>;
Expand All @@ -34,7 +35,8 @@ const noopFn = () => {};

const CustomNode: FunctionComponent<CustomNodeProps> = observer(({ element, ...rest }) => {
const vizNode = element.getData()?.vizNode;
const label = vizNode?.getNodeLabel();
const settingsAdapter = useContext(SettingsContext);
const label = vizNode?.getNodeLabel(settingsAdapter.getSettings().nodeLabel);
const isDisabled = !!vizNode?.getComponentSchema()?.definition?.disabled;
const tooltipContent = vizNode?.getTooltipContent();
const statusDecoratorTooltip = vizNode?.getNodeValidationText();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('LocalStorageSettingsAdapter', () => {

it('should save and retrieve settings', () => {
const adapter = new LocalStorageSettingsAdapter();
const newSettings: SettingsModel = { catalogUrl: 'http://example.com' };
const newSettings: SettingsModel = { catalogUrl: 'http://example.com', nodeLabel: 'description' };

adapter.saveSettings(newSettings);

Expand All @@ -30,7 +30,7 @@ describe('LocalStorageSettingsAdapter', () => {
const localStorageSetItemSpy = jest.spyOn(Storage.prototype, 'setItem');

const adapter = new LocalStorageSettingsAdapter();
const newSettings: SettingsModel = { catalogUrl: 'http://example.com' };
const newSettings: SettingsModel = { catalogUrl: 'http://example.com', nodeLabel: 'description' };

adapter.saveSettings(newSettings);

Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/models/settings/settings.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface ISettingsModel {
catalogUrl: string;
nodeLabel: string;
}

export interface AbstractSettingsAdapter {
Expand All @@ -9,6 +10,7 @@ export interface AbstractSettingsAdapter {

export class SettingsModel implements ISettingsModel {
catalogUrl: string = '';
nodeLabel: string = 'description';

constructor(options: Partial<ISettingsModel> = {}) {
Object.assign(this, options);
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/models/visualization/base-visual-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface BaseVisualCamelEntity extends BaseCamelEntity {
setId: (id: string) => void;

/** Given a path, get the component label */
getNodeLabel: (path?: string) => string;
getNodeLabel: (path?: string, labelType?: string) => string;

/** Given a path, get the component tooltip content */
getTooltipContent: (path?: string) => string;
Expand Down Expand Up @@ -75,7 +75,7 @@ export interface IVisualizationNode<T extends IVisualizationNodeData = IVisualiz
getBaseEntity(): BaseVisualCamelEntity | undefined;

/** This method returns the label to be used by the canvas nodes */
getNodeLabel(): string;
getNodeLabel(labelType?: string): string;

/** This method returns the tooltip content to be used by the canvas nodes */
getTooltipContent(): string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ export abstract class AbstractCamelVisualEntity<T extends object> implements Bas
return this.id;
}

getNodeLabel(path?: string): string {
getNodeLabel(path?: string, labelType?: string): string {
if (!path) return '';

const componentModel = getValue(this.route, path);
const label = CamelComponentSchemaService.getNodeLabel(
CamelComponentSchemaService.getCamelComponentLookup(path, componentModel),
componentModel,
labelType,
);

return label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ describe('Camel Route', () => {
const getNodeLabelSpy = jest.spyOn(CamelComponentSchemaService, 'getNodeLabel');
jest.spyOn(CamelComponentSchemaService, 'getCamelComponentLookup').mockReturnValueOnce(lookupValue);

const label = camelEntity.getNodeLabel('from');
const label = camelEntity.getNodeLabel('from', 'id');

expect(getNodeLabelSpy).toHaveBeenCalledWith(lookupValue, camelRouteJson.route.from);
expect(getNodeLabelSpy).toHaveBeenCalledWith(lookupValue, camelRouteJson.route.from, 'id');
expect(label).toEqual('timer');
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ export class CamelComponentSchemaService {
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
static getNodeLabel(camelElementLookup: ICamelElementLookupResult, definition?: any): string {
if (typeof definition?.description === 'string' && definition.description !== '') {
static getNodeLabel(camelElementLookup: ICamelElementLookupResult, definition?: any, labelType?: string): string {
if (typeof definition?.description === 'string' && labelType !== 'id' && definition.description !== '') {
return definition.description;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ describe('VisualizationNode', () => {
} as unknown as BaseVisualCamelEntity;

node = createVisualizationNode('test', { path: 'test-path', entity: visualEntity });
const label = node.getNodeLabel();
const label = node.getNodeLabel('id');

expect(getNodeLabelSpy).toHaveBeenCalledWith(node.data.path);
expect(getNodeLabelSpy).toHaveBeenCalledWith(node.data.path, 'id');
expect(label).toEqual('test-label');
});

Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/models/visualization/visualization-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class VisualizationNode<T extends IVisualizationNodeData = IVisualizationNodeDat
return this.getRootNode().data.entity;
}

getNodeLabel(): string {
return this.getBaseEntity()?.getNodeLabel(this.data.path) ?? this.id;
getNodeLabel(labelType?: string): string {
return this.getBaseEntity()?.getNodeLabel(this.data.path, labelType) ?? this.id;
}

getTooltipContent(): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ exports[`SettingsProvider should render 1`] = `
<p
data-testid="settings"
>
{"catalogUrl":""}
{"catalogUrl":"","nodeLabel":"description"}
</p>
`;

0 comments on commit e33d897

Please sign in to comment.