@@ -2,6 +2,7 @@ import '@js/ui/validation_summary';
22import '@js/ui/validation_group' ;
33
44import type { EditorStyle } from '@js/common' ;
5+ import type { RequestCallbacks , SmartPasteCommandParams , SmartPasteCommandResult } from '@js/common/ai-integration' ;
56import eventsEngine from '@js/common/core/events/core/events_engine' ;
67import { triggerResizeEvent , triggerShownEvent } from '@js/common/core/events/visibility_change' ;
78import messageLocalization from '@js/common/core/localization/message' ;
@@ -26,7 +27,12 @@ import type { ChangedOptionInfo, EventInfo } from '@js/events';
2627import type {
2728 FieldDataChangedEvent ,
2829 FormItemType ,
29- GroupItem , Item , LabelLocation , Properties , SimpleItemTemplateData , TabbedItem ,
30+ GroupItem ,
31+ Item ,
32+ LabelLocation ,
33+ Properties ,
34+ SimpleItemTemplateData ,
35+ TabbedItem ,
3036} from '@js/ui/form' ;
3137import { current , isMaterial , isMaterialBased } from '@js/ui/themes' ;
3238import type { ValidationResult } from '@js/ui/validation_group' ;
@@ -37,9 +43,7 @@ import Widget, { FOCUSED_STATE_CLASS } from '@ts/core/widget/widget';
3743import type { Button } from '@ts/ui/button/button' ;
3844import { DROP_DOWN_EDITOR_CLASS } from '@ts/ui/drop_down_editor/m_drop_down_editor' ;
3945import Editor from '@ts/ui/editor/editor' ;
40- import {
41- setLabelWidthByMaxLabelWidth ,
42- } from '@ts/ui/form/components/label' ;
46+ import { setLabelWidthByMaxLabelWidth } from '@ts/ui/form/components/label' ;
4347import {
4448 FIELD_ITEM_CLASS ,
4549 FIELD_ITEM_CONTENT_CLASS ,
@@ -58,6 +62,7 @@ import {
5862 GROUP_COL_COUNT_CLASS ,
5963 ROOT_SIMPLE_ITEM_CLASS ,
6064} from '@ts/ui/form/constants' ;
65+ import { getItemFormatInfo } from '@ts/ui/form/form.ai.utils' ;
6166import type { ItemOptionActionType } from '@ts/ui/form/form.item_options_actions' ;
6267import tryCreateItemOptionAction from '@ts/ui/form/form.item_options_actions' ;
6368import type {
@@ -91,6 +96,21 @@ import TabPanel from '@ts/ui/tab_panel/tab_panel';
9196import { TEXTEDITOR_CLASS , TEXTEDITOR_INPUT_CLASS } from '@ts/ui/text_box/m_text_editor.base' ;
9297import { TOOLBAR_CLASS } from '@ts/ui/toolbar/constants' ;
9398
99+ export type FormAICommandName = 'smartPaste' ;
100+ export interface AICommandParamsMap {
101+ smartPaste : SmartPasteCommandParams ;
102+ }
103+
104+ export interface AICommandResultMap {
105+ smartPaste : SmartPasteCommandResult ;
106+ }
107+
108+ interface AICommandWithParams < T extends FormAICommandName > {
109+ command : T ;
110+ params : AICommandParamsMap [ T ] ;
111+ callbacks : RequestCallbacks < AICommandResultMap [ T ] > ;
112+ }
113+
94114const ITEM_OPTIONS_FOR_VALIDATION_UPDATING = [ 'items' , 'isRequired' , 'validationRules' , 'visible' ] ;
95115
96116export interface FormProperties extends Properties {
@@ -104,6 +124,10 @@ export interface FormProperties extends Properties {
104124}
105125
106126class Form extends Widget < FormProperties > {
127+ private _abort ?: ( ) => void ;
128+
129+ private _currentAICommand ?: AICommandWithParams < FormAICommandName > = undefined ;
130+
107131 _targetScreenFactor ?: ScreenSizeQualifier ;
108132
109133 _lastMarkupScreenFactor ! : ScreenSizeQualifier ;
@@ -1100,6 +1124,11 @@ class Form extends Widget<FormProperties> {
11001124 ValidationEngine . removeGroup ( args . previousValue || this ) ;
11011125 this . _invalidate ( ) ;
11021126 break ;
1127+ // @ts -expect-error
1128+ case 'aiIntegration' : {
1129+ this . _processAIIntegrationUpdate ( ) ;
1130+ break ;
1131+ }
11031132 default :
11041133 super . _optionChanged ( args ) ;
11051134 }
@@ -1760,6 +1789,71 @@ class Form extends Widget<FormProperties> {
17601789 getTargetScreenFactor ( ) : ScreenSizeQualifier | undefined {
17611790 return this . _targetScreenFactor ;
17621791 }
1792+
1793+ private _processCommandCompletion ( ) : void {
1794+ this . _abort ?.( ) ;
1795+ this . _abort = undefined ;
1796+ this . _currentAICommand = undefined ;
1797+ }
1798+
1799+ private _processAIIntegrationUpdate ( ) : void {
1800+ if ( this . _currentAICommand ) {
1801+ const { command, params, callbacks } = this . _currentAICommand ;
1802+
1803+ this . _processCommandCompletion ( ) ;
1804+ this . _executeAICommand ( command , params , callbacks ) ;
1805+ }
1806+ }
1807+
1808+ private _executeAICommand < T extends FormAICommandName > (
1809+ command : T ,
1810+ params : AICommandParamsMap [ T ] ,
1811+ callbacks : RequestCallbacks < AICommandResultMap [ T ] > ,
1812+ ) : void {
1813+ // @ts -expect-error
1814+ const { aiIntegration } = this . option ( ) ;
1815+
1816+ this . _currentAICommand = {
1817+ command,
1818+ params,
1819+ callbacks,
1820+ } ;
1821+ this . _abort = aiIntegration ?. [ command ] ( params , callbacks ) ;
1822+ }
1823+
1824+ private _getSmartPasteCommandCallbacks ( ) : RequestCallbacks < SmartPasteCommandResult > {
1825+ return {
1826+ onComplete : ( fieldsData : SmartPasteCommandResult ) : void => {
1827+ this . beginUpdate ( ) ;
1828+ fieldsData . forEach ( ( { name, value } : SmartPasteCommandResult [ number ] ) => {
1829+ this . _updateFieldValue ( name , value ) ;
1830+ } ) ;
1831+ this . endUpdate ( ) ;
1832+ this . _processCommandCompletion ( ) ;
1833+ } ,
1834+ onError : ( ) : void => {
1835+ this . _processCommandCompletion ( ) ;
1836+ } ,
1837+ } ;
1838+ }
1839+
1840+ async smartPaste ( text ?: string ) : Promise < void > {
1841+ const dataItems = this . _itemsRunTimeInfo . getItemsForDataExtraction ( ) ;
1842+ const fields = dataItems . map ( ( item ) => ( {
1843+ name : item . dataField ,
1844+ format : getItemFormatInfo ( item ) ,
1845+ // @ts -expect-error
1846+ instruction : item . aiOptions ?. instruction ,
1847+ } ) ) ;
1848+
1849+ const smartPasteParams = {
1850+ text : text ?? await navigator . clipboard . readText ( ) ,
1851+ fields,
1852+ } ;
1853+ const smartPasteCallbacks = this . _getSmartPasteCommandCallbacks ( ) ;
1854+
1855+ this . _executeAICommand ( 'smartPaste' , smartPasteParams , smartPasteCallbacks ) ;
1856+ }
17631857}
17641858
17651859registerComponent ( 'dxForm' , Form ) ;
0 commit comments