=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java 2013-05-19 18:49:47 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java 2013-07-23 09:55:18 +0000 @@ -121,7 +121,7 @@ public BaseIdentifiableObject() { } - + public BaseIdentifiableObject( int id, String uid, String name ) { this.id = id; === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/Dashboard.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/Dashboard.java 2013-07-23 07:51:07 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/Dashboard.java 2013-07-23 09:55:18 +0000 @@ -38,6 +38,9 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +/** + * @author Lars Helge Overland + */ @JacksonXmlRootElement( localName = "dashboardItem", namespace = DxfNamespaces.DXF_2_0) public class Dashboard extends BaseIdentifiableObject @@ -58,6 +61,45 @@ } // ------------------------------------------------------------------------- + // Logic + // ------------------------------------------------------------------------- + + /** + * Moves an item in the list. Returns true if the operation lead to a + * modification of the list order. Returns false if there are no items, + * the given position is out of bounds, the item is not present, if position + * is equal to current item index or if attempting to move an item one + * position to the right (pointless operation). + * + * @param uid the uid of the item to move. + * @param position the new index position of the item. + * @return true if the operation lead to a modification of order, false otherwise. + */ + public boolean moveItem( String uid, int position ) + { + if ( items == null || position < 0 || position > items.size() ) + { + return false; // No items or position out of bounds + } + + int index = items.indexOf( new DashboardItem( uid ) ); + + if ( index == -1 || index == position || ( index + 1 ) == position ) + { + return false; // Not found, already at position or pointless move + } + + DashboardItem item = items.get( index ); + + index = position < index ? ( index + 1 ) : index; // New index after move + + items.add( position, item ); // Add item at position + items.remove( index ); // Remove item at previous index + + return true; + } + + // ------------------------------------------------------------------------- // Getters and setters // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/DashboardItem.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/DashboardItem.java 2013-07-23 07:51:07 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/DashboardItem.java 2013-07-23 09:55:18 +0000 @@ -45,6 +45,9 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +/** + * @author Lars Helge Overland + */ @JacksonXmlRootElement( localName = "dashboardItem", namespace = DxfNamespaces.DXF_2_0) public class DashboardItem extends BaseIdentifiableObject @@ -69,6 +72,11 @@ { } + public DashboardItem( String uid ) + { + this.uid = uid; + } + // ------------------------------------------------------------------------- // Logic // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/DashboardService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/DashboardService.java 2013-07-23 07:51:07 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dashboard/DashboardService.java 2013-07-23 09:55:18 +0000 @@ -43,6 +43,8 @@ void mergeDashboard( Dashboard dashboard ); + void mergeDashboardItem( DashboardItem item ); + int saveDashboard( Dashboard dashboard ); void updateDashboard( Dashboard dashboard ); === added directory 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/dashboard' === added file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/dashboard/DashboardTest.java' --- dhis-2/dhis-api/src/test/java/org/hisp/dhis/dashboard/DashboardTest.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/dashboard/DashboardTest.java 2013-07-23 09:55:18 +0000 @@ -0,0 +1,98 @@ +package org.hisp.dhis.dashboard; + +/* + * Copyright (c) 2004-2012, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +/** + * @author Lars Helge Overland + */ +public class DashboardTest +{ + @Test + public void testMoveItem() + { + Dashboard dashboard = new Dashboard(); + + DashboardItem diA = new DashboardItem(); + DashboardItem diB = new DashboardItem(); + DashboardItem diC = new DashboardItem(); + DashboardItem diD = new DashboardItem(); + + diA.setUid( "A" ); + diB.setUid( "B" ); + diC.setUid( "C" ); + diD.setUid( "D" ); + + dashboard.getItems().add( diA ); + dashboard.getItems().add( diB ); + dashboard.getItems().add( diC ); + dashboard.getItems().add( diD ); + + assertEquals( 4, dashboard.getItems().size() ); + assertEquals( 2, dashboard.getItems().indexOf( diC ) ); + + assertTrue( dashboard.moveItem( "B", 3 ) ); // Move B up + + assertEquals( 4, dashboard.getItems().size() ); + + assertEquals( 0, dashboard.getItems().indexOf( diA ) ); + assertEquals( 1, dashboard.getItems().indexOf( diC ) ); + assertEquals( 2, dashboard.getItems().indexOf( diB ) ); + assertEquals( 3, dashboard.getItems().indexOf( diD ) ); + + assertTrue( dashboard.moveItem( "C", 4 ) ); // Move C last + + assertEquals( 0, dashboard.getItems().indexOf( diA ) ); + assertEquals( 1, dashboard.getItems().indexOf( diB ) ); + assertEquals( 2, dashboard.getItems().indexOf( diD ) ); + assertEquals( 3, dashboard.getItems().indexOf( diC ) ); + + assertTrue( dashboard.moveItem( "D", 1 ) ); // Move D down + + assertEquals( 0, dashboard.getItems().indexOf( diA ) ); + assertEquals( 1, dashboard.getItems().indexOf( diD ) ); + assertEquals( 2, dashboard.getItems().indexOf( diB ) ); + assertEquals( 3, dashboard.getItems().indexOf( diC ) ); + + assertTrue( dashboard.moveItem( "C", 0 ) ); // Move C first + + assertEquals( 0, dashboard.getItems().indexOf( diC ) ); + assertEquals( 1, dashboard.getItems().indexOf( diA ) ); + assertEquals( 2, dashboard.getItems().indexOf( diD ) ); + assertEquals( 3, dashboard.getItems().indexOf( diB ) ); + + assertFalse( dashboard.moveItem( "C", 5 ) ); // Out of bounds + assertFalse( dashboard.moveItem( "A", 1 ) ); // Already at position + assertFalse( dashboard.moveItem( "A", 2 ) ); // Pointless move + } +} === modified file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/mock/MockI18nFormat.java' --- dhis-2/dhis-api/src/test/java/org/hisp/dhis/mock/MockI18nFormat.java 2011-12-26 10:07:59 +0000 +++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/mock/MockI18nFormat.java 2013-07-23 09:55:18 +0000 @@ -34,7 +34,6 @@ /** * @author Lars Helge Overland - * @version $Id$ */ public class MockI18nFormat extends I18nFormat === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/dashboard/impl/DefaultDashboardService.java' --- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/dashboard/impl/DefaultDashboardService.java 2013-07-23 07:51:07 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/dashboard/impl/DefaultDashboardService.java 2013-07-23 09:55:18 +0000 @@ -134,38 +134,43 @@ { for ( DashboardItem item : dashboard.getItems() ) { - if ( item.getChart() != null ) - { - item.setChart( chartService.getChart( item.getChart().getUid() ) ); - } - - if ( item.getChart() != null ) - { - item.setMap( mappingService.getMap( item.getMap().getUid() ) ); - } - - if ( item.getUsers() != null ) - { - item.setUsers( userService.getUsersByUid( getUids( item.getUsers() ) ) ); - } - - if ( item.getReportTables() != null ) - { - item.setReportTables( reportTableService.getReportTablesByUid( getUids( item.getReportTables() ) ) ); - } - - if ( item.getReports() != null ) - { - item.setReports( reportService.getReportsByUid( getUids( item.getReports() ) ) ); - } - - if ( item.getResources() != null ) - { - item.setResources( documentService.getDocumentsByUid( getUids( item.getResources() ) ) ); - } + mergeDashboardItem( item ); } } } + + public void mergeDashboardItem( DashboardItem item ) + { + if ( item.getChart() != null ) + { + item.setChart( chartService.getChart( item.getChart().getUid() ) ); + } + + if ( item.getChart() != null ) + { + item.setMap( mappingService.getMap( item.getMap().getUid() ) ); + } + + if ( item.getUsers() != null ) + { + item.setUsers( userService.getUsersByUid( getUids( item.getUsers() ) ) ); + } + + if ( item.getReportTables() != null ) + { + item.setReportTables( reportTableService.getReportTablesByUid( getUids( item.getReportTables() ) ) ); + } + + if ( item.getReports() != null ) + { + item.setReports( reportService.getReportsByUid( getUids( item.getReports() ) ) ); + } + + if ( item.getResources() != null ) + { + item.setResources( documentService.getDocumentsByUid( getUids( item.getResources() ) ) ); + } + } @Override public int saveDashboard( Dashboard dashboard ) === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DashboardController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DashboardController.java 2013-07-23 07:51:07 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DashboardController.java 2013-07-23 09:55:18 +0000 @@ -1,5 +1,32 @@ package org.hisp.dhis.api.controller; +/* + * Copyright (c) 2004-2012, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + import java.io.InputStream; import javax.servlet.http.HttpServletRequest; @@ -7,6 +34,7 @@ import org.hisp.dhis.api.utils.ContextUtils; import org.hisp.dhis.dashboard.Dashboard; +import org.hisp.dhis.dashboard.DashboardItem; import org.hisp.dhis.dashboard.DashboardSearchResult; import org.hisp.dhis.dashboard.DashboardService; import org.hisp.dhis.dxf2.utils.JacksonUtils; @@ -16,7 +44,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +/** + * @author Lars Helge Overland + */ @Controller @RequestMapping( value = DashboardController.RESOURCE_PATH ) public class DashboardController @@ -51,4 +83,35 @@ ContextUtils.createdResponse( response, "Dashboard created", RESOURCE_PATH + "/" + dashboard.getUid() ); } + + @RequestMapping( value = "/{uid}/items", method = RequestMethod.POST, consumes = "application/json" ) + public void addItem( HttpServletResponse response, HttpServletRequest request, + InputStream input, @PathVariable String uid ) throws Exception + { + Dashboard dashboard = dashboardService.getDashboard( uid ); + + DashboardItem item = JacksonUtils.fromJson( input, DashboardItem.class ); + + dashboardService.mergeDashboardItem( item ); + + dashboard.getItems().add( item ); + + dashboardService.updateDashboard( dashboard ); + + ContextUtils.createdResponse( response, "Dashboard item created", item.getUid() ); + } + + @RequestMapping( value = "/{dashboardUid}/items/{itemUid}/move", method = RequestMethod.PUT, consumes = "application/json" ) + public void moveItem( HttpServletResponse response, HttpServletRequest request, + @PathVariable String dashboardUid, @PathVariable String itemUid, @RequestParam int position ) throws Exception + { + Dashboard dashboard = dashboardService.getDashboard( dashboardUid ); + + if ( dashboard.moveItem( itemUid, position ) ) + { + dashboardService.updateDashboard( dashboard ); + + ContextUtils.okResponse( response, "Dashboard item moved" ); + } + } }