Author: bleny Date: 2010-11-19 17:13:34 +0000 (Fri, 19 Nov 2010) New Revision: 792 Log: add multi-select filters on synthesis and sampling plan ; consider sample-row code uniqueness in boarding indicator Modified: trunk/src/site/rst/business-rules.rst trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java trunk/wao-business/src/main/xmi/wao.zargo trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/base/AbstractFilteredPage.java trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Synthesis.java trunk/wao-ui/src/main/resources/fr/ifremer/wao/ui/pages/Synthesis.properties trunk/wao-ui/src/main/webapp/SamplingPlan.tml trunk/wao-ui/src/main/webapp/Synthesis.tml Modified: trunk/src/site/rst/business-rules.rst =================================================================== --- trunk/src/site/rst/business-rules.rst 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/src/site/rst/business-rules.rst 2010-11-19 17:13:34 UTC (rev 792) @@ -189,7 +189,7 @@ 0,1 Formule : - (nombre de marées respectant le critère du numbre d'observateurs embarqués ÷ nombre de marées réalisées) × 100 + (nombre de marées respectant le critère du nombre d'observateurs embarqués ÷ nombre de marées réalisées) × 100 +---------+--------+------------------+------------------+------------------+-------------------+-------+ | Niveaux | 1 | 2 | 3 | 4 | 5 | 6 | @@ -204,8 +204,13 @@ 0,2 Formule : - (nombre de marées à 1 seule sollicitation ÷ nombre de marées réalisées) × 100 + (nombre de marées valides ÷ nombre de marées réalisées) × 100 +Une marée est considérée comme valide pour un même bateau si ce sont des lignes +du plan d'échantillonage différentes qui ont été observées. Par contre, on peut +observer sur un même bateau et pour la même ligne du plan à condition que ces +observations soient effectuées à plus de 3 mois d'intervale. + +---------+--------+------------------+------------------+------------------+-------------------+-------+ | Niveaux | 1 | 2 | 3 | 4 | 5 | 6 | +---------+--------+------------------+------------------+------------------+-------------------+-------+ Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java 2010-11-19 17:13:34 UTC (rev 792) @@ -24,7 +24,6 @@ package fr.ifremer.wao.service; -import fr.ifremer.wao.bean.SynthesisId; import fr.ifremer.wao.WaoContext; import fr.ifremer.wao.WaoDAOHelper; import fr.ifremer.wao.WaoException; @@ -32,8 +31,38 @@ import fr.ifremer.wao.WaoQueryHelper; import fr.ifremer.wao.WaoQueryHelper.BoatDistrictProperty; import fr.ifremer.wao.WaoQueryHelper.ContactProperty; -import fr.ifremer.wao.bean.*; -import fr.ifremer.wao.entity.*; +import fr.ifremer.wao.bean.BoardingResult; +import fr.ifremer.wao.bean.BoardingResultImpl; +import fr.ifremer.wao.bean.ContactAverageReactivity; +import fr.ifremer.wao.bean.ContactAverageReactivityImpl; +import fr.ifremer.wao.bean.ContactFilter; +import fr.ifremer.wao.bean.ContactPieChartConstant; +import fr.ifremer.wao.bean.ContactState; +import fr.ifremer.wao.bean.ContactStateStatistics; +import fr.ifremer.wao.bean.ContactStateStatisticsImpl; +import fr.ifremer.wao.bean.DataReliability; +import fr.ifremer.wao.bean.GlobalSynthesisParameters; +import fr.ifremer.wao.bean.GlobalSynthesisParametersImpl; +import fr.ifremer.wao.bean.GlobalSynthesisResult; +import fr.ifremer.wao.bean.GlobalSynthesisResultImpl; +import fr.ifremer.wao.bean.PieChartData; +import fr.ifremer.wao.bean.PieChartDataImpl; +import fr.ifremer.wao.bean.PieChartSeries; +import fr.ifremer.wao.bean.PieChartSeriesImpl; +import fr.ifremer.wao.bean.SamplingFilter; +import fr.ifremer.wao.bean.SynthesisId; +import fr.ifremer.wao.entity.Boat; +import fr.ifremer.wao.entity.Company; +import fr.ifremer.wao.entity.Contact; +import fr.ifremer.wao.entity.ContactDAO; +import fr.ifremer.wao.entity.Indicator; +import fr.ifremer.wao.entity.IndicatorDAO; +import fr.ifremer.wao.entity.IndicatorLevel; +import fr.ifremer.wao.entity.IndicatorLevelImpl; +import fr.ifremer.wao.entity.IndicatorLog; +import fr.ifremer.wao.entity.IndicatorLogImpl; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.WaoUser; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; import org.nuiton.topia.framework.TopiaQuery; @@ -50,6 +79,7 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -177,29 +207,31 @@ * company is needed. * * @return a BoardingResult which contains the number of boats for boardings - * from 1 to {@code MAX_BOARDINGS}, the boat with the max boarding and its - * value. + * and for invalid boardings from 1 to {@code MAX_BOARDINGS}, the boat with + * the max boarding and its value. * @throws WaoException */ - @Override - public BoardingResult executeGetBoardingBoats(TopiaContext transaction, - SamplingFilter filter) - throws TopiaException { - Map<String, Integer> map = new LinkedHashMap<String, Integer>(); + protected BoardingResult executeGetBoardingBoats(TopiaContext transaction, SamplingFilter filter) throws Exception { + Map<String, Integer> mapBoarding = new LinkedHashMap<String, Integer>(); + Map<String, Integer> mapInvalidBoarding = new LinkedHashMap<String, Integer>(); BoardingResult result = new BoardingResultImpl(); - result.setData(map); + result.setBoardings(mapBoarding); + result.setInvalidBoarding(mapInvalidBoarding); // Initialize max boardings and its max key value - final int maxBoardings = 12; - final String maxBoardingsKey = maxBoardings + " +"; + final int MAX_BOARDINGS = 12; + final String maxBoardingsKey = MAX_BOARDINGS + " +"; // Prepare map which contains for each entry the number of boardings // for the key and the number of boats for the value. - for (int i = 1; i < maxBoardings; i++) { - map.put(String.valueOf(i), 0); + mapInvalidBoarding.put(String.valueOf(0), 0); + for (int i = 1; i < MAX_BOARDINGS; i++) { + mapBoarding.put(String.valueOf(i), 0); + mapInvalidBoarding.put(String.valueOf(i), 0); } - map.put(maxBoardingsKey, 0); + mapBoarding.put(maxBoardingsKey, 0); + mapInvalidBoarding.put(maxBoardingsKey, 0); // The number of boardings is the number of finished contacts // Use fromDate to filter contacts finished from this date @@ -207,61 +239,162 @@ WaoQueryBuilder builder = context.newQueryBuilder(); ContactProperty contactProperty = builder.initializeForContact(); TopiaQuery query = builder.applySamplingFilter(filter). - addEquals(contactProperty.state(), ContactState.BOARDING_DONE.ordinal()). - addEquals(contactProperty.validationCompany(), Boolean.TRUE). - addNullOr(contactProperty.validationProgram(), Op.EQ, Boolean.TRUE); + addEquals(contactProperty.state(), ContactState.BOARDING_DONE.ordinal()); - String contact = query.getMainAlias(); - String sampleRow = contact + "." + Contact.SAMPLE_ROW; + if (filter.getEstimatedTides()) { + query.addNullOr(contactProperty.validationCompany(), Op.EQ, Boolean.TRUE); + } else { + query.addEquals(contactProperty.validationCompany(), Boolean.TRUE); + } // Only for sampleRows with averageTideTime less or equals to 2 days - query.addWhere(sampleRow + "." + SampleRow.AVERAGE_TIDE_TIME, Op.LE, 2.); + WaoQueryHelper.SampleRowProperty sampleRowProperty = WaoQueryHelper.newSampleRowProperty(); + query.addWhere(sampleRowProperty.averageTideTime(), Op.LE, 2.); - // Prepare aliases for mapping results in select part - String countAlias = "nbBoardings"; - String boatAlias = "boat"; - // Use a map for each result with boat and its number of boardings - // Order by number of boardings to easily find the max value (the - // first result) - query.setSelect("new map(" + contact + "." + Contact.BOAT + " as " + - boatAlias + ", COUNT(*) as " + countAlias + ")"). - addGroup(contact + "." + Contact.BOAT). - addOrderDesc("COUNT(*)"); + WaoQueryHelper.BoatProperty boatProperty = WaoQueryHelper.newBoatProperty(); + query.setSelect(boatProperty.$alias(), // boat + sampleRowProperty.code(), // sample-row code + contactProperty.tideBeginDate()) // boarding date + // join contact, boats, and sample-rows + .addJoin(contactProperty.boat(), boatProperty.$alias(), false) + .addJoin(contactProperty.sampleRow(), sampleRowProperty.$alias(), false) + + // and sort everything + .addOrder(boatProperty.name(), + sampleRowProperty.code(), + contactProperty.tideBeginDate()); + if (log.isTraceEnabled()) { log.trace("Exec query : " + query); } - List<Map<String, Object>> nbBoardingsByBoat = transaction.findByQuery(query); + List<Object[]> nbBoardingsByBoat = transaction.findByQuery(query); - if (!nbBoardingsByBoat.isEmpty()) { - for (Map<String, Object> row : nbBoardingsByBoat) { - Long count = (Long)row.get(countAlias); - int intValue = count.intValue(); - String value = count.toString(); - if (intValue >= maxBoardings) { - value = maxBoardingsKey; + + + if (log.isDebugEnabled()) { + for (Object[] row : nbBoardingsByBoat) { + log.debug("results for nbBoardingBoats " + Arrays.toString(row)); + } + } + + // results like + // [AN TUAZ COZ, 2010_0043, 2009-11-19 00:00:00.0] + // [AN TUAZ COZ, 2010_0043, 2009-11-20 00:00:00.0] + // [APHRODITE, 2009_0185, 2009-09-24 00:00:00.0] + // [APHRODITE, 2009_0186, 2009-05-26 00:00:00.0] + // [APHRODITE, 2009_0186, 2009-06-23 00:00:00.0] + // [APHRODITE, 2009_0186, 2009-07-23 00:00:00.0] + // [ARC EN CIEL, 2009_0172, 2009-09-23 00:00:00.0] + // [ARC EN CIEL, 2009_0200, 2010-01-16 00:00:00.0] + // [ARC EN CIEL, 2009_0200, 2010-01-17 00:00:00.0] + // [ARC EN CIEL, 2009_0200, 2010-02-13 00:00:00.0] + + String lastBoatName = null; + String lastSampleRowCode = null; + Date lastTideBeginDate = null; + + int currentBoardingCount = 1; + int currentInvalidBoardingCount = 0; + + int maxBoardingCount = -1; + Boat maxBoardingBoat = null; + + // We will browse result line after line, at each line, we know what was + // in the last line. By Comparing we know if it's the same boat. + // If yes, check sample-row and date to count a possible invalid + // boarding. If no, we changed boat and then we can add it to the totals + // and consider it as a maximum + //for (Object[] row : nbBoardingsByBoat) { + Iterator<Object[]> it = nbBoardingsByBoat.iterator(); + while (it.hasNext()) { + Object[] row = it.next(); + + Boat boat = (Boat) row[0]; + String boatName = boat.getName(); + String sampleRowCode = (String) row[1]; + Date tideBeginDate = (Date) row[2]; + + if (log.isDebugEnabled()) { + log.debug("results for nbBoardingBoats " + Arrays.toString(row)); + } + + if (boatName.equals(lastBoatName)) { + + currentBoardingCount += 1; + + if (sampleRowCode.equals(lastSampleRowCode) && + DateUtil.getDifferenceInMonths(lastTideBeginDate, tideBeginDate) <= 3) { + + currentInvalidBoardingCount += 1; } - // Increment the number of boats for the current number of - // boardings - Integer nbBoats = map.get(value); - map.put(value, nbBoats + 1); + } - // Set the max boat and its number of boardings value - Map<String, Object> max = nbBoardingsByBoat.get(0); - result.setMaxBoardingBoat((Boat)max.get(boatAlias)); - Long maxValue = (Long)max.get(countAlias); - result.setMaxBoardingValue(maxValue.intValue()); - } - - if (log.isDebugEnabled()) { - log.debug("results in data from getBoardingBoat "); - for (Map.Entry<String, Integer> entry : result.getData().entrySet()) { - log.debug(entry.getKey() + " -> " + entry.getValue()); + boolean computeValue = // there is two case when we know we can consider we + // computed a new set of data for a same boat + + // first case, current row has not the same boat + // as last row. Common case : we can conclude + // things from last rows + ! boatName.equals(lastBoatName) + // just one exception for the first row + // don't conclude things for boat "null" + && lastBoatName != null + + // second case, this is the last boat and + // the last row, we must compute now or we will + // miss data for the last boat + || ! it.hasNext(); + + if (computeValue) { + + // update max + if (currentBoardingCount > maxBoardingCount) { + maxBoardingCount = currentBoardingCount; + maxBoardingBoat = boat; + } + + // update mapBoarding + String key; + if (currentBoardingCount >= MAX_BOARDINGS) { + key = maxBoardingsKey; + } else { + key = String.valueOf(currentBoardingCount); + } + + Integer oldValue = mapBoarding.get(key); + mapBoarding.put(key, oldValue + 1); + + // update mapInvalidBoarding + if (currentInvalidBoardingCount >= MAX_BOARDINGS) { + key = maxBoardingsKey; + } else { + key = String.valueOf(currentInvalidBoardingCount); + } + + oldValue = mapInvalidBoarding.get(key); + mapInvalidBoarding.put(key, oldValue + 1); + + if (log.isDebugEnabled()) { + log.debug(lastBoatName + " made " + currentBoardingCount + " boardings and " + + currentInvalidBoardingCount + " invalid boardings"); + } + + // re-initialize values for the new boat in the lines + currentBoardingCount = 1; + currentInvalidBoardingCount = 0; } + + lastBoatName = boatName; + lastSampleRowCode = sampleRowCode; + lastTideBeginDate = tideBeginDate; } - + + result.setMaxBoardingValue(maxBoardingCount); + result.setMaxBoardingBoat(maxBoardingBoat); + return result; } @@ -776,14 +909,15 @@ /** return null if 0 boarding */ protected Double getIndicatorValueForBoarding(SamplingFilter filter) { BoardingResult boardingResult = getBoardingBoats(filter); - int numberOfBoatWithOneBoarding = boardingResult.getData().get("1"); + + int numberOfBoatsWithZeroInvalidBoarding = boardingResult.getInvalidBoarding().get(String.valueOf(0)); int totalNumberOfBoarding = 0; - for (Integer numberOfBoarding : boardingResult.getData().values()) { + for (Integer numberOfBoarding : boardingResult.getBoardings().values()) { totalNumberOfBoarding += numberOfBoarding; } Double rate = null; if (totalNumberOfBoarding > 0) { - rate = ((double) numberOfBoatWithOneBoarding / + rate = ((double) numberOfBoatsWithZeroInvalidBoarding / (double) totalNumberOfBoarding) * 100.0; } return rate; Modified: trunk/wao-business/src/main/xmi/wao.zargo =================================================================== (Binary files differ) Modified: trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java =================================================================== --- trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java 2010-11-19 17:13:34 UTC (rev 792) @@ -184,11 +184,12 @@ /** EXEC METHOD **/ SamplingFilter filter = new SamplingFilterImpl(); + filter.setEstimatedTides(true); BoardingResult result = service.getBoardingBoats(filter); // one boat with one boarding (177474) - assertEquals(1, result.getData().get("1").intValue()); + assertEquals(1, result.getBoardings().get("1").intValue()); // one boat with two boardings (174258) - assertEquals(1, result.getData().get("2").intValue()); + assertEquals(1, result.getBoardings().get("2").intValue()); assertEquals(2, result.getMaxBoardingValue()); assertEquals(174258, result.getMaxBoardingBoat().getImmatriculation()); } Modified: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/base/AbstractFilteredPage.java =================================================================== --- trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/base/AbstractFilteredPage.java 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/base/AbstractFilteredPage.java 2010-11-19 17:13:34 UTC (rev 792) @@ -143,6 +143,26 @@ @Persist private boolean programSelect; + + + + public void onSelectedFromAddSampleRowCode() { + + List<SampleRow> rows = getFilter().getSampleRows(); + if (rows == null) { + rows = new ArrayList<SampleRow>(); + getFilter().setSampleRows(rows); + } + rows.add(getSampleRowSelectModel().findObject(sampleRowId)); + + edited = true; + } + + public void onSelectedFromRemoveSampleRowCode() { + getFilter().getSampleRows().remove(getSampleRowSelectModel().findObject(sampleRowId)); + edited = true; + } + /** * Need to be call in setupRender of the page which inherits this abstract * class. @@ -286,10 +306,10 @@ getFilter().setSampleRow(rowFiltered); */ - //List<SampleRow> rowsFiltered = getFilter().getSampleRows(); - //getFilter().setSampleRows(null); + List<SampleRow> rowsFiltered = getFilter().getSampleRows(); + getFilter().setSampleRows(null); List<SampleRow> sampleRows = serviceSampling.getSampleRowsByFilter(getFilter()); - //getFilter().setSampleRows(rowsFiltered); + getFilter().setSampleRows(rowsFiltered); sampleRowSelectModel = new GenericSelectModel<SampleRow>(sampleRows, SampleRow.class, "code", "topiaId", propertyAccess); Modified: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Synthesis.java =================================================================== --- trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Synthesis.java 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Synthesis.java 2010-11-19 17:13:34 UTC (rev 792) @@ -40,6 +40,7 @@ import fr.ifremer.wao.entity.Company; import fr.ifremer.wao.entity.Indicator; import fr.ifremer.wao.entity.IndicatorLevel; +import fr.ifremer.wao.entity.SampleRow; import fr.ifremer.wao.service.ServiceSynthesis; import fr.ifremer.wao.ui.base.AbstractFilteredPage; import fr.ifremer.wao.ui.data.ChartUtils; @@ -70,6 +71,7 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; @@ -287,6 +289,12 @@ return this; } + /** + * Current SampleRow from loop + */ + @Property + private SampleRow row; + /********************* DYNAMICAL GRAPH : DATA SAMPLING ********************/ @InjectComponent @@ -323,10 +331,10 @@ private BoardingResult boardingResult; - public JFreeChart getBoardingBoatsChart() throws WaoException { + /*public JFreeChart getBoardingBoatsChart() throws WaoException { Map<String, Map<?, Integer>> data = new HashMap<String, Map<?, Integer>>(); - data.put("Navires", getBoardingResult().getData()); + data.put("Navires", getBoardingResult().getBoardings()); String title = "Sollicitations des navires depuis le " + getDateFormat().format(getFilter().getPeriod().getFromDate()); @@ -338,6 +346,29 @@ return ChartUtils.createCategoryChart(title, "Nb navires", "Nb embarquements", ChartType.BAR, data); + }*/ + + public JFreeChart getBoardingBoatsChart() throws WaoException { + Map<String, Map<?, Integer>> data = + new LinkedHashMap<String, Map<?, Integer>>(); + + // remove column with number of boats with 0 invalid boarding, we + // don't want it to be showed in the graph. + getBoardingResult().getInvalidBoarding().remove(String.valueOf(0)); + + data.put("Nombre de navires ayant effectués x embarquements", getBoardingResult().getBoardings()); + data.put("Nombre de navires ayant effectués x embarquements invalides", getBoardingResult().getInvalidBoarding()); + + String title = "Sollicitations des navires depuis le " + + getDateFormat().format(getFilter().getPeriod().getFromDate()); + + Company companyForBoarding = getFilter().getCompany(); + if (companyForBoarding != null) { + title += "\nSociété " + companyForBoarding.getName(); + } + + return ChartUtils.createCategoryChart(title, "Nb navires", + "Nb embarquements", ChartType.BAR, data); } public BoardingResult getBoardingResult() throws WaoException { Modified: trunk/wao-ui/src/main/resources/fr/ifremer/wao/ui/pages/Synthesis.properties =================================================================== --- trunk/wao-ui/src/main/resources/fr/ifremer/wao/ui/pages/Synthesis.properties 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-ui/src/main/resources/fr/ifremer/wao/ui/pages/Synthesis.properties 2010-11-19 17:13:34 UTC (rev 792) @@ -29,7 +29,7 @@ boatDistrictCode-label: Quartier facadeName-label: Fa\u00e7ade sectorName-label: Zone -sampleRow-label: Code ligne +sampleRowId-label: Code ligne company-label: Soci\u00e9t\u00e9 programName-label: Programme estimatedTides-label: Voir l'effort d'observations estim\u00e9 Modified: trunk/wao-ui/src/main/webapp/SamplingPlan.tml =================================================================== --- trunk/wao-ui/src/main/webapp/SamplingPlan.tml 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-ui/src/main/webapp/SamplingPlan.tml 2010-11-19 17:13:34 UTC (rev 792) @@ -136,8 +136,16 @@ <select t:type="select" t:id="sectorName" t:model="sectorSelectModel" t:value="filter.sectorName" /> <input t:type="submit" class="ico22px refresh" t:id="refreshBySector" value="Refresh" title="Rafraîchir les métiers en fonction de la zone sélectionnée"/> + <select t:type="select" t:id="sampleRowId" t:model="sampleRowSelectModel" t:value="sampleRowId" /> + <input t:type="submit" class="ico22px add" t:id="addSampleRowCode" value="Add" title="Ajouter un code de ligne"/> + <input t:type="submit" class="ico22px remove" t:id="removeSampleRowCode" value="Remove" title="Retirer un code de ligne" /> + <ul> + <li style="display: inline;" t:type="loop" t:source="filter.sampleRows" t:value="row" t:volatile="true"> + ${row.code} + </li> + </ul> <t:zone id="so-sampling-sampleRowZone" t:id="sampleRowZone" t:update="show"> - <t:nuiton.subForm t:visible="refreshSampleRowCodeZone"> + <!--t:nuiton.subForm t:visible="refreshSampleRowCodeZone"> <t:label t:for="selectedSampleRow" />: <select t:type="select" t:id="selectedSampleRow" t:value="selectedSampleRow" t:model="sampleRowSelectModel" t:mixins="ck/onEvent" t:event="change"/> @@ -148,11 +156,11 @@ <li style="display: inline;" t:type="loop" t:source="filter.sampleRows" t:value="row" t:index="sampleRowCodeIndex" t:volatile="true"> ${row.code} <a t:type="actionlink" t:id="removeSampleRowCode" t:context="sampleRowCodeIndex" title="Supprimer ce code de ligne" t:zone="so-sampling-sampleRowZone"> - <img src="${asset:context:img/clock-22px.png}" /> + <img src="${asset:context:img/remove-22px.png}" /> </a> </li> </ul> - </t:nuiton.subForm> + </t:nuiton.subForm--> </t:zone> </div> <div> @@ -242,7 +250,7 @@ <t:if t:test="canEditSampleRow()"> <t:if test="rowModified"> <a t:type="pagelink" t:page="sampleRowHistoric" t:context="row.code"> - <img src="${asset:context:}/img/edit.png" class="fright" alt=" * " title="Cette ligne a été modifiée (voir l'historique)"/> + <img src="${asset:context:}/img/clock-22px.png" class="fright" alt=" * " title="Cette ligne a été modifiée (voir l'historique)"/> </a> </t:if> </t:if> Modified: trunk/wao-ui/src/main/webapp/Synthesis.tml =================================================================== --- trunk/wao-ui/src/main/webapp/Synthesis.tml 2010-11-18 12:32:18 UTC (rev 791) +++ trunk/wao-ui/src/main/webapp/Synthesis.tml 2010-11-19 17:13:34 UTC (rev 792) @@ -66,8 +66,15 @@ <select t:type="select" t:id="sectorName" t:model="sectorSelectModel" value="filter.sectorName" /> <input t:type="submit" class="ico22px refresh" t:id="refreshBySector" value="Refresh" title="Rafraîchir les métiers en fonction de la zone sélectionnée"/> - <t:label t:for="sampleRow" />: - <input t:type="select" t:id="sampleRow" t:model="sampleRowSelectModel" value="sampleRowId" /> + <t:label t:for="sampleRowId" />: + <select t:type="select" t:id="sampleRowId" t:model="sampleRowSelectModel" t:value="sampleRowId" /> + <input t:type="submit" class="ico22px add" t:id="addSampleRowCode" value="Add" title="Ajouter un code de ligne"/> + <input t:type="submit" class="ico22px remove" t:id="removeSampleRowCode" value="Remove" title="Retirer un code de ligne" /> + <ul> + <li style="display: inline;" t:type="loop" t:source="filter.sampleRows" t:value="row" t:volatile="true"> + ${row.code} + </li> + </ul> <!--<t:label t:for="program" />: <input t:type="select" t:id="program" t:model="programSelectModel" value="programId" />-->