Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@netgrif/components-project",
"version": "7.0.0-rc.14",
"version": "7.0.0-rc.15",
"description": "Netgrif Application Engine Frontend project. Project includes angular libraries as base for NAE applications.",
"homepage": "https://components.netgrif.com",
"license": "SEE LICENSE IN LICENSE",
Expand Down
2 changes: 1 addition & 1 deletion projects/netgrif-components-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@netgrif/components-core",
"version": "7.0.0-rc.14",
"version": "7.0.0-rc.15",
"description": "Netgrif Application engine frontend core Angular library",
"homepage": "https://components.netgrif.com",
"license": "SEE LICENSE IN LICENSE",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ export interface PetriNetSearchRequest {
/**
* Queried PetriNet identifier
*/
identifier: string;
identifier?: string;
/**
* Queried PetriNet mongo ID
*/
processId?: string;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {FeaturedValue} from './featured-value';
import {CurrencyPipe} from '@angular/common';
import {ImmediateData} from '../../resources/interface/immediate-data';
import {OverflowService} from '../../header/services/overflow.service';
import {I18nFieldValue} from "../../data-fields/i18n-field/models/i18n-field-value";

@Component({
selector: 'ncc-abstract-panel-with-immediate',
Expand Down Expand Up @@ -35,33 +36,37 @@ export abstract class AbstractPanelWithImmediateDataComponent extends AbstractPa
case 'dateTime':
return {
value: toMoment(immediate.value as NaeDate).format(DATE_TIME_FORMAT_STRING),
icon: 'event', type: immediate.type
icon: 'event',
type: immediate.type
};
case 'enumeration':
return {value: immediate.value.defaultValue, icon: undefined, type: immediate.type};
return {value: this.getTranslation(immediate.value), icon: undefined, type: immediate.type};
case 'multichoice':
return {
value: immediate.value.map(it => it.defaultValue).join(', '),
value: immediate.value.map(it => this.getTranslation(it)).join(', '),
icon: undefined,
type: immediate.type
};
case 'enumeration_map':
return {
value: immediate.options[immediate.value].defaultValue,
value: this.getTranslation(immediate.options[immediate.value]),
icon: undefined,
type: immediate.type
};
case 'multichoice_map':
return {
value: immediate.value.map(it =>
immediate.options[it].defaultValue).join(', '), icon: undefined, type: immediate.type
this.getTranslation(immediate.options[it])).join(', '),
icon: undefined,
type: immediate.type
};
Comment on lines +43 to 62
Copy link

@coderabbitai coderabbitai bot Nov 4, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify type compatibility for immediate data values.

The code now assumes that values for enumeration, multichoice, enumeration_map, and multichoice_map field types conform to the I18nFieldValue interface. Ensure that:

  1. The ImmediateData interface definitions for these field types guarantee values are I18nFieldValue objects
  2. Backend APIs always return data in this format for these field types
  3. Existing data in the system has been migrated to include the translations field (even if empty)

Run the following script to verify the ImmediateData type definitions:


🏁 Script executed:

#!/bin/bash
# Description: Verify ImmediateData interface and type definitions

# Find ImmediateData interface definition
ast-grep --pattern 'interface ImmediateData {
  $$$
}'

# Find type definitions for immediate data values
rg -nP --type=ts 'type.*=.*enumeration|multichoice' -A5 -B5 -g '!node_modules'

Length of output: 113361


Looking at the shell script results to verify the type safety concerns in the panel-with-immediate-data.ts code.


🏁 Script executed:

#!/bin/bash
# Search for I18nFieldValue type definition and getTranslation method

echo "=== Searching for I18nFieldValue type ==="
rg -nP --type=ts 'type I18nFieldValue|interface I18nFieldValue' -A5

echo "=== Searching for getTranslation method in panel-with-immediate-data.ts ==="
rg -nP --type=ts 'getTranslation' projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts -B5 -A5

echo "=== Searching for where immediate.options is used ==="
rg -nP --type=ts 'immediate\.options' -B3 -A3

Length of output: 5260


🏁 Script executed:

#!/bin/bash
# Deep dive into getTranslation and I18nFieldValue

echo "=== Find I18nFieldValue definition ==="
fd -t f -e ts | xargs grep -l "I18nFieldValue" | head -5
rg -nP "type I18nFieldValue|interface I18nFieldValue" -A10 --type=ts

echo "=== Find getTranslation implementation ==="
ast-grep --pattern 'getTranslation($_) {
  $$$
}'

echo "=== Check panel-with-immediate-data.ts full content ==="
cat projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts | head -100

Length of output: 6895


Type definitions for ImmediateData are insufficient for enumeration_map and multichoice_map field types.

The ImmediateData interface (line 50) defines options?: { defaultValue?: string }, but the code at lines 52 and 59 treats it as a map of I18nFieldValue objects. Additionally, value is typed as any rather than enforcing the expected I18nFieldValue structure for enumeration and multichoice cases.

The type mismatch should be fixed in the interface definition:

// Current ImmediateData.options definition
options?: { defaultValue?: string };

// Should be (for enumeration_map/multichoice_map types)
options?: Record<string, I18nFieldValue>;

Also consider tightening the value field type for these field types using discriminated unions if possible, or at minimum document the expected structure in comments.

🤖 Prompt for AI Agents
In
projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts
around lines 43 to 62, the ImmediateData type is too loose for enumeration_map
and multichoice_map: options is currently declared as { defaultValue?: string }
and value is any, but the code treats options as a map of I18nFieldValue and
values as keys/arrays of those keys; update the ImmediateData.interface so
options?: Record<string, I18nFieldValue> (or equivalent map type) and narrow
value types (use a discriminated-union for field type cases or at minimum
document expected structures and replace any with the appropriate string or
string[] types for enumeration_map and multichoice_map) so the runtime access
immediate.options[immediate.value] and immediate.options[it] types-check
correctly.

Copy link
Member

Choose a reason for hiding this comment

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

Options in ImmediateData interface is defined as follows:

options?: {
        [k: string]: I18nFieldValue
    };

Interface si defined in file projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the current ImmediateData interface definition
echo "=== Current ImmediateData interface definition ==="
cat projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts

Length of output: 1225


@tuplle, thank you for the correction! You're absolutely right. I've verified that the ImmediateData interface in projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts correctly defines options as:

options?: {
    [k: string]: I18nFieldValue
};

This properly supports the usage in panel-with-immediate-data.ts where immediate.options[immediate.value] and immediate.options[it] are accessed. The type definitions are correct, and my earlier concern was based on incorrect information. I apologize for the confusion.

The implementation looks good from a type safety perspective! ✅


🧬 Code Graph Analysis Results

projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts

export interface ImmediateData { /** * @ignore */ stringId: string; /** * @ignore */ // TODO Exist only in Net Immediate data title?: any; /** * @ignore */ type: string; /** * @ignore */ value?: any; /** * Only for Fields of type `CaseRef` and `Filter` */ allowedNets?: Array; /** * Only for Fields of type `Filter` */ filterMetadata?: FilterMetadata; /** * Only for Currency Number Fields */ format?: FormatFilter; /** * Only for Currency Number Fields */ component?: Component; /** * @ignore */ // TODO Exists only in case immediate data name?: any; /** * Only for enumeration_map and multichoice_map */ options?: { [k: string]: I18nFieldValue }; }

projects/netgrif-components-core/src/lib/data-fields/i18n-field/models/i18n-field-value.ts

export interface I18nFieldValue { defaultValue: string; key?: string; translations?: I18nFieldTranslations; }

case 'file':
return {value: immediate.value?.name, icon: 'insert_drive_file', type: immediate.type};
case 'fileList':
return {
value: immediate.value?.namesPaths.map(obj => obj.name).join(', '),
icon: 'file_copy', type: immediate.type
icon: 'file_copy',
type: immediate.type
};
case 'userList':
return {value: immediate.value?.userValues.map(obj => obj.fullName).join(', '), icon: 'account_circle', type: immediate.type};
Expand All @@ -73,11 +78,18 @@ export abstract class AbstractPanelWithImmediateDataComponent extends AbstractPa
icon: undefined, type: immediate.type
};
case 'button':
let buttonValue: string;
if ((immediate as any).placeholder?.defaultValue !== undefined) {
buttonValue = this.getTranslation((immediate as any).placeholder);
} else if (immediate.name?.defaultValue !== undefined) {
buttonValue = this.getTranslation(immediate.name);
} else {
buttonValue = this._translate.instant('dialog.submit');
}
return {
value: (immediate as any).placeholder && (immediate as any).placeholder.defaultValue !== undefined
? (immediate as any).placeholder.defaultValue : (immediate.name && immediate.name.defaultValue !== undefined
? immediate.name.defaultValue : this._translate.instant('dialog.submit')),
icon: undefined, type: immediate.type
value: buttonValue,
icon: undefined,
type: immediate.type
};
Comment on lines +81 to 93
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Wrap the button clause in a block. Declaring let buttonValue directly in the case violates noSwitchDeclarations (Biome error) because the binding leaks to sibling clauses. Enclose this case in braces so the lint/build passes.

Apply this diff:

-                case 'button':
+                case 'button': {
                     let buttonValue: string;
                     if ((immediate as any).placeholder?.defaultValue !== undefined) {
                         buttonValue = this.getTranslation((immediate as any).placeholder);
                     } else if (immediate.name?.defaultValue !== undefined) {
                         buttonValue = this.getTranslation(immediate.name);
                     } else {
                         buttonValue = this._translate.instant('dialog.submit');
                     }
                     return {
                         value: buttonValue,
                         icon: undefined,
                         type: immediate.type
                     };
+                }

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (2.1.2)

[error] 81-81: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🤖 Prompt for AI Agents
In
projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts
around lines 81 to 93, the switch case that declares let buttonValue leaks the
binding to sibling clauses and violates noSwitchDeclarations; wrap that case
body in a block (add { ... }) and move the let buttonValue declaration inside
that block (or change to const) so the variable scope is limited to the case;
ensure the return object remains unchanged and formatting/indentation is updated
accordingly.

case 'filter':
return {
Expand All @@ -101,6 +113,13 @@ export abstract class AbstractPanelWithImmediateDataComponent extends AbstractPa
}
}

protected getTranslation(i18n: I18nFieldValue | undefined): string {
const locale = this._translate.currentLang;
return (i18n && i18n.translations && locale in i18n.translations)
? i18n.translations[locale]
: (i18n?.defaultValue ?? '');
}

protected formatCurrencyPipe(value: any, code: string, fraction: number, locale: string, type: string) {
return {
value:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class TestWrapperComponent {
{stringId: 'date', title: 'string', type: 'date', value: [2020, 1, 1, 10, 10]},
{stringId: 'string', title: 'string', type: 'string', value: 'dasdsadsad'},
{stringId: 'dateTime', title: 'string', type: 'dateTime', value: [2020, 1, 1, 10, 10]},
{stringId: 'enum', title: 'string', type: 'enumeration', value: {defaultValue: 'dasd'}},
{stringId: 'enum', title: 'string', type: 'enumeration', value: {defaultValue: 'dasd', translations: {}}},
]
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {FilterMetadata} from '../../search/models/persistance/filter-metadata';
import {FormatFilter} from '../../data-fields/models/format-filter';
import {Component} from '../../data-fields/models/component';
import {I18nFieldValue} from "../../data-fields/i18n-field/models/i18n-field-value";

/**
* @ignore
Expand Down Expand Up @@ -47,5 +48,7 @@ export interface ImmediateData {
/**
* Only for enumeration_map and multichoice_map
*/
options?: { defaultValue?: string };
options?: {
[k: string]: I18nFieldValue
};
}
4 changes: 2 additions & 2 deletions projects/netgrif-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@netgrif/components",
"version": "7.0.0-rc.14",
"version": "7.0.0-rc.15",
"description": "Netgrif Application Engine frontend Angular components",
"homepage": "https://components.netgrif.com",
"license": "SEE LICENSE IN LICENSE",
Expand Down Expand Up @@ -29,7 +29,7 @@
"nae frontend"
],
"peerDependencies": {
"@netgrif/components-core": "7.0.0-rc.14",
"@netgrif/components-core": "7.0.0-rc.15",
"@angular-material-components/datetime-picker": "~16.0.0",
"@angular-material-components/moment-adapter": "~16.0.0",
"@angular/animations": "~17.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class TestWrapperComponent {
{stringId: 'date', title: 'string', type: 'date', value: [2020, 1, 1, 10, 10]},
{stringId: 'string', title: 'string', type: 'string', value: 'dasdsadsad'},
{stringId: 'dateTime', title: 'string', type: 'dateTime', value: [2020, 1, 1, 10, 10]},
{stringId: 'enum', title: 'string', type: 'enumeration', value: {defaultValue: 'dasd'}},
{stringId: 'enum', title: 'string', type: 'enumeration', value: {defaultValue: 'dasd', translations: {}}},
]
};
}
Loading