@@ -61,6 +61,46 @@ class UpdateUserCommand extends Command<object> {
6161 }
6262}
6363
64+ /** Command that simulates a 2-second server delay to demonstrate the busy state. */
65+ class DemoSlowUpdateUserCommand extends Command < object > {
66+ readonly route : string = '/api/users/update' ;
67+ readonly validation : CommandValidator = new UpdateUserCommandValidator ( ) ;
68+ readonly propertyDescriptors : PropertyDescriptor [ ] = [
69+ new PropertyDescriptor ( 'name' , String ) ,
70+ new PropertyDescriptor ( 'email' , String ) ,
71+ new PropertyDescriptor ( 'age' , Number ) ,
72+ ] ;
73+
74+ name = '' ;
75+ email = '' ;
76+ age = 0 ;
77+
78+ constructor ( ) {
79+ super ( Object , false ) ;
80+ }
81+
82+ get requestParameters ( ) : string [ ] {
83+ return [ ] ;
84+ }
85+
86+ get properties ( ) : string [ ] {
87+ return [ 'name' , 'email' , 'age' ] ;
88+ }
89+
90+ override async validate ( ) : Promise < CommandResult < object > > {
91+ const errors = this . validation ?. validate ( this ) ?? [ ] ;
92+ if ( errors . length > 0 ) {
93+ return CommandResult . validationFailed ( errors ) ;
94+ }
95+ return CommandResult . empty ;
96+ }
97+
98+ override async execute ( ) : Promise < CommandResult < object > > {
99+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
100+ return CommandResult . empty ;
101+ }
102+ }
103+
64104/** Variant that keeps the original server-calling validate() for the WithServerValidation story. */
65105class UpdateUserCommandWithServer extends Command < object > {
66106 readonly route : string = '/api/users/update' ;
@@ -681,3 +721,50 @@ const MixedChildrenWrapper = () => {
681721export const MixedChildren : Story = {
682722 render : ( ) => < MixedChildrenWrapper /> ,
683723} ;
724+
725+ const WithBusyStateWrapper = ( ) => {
726+ const [ visible , setVisible ] = useState ( true ) ;
727+ const [ result , setResult ] = useState < string > ( '' ) ;
728+
729+ return (
730+ < div className = "storybook-wrapper" >
731+ < button
732+ className = "p-button p-component mb-3"
733+ onClick = { ( ) => {
734+ setResult ( '' ) ;
735+ setVisible ( true ) ;
736+ } }
737+ >
738+ Open Dialog
739+ </ button >
740+
741+ { result && (
742+ < div className = "p-3 mt-3 bg-green-100 border-round" >
743+ < strong > Saved:</ strong > { result }
744+ </ div >
745+ ) }
746+
747+ < CommandDialog < DemoSlowUpdateUserCommand >
748+ command = { DemoSlowUpdateUserCommand }
749+ visible = { visible }
750+ title = "Save User (2s simulated delay)"
751+ okLabel = "Save"
752+ cancelLabel = "Cancel"
753+ autoServerValidate = { false }
754+ onConfirm = { async ( ) => {
755+ setResult ( 'User saved successfully' ) ;
756+ setVisible ( false ) ;
757+ } }
758+ onCancel = { ( ) => setVisible ( false ) }
759+ >
760+ < InputTextField value = { ( c : DemoSlowUpdateUserCommand ) => c . name } title = "Name" placeholder = "Enter name (min 2 chars)" />
761+ < InputTextField value = { ( c : DemoSlowUpdateUserCommand ) => c . email } title = "Email" placeholder = "Enter email" type = "email" />
762+ < NumberField value = { ( c : DemoSlowUpdateUserCommand ) => c . age } title = "Age" placeholder = "Enter age (18-120)" />
763+ </ CommandDialog >
764+ </ div >
765+ ) ;
766+ } ;
767+
768+ export const WithBusyState : Story = {
769+ render : ( ) => < WithBusyStateWrapper /> ,
770+ } ;
0 commit comments