@@ -3,149 +3,143 @@ import { sampleProducts } from '../common/sample-products';
3
3
import { MyCommandCell } from './MyCommandCell.jsx' ;
4
4
import { Grid , GridColumn as Column , GridToolbar } from '@progress/kendo-react-grid' ;
5
5
import { Button } from '@progress/kendo-react-buttons' ;
6
- import { process } from '@progress/kendo-data-query ' ;
6
+ import { insertItem , getItems , updateItem , deleteItem } from '../common/products-services ' ;
7
7
import ThemeChooser from './ThemeChooser' ;
8
8
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 ( { } ) ;
15
10
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
+ } ;
22
25
26
+ const DATA_ITEM_KEY = 'ProductID' ;
23
27
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 ( { } ) ;
30
31
31
32
const remove = ( dataItem ) => {
32
-
33
- const newData = [ ...data ] ;
34
- removeItem ( newData , dataItem ) ;
35
- removeItem ( sampleProducts , dataItem ) ;
33
+ const newData = deleteItem ( dataItem ) ;
36
34
setData ( [ ...newData ] ) ;
37
- }
35
+ } ;
38
36
39
37
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 ) ;
51
39
setData ( newData ) ;
52
- }
40
+ setEdit ( { } ) ;
41
+ } ;
53
42
54
43
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
+ } ;
60
49
50
+ const discard = ( dataItem ) => {
51
+ const newData = [ ...data ] ;
52
+ newData . splice ( 0 , 1 ) ;
61
53
setData ( newData ) ;
62
- }
54
+ setEdit ( ( ) => ( { ...edit , [ String ( dataItem [ DATA_ITEM_KEY ] ) ] : false } ) ) ;
55
+ } ;
63
56
64
57
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
+ ) ;
67
62
68
63
setData ( newData ) ;
69
- }
64
+ setEdit ( ( ) => ( { ...edit , [ String ( dataItem [ DATA_ITEM_KEY ] ) ] : false } ) ) ;
65
+ } ;
70
66
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
+ } ;
77
70
78
71
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
82
75
) ;
76
+
83
77
setData ( newData ) ;
84
- }
78
+ } ;
85
79
86
80
const addNew = ( ) => {
87
- const newDataItem = { inEdit : true , Discontinued : false } ;
81
+ const newDataItem = {
82
+ [ DATA_ITEM_KEY ] : null ,
83
+ Discontinued : false
84
+ } ;
85
+
88
86
setData ( [ newDataItem , ...data ] ) ;
89
- }
87
+ setEdit ( ( edit ) => ( { ...edit , [ String ( newDataItem [ DATA_ITEM_KEY ] ) ] : true } ) ) ;
88
+ } ;
90
89
91
90
const cancelCurrentChanges = ( ) => {
92
91
setData ( [ ...sampleProducts ] ) ;
93
92
}
94
93
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 ) ;
108
94
return (
109
95
< div className = "container-fluid" >
110
96
< ThemeChooser changeTheme = { props . changeTheme } theme = { props . theme } />
111
97
< div className = 'row my-4' >
112
98
< 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 >
134
119
< Button
135
- title = "Cancel current changes"
136
- onClick = { cancelCurrentChanges }
120
+ title = "Add new"
121
+ themeColor = { 'primary' }
122
+ onClick = { addNew }
137
123
>
138
- Cancel current changes
124
+ Add new
139
125
</ 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 >
149
143
</ div >
150
144
< div className = 'col-12 col-lg-3 mt-3 mt-lg-0' >
151
145
< h3 > KendoReact Grid</ h3 >
0 commit comments