@@ -27,7 +27,7 @@ import union from 'lodash/union';
2727import { DispatchCell } from '@jsonforms/react' ;
2828import startCase from 'lodash/startCase' ;
2929import range from 'lodash/range' ;
30- import React from 'react' ;
30+ import React , { Fragment } from 'react' ;
3131import { connect } from 'react-redux' ;
3232import {
3333 FormHelperText ,
@@ -37,7 +37,8 @@ import {
3737 TableCell ,
3838 TableHead ,
3939 TableRow ,
40- Typography
40+ Typography ,
41+ Grid
4142} from '@material-ui/core' ;
4243import {
4344 ArrayLayoutProps ,
@@ -51,13 +52,22 @@ import {
5152} from '@jsonforms/core' ;
5253import IconButton from '@material-ui/core/IconButton' ;
5354import DeleteIcon from '@material-ui/icons/Delete' ;
55+ import ArrowDownward from '@material-ui/icons/ArrowDownward' ;
56+ import ArrowUpward from '@material-ui/icons/ArrowUpward' ;
57+
5458import { WithDeleteDialogSupport } from './DeleteDialog' ;
5559import NoBorderTableCell from './NoBorderTableCell' ;
5660import TableToolbar from './TableToolbar' ;
57-
5861// we want a cell that doesn't automatically span
5962const styles = {
6063 fixedCell : {
64+ width : '150px' ,
65+ height : '50px' ,
66+ paddingLeft : 0 ,
67+ paddingRight : 0 ,
68+ textAlign : 'center'
69+ } ,
70+ fixedCellSmall : {
6171 width : '50px' ,
6272 height : '50px' ,
6373 paddingLeft : 0 ,
@@ -114,7 +124,7 @@ export interface EmptyTableProps {
114124const EmptyTable = ( { numColumns } : EmptyTableProps ) => (
115125 < TableRow >
116126 < NoBorderTableCell colSpan = { numColumns } >
117- < Typography align = ' center' > No data</ Typography >
127+ < Typography align = " center" > No data</ Typography >
118128 </ NoBorderTableCell >
119129 </ TableRow >
120130) ;
@@ -141,14 +151,11 @@ const mapStateToNonEmptyCellProps = (
141151 state : JsonFormsState ,
142152 ownProps : OwnPropsOfNonEmptyCell
143153) : NonEmptyCellProps => {
144-
145- const path = ownProps . rowPath + ( ownProps . schema . type === 'object' ? '.' + ownProps . propName : '' ) ;
154+ const path =
155+ ownProps . rowPath +
156+ ( ownProps . schema . type === 'object' ? '.' + ownProps . propName : '' ) ;
146157 const errors = formatErrorMessage (
147- union (
148- getErrorAt ( path , ownProps . schema ) ( state ) . map (
149- error => error . message
150- )
151- )
158+ union ( getErrorAt ( path , ownProps . schema ) ( state ) . map ( error => error . message ) )
152159 ) ;
153160 return {
154161 rowPath : ownProps . rowPath ,
@@ -185,12 +192,12 @@ class NonEmptyCellInner extends React.Component<NonEmptyCellProps, any> {
185192 path = { path }
186193 />
187194 ) : (
188- < DispatchCell
189- schema = { schema }
190- uischema = { controlWithoutLabel ( '#' ) }
191- path = { path }
192- />
193- ) }
195+ < DispatchCell
196+ schema = { schema }
197+ uischema = { controlWithoutLabel ( '#' ) }
198+ path = { path }
199+ />
200+ ) }
194201 < FormHelperText error = { ! isValid } > { ! isValid && errors } </ FormHelperText >
195202 </ NoBorderTableCell >
196203 ) ;
@@ -202,60 +209,113 @@ interface NonEmptyRowProps {
202209 childPath : string ;
203210 schema : JsonSchema ;
204211 rowIndex : number ;
212+ moveUp : ( ) => void ;
213+ moveDown : ( ) => void ;
214+ enableUp : boolean ;
215+ enableDown : boolean ;
216+ showSortButtons : boolean ;
205217}
206218
207- const NonEmptyRow = React . memo ( ( {
208- childPath,
209- schema,
210- rowIndex,
211- openDeleteDialog
212- } : NonEmptyRowProps & WithDeleteDialogSupport ) => (
213- < TableRow key = { childPath } hover >
214- { generateCells ( NonEmptyCell , schema , childPath ) }
215- < NoBorderTableCell style = { styles . fixedCell } >
216- < div style = { { display : 'flex' , justifyContent : 'center' } } >
217- < IconButton
218- aria-label = { `Delete` }
219- onClick = { ( ) => openDeleteDialog ( childPath , rowIndex ) }
220- >
221- < DeleteIcon />
222- </ IconButton >
223- </ div >
224- </ NoBorderTableCell >
225- </ TableRow >
226- ) ) ;
219+ const NonEmptyRow = React . memo (
220+ ( {
221+ childPath,
222+ schema,
223+ rowIndex,
224+ openDeleteDialog,
225+ moveUp,
226+ moveDown,
227+ enableUp,
228+ enableDown,
229+ showSortButtons
230+ } : NonEmptyRowProps & WithDeleteDialogSupport ) => {
231+ return (
232+ < TableRow key = { childPath } hover >
233+ { generateCells ( NonEmptyCell , schema , childPath ) }
234+ < NoBorderTableCell
235+ style = { showSortButtons ? styles . fixedCell : styles . fixedCellSmall }
236+ >
237+ < Grid container direction = "row" justify = "center" alignItems = "center" >
238+ { showSortButtons ? (
239+ < Fragment >
240+ < Grid item >
241+ < IconButton
242+ aria-label = { `Move up` }
243+ onClick = { moveUp }
244+ disabled = { ! enableUp }
245+ >
246+ < ArrowUpward />
247+ </ IconButton >
248+ </ Grid >
249+ < Grid item >
250+ < IconButton
251+ aria-label = { `Move down` }
252+ onClick = { moveDown }
253+ disabled = { ! enableDown }
254+ >
255+ < ArrowDownward />
256+ </ IconButton >
257+ </ Grid >
258+ </ Fragment >
259+ ) : (
260+ ''
261+ ) }
262+
263+ < Grid item >
264+ < IconButton
265+ aria-label = { `Delete` }
266+ onClick = { ( ) => openDeleteDialog ( childPath , rowIndex ) }
267+ >
268+ < DeleteIcon />
269+ </ IconButton >
270+ </ Grid >
271+ </ Grid >
272+ </ NoBorderTableCell >
273+ </ TableRow >
274+ ) ;
275+ }
276+ ) ;
227277interface TableRowsProp {
228278 data : number ;
229279 path : string ;
230280 schema : JsonSchema ;
281+ moveUp ?( path : string , toMove : number ) : ( ) => void ;
282+ moveDown ?( path : string , toMove : number ) : ( ) => void ;
283+ uischema : ControlElement ;
231284}
232285const TableRows = ( {
233286 data,
234287 path,
235288 schema,
236- openDeleteDialog
289+ openDeleteDialog,
290+ moveUp,
291+ moveDown,
292+ uischema
237293} : TableRowsProp & WithDeleteDialogSupport ) => {
238294 const isEmptyTable = data === 0 ;
239-
240295 if ( isEmptyTable ) {
241296 return < EmptyTable numColumns = { getValidColumnProps ( schema ) . length + 1 } /> ;
242297 }
243-
244298 return (
245299 < React . Fragment >
246300 { range ( data ) . map ( ( index : number ) => {
247301 const childPath = Paths . compose (
248302 path ,
249303 `${ index } `
250304 ) ;
251-
252305 return (
253306 < NonEmptyRow
254307 key = { childPath }
255308 childPath = { childPath }
256309 rowIndex = { index }
257310 schema = { schema }
258311 openDeleteDialog = { openDeleteDialog }
312+ moveUp = { moveUp ( path , index ) }
313+ moveDown = { moveDown ( path , index ) }
314+ enableUp = { index !== 0 }
315+ enableDown = { index !== data - 1 }
316+ showSortButtons = {
317+ uischema . options && uischema . options . showSortButtons
318+ }
259319 />
260320 ) ;
261321 } ) }
@@ -266,7 +326,7 @@ const TableRows = ({
266326export class MaterialTableControl extends React . Component <
267327 ArrayLayoutProps & WithDeleteDialogSupport ,
268328 any
269- > {
329+ > {
270330 addItem = ( path : string , value : any ) => this . props . addItem ( path , value ) ;
271331 render ( ) {
272332 const {
0 commit comments