# HG changeset patch # User ymh # Date 1400993124 -32400 # Node ID 2f35c2ae7de87a79749b72d7da3bdcfd453847cd # Parent 7de2652f7ee8afc516694b330983cd318dcc2f14 export + import renkans diff -r 7de2652f7ee8 -r 2f35c2ae7de8 client/js/main.js --- a/client/js/main.js Sun May 18 10:31:12 2014 +0200 +++ b/client/js/main.js Sun May 25 13:45:24 2014 +0900 @@ -319,24 +319,25 @@ }; /* Utility functions */ +var getUUID4 = function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); +}; Rkns.Utils = { + getUUID4 : getUUID4, getUID : (function() { function pad(n){ return n<10 ? '0'+n : n; } - function fillrand() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); - } var _d = new Date(), ID_AUTO_INCREMENT = 0, ID_BASE = _d.getUTCFullYear() + '-' + pad(_d.getUTCMonth()+1) + '-' + pad(_d.getUTCDate()) + '-' + - fillrand(); + getUUID4(); return function(_base) { var _n = (++ID_AUTO_INCREMENT).toString(16), _uidbase = (typeof _base === "undefined" ? "" : _base + "-" ); diff -r 7de2652f7ee8 -r 2f35c2ae7de8 client/js/models.js --- a/client/js/models.js Sun May 18 10:31:12 2014 +0200 +++ b/client/js/models.js Sun May 25 13:45:24 2014 +0900 @@ -12,7 +12,12 @@ var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); return v.toString(16); }); - return obj.type + "-" + guid; + if(typeof obj !== 'undefined') { + return obj.type + "-" + guid; + } + else { + return guid; + } }; diff -r 7de2652f7ee8 -r 2f35c2ae7de8 client/js/renderer/scene.js --- a/client/js/renderer/scene.js Sun May 18 10:31:12 2014 +0200 +++ b/client/js/renderer/scene.js Sun May 25 13:45:24 2014 +0900 @@ -1186,15 +1186,26 @@ // clean ids delete projectJSON.id; + delete projectJSON._id; + delete projectJSON.space_id; + + var objId; + var idsMap = {}; + _.each(projectJSON.nodes, function(e,i,l) { + objId = e.id || e._id; delete e._id; delete e.id; + idsMap[objId] = e['@id'] = Utils.getUUID4(); }); _.each(projectJSON.edges, function(e,i,l) { delete e._id; delete e.id; + e.to = idsMap[e.to]; + e.from = idsMap[e.from]; }); _.each(projectJSON.views, function(e,i,l) { + objId = e.id || e._id; delete e._id; delete e.id; }); diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/AbstractRenkanModel.java --- a/server/src/main/java/org/iri_research/renkan/models/AbstractRenkanModel.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/AbstractRenkanModel.java Sun May 25 13:45:24 2014 +0900 @@ -10,15 +10,22 @@ import org.apache.commons.codec.binary.Hex; import org.iri_research.renkan.Constants; import org.iri_research.renkan.RenkanException; -import org.iri_research.renkan.RenkanRuntimeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonIgnore; public abstract class AbstractRenkanModel implements IRenkanModel { + @SuppressWarnings("unused") + private static Logger logger = LoggerFactory.getLogger(AbstractRenkanModel.class); + public AbstractRenkanModel(ID id, String title, String description, String uri, String color) { super(); this.id = id; + this.idSet = true; this.title = title; this.description = description; this.uri = uri; @@ -28,7 +35,9 @@ protected AbstractRenkanModel() { } - protected ID id; + protected ID id = this.getDefaultId(); + @JsonIgnore + protected boolean idSet = false; protected String title; protected String description; protected String uri; @@ -60,13 +69,16 @@ } @Override - public void setId(ID id) throws RenkanRuntimeException { - if (this.id != null) { - throw new RenkanRuntimeException( - "Current id is not null, can not change object id"); - } + public void setId(ID id) { + this.idSet = true; this.id = id; } + + @JsonIgnore + @Override + public boolean isIdSet() { + return this.idSet; + }; @Override public void setTitle(String title) { @@ -89,6 +101,7 @@ } abstract protected String getRawKeyPart(); + abstract protected ID getDefaultId(); private String getRawKey(String salt) { StringBuffer key = new StringBuffer(salt != null ? salt + "|" : ""); diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/Edge.java --- a/server/src/main/java/org/iri_research/renkan/models/Edge.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/Edge.java Sun May 25 13:45:24 2014 +0900 @@ -1,15 +1,20 @@ package org.iri_research.renkan.models; +import java.util.UUID; + import org.iri_research.renkan.Constants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; @Document(collection = "edges") +@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id") public class Edge extends AbstractRenkanModel { @DBRef @@ -44,6 +49,9 @@ public Edge(String id, String title, String description, String uri, String color, Node from, Node to, String createdBy, String projectId) { super(id, title, description, uri, color); + if(this.id == null) { + this.id = Constants.UUID_GENERATOR.generate().toString(); + } this.from = from; this.to = to; this.createdBy = createdBy; @@ -90,4 +98,9 @@ return this.createdBy; } + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } + } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/Group.java --- a/server/src/main/java/org/iri_research/renkan/models/Group.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/Group.java Sun May 25 13:45:24 2014 +0900 @@ -2,7 +2,9 @@ import java.util.Set; import java.util.TreeSet; +import java.util.UUID; +import org.iri_research.renkan.Constants; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "groups") @@ -17,6 +19,9 @@ public Group(String id, String title, String description, String uri, String color) { super(id, title, description, uri, color); + if(this.id == null) { + this.id = Constants.UUID_GENERATOR.generate().toString(); + } } public String getAvatar() { @@ -62,5 +67,10 @@ } return false; } + + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/IRenkanModel.java --- a/server/src/main/java/org/iri_research/renkan/models/IRenkanModel.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/IRenkanModel.java Sun May 25 13:45:24 2014 +0900 @@ -17,7 +17,9 @@ * @throws RenkanRuntimeException * if the current id is not null */ - public void setId(ID id) throws RenkanRuntimeException; + public void setId(ID id); + + public boolean isIdSet(); public String getTitle(); diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/Node.java --- a/server/src/main/java/org/iri_research/renkan/models/Node.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/Node.java Sun May 25 13:45:24 2014 +0900 @@ -1,14 +1,19 @@ package org.iri_research.renkan.models; +import java.util.UUID; + import org.iri_research.renkan.Constants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.geo.Point; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; @Document(collection = "nodes") +@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id") public class Node extends AbstractRenkanModel { public Node(Node node, String projectId) { @@ -79,4 +84,9 @@ return this.createdBy; } + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } + } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/Project.java --- a/server/src/main/java/org/iri_research/renkan/models/Project.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/Project.java Sun May 25 13:45:24 2014 +0900 @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import javax.crypto.spec.SecretKeySpec; @@ -80,6 +81,10 @@ public Project(String spaceId, String id, String title, String description, String uri, DateTime created, int revCounter) { super(id, title, description, uri, null); + + if(this.id == null) { + this.id = Constants.UUID_GENERATOR.generate().toString(); + } this.revCounter = revCounter; this.spaceId = spaceId; this.created = created; @@ -93,6 +98,7 @@ public Project(String spaceId, String id, String title, String description, String uri, DateTime created) { this(spaceId, id, title, description, uri, created, 1); + logger.debug("partial constructor used"); } @SuppressWarnings("unused") @@ -258,5 +264,11 @@ protected String getRawKeyPart() { return this.getId() + Long.toString(this.getCreated().getMillis()); } + + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } + } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/ProjectRevision.java --- a/server/src/main/java/org/iri_research/renkan/models/ProjectRevision.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/ProjectRevision.java Sun May 25 13:45:24 2014 +0900 @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.UUID; import org.bson.types.ObjectId; import org.joda.time.DateTime; @@ -47,6 +48,9 @@ public ProjectRevision(ObjectId id, String title, String description, String uri, Project project, int revision, Date created) { super(id, title, description, uri, null); + if(this.id == null) { + this.id = new ObjectId(); + } this.project = project; this.revision = revision; if (created == null) { @@ -79,5 +83,11 @@ protected String getRawKeyPart() { return Long.toString(this.getCreated().getMillis()); } + + @Override + protected ObjectId getDefaultId() { + return new ObjectId(); + } + } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/RosterUser.java --- a/server/src/main/java/org/iri_research/renkan/models/RosterUser.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/RosterUser.java Sun May 25 13:45:24 2014 +0900 @@ -1,5 +1,9 @@ package org.iri_research.renkan.models; +import java.util.UUID; + +import org.iri_research.renkan.Constants; + import com.fasterxml.jackson.annotation.JsonProperty; public class RosterUser extends AbstractRenkanModel { @@ -12,6 +16,9 @@ String color, String project_id, Long site_id, String client_id) { super(id, title, description, uri, color); + if(this.id == null) { + this.id = Constants.UUID_GENERATOR.generate().toString(); + } this.projectId = project_id; this.siteId = site_id; this.clientId = client_id; @@ -52,5 +59,10 @@ protected String getRawKeyPart() { return this.id; } + + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/Space.java --- a/server/src/main/java/org/iri_research/renkan/models/Space.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/Space.java Sun May 25 13:45:24 2014 +0900 @@ -1,5 +1,8 @@ package org.iri_research.renkan.models; +import java.util.UUID; + +import org.iri_research.renkan.Constants; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.mapping.Document; @@ -16,7 +19,9 @@ String uri, String color, String createdBy, String image, DateTime created) { super(id, title, description, uri, color); - + if(this.id == null) { + this.id = Constants.UUID_GENERATOR.generate().toString(); + } this.binConfig = binConfig; this.createdBy = createdBy; this.setImage(image); @@ -78,5 +83,11 @@ protected String getRawKeyPart() { return this.id+Long.toString(this.getCreated().getMillis()); } + + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } + } \ No newline at end of file diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/models/User.java --- a/server/src/main/java/org/iri_research/renkan/models/User.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/models/User.java Sun May 25 13:45:24 2014 +0900 @@ -6,6 +6,7 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; +import java.util.UUID; import org.iri_research.renkan.Constants; import org.joda.time.LocalDate; @@ -61,6 +62,9 @@ public User(String id, String title, String description, String uri, String color) { super(id, title, description, uri, color); + if(this.id == null) { + this.id = Constants.UUID_GENERATOR.generate().toString(); + } } @Override @@ -200,5 +204,10 @@ public boolean removeGroup(String groupId) { return (this.groups == null)?false:this.groups.remove(groupId); } + + @Override + protected String getDefaultId() { + return UUID.randomUUID().toString(); + } } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java --- a/server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java Sun May 25 13:45:24 2014 +0900 @@ -1,24 +1,55 @@ package org.iri_research.renkan.rest; +import java.io.IOException; + import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; +import org.springframework.data.mongodb.core.geo.Point; import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.joda.JodaModule; @Component @Provider public class ObjectMapperProvider implements ContextResolver { + public static class RenkanPointDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -2380557631785838410L; + + protected RenkanPointDeserializer(Class vc) { + super(vc); + } + + @Override + public Point deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + double x = node.get("x") != null? node.get("x").asDouble(): Double.NaN; + double y = node.get("y") != null? node.get("y").asDouble(): Double.NaN; + Point p = new Point(x, y); + return p; + } + } @Override public ObjectMapper getContext(Class type) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); objectMapper.registerModule(new JodaModule()); + + SimpleModule pointModule = new SimpleModule("RenkanPointModule") + .addDeserializer(Point.class, new RenkanPointDeserializer(Point.class)); + objectMapper.registerModule(pointModule); return objectMapper; } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java --- a/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java Sun May 25 13:45:24 2014 +0900 @@ -8,7 +8,9 @@ import org.iri_research.renkan.Constants; import org.iri_research.renkan.models.Project; +import org.iri_research.renkan.repositories.EdgesRepository; import org.iri_research.renkan.repositories.IRenkanRepository; +import org.iri_research.renkan.repositories.NodesRepository; import org.iri_research.renkan.repositories.ProjectsRepository; import org.joda.time.DateTime; import org.slf4j.Logger; @@ -16,6 +18,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +//TODO: Add views management +//TODO: Add user management (on POST for example) @Singleton @Path("projects") @Component @@ -26,6 +30,10 @@ @Autowired private ProjectsRepository projectsRepository; + @Autowired + private NodesRepository nodesRepository; + @Autowired + private EdgesRepository edgesRepository; @Override protected IRenkanRepository getRepository() { @@ -54,5 +62,13 @@ protected void doDeleteObject(String objectId) { this.projectsRepository.deleteRecursive(objectId); } + + @Override + protected Project saveObjectPost(Project obj) { + + this.nodesRepository.save(obj.getNodes()); + this.edgesRepository.save(obj.getEdges()); + return super.saveObjectPost(obj); + } } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java --- a/server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java Sun May 25 13:45:24 2014 +0900 @@ -95,6 +95,18 @@ + " deleted").build(); } + + protected T saveObject(T obj) { + return this.getRepository().save(obj); + } + + protected T saveObjectPost(T obj) { + return this.saveObject(obj); + } + + protected T saveObjectPut(T obj) { + return this.saveObject(obj); + } /** * test: curl -i -X PUT -H 'Content-Type: application/json' -d @@ -121,7 +133,7 @@ .build()); } - this.prepareObject(obj); + this.saveObjectPut(obj); this.getRepository().save(obj); return Response.noContent().build(); @@ -132,15 +144,15 @@ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public Response postRenkanObject(T obj) { - if (obj.getId() != null) { + if (obj.isIdSet()) { throw new WebApplicationException(Response .status(Status.BAD_REQUEST) - .entity("Id in JSON must be null").build()); + .entity("Id in JSON must not be set").build()); } obj.setId(getNewId()); this.prepareObject(obj); - obj = this.getRepository().save(obj); + obj = this.saveObjectPost(obj); return Response .created( this.uriInfo.getAbsolutePathBuilder() diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/java/org/iri_research/renkan/rest/RestApplication.java --- a/server/src/main/java/org/iri_research/renkan/rest/RestApplication.java Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/java/org/iri_research/renkan/rest/RestApplication.java Sun May 25 13:45:24 2014 +0900 @@ -5,24 +5,23 @@ import org.glassfish.jersey.server.spring.scope.RequestContextFilter; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.joda.JodaModule; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; public class RestApplication extends ResourceConfig { + + private ObjectMapperProvider objectMapperProvider = new ObjectMapperProvider(); + public RestApplication() { this.packages("org.iri_research.renkan.rest"); this.register(SpringLifecycleListener.class); this.register(RequestContextFilter.class); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, - false); - objectMapper.registerModule(new JodaModule()); - JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(objectMapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS); + ObjectMapper objectMapper = this.objectMapperProvider.getContext(ObjectMapper.class); + + JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(objectMapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS); this.register(provider); - + } } diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/webapp/WEB-INF/applicationContext.xml --- a/server/src/main/webapp/WEB-INF/applicationContext.xml Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/webapp/WEB-INF/applicationContext.xml Sun May 25 13:45:24 2014 +0900 @@ -67,6 +67,7 @@ + @@ -77,7 +78,7 @@ - + diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/webapp/WEB-INF/i18n/messages.properties --- a/server/src/main/webapp/WEB-INF/i18n/messages.properties Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/webapp/WEB-INF/i18n/messages.properties Sun May 25 13:45:24 2014 +0900 @@ -23,6 +23,8 @@ renkanIndex.project_filter = Filter title renkanIndex.space_exp = Create a space +renkanIndex.renkan_title = Title +renkanIndex.renkan_file = File renkanIndex.renkan_spaces = Renkan Spaces renkanIndex.renkan_space = Renkan Space renkanIndex.space_list = Space list @@ -35,6 +37,7 @@ renkanIndex.js.empty_name_error = Please enter a title +renkanIndex.js.empty_form_error = Please enter a title or a file renkanAdmin.renkan_admin = Renkan administration renkanAdmin.site_admin = Site administration diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/webapp/WEB-INF/i18n/messages_en.properties --- a/server/src/main/webapp/WEB-INF/i18n/messages_en.properties Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/webapp/WEB-INF/i18n/messages_en.properties Sun May 25 13:45:24 2014 +0900 @@ -22,6 +22,8 @@ renkanIndex.project_filter = Filter title renkanIndex.space_exp = Create a space +renkanIndex.renkan_title = Title +renkanIndex.renkan_file = File renkanIndex.renkan_spaces = Renkan Spaces renkanIndex.renkan_space = Renkan Space renkanIndex.space_list = Space list @@ -34,6 +36,7 @@ renkanIndex.js.empty_name_error = Please enter a title +renkanIndex.js.empty_form_error = Please enter a title or a file renkanAdmin.renkan_admin = Renkan administration renkanAdmin.site_admin = Site administration diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/webapp/WEB-INF/i18n/messages_fr.properties --- a/server/src/main/webapp/WEB-INF/i18n/messages_fr.properties Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/webapp/WEB-INF/i18n/messages_fr.properties Sun May 25 13:45:24 2014 +0900 @@ -23,6 +23,8 @@ renkanIndex.project_filter = Filtre titre renkanIndex.space_exp = Créer un espace +renkanIndex.renkan_title = Titre +renkanIndex.renkan_file = Fichier renkanIndex.renkan_spaces = Espaces Renkan renkanIndex.renkan_space = Espace Renkan renkanIndex.space_list = Liste des espaces @@ -34,6 +36,7 @@ renkanIndex.space_proj_count = Nb. proj. renkanIndex.js.empty_name_error = Veuillez entrer un titre +renkanIndex.js.empty_form_error = Veuillez entrer un titre ou un fichier renkanAdmin.renkan_admin = Administration Renkan diff -r 7de2652f7ee8 -r 2f35c2ae7de8 server/src/main/webapp/WEB-INF/templates/projectIndex.html --- a/server/src/main/webapp/WEB-INF/templates/projectIndex.html Sun May 18 10:31:12 2014 +0200 +++ b/server/src/main/webapp/WEB-INF/templates/projectIndex.html Sun May 25 13:45:24 2014 +0900 @@ -14,7 +14,7 @@ - + @@ -28,9 +28,12 @@
Create a Renkan
-
- - + +
+
+
+
+
@@ -39,11 +42,11 @@
-
+
-
- << +
+ << < ... 2 @@ -74,13 +77,13 @@ update date Edit project - Copy project - Delete project + Copy project + Delete project View project -
+