@@ -7,6 +7,7 @@ import { CommandDialog } from './CommandDialog';
77import { Command , CommandResult , CommandValidator } from '@cratis/arc/commands' ;
88import { PropertyDescriptor } from '@cratis/arc/reflection' ;
99import { InputTextField , NumberField , TextAreaField } from '../CommandForm/fields' ;
10+ import { DialogResult , useDialog , useDialogContext } from '@cratis/arc.react/dialogs' ;
1011import '@cratis/arc/validation' ;
1112
1213const meta : Meta < typeof CommandDialog > = {
@@ -87,7 +88,7 @@ class UpdateUserCommandWithServer extends Command<object> {
8788 }
8889}
8990
90- const DialogWrapper = ( ) => {
91+ const ServerValidationWrapper = ( ) => {
9192 const [ visible , setVisible ] = useState ( true ) ;
9293 const [ result , setResult ] = useState < string > ( '' ) ;
9394 const [ validationErrors , setValidationErrors ] = useState < string [ ] > ( [ ] ) ;
@@ -122,99 +123,88 @@ const DialogWrapper = () => {
122123 </ div >
123124 ) }
124125
125- < CommandDialog < UpdateUserCommand >
126- command = { UpdateUserCommand }
126+ < CommandDialog < UpdateUserCommandWithServer >
127+ command = { UpdateUserCommandWithServer }
127128 visible = { visible }
128- header = "Update User Information (with Validation)"
129+ header = "Update User Information (with Server Validation)"
129130 confirmLabel = "Save"
130131 cancelLabel = "Cancel"
131- autoServerValidate = { false }
132132 onConfirm = { async ( commandResult ) => {
133133 setResult ( JSON . stringify ( commandResult ) ) ;
134134 setVisible ( false ) ;
135135 } }
136136 onCancel = { ( ) => setVisible ( false ) }
137- onFieldChange = { ( command ) => {
138- // Client-side only validation - validate as fields change
139- const errors = command . validation ?. validate ( command ) ?? [ ] ;
140- setValidationErrors ( errors . map ( v => v . message ) ) ;
137+ onFieldChange = { async ( command ) => {
138+ // Progressive validation - validate as fields change
139+ const validationResult = await command . validate ( ) ;
140+
141+ if ( ! validationResult . isValid ) {
142+ setValidationErrors ( validationResult . validationResults . map ( v => v . message ) ) ;
143+ } else {
144+ setValidationErrors ( [ ] ) ;
145+ }
141146 } }
142147 >
143- < InputTextField value = { ( c : UpdateUserCommand ) => c . name } title = "Name" placeholder = "Enter name (min 2 chars)" />
144- < InputTextField value = { ( c : UpdateUserCommand ) => c . email } title = "Email" placeholder = "Enter email" type = "email" />
145- < NumberField value = { ( c : UpdateUserCommand ) => c . age } title = "Age" placeholder = "Enter age (18-120)" />
148+ < InputTextField value = { ( c : UpdateUserCommandWithServer ) => c . name } title = "Name" placeholder = "Enter name (min 2 chars)" />
149+ < InputTextField value = { ( c : UpdateUserCommandWithServer ) => c . email } title = "Email" placeholder = "Enter email" type = "email" />
150+ < NumberField value = { ( c : UpdateUserCommandWithServer ) => c . age } title = "Age" placeholder = "Enter age (18-120)" />
146151 </ CommandDialog >
147152 </ div >
148153 ) ;
149154} ;
150155
151- const ServerValidationWrapper = ( ) => {
152- const [ visible , setVisible ] = useState ( true ) ;
156+ const AwaitableWithResultWrapper = ( ) => {
153157 const [ result , setResult ] = useState < string > ( '' ) ;
154- const [ validationErrors , setValidationErrors ] = useState < string [ ] > ( [ ] ) ;
158+
159+ const UpdateUserDialog = ( ) => {
160+ const { closeDialog } = useDialogContext < CommandResult < object > > ( ) ;
161+
162+ return (
163+ < CommandDialog < UpdateUserCommand >
164+ command = { UpdateUserCommand }
165+ header = "Update User Information (awaitable result)"
166+ confirmLabel = "Save"
167+ cancelLabel = "Cancel"
168+ autoServerValidate = { false }
169+ onConfirm = { async commandResult => closeDialog ( DialogResult . Ok , commandResult ) }
170+ onCancel = { ( ) => closeDialog ( DialogResult . Cancelled ) }
171+ >
172+ < InputTextField value = { ( c : UpdateUserCommand ) => c . name } title = "Name" placeholder = "Enter name (min 2 chars)" />
173+ < InputTextField value = { ( c : UpdateUserCommand ) => c . email } title = "Email" placeholder = "Enter email" type = "email" />
174+ < NumberField value = { ( c : UpdateUserCommand ) => c . age } title = "Age" placeholder = "Enter age (18-120)" />
175+ </ CommandDialog >
176+ ) ;
177+ } ;
178+
179+ const [ UpdateUserDialogComponent , showUpdateUserDialog ] = useDialog < CommandResult < object > > ( UpdateUserDialog ) ;
155180
156181 return (
157182 < div className = "storybook-wrapper" >
158183 < button
159184 className = "p-button p-component mb-3"
160- onClick = { ( ) => {
161- setVisible ( true ) ;
162- setValidationErrors ( [ ] ) ;
163- setResult ( '' ) ;
185+ onClick = { async ( ) => {
186+ const [ dialogResult , commandResult ] = await showUpdateUserDialog ( ) ;
187+ if ( dialogResult === DialogResult . Ok && commandResult ) {
188+ setResult ( JSON . stringify ( commandResult ) ) ;
189+ }
164190 } }
165191 >
166192 Open Dialog
167193 </ button >
168194
169- { validationErrors . length > 0 && (
170- < div className = "p-3 mt-3 bg-red-100 border-round" >
171- < strong > Validation Errors:</ strong >
172- < ul className = "mt-2 mb-0" >
173- { validationErrors . map ( ( error , index ) => (
174- < li key = { index } > { error } </ li >
175- ) ) }
176- </ ul >
177- </ div >
178- ) }
179-
180195 { result && (
181196 < div className = "p-3 mt-3 bg-green-100 border-round" >
182197 < strong > Command executed:</ strong > { result }
183198 </ div >
184199 ) }
185200
186- < CommandDialog < UpdateUserCommandWithServer >
187- command = { UpdateUserCommandWithServer }
188- visible = { visible }
189- header = "Update User Information (with Server Validation)"
190- confirmLabel = "Save"
191- cancelLabel = "Cancel"
192- onConfirm = { async ( commandResult ) => {
193- setResult ( JSON . stringify ( commandResult ) ) ;
194- setVisible ( false ) ;
195- } }
196- onCancel = { ( ) => setVisible ( false ) }
197- onFieldChange = { async ( command ) => {
198- // Progressive validation - validate as fields change
199- const validationResult = await command . validate ( ) ;
200-
201- if ( ! validationResult . isValid ) {
202- setValidationErrors ( validationResult . validationResults . map ( v => v . message ) ) ;
203- } else {
204- setValidationErrors ( [ ] ) ;
205- }
206- } }
207- >
208- < InputTextField value = { ( c : UpdateUserCommandWithServer ) => c . name } title = "Name" placeholder = "Enter name (min 2 chars)" />
209- < InputTextField value = { ( c : UpdateUserCommandWithServer ) => c . email } title = "Email" placeholder = "Enter email" type = "email" />
210- < NumberField value = { ( c : UpdateUserCommandWithServer ) => c . age } title = "Age" placeholder = "Enter age (18-120)" />
211- </ CommandDialog >
201+ < UpdateUserDialogComponent />
212202 </ div >
213203 ) ;
214204} ;
215205
216206export const Default : Story = {
217- render : ( ) => < DialogWrapper /> ,
207+ render : ( ) => < AwaitableWithResultWrapper /> ,
218208} ;
219209
220210export const WithServerValidation : Story = {
0 commit comments