@@ -3,149 +3,143 @@ import { sampleProducts } from '../common/sample-products';
33import { MyCommandCell } from './MyCommandCell.jsx' ;
44import { Grid , GridColumn as Column , GridToolbar } from '@progress/kendo-react-grid' ;
55import { Button } from '@progress/kendo-react-buttons' ;
6- import { process } from '@progress/kendo-data-query ' ;
6+ import { insertItem , getItems , updateItem , deleteItem } from '../common/products-services ' ;
77import ThemeChooser from './ThemeChooser' ;
88
9- const GridPage = ( props ) => {
10- const editField = "inEdit" ;
11- const [ data , setData ] = useState ( sampleProducts ) ;
12- const [ dataState , setDataState ] = useState ( { skip : 0 , take : 10 } )
13-
14- const generateId = data => data . reduce ( ( acc , current ) => Math . max ( acc , current . ProductID ) , 0 ) + 1 ;
9+ const GridContext = React . createContext ( { } ) ;
1510
16- const removeItem = ( data , item ) => {
17- let index = data . findIndex ( p => ( p === item || item . ProductID ) && ( p . ProductID === item . ProductID ) ) ;
18- if ( index >= 0 ) {
19- data . splice ( index , 1 ) ;
20- }
21- }
11+ const CommandCell = ( props ) => {
12+ const { enterEdit, remove, add, discard, update, cancel } = React . useContext ( GridContext ) ;
13+ return (
14+ < MyCommandCell
15+ { ...props }
16+ edit = { enterEdit }
17+ remove = { remove }
18+ add = { add }
19+ discard = { discard }
20+ update = { update }
21+ cancel = { cancel }
22+ />
23+ )
24+ } ;
2225
26+ const DATA_ITEM_KEY = 'ProductID' ;
2327
24- const enterEdit = ( dataItem ) => {
25- setData ( data . map ( item =>
26- item . ProductID === dataItem . ProductID ?
27- { ...item , inEdit : true } : item
28- ) ) ;
29- }
28+ const GridPage = ( props ) => {
29+ const [ data , setData ] = useState ( sampleProducts ) ;
30+ const [ edit , setEdit ] = useState ( { } ) ;
3031
3132 const remove = ( dataItem ) => {
32-
33- const newData = [ ...data ] ;
34- removeItem ( newData , dataItem ) ;
35- removeItem ( sampleProducts , dataItem ) ;
33+ const newData = deleteItem ( dataItem ) ;
3634 setData ( [ ...newData ] ) ;
37- }
35+ } ;
3836
3937 const add = ( dataItem ) => {
40- dataItem . inEdit = undefined ;
41- dataItem . ProductID = generateId ( sampleProducts ) ;
42-
43- sampleProducts . unshift ( dataItem ) ;
44- setData ( [ ...data ] )
45- }
46-
47- const discard = ( dataItem ) => {
48- const newData = [ data ] ;
49- removeItem ( newData , dataItem ) ;
50-
38+ const newData = insertItem ( dataItem ) ;
5139 setData ( newData ) ;
52- }
40+ setEdit ( { } ) ;
41+ } ;
5342
5443 const update = ( dataItem ) => {
55- const newData = [ ... data ]
56- const updatedItem = { ... dataItem , inEdit : undefined } ;
57-
58- updateItem ( newData , updatedItem ) ;
59- updateItem ( sampleProducts , updatedItem ) ;
44+ dataItem . inEdit = false ;
45+ const newData = updateItem ( dataItem ) ;
46+ setData ( newData ) ;
47+ setEdit ( ( edit ) => ( { ... edit , [ String ( dataItem [ DATA_ITEM_KEY ] ) ] : false } ) ) ;
48+ } ;
6049
50+ const discard = ( dataItem ) => {
51+ const newData = [ ...data ] ;
52+ newData . splice ( 0 , 1 ) ;
6153 setData ( newData ) ;
62- }
54+ setEdit ( ( ) => ( { ...edit , [ String ( dataItem [ DATA_ITEM_KEY ] ) ] : false } ) ) ;
55+ } ;
6356
6457 const cancel = ( dataItem ) => {
65- const originalItem = sampleProducts . find ( p => p . ProductID === dataItem . ProductID ) ;
66- const newData = data . map ( item => item . ProductID === originalItem . ProductID ? originalItem : item ) ;
58+ const originalItem = getItems ( ) . find ( ( p ) => p [ DATA_ITEM_KEY ] === dataItem [ DATA_ITEM_KEY ] ) ;
59+ const newData = data . map ( ( item ) =>
60+ item [ DATA_ITEM_KEY ] === originalItem ?. [ DATA_ITEM_KEY ] ? originalItem : item
61+ ) ;
6762
6863 setData ( newData ) ;
69- }
64+ setEdit ( ( ) => ( { ...edit , [ String ( dataItem [ DATA_ITEM_KEY ] ) ] : false } ) ) ;
65+ } ;
7066
71- const updateItem = ( data , item ) => {
72- let index = data . findIndex ( p => p === item || ( item . ProductID && p . ProductID === item . ProductID ) ) ;
73- if ( index >= 0 ) {
74- data [ index ] = { ...item } ;
75- }
76- }
67+ const enterEdit = ( dataItem ) => {
68+ setEdit ( ( edit ) => ( { ...edit , [ String ( dataItem [ DATA_ITEM_KEY ] ) ] : true } ) ) ;
69+ } ;
7770
7871 const itemChange = ( event ) => {
79- const newData = data . map ( item =>
80- item . ProductID === event . dataItem . ProductID ?
81- { ...item , [ event . field ] : event . value } : item
72+ const field = event . field || '' ;
73+ const newData = data . map ( ( item ) =>
74+ item [ DATA_ITEM_KEY ] === event . dataItem [ DATA_ITEM_KEY ] ? { ...item , [ field ] : event . value } : item
8275 ) ;
76+
8377 setData ( newData ) ;
84- }
78+ } ;
8579
8680 const addNew = ( ) => {
87- const newDataItem = { inEdit : true , Discontinued : false } ;
81+ const newDataItem = {
82+ [ DATA_ITEM_KEY ] : null ,
83+ Discontinued : false
84+ } ;
85+
8886 setData ( [ newDataItem , ...data ] ) ;
89- }
87+ setEdit ( ( edit ) => ( { ...edit , [ String ( newDataItem [ DATA_ITEM_KEY ] ) ] : true } ) ) ;
88+ } ;
9089
9190 const cancelCurrentChanges = ( ) => {
9291 setData ( [ ...sampleProducts ] ) ;
9392 }
9493
95- const CommandCell = ( props ) => (
96- < MyCommandCell
97- { ...props }
98- edit = { enterEdit }
99- remove = { remove }
100- add = { add }
101- discard = { discard }
102- update = { update }
103- cancel = { cancel }
104- editField = { editField }
105- />
106- ) ;
107- const hasEditedItem = data . some ( p => p . inEdit ) ;
10894 return (
10995 < div className = "container-fluid" >
11096 < ThemeChooser changeTheme = { props . changeTheme } theme = { props . theme } />
11197 < div className = 'row my-4' >
11298 < div className = 'col-12 col-lg-9 border-right' >
113- < Grid
114- data = { process ( data , dataState ) }
115- onItemChange = { itemChange }
116- editField = { editField }
117- // pageable // uncomment to enable paging
118- // sortable // uncomment to enable sorting
119- // filterable // uncomment to enable filtering
120- onDataStateChange = { ( e ) =>
121- setDataState ( e . dataState )
122- } // uncomment to enable data operations
123- { ...dataState } // uncomment to enable data operations
124- >
125- < GridToolbar >
126- < Button
127- title = "Add new"
128- themeColor = { 'primary' }
129- onClick = { addNew }
130- >
131- Add new
132- </ Button >
133- { hasEditedItem && (
99+ < GridContext . Provider value = { { enterEdit, remove, add, discard, update, cancel } } >
100+ < Grid
101+ data = { data }
102+ autoProcessData = { true }
103+ dataItemKey = { DATA_ITEM_KEY }
104+
105+ pageable = { true }
106+ defaultSkip = { 0 }
107+ defaultTake = { 10 }
108+
109+ edit = { edit }
110+ editable = { { mode : 'inline' } }
111+ navigatable = { { mode : 'inline' } }
112+
113+ sortable = { true }
114+ filterable = { true }
115+
116+ onItemChange = { itemChange }
117+ >
118+ < GridToolbar >
134119 < Button
135- title = "Cancel current changes"
136- onClick = { cancelCurrentChanges }
120+ title = "Add new"
121+ themeColor = { 'primary' }
122+ onClick = { addNew }
137123 >
138- Cancel current changes
124+ Add new
139125 </ Button >
140- ) }
141- </ GridToolbar >
142- < Column field = "ProductID" title = "Id" width = "50px" editable = { false } />
143- < Column field = "ProductName" title = "Product Name" />
144- < Column field = "FirstOrderedOn" title = "First Ordered" editor = "date" format = "{0:d}" />
145- < Column field = "UnitsInStock" title = "Units" width = "150px" editor = "numeric" />
146- < Column field = "Discontinued" title = "Discontinued" editor = "boolean" />
147- < Column cell = { CommandCell } width = "240px" />
148- </ Grid >
126+ { Object . keys ( edit ) . length > 0 && (
127+ < Button
128+ title = "Cancel current changes"
129+ onClick = { cancelCurrentChanges }
130+ >
131+ Cancel current changes
132+ </ Button >
133+ ) }
134+ </ GridToolbar >
135+ < Column field = "ProductID" title = "Id" width = "50px" editable = { false } filterable = { false } />
136+ < Column field = "ProductName" title = "Product Name" />
137+ < Column field = "UnitPrice" title = "Unit Price" />
138+ < Column field = "UnitsInStock" title = "Units" width = "150px" editor = "numeric" />
139+ < Column field = "Discontinued" title = "Discontinued" editor = "boolean" />
140+ < Column cells = { { data : ( props ) => < CommandCell { ...props } /> } } width = "240px" filterable = { false } />
141+ </ Grid >
142+ </ GridContext . Provider >
149143 </ div >
150144 < div className = 'col-12 col-lg-3 mt-3 mt-lg-0' >
151145 < h3 > KendoReact Grid</ h3 >
0 commit comments