r84 - in trunk: . faxtomail-persistence/src/main/java/com/franciaflex/faxtomail/persistence/entities faxtomail-persistence/src/main/xmi faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service faxtomail-ui-web faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin faxtomail-ui-web/src/main/resources/i18n faxtomail-ui-web/src/main/webap
Author: echatellier Date: 2014-05-21 18:53:25 +0200 (Wed, 21 May 2014) New Revision: 84 Url: http://forge.codelutin.com/projects/faxtomail/repository/revisions/84 Log: refs #4662: Refactoring de la configuration Added: trunk/faxtomail-persistence/src/main/java/com/franciaflex/faxtomail/persistence/entities/Field.java trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/HibernateProxyTypeAdapter.java trunk/faxtomail-ui-web/src/main/webapp/js/faxtomail.js Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.properties trunk/faxtomail-persistence/src/main/xmi/faxtomail.zargo trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/CompanyService.java trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/ConfigurationService.java trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/InitFaxToMailService.java trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/MailFolderService.java trunk/faxtomail-ui-web/pom.xml trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailActionSupport.java trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailApplicationListener.java trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java trunk/faxtomail-ui-web/src/main/resources/i18n/faxtomail-ui-web_fr_FR.properties trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration.jsp trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js trunk/pom.xml Added: trunk/faxtomail-persistence/src/main/java/com/franciaflex/faxtomail/persistence/entities/Field.java =================================================================== --- trunk/faxtomail-persistence/src/main/java/com/franciaflex/faxtomail/persistence/entities/Field.java (rev 0) +++ trunk/faxtomail-persistence/src/main/java/com/franciaflex/faxtomail/persistence/entities/Field.java 2014-05-21 16:53:25 UTC (rev 84) @@ -0,0 +1,53 @@ +package com.franciaflex.faxtomail.persistence.entities; + +/* + * #%L + * FaxToMail :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2014 Franciaflex, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +/** + * Required email fields for specific {@link EtatAttente}. + * + * @author Eric Chatellier + */ +public enum Field { + + RECEPTION_DATE, + EDI_CODE_NUMBER, + PROJECT_REFERENCE, + SENDER, + FAX, + RECIPIENT, + OBJECT, + ARCHIVE_DATE, + COMPANY_REFERENCE, + ORIGINAL_EMAIL, + COMMENT, + DEMAND_TYPE, + PRIORITY, + ETAT_ATTENTE, + TAKEN_BY, + RANGE_ROW, + CLIENT, + DEMANDE_STATUS + +} Property changes on: trunk/faxtomail-persistence/src/main/java/com/franciaflex/faxtomail/persistence/entities/Field.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.properties =================================================================== --- trunk/faxtomail-persistence/src/main/xmi/faxtomail.properties 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-persistence/src/main/xmi/faxtomail.properties 2014-05-21 16:53:25 UTC (rev 84) @@ -25,7 +25,6 @@ model.tagValue.constantPrefix=PROPERTY_ model.tagValue.java.lang.String=text #model.tagvalue.java.sql.Blob=blob -#model.tagvalue.byte=binary model.tagValue.useEnumerationName=true model.tagValue.doNotGenerateBooleanGetMethods=true @@ -35,3 +34,24 @@ # AttachmentFile com.franciaflex.faxtomail.persistence.entities.AttachmentFile.attribute.filename.tagvalue.notNull=true com.franciaflex.faxtomail.persistence.entities.AttachmentFile.attribute.content.tagvalue.notNull=true + +# Company +com.franciaflex.faxtomail.persistence.entities.Company.attribute.name.tagvalue.naturalId=true + +# MailFolder +com.franciaflex.faxtomail.persistence.entities.MailFolder.attribute.parent.tagvalue.naturalId=true +com.franciaflex.faxtomail.persistence.entities.MailFolder.attribute.parent.tagvalue.notNull=false +com.franciaflex.faxtomail.persistence.entities.MailFolder.attribute.name.tagvalue.naturalId=true + +# EtatAttente +com.franciaflex.faxtomail.persistence.entities.EtatAttente.attribute.label.tagvalue.naturalId=true + +# Priority +com.franciaflex.faxtomail.persistence.entities.Priority.attribute.label.tagvalue.naturalId=true + +# Range +com.franciaflex.faxtomail.persistence.entities.Range.attribute.label.tagvalue.naturalId=true + +# DemandType +com.franciaflex.faxtomail.persistence.entities.DemandType.attribute.label.tagvalue.naturalId=true + Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.zargo =================================================================== (Binary files differ) Modified: trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/CompanyService.java =================================================================== --- trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/CompanyService.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/CompanyService.java 2014-05-21 16:53:25 UTC (rev 84) @@ -73,7 +73,7 @@ return company; } - public Company saveCompany(Company company, Collection<MailFolder> mailFolders, Map<MailFilter, String> mailFilters) { + /*public Company saveCompany(Company company, Collection<MailFolder> mailFolders, Map<MailFilter, String> mailFilters) { Preconditions.checkNotNull(company); ConfigurationService configurationService = getConfigurationService(); @@ -99,7 +99,7 @@ getPersistenceContext().commit(); return company; - } + }*/ public Collection<MailFilter> saveMailFilters(Collection<MailFilter> mailFilters) { MailFilterTopiaDao dao = getPersistenceContext().getMailFilterDao(); Modified: trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/ConfigurationService.java =================================================================== --- trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/ConfigurationService.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/ConfigurationService.java 2014-05-21 16:53:25 UTC (rev 84) @@ -24,21 +24,17 @@ * #L% */ -import com.franciaflex.faxtomail.persistence.entities.CompanyTopiaDao; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.franciaflex.faxtomail.persistence.entities.Configuration; +import com.franciaflex.faxtomail.persistence.entities.ConfigurationImpl; import com.franciaflex.faxtomail.persistence.entities.ConfigurationTopiaDao; -import com.franciaflex.faxtomail.persistence.entities.MailFilter; -import com.franciaflex.faxtomail.persistence.entities.MailFilterTopiaDao; import com.franciaflex.faxtomail.services.FaxToMailServiceSupport; import com.google.common.collect.Lists; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.topia.persistence.TopiaIdFactory; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - /** * @author kmorin <kmorin@codelutin.com> * @since x.x @@ -53,15 +49,27 @@ return configs; } - public Configuration getConfiguration(String id) { + /** + * Return unique database configuration. + * + * @return configuration (not {@code null}, created on not found in database) + */ + public Configuration getConfiguration() { ConfigurationTopiaDao dao = getPersistenceContext().getConfigurationDao(); - Configuration config = dao.findByTopiaId(id); + Configuration config = dao.forAll().findUniqueOrNull(); + if (config == null) { + config = new ConfigurationImpl(); + } return config; } public Configuration saveConfiguration(Configuration config) { ConfigurationTopiaDao dao = getPersistenceContext().getConfigurationDao(); - config = dao.update(config); + if (config.isPersisted()) { + config = dao.update(config); + } else { + config = dao.create(config); + } return config; } Modified: trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/InitFaxToMailService.java =================================================================== --- trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/InitFaxToMailService.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/InitFaxToMailService.java 2014-05-21 16:53:25 UTC (rev 84) @@ -260,12 +260,12 @@ // "lastAttachmentOpeningUser," + // Email.PROPERTY_ATTACHMENT // ); - Configuration configuration = configurationTopiaDao.create(); - Company fx = companyTopiaDao.create(Company.PROPERTY_NAME, "Franciaflex", + //Configuration configuration = configurationTopiaDao.create(); + Company fx = companyTopiaDao.create(Company.PROPERTY_NAME, "Franciaflex"/*, Company.PROPERTY_CONFIGURATION, configuration, - Company.PROPERTY_MAIL_FOLDER, folders.values()); - companyTopiaDao.create(Company.PROPERTY_NAME, "Faber", Company.PROPERTY_CONFIGURATION, configurationTopiaDao.create()); - companyTopiaDao.create(Company.PROPERTY_NAME, "France Fermeture", Company.PROPERTY_CONFIGURATION, configurationTopiaDao.create()); + Company.PROPERTY_MAIL_FOLDER, folders.values()*/); + companyTopiaDao.create(Company.PROPERTY_NAME, "Faber"/*, Company.PROPERTY_CONFIGURATION, configurationTopiaDao.create()*/); + companyTopiaDao.create(Company.PROPERTY_NAME, "France Fermeture"/*, Company.PROPERTY_CONFIGURATION, configurationTopiaDao.create()*/); // user folders Collections.shuffle(etatAttentes); @@ -324,8 +324,8 @@ if (emailFiltersPropertiesStream != null) { List<MailFilter> mailFilters = getReferentielService().importEmailFilters(emailFiltersPropertiesStream, folders); - fx.addAllMailFilter(mailFilters); - companyTopiaDao.update(fx); + //fx.addAllMailFilter(mailFilters); + //companyTopiaDao.update(fx); } } catch(Exception e) { Modified: trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/MailFolderService.java =================================================================== --- trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/MailFolderService.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/service/MailFolderService.java 2014-05-21 16:53:25 UTC (rev 84) @@ -79,6 +79,12 @@ MailFolderTopiaDao dao = getPersistenceContext().getMailFolderDao(); return new ArrayList<MailFolder>(dao.findAll()); } + + public List<MailFolder> getRootMailFolders() { + MailFolderTopiaDao dao = getPersistenceContext().getMailFolderDao(); + List<MailFolder> result = dao.forParentEquals(null).findAll(); + return result; + } public List<MailFolder> getMailFolders(Collection<String> ids) { MailFolderTopiaDao dao = getPersistenceContext().getMailFolderDao(); Modified: trunk/faxtomail-ui-web/pom.xml =================================================================== --- trunk/faxtomail-ui-web/pom.xml 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/pom.xml 2014-05-21 16:53:25 UTC (rev 84) @@ -238,6 +238,10 @@ <artifactId>select2</artifactId> </dependency> + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-angular-ui-tree</artifactId> + </dependency> </dependencies> <build> Added: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/HibernateProxyTypeAdapter.java =================================================================== --- trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/HibernateProxyTypeAdapter.java (rev 0) +++ trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/HibernateProxyTypeAdapter.java 2014-05-21 16:53:25 UTC (rev 84) @@ -0,0 +1,58 @@ +package com.franciaflex.faxtomail; + +import java.io.IOException; + +import org.hibernate.Hibernate; +import org.hibernate.proxy.HibernateProxy; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +/** + * This TypeAdapter unproxies Hibernate proxied objects, and serializes them + * through the registered (or default) TypeAdapter of the base class. + * + * Voir : http://stackoverflow.com/a/13525550/2038100 + */ +public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> { + + public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { + @Override + @SuppressWarnings("unchecked") + public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { + return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null); + } + }; + private final Gson context; + + private HibernateProxyTypeAdapter(Gson context) { + this.context = context; + } + + @Override + public HibernateProxy read(JsonReader in) throws IOException { + throw new UnsupportedOperationException("Not supported"); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public void write(JsonWriter out, HibernateProxy value) throws IOException { + if (value == null) { + out.nullValue(); + return; + } + // Retrieve the original (not proxy) class + Class<?> baseType = Hibernate.getClass(value); + // Get the TypeAdapter of the original class, to delegate the serialization + TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType)); + // Get a filled instance of the original class + Object unproxiedValue = value.getHibernateLazyInitializer().getImplementation(); + // Serialize the value + delegate.write(out, unproxiedValue); + } + +} Property changes on: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/HibernateProxyTypeAdapter.java ___________________________________________________________________ Added: svn:eol-style + native Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailActionSupport.java =================================================================== --- trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailActionSupport.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailActionSupport.java 2014-05-21 16:53:25 UTC (rev 84) @@ -24,17 +24,36 @@ * #L% */ -import com.franciaflex.faxtomail.FaxToMailConfiguration; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.web.struts2.BaseAction; +import com.franciaflex.faxtomail.FaxToMailConfiguration; +import com.franciaflex.faxtomail.HibernateProxyTypeAdapter; +import com.franciaflex.faxtomail.persistence.entities.MailFilter; +import com.franciaflex.faxtomail.persistence.entities.MailFilterAbstract; +import com.franciaflex.faxtomail.persistence.entities.MailFolder; +import com.franciaflex.faxtomail.persistence.entities.MailFolderAbstract; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opensymphony.xwork2.ActionSupport; + @Results({ @Result(name="login", type="redirectAction", params = { "actionName", "login!input", "namespace", "/authentication"}) }) -public class FaxToMailActionSupport extends BaseAction { +public class FaxToMailActionSupport extends ActionSupport { + private static final Log log = LogFactory.getLog(FaxToMailActionSupport.class); + public static final String SAVE = "save"; public static final String NEXT = "next"; @@ -43,6 +62,8 @@ private FaxToMailSession session; + protected Gson gson; + public void setApplicationConfig(FaxToMailConfiguration applicationConfig) { this.applicationConfig = applicationConfig; } @@ -63,22 +84,19 @@ return true; } - public String translateEnum(Class cl, String name) { + /*public String translateEnum(Class cl, String name) { return t(cl.getName() + "." + name); } public String translateEnum(Enum en) { return translateEnum(en.getClass(), en.name()); - } + }*/ public String getId(TopiaEntity entity) { - // XXX brendan 19/08/13 hashCode may return a non-unique value String id = ""; if (entity.getTopiaId() != null) { - id = Integer.toString(entity.getTopiaId().hashCode()); - } return id; @@ -89,25 +107,67 @@ return applicationConfig.getInstanceDisclaimer(); } -// public String getUserName() { -// ExtranetUser extranetUser = session.getExtranetUser(); -// String userName = ""; -// if (extranetUser != null) { -// userName = extranetUser.getFirstName() + " " + extranetUser.getLastName(); -// } -// return userName; -// } - -// public boolean isConnected() { -// ExtranetUser extranetUser = session.getExtranetUser(); -// return extranetUser != null; -// } - public void setSession(FaxToMailSession session) { this.session = session; } -// public String getSupportEmail() { -// return getApplicationConfig().getSupportEmail(); -// } + public String toJson(Object element) { + String result = null; + try { + result = getGson().toJson(element); + } catch (Exception e) { + log.warn("Can't convert object to json", e); + } + return result; + } + + public Gson getGson() { + if (gson == null) { + GsonBuilder builder = new GsonBuilder(); + + // exclusion + final Multimap<Class<?>, String> gsonExclusions = HashMultimap.create(); + gsonExclusions.put(MailFolderAbstract.class, MailFolder.PROPERTY_PARENT); + gsonExclusions.put(MailFilterAbstract.class, MailFilter.PROPERTY_MAIL_FOLDER); + builder.addSerializationExclusionStrategy(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes f) { + // TODO AThimel 06/08/13 Maybe another Multimap implementation will do the job ? + Class<?> declaringClass = f.getDeclaringClass(); + String attributeName = f.getName(); + boolean result = gsonExclusions.containsEntry(declaringClass, attributeName); + return result; + } + + @Override + public boolean shouldSkipClass(Class<?> clazz) { + return false; + } + }); + + // Type adapters : Hibernate proxies + builder.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY); + + gson = builder.create(); + } + return gson; + } + + /** + * Transform enumeration values into map with i18n value for each enum value. + * + * i18n key is fqn.NAME + * + * @param values values to transform + * @return map (enum value > i18n text) + */ + protected <T> Map<T, String> getEnumAsMap(T... values) { + Map<T, String> valuesMap = Maps.newLinkedHashMap(); + for (T value : values) { + String i18n = value.getClass().getName() + "." + value.toString(); + String trans = getText(i18n); + valuesMap.put(value, trans); + } + return valuesMap; + } } Modified: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailApplicationListener.java =================================================================== --- trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailApplicationListener.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/FaxToMailApplicationListener.java 2014-05-21 16:53:25 UTC (rev 84) @@ -24,9 +24,9 @@ * #L% */ -import com.franciaflex.faxtomail.FaxToMailApplicationContext; -import com.franciaflex.faxtomail.persistence.entities.FaxToMailTopiaPersistenceContext; -import com.franciaflex.faxtomail.services.FaxToMailServiceContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.CronScheduleBuilder; @@ -39,8 +39,10 @@ import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; +import com.franciaflex.faxtomail.FaxToMailApplicationContext; +import com.franciaflex.faxtomail.persistence.entities.FaxToMailTopiaPersistenceContext; +import com.franciaflex.faxtomail.services.FaxToMailServiceContext; +import com.franciaflex.faxtomail.services.service.InitFaxToMailService; public class FaxToMailApplicationListener implements ServletContextListener { @@ -69,6 +71,9 @@ FaxToMailTopiaPersistenceContext persistenceContext = applicationContext.newPersistenceContext(); FaxToMailServiceContext serviceContext = applicationContext.newServiceContext(persistenceContext); + + serviceContext.newService(InitFaxToMailService.class).init(); + data.put(MailFilterJob.SERVICE_CONTEXT, serviceContext); JobDetail job = JobBuilder.newJob(MailFilterJob.class) Modified: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java =================================================================== --- trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java 2014-05-21 16:53:25 UTC (rev 84) @@ -24,40 +24,23 @@ * #L% */ -import com.franciaflex.faxtomail.persistence.entities.Company; -import com.franciaflex.faxtomail.persistence.entities.Email; -import com.franciaflex.faxtomail.persistence.entities.FaxToMailUser; -import com.franciaflex.faxtomail.persistence.entities.FaxToMailUserGroup; -import com.franciaflex.faxtomail.persistence.entities.MailFilter; -import com.franciaflex.faxtomail.persistence.entities.MailFilterImpl; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.franciaflex.faxtomail.persistence.entities.Action; +import com.franciaflex.faxtomail.persistence.entities.Configuration; +import com.franciaflex.faxtomail.persistence.entities.EtatAttente; +import com.franciaflex.faxtomail.persistence.entities.Field; import com.franciaflex.faxtomail.persistence.entities.MailFolder; -import com.franciaflex.faxtomail.persistence.entities.MailFolderImpl; -import com.franciaflex.faxtomail.services.service.CompanyService; +import com.franciaflex.faxtomail.services.service.ConfigurationService; import com.franciaflex.faxtomail.services.service.MailFolderService; -import com.franciaflex.faxtomail.services.service.UserService; +import com.franciaflex.faxtomail.services.service.ReferentielService; import com.franciaflex.faxtomail.web.FaxToMailActionSupport; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; import com.opensymphony.xwork2.Preparable; -import org.apache.commons.collections4.ComparatorUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - /** * @author kmorin <kmorin@codelutin.com> * @since x.x @@ -66,35 +49,41 @@ private static final Log log = LogFactory.getLog(ConfigurationAction.class); - protected CompanyService companyService; + protected ConfigurationService configurationService; + protected ReferentielService referentielService; + protected MailFolderService mailFolderService; - protected UserService userService; + protected Configuration configuration; - protected List<Company> companies; + protected List<EtatAttente> etatAttentes; - protected Company company; - protected List<MailFolder> mailFolders; - protected Map<String, String> mailFoldersFlat; + //protected UserService userService; - protected List<MailFilterUIBean> mailFilters; + //protected List<MailFolder> mailFolders; - protected List<FaxToMailUser> allUsers; + //protected Map<String, String> mailFoldersFlat; - protected List<FaxToMailUserGroup> allUserGroups; + //protected List<MailFilterUIBean> mailFilters; - protected String activeTab; + //protected List<FaxToMailUser> allUsers; + //protected List<FaxToMailUserGroup> allUserGroups; + + //protected String activeTab; + @Override public void prepare() throws Exception { - companies = companyService.getAllCompanies(); + configuration = configurationService.getConfiguration(); } @Override public String input() throws Exception { + etatAttentes = referentielService.getAllEtatAttente(); + mailFolders = mailFolderService.getRootMailFolders(); return INPUT; } @@ -102,69 +91,77 @@ public String execute() throws Exception { String result = super.execute(); - if (!ERROR.equals(result)) { - if (company != null) { - log.debug(company.getMailFilter()); - Map<MailFilter, String> folderIdByFilter = new HashMap<>(); - if (mailFilters != null) { - for (MailFilterUIBean filter : mailFilters) { - String folderId = filter.getMailFolderId(); - folderIdByFilter.put(filter, folderId); - } - } - companyService.saveCompany(company, mailFolders, folderIdByFilter); + /*Map<MailFilter, String> folderIdByFilter = new HashMap<>(); + if (mailFilters != null) { + for (MailFilterUIBean filter : mailFilters) { + String folderId = filter.getMailFolderId(); + folderIdByFilter.put(filter, folderId); } - result = INPUT; } + configurationService.saveCompany(company, mailFolders, folderIdByFilter);*/ + + configurationService.saveConfiguration(configuration); + return result; } - public void setCompanyService(CompanyService companyService) { - this.companyService = companyService; + public void setConfigurationService(ConfigurationService configurationService) { + this.configurationService = configurationService; } + public void setReferentielService(ReferentielService referentielService) { + this.referentielService = referentielService; + } + public void setMailFolderService(MailFolderService mailFolderService) { this.mailFolderService = mailFolderService; } - public void setUserService(UserService userService) { - this.userService = userService; + public Configuration getConfiguration() { + return configuration; } - public void setCompanyId(String companyId) { - if (StringUtils.isNotEmpty(companyId)) { - this.company = companyService.getCompany(companyId); - } + public List<EtatAttente> getEtatAttentes() { + return etatAttentes; } - public String getCompanyId() { - if (company == null) { - return null; - } - return company.getTopiaId(); + public void setEtatAttentes(List<EtatAttente> etatAttentes) { + this.etatAttentes = etatAttentes; } - public void setCompany(Company company) { - this.company = company; + public Map<Action, String> getEtatAttenteActions() { + return getEnumAsMap(Action.values()); } + + public Map<Field, String> getEtatAttenteFields() { + return getEnumAsMap(Field.values()); + } - public Company getCompany() { - return company; + public List<MailFolder> getMailFolders() { + return mailFolders; } - public List<Company> getCompanies() { - return companies; + public void setMailFolders(List<MailFolder> mailFolders) { + this.mailFolders = mailFolders; } - public String getActiveTab() { + /*public void setMailFolderService(MailFolderService mailFolderService) { + this.mailFolderService = mailFolderService; + } + + public void setUserService(UserService userService) { + this.userService = userService; + }*/ + + /*public String getActiveTab() { return activeTab; } public void setActiveTab(String activeTab) { this.activeTab = activeTab; - } + }*/ - public Map<String, String> getEmailFields() { + /*public Map<String, String> getEmailFields() { Map<String, String> result = new HashMap<>(); result.put(Email.PROPERTY_SENDER, "Adresse email"); result.put(Email.PROPERTY_RECEPTION_DATE, "Date de réception"); @@ -295,5 +292,5 @@ public void setMailFolderId(String mailFolderId) { this.mailFolderId = mailFolderId; } - } + }*/ } Modified: trunk/faxtomail-ui-web/src/main/resources/i18n/faxtomail-ui-web_fr_FR.properties =================================================================== --- trunk/faxtomail-ui-web/src/main/resources/i18n/faxtomail-ui-web_fr_FR.properties 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/resources/i18n/faxtomail-ui-web_fr_FR.properties 2014-05-21 16:53:25 UTC (rev 84) @@ -1 +1,25 @@ +com.franciaflex.faxtomail.persistence.entities.Action.ARCHIVE=Archiver +com.franciaflex.faxtomail.persistence.entities.Action.GROUP=Grouper +com.franciaflex.faxtomail.persistence.entities.Action.PRINT=Imprimer +com.franciaflex.faxtomail.persistence.entities.Action.REPLY=Repondre +com.franciaflex.faxtomail.persistence.entities.Action.SAVE=Sauver +com.franciaflex.faxtomail.persistence.entities.Action.TRANSMIT=Transfer +com.franciaflex.faxtomail.persistence.entities.Field.ARCHIVE_DATE=Date d'archive +com.franciaflex.faxtomail.persistence.entities.Field.CLIENT=Client +com.franciaflex.faxtomail.persistence.entities.Field.COMMENT=Commentaire +com.franciaflex.faxtomail.persistence.entities.Field.COMPANY_REFERENCE=Référence +com.franciaflex.faxtomail.persistence.entities.Field.DEMANDE_STATUS=Statut de demande +com.franciaflex.faxtomail.persistence.entities.Field.DEMAND_TYPE=Type de demande +com.franciaflex.faxtomail.persistence.entities.Field.EDI_CODE_NUMBER=Code EDI +com.franciaflex.faxtomail.persistence.entities.Field.ETAT_ATTENTE=État d'attente +com.franciaflex.faxtomail.persistence.entities.Field.FAX=Fax +com.franciaflex.faxtomail.persistence.entities.Field.OBJECT=Objet +com.franciaflex.faxtomail.persistence.entities.Field.ORIGINAL_EMAIL=Email original +com.franciaflex.faxtomail.persistence.entities.Field.PRIORITY=Priorité +com.franciaflex.faxtomail.persistence.entities.Field.PROJECT_REFERENCE=Réference projet +com.franciaflex.faxtomail.persistence.entities.Field.RANGE_ROW=Gamme +com.franciaflex.faxtomail.persistence.entities.Field.RECEPTION_DATE=Date de réception +com.franciaflex.faxtomail.persistence.entities.Field.RECIPIENT=Destinataire +com.franciaflex.faxtomail.persistence.entities.Field.SENDER=Expéditeur +com.franciaflex.faxtomail.persistence.entities.Field.TAKEN_BY=Pris par faxtomail.email.projectReference.default= Modified: trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration.jsp =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration.jsp 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration.jsp 2014-05-21 16:53:25 UTC (rev 84) @@ -29,339 +29,312 @@ <head> <title>Configuration</title> <link rel="stylesheet" type="text/css" href="<s:url value='/webjars/select2/3.4.8/select2.css' />" /> - <link rel="stylesheet" type="text/css" href="<s:url value='/webjars/jstree/3.0.0/themes/default/style.min.css' />" /> + <link rel="stylesheet" type="text/css" href="<s:url value='/nuiton-js-angular-ui-tree/angular-ui-tree.css' />" /> <link rel="stylesheet" type="text/css" href="<s:url value='/css/configuration.css' />" /> <script type="text/javascript" src="<s:url value='/webjars/select2/3.4.8/select2.min.js' />"></script> <script type="text/javascript" src="<s:url value='/webjars/select2/3.4.8/select2_locale_fr.js' />"></script> - <script type="text/javascript" src="<s:url value='/webjars/jstree/3.0.0/jstree.min.js' />"></script> + <script type="text/javascript" src="<s:url value='/webjars/angularjs/1.2.16/angular.min.js' />"></script> + <script type="text/javascript" src="<s:url value='/nuiton-js-angular-ui-tree/angular-ui-tree.js' />"></script> + <script type="text/javascript" src="<s:url value='/js/faxtomail.js' />"></script> + <script type="text/javascript" src="<s:url value='/js/configuration.js' />"></script> - <script> - var emailFields = {}; - <s:iterator value="emailFields"> - emailFields["<s:property value='key'/>"] = "<s:property value='value' escapeHtml='false'/>"; - </s:iterator> - - var folderData = JSON.parse('<s:property value="foldersTreeAsJson" escapeHtml="false"/>'); + <script type="text/javascript"> + angular.module('ConfigurationModule', ['FaxToMail', 'ui.tree']) + .value('ConfigurationData', { + 'etatAttentes' : <s:property value="toJson(etatAttentes)" escapeHtml="false"/>, + 'etatAttenteActions': <s:property value="toJson(etatAttenteActions)" escapeHtml="false"/>, + 'etatAttenteFields': <s:property value="toJson(etatAttenteFields)" escapeHtml="false"/>, + 'mailFolders': <s:property value="toJson(mailFolders)" escapeHtml="false"/> + }); </script> - - <script type="text/javascript" src="<s:url value='/js/configuration.js' />"></script> </head> - <body> - <!-- navbar --> - <div class="navbar navbar-inverse navbar-fixed-top"> - <div class="navbar-inner"> + <body> + <div ng-app="ConfigurationModule"> + <!-- navbar --> + <header class="navbar navbar-inverse navbar-static-top bs-docs-nav" id="top" role="banner"> <div class="container"> - <s:a cssClass="brand">FaxToMail</s:a> + <div class="navbar-header"> + <a href="<s:url value='/' />" class="navbar-brand">FaxToMail</a> + </div> + </div> - </div> - </div> - - <div id="main-container" class="container"> - - <h1 class="margin-bottom25">Configuration</h1> - - <s:form action='configuration!input' method="get" theme="simple"> - - <div class="input-append"> - - <s:select name="companyId" - label="Société" - emptyOption="true" - list="companies" - listKey="topiaId" - listValue="name" - value="company.topiaId" - cssClass="input-xxlarge"/> - - <button class="btn" type="submit">OK</button> - - </div> - - </s:form> - - <s:if test="company"> - - <s:form id="main_form"> - + </header> + + <div id="main-container" class="container"> + + <h1 class="page-header">Configuration</h1> + + <s:form id="main_form" ng-controller="ConfigurationController"> + <s:hidden name="companyId"/> <s:hidden name="activeTab"/> - + <ul id="tabs" class="nav nav-tabs"> - <li><a href="#tabs-general" data-toggle="tab">Général</a></li> - <li><a href="#tabs-table" data-toggle="tab">Champs du tableau</a></li> + <li class="active"><a href="#tabs-general" data-toggle="tab">Général</a></li> + <li><a href="#tabs-wait" data-toggle="tab">États d'attente</a></li> <li><a href="#tabs-tree" data-toggle="tab">Arborescence</a></li> <li><a href="#tabs-filters" data-toggle="tab">Filtres de mail</a></li> - <li><a href="#tabs-rights" data-toggle="tab">Droits</a></li> - <li><a href="#tabs-email-accounts" data-toggle="tab">Comptes mails</a></li> + <!-- <li><a href="#tabs-rights" data-toggle="tab">Droits</a></li> + <li><a href="#tabs-email-accounts" data-toggle="tab">Comptes mails</a></li> --> </ul> - - <div class="tab-content"> - - <div id="tabs-general" class="tab-pane"> + + <div class="tab-content active" ng-controller="ConfigurationMiscController"> + + <div id="tabs-general" class="tab-pane active"> <!-- Général --> - - <s:checkbox name="company.configuration.sendAknowledgement" + + <s:checkbox name="configuration.sendAknowledgement" label="Envoyer directement l'accusé de réception si demandé par l'expéditeur"/> - - <s:checkbox name="company.configuration.rejectUnknownSender" + + <s:checkbox name="configuration.rejectUnknownSender" label="Refuser les mails dont l'email est inconnu de la base client" cssClass="margin-bottom25"/> - - <s:textfield name="company.configuration.ediFolder" + + <s:textfield name="configuration.ediFolder" label="Dossier de dépôt du fichier pour l'EDI" cssClass="span12"/> - + + <s:textfield name="configuration.convertToPdfCommand" + label="Ligne de commande de conversion de fichier X en pdf" + cssClass="span12"/> + + <s:textfield name="configuration.openAttachmentCommand" + label="Ligne de commande d'ouverture de fichier non TXT, TIFF, JPEG, PDF" + cssClass="span12"/> + <!-- Il faut pouvoir configurer le dossier par défaut de déplacement en fonction des champs saisis sur la fiche (configuration sur statut, type de fiche, ...). Ce dossier n'est qu'une proposition que l'utilisateur peut modifier)--> - + </div> - - <div id="tabs-table" class="tab-pane"> - <!-- Champs du tableau --> - - <div class="control-group "> - <label class="control-label" for="tableColumns">Champs à afficher dans le tableau (l'ordre peut être changé en faisant un glisser/déposer sur les champs)</label> - - <div class="controls"> - - <s:hidden name="company.configuration.tableColumns" - id="tableColumns" cssClass="full-width margin-bottom25"/> - - </div> - - <div> - <table id='table-snapshot' class="table table-bordered"> - <caption>Aperçu</caption> - <thead><tr></tr></thead> + + <div id="tabs-wait" class="tab-pane" ng-controller="ConfigurationWaitController"> + + <div class="row"> + <div class="col-md-4"> + <table class="table table-hover"> + <thead> + <tr> + <th>État d'attente</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="etatAttente in etatAttentes" + ng-class="{'info' : etatAttente == selectedEtatAttente}" + ng-click="editEtatAttente(etatAttente)"> + <td>{{etatAttente.label}}</td> + </tr> + </tbody> </table> </div> + <div class="col-md-7" ng-if="selectedEtatAttente"> + Champs obligatoires pour l'état d'attente <strong>{{selectedEtatAttente.label}}</strong>: + <label class="checkbox" ng-repeat="(etatAttenteField,label) in etatAttenteFields"> + <input type="checkbox" ng-checked="selectedEtatAttente.fields.indexOf(etatAttenteField) != -1" + ng-click="changeEtatAttenteField(etatAttenteAction)"> {{label}} + </label> + Actions autorisées pour l'état d'attente <strong>{{selectedEtatAttente.label}}</strong>: + <label class="checkbox" ng-repeat="(etatAttenteAction,label) in etatAttenteActions"> + <input type="checkbox" ng-checked="selectedEtatAttente.actions.indexOf(etatAttenteAction) != -1" + ng-click="changeEtatAttenteAction(etatAttenteAction)"> {{label}} + </label> + </div> + <div class="col-md-7" ng-if="!selectedEtatAttente"> + <em>Sélectionnez un état d'attente.</em> + </div> </div> - + </div> - - <div id="tabs-tree" class="tab-pane"> - <!-- Tree Diagram --> - - <div id="treeDiagram" class="jstree margin-bottom25"> - </div> - - <button class="btn" type="button" onClick="createNewNode()"> - <i class="icon-plus"></i> Nouvelle racine - </button> - </div> - - - <div id="tabs-filters" class="tab-pane"> - <!-- Filtres de mail --> - <table id="filters" class="table table-bordered"> - <thead> - <tr> - <th>Filtre</th> - <th>Dossier</th> - </tr> - </thead> - <tbody> - <s:iterator value="company.mailFilter" status="rowStatus" var="filter"> - <tr> - <td> - <s:property value='expression'/> - <s:hidden name="mailFilters[%{#rowStatus.index}].expression" - value="%{#filter.expression}"/> - </td> - <td> - <s:property value='allFoldersFlat.get(mailFolder.topiaId)'/> - <s:hidden name="mailFilters[%{#rowStatus.index}].mailFolderId" - value="%{#filter.mailFolder.topiaId}"/> - </td> - <s:hidden name="mailFilters[%{#rowStatus.index}].topiaId" - value="%{#filter.topiaId}"/> - </tr> - </s:iterator> - </tbody> - </table> - - <fieldset class="margin-bottom25"> - <legend>Nouveau filtre</legend> - - <div id="newFilterExpression-group" class="control-group"> - <label for="newFilterExpression">Expression</label> - <div class="controls"> - <input type="text" - id="newFilterExpression" - class="input-xxlarge" - <s:if test="allFoldersFlat.isEmpty()">disabled</s:if>/> - <span id="newFilterExpression-help" class="help-inline"></span> + + <div id="tabs-tree" class="tab-pane" ng-controller="ConfigurationTreeController"> + + <div class="row"> + <div class="col-md-4"> + <script type="text/ng-template" id="nodes_renderer.html"> + <div ui-tree-handle ng-click="editMailFolder(mailFolder)" ng-class="{'bg-warning' : mailFolder == selectedMailFolder}"> + <a class="btn btn-success btn-xs" data-nodrag ng-click="toggle(this)"> + <span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed, 'glyphicon-chevron-down': !collapsed}"></span> + </a> + {{mailFolder.name}} + <a class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="remove(this)"><span class="glyphicon glyphicon-remove"></span></a> + <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="newSubItem(this)" style="margin-right: 8px;"><span class="glyphicon glyphicon-plus"></span></a> + </div> + <ol ui-tree-nodes="options" ng-model="mailFolder.children" ng-class="{hidden: collapsed}"> + <li ng-repeat="mailFolder in mailFolder.children" ui-tree-node ng-include="'nodes_renderer.html'"> + </li> + </ol> + </script> + <div ui-tree="options" data-drag-enabled="false"> + <ol ui-tree-nodes="" ng-model="mailFolders" id="tree-root"> + <li ng-repeat="mailFolder in mailFolders" ui-tree-node ng-include="'nodes_renderer.html'"></li> + </ol> </div> </div> + + <div class="col-md-8" ng-if="selectedMailFolder"> + <div class="panel-group" id="accordion"> - <div id="newFilterFolder-group" class="control-group"> - <label for="newFilterFolder">Dossier de destination</label> - <div class="controls"> - <select id="newFilterFolder" - class="input-xxlarge" - <s:if test="allFoldersFlat.isEmpty()">disabled</s:if>> - <s:iterator value="allFoldersFlat"> - <option value="<s:property value='key'/>"><s:property value='value'/></option> - </s:iterator> - </select> - <span id="newFilterFolder-help" class="help-inline"></span> + <!-- Liste des chargés de clientèle --> + <div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse1"> + Liste des chargés de clientèle {{selectedMailFolder.name}} + </a> + </h4> + </div> + <div id="collapse1" class="panel-collapse collapse"> + <div class="panel-body"> + Toto + </div> + </div> </div> - </div> - <div> - <button class="btn" type="button" onClick="createNewFilter()" <s:if test="allFoldersFlat.isEmpty()">disabled</s:if>> - <i class="icon-plus"></i> Ajouter - </button> - </div> + <!-- Liste des emails expéditeur --> + <div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse2"> + liste des emails expéditeur + </a> + </h4> + </div> + <div id="collapse2" class="panel-collapse collapse"> + <div class="panel-body"> + Toto + </div> + </div> + </div> - </fieldset> - </div> - - <div id="tabs-rights" class="tab-pane"> - <!-- Droits d'accès --> - <table id="rights" class="table table-bordered"> - <thead> - <tr> - <th>Utilisateur ou groupe</th> - <th>Dossier</th> - <th>Type</th> - </tr> - </thead> - <tbody></tbody> - </table> - - <fieldset class="margin-bottom25"> - - <legend>Nouveau droit</legend> - - <div id="newRightUser-group" class="control-group"> - <label for="newRightUser">Utilisateur ou groupe</label> - <div class="controls"> - <select id="newRightUser" - class="input-xxlarge" - <s:if test="allUsers.isEmpty() && allUserGroups.isEmpty()">disabled</s:if>> - <optgroup label="Utilisateurs"> - <s:iterator value="allUsers"> - <option value="<s:property value='topiaId'/>"><s:property value='name'/></option> - </s:iterator> - </optgroup> - <optgroup label="Groupes"> - <s:iterator value="allUserGroups"> - <option value="<s:property value='topiaId'/>"><s:property value='name'/></option> - </s:iterator> - </optgroup> - </select> - <span id="newRightUser-help" class="help-inline"></span> + <!-- Liste des emails expéditeur --> + <div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse3"> + sélection des états d'attentes possibles pour ce dossier + </a> + </h4> + </div> + <div id="collapse3" class="panel-collapse collapse"> + <div class="panel-body"> + Toto + </div> + </div> </div> - </div> + + <!-- Liste des emails expéditeur --> + <div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse4"> + groupes/personnes ayant droit d'écriture sur le dossier + </a> + </h4> + </div> + <div id="collapse4" class="panel-collapse collapse"> + <div class="panel-body"> + Toto + </div> + </div> + </div> + + <!-- Liste des emails expéditeur --> + <div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse5"> + actions possibles du menu contextuel pour ce dossier + </a> + </h4> + </div> + <div id="collapse5" class="panel-collapse collapse"> + <div class="panel-body"> + Toto + </div> + </div> + </div> - <div id="newRightFolder-group" class="control-group"> - <label for="newRightFolder">Dossier de destination</label> - <div class="controls"> - <select id="newRightFolder" - class="input-xxlarge" - <s:if test="allFoldersFlat.isEmpty()">disabled</s:if>> - <s:iterator value="allFoldersFlat"> - <option value="<s:property value='key'/>"><s:property value='value'/></option> - </s:iterator> - </select> - <span id="newRightFolder-help" class="help-inline"></span> + <!-- configuration des colonnes a afficher --> + <div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"> + <a data-toggle="collapse" data-parent="#accordion" href="#collapse6"> + configuration des colonnes a afficher + </a> + </h4> + </div> + <div id="collapse6" class="panel-collapse collapse"> + <div class="panel-body"> + Toto + </div> + </div> </div> - </div> - <div id="newRightTypes-group" class="control-group"> - <label>Types</label> - <div class="controls"> - <label class="checkbox inline"> - <input type="checkbox" id="newRightType-read" value="READ"/> lecture - </label> - <label class="checkbox inline"> - <input type="checkbox" id="newRightType-write" value="WRITE"/> écriture - </label> - <label class="checkbox inline"> - <input type="checkbox" id="newRightType-archive" value="ARCHIVE"/> archives - </label> - <span id="newRightType-help" class="help-inline"></span> - </div> </div> - - <div> - <button class="btn" type="button" onClick="createNewRight()" <s:if test="allFoldersFlat.isEmpty()">disabled</s:if>> - <i class="icon-plus"></i> Ajouter - </button> + + <div class="checkbox"> + <label for="printActionEqualTakeActionField">action imprimer est-elle équivalente à "prendre"</label> + <input type="checkbox" id="printActionEqualTakeActionField" ng-model="selectedMailFolder.printActionEqualTakeAction"> </div> - - </fieldset> - - </div> - - <div id="tabs-email-accounts" class="tab-pane"> - <!-- Comptes email --> - <table id="emailAccounts" class="table table-bordered"> - <thead> - <tr> - <th>Nom d'utilisateur</th> - <th>Serveur</th> - <th>Port</th> - </tr> - </thead> - <tbody></tbody> - </table> - - <fieldset class="margin-bottom25"> - <legend>Nouveau compte mail</legend> - - <div id="newEmailAccountUsername-group" class="control-group"> - <label for="newEmailAccountUsername">Nom d'utilisateur</label> - <div class="controls"> - <input type="text" - id="newEmailAccountUsername" - class="input-xxlarge"/> - <span id="newEmailAccountUsername-help" class="help-inline"></span> - </div> - </div> - - <div id="newEmailAccountServer-group" class="control-group"> - <label for="newEmailAccountServer">Serveur</label> - <div class="controls"> - <input type="text" - id="newEmailAccountServer" - class="input-xxlarge"/> - <span id="newEmailAccountServer-help" class="help-inline"></span> - </div> - </div> - - <div id="newEmailAccountPort-group" class="control-group"> - <label for="newEmailAccountPort">Port</label> - <div class="controls"> - <input type="number" - id="newEmailAccountPort" - class="input-xxlarge"/> - <span id="newEmailAccountPort-help" class="help-inline"></span> + + <div class="checkbox"> + <label for="openAttachmentReportNoTakenField">ouvrir une pièce jointe sans prendre, met-il la ligne en orange ou non</label> + <input type="checkbox" id="openAttachmentReportNoTakenField" ng-model="selectedMailFolder.openAttachmentReportNoTaken"> </div> - </div> - - <div> - <button class="btn" type="button" onClick="createNewEmailAccount()"> - <i class="icon-plus"></i> Ajouter - </button> - </div> - - </fieldset> - + + <div class="form-group"> + <label for="ediFolderField">dossier (FS) de dépôt des demandes EDI</label> + <input type="text" class="form-control" id="ediFolderField" ng-model="selectedMailFolder.ediFolder"> + </div> + </div> </div> - </div> - <div class="form-actions"> - <button type="submit" class="btn btn-primary">Valider</button> + <div id="tabs-filters" class="tab-pane" ng-controller="ConfigurationFilterController"> + <table class="table table-hover table-bordered"> + <thead> + <tr> + <th>Filtre</th> + <th>Dossier</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mailFilter in allMailFilters()"> + <td>{{mailFilter.expression}}</td> + <td>{{mailFilter.fmMailFolder.name}}</td> + </tr> + </tbody> + </table> + + <div role="form"> + <div class="form-group"> + <label for="filterField">Filtre</label> + <input type="text" class="form-control" id="folderField" ng-model="selectedFilter"> + </div> + <div class="form-group"> + <label for="folderField">Dossier</label> + <select class="form-control" ng-model="selectedFolder" ng-options="mailFolder.name for mailFolder in flatMailFolders()"></select> + </div> + </div> + <button type="button" class="btn btn-success" ng-disabled="!selectedFilter || !selectedFolder" ng-click="addNewFilter()"> + <i class="glyphicon glyphicon-plus"></i>Ajouter + </button> </div> - </s:form> - </s:if> + <!-- <div class="container form-actions"> + <button type="submit" class="btn btn-primary pull-right">Valider</button> + </div> --> + + <nav class="navbar navbar-default navbar-fixed-bottom"> + <div class="container"> + <button type="submit" class="btn btn-primary navbar-btn pull-right">Valider</button> + </div> + </nav> + </div> + </s:form> </div> + </div> </body> </html> Modified: trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css 2014-05-21 16:53:25 UTC (rev 84) @@ -21,14 +21,7 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -#main-container { - padding-top: 60px; -} -.margin-bottom25 { - margin-bottom: 25px; -} - .full-width { width: 100%; } @@ -37,12 +30,26 @@ padding-bottom: 70px; } -.form-actions { - position: fixed; - bottom: 0; - width: 900px; +.page-header { + margin-bottom: 25px; } -#treeDiagram { - background: #f0f0f0; +.angular-ui-tree-handle { + background: #f8faff; + border: 1px solid #dae2ea; + color: #7c9eb2; + padding: 10px 10px; + cursor:default; +} +.angular-ui-tree-handle.bg-warning { + background: #fcf8e3; +} + +.angular-ui-tree-handle:hover { + color: #438eb9; + background: #f4f6f7; + border-color: #dce2e8; +} +.angular-ui-tree-handle.bg-warning:hover { + background: #fcf8e3; } \ No newline at end of file Modified: trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js 2014-05-21 16:53:25 UTC (rev 84) @@ -1,261 +1,143 @@ -/* - * #%L - * FaxToMail :: Web - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2014 Franciaflex, Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ + /** - * adds a new folder in the tree + * Global configuration controller. */ -var createNewNode = function() { - $('.jstree').jstree(true).create_node('#', 'Nouvelle racine'); -} +FaxToMailModule.controller('ConfigurationController', ['$scope', '$http', 'ConfigurationData', + function($scope, $http, ConfigurationData) { + //mail folders + $scope.mailFolders = ConfigurationData.mailFolders; +}]); /** - * adds a new filter in the table + * Misc tab controller. */ -var createNewFilter = function() { - var filterExpression = $("#newFilterExpression").val(); - if (!filterExpression) { - $("#newFilterExpression-group").addClass("error"); - $("#newFilterExpression-group .help-inline").text("Veuillez entrer une valeur"); - return; - } - $("#newFilterExpression-group").removeClass("error"); - $("#newFilterExpression-group .help-inline").text(""); +FaxToMailModule.controller('ConfigurationMiscController', ['$scope', '$http', 'ConfigurationData', + function($scope, $http, ConfigurationData) { + +}]); - var filterFolderId = $("#newFilterFolder :selected").val(); - var filterFolder = $("#newFilterFolder :selected").text(); - if (!filterFolder) { - $("#newFilterFolder-group").addClass("error"); - $("#newFilterFolder-group .help-inline").text("Veuillez sélectionner un dossier"); - return; - } - $("#newFilterFolder-group").removeClass("error"); - $("#newFilterFolder-group .help-inline").text(""); - - var index = $("#filters tbody tr").length; - var row = "<tr>" + - "<td>" + - filterExpression + - "<input type='hidden' name='mailFilters[" + index + "].expression' value='" + filterExpression + "'/>" + - "</td>" + - "<td>" + - filterFolder + - "<input type='hidden' name='mailFilters[" + index + "].mailFolderId' value='" + filterFolderId + "'/>" + - "</td>" + - "</tr>"; - $("#filters tbody").append(row); -} - /** - * adds a new right in the table + * Etat attente tab controller. */ -var createNewRight = function() { - var rightUserId = $("#newRightUser :selected").val(); - var rightUser = $("#newRightUser :selected").text(); - if (!rightUser) { - $("#newRightUser-group").addClass("error"); - $("#newRightUser-group .help-inline").text("Veuillez sélectionner au moins un utilisateur"); - return; - } - $("#newRightUser-group").removeClass("error"); - $("#newRightUser-group .help-inline").text(""); +FaxToMailModule.controller('ConfigurationWaitController', ['$scope', '$http', 'ConfigurationData', + function($scope, $http, ConfigurationData) { + //{Array} les etats d'attentes disponibles + $scope.etatAttentes = ConfigurationData.etatAttentes; + //{Array} les actions possibles pour les etats d'attentes + $scope.etatAttenteActions = ConfigurationData.etatAttenteActions; + //{Array} les champs obligatoires possibles + $scope.etatAttenteFields = ConfigurationData.etatAttenteFields; + //{Object} etat d'attente selectionné + $scope.selectedEtatAttente; - var rightFolderId = $("#newRightFolder :selected").val(); - var rightFolder = $("#newRightFolder :selected").text(); - if (!rightFolder) { - $("#newRightFolder-group").addClass("error"); - $("#newRightFolder-group .help-inline").text("Veuillez sélectionner un dossier"); - return; - } - $("#newRightFolder-group").removeClass("error"); - $("#newRightFolder-group .help-inline").text(""); + // edition de l'etat d'attent cliqué + $scope.editEtatAttente = function(etatAttente) { + $scope.selectedEtatAttente = etatAttente; - var rightTypeIds = new Array(); - var rightTypes = new Array(); - var checkedTypes = $("#newRightTypes-group :checked"); - if (checkedTypes.length == 0) { - $("#newRightTypes-group").removeClass("error"); - $("#newRightTypes-group .help-inline").text(""); - return; - } - $("#newRightTypes-group").addClass("error"); - $("#newRightTypes-group .help-inline").text("Veuillez choisir au moins un type"); - checkedTypes.each(function() { - rightTypeIds.push($(this).val()); - rightTypes.push($(this).parent().text().trim()); - }); + // initialize le tableau d'action si vide + if (!$scope.selectedEtatAttente.actions) { + $scope.selectedEtatAttente.actions = []; + } + if (!$scope.selectedEtatAttente.fields) { + $scope.selectedEtatAttente.fields = []; + } + }; - var index = $("#rights tbody tr").length; - var row = "<tr>" + - "<td>" + - rightUser + - "<input type='hidden' name='rights[" + index + "].userId' value='" + rightUserId + "'/>" + - "</td>" + - "<td>" + - rightFolder + - "<input type='hidden' name='rights[" + index + "].mailFolderId' value='" + rightFolderId + "'/>" + - "</td>" + - "<td>" + - rightTypes.join(", ") + - "<input type='hidden' name='rights[" + index + "].types' value='" + rightTypeIds.join(",") + "'/>" + - "</td>" + - "</tr>"; - $("#rights tbody").append(row); -} + // selection/deselection d'une action + $scope.changeEtatAttenteAction = function(etatAttenteAction) { + + var index = $scope.selectedEtatAttente.actions.indexOf(etatAttenteAction); + if (index != -1) { + $scope.selectedEtatAttente.actions.splice(index, 1); + } else { + $scope.selectedEtatAttente.actions.push(etatAttenteAction); + } + }; + + // selection/deselection d'un champ + $scope.changeEtatAttenteField = function(etatAttenteField) { + + var index = $scope.selectedEtatAttente.fields.indexOf(etatAttenteField); + if (index != -1) { + $scope.selectedEtatAttente.fields.splice(index, 1); + } else { + $scope.selectedEtatAttente.fields.push(etatAttenteField); + } + }; +}]); -var createNewEmailAccount = function() { - var emailAccountUsername = $("#newEmailAccountUsername").val(); - if (!emailAccountUsername) { - $("#newEmailAccountUsername-group").addClass("error"); - $("#newEmailAccountUsername-group .help-inline").text("Veuillez entrer une valeur"); - return; - } - $("#newEmailAccountUsername-group").removeClass("error"); - $("#newEmailAccountUsername-group .help-inline").text(""); +/** + * Mail folder tab controller. + */ +FaxToMailModule.controller('ConfigurationTreeController', ['$scope', '$http', 'ConfigurationData', + function($scope, $http, ConfigurationData) { + // selected mail folder + $scope.selectedMailFolder; - var emailAccountServer = $("#newEmailAccountServer").val(); - if (!emailAccountServer) { - $("#newEmailAccountServer-group").addClass("error"); - $("#newEmailAccountServer-group .help-inline").text("Veuillez entrer une valeur"); - return; - } - $("#newEmailAccountServer-group").removeClass("error"); - $("#newEmailAccountServer-group .help-inline").text(""); + // toggle node + $scope.toggle = function(scope) { + scope.toggle(); + }; + + // edit mail folder + $scope.editMailFolder = function(mailFolder) { + $scope.selectedMailFolder = mailFolder; + }; +}]); - var emailAccountPort = $("#newEmailAccountPort").val(); - if (!emailAccountPort) { - $("#newEmailAccountPort-group").addClass("error"); - $("#newEmailAccountPort-group .help-inline").text("Veuillez entrer une valeur"); - return; - } - $("#newEmailAccountPort-group").removeClass("error"); - $("#newEmailAccountPort-group .help-inline").text(""); +/** + * Mail filter tab controller. + */ +FaxToMailModule.controller('ConfigurationFilterController', ['$scope', '$http', 'ConfigurationData', + function($scope, $http, ConfigurationData) { + //{String} input filter in add form + $scope.selectedFilter; + //{Object} selected folder in add form + $scope.selectedFolder; + + // FIXME in binding sur une methode c'est pas terrible + $scope.allMailFilters = function() { + var mailFilters = []; + angular.forEach($scope.flatMailFolders(), function(mailFolder) { + if (mailFolder.filters) { + mailFilters = mailFilters.concat(mailFolder.filters); + angular.forEach($scope.mailFilters, function(mailFilter) { + + // ca c'est pas propre, on modifie l'object original pour affichage + mailFilter.fmMailFolder = mailFolder; - var index = $("#emailAccounts tbody tr").length; - var row = "<tr>" + - "<td>" + - emailAccountUsername + - "<input type='hidden' name='emailAccounts[" + index + "].username' value='" + emailAccountUsername + "'/>" + - "</td>" + - "<td>" + - emailAccountServer + - "<input type='hidden' name='emailAccounts[" + index + "].server' value='" + emailAccountServer + "'/>" + - "</td>" + - "<td>" + - emailAccountPort + - "<input type='hidden' name='emailAccounts[" + index + "].port' value='" + emailAccountPort + "'/>" + - "</td>" + - "</tr>"; - $("#emailAccounts tbody").append(row); - console.log("debig") -} - -var formatToSendData = function(mailFolders) { - var result = []; - for (var i = 0 ; i < mailFolders.length ; i++) { - var mailFolder = mailFolders[i]; - var children = formatToSendData(mailFolder.children); - result.push({ name: mailFolder.text, children: children, topiaId: mailFolder.id }); - } - return result; -} - -var formatReceivedData = function(mailFolders) { - var result = []; - for (var i = 0 ; i < mailFolders.length ; i++) { - var mailFolder = mailFolders[i]; - var children = formatReceivedData(mailFolder.children); - result.push({ text: mailFolder.name, children: children, id: mailFolder.topiaId }); - } - return result; -} - -var updateTableSnapshot = function() { - var tableHeader = $("#table-snapshot thead tr"); - tableHeader.empty(); - var value = $("#tableColumns").val(); - if (value) { - var columns = value.split(","); - for (var i = 0 ; i < columns.length ; i++) { - tableHeader.append("<th>" + emailFields[columns[i]] + "</th>"); + mailFilters.push(mailFolder); + }); + } else { + mailFolder.filters = []; } - } -} + }); + return mailFilters; + }; -$().ready(function() { + var recursiveAddMailFolder = function(result, mailFolders) { + if (mailFolders) { + angular.forEach(mailFolders, function(mailFolder) { + result.push(mailFolder); + recursiveAddMailFolder(result, mailFolder.children); + }); + } + }; - $('a[data-toggle="tab"]').on('shown', function (e) { - var hash = e.target.hash; - $(":input[name='activeTab']").val(hash); - }); + // FIXME second binding sur une methode, pas top + $scope.flatMailFolders = function() { + var flatMailFolders = []; + recursiveAddMailFolder(flatMailFolders, $scope.mailFolders); + return flatMailFolders; + }; + + // add new filter action + $scope.addNewFilter = function() { + var filter = {expression: $scope.selectedFilter, fmMailFolder: $scope.selectedFolder}; + $scope.selectedFolder.filters.push(filter); - var hash = $(":input[name='activeTab']").val(); - if (!hash) { - hash = "#tabs-general"; - } - $('#tabs a[href="' + hash + '"]').tab('show'); - - // table columns - - var tableColumnTags = new Array(); - for (var k in emailFields) { - tableColumnTags.push({ id: k, text: emailFields[k] }) - } - $('#tableColumns').select2({tags:tableColumnTags}).on("change", function(e) { - updateTableSnapshot(); - }); - - $("#tableColumns").select2("container").find("ul.select2-choices").sortable({ - containment: 'parent', - start: function() { $("#tableColumns").select2("onSortStart"); }, - update: function() { $("#tableColumns").select2("onSortEnd"); } - }); - - updateTableSnapshot(); - - // tree diagram - folderData = formatReceivedData(folderData); - - $('#treeDiagram').jstree({ - core: { - data: folderData, - check_callback: true, - multiple: false, - themes: { - variant: "large" - } - }, - state: { key: "faxtomail-treeDiagram" }, - plugins: [ "contextmenu", "sort", "state", "unique", "dnd" ] - }); - - $("#main_form").submit(function(event) { - var mailFolders = $('#treeDiagram').jstree(true).get_json('#', {}); - var foldersAsJson = formatToSendData(mailFolders); - console.log(foldersAsJson); - - var input = $("<input>") - .attr("type", "hidden") - .attr("name", "foldersTreeAsJson").val(JSON.stringify(foldersAsJson)); - $('#main_form').append($(input)); - }); -}); \ No newline at end of file + // clear form + delete $scope.selectedFilter; + delete $scope.selectedFolder; + }; +}]); Added: trunk/faxtomail-ui-web/src/main/webapp/js/faxtomail.js =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/js/faxtomail.js (rev 0) +++ trunk/faxtomail-ui-web/src/main/webapp/js/faxtomail.js 2014-05-21 16:53:25 UTC (rev 84) @@ -0,0 +1,2 @@ + +var FaxToMailModule = angular.module('FaxToMail', []); Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2014-05-20 21:03:58 UTC (rev 83) +++ trunk/pom.xml 2014-05-21 16:53:25 UTC (rev 84) @@ -115,7 +115,7 @@ <struts2Version>2.3.16.3</struts2Version> <jqueryPluginVersion>3.7.1</jqueryPluginVersion> - <bootstrapPluginVersion>1.7.0</bootstrapPluginVersion> + <bootstrapPluginVersion>2.0.0</bootstrapPluginVersion> <shiroVersion>1.2.3</shiroVersion> <slf4jVersion>1.7.7</slf4jVersion> <mockitoVersion>1.9.5</mockitoVersion> @@ -281,7 +281,7 @@ <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> - <version>5.5.0</version> + <version>5.5.1</version> </dependency> <!-- librairie Jaxx --> @@ -548,6 +548,12 @@ <scope>runtime</scope> </dependency> + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-angular-ui-tree</artifactId> + <version>2.0.6-1-SNAPSHOT</version> + <scope>runtime</scope> + </dependency> </dependencies> </dependencyManagement>
participants (1)
-
echatellier@users.forge.codelutin.com