/branches/v3/impl/src/java/jomm/utils/FilesUtils.java |
---|
1,12 → 1,9 |
package jomm.utils; |
import java.io.*; |
import java.util.zip.ZipFile; |
import java.util.zip.ZipException; |
import java.security.MessageDigest; |
import java.util.zip.ZipEntry; |
import java.util.zip.ZipOutputStream; |
import java.util.Date; |
import java.util.Enumeration; |
/** |
* @author Jorge Machado |
123,4 → 120,86 |
} |
return allEliminated; |
} |
public static byte[] createChecksum(File file) throws Exception |
{ |
InputStream fis = new FileInputStream(file); |
byte[] buffer = new byte[1024]; |
MessageDigest complete = MessageDigest.getInstance("MD5"); |
int numRead; |
do { |
numRead = fis.read(buffer); |
if (numRead > 0) { |
complete.update(buffer, 0, numRead); |
} |
} while (numRead != -1); |
fis.close(); |
return complete.digest(); |
} |
// see this How-to for a faster way to convert |
// a byte array to a HEX string |
public static String getMD5Checksum(File file) throws Exception { |
byte[] b = createChecksum(file); |
String result = ""; |
for (int i=0; i < b.length; i++) { |
result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ); |
} |
return result; |
} |
/** |
* Return true if files are the same in terms of bytes |
* @param file1 |
* @param file2 |
* @return |
*/ |
public static boolean compareTwoFiles(File file1, File file2) |
{ |
if(file1.length() != file2.length()){ |
return false; |
} |
try{ |
InputStream in1 =new BufferedInputStream(new FileInputStream(file1)); |
InputStream in2 =new BufferedInputStream(new FileInputStream(file2)); |
int value1,value2; |
do{ |
//since we're buffered read() isn't expensive |
value1 = in1.read(); |
value2 = in2.read(); |
if(value1 !=value2){ |
in1.close(); |
in2.close(); |
return false; |
} |
}while(value1 >=0); |
//since we already checked that the file sizes are equal |
//if we're here we reached the end of both files without a mismatch |
in1.close(); |
in2.close(); |
return true; |
} catch (FileNotFoundException e) { |
e.printStackTrace(); |
} catch (IOException e) { |
e.printStackTrace(); |
} |
return false; |
} |
public static void main(String[] args) throws Exception { |
System.out.println(getMD5Checksum(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"))); |
System.out.println(getMD5Checksum(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"))); |
System.out.println(getMD5Checksum(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"))); |
System.out.println(compareTwoFiles(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"), new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar-copia.bz2"))); |
System.out.println(compareTwoFiles(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"), new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.1_macosx-x86.app.tar.bz2"))); |
} |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/services/sigesimports/oracle/OracleConnectionTest.java |
---|
1,5 → 1,6 |
package pt.estgp.estgweb.services.sigesimports.oracle; |
import junit.framework.TestCase; |
import oracle.jdbc.pool.OracleDataSource; |
import java.sql.Connection; |
10,7 → 11,7 |
/** |
* Created by jorgemachado on 07/01/16. |
*/ |
public class OracleConnectionTest |
public class OracleConnectionTest extends TestCase |
{ |
public static void main(String[] args) throws SQLException |
{ |
/branches/v3/impl/src/java/pt/estgp/estgweb/services/data/RepositoryService.java |
---|
48,6 → 48,9 |
repositoryFile.setOwner(user); |
DaoFactory.getRepositoryFileDaoImpl().save(repositoryFile); |
//todo getMD5Checksum() |
// System.out.println(getMD5Checksum(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"))); |
//System.out.println(compareTwoFiles(new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar.bz2"), new File("/Volumes/Home/jorgemachado/Documents/FileZilla_3.24.0_macosx-x86.app.tar-copia.bz2"))); |
RepositoryFileVersionImpl repositoryFileVersion = createVersion(repositoryFile); |
repositoryFileVersion.setName(name); |
repositoryFileVersion.setSize(size); |
126,10 → 129,7 |
* @return a view with an inputStream for document |
*/ |
public IRepositoryFile load(String identifier) |
{ |
return load(identifier,null); |
} |
public IRepositoryFile load(String identifier, UserSession userSession) |
{ |
DefaultRepositoryFile iRepositoryFile = new DefaultRepositoryFile(); |
/branches/v3/impl/src/java/pt/estgp/estgweb/services/data/repositorydocuments/RepositoryDocumentService.java |
---|
1,19 → 1,130 |
package pt.estgp.estgweb.services.data.repositorydocuments; |
import com.owlike.genson.TransformationException; |
import org.json.JSONArray; |
import org.json.JSONException; |
import org.json.JSONObject; |
import pt.estgp.estgweb.Globals; |
import pt.estgp.estgweb.domain.*; |
import pt.estgp.estgweb.domain.dao.DaoFactory; |
import pt.estgp.estgweb.filters.chains.ResourceAccessControlEnum; |
import pt.estgp.estgweb.filters.exceptions.AccessDeniedException; |
import pt.estgp.estgweb.services.data.RepositoryService; |
import pt.estgp.estgweb.web.controllers.utils.FileUploaded; |
import pt.estgp.estgweb.web.controllers.utils.FilesUploadResult; |
import pt.utl.ist.berserk.logic.serviceManager.IService; |
import java.io.FileInputStream; |
import java.io.IOException; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Set; |
/** |
* Created by jorgemachado on 23/02/17. |
*/ |
public class RepositoryDocumentService implements IService { |
public class RepositoryDocumentService implements IService |
{ |
public RepositoryDocumentImpl saveRepositoryDocument(String docJson, UserSession userSession) throws IOException, TransformationException { |
public static final String REPOSITORY_DOCS_ROLE = "repositoryDocs"; |
/** |
* Public service |
* Uses Roles to filter collections |
* @param collectionId |
* @param userSession |
* @return |
* @throws IOException |
* @throws TransformationException |
* @throws JSONException |
* @throws AccessDeniedException |
*/ |
public JSONArray openRepositoryCollection(Long collectionId, UserSession userSession) throws IOException, TransformationException, JSONException, AccessDeniedException { |
boolean visible = userSession.getUser() != null && |
(userSession.getUser().hasRole(REPOSITORY_DOCS_ROLE) |
|| |
userSession.getUser().isSuperuserOrAdmin()); |
if(collectionId == null) |
{ |
//finding roots |
List<RepositoryDocumentCollectionImpl> roots = DaoFactory.getRepositoryDocumentCollectionDaoImpl().findRoots(visible); |
return RepositoryDocumentCollectionImpl.toJsonArray(roots); |
} |
else |
{ |
List<RepositoryDocumentCollectionImpl> childs = DaoFactory.getRepositoryDocumentCollectionDaoImpl().findChilds(visible,collectionId); |
return RepositoryDocumentCollectionImpl.toJsonArray(childs); |
} |
} |
public JSONArray openRepositoryCollectionDocuments(Long collectionId, UserSession userSession) throws IOException, TransformationException, JSONException, AccessDeniedException { |
boolean visible = userSession.getUser() != null && |
(userSession.getUser().hasRole(REPOSITORY_DOCS_ROLE) |
|| |
userSession.getUser().isSuperuserOrAdmin()); |
List<RepositoryDocumentImpl> docs = DaoFactory.getRepositoryDocumentDaoImpl().findDocumentsSortPublishDateDesc(visible, collectionId); |
return RepositoryDocumentImpl.toJsonArray(docs); |
} |
public JSONObject addRepositoryCollection(Long collectionParentId, UserSession userSession) throws IOException, TransformationException, JSONException, AccessDeniedException { |
RepositoryDocumentCollectionImpl collectionParent = null; |
if(collectionParentId != null) |
{ |
collectionParent = (RepositoryDocumentCollectionImpl) DaoFactory.getRepositoryDocumentCollectionDaoImpl().get(collectionParentId); |
} |
RepositoryDocumentCollectionImpl collectionChild = DomainObjectFactory.createRepositoryDocumentCollectionImpl(); |
collectionChild.setParent(collectionParent); |
if(collectionParent != null) |
collectionParent.getChilds().add(collectionChild); |
collectionChild.setVisible(true); |
DaoFactory.getRepositoryDocumentCollectionDaoImpl().save(collectionChild); |
return collectionChild.toJsonObject(); |
} |
public JSONObject changeParentRepositoryDocumentCollection(Long collectionId,Long newParentId, UserSession userSession) throws IOException, TransformationException, JSONException, AccessDeniedException { |
RepositoryDocumentCollectionImpl collectionChild = (RepositoryDocumentCollectionImpl) DaoFactory.getRepositoryDocumentCollectionDaoImpl().get(collectionId); |
RepositoryDocumentCollectionImpl collectionNewParent = newParentId == null ? null : (RepositoryDocumentCollectionImpl) DaoFactory.getRepositoryDocumentCollectionDaoImpl().get(newParentId); |
if(collectionChild.getParent() != null) |
{ |
collectionChild.getParent().getChilds().remove(collectionChild); |
} |
collectionChild.setParent(collectionNewParent); |
if(collectionNewParent != null) |
{ |
collectionNewParent.getChilds().add(collectionChild); |
} |
return collectionChild.toJsonObject(); |
} |
public JSONObject updateRepositoryCollection(String collection, UserSession userSession) throws IOException, TransformationException, JSONException, AccessDeniedException { |
RepositoryDocumentCollectionImpl collectionChild = RepositoryDocumentCollectionImpl.loadFromJson(collection); |
RepositoryDocumentCollectionImpl persistent = (RepositoryDocumentCollectionImpl) DaoFactory.getRepositoryDocumentCollectionDaoImpl().get(collectionChild.getId()); |
persistent.setName(collectionChild.getName()); |
persistent.setDescription(collectionChild.getDescription()); |
persistent.setLegacyUrl(collectionChild.getLegacyUrl()); |
persistent.setVisible(collectionChild.isVisible()); |
return persistent.toJsonObject(); |
} |
public JSONObject saveRepositoryDocument(String docJson, FilesUploadResult uploadedFiles, UserSession userSession) throws IOException, TransformationException, JSONException, AccessDeniedException { |
RepositoryDocumentImpl view = RepositoryDocumentImpl.loadFromJson(docJson); |
RepositoryDocumentImpl persistent = null; |
if(view.getId() <= 0) |
21,6 → 132,10 |
persistent = DomainObjectFactory.createRepositoryDocumentImpl(); |
DaoFactory.getRepositoryDocumentDaoImpl().save(persistent); |
} |
else |
{ |
persistent = (RepositoryDocumentImpl) DaoFactory.getRepositoryDocumentDaoImpl().get(view.getId()); |
} |
persistent.setContributorsJson(view.getContributorsJson()); |
persistent.setAuthorsJson(view.getAuthorsJson()); |
40,7 → 155,94 |
persistent.setCollection((RepositoryDocumentCollectionImpl) col); |
} |
/** |
* atualizar campos dos ficheiros já existentes |
*/ |
if(view.getRepositoryDocumentFiles() != null && view.getRepositoryDocumentFiles().size() > 0) |
{ |
for(RepositoryDocumentFileImpl ficheiroAtualizado : view.getRepositoryDocumentFiles()) |
{ |
for(RepositoryDocumentFileImpl repoFileCandidate: persistent.getRepositoryDocumentFiles() ) |
{ |
if(repoFileCandidate.getId()==ficheiroAtualizado.getId()) |
{ |
//ficheiro encontrado |
repoFileCandidate.setTitle(ficheiroAtualizado.getTitle()); |
repoFileCandidate.setDescription(ficheiroAtualizado.getDescription()); |
repoFileCandidate.setVisible(ficheiroAtualizado.isVisible()); |
repoFileCandidate.getRepositoryFileProxy().getRepositoryFile().setAccessControl(ficheiroAtualizado.getRepositoryFileProxy().getRepositoryFile().getAccessControl()); |
break; |
} |
} |
} |
} |
if(uploadedFiles != null) |
{ |
RepositoryService repositoryService = new RepositoryService(); |
for(FileUploaded uploadedF : uploadedFiles.getUploadedFiles()) |
{ |
ResourceAccessControlEnum controloAcesso = ResourceAccessControlEnum.parse(uploadedF.getAccessControl()); |
RepositoryDocumentFileImpl repoFile = null; |
String repositoryStream = uploadedF.getRepositoryStream(); |
if(repositoryStream != null) |
{ |
for(RepositoryDocumentFileImpl repoFileCandidate: persistent.getRepositoryDocumentFiles() ) |
{ |
if(repoFileCandidate.getRepositoryFileProxy().getRepositoryStream().equals(repositoryStream)) |
{ |
repoFile = repoFileCandidate; |
break; |
} |
} |
if(repoFile == null) |
throw new AccessDeniedException("Trying to access to a repoFile not Allowded"); |
repositoryService.updateRepositoryFile( |
repositoryStream, |
new FileInputStream(new java.io.File(Globals.TMP_DIR + "/" + uploadedF.getTmpName())), |
uploadedF.getContentType(), |
uploadedF.getExtension(), |
(int)uploadedF.getFileSize(), |
uploadedF.getFileName(), |
"Institutional Repository Document File", |
controloAcesso); |
} |
else |
{ |
repositoryStream = repositoryService.storeRepositoryFile( |
new FileInputStream(new java.io.File(Globals.TMP_DIR + "/" + uploadedF.getTmpName())), |
uploadedF.getContentType(), |
uploadedF.getExtension(), |
(int)uploadedF.getFileSize(), |
uploadedF.getFileName(), |
"Institutional Repository Document File", |
controloAcesso, |
userSession.getUser()); |
Set<RepositoryDocumentFileImpl> files = persistent.getRepositoryDocumentFiles(); |
if(files == null) |
{ |
files = new HashSet<RepositoryDocumentFileImpl>(); |
persistent.setRepositoryDocumentFiles(files); |
} |
repoFile = new RepositoryDocumentFileImpl(); |
DaoFactory.getRepositoryDocumentFileDaoImpl().save(repoFile); |
files.add(repoFile); |
RepositoryFileProxy repositoryFileProxy = new RepositoryFileProxy(); |
repositoryFileProxy.setRepositoryStream(repositoryStream); |
repoFile.setRepositoryFileProxy(repositoryFileProxy); |
} |
repoFile.setVisible(uploadedF.isVisible()); |
repoFile.setTitle(uploadedF.getTitle()); |
repoFile.setDescription(uploadedF.getDescription()); |
} |
} |
System.out.println(view.toJson()); |
return persistent; |
return persistent.toJsonObject(); |
} |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/services/bpmnprocess/types/test/TestEnhancedType.java |
---|
36,7 → 36,10 |
AbstractDao.getCurrentSession().beginTransaction(); |
BpmnFlowComponentEventEndMessagesImpl eventLoaded = (BpmnFlowComponentEventEndMessagesImpl) AbstractDao.getCurrentSession().load(BpmnFlowComponentEventEndMessagesImpl.class,id); |
BpmnFlowComponentEventEndMessagesImpl eventLoaded = |
(BpmnFlowComponentEventEndMessagesImpl) |
AbstractDao.getCurrentSession(). |
load(BpmnFlowComponentEventEndMessagesImpl.class, id); |
assertTrue(eventLoaded.getTargetTypes() != null); |
assertTrue(eventLoaded.getTargetTypes().getType() != null); |
/branches/v3/impl/src/java/pt/estgp/estgweb/domain/RepositoryDocumentCollectionImpl.java |
---|
2,12 → 2,15 |
import com.owlike.genson.Genson; |
import com.owlike.genson.TransformationException; |
import org.json.JSONArray; |
import org.json.JSONException; |
import org.json.JSONObject; |
import java.io.IOException; |
import java.io.Serializable; |
import java.util.ArrayList; |
import java.util.List; |
import java.util.Set; |
/** |
* Created by jorgemachado on 23/02/17. |
19,12 → 22,17 |
} |
static Genson genson = new Genson.Builder() |
static Genson genson; |
static { |
Genson.Builder gensonBuilder = new Genson.Builder() |
.exclude(Object.class) |
.include(RepositoryDocumentCollectionImpl.class) |
.include(String.class) |
.create(); |
.exclude("parent", RepositoryDocumentCollection.class); |
genson = gensonBuilder.create(); |
} |
public String toJson() throws IOException, TransformationException |
{ |
return genson.serialize(this); |
34,7 → 42,15 |
{ |
return genson.serialize(collections); |
} |
public static JSONArray toJsonArray(Set<RepositoryDocumentCollectionImpl> collections) throws IOException, TransformationException, JSONException { |
ArrayList<RepositoryDocumentCollectionImpl> collectionsList = new ArrayList<RepositoryDocumentCollectionImpl>(collections); |
return toJsonArray(collectionsList); |
} |
public static JSONArray toJsonArray(List<RepositoryDocumentCollectionImpl> collections) throws IOException, TransformationException, JSONException { |
return new JSONArray(genson.serialize(collections)); |
} |
public static RepositoryDocumentCollectionImpl loadFromJson(String json) throws IOException, TransformationException { |
return genson.deserialize(json, RepositoryDocumentCollectionImpl.class); |
} |
42,5 → 58,13 |
public JSONObject toJsonObject() throws IOException, TransformationException, JSONException { |
return new JSONObject(toJson()); |
} |
public String getPathName() |
{ |
if(getParent()==null) |
return getName(); |
else |
return getParent().getPathName() + " - " + getName(); |
} |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/domain/dao/impl/RepositoryDocumentCollectionDaoImpl.java |
---|
New file |
0,0 → 1,53 |
package pt.estgp.estgweb.domain.dao.impl; |
import org.hibernate.criterion.Order; |
import org.hibernate.criterion.Restrictions; |
import pt.estgp.estgweb.domain.RepositoryDocumentCollection; |
import pt.estgp.estgweb.domain.RepositoryDocumentCollectionImpl; |
import java.util.List; |
import static org.hibernate.criterion.Restrictions.eq; |
/** |
* @author Jorge Machado |
* @date 28/Fev/2008 |
* @time 2:51:06 |
* @see pt.estgp.estgweb.domain.dao.impl |
*/ |
public class RepositoryDocumentCollectionDaoImpl extends RepositoryDocumentCollectionDao |
{ |
private RepositoryDocumentCollectionDaoImpl() |
{ |
} |
public static RepositoryDocumentCollectionDaoImpl getInstance() |
{ |
if (myInstance == null) |
myInstance = new RepositoryDocumentCollectionDaoImpl(); |
return (RepositoryDocumentCollectionDaoImpl) myInstance; |
} |
public List<RepositoryDocumentCollection> findRoots() |
{ |
return createCriteria().add(Restrictions.isNull("parent")).addOrder(Order.asc("name")).list(); |
} |
public List<RepositoryDocumentCollectionImpl> findRoots(boolean visible) |
{ |
return createCriteria() |
.add(Restrictions.isNull("parent")) |
.add(eq("visible",visible)) |
.addOrder(Order.asc("name")).list(); |
} |
public List<RepositoryDocumentCollectionImpl> findChilds(boolean visible,long collectionId) |
{ |
return createCriteria() |
.add(eq("parent.id",collectionId)) |
.add(eq("visible",visible)) |
.addOrder(Order.asc("name")).list(); |
} |
} |
Property changes: |
Added: svn:executable |
+ * |
/branches/v3/impl/src/java/pt/estgp/estgweb/domain/dao/impl/RepositoryDocumentDaoImpl.java |
---|
New file |
0,0 → 1,61 |
package pt.estgp.estgweb.domain.dao.impl; |
import org.hibernate.criterion.Order; |
import pt.estgp.estgweb.domain.RepositoryDocumentImpl; |
import java.util.List; |
import static org.hibernate.criterion.Restrictions.eq; |
/** |
* @author Jorge Machado |
* @date 28/Fev/2008 |
* @time 2:51:06 |
* @see pt.estgp.estgweb.domain.dao.impl |
*/ |
public class RepositoryDocumentDaoImpl extends RepositoryDocumentDao |
{ |
private RepositoryDocumentDaoImpl() |
{ |
} |
public static RepositoryDocumentDaoImpl getInstance() |
{ |
if (myInstance == null) |
myInstance = new RepositoryDocumentDaoImpl(); |
return (RepositoryDocumentDaoImpl) myInstance; |
} |
public List<RepositoryDocumentImpl> findDocumentsSortPublishDateDesc(boolean visible,long collectionId) |
{ |
return findDocuments(visible,collectionId,"publishDate","desc"); |
} |
public List<RepositoryDocumentImpl> findDocumentsSortPublishDateAsc(boolean visible,long collectionId) |
{ |
return findDocuments(visible,collectionId,"publishDate","asc"); |
} |
public List<RepositoryDocumentImpl> findDocumentsSortTitleDesc(boolean visible,long collectionId) |
{ |
return findDocuments(visible,collectionId,"title","desc"); |
} |
public List<RepositoryDocumentImpl> findDocumentsSortTitleAsc(boolean visible,long collectionId) |
{ |
return findDocuments(visible,collectionId,"title","asc"); |
} |
public List<RepositoryDocumentImpl> findDocuments(boolean visible,long collectionId,String orderField, String orderDirection) |
{ |
String orderFinalField = orderField == null ? "publishDate" : orderField; |
Order order = orderDirection.equals("asc") ? Order.asc(orderFinalField) : Order.desc(orderFinalField); |
return createCriteria() |
.add(eq("collection.id",collectionId)) |
.add(eq("visible",visible)) |
.addOrder(order) |
.addOrder(Order.desc("saveDate")) |
.list(); |
} |
} |
Property changes: |
Added: svn:executable |
+ * |
/branches/v3/impl/src/java/pt/estgp/estgweb/domain/dao/DaoFactory.java |
---|
198,9 → 198,9 |
return RepositoryFileDaoImpl.getInstance(); |
} |
public static RepositoryDocumentDao getRepositoryDocumentDaoImpl() |
public static RepositoryDocumentDaoImpl getRepositoryDocumentDaoImpl() |
{ |
return RepositoryDocumentDao.getInstance(); |
return RepositoryDocumentDaoImpl.getInstance(); |
} |
public static RepositoryDocumentFileDao getRepositoryDocumentFileDaoImpl() |
208,9 → 208,9 |
return RepositoryDocumentFileDao.getInstance(); |
} |
public static RepositoryDocumentCollectionDao getRepositoryDocumentCollectionDaoImpl() |
public static RepositoryDocumentCollectionDaoImpl getRepositoryDocumentCollectionDaoImpl() |
{ |
return RepositoryDocumentCollectionDao.getInstance(); |
return RepositoryDocumentCollectionDaoImpl.getInstance(); |
} |
public static RepositoryFileVersionDaoImpl getRepositoryFileVersionDaoImpl() |
/branches/v3/impl/src/java/pt/estgp/estgweb/domain/DomainObjectFactory.java |
---|
210,6 → 210,10 |
{ |
return new RepositoryDocumentImpl(); |
} |
public static RepositoryDocumentCollectionImpl createRepositoryDocumentCollectionImpl() |
{ |
return new RepositoryDocumentCollectionImpl(); |
} |
public static SruSourceImpl createSruSourceImpl() { |
return new SruSourceImpl(); |
/branches/v3/impl/src/java/pt/estgp/estgweb/domain/RepositoryDocumentImpl.java |
---|
3,6 → 3,7 |
import com.owlike.genson.Genson; |
import com.owlike.genson.TransformationException; |
import jomm.dao.impl.AbstractDao; |
import org.json.JSONArray; |
import org.json.JSONException; |
import org.json.JSONObject; |
import pt.estgp.estgweb.domain.dao.DaoFactory; |
14,6 → 15,7 |
import java.io.IOException; |
import java.io.Serializable; |
import java.util.HashSet; |
import java.util.List; |
/** |
* Created by jorgemachado on 30/01/17. |
111,6 → 113,10 |
return gensonSerialize.serialize(this); |
} |
public static JSONArray toJsonArray(List<RepositoryDocumentImpl> docs) throws IOException, TransformationException, JSONException { |
return new JSONArray(gensonSerialize.serialize(docs)); |
} |
public static RepositoryDocumentImpl loadFromJson(String json) throws IOException, TransformationException { |
return gensonDeserialize.deserialize(json, RepositoryDocumentImpl.class); |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/web/controllers/courseunits/CourseUnitsProgramController.java |
---|
225,7 → 225,7 |
} |
//TODO meter aqui a navega��o respectiva de adicionar teacher e ir para o programa de novo |
//TODO meter aqui a navegacao respectiva de adicionar teacher e ir para o programa de novo |
public ActionForward addTeacher(ActionMapping mapping, |
ActionForm form, |
HttpServletRequest request, |
/branches/v3/impl/src/java/pt/estgp/estgweb/web/controllers/repositorydocs/interfaces/InterfaceConfiguration.java |
---|
New file |
0,0 → 1,69 |
package pt.estgp.estgweb.web.controllers.repositorydocs.interfaces; |
import com.owlike.genson.Genson; |
import com.owlike.genson.TransformationException; |
import org.json.JSONException; |
import org.json.JSONObject; |
import java.io.IOException; |
import java.util.ArrayList; |
/** |
* Created by jorgemachado on 17/03/17. |
*/ |
public class InterfaceConfiguration implements java.io.Serializable |
{ |
String title; |
String description; |
ArrayList<InterfaceBlock> blocks = new ArrayList<InterfaceBlock>(); |
public String getTitle() { |
return title; |
} |
public void setTitle(String title) { |
this.title = title; |
} |
public String getDescription() { |
return description; |
} |
public void setDescription(String description) { |
this.description = description; |
} |
public ArrayList<InterfaceBlock> getBlocks() { |
return blocks; |
} |
public void setBlocks(ArrayList<InterfaceBlock> blocks) { |
this.blocks = blocks; |
} |
static Genson genson; |
static { |
Genson.Builder gensonBuilder = new Genson.Builder() |
.exclude(Object.class) |
.include(InterfaceConfiguration.class) |
.include(String.class) |
.include(InterfaceBlock.class) |
.include(ArrayList.class); |
genson = gensonBuilder.create(); |
} |
public String toJson() throws IOException, TransformationException |
{ |
return genson.serialize(this); |
} |
public static InterfaceConfiguration loadFromJson(String json) throws IOException, TransformationException { |
return genson.deserialize(json, InterfaceConfiguration.class); |
} |
public JSONObject toJsonObject() throws IOException, TransformationException, JSONException { |
return new JSONObject(toJson()); |
} |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/web/controllers/repositorydocs/interfaces/InterfaceBlock.java |
---|
New file |
0,0 → 1,78 |
package pt.estgp.estgweb.web.controllers.repositorydocs.interfaces; |
import java.util.ArrayList; |
import java.util.Date; |
/** |
* Created by jorgemachado on 17/03/17. |
*/ |
public class InterfaceBlock implements java.io.Serializable |
{ |
String title; |
String description; |
ArrayList<Long> collectionId = new ArrayList<Long>(); |
//or |
boolean splitSubCollections; |
boolean onlyTitleFileView; |
Date maxPublishDate; |
Date minPublishDate; |
public boolean isSplitSubCollections() |
{ |
return splitSubCollections; |
} |
public void setSplitSubCollections(boolean splitSubCollections) { |
this.splitSubCollections = splitSubCollections; |
} |
public boolean isOnlyTitleFileView() { |
return onlyTitleFileView; |
} |
public void setOnlyTitleFileView(boolean onlyTitleFileView) { |
this.onlyTitleFileView = onlyTitleFileView; |
} |
public Date getMaxPublishDate() { |
return maxPublishDate; |
} |
public void setMaxPublishDate(Date maxPublishDate) { |
this.maxPublishDate = maxPublishDate; |
} |
public Date getMinPublishDate() { |
return minPublishDate; |
} |
public void setMinPublishDate(Date minPublishDate) { |
this.minPublishDate = minPublishDate; |
} |
public String getTitle() { |
return title; |
} |
public void setTitle(String title) { |
this.title = title; |
} |
public String getDescription() { |
return description; |
} |
public void setDescription(String description) { |
this.description = description; |
} |
public ArrayList<Long> getCollectionId() { |
return collectionId; |
} |
public void setCollectionId(ArrayList<Long> collectionId) { |
this.collectionId = collectionId; |
} |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/web/controllers/repositorydocs/RepositoryDocController.java |
---|
1,8 → 1,8 |
package pt.estgp.estgweb.web.controllers.repositorydocs; |
import org.apache.struts.action.ActionForm; |
import org.json.JSONArray; |
import org.json.JSONObject; |
import pt.estgp.estgweb.domain.RepositoryDocumentImpl; |
import pt.estgp.estgweb.web.controllers.utils.AbstractWidgetAjaxController; |
import pt.estgp.estgweb.web.controllers.utils.FilesUploadResult; |
import pt.estgp.estgweb.web.utils.RequestUtils; |
21,16 → 21,90 |
public JSONObject saveRepositoryDocument(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable { |
String docJson = request.getParameter("doc"); |
FilesUploadResult uploadedProvisorios = FilesUploadResult.parse("uploadedFiles"); |
FilesUploadResult uploadedProvisorios = FilesUploadResult.parse(request.getParameter("uploadedFiles")); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{docJson}; |
RepositoryDocumentImpl persistent = (RepositoryDocumentImpl) sm.execute(RequestUtils.getRequester(request, response), "SaveRepositoryDocument", args, names); |
JSONObject tJson = persistent.toJsonObject(); |
addMessage(request,"repository.document.save.success",persistent.getTitle()); |
return tJson; |
Object[] args = new Object[]{docJson,uploadedProvisorios}; |
JSONObject persistent = (JSONObject) sm.execute(RequestUtils.getRequester(request, response), "SaveRepositoryDocument", args, names); |
addMessage(request,"repository.document.save.success", (String) persistent.get("title")); |
return persistent; |
} |
public JSONObject openRepositoryCollection(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable { |
Long collectionId = Long.parseLong(request.getParameter("id")); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{collectionId}; |
JSONArray persistent = (JSONArray) sm.execute(RequestUtils.getRequester(request, response), "OpenRepositoryCollection", args, names); |
JSONObject collections = new JSONObject(); |
collections.put("collections",persistent); |
return collections; |
} |
public JSONObject openRepositoryCollectionDocuments(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable { |
Long collectionId = Long.parseLong(request.getParameter("id")); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{collectionId}; |
JSONArray persistent = (JSONArray) sm.execute(RequestUtils.getRequester(request, response), "OpenRepositoryCollectionDocuments", args, names); |
JSONObject documents = new JSONObject(); |
documents.put("documents",persistent); |
return documents; |
} |
public JSONObject addCollection(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable { |
Long collectionId = Long.parseLong(request.getParameter("id")); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{collectionId}; |
JSONObject persistent = (JSONObject) sm.execute(RequestUtils.getRequester(request, response), "AddRepositoryCollection", args, names); |
return persistent; |
} |
public boolean changeParentCollection(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable { |
Long collectionId = Long.parseLong(request.getParameter("id")); |
Long newParentCollectionId = Long.parseLong(request.getParameter("newParentId")); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{collectionId,newParentCollectionId}; |
JSONObject persistent = (JSONObject) sm.execute(RequestUtils.getRequester(request, response), "ChangeParentRepositoryDocumentCollection", args, names); |
return true; |
} |
public boolean changeToRootCollection(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable { |
Long collectionId = Long.parseLong(request.getParameter("id")); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{collectionId,null}; |
JSONObject persistent = (JSONObject) sm.execute(RequestUtils.getRequester(request, response), "ChangeParentRepositoryDocumentCollection", args, names); |
return true; |
} |
public JSONObject newRootCollection(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable |
{ |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{null}; |
JSONObject persistent = (JSONObject) sm.execute(RequestUtils.getRequester(request, response), "AddRepositoryCollection", args, names); |
return persistent; |
} |
public boolean updateCollection(ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Throwable |
{ |
String collectionJson = request.getParameter("collection"); |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{collectionJson}; |
JSONObject persistent = (JSONObject) sm.execute(RequestUtils.getRequester(request, response), "UpdateRepositoryCollection", args, names); |
return true; |
} |
} |
/branches/v3/impl/src/java/pt/estgp/estgweb/web/controllers/utils/FileUploaded.java |
---|
11,6 → 11,7 |
*/ |
public class FileUploaded implements Serializable |
{ |
String fileName; |
long fileSize; |
String contentType; |
21,6 → 22,11 |
String repositoryStream; |
boolean visible; |
String accessControl; |
public String getRepositoryStream() { |
return repositoryStream; |
} |
78,6 → 84,22 |
this.extension = extension; |
} |
public boolean isVisible() { |
return visible; |
} |
public void setVisible(boolean visible) { |
this.visible = visible; |
} |
public String getAccessControl() { |
return accessControl; |
} |
public void setAccessControl(String accessControl) { |
this.accessControl = accessControl; |
} |
public String getTmpName() { |
return tmpName; |
} |
/branches/v3/impl/src/doc/estgweb.eap |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/branches/v3/impl/src/hbm/pt/estgp/estgweb/domain/RepositoryFile.hbm.xml |
---|
37,6 → 37,9 |
<property name="extension" type="string"/> |
<property name="size" type="int"/> |
<property name="description" type="text"/> |
<property name="md5checksum" type="string" index="md5checksumIndex"/> |
<!--When version already exist we refer here for it in order to avoid duplicate in FileSystem--> |
<property name="mirrorFileVersionId" type="string"/> |
<many-to-one name="repositoryFile" class="pt.estgp.estgweb.domain.RepositoryFileImpl" outer-join="true" lazy="false"/> |
<subclass name="pt.estgp.estgweb.domain.RepositoryFileVersionImpl" discriminator-value="RepositoryFileVersionImpl"/> |
</class> |
91,6 → 94,12 |
<property name="description" type="string"> |
<column name="description" sql-type="TEXT"/> |
</property> |
<property name="legacyUrl" type="string"/> |
<many-to-one name="parent" class="pt.estgp.estgweb.domain.RepositoryDocumentCollectionImpl" outer-join="true" lazy="false"/> |
<set name="childs" lazy="true" order-by="name desc"> |
<key column="parent"/> |
<one-to-many class="pt.estgp.estgweb.domain.RepositoryDocumentCollectionImpl"/> |
</set> |
<subclass name="pt.estgp.estgweb.domain.RepositoryDocumentCollectionImpl" discriminator-value="RepositoryDocumentCollectionImpl"/> |
</class> |
/branches/v3/impl/src/web/css/style.css |
---|
17,6 → 17,17 |
margin-bottom: 2px !important; |
margin-left: 20px; |
} |
.btn-huge{ |
padding-top:20px; |
padding-bottom:20px; |
} |
.bacoInvisible,.bacoInvisible * |
{ |
background-color: lightgray !important; |
color:dimgray !important; |
} |
/***** NOVOS ***/ |
/branches/v3/impl/src/web/js/baco-widgets.js |
---|
27,6 → 27,7 |
{ |
widgetCallWithActionParameters(form.action,serviceName,parameters,form,handlerOk,handlerFail); |
} |
/** |
* Created by jorgemachado on 28/12/16. |
*/ |
/branches/v3/impl/src/web/js/angularjs/angular-ui-tree/angular-ui-tree.css |
---|
New file |
0,0 → 1,61 |
.angular-ui-tree { |
} |
.angular-ui-tree-empty { |
border: 1px dashed #bbb; |
min-height: 100px; |
background-color: #e5e5e5; |
background-image: -webkit-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff), -webkit-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff); |
background-image: -moz-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff), -moz-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff); |
background-image: linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff), linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff); |
background-size: 60px 60px; |
background-position: 0 0, 30px 30px; |
pointer-events: none; |
} |
.angular-ui-tree-nodes { |
position: relative; |
margin: 0; |
padding: 0; |
list-style: none; |
} |
.angular-ui-tree-nodes .angular-ui-tree-nodes { |
padding-left: 20px; |
} |
.angular-ui-tree-node, .angular-ui-tree-placeholder { |
position: relative; |
margin: 0; |
padding: 0; |
min-height: 20px; |
line-height: 20px; |
} |
.angular-ui-tree-hidden { |
display: none; |
} |
.angular-ui-tree-placeholder { |
margin: 5px 0; |
padding: 0; |
min-height: 30px; |
} |
.angular-ui-tree-handle { |
cursor: move; |
text-decoration: none; |
font-weight: bold; |
-webkit-box-sizing: border-box; |
-moz-box-sizing: border-box; |
box-sizing: border-box; |
min-height: 20px; |
line-height: 20px; |
} |
.angular-ui-tree-drag { |
position: absolute; |
pointer-events: none; |
z-index: 999; |
opacity: .8; |
} |
/branches/v3/impl/src/web/js/angularjs/angular-ui-tree/angular-ui-tree.min.css |
---|
New file |
0,0 → 1,0 |
.angular-ui-tree-empty{border:1px dashed #bbb;min-height:100px;background-color:#e5e5e5;background-image:-webkit-linear-gradient(45deg,#fff 25%,transparent 0,transparent 75%,#fff 0,#fff),-webkit-linear-gradient(45deg,#fff 25%,transparent 0,transparent 75%,#fff 0,#fff);background-image:linear-gradient(45deg,#fff 25%,transparent 0,transparent 75%,#fff 0,#fff),linear-gradient(45deg,#fff 25%,transparent 0,transparent 75%,#fff 0,#fff);background-size:60px 60px;background-position:0 0,30px 30px;pointer-events:none}.angular-ui-tree-nodes{position:relative;margin:0;padding:0;list-style:none}.angular-ui-tree-nodes .angular-ui-tree-nodes{padding-left:20px}.angular-ui-tree-node,.angular-ui-tree-placeholder{position:relative;margin:0;padding:0;min-height:20px;line-height:20px}.angular-ui-tree-hidden{display:none}.angular-ui-tree-placeholder{margin:5px 0;padding:0;min-height:30px}.angular-ui-tree-handle{cursor:move;text-decoration:none;font-weight:700;box-sizing:border-box;min-height:20px;line-height:20px}.angular-ui-tree-drag{position:absolute;pointer-events:none;z-index:999;opacity:.8} |
/branches/v3/impl/src/web/js/angularjs/angular-ui-tree/angular-ui-tree.js |
---|
New file |
0,0 → 1,1825 |
/** |
* @license Angular UI Tree v2.22.2 |
* (c) 2010-2016. https://github.com/angular-ui-tree/angular-ui-tree |
* License: MIT |
*/ |
(function () { |
'use strict'; |
angular.module('ui.tree', []) |
.constant('treeConfig', { |
treeClass: 'angular-ui-tree', |
emptyTreeClass: 'angular-ui-tree-empty', |
hiddenClass: 'angular-ui-tree-hidden', |
nodesClass: 'angular-ui-tree-nodes', |
nodeClass: 'angular-ui-tree-node', |
handleClass: 'angular-ui-tree-handle', |
placeholderClass: 'angular-ui-tree-placeholder', |
dragClass: 'angular-ui-tree-drag', |
dragThreshold: 3, |
defaultCollapsed: false, |
appendChildOnHover: true |
}); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.controller('TreeHandleController', ['$scope', '$element', |
function ($scope, $element) { |
this.scope = $scope; |
$scope.$element = $element; |
$scope.$nodeScope = null; |
$scope.$type = 'uiTreeHandle'; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.controller('TreeNodeController', ['$scope', '$element', |
function ($scope, $element) { |
this.scope = $scope; |
$scope.$element = $element; |
$scope.$modelValue = null; // Model value for node; |
$scope.$parentNodeScope = null; // uiTreeNode Scope of parent node; |
$scope.$childNodesScope = null; // uiTreeNodes Scope of child nodes. |
$scope.$parentNodesScope = null; // uiTreeNodes Scope of parent nodes. |
$scope.$treeScope = null; // uiTree scope |
$scope.$handleScope = null; // it's handle scope |
$scope.$type = 'uiTreeNode'; |
$scope.$$allowNodeDrop = false; |
$scope.collapsed = false; |
$scope.expandOnHover = false; |
//Called by uiTreeNode Directive on load. |
$scope.init = function (controllersArr) { |
var treeNodesCtrl = controllersArr[0]; |
$scope.$treeScope = controllersArr[1] ? controllersArr[1].scope : null; |
//Find the scope of it's parent node. |
$scope.$parentNodeScope = treeNodesCtrl.scope.$nodeScope; |
//modelValue for current node. |
$scope.$modelValue = treeNodesCtrl.scope.$modelValue[$scope.$index]; |
$scope.$parentNodesScope = treeNodesCtrl.scope; |
//Init sub nodes. |
treeNodesCtrl.scope.initSubNode($scope); |
$element.on('$destroy', function () { |
//Destroy sub nodes. |
treeNodesCtrl.scope.destroySubNode($scope); |
}); |
}; |
//Return the index of child node in parent node (nodesScope). |
$scope.index = function () { |
return $scope.$parentNodesScope.$modelValue.indexOf($scope.$modelValue); |
}; |
$scope.dragEnabled = function () { |
return !($scope.$treeScope && !$scope.$treeScope.dragEnabled); |
}; |
$scope.isSibling = function (targetNode) { |
return $scope.$parentNodesScope == targetNode.$parentNodesScope; |
}; |
$scope.isChild = function (targetNode) { |
var nodes = $scope.childNodes(); |
return nodes && nodes.indexOf(targetNode) > -1; |
}; |
//TODO(jcarter): This method is on uiTreeHelper already. |
$scope.prev = function () { |
var index = $scope.index(); |
if (index > 0) { |
return $scope.siblings()[index - 1]; |
} |
return null; |
}; |
//Calls childNodes on parent. |
$scope.siblings = function () { |
return $scope.$parentNodesScope.childNodes(); |
}; |
$scope.childNodesCount = function () { |
return $scope.childNodes() ? $scope.childNodes().length : 0; |
}; |
$scope.hasChild = function () { |
return $scope.childNodesCount() > 0; |
}; |
$scope.childNodes = function () { |
return $scope.$childNodesScope && $scope.$childNodesScope.$modelValue ? |
$scope.$childNodesScope.childNodes() : |
null; |
}; |
$scope.accept = function (sourceNode, destIndex) { |
return $scope.$childNodesScope && |
$scope.$childNodesScope.$modelValue && |
$scope.$childNodesScope.accept(sourceNode, destIndex); |
}; |
$scope.remove = function () { |
return $scope.$parentNodesScope.removeNode($scope); |
}; |
$scope.toggle = function () { |
$scope.collapsed = !$scope.collapsed; |
$scope.$treeScope.$callbacks.toggle($scope.collapsed, $scope); |
}; |
$scope.collapse = function () { |
$scope.collapsed = true; |
}; |
$scope.expand = function () { |
$scope.collapsed = false; |
}; |
$scope.depth = function () { |
var parentNode = $scope.$parentNodeScope; |
if (parentNode) { |
return parentNode.depth() + 1; |
} |
return 1; |
}; |
/** |
* Returns the depth of the deepest subtree under this node |
* @param scope a TreeNodesController scope object |
* @returns Depth of all nodes *beneath* this node. If scope belongs to a leaf node, the |
* result is 0 (it has no subtree). |
*/ |
function countSubTreeDepth(scope) { |
if (!scope) { |
return 0; |
} |
var thisLevelDepth = 0, |
childNodes = scope.childNodes(), |
childNode, |
childDepth, |
i; |
if (!childNodes || childNodes.length === 0) { |
return 0; |
} |
for (i = childNodes.length - 1; i >= 0 ; i--) { |
childNode = childNodes[i], |
childDepth = 1 + countSubTreeDepth(childNode); |
thisLevelDepth = Math.max(thisLevelDepth, childDepth); |
} |
return thisLevelDepth; |
} |
$scope.maxSubDepth = function () { |
return $scope.$childNodesScope ? countSubTreeDepth($scope.$childNodesScope) : 0; |
}; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.controller('TreeNodesController', ['$scope', '$element', |
function ($scope, $element) { |
this.scope = $scope; |
$scope.$element = $element; |
$scope.$modelValue = null; |
$scope.$nodeScope = null; // the scope of node which the nodes belongs to |
$scope.$treeScope = null; |
$scope.$type = 'uiTreeNodes'; |
$scope.$nodesMap = {}; |
$scope.nodropEnabled = false; |
$scope.maxDepth = 0; |
$scope.cloneEnabled = false; |
$scope.initSubNode = function (subNode) { |
if (!subNode.$modelValue) { |
return null; |
} |
$scope.$nodesMap[subNode.$modelValue.$$hashKey] = subNode; |
}; |
$scope.destroySubNode = function (subNode) { |
if (!subNode.$modelValue) { |
return null; |
} |
$scope.$nodesMap[subNode.$modelValue.$$hashKey] = null; |
}; |
$scope.accept = function (sourceNode, destIndex) { |
return $scope.$treeScope.$callbacks.accept(sourceNode, $scope, destIndex); |
}; |
$scope.beforeDrag = function (sourceNode) { |
return $scope.$treeScope.$callbacks.beforeDrag(sourceNode); |
}; |
$scope.isParent = function (node) { |
return node.$parentNodesScope == $scope; |
}; |
$scope.hasChild = function () { |
return $scope.$modelValue.length > 0; |
}; |
$scope.safeApply = function (fn) { |
var phase = this.$root.$$phase; |
if (phase == '$apply' || phase == '$digest') { |
if (fn && (typeof (fn) === 'function')) { |
fn(); |
} |
} else { |
this.$apply(fn); |
} |
}; |
//Called in apply method of UiTreeHelper.dragInfo. |
$scope.removeNode = function (node) { |
var index = $scope.$modelValue.indexOf(node.$modelValue); |
if (index > -1) { |
$scope.safeApply(function () { |
$scope.$modelValue.splice(index, 1)[0]; |
}); |
return $scope.$treeScope.$callbacks.removed(node); |
} |
return null; |
}; |
//Called in apply method of UiTreeHelper.dragInfo. |
$scope.insertNode = function (index, nodeData) { |
$scope.safeApply(function () { |
$scope.$modelValue.splice(index, 0, nodeData); |
}); |
}; |
$scope.childNodes = function () { |
var i, nodes = []; |
if ($scope.$modelValue) { |
for (i = 0; i < $scope.$modelValue.length; i++) { |
nodes.push($scope.$nodesMap[$scope.$modelValue[i].$$hashKey]); |
} |
} |
return nodes; |
}; |
$scope.depth = function () { |
if ($scope.$nodeScope) { |
return $scope.$nodeScope.depth(); |
} |
return 0; // if it has no $nodeScope, it's root |
}; |
// check if depth limit has reached |
$scope.outOfDepth = function (sourceNode) { |
var maxDepth = $scope.maxDepth || $scope.$treeScope.maxDepth; |
if (maxDepth > 0) { |
return $scope.depth() + sourceNode.maxSubDepth() + 1 > maxDepth; |
} |
return false; |
}; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.controller('TreeController', ['$scope', '$element', |
function ($scope, $element) { |
this.scope = $scope; |
$scope.$element = $element; |
$scope.$nodesScope = null; // root nodes |
$scope.$type = 'uiTree'; |
$scope.$emptyElm = null; |
$scope.$callbacks = null; |
$scope.dragEnabled = true; |
$scope.emptyPlaceholderEnabled = true; |
$scope.maxDepth = 0; |
$scope.dragDelay = 0; |
$scope.cloneEnabled = false; |
$scope.nodropEnabled = false; |
// Check if it's a empty tree |
$scope.isEmpty = function () { |
return ($scope.$nodesScope && $scope.$nodesScope.$modelValue |
&& $scope.$nodesScope.$modelValue.length === 0); |
}; |
// add placeholder to empty tree |
$scope.place = function (placeElm) { |
$scope.$nodesScope.$element.append(placeElm); |
$scope.$emptyElm.remove(); |
}; |
this.resetEmptyElement = function () { |
if ((!$scope.$nodesScope.$modelValue || $scope.$nodesScope.$modelValue.length === 0) && |
$scope.emptyPlaceholderEnabled) { |
$element.append($scope.$emptyElm); |
} else { |
$scope.$emptyElm.remove(); |
} |
}; |
$scope.resetEmptyElement = this.resetEmptyElement; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.directive('uiTree', ['treeConfig', '$window', |
function (treeConfig, $window) { |
return { |
restrict: 'A', |
scope: true, |
controller: 'TreeController', |
link: function (scope, element, attrs, ctrl) { |
var callbacks = { |
accept: null, |
beforeDrag: null |
}, |
config = {}, |
tdElm, |
$trElm, |
emptyElmColspan; |
//Adding configured class to uiTree. |
angular.extend(config, treeConfig); |
if (config.treeClass) { |
element.addClass(config.treeClass); |
} |
//Determining if uiTree is on a table. |
if (element.prop('tagName').toLowerCase() === 'table') { |
scope.$emptyElm = angular.element($window.document.createElement('tr')); |
$trElm = element.find('tr'); |
//If we can find a tr, then we can use its td children as the empty element colspan. |
if ($trElm.length > 0) { |
emptyElmColspan = angular.element($trElm).children().length; |
} else { |
//If not, by setting a huge colspan we make sure it takes full width. |
//TODO(jcarter): Check for negative side effects. |
emptyElmColspan = 1000000; |
} |
tdElm = angular.element($window.document.createElement('td')) |
.attr('colspan', emptyElmColspan); |
scope.$emptyElm.append(tdElm); |
} else { |
scope.$emptyElm = angular.element($window.document.createElement('div')); |
} |
if (config.emptyTreeClass) { |
scope.$emptyElm.addClass(config.emptyTreeClass); |
} |
scope.$watch('$nodesScope.$modelValue.length', function (val) { |
if (!angular.isNumber(val)) { |
return; |
} |
ctrl.resetEmptyElement(); |
}, true); |
scope.$watch(attrs.dragEnabled, function (val) { |
if ((typeof val) == 'boolean') { |
scope.dragEnabled = val; |
} |
}); |
scope.$watch(attrs.emptyPlaceholderEnabled, function (val) { |
if ((typeof val) == 'boolean') { |
scope.emptyPlaceholderEnabled = val; |
ctrl.resetEmptyElement(); |
} |
}); |
scope.$watch(attrs.nodropEnabled, function (val) { |
if ((typeof val) == 'boolean') { |
scope.nodropEnabled = val; |
} |
}); |
scope.$watch(attrs.cloneEnabled, function (val) { |
if ((typeof val) == 'boolean') { |
scope.cloneEnabled = val; |
} |
}); |
scope.$watch(attrs.maxDepth, function (val) { |
if ((typeof val) == 'number') { |
scope.maxDepth = val; |
} |
}); |
scope.$watch(attrs.dragDelay, function (val) { |
if ((typeof val) == 'number') { |
scope.dragDelay = val; |
} |
}); |
/** |
* Callback checks if the destination node can accept the dragged node. |
* By default, ui-tree will check that 'data-nodrop-enabled' is not set for the |
* destination ui-tree-nodes, and that the 'max-depth' attribute will not be exceeded |
* if it is set on the ui-tree or ui-tree-nodes. |
* This callback can be overridden, but callers must manually enforce nodrop and max-depth |
* themselves if they need those to be enforced. |
* @param sourceNodeScope Scope of the ui-tree-node being dragged |
* @param destNodesScope Scope of the ui-tree-nodes where the node is hovering |
* @param destIndex Index in the destination nodes array where the source node will drop |
* @returns {boolean} True if the node is permitted to be dropped here |
*/ |
callbacks.accept = function (sourceNodeScope, destNodesScope, destIndex) { |
return !(destNodesScope.nodropEnabled || destNodesScope.$treeScope.nodropEnabled || destNodesScope.outOfDepth(sourceNodeScope)); |
}; |
callbacks.beforeDrag = function (sourceNodeScope) { |
return true; |
}; |
callbacks.expandTimeoutStart = function() |
{ |
}; |
callbacks.expandTimeoutCancel = function() |
{ |
}; |
callbacks.expandTimeoutEnd = function() |
{ |
}; |
callbacks.removed = function (node) { |
}; |
/** |
* Callback is fired when a node is successfully dropped in a new location |
* @param event |
*/ |
callbacks.dropped = function (event) { |
}; |
/** |
* Callback is fired each time the user starts dragging a node |
* @param event |
*/ |
callbacks.dragStart = function (event) { |
}; |
/** |
* Callback is fired each time a dragged node is moved with the mouse/touch. |
* @param event |
*/ |
callbacks.dragMove = function (event) { |
}; |
/** |
* Callback is fired when the tree exits drag mode. If the user dropped a node, the drop may have been |
* accepted or reverted. |
* @param event |
*/ |
callbacks.dragStop = function (event) { |
}; |
/** |
* Callback is fired when a user drops a node (but prior to processing the drop action) |
* beforeDrop can return a Promise, truthy, or falsy (returning nothing is falsy). |
* If it returns falsy, or a resolve Promise, the node move is accepted |
* If it returns truthy, or a rejected Promise, the node move is reverted |
* @param event |
* @returns {Boolean|Promise} Truthy (or rejected Promise) to cancel node move; falsy (or resolved promise) |
*/ |
callbacks.beforeDrop = function (event) { |
}; |
/** |
* Callback is fired when a user toggles node (but after processing the toggle action) |
* @param sourceNodeScope |
* @param collapsed |
*/ |
callbacks.toggle = function (collapsed, sourceNodeScope) { |
}; |
scope.$watch(attrs.uiTree, function (newVal, oldVal) { |
angular.forEach(newVal, function (value, key) { |
if (callbacks[key]) { |
if (typeof value === 'function') { |
callbacks[key] = value; |
} |
} |
}); |
scope.$callbacks = callbacks; |
}, true); |
} |
}; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.directive('uiTreeHandle', ['treeConfig', |
function (treeConfig) { |
return { |
require: '^uiTreeNode', |
restrict: 'A', |
scope: true, |
controller: 'TreeHandleController', |
link: function (scope, element, attrs, treeNodeCtrl) { |
var config = {}; |
angular.extend(config, treeConfig); |
if (config.handleClass) { |
element.addClass(config.handleClass); |
} |
// connect with the tree node. |
if (scope != treeNodeCtrl.scope) { |
scope.$nodeScope = treeNodeCtrl.scope; |
treeNodeCtrl.scope.$handleScope = scope; |
} |
} |
}; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.directive('uiTreeNode', ['treeConfig', 'UiTreeHelper', '$window', '$document', '$timeout', '$q', |
function (treeConfig, UiTreeHelper, $window, $document, $timeout, $q) { |
return { |
require: ['^uiTreeNodes', '^uiTree'], |
restrict: 'A', |
controller: 'TreeNodeController', |
link: function (scope, element, attrs, controllersArr) { |
var config = {}, |
hasTouch = 'ontouchstart' in window, |
firstMoving, |
dragInfo, |
pos, |
placeElm, |
hiddenPlaceElm, |
dragElm, |
scrollContainerElm, |
unhover, |
treeScope = null, |
elements, // As a parameter for callbacks |
dragDelaying = true, |
dragStarted = false, |
dragTimer = null, |
body = document.body, |
html = document.documentElement, |
document_height, |
document_width, |
dragStart, |
tagName, |
dragMove, |
dragEnd, |
dragStartEvent, |
dragMoveEvent, |
dragEndEvent, |
dragCancelEvent, |
dragDelay, |
bindDragStartEvents, |
bindDragMoveEvents, |
unbindDragMoveEvents, |
keydownHandler, |
isHandleChild, |
el, |
isUiTreeRoot, |
treeOfOrigin; |
//Adding configured class to ui-tree-node. |
angular.extend(config, treeConfig); |
if (config.nodeClass) { |
element.addClass(config.nodeClass); |
} |
//Call init function in nodeCtrl, sets parent node and sets up sub nodes. |
scope.init(controllersArr); |
scope.collapsed = !!UiTreeHelper.getNodeAttribute(scope, 'collapsed') || treeConfig.defaultCollapsed; |
scope.expandOnHover = !!UiTreeHelper.getNodeAttribute(scope, 'expandOnHover'); |
scope.scrollContainer = UiTreeHelper.getNodeAttribute(scope, 'scrollContainer') || attrs.scrollContainer || null; |
scope.sourceOnly = scope.nodropEnabled || scope.$treeScope.nodropEnabled; |
scope.$watch(attrs.collapsed, function (val) { |
if ((typeof val) == 'boolean') { |
scope.collapsed = val; |
} |
}); |
//Watches to trigger behavior based on actions and settings. |
scope.$watch('collapsed', function (val) { |
UiTreeHelper.setNodeAttribute(scope, 'collapsed', val); |
attrs.$set('collapsed', val); |
}); |
scope.$watch(attrs.expandOnHover, function(val) { |
if ((typeof val) === 'boolean' || (typeof val) === 'number') { |
scope.expandOnHover = val; |
} |
}); |
scope.$watch('expandOnHover', function (val) { |
UiTreeHelper.setNodeAttribute(scope, 'expandOnHover', val); |
attrs.$set('expandOnHover', val); |
}); |
attrs.$observe('scrollContainer', function(val) { |
if ((typeof val) === 'string') { |
scope.scrollContainer = val; |
} |
}); |
scope.$watch('scrollContainer', function(val) { |
UiTreeHelper.setNodeAttribute(scope, 'scrollContainer', val); |
attrs.$set('scrollContainer', val); |
scrollContainerElm = document.querySelector(val); |
}); |
scope.$on('angular-ui-tree:collapse-all', function () { |
scope.collapsed = true; |
}); |
scope.$on('angular-ui-tree:expand-all', function () { |
scope.collapsed = false; |
}); |
/** |
* Called when the user has grabbed a node and started dragging it. |
* |
* @param {MouseEvent} e event that is triggered by DOM. |
* @return undefined? |
*/ |
dragStart = function (e) { |
//Disable right click. |
if (!hasTouch && (e.button === 2 || e.which === 3)) { |
return; |
} |
//Event has already fired in other scope. |
if (e.uiTreeDragging || (e.originalEvent && e.originalEvent.uiTreeDragging)) { |
return; |
} |
//The node being dragged. |
var eventElm = angular.element(e.target), |
isHandleChild, |
cloneElm, |
eventElmTagName, |
tagName, |
eventObj, |
tdElm, |
hStyle, |
isTreeNode, |
isTreeNodeHandle; |
//If the target element is a child element of a ui-tree-handle, |
// use the containing handle element as target element. |
isHandleChild = UiTreeHelper.treeNodeHandlerContainerOfElement(eventElm); |
if (isHandleChild) { |
eventElm = angular.element(isHandleChild); |
} |
cloneElm = element.clone(); |
isTreeNode = UiTreeHelper.elementIsTreeNode(eventElm); |
isTreeNodeHandle = UiTreeHelper.elementIsTreeNodeHandle(eventElm); |
//If we are not triggering mousedown on our uiTree or any of it's parts, return. |
if (!isTreeNode && !isTreeNodeHandle) { |
return; |
} |
//If we are not triggering mousedown on our uiTree or any of it's parts, return. |
if (isTreeNode && UiTreeHelper.elementContainsTreeNodeHandler(eventElm)) { |
return; |
} |
//Dragging not allowed on inputs or buttons. |
eventElmTagName = eventElm.prop('tagName').toLowerCase(); |
if (eventElmTagName == 'input' || |
eventElmTagName == 'textarea' || |
eventElmTagName == 'button' || |
eventElmTagName == 'select') { |
return; |
} |
//Check if it or it's parents has a 'data-nodrag' attribute |
el = angular.element(e.target); |
while (el && el[0] && el[0] !== element && !isUiTreeRoot) { |
//Checking that I can access attributes. |
if (el[0].attributes) { |
isUiTreeRoot = el[0].attributes['ui-tree']; |
} |
//If the node mark as `nodrag`, DONOT drag it. |
if (UiTreeHelper.nodrag(el)) { |
return; |
} |
el = el.parent(); |
} |
//If users beforeDrag calback returns falsey, do not initiate. |
if (!scope.beforeDrag(scope)) { |
return; |
} |
//Set property checked at start of function to prevent running logic again. |
e.uiTreeDragging = true; |
if (e.originalEvent) { |
e.originalEvent.uiTreeDragging = true; |
} |
e.preventDefault(); |
//Get original event if TouchEvent. |
eventObj = UiTreeHelper.eventObj(e); |
//Set boolean used to specify beginning of move. |
firstMoving = true; |
//Setting drag info properties and methods in scope of node being moved. |
dragInfo = UiTreeHelper.dragInfo(scope); |
//Setting original tree to adjust horizontal behavior in drag move. |
treeOfOrigin = dragInfo.source.$treeScope.$id; |
//Determine tage name of element ui-tree-node is on. |
tagName = element.prop('tagName'); |
if (tagName.toLowerCase() === 'tr') { |
//Create a new table column as placeholder. |
placeElm = angular.element($window.document.createElement(tagName)); |
//Create a column placeholder and set colspan to whole row length. |
tdElm = angular.element($window.document.createElement('td')) |
.addClass(config.placeholderClass) |
.attr('colspan', element[0].children.length); |
placeElm.append(tdElm); |
} else { |
//If not a table just duplicate element and add placeholder class. |
placeElm = angular.element($window.document.createElement(tagName)) |
.addClass(config.placeholderClass); |
} |
//Create a hidden placeholder and add class from config. |
hiddenPlaceElm = angular.element($window.document.createElement(tagName)); |
if (config.hiddenClass) { |
hiddenPlaceElm.addClass(config.hiddenClass); |
} |
//Getting starting position of element being moved. |
pos = UiTreeHelper.positionStarted(eventObj, element); |
placeElm.css('height', UiTreeHelper.height(element) + 'px'); |
//Creating drag element to represent node. |
dragElm = angular.element($window.document.createElement(scope.$parentNodesScope.$element.prop('tagName'))) |
.addClass(scope.$parentNodesScope.$element.attr('class')).addClass(config.dragClass); |
dragElm.css('width', UiTreeHelper.width(element) + 'px'); |
dragElm.css('z-index', 9999); |
//Prevents cursor to change rapidly in Opera 12.16 and IE when dragging an element. |
hStyle = (element[0].querySelector('.angular-ui-tree-handle') || element[0]).currentStyle; |
if (hStyle) { |
document.body.setAttribute('ui-tree-cursor', $document.find('body').css('cursor') || ''); |
$document.find('body').css({'cursor': hStyle.cursor + '!important'}); |
} |
//If tree is sourceOnly (noDragDrop) don't show placeholder when moving about it. |
if (scope.sourceOnly) { |
placeElm.css('display', 'none'); |
} |
//Insert placeholder. |
element.after(placeElm); |
element.after(hiddenPlaceElm); |
if (dragInfo.isClone() && scope.sourceOnly) { |
dragElm.append(cloneElm); |
} else { |
dragElm.append(element); |
} |
//Create drag element. |
$document.find('body').append(dragElm); |
//Set drag elements position on screen. |
dragElm.css({ |
'left': eventObj.pageX - pos.offsetX + 'px', |
'top': eventObj.pageY - pos.offsetY + 'px' |
}); |
elements = { |
placeholder: placeElm, |
dragging: dragElm |
}; |
//Create all drag/move bindings. |
bindDragMoveEvents(); |
//Fire dragStart callback. |
scope.$apply(function () { |
scope.$treeScope.$callbacks.dragStart(dragInfo.eventArgs(elements, pos)); |
}); |
//Get bounds of document. |
document_height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); |
document_width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth); |
}; |
dragMove = function (e) { |
var eventObj = UiTreeHelper.eventObj(e), |
prev, |
next, |
leftElmPos, |
topElmPos, |
top_scroll, |
bottom_scroll, |
scrollContainerElmRect, |
target, |
targetX, |
targetY, |
displayElm, |
targetNode, |
targetElm, |
isEmpty, |
scrollDownBy, |
scrollUpBy, |
targetOffset, |
targetBefore, |
moveWithinTree, |
targetBeforeBuffer, |
targetHeight, |
targetChildElm, |
targetChildHeight; |
//If check ensures that drag element was created. |
if (dragElm) { |
e.preventDefault(); |
//Deselect anything (text, etc.) that was selected when move began. |
if ($window.getSelection) { |
$window.getSelection().removeAllRanges(); |
} else if ($window.document.selection) { |
$window.document.selection.empty(); |
} |
//Get top left positioning of element being moved. |
leftElmPos = eventObj.pageX - pos.offsetX; |
topElmPos = eventObj.pageY - pos.offsetY; |
//dragElm can't leave the screen on the left. |
if (leftElmPos < 0) { |
leftElmPos = 0; |
} |
//dragElm can't leave the screen on the top. |
if (topElmPos < 0) { |
topElmPos = 0; |
} |
//dragElm can't leave the screen on the bottom. |
if ((topElmPos + 10) > document_height) { |
topElmPos = document_height - 10; |
} |
//dragElm can't leave the screen on the right. |
if ((leftElmPos + 10) > document_width) { |
leftElmPos = document_width - 10; |
} |
//Updating element being moved css. |
dragElm.css({ |
'left': leftElmPos + 'px', |
'top': topElmPos + 'px' |
}); |
if (scrollContainerElm) { |
//Getting position to top and bottom of container element. |
scrollContainerElmRect = scrollContainerElm.getBoundingClientRect(); |
top_scroll = scrollContainerElm.scrollTop; |
bottom_scroll = top_scroll + scrollContainerElm.clientHeight; |
//To scroll down if cursor y-position is greater than the bottom position of the container vertical scroll |
if (scrollContainerElmRect.bottom < eventObj.clientY && bottom_scroll < scrollContainerElm.scrollHeight) { |
scrollDownBy = Math.min(scrollContainerElm.scrollHeight - bottom_scroll, 10); |
scrollContainerElm.scrollTop += scrollDownBy; |
} |
//To scroll top if cursor y-position is less than the top position of the container vertical scroll |
if (scrollContainerElmRect.top > eventObj.clientY && top_scroll > 0) { |
scrollUpBy = Math.min(top_scroll, 10); |
scrollContainerElm.scrollTop -= scrollUpBy; |
} |
} else { |
//Getting position to top and bottom of page. |
top_scroll = window.pageYOffset || $window.document.documentElement.scrollTop; |
bottom_scroll = top_scroll + (window.innerHeight || $window.document.clientHeight || $window.document.clientHeight); |
//To scroll down if cursor y-position is greater than the bottom position of the window vertical scroll |
if (bottom_scroll < eventObj.pageY && bottom_scroll < document_height) { |
scrollDownBy = Math.min(document_height - bottom_scroll, 10); |
window.scrollBy(0, scrollDownBy); |
} |
//To scroll top if cursor y-position is less than the top position of the window vertical scroll |
if (top_scroll > eventObj.pageY) { |
scrollUpBy = Math.min(top_scroll, 10); |
window.scrollBy(0, -scrollUpBy); |
} |
} |
//Calling service to update position coordinates based on move. |
UiTreeHelper.positionMoved(e, pos, firstMoving); |
if (firstMoving) { |
firstMoving = false; |
return; |
} |
//Setting X point for elementFromPoint. |
targetX = eventObj.pageX - ($window.pageXOffset || |
$window.document.body.scrollLeft || |
$window.document.documentElement.scrollLeft) - |
($window.document.documentElement.clientLeft || 0); |
targetY = eventObj.pageY - ($window.pageYOffset || |
$window.document.body.scrollTop || |
$window.document.documentElement.scrollTop) - |
($window.document.documentElement.clientTop || 0); |
//Select the drag target. Because IE does not support CSS 'pointer-events: none', it will always |
// pick the drag element itself as the target. To prevent this, we hide the drag element while |
// selecting the target. |
if (angular.isFunction(dragElm.hide)) { |
dragElm.hide(); |
} else { |
displayElm = dragElm[0].style.display; |
dragElm[0].style.display = 'none'; |
} |
//When using elementFromPoint() inside an iframe, you have to call |
// elementFromPoint() twice to make sure IE8 returns the correct value |
//MDN: The elementFromPoint() method of the Document interface returns the topmost element at the specified coordinates. |
$window.document.elementFromPoint(targetX, targetY); |
//Set target element (element in specified x/y coordinates). |
targetElm = angular.element($window.document.elementFromPoint(targetX, targetY)); |
//If the target element is a child element of a ui-tree-handle, |
// use the containing handle element as target element |
isHandleChild = UiTreeHelper.treeNodeHandlerContainerOfElement(targetElm); |
if (isHandleChild) { |
targetElm = angular.element(isHandleChild); |
} |
if (angular.isFunction(dragElm.show)) { |
dragElm.show(); |
} else { |
dragElm[0].style.display = displayElm; |
} |
//Assigning scope to target you are moving draggable over. |
if (UiTreeHelper.elementIsTree(targetElm)) { |
targetNode = targetElm.controller('uiTree').scope; |
} else if (UiTreeHelper.elementIsTreeNodeHandle(targetElm)) { |
targetNode = targetElm.controller('uiTreeHandle').scope; |
} else if (UiTreeHelper.elementIsTreeNode(targetElm)) { |
targetNode = targetElm.controller('uiTreeNode').scope; |
} else if (UiTreeHelper.elementIsTreeNodes(targetElm)) { |
targetNode = targetElm.controller('uiTreeNodes').scope; |
} else if (UiTreeHelper.elementIsPlaceholder(targetElm)) { |
targetNode = targetElm.controller('uiTreeNodes').scope; |
} else if (targetElm.controller('uiTreeNode')) { |
//Is a child element of a node. |
targetNode = targetElm.controller('uiTreeNode').scope; |
} |
moveWithinTree = (targetNode && targetNode.$treeScope && targetNode.$treeScope.$id && targetNode.$treeScope.$id === treeOfOrigin); |
/* (jcarter) Notes to developers: |
* pos.dirAx is either 0 or 1 |
* 1 means horizontal movement is happening |
* 0 means vertical movement is happening |
*/ |
// Move nodes up and down in nesting level. |
if (moveWithinTree && pos.dirAx) { |
// increase horizontal level if previous sibling exists and is not collapsed |
// example 1.1.1 becomes 1.2 |
if (pos.distX > 0) { |
prev = dragInfo.prev(); |
if (prev && !prev.collapsed |
&& prev.accept(scope, prev.childNodesCount())) { |
prev.$childNodesScope.$element.append(placeElm); |
dragInfo.moveTo(prev.$childNodesScope, prev.childNodes(), prev.childNodesCount()); |
} |
} |
// decrease horizontal level |
// example 1.2 become 1.1.1 |
if (pos.distX < 0) { |
// we can't decrease a level if an item preceeds the current one |
next = dragInfo.next(); |
if (!next) { |
target = dragInfo.parentNode(); // As a sibling of it's parent node |
if (target |
&& target.$parentNodesScope.accept(scope, target.index() + 1)) { |
target.$element.after(placeElm); |
dragInfo.moveTo(target.$parentNodesScope, target.siblings(), target.index() + 1); |
} |
} |
} |
} else { //Either in origin tree and moving horizontally OR you are moving within a new tree. |
//Check it's new position. |
isEmpty = false; |
//Exit if target is not a uiTree or child of one. |
if (!targetNode) { |
return; |
} |
//Show the placeholder if it was hidden for nodrop-enabled and this is a new tree |
if (targetNode.$treeScope && !targetNode.$parent.nodropEnabled && !targetNode.$treeScope.nodropEnabled) { |
placeElm.css('display', ''); |
} |
//Set whether target tree is empty or not. |
if (targetNode.$type === 'uiTree' && targetNode.dragEnabled) { |
isEmpty = targetNode.isEmpty(); |
} |
//If target is a handle set new target to handle's node. |
if (targetNode.$type === 'uiTreeHandle') { |
targetNode = targetNode.$nodeScope; |
} |
//Check if it is a uiTreeNode or it's an empty tree. |
if (targetNode.$type !== 'uiTreeNode' && !isEmpty) { |
// Allow node to return to its original position if no longer hovering over target |
if (config.appendChildOnHover) { |
next = dragInfo.next(); |
if (!next && unhover) { |
target = dragInfo.parentNode(); |
target.$element.after(placeElm); |
dragInfo.moveTo(target.$parentNodesScope, target.siblings(), target.index() + 1); |
unhover = false; |
} |
} |
return; |
} |
//If placeholder move from empty tree, reset it. |
if (treeScope && placeElm.parent()[0] != treeScope.$element[0]) { |
treeScope.resetEmptyElement(); |
treeScope = null; |
} |
//It's an empty tree |
if (isEmpty) { |
treeScope = targetNode; |
if (targetNode.$nodesScope.accept(scope, 0)) { |
targetNode.place(placeElm); |
dragInfo.moveTo(targetNode.$nodesScope, targetNode.$nodesScope.childNodes(), 0); |
} |
//Not empty and drag enabled. |
} else if (targetNode.dragEnabled()) { |
//Setting/Resetting data for exanding on hover. |
if (angular.isDefined(scope.expandTimeoutOn) && scope.expandTimeoutOn !== targetNode.id) { |
$timeout.cancel(scope.expandTimeout); |
delete scope.expandTimeout; |
delete scope.expandTimeoutOn; |
scope.$callbacks.expandTimeoutCancel(); |
} |
//Determining if expansion is needed. |
if (targetNode.collapsed) { |
if (scope.expandOnHover === true || (angular.isNumber(scope.expandOnHover) && scope.expandOnHover === 0)) { |
targetNode.collapsed = false; |
} else if (scope.expandOnHover !== false && angular.isNumber(scope.expandOnHover) && scope.expandOnHover > 0) { |
//Triggering expansion. |
if (angular.isUndefined(scope.expandTimeoutOn)) { |
scope.expandTimeoutOn = targetNode.$id; |
scope.$callbacks.expandTimeoutStart(); |
scope.expandTimeout = $timeout(function() |
{ |
scope.$callbacks.expandTimeoutEnd(); |
targetNode.collapsed = false; |
}, scope.expandOnHover); |
} |
} |
} |
//Get the element of ui-tree-node |
targetElm = targetNode.$element; |
targetOffset = UiTreeHelper.offset(targetElm); |
targetHeight = UiTreeHelper.height(targetElm); |
targetChildElm = targetNode.$childNodesScope ? targetNode.$childNodesScope.$element : null; |
targetChildHeight = targetChildElm ? UiTreeHelper.height(targetChildElm) : 0; |
targetHeight -= targetChildHeight; |
targetBeforeBuffer = config.appendChildOnHover ? targetHeight * 0.25 : UiTreeHelper.height(targetElm) / 2; |
targetBefore = eventObj.pageY < (targetOffset.top + targetBeforeBuffer); |
if (targetNode.$parentNodesScope.accept(scope, targetNode.index())) { |
if (targetBefore) { |
targetElm[0].parentNode.insertBefore(placeElm[0], targetElm[0]); |
dragInfo.moveTo(targetNode.$parentNodesScope, targetNode.siblings(), targetNode.index()); |
} else { |
// Try to append as a child if dragged upwards onto targetNode |
if (config.appendChildOnHover && targetNode.accept(scope, targetNode.childNodesCount())) { |
targetNode.$childNodesScope.$element.prepend(placeElm); |
dragInfo.moveTo(targetNode.$childNodesScope, targetNode.childNodes(), 0); |
unhover = true; |
} else { |
targetElm.after(placeElm); |
dragInfo.moveTo(targetNode.$parentNodesScope, targetNode.siblings(), targetNode.index() + 1); |
} |
} |
//We have to check if it can add the dragging node as a child. |
} else if (!targetBefore && targetNode.accept(scope, targetNode.childNodesCount())) { |
targetNode.$childNodesScope.$element.append(placeElm); |
dragInfo.moveTo(targetNode.$childNodesScope, targetNode.childNodes(), targetNode.childNodesCount()); |
} |
} |
} |
//Triggering dragMove callback. |
scope.$apply(function () { |
scope.$treeScope.$callbacks.dragMove(dragInfo.eventArgs(elements, pos)); |
}); |
} |
}; |
dragEnd = function (e) { |
var dragEventArgs = dragInfo.eventArgs(elements, pos); |
e.preventDefault(); |
//TODO(jcarter): Is dragStart need to be unbound? |
unbindDragMoveEvents(); |
//This cancel the collapse/expand login running. |
$timeout.cancel(scope.expandTimeout); |
scope.$treeScope.$apply(function () { |
$q.when(scope.$treeScope.$callbacks.beforeDrop(dragEventArgs)) |
//Promise resolved (or callback didn't return false) |
.then(function (allowDrop) { |
if (allowDrop !== false && scope.$$allowNodeDrop) { |
//Node drop accepted. |
dragInfo.apply(); |
//Fire the dropped callback only if the move was successful. |
scope.$treeScope.$callbacks.dropped(dragEventArgs); |
} else { |
//Drop canceled - revert the node to its original position. |
bindDragStartEvents(); |
} |
}) |
//Promise rejected - revert the node to its original position. |
.catch(function () { |
bindDragStartEvents(); |
}) |
.finally(function () { |
//Replace placeholder with newly dropped element. |
hiddenPlaceElm.replaceWith(scope.$element); |
placeElm.remove(); |
//Remove drag element if still in DOM. |
if (dragElm) { |
dragElm.remove(); |
dragElm = null; |
} |
//Fire dragStope callback. |
scope.$treeScope.$callbacks.dragStop(dragEventArgs); |
scope.$$allowNodeDrop = false; |
dragInfo = null; |
//Restore cursor in Opera 12.16 and IE |
var oldCur = document.body.getAttribute('ui-tree-cursor'); |
if (oldCur !== null) { |
$document.find('body').css({'cursor': oldCur}); |
document.body.removeAttribute('ui-tree-cursor'); |
} |
}); |
}); |
}; |
dragStartEvent = function (e) { |
if (scope.dragEnabled()) { |
dragStart(e); |
} |
}; |
dragMoveEvent = function (e) { |
dragMove(e); |
}; |
dragEndEvent = function (e) { |
scope.$$allowNodeDrop = true; |
dragEnd(e); |
}; |
dragCancelEvent = function (e) { |
dragEnd(e); |
}; |
dragDelay = (function () { |
var to; |
return { |
exec: function (fn, ms) { |
if (!ms) { |
ms = 0; |
} |
this.cancel(); |
to = $timeout(fn, ms); |
}, |
cancel: function () { |
$timeout.cancel(to); |
} |
}; |
})(); |
keydownHandler = function (e) { |
if (e.keyCode === 27) { |
dragEndEvent(e); |
} |
}; |
/** |
* Binds the mouse/touch events to enable drag start for this node. |
*/ |
//This is outside of bindDragMoveEvents because of the potential for a delay setting. |
bindDragStartEvents = function () { |
element.bind('touchstart mousedown', function (e) { |
//Don't call drag delay if no delay was specified. |
if (scope.dragDelay > 0) { |
dragDelay.exec(function () { |
dragStartEvent(e); |
}, scope.dragDelay); |
} else { |
dragStartEvent(e); |
} |
}); |
element.bind('touchend touchcancel mouseup', function () { |
if (scope.dragDelay > 0) { |
dragDelay.cancel(); |
} |
}); |
}; |
bindDragStartEvents(); |
/** |
* Binds mouse/touch events that handle moving/dropping this dragged node |
*/ |
bindDragMoveEvents = function () { |
angular.element($document).bind('touchend', dragEndEvent); |
angular.element($document).bind('touchcancel', dragEndEvent); |
angular.element($document).bind('touchmove', dragMoveEvent); |
angular.element($document).bind('mouseup', dragEndEvent); |
angular.element($document).bind('mousemove', dragMoveEvent); |
angular.element($document).bind('mouseleave', dragCancelEvent); |
angular.element($document).bind('keydown', keydownHandler); |
}; |
/** |
* Unbinds mouse/touch events that handle moving/dropping this dragged node. |
*/ |
unbindDragMoveEvents = function () { |
angular.element($document).unbind('touchend', dragEndEvent); |
angular.element($document).unbind('touchcancel', dragEndEvent); |
angular.element($document).unbind('touchmove', dragMoveEvent); |
angular.element($document).unbind('mouseup', dragEndEvent); |
angular.element($document).unbind('mousemove', dragMoveEvent); |
angular.element($document).unbind('mouseleave', dragCancelEvent); |
angular.element($document).unbind('keydown', keydownHandler); |
}; |
} |
}; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
.directive('uiTreeNodes', ['treeConfig', '$window', |
function (treeConfig) { |
return { |
require: ['ngModel', '?^uiTreeNode', '^uiTree'], |
restrict: 'A', |
scope: true, |
controller: 'TreeNodesController', |
link: function (scope, element, attrs, controllersArr) { |
var config = {}, |
ngModel = controllersArr[0], |
treeNodeCtrl = controllersArr[1], |
treeCtrl = controllersArr[2]; |
angular.extend(config, treeConfig); |
if (config.nodesClass) { |
element.addClass(config.nodesClass); |
} |
if (treeNodeCtrl) { |
treeNodeCtrl.scope.$childNodesScope = scope; |
scope.$nodeScope = treeNodeCtrl.scope; |
} else { |
// find the root nodes if there is no parent node and have a parent ui-tree |
treeCtrl.scope.$nodesScope = scope; |
} |
scope.$treeScope = treeCtrl.scope; |
if (ngModel) { |
ngModel.$render = function () { |
scope.$modelValue = ngModel.$modelValue; |
}; |
} |
scope.$watch(function () { |
return attrs.maxDepth; |
}, function (val) { |
if ((typeof val) == 'number') { |
scope.maxDepth = val; |
} |
}); |
scope.$watch(function () { |
return attrs.nodropEnabled; |
}, function (newVal) { |
if ((typeof newVal) != 'undefined') { |
scope.nodropEnabled = true; |
} |
}, true); |
} |
}; |
} |
]); |
})(); |
(function () { |
'use strict'; |
angular.module('ui.tree') |
/** |
* @ngdoc service |
* @name ui.tree.service:UiTreeHelper |
* @requires ng.$document |
* @requires ng.$window |
* |
* @description |
* angular-ui-tree. |
*/ |
.factory('UiTreeHelper', ['$document', '$window', 'treeConfig', |
function ($document, $window, treeConfig) { |
return { |
/** |
* A hashtable used to storage data of nodes |
* @type {Object} |
*/ |
nodesData: {}, |
setNodeAttribute: function (scope, attrName, val) { |
if (!scope.$modelValue) { |
return null; |
} |
var data = this.nodesData[scope.$modelValue.$$hashKey]; |
if (!data) { |
data = {}; |
this.nodesData[scope.$modelValue.$$hashKey] = data; |
} |
data[attrName] = val; |
}, |
getNodeAttribute: function (scope, attrName) { |
if (!scope.$modelValue) { |
return null; |
} |
var data = this.nodesData[scope.$modelValue.$$hashKey]; |
if (data) { |
return data[attrName]; |
} |
return null; |
}, |
/** |
* @ngdoc method |
* @methodOf ui.tree.service:$nodrag |
* @param {Object} targetElm angular element |
* @return {Bool} check if the node can be dragged. |
*/ |
nodrag: function (targetElm) { |
if (typeof targetElm.attr('data-nodrag') != 'undefined') { |
return targetElm.attr('data-nodrag') !== 'false'; |
} |
return false; |
}, |
/** |
* Get the event object for touches. |
* |
* @param {MouseEvent|TouchEvent} e MouseEvent or TouchEvent that kicked off dragX method. |
* @return {MouseEvent|TouchEvent} Object returned as original event object. |
*/ |
eventObj: function (e) { |
var obj = e; |
if (e.targetTouches !== undefined) { |
//Set obj equal to the first Touch object in the TouchList. |
obj = e.targetTouches.item(0); |
//Logic to set obj to original TouchEvent. |
} else if (e.originalEvent !== undefined && e.originalEvent.targetTouches !== undefined) { |
obj = e.originalEvent.targetTouches.item(0); |
} |
return obj; |
}, |
/** |
* Generate object used to store data about node being moved. |
* |
* {angular.$scope} node Scope of the node that is being moved. |
*/ |
dragInfo: function (node) { |
return { |
source: node, |
sourceInfo: { |
cloneModel: node.$treeScope.cloneEnabled === true ? angular.copy(node.$modelValue) : undefined, |
nodeScope: node, |
index: node.index(), |
nodesScope: node.$parentNodesScope |
}, |
index: node.index(), |
//Slice(0) just duplicates an array. |
siblings: node.siblings().slice(0), |
parent: node.$parentNodesScope, |
//Reset parent to source parent. |
resetParent: function() { |
this.parent = node.$parentNodesScope; |
}, |
//Move the node to a new position, determining where the node will be inserted to when dropped happens here. |
moveTo: function (parent, siblings, index) { |
this.parent = parent; |
//Duplicate siblings array. |
this.siblings = siblings.slice(0); |
//If source node is in the target nodes |
var i = this.siblings.indexOf(this.source); |
if (i > -1) { |
this.siblings.splice(i, 1); |
if (this.source.index() < index) { |
index--; |
} |
} |
this.siblings.splice(index, 0, this.source); |
this.index = index; |
}, |
//Get parent nodes nodeScope. |
parentNode: function () { |
return this.parent.$nodeScope; |
}, |
//Get previous sibling node. |
prev: function () { |
if (this.index > 0) { |
return this.siblings[this.index - 1]; |
} |
return null; |
}, |
//Get next sibling node. |
next: function () { |
if (this.index < this.siblings.length - 1) { |
return this.siblings[this.index + 1]; |
} |
return null; |
}, |
//Return what cloneEnabled is set to on uiTree. |
isClone: function () { |
return this.source.$treeScope.cloneEnabled === true; |
}, |
//Returns a copy of node passed in. |
clonedNode: function (node) { |
return angular.copy(node); |
}, |
//Returns true if parent or index have changed (move happened within any uiTree). |
isDirty: function () { |
return this.source.$parentNodesScope != this.parent || |
this.source.index() != this.index; |
}, |
//Return whether node has a new parent (set on moveTo method). |
isForeign: function () { |
return this.source.$treeScope !== this.parent.$treeScope; |
}, |
//Sets arguments passed to user callbacks. |
eventArgs: function (elements, pos) { |
return { |
source: this.sourceInfo, |
dest: { |
index: this.index, |
nodesScope: this.parent |
}, |
elements: elements, |
pos: pos |
}; |
}, |
//Method that actually manipulates the node being moved. |
apply: function () { |
var nodeData = this.source.$modelValue; |
//Nodrop enabled on tree or parent |
if (this.parent.nodropEnabled || this.parent.$treeScope.nodropEnabled) { |
return; |
} |
//Node was dropped in the same place - do nothing. |
if (!this.isDirty()) { |
return; |
} |
//CloneEnabled and cross-tree so copy and do not remove from source. |
if (this.isClone() && this.isForeign()) { |
this.parent.insertNode(this.index, this.sourceInfo.cloneModel); |
//Any other case, remove and reinsert. |
} else { |
this.source.remove(); |
this.parent.insertNode(this.index, nodeData); |
} |
} |
}; |
}, |
/** |
* @ngdoc method |
* @name ui.tree#height |
* @methodOf ui.tree.service:UiTreeHelper |
* |
* @description |
* Get the height of an element. |
* |
* @param {Object} element Angular element. |
* @returns {String} Height |
*/ |
height: function (element) { |
return element.prop('scrollHeight'); |
}, |
/** |
* @ngdoc method |
* @name ui.tree#width |
* @methodOf ui.tree.service:UiTreeHelper |
* |
* @description |
* Get the width of an element. |
* |
* @param {Object} element Angular element. |
* @returns {String} Width |
*/ |
width: function (element) { |
return element.prop('scrollWidth'); |
}, |
/** |
* @ngdoc method |
* @name ui.tree#offset |
* @methodOf ui.nestedSortable.service:UiTreeHelper |
* |
* @description |
* Get the offset values of an element. |
* |
* @param {Object} element Angular element. |
* @returns {Object} Object with properties width, height, top and left |
*/ |
offset: function (element) { |
var boundingClientRect = element[0].getBoundingClientRect(); |
return { |
width: element.prop('offsetWidth'), |
height: element.prop('offsetHeight'), |
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop || $document[0].documentElement.scrollTop), |
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft || $document[0].documentElement.scrollLeft) |
}; |
}, |
/** |
* @ngdoc method |
* @name ui.tree#positionStarted |
* @methodOf ui.tree.service:UiTreeHelper |
* |
* @description |
* Get the start position of the target element according to the provided event properties. |
* |
* @param {Object} e Event |
* @param {Object} target Target element |
* @returns {Object} Object with properties offsetX, offsetY, startX, startY, nowX and dirX. |
*/ |
positionStarted: function (e, target) { |
var pos = {}, |
pageX = e.pageX, |
pageY = e.pageY; |
//Check to set correct data for TouchEvents |
if (e.originalEvent && e.originalEvent.touches && (e.originalEvent.touches.length > 0)) { |
pageX = e.originalEvent.touches[0].pageX; |
pageY = e.originalEvent.touches[0].pageY; |
} |
pos.offsetX = pageX - this.offset(target).left; |
pos.offsetY = pageY - this.offset(target).top; |
pos.startX = pos.lastX = pageX; |
pos.startY = pos.lastY = pageY; |
pos.nowX = pos.nowY = pos.distX = pos.distY = pos.dirAx = 0; |
pos.dirX = pos.dirY = pos.lastDirX = pos.lastDirY = pos.distAxX = pos.distAxY = 0; |
return pos; |
}, |
positionMoved: function (e, pos, firstMoving) { |
var pageX = e.pageX, |
pageY = e.pageY, |
newAx; |
//If there are multiple touch points, choose one to use as X and Y. |
if (e.originalEvent && e.originalEvent.touches && (e.originalEvent.touches.length > 0)) { |
pageX = e.originalEvent.touches[0].pageX; |
pageY = e.originalEvent.touches[0].pageY; |
} |
//Mouse position last event. |
pos.lastX = pos.nowX; |
pos.lastY = pos.nowY; |
//Mouse position this event. |
pos.nowX = pageX; |
pos.nowY = pageY; |
//Distance mouse moved between events. |
pos.distX = pos.nowX - pos.lastX; |
pos.distY = pos.nowY - pos.lastY; |
//Direction mouse was moving. |
pos.lastDirX = pos.dirX; |
pos.lastDirY = pos.dirY; |
//Direction mouse is now moving (on both axis). |
pos.dirX = pos.distX === 0 ? 0 : pos.distX > 0 ? 1 : -1; |
pos.dirY = pos.distY === 0 ? 0 : pos.distY > 0 ? 1 : -1; |
//Axis mouse is now moving on. |
newAx = Math.abs(pos.distX) > Math.abs(pos.distY) ? 1 : 0; |
//Do nothing on first move. |
if (firstMoving) { |
pos.dirAx = newAx; |
pos.moving = true; |
return; |
} |
//Calc distance moved on this axis (and direction). |
if (pos.dirAx !== newAx) { |
pos.distAxX = 0; |
pos.distAxY = 0; |
} else { |
pos.distAxX += Math.abs(pos.distX); |
if (pos.dirX !== 0 && pos.dirX !== pos.lastDirX) { |
pos.distAxX = 0; |
} |
pos.distAxY += Math.abs(pos.distY); |
if (pos.dirY !== 0 && pos.dirY !== pos.lastDirY) { |
pos.distAxY = 0; |
} |
} |
pos.dirAx = newAx; |
}, |
elementIsTreeNode: function (element) { |
return typeof element.attr('ui-tree-node') !== 'undefined'; |
}, |
elementIsTreeNodeHandle: function (element) { |
return typeof element.attr('ui-tree-handle') !== 'undefined'; |
}, |
elementIsTree: function (element) { |
return typeof element.attr('ui-tree') !== 'undefined'; |
}, |
elementIsTreeNodes: function (element) { |
return typeof element.attr('ui-tree-nodes') !== 'undefined'; |
}, |
elementIsPlaceholder: function (element) { |
return element.hasClass(treeConfig.placeholderClass); |
}, |
elementContainsTreeNodeHandler: function (element) { |
return element[0].querySelectorAll('[ui-tree-handle]').length >= 1; |
}, |
treeNodeHandlerContainerOfElement: function (element) { |
return findFirstParentElementWithAttribute('ui-tree-handle', element[0]); |
} |
}; |
} |
]); |
// TODO: optimize this loop |
//(Jcarter): Suggest adding a parent element property on uiTree, then all these bubble |
// to <html> can trigger to stop when they reach the parent. |
function findFirstParentElementWithAttribute(attributeName, childObj) { |
//Undefined if the mouse leaves the browser window |
if (childObj === undefined) { |
return null; |
} |
var testObj = childObj.parentNode, |
count = 1, |
//Check for setAttribute due to exception thrown by Firefox when a node is dragged outside the browser window |
res = (typeof testObj.setAttribute === 'function' && testObj.hasAttribute(attributeName)) ? testObj : null; |
while (testObj && typeof testObj.setAttribute === 'function' && !testObj.hasAttribute(attributeName)) { |
testObj = testObj.parentNode; |
res = testObj; |
//Stop once we reach top of page. |
if (testObj === document.documentElement) { |
res = null; |
break; |
} |
count++; |
} |
return res; |
} |
})(); |
/branches/v3/impl/src/web/js/angularjs/angular-ui-tree/angular-ui-tree.min.js |
---|
New file |
0,0 → 1,6 |
/** |
* @license Angular UI Tree v2.22.2 |
* (c) 2010-2016. https://github.com/angular-ui-tree/angular-ui-tree |
* License: MIT |
*/ |
!function(){"use strict";angular.module("ui.tree",[]).constant("treeConfig",{treeClass:"angular-ui-tree",emptyTreeClass:"angular-ui-tree-empty",hiddenClass:"angular-ui-tree-hidden",nodesClass:"angular-ui-tree-nodes",nodeClass:"angular-ui-tree-node",handleClass:"angular-ui-tree-handle",placeholderClass:"angular-ui-tree-placeholder",dragClass:"angular-ui-tree-drag",dragThreshold:3,defaultCollapsed:!1,appendChildOnHover:!0})}(),function(){"use strict";angular.module("ui.tree").controller("TreeHandleController",["$scope","$element",function(e,n){this.scope=e,e.$element=n,e.$nodeScope=null,e.$type="uiTreeHandle"}])}(),function(){"use strict";angular.module("ui.tree").controller("TreeNodeController",["$scope","$element",function(e,n){function t(e){if(!e)return 0;var n,o,l,r=0,a=e.childNodes();if(!a||0===a.length)return 0;for(l=a.length-1;l>=0;l--)n=a[l],o=1+t(n),r=Math.max(r,o);return r}this.scope=e,e.$element=n,e.$modelValue=null,e.$parentNodeScope=null,e.$childNodesScope=null,e.$parentNodesScope=null,e.$treeScope=null,e.$handleScope=null,e.$type="uiTreeNode",e.$$allowNodeDrop=!1,e.collapsed=!1,e.expandOnHover=!1,e.init=function(t){var o=t[0];e.$treeScope=t[1]?t[1].scope:null,e.$parentNodeScope=o.scope.$nodeScope,e.$modelValue=o.scope.$modelValue[e.$index],e.$parentNodesScope=o.scope,o.scope.initSubNode(e),n.on("$destroy",function(){o.scope.destroySubNode(e)})},e.index=function(){return e.$parentNodesScope.$modelValue.indexOf(e.$modelValue)},e.dragEnabled=function(){return!(e.$treeScope&&!e.$treeScope.dragEnabled)},e.isSibling=function(n){return e.$parentNodesScope==n.$parentNodesScope},e.isChild=function(n){var t=e.childNodes();return t&&t.indexOf(n)>-1},e.prev=function(){var n=e.index();return n>0?e.siblings()[n-1]:null},e.siblings=function(){return e.$parentNodesScope.childNodes()},e.childNodesCount=function(){return e.childNodes()?e.childNodes().length:0},e.hasChild=function(){return e.childNodesCount()>0},e.childNodes=function(){return e.$childNodesScope&&e.$childNodesScope.$modelValue?e.$childNodesScope.childNodes():null},e.accept=function(n,t){return e.$childNodesScope&&e.$childNodesScope.$modelValue&&e.$childNodesScope.accept(n,t)},e.remove=function(){return e.$parentNodesScope.removeNode(e)},e.toggle=function(){e.collapsed=!e.collapsed,e.$treeScope.$callbacks.toggle(e.collapsed,e)},e.collapse=function(){e.collapsed=!0},e.expand=function(){e.collapsed=!1},e.depth=function(){var n=e.$parentNodeScope;return n?n.depth()+1:1},e.maxSubDepth=function(){return e.$childNodesScope?t(e.$childNodesScope):0}}])}(),function(){"use strict";angular.module("ui.tree").controller("TreeNodesController",["$scope","$element",function(e,n){this.scope=e,e.$element=n,e.$modelValue=null,e.$nodeScope=null,e.$treeScope=null,e.$type="uiTreeNodes",e.$nodesMap={},e.nodropEnabled=!1,e.maxDepth=0,e.cloneEnabled=!1,e.initSubNode=function(n){return n.$modelValue?void(e.$nodesMap[n.$modelValue.$$hashKey]=n):null},e.destroySubNode=function(n){return n.$modelValue?void(e.$nodesMap[n.$modelValue.$$hashKey]=null):null},e.accept=function(n,t){return e.$treeScope.$callbacks.accept(n,e,t)},e.beforeDrag=function(n){return e.$treeScope.$callbacks.beforeDrag(n)},e.isParent=function(n){return n.$parentNodesScope==e},e.hasChild=function(){return e.$modelValue.length>0},e.safeApply=function(e){var n=this.$root.$$phase;"$apply"==n||"$digest"==n?e&&"function"==typeof e&&e():this.$apply(e)},e.removeNode=function(n){var t=e.$modelValue.indexOf(n.$modelValue);return t>-1?(e.safeApply(function(){e.$modelValue.splice(t,1)[0]}),e.$treeScope.$callbacks.removed(n)):null},e.insertNode=function(n,t){e.safeApply(function(){e.$modelValue.splice(n,0,t)})},e.childNodes=function(){var n,t=[];if(e.$modelValue)for(n=0;n<e.$modelValue.length;n++)t.push(e.$nodesMap[e.$modelValue[n].$$hashKey]);return t},e.depth=function(){return e.$nodeScope?e.$nodeScope.depth():0},e.outOfDepth=function(n){var t=e.maxDepth||e.$treeScope.maxDepth;return t>0&&e.depth()+n.maxSubDepth()+1>t}}])}(),function(){"use strict";angular.module("ui.tree").controller("TreeController",["$scope","$element",function(e,n){this.scope=e,e.$element=n,e.$nodesScope=null,e.$type="uiTree",e.$emptyElm=null,e.$callbacks=null,e.dragEnabled=!0,e.emptyPlaceholderEnabled=!0,e.maxDepth=0,e.dragDelay=0,e.cloneEnabled=!1,e.nodropEnabled=!1,e.isEmpty=function(){return e.$nodesScope&&e.$nodesScope.$modelValue&&0===e.$nodesScope.$modelValue.length},e.place=function(n){e.$nodesScope.$element.append(n),e.$emptyElm.remove()},this.resetEmptyElement=function(){e.$nodesScope.$modelValue&&0!==e.$nodesScope.$modelValue.length||!e.emptyPlaceholderEnabled?e.$emptyElm.remove():n.append(e.$emptyElm)},e.resetEmptyElement=this.resetEmptyElement}])}(),function(){"use strict";angular.module("ui.tree").directive("uiTree",["treeConfig","$window",function(e,n){return{restrict:"A",scope:!0,controller:"TreeController",link:function(t,o,l,r){var a,i,d,c={accept:null,beforeDrag:null},u={};angular.extend(u,e),u.treeClass&&o.addClass(u.treeClass),"table"===o.prop("tagName").toLowerCase()?(t.$emptyElm=angular.element(n.document.createElement("tr")),i=o.find("tr"),d=i.length>0?angular.element(i).children().length:1e6,a=angular.element(n.document.createElement("td")).attr("colspan",d),t.$emptyElm.append(a)):t.$emptyElm=angular.element(n.document.createElement("div")),u.emptyTreeClass&&t.$emptyElm.addClass(u.emptyTreeClass),t.$watch("$nodesScope.$modelValue.length",function(e){angular.isNumber(e)&&r.resetEmptyElement()},!0),t.$watch(l.dragEnabled,function(e){"boolean"==typeof e&&(t.dragEnabled=e)}),t.$watch(l.emptyPlaceholderEnabled,function(e){"boolean"==typeof e&&(t.emptyPlaceholderEnabled=e,r.resetEmptyElement())}),t.$watch(l.nodropEnabled,function(e){"boolean"==typeof e&&(t.nodropEnabled=e)}),t.$watch(l.cloneEnabled,function(e){"boolean"==typeof e&&(t.cloneEnabled=e)}),t.$watch(l.maxDepth,function(e){"number"==typeof e&&(t.maxDepth=e)}),t.$watch(l.dragDelay,function(e){"number"==typeof e&&(t.dragDelay=e)}),c.accept=function(e,n,t){return!(n.nodropEnabled||n.$treeScope.nodropEnabled||n.outOfDepth(e))},c.beforeDrag=function(e){return!0},c.expandTimeoutStart=function(){},c.expandTimeoutCancel=function(){},c.expandTimeoutEnd=function(){},c.removed=function(e){},c.dropped=function(e){},c.dragStart=function(e){},c.dragMove=function(e){},c.dragStop=function(e){},c.beforeDrop=function(e){},c.toggle=function(e,n){},t.$watch(l.uiTree,function(e,n){angular.forEach(e,function(e,n){c[n]&&"function"==typeof e&&(c[n]=e)}),t.$callbacks=c},!0)}}}])}(),function(){"use strict";angular.module("ui.tree").directive("uiTreeHandle",["treeConfig",function(e){return{require:"^uiTreeNode",restrict:"A",scope:!0,controller:"TreeHandleController",link:function(n,t,o,l){var r={};angular.extend(r,e),r.handleClass&&t.addClass(r.handleClass),n!=l.scope&&(n.$nodeScope=l.scope,l.scope.$handleScope=n)}}}])}(),function(){"use strict";angular.module("ui.tree").directive("uiTreeNode",["treeConfig","UiTreeHelper","$window","$document","$timeout","$q",function(e,n,t,o,l,r){return{require:["^uiTreeNodes","^uiTree"],restrict:"A",controller:"TreeNodeController",link:function(a,i,d,c){var u,s,p,f,m,h,$,g,b,v,N,S,y,x,E,T,C,w,D,H,O,Y,A,X,V,k,M,I={},P="ontouchstart"in window,L=null,W=document.body,q=document.documentElement;angular.extend(I,e),I.nodeClass&&i.addClass(I.nodeClass),a.init(c),a.collapsed=!!n.getNodeAttribute(a,"collapsed")||e.defaultCollapsed,a.expandOnHover=!!n.getNodeAttribute(a,"expandOnHover"),a.scrollContainer=n.getNodeAttribute(a,"scrollContainer")||d.scrollContainer||null,a.sourceOnly=a.nodropEnabled||a.$treeScope.nodropEnabled,a.$watch(d.collapsed,function(e){"boolean"==typeof e&&(a.collapsed=e)}),a.$watch("collapsed",function(e){n.setNodeAttribute(a,"collapsed",e),d.$set("collapsed",e)}),a.$watch(d.expandOnHover,function(e){"boolean"!=typeof e&&"number"!=typeof e||(a.expandOnHover=e)}),a.$watch("expandOnHover",function(e){n.setNodeAttribute(a,"expandOnHover",e),d.$set("expandOnHover",e)}),d.$observe("scrollContainer",function(e){"string"==typeof e&&(a.scrollContainer=e)}),a.$watch("scrollContainer",function(e){n.setNodeAttribute(a,"scrollContainer",e),d.$set("scrollContainer",e),$=document.querySelector(e)}),a.$on("angular-ui-tree:collapse-all",function(){a.collapsed=!0}),a.$on("angular-ui-tree:expand-all",function(){a.collapsed=!1}),S=function(e){if((P||2!==e.button&&3!==e.which)&&!(e.uiTreeDragging||e.originalEvent&&e.originalEvent.uiTreeDragging)){var l,r,d,c,$,g,S,y,x,E=angular.element(e.target);if(l=n.treeNodeHandlerContainerOfElement(E),l&&(E=angular.element(l)),r=i.clone(),y=n.elementIsTreeNode(E),x=n.elementIsTreeNodeHandle(E),(y||x)&&!(y&&n.elementContainsTreeNodeHandler(E)||(d=E.prop("tagName").toLowerCase(),"input"==d||"textarea"==d||"button"==d||"select"==d))){for(V=angular.element(e.target);V&&V[0]&&V[0]!==i&&!k;){if(V[0].attributes&&(k=V[0].attributes["ui-tree"]),n.nodrag(V))return;V=V.parent()}a.beforeDrag(a)&&(e.uiTreeDragging=!0,e.originalEvent&&(e.originalEvent.uiTreeDragging=!0),e.preventDefault(),$=n.eventObj(e),u=!0,s=n.dragInfo(a),M=s.source.$treeScope.$id,c=i.prop("tagName"),"tr"===c.toLowerCase()?(f=angular.element(t.document.createElement(c)),g=angular.element(t.document.createElement("td")).addClass(I.placeholderClass).attr("colspan",i[0].children.length),f.append(g)):f=angular.element(t.document.createElement(c)).addClass(I.placeholderClass),m=angular.element(t.document.createElement(c)),I.hiddenClass&&m.addClass(I.hiddenClass),p=n.positionStarted($,i),f.css("height",n.height(i)+"px"),h=angular.element(t.document.createElement(a.$parentNodesScope.$element.prop("tagName"))).addClass(a.$parentNodesScope.$element.attr("class")).addClass(I.dragClass),h.css("width",n.width(i)+"px"),h.css("z-index",9999),S=(i[0].querySelector(".angular-ui-tree-handle")||i[0]).currentStyle,S&&(document.body.setAttribute("ui-tree-cursor",o.find("body").css("cursor")||""),o.find("body").css({cursor:S.cursor+"!important"})),a.sourceOnly&&f.css("display","none"),i.after(f),i.after(m),s.isClone()&&a.sourceOnly?h.append(r):h.append(i),o.find("body").append(h),h.css({left:$.pageX-p.offsetX+"px",top:$.pageY-p.offsetY+"px"}),b={placeholder:f,dragging:h},O(),a.$apply(function(){a.$treeScope.$callbacks.dragStart(s.eventArgs(b,p))}),v=Math.max(W.scrollHeight,W.offsetHeight,q.clientHeight,q.scrollHeight,q.offsetHeight),N=Math.max(W.scrollWidth,W.offsetWidth,q.clientWidth,q.scrollWidth,q.offsetWidth))}}},y=function(e){var o,r,i,d,c,m,S,y,x,E,T,C,w,D,H,O,Y,A,V,k,P,W,q,F=n.eventObj(e);if(h){if(e.preventDefault(),t.getSelection?t.getSelection().removeAllRanges():t.document.selection&&t.document.selection.empty(),i=F.pageX-p.offsetX,d=F.pageY-p.offsetY,i<0&&(i=0),d<0&&(d=0),d+10>v&&(d=v-10),i+10>N&&(i=N-10),h.css({left:i+"px",top:d+"px"}),$?(S=$.getBoundingClientRect(),c=$.scrollTop,m=c+$.clientHeight,S.bottom<F.clientY&&m<$.scrollHeight&&(H=Math.min($.scrollHeight-m,10),$.scrollTop+=H),S.top>F.clientY&&c>0&&(O=Math.min(c,10),$.scrollTop-=O)):(c=window.pageYOffset||t.document.documentElement.scrollTop,m=c+(window.innerHeight||t.document.clientHeight||t.document.clientHeight),m<F.pageY&&m<v&&(H=Math.min(v-m,10),window.scrollBy(0,H)),c>F.pageY&&(O=Math.min(c,10),window.scrollBy(0,-O))),n.positionMoved(e,p,u),u)return void(u=!1);if(x=F.pageX-(t.pageXOffset||t.document.body.scrollLeft||t.document.documentElement.scrollLeft)-(t.document.documentElement.clientLeft||0),E=F.pageY-(t.pageYOffset||t.document.body.scrollTop||t.document.documentElement.scrollTop)-(t.document.documentElement.clientTop||0),angular.isFunction(h.hide)?h.hide():(T=h[0].style.display,h[0].style.display="none"),t.document.elementFromPoint(x,E),w=angular.element(t.document.elementFromPoint(x,E)),X=n.treeNodeHandlerContainerOfElement(w),X&&(w=angular.element(X)),angular.isFunction(h.show)?h.show():h[0].style.display=T,n.elementIsTree(w)?C=w.controller("uiTree").scope:n.elementIsTreeNodeHandle(w)?C=w.controller("uiTreeHandle").scope:n.elementIsTreeNode(w)?C=w.controller("uiTreeNode").scope:n.elementIsTreeNodes(w)?C=w.controller("uiTreeNodes").scope:n.elementIsPlaceholder(w)?C=w.controller("uiTreeNodes").scope:w.controller("uiTreeNode")&&(C=w.controller("uiTreeNode").scope),V=C&&C.$treeScope&&C.$treeScope.$id&&C.$treeScope.$id===M,V&&p.dirAx)p.distX>0&&(o=s.prev(),o&&!o.collapsed&&o.accept(a,o.childNodesCount())&&(o.$childNodesScope.$element.append(f),s.moveTo(o.$childNodesScope,o.childNodes(),o.childNodesCount()))),p.distX<0&&(r=s.next(),r||(y=s.parentNode(),y&&y.$parentNodesScope.accept(a,y.index()+1)&&(y.$element.after(f),s.moveTo(y.$parentNodesScope,y.siblings(),y.index()+1))));else{if(D=!1,!C)return;if(!C.$treeScope||C.$parent.nodropEnabled||C.$treeScope.nodropEnabled||f.css("display",""),"uiTree"===C.$type&&C.dragEnabled&&(D=C.isEmpty()),"uiTreeHandle"===C.$type&&(C=C.$nodeScope),"uiTreeNode"!==C.$type&&!D)return void(I.appendChildOnHover&&(r=s.next(),!r&&g&&(y=s.parentNode(),y.$element.after(f),s.moveTo(y.$parentNodesScope,y.siblings(),y.index()+1),g=!1)));L&&f.parent()[0]!=L.$element[0]&&(L.resetEmptyElement(),L=null),D?(L=C,C.$nodesScope.accept(a,0)&&(C.place(f),s.moveTo(C.$nodesScope,C.$nodesScope.childNodes(),0))):C.dragEnabled()&&(angular.isDefined(a.expandTimeoutOn)&&a.expandTimeoutOn!==C.id&&(l.cancel(a.expandTimeout),delete a.expandTimeout,delete a.expandTimeoutOn,a.$callbacks.expandTimeoutCancel()),C.collapsed&&(a.expandOnHover===!0||angular.isNumber(a.expandOnHover)&&0===a.expandOnHover?C.collapsed=!1:a.expandOnHover!==!1&&angular.isNumber(a.expandOnHover)&&a.expandOnHover>0&&angular.isUndefined(a.expandTimeoutOn)&&(a.expandTimeoutOn=C.$id,a.$callbacks.expandTimeoutStart(),a.expandTimeout=l(function(){a.$callbacks.expandTimeoutEnd(),C.collapsed=!1},a.expandOnHover))),w=C.$element,Y=n.offset(w),P=n.height(w),W=C.$childNodesScope?C.$childNodesScope.$element:null,q=W?n.height(W):0,P-=q,k=I.appendChildOnHover?.25*P:n.height(w)/2,A=F.pageY<Y.top+k,C.$parentNodesScope.accept(a,C.index())?A?(w[0].parentNode.insertBefore(f[0],w[0]),s.moveTo(C.$parentNodesScope,C.siblings(),C.index())):I.appendChildOnHover&&C.accept(a,C.childNodesCount())?(C.$childNodesScope.$element.prepend(f),s.moveTo(C.$childNodesScope,C.childNodes(),0),g=!0):(w.after(f),s.moveTo(C.$parentNodesScope,C.siblings(),C.index()+1)):!A&&C.accept(a,C.childNodesCount())&&(C.$childNodesScope.$element.append(f),s.moveTo(C.$childNodesScope,C.childNodes(),C.childNodesCount())))}a.$apply(function(){a.$treeScope.$callbacks.dragMove(s.eventArgs(b,p))})}},x=function(e){var n=s.eventArgs(b,p);e.preventDefault(),Y(),l.cancel(a.expandTimeout),a.$treeScope.$apply(function(){r.when(a.$treeScope.$callbacks.beforeDrop(n)).then(function(e){e!==!1&&a.$$allowNodeDrop?(s.apply(),a.$treeScope.$callbacks.dropped(n)):H()}).catch(function(){H()}).finally(function(){m.replaceWith(a.$element),f.remove(),h&&(h.remove(),h=null),a.$treeScope.$callbacks.dragStop(n),a.$$allowNodeDrop=!1,s=null;var e=document.body.getAttribute("ui-tree-cursor");null!==e&&(o.find("body").css({cursor:e}),document.body.removeAttribute("ui-tree-cursor"))})})},E=function(e){a.dragEnabled()&&S(e)},T=function(e){y(e)},C=function(e){a.$$allowNodeDrop=!0,x(e)},w=function(e){x(e)},D=function(){var e;return{exec:function(n,t){t||(t=0),this.cancel(),e=l(n,t)},cancel:function(){l.cancel(e)}}}(),A=function(e){27===e.keyCode&&C(e)},H=function(){i.bind("touchstart mousedown",function(e){a.dragDelay>0?D.exec(function(){E(e)},a.dragDelay):E(e)}),i.bind("touchend touchcancel mouseup",function(){a.dragDelay>0&&D.cancel()})},H(),O=function(){angular.element(o).bind("touchend",C),angular.element(o).bind("touchcancel",C),angular.element(o).bind("touchmove",T),angular.element(o).bind("mouseup",C),angular.element(o).bind("mousemove",T),angular.element(o).bind("mouseleave",w),angular.element(o).bind("keydown",A)},Y=function(){angular.element(o).unbind("touchend",C),angular.element(o).unbind("touchcancel",C),angular.element(o).unbind("touchmove",T),angular.element(o).unbind("mouseup",C),angular.element(o).unbind("mousemove",T),angular.element(o).unbind("mouseleave",w),angular.element(o).unbind("keydown",A)}}}}])}(),function(){"use strict";angular.module("ui.tree").directive("uiTreeNodes",["treeConfig","$window",function(e){return{require:["ngModel","?^uiTreeNode","^uiTree"],restrict:"A",scope:!0,controller:"TreeNodesController",link:function(n,t,o,l){var r={},a=l[0],i=l[1],d=l[2];angular.extend(r,e),r.nodesClass&&t.addClass(r.nodesClass),i?(i.scope.$childNodesScope=n,n.$nodeScope=i.scope):d.scope.$nodesScope=n,n.$treeScope=d.scope,a&&(a.$render=function(){n.$modelValue=a.$modelValue}),n.$watch(function(){return o.maxDepth},function(e){"number"==typeof e&&(n.maxDepth=e)}),n.$watch(function(){return o.nodropEnabled},function(e){"undefined"!=typeof e&&(n.nodropEnabled=!0)},!0)}}}])}(),function(){"use strict";function e(e,n){if(void 0===n)return null;for(var t=n.parentNode,o=1,l="function"==typeof t.setAttribute&&t.hasAttribute(e)?t:null;t&&"function"==typeof t.setAttribute&&!t.hasAttribute(e);){if(t=t.parentNode,l=t,t===document.documentElement){l=null;break}o++}return l}angular.module("ui.tree").factory("UiTreeHelper",["$document","$window","treeConfig",function(n,t,o){return{nodesData:{},setNodeAttribute:function(e,n,t){if(!e.$modelValue)return null;var o=this.nodesData[e.$modelValue.$$hashKey];o||(o={},this.nodesData[e.$modelValue.$$hashKey]=o),o[n]=t},getNodeAttribute:function(e,n){if(!e.$modelValue)return null;var t=this.nodesData[e.$modelValue.$$hashKey];return t?t[n]:null},nodrag:function(e){return"undefined"!=typeof e.attr("data-nodrag")&&"false"!==e.attr("data-nodrag")},eventObj:function(e){var n=e;return void 0!==e.targetTouches?n=e.targetTouches.item(0):void 0!==e.originalEvent&&void 0!==e.originalEvent.targetTouches&&(n=e.originalEvent.targetTouches.item(0)),n},dragInfo:function(e){return{source:e,sourceInfo:{cloneModel:e.$treeScope.cloneEnabled===!0?angular.copy(e.$modelValue):void 0,nodeScope:e,index:e.index(),nodesScope:e.$parentNodesScope},index:e.index(),siblings:e.siblings().slice(0),parent:e.$parentNodesScope,resetParent:function(){this.parent=e.$parentNodesScope},moveTo:function(e,n,t){this.parent=e,this.siblings=n.slice(0);var o=this.siblings.indexOf(this.source);o>-1&&(this.siblings.splice(o,1),this.source.index()<t&&t--),this.siblings.splice(t,0,this.source),this.index=t},parentNode:function(){return this.parent.$nodeScope},prev:function(){return this.index>0?this.siblings[this.index-1]:null},next:function(){return this.index<this.siblings.length-1?this.siblings[this.index+1]:null},isClone:function(){return this.source.$treeScope.cloneEnabled===!0},clonedNode:function(e){return angular.copy(e)},isDirty:function(){return this.source.$parentNodesScope!=this.parent||this.source.index()!=this.index},isForeign:function(){return this.source.$treeScope!==this.parent.$treeScope},eventArgs:function(e,n){return{source:this.sourceInfo,dest:{index:this.index,nodesScope:this.parent},elements:e,pos:n}},apply:function(){var e=this.source.$modelValue;this.parent.nodropEnabled||this.parent.$treeScope.nodropEnabled||this.isDirty()&&(this.isClone()&&this.isForeign()?this.parent.insertNode(this.index,this.sourceInfo.cloneModel):(this.source.remove(),this.parent.insertNode(this.index,e)))}}},height:function(e){return e.prop("scrollHeight")},width:function(e){return e.prop("scrollWidth")},offset:function(e){var o=e[0].getBoundingClientRect();return{width:e.prop("offsetWidth"),height:e.prop("offsetHeight"),top:o.top+(t.pageYOffset||n[0].body.scrollTop||n[0].documentElement.scrollTop),left:o.left+(t.pageXOffset||n[0].body.scrollLeft||n[0].documentElement.scrollLeft)}},positionStarted:function(e,n){var t={},o=e.pageX,l=e.pageY;return e.originalEvent&&e.originalEvent.touches&&e.originalEvent.touches.length>0&&(o=e.originalEvent.touches[0].pageX,l=e.originalEvent.touches[0].pageY),t.offsetX=o-this.offset(n).left,t.offsetY=l-this.offset(n).top,t.startX=t.lastX=o,t.startY=t.lastY=l,t.nowX=t.nowY=t.distX=t.distY=t.dirAx=0,t.dirX=t.dirY=t.lastDirX=t.lastDirY=t.distAxX=t.distAxY=0,t},positionMoved:function(e,n,t){var o,l=e.pageX,r=e.pageY;return e.originalEvent&&e.originalEvent.touches&&e.originalEvent.touches.length>0&&(l=e.originalEvent.touches[0].pageX,r=e.originalEvent.touches[0].pageY),n.lastX=n.nowX,n.lastY=n.nowY,n.nowX=l,n.nowY=r,n.distX=n.nowX-n.lastX,n.distY=n.nowY-n.lastY,n.lastDirX=n.dirX,n.lastDirY=n.dirY,n.dirX=0===n.distX?0:n.distX>0?1:-1,n.dirY=0===n.distY?0:n.distY>0?1:-1,o=Math.abs(n.distX)>Math.abs(n.distY)?1:0,t?(n.dirAx=o,void(n.moving=!0)):(n.dirAx!==o?(n.distAxX=0,n.distAxY=0):(n.distAxX+=Math.abs(n.distX),0!==n.dirX&&n.dirX!==n.lastDirX&&(n.distAxX=0),n.distAxY+=Math.abs(n.distY),0!==n.dirY&&n.dirY!==n.lastDirY&&(n.distAxY=0)),void(n.dirAx=o))},elementIsTreeNode:function(e){return"undefined"!=typeof e.attr("ui-tree-node")},elementIsTreeNodeHandle:function(e){return"undefined"!=typeof e.attr("ui-tree-handle")},elementIsTree:function(e){return"undefined"!=typeof e.attr("ui-tree")},elementIsTreeNodes:function(e){return"undefined"!=typeof e.attr("ui-tree-nodes")},elementIsPlaceholder:function(e){return e.hasClass(o.placeholderClass)},elementContainsTreeNodeHandler:function(e){return e[0].querySelectorAll("[ui-tree-handle]").length>=1},treeNodeHandlerContainerOfElement:function(n){return e("ui-tree-handle",n[0])}}}])}(); |
/branches/v3/impl/src/web/layout/themes/scripts-default.jsp |
---|
740,3 → 740,4 |
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/bpmn/css/bpmn.css" /> |
/branches/v3/impl/src/web/layout/headerTools.jsp |
---|
321,3 → 321,6 |
<jsp:include page="intranetTools/files-upload-form.jsp"/> |
<link rel="stylesheet" href="<%=request.getContextPath()%>/js/angularjs/angular-ui-tree/angular-ui-tree.min.css"> |
<script type="text/javascript" src="<%=request.getContextPath()%>/js/angularjs/angular-ui-tree/angular-ui-tree.js"></script> |
/branches/v3/impl/src/web/layout/intranetTools/files-upload-form.jsp |
---|
12,6 → 12,8 |
<script> |
var uploadMultipleFiles = false; |
//Token para transmitir informação entre chamador e chamado |
var token = ""; |
</script> |
29,10 → 31,11 |
</h3> |
</div> |
<div class="modal-body"> |
<form id="files-upload-form"> |
<form id="files-upload-form" accept-charset="UTF-8"> |
<%-- |
<p>TODO - Colocar isto a hidden depois dos testes</p> |
<input type="text" name="jsonFiles" id="jsonFiles" value="{{jsonFiles()}}" class="form-control"> |
--%> |
<input type="hidden" name="jsonFiles" id="jsonFiles" value="{{jsonFiles()}}" class="form-control"> |
<div class="web-messages"> |
</div> |
52,13 → 55,13 |
<button class="btn btn-danger" type="button" ng-click="removeFileFromModel(f.tmpName)"><span class="glyphicon glyphicon-remove"/></button> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div ng-show="showMetaFields == true" class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Titulo:</div> |
<div class="col-md-10 control-label"> |
<input type="text" class="form-control" ng-model="f.title"/> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div ng-show="showMetaFields == true" class="list-group-item clearfix"> |
<div class="col-md-2 control-label">Descrição:</div> |
<div class="col-md-10 control-label"> |
<textarea rows="3" class="form-control" ng-model="f.description"></textarea> |
89,18 → 92,50 |
$('.filesUploadModal').on('show.bs.modal', function(e) |
{ |
$("#filesUploadModal .modal-title .title-wrap").html($(e.relatedTarget).data('title')); |
if($(e.relatedTarget).data('multiple') && $(e.relatedTarget).data('multiple') == true) |
if($(e.relatedTarget).data('multiple') != null && $(e.relatedTarget).data('multiple') == true) |
{ |
uploadMultipleFiles = true; |
$("#${FILE_INPUT_ID}").attr( "multiple" ); |
} |
else |
else if($(e.relatedTarget).data('multiple') != null) |
{ |
uploadMultipleFiles = false; |
$("#${FILE_INPUT_ID}").removeAttr( "multiple" ); |
} |
else |
{ |
$("#${FILE_INPUT_ID}").attr( "multiple" ); |
} |
token = ""; |
if($(e.relatedTarget).data('token')) |
{ |
token = $(e.relatedTarget).data('token'); |
} |
if($(e.relatedTarget).data('showmetafields') != null && $(e.relatedTarget).data('showmetafields') == true) |
{ |
angular.element($("#filesUploadModal")).scope().showMetaFields = true; |
} |
else if($(e.relatedTarget).data('showmetafields') != null) |
{ |
angular.element($("#filesUploadModal")).scope().showMetaFields = false; |
} |
else |
{ |
angular.element($("#filesUploadModal")).scope().showMetaFields = true; |
} |
angular.element($("#filesUploadModal")).scope().uploadedFiles = []; |
angular.element($("#filesUploadModal")).scope().$apply(); |
jsonTargetId = $(e.relatedTarget).data('jsontargetid'); |
$(this).find('.btn-ok').unbind('click').click( |
function() |
131,7 → 166,9 |
} |
); |
$("#${FILE_INPUT_ID}").fileinput('clear'); |
}); |
var filesUploadModule = angular.module('filesUploadModule', []); |
141,8 → 178,9 |
filesUploadModule.controller('filesUploadModuleController', function($scope) { |
//$scope.files = {"service":"ok","uploadedFiles":[{fileName:"teste"}]}; |
$scope.uploadedFiles = []; |
$scope.showMetaFields = true; |
$scope.jsonFiles = function() { |
return {"service":"ok","uploadedFiles": $scope.uploadedFiles }; |
return {"service":"ok", "token":token, "uploadedFiles": $scope.uploadedFiles }; |
}; |
$scope.addRows = function(uploadedFilesToPush) { |
for(var i in uploadedFilesToPush) |
163,13 → 201,125 |
} |
}); |
/* |
var defaultDiacriticsRemovalMap = [ |
{'base':'A', 'letters':'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'}, |
{'base':'AA','letters':'\uA732'}, |
{'base':'AE','letters':'\u00C6\u01FC\u01E2'}, |
{'base':'AO','letters':'\uA734'}, |
{'base':'AU','letters':'\uA736'}, |
{'base':'AV','letters':'\uA738\uA73A'}, |
{'base':'AY','letters':'\uA73C'}, |
{'base':'B', 'letters':'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'}, |
{'base':'C', 'letters':'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'}, |
{'base':'D', 'letters':'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0'}, |
{'base':'DZ','letters':'\u01F1\u01C4'}, |
{'base':'Dz','letters':'\u01F2\u01C5'}, |
{'base':'E', 'letters':'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'}, |
{'base':'F', 'letters':'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'}, |
{'base':'G', 'letters':'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'}, |
{'base':'H', 'letters':'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'}, |
{'base':'I', 'letters':'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'}, |
{'base':'J', 'letters':'\u004A\u24BF\uFF2A\u0134\u0248'}, |
{'base':'K', 'letters':'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'}, |
{'base':'L', 'letters':'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'}, |
{'base':'LJ','letters':'\u01C7'}, |
{'base':'Lj','letters':'\u01C8'}, |
{'base':'M', 'letters':'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'}, |
{'base':'N', 'letters':'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'}, |
{'base':'NJ','letters':'\u01CA'}, |
{'base':'Nj','letters':'\u01CB'}, |
{'base':'O', 'letters':'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'}, |
{'base':'OI','letters':'\u01A2'}, |
{'base':'OO','letters':'\uA74E'}, |
{'base':'OU','letters':'\u0222'}, |
{'base':'OE','letters':'\u008C\u0152'}, |
{'base':'oe','letters':'\u009C\u0153'}, |
{'base':'P', 'letters':'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'}, |
{'base':'Q', 'letters':'\u0051\u24C6\uFF31\uA756\uA758\u024A'}, |
{'base':'R', 'letters':'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'}, |
{'base':'S', 'letters':'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'}, |
{'base':'T', 'letters':'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'}, |
{'base':'TZ','letters':'\uA728'}, |
{'base':'U', 'letters':'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'}, |
{'base':'V', 'letters':'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'}, |
{'base':'VY','letters':'\uA760'}, |
{'base':'W', 'letters':'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'}, |
{'base':'X', 'letters':'\u0058\u24CD\uFF38\u1E8A\u1E8C'}, |
{'base':'Y', 'letters':'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'}, |
{'base':'Z', 'letters':'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'}, |
{'base':'a', 'letters':'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'}, |
{'base':'aa','letters':'\uA733'}, |
{'base':'ae','letters':'\u00E6\u01FD\u01E3'}, |
{'base':'ao','letters':'\uA735'}, |
{'base':'au','letters':'\uA737'}, |
{'base':'av','letters':'\uA739\uA73B'}, |
{'base':'ay','letters':'\uA73D'}, |
{'base':'b', 'letters':'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'}, |
{'base':'c', 'letters':'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'}, |
{'base':'d', 'letters':'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'}, |
{'base':'dz','letters':'\u01F3\u01C6'}, |
{'base':'e', 'letters':'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'}, |
{'base':'f', 'letters':'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'}, |
{'base':'g', 'letters':'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'}, |
{'base':'h', 'letters':'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'}, |
{'base':'hv','letters':'\u0195'}, |
{'base':'i', 'letters':'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'}, |
{'base':'j', 'letters':'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'}, |
{'base':'k', 'letters':'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'}, |
{'base':'l', 'letters':'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'}, |
{'base':'lj','letters':'\u01C9'}, |
{'base':'m', 'letters':'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'}, |
{'base':'n', 'letters':'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'}, |
{'base':'nj','letters':'\u01CC'}, |
{'base':'o', 'letters':'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'}, |
{'base':'oi','letters':'\u01A3'}, |
{'base':'ou','letters':'\u0223'}, |
{'base':'oo','letters':'\uA74F'}, |
{'base':'p','letters':'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'}, |
{'base':'q','letters':'\u0071\u24E0\uFF51\u024B\uA757\uA759'}, |
{'base':'r','letters':'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'}, |
{'base':'s','letters':'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'}, |
{'base':'t','letters':'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'}, |
{'base':'tz','letters':'\uA729'}, |
{'base':'u','letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'}, |
{'base':'v','letters':'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'}, |
{'base':'vy','letters':'\uA761'}, |
{'base':'w','letters':'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'}, |
{'base':'x','letters':'\u0078\u24E7\uFF58\u1E8B\u1E8D'}, |
{'base':'y','letters':'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'}, |
{'base':'z','letters':'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'} |
]; |
var diacriticsMap = {}; |
for (var i=0; i < defaultDiacriticsRemovalMap .length; i++){ |
var letters = defaultDiacriticsRemovalMap [i].letters; |
for (var j=0; j < letters.length ; j++){ |
diacriticsMap[letters[j]] = defaultDiacriticsRemovalMap [i].base; |
} |
} |
// "what?" version ... http://jsperf.com/diacritics/12 |
function removeDiacritics (str) { |
return str.replace(/[^\u0000-\u007E]/g, function(a){ |
return diacriticsMap[a] || a; |
}); |
}*/ |
$(document).ready( function() { |
$("#${FILE_INPUT_ID}").fileinput({ |
uploadUrl: '<%=request.getContextPath()%>/filesUpload', |
maxFilePreviewSize: 4096, |
uploadAsync: false, |
language: "pt" |
language: "pt", |
multiple: "true", |
slugCallback: function(filename) { |
return filename.replace(/[^\x00-\x7F]/g, ""); |
} |
}); |
}); |
/branches/v3/impl/src/web/examples/angular/angular-tree.jsp |
---|
New file |
0,0 → 1,319 |
<%-- |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
PARA TESTAR ESTE EXEMPLO INVOQUE O SEGUINTE URL: |
/examples/angular/angularTree.do |
PORQUE ESTA PAGINA USA A INCLUSAO DOS SCRIPTS DA ANGULAR TREE |
QUE ESTAO EM /layout/themes/scripts-default.jsp |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
--%> |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> |
<%@ taglib prefix="bacoTags" tagdir="/WEB-INF/tags" %> |
<%@ taglib prefix="logic" uri="/WEB-INF/tlds/struts-logic.tld" %> |
<style> |
.btn { |
margin-right: 8px; |
} |
.tree-node,.angular-ui-tree-handle { |
background: #f8faff; |
border: 1px solid #dae2ea; |
color: #7c9eb2; |
padding: 10px 10px; |
} |
.ui-tree-node |
{ |
padding: 10px; |
} |
.angular-ui-tree-handle:hover { |
color: #438eb9; |
background: #f4f6f7; |
border-color: #dce2e8; |
} |
.angular-ui-tree-placeholder { |
background: #f0f9ff; |
border: 2px dashed #bed2db; |
-webkit-box-sizing: border-box; |
-moz-box-sizing: border-box; |
box-sizing: border-box; |
} |
.nodeEmpty { |
height: 50px; |
margin:10px; |
margin-left: 30px; |
border: 1px dashed blue; |
} |
.group-title { |
background-color: #687074 !important; |
color: #FFF !important; |
} |
/* --- Tree --- */ |
.tree-node { |
border: 1px solid #dae2ea; |
background: #f8faff; |
color: #7c9eb2; |
} |
.nodrop { |
background-color: #f2dede; |
} |
.nodrag { |
background-color: #f2eec1; |
} |
.tree-node-content { |
margin: 10px; |
} |
/*Estilo adicionado por mim para os movidos*/ |
.moved |
{ |
border: 2px solid blue !important; |
} |
</style> |
<div class="container-fluid"> |
<% |
//Para ler da base de dados por exemplo |
// AbstractDao.getCurrentSession().beginTransaction(); |
//List<RepositoryDocumentCollection> collections = DaoFactory.getRepositoryDocumentCollectionDaoImpl().findRoots(); |
//String collectionsJson = RepositoryDocumentCollectionImpl.toJson(collections); |
//NAO ESTA A SER USADO É APENAS PARA EXEMPLIFICAR |
//O JSON ESTA INCIALIZADO NO SCOPE DO JAVA_SCRIPT |
String collectionsJson =""; |
request.setAttribute("collectionsJson", collectionsJson); |
%> |
<div id="treeAppPageContent" ng-app="treeAppPageContent" ng-controller="treeAppPageContentController"> |
<script> |
var treeAppPageContent = angular.module('treeAppPageContent', ['ui.tree']); |
GLOBAL_BacoAngularAppDependencies.push('treeAppPageContent'); |
<!-- estes codigos todos do remove e do toggle e etc's não mechi em nada limitei-me a copiar dos gajos--> |
treeAppPageContent.controller('treeAppPageContentController', function ($scope) { |
//PARA USAR O QUE VEM DA BASE DE DADOS |
//$scope.data = ${collectionsJson}; |
$scope.data = [ |
{ |
"id" : 1, |
"name" : "Nao deixa fazer drag", |
"nodrag" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 2, |
"name" : "Nao deixa fazer drop", |
"nodrop" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 3, |
"name" : "Deixa fazer Tudo", |
"isDirectory" : true |
}, |
{ |
"id" : 4, |
"name" : "Deixa fazer Tudo e ja foi movido", |
"moved" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 5, |
"name" : "Exemplo de folha nao deixa abrir", |
"isDirectory" : false |
} |
]; |
$scope.treeOptions = { |
accept: function(sourceNodeScope, destNodesScope, destIndex) { |
return true; |
}, |
dropped: function(e) { |
console.log (e.source.nodeScope.$modelValue); |
alert ("Largado o nó com nome: " + e.source.nodeScope.$modelValue.name + " sobre " + e.dest.nodesScope.$parent.$modelValue.name); |
e.source.nodeScope.$modelValue.moved = true; |
} |
}; |
$scope.remove = function (scope) |
{ |
var nodeData = scope.$modelValue; |
alert("removendo item com id " + nodeData.id) |
scope.remove(); |
}; |
$scope.openedAndHasNotChilds = function(node) |
{ |
if(node.childs == null) |
return false; |
return node.childs.length == 0; |
} |
$scope.newSubItem = function (scope) |
{ |
var nodeData = scope.$modelValue; |
if(nodeData.open != null && nodeData.open == true) |
{ |
if(!nodeData.childs) |
{ |
nodeData.childs = []; |
} |
nodeData.childs.push({ |
id: -1, |
title: nodeData.name + '.' + (nodeData.childs.length + 1), |
nodes: [], |
isDirectory: true |
}); |
} |
else |
{ |
alert("Abra primeiro o nó") |
} |
}; |
$scope.collapseAll = function () { |
$scope.$broadcast('angular-ui-tree:collapse-all'); |
}; |
$scope.expandAll = function () { |
$scope.$broadcast('angular-ui-tree:expand-all'); |
}; |
$scope.openItem = function(item) |
{ |
//apenas deixa abrir neste caso |
if(item.open && item.open==true) |
{ |
//Desligamos o Close se nao isto é uma trapalhada para os elementos que já perderam filhos |
//e depois iamos abri-los novamente |
//item.open=false; |
//delete item.childs; |
} |
else |
{ |
alert("Abrindo Filhos Exemplo"); |
item.open = true; |
item.childs = []; //linha necessária para deixar fazer drop no <ul> |
/* |
Exemplo de chamar um JSON para abrir filhos |
$.getJSON("<%=request.getContextPath()%>/user/pagecontent/jorgeaux/section.jsp",{path:item.path}, |
function(json){ |
item.childs = json; |
item.open = true; |
angular.element($("#treeAppPageContent")).scope().$apply(); |
});*/ |
} |
} |
} |
); |
</script> |
<!--TEMPLATE RECURSIVO--> |
<script type="text/ng-template" id="childs_renderer.html"> |
<!--Para nao deixar fazer drag--> |
<div ng-attr-data-nodrag="{{node.nodrag}}" class="tree-node tree-node-content clearfix" ng-class="{nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved}"> |
<!--O ATRIBUTO ui-tree-handle DEVE SER COLOCADO ONDE É FEITO O CONTROLO DE ARRASTO DRAG AND DROP |
NORMALMENTE NOS EXEMPLOS DEFAULT ESTÁ NO NÓ INTEIRO MAS SE QUISERMOS OUTROS BOTOES TEMOS DE SEPARAR |
SE NAO NADA FUNCIONA POIS O DRAG SOBREPOEM-SE A TUDO--> |
<div class="col-md-1"> |
<i class="glyphicon glyphicon-resize-vertical" ui-tree-handle></i> |
</div> |
<!--O atributo isDirectory apenas deixa abrir ou nao |
data-nodrag significa que não é arrastavel este botão |
as setas são colocadas consoante esteja aberto ou fechado |
--> |
<div class="col-md-1"> |
<a class="btn btn-success btn-xs" ng-if="node.isDirectory" data-nodrag ng-click="openItem(node)"> |
<span |
class="glyphicon" |
ng-class="{ |
'glyphicon-chevron-right': !node.open, |
'glyphicon-chevron-down': node.open |
}"> |
</span> |
</a> |
</div> |
<div class="col-md-8"> |
<input ng-model="node.name" type="text" class="form-control" data-nodrag> |
<span ng-if="node.nodrop">* No drop</span> <span ng-if="node.nodrag">* No drag</span> |
</div> |
<!--BOTOES DE REMOVE E NEW SUBITEMS CHAMAM FUNCOES DO SCOPE--> |
<div class="col-md-2"> |
<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> |
</div> |
<!-- 1) UMA LISTA PARA O NODROP data-nodrop-enabled="true" 2) (EM BAIXO) OUTRA PARA OS QUE DEIXAM FAZER DROP DROP--> |
<ol ng-if="node.nodrop" ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.childs" ng-class="{hidden: collapsed, nodeEmpty: openedAndHasNotChilds(node) }"> |
<li ng-repeat="node in node.childs" ui-tree-node ng-include="'childs_renderer.html'"> |
</li> |
</ol> |
<!-- 2) LISTA DO DROP--> |
<ol ng-if="!node.nodrop" ui-tree-nodes="" ng-model="node.childs" ng-class="{hidden: collapsed, nodeEmpty: openedAndHasNotChilds(node) }"> |
<li ng-repeat="node in node.childs" ui-tree-node ng-include="'childs_renderer.html'"> |
</li> |
</ol> |
</script> |
<!-- E finalmente este é o unico codigo dos gajos que metem no HTML puro--> |
<div class="row"> |
<div class="col-sm-6"> |
<div ui-tree="treeOptions" id="page-content-root"> |
<ol ui-tree-nodes ng-model="data"> |
<li ng-repeat="node in data" ui-tree-node ng-include="'childs_renderer.html'"></li> |
</ol> |
</div> |
</div> |
<div class="col-sm-6"> |
<pre class="code">{{ data | json }}</pre> |
</div> |
</div> |
</div> |
<%--AbstractDao.getCurrentSession().getTransaction().commit();--%> |
</div> |
/branches/v3/impl/src/web/examples/examples.jsp |
---|
51,5 → 51,12 |
</ul> |
<h2>6 - Angular Tree</h2> |
<ul> |
<li><html:link action="/examples/angular/angularTree"> Exemplo de Uso Angular Tree</html:link></li> |
</ul> |
</body> |
</html> |
/branches/v3/impl/src/web/examples/jsonwidget/pesquisa.jsp |
---|
New file |
0,0 → 1,26 |
<%@ page import="jomm.dao.impl.AbstractDao" %> |
<%@ page import="pt.estgp.estgweb.domain.User" %> |
<%@ page import="pt.estgp.estgweb.domain.dao.DaoFactory" %> |
<%@ page import="pt.estgp.estgweb.services.common.SearchTypeEnum" %> |
<%@ page import="java.util.List" %> |
<%@ page import="org.json.JSONArray" %> |
<%@ page import="org.json.JSONObject" %> |
<%@ page contentType="application/json;charset=UTF-8" language="java" %><% |
String query = request.getParameter("query"); |
AbstractDao.getCurrentSession().beginTransaction(); |
List<User> users = DaoFactory.getUserDaoImpl().search(query, SearchTypeEnum.AllWords,10,0); |
JSONArray array = new JSONArray(); |
for(User u: users) |
{ |
JSONObject obj = new JSONObject(); |
obj.put("name",u.getName()); |
obj.put("morada",u.getAddress()); |
array.put(obj); |
} |
AbstractDao.getCurrentSession().getTransaction().commit(); |
out.write(array.toString()); |
%> |
/branches/v3/impl/src/web/examples/jsonwidget/simpleAngularConfigExampleTable.jsp |
---|
New file |
0,0 → 1,203 |
<!DOCTYPE html> |
<html> |
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> |
<body ng-app="myApp0"> |
<script> |
var GLOBAL_BacoAngularAppDependencies = []; |
angular.module('myApp0', GLOBAL_BacoAngularAppDependencies); |
</script> |
<p>Try to change the names.</p> |
<div id="myApp1" ng-app="myApp1" ng-controller="myCtrl1"> |
Variavel <input type="text" value="{{pessoas}}"> |
Nome do Director: <input type="text" ng-model="director.nome"><br> |
Morada do Director: <input type="text" ng-model="director.morada"><br> |
<br> |
Full Name: {{firstName + " " + lastName}} |
<h2>Pessoas</h2> |
<button type="button" ng-click="addPessoa()">Adicionar User</button> |
<table> |
<tr> |
<th>Nome</th> |
<th>Ultimo</th> |
<th>Completo</th> |
<th>Morada</th> |
<th>Idade</th> |
<th></th> |
</tr> |
<tr ng-repeat="p in pessoas"> |
<td> |
<input ng-model="p.nome"/> |
</td> |
<td> |
<input ng-model="p.apelido"/> |
</td> |
<td> |
<input readonly="true" value="{{p.nome + ' ' + p.apelido}}"/> |
</td> |
<td> |
<input ng-model="p.morada"/> |
</td> |
<td> |
<input ng-model="p.idade"/> |
</td> |
</tr> |
</table> |
<div class="row form-horizontal"> |
<div class="col-md-4"> |
<div class="form-group"> |
<label class="control-label col-md-2"> |
Pesquisar Pessoa |
</label> |
<div class="col-md-9"> |
<input class="form-control" type="text" id="query"> |
</div> |
<div class="col-md-1"> |
<button class="btn btn-default " type="button" ng-click="pesquisar()"> |
<span class="glyphicon glyphicon-search"/> |
</button> |
</div> |
</div> |
</div> |
<div class="col-md-7"> |
<table class="table" ng-show="findUsers.length > 0"> |
<thead> |
<tr> |
<th>Nome</th> |
<th>Morada</th> |
</tr> |
</thead> |
<tbody> |
<tr ng-repeat="p in findUsers"> |
<td> |
{{p.name}} |
</td> |
<td> |
{{p.morada}} |
</td> |
<td> |
<button class="btn btn-success" type="button" ng-click="escolheDirector(p)"> |
<span class="glyphicon glyphicon-plus"/> |
</button> |
</td> |
</tr> |
</tbody> |
</table> |
</div> |
</div> |
<br/> |
Media de idades: <input type="text" ng-model="mediaIdades()"/> |
<div> |
<pre>{{pessoas | json}}</pre> |
</div> |
</div> |
<script> |
var app1 = angular.module('myApp1', []); |
GLOBAL_BacoAngularAppDependencies.push('myApp1'); |
app1.controller('myCtrl1', function($scope) { |
$scope.firstName= "John"; |
$scope.lastName= "Doe"; |
$scope.findUsers= []; |
$scope.director = { |
"nome" : "", |
"morada" :"" |
} |
$scope.pessoas = [ |
{ |
"nome" : "jorge", |
"apelido" : "machado", |
"morada" : "portalegre" |
}, |
{ |
"nome" : "Mario", |
"apelido" : "Costa", |
"morada" : "portalegre" |
} |
]; |
$scope.addPessoa = function(){ |
$scope.pessoas.push( |
{ |
"nome" : "", |
"apelido" : "", |
"morada" : "" |
} |
); |
} |
$scope.mediaIdades = function(){ |
soma = 0; |
for (index = 0; index < $scope.pessoas.length; ++index) { |
soma += parseFloat($scope.pessoas[index].idade); |
} |
media = soma / $scope.pessoas.length; |
return media; |
} |
$scope.pesquisar = function() |
{ |
query = $("#query").val(); |
$.getJSON("<%=request.getContextPath()%>/examples/jsonwidget/pesquisa.jsp", |
{ |
"query" : query |
}, |
function(json){ |
$scope.findUsers = json; |
angular.element($("#myApp1")).scope().$apply(); |
} |
); |
} |
$scope.escolheDirector = function(p) |
{ |
$scope.director.nome = p.name; |
$scope.director.morada = p.morada; |
} |
}); |
</script> |
</body> |
</html> |
/branches/v3/impl/src/web/user/home/panels/institutionTools.jsp |
---|
17,6 → 17,8 |
<div class="list-group"> |
<baco:hasRole role="admin,all,repositoryDocs"> |
<div class="list-group-item"><html:link action="/user/editRepositoryDoc"><bean:message key="repositorydoc"/></html:link></div> |
<div class="list-group-item"><html:link action="/user/editRepositoryCol"><bean:message key="repositorycol"/></html:link></div> |
<div class="list-group-item"><html:link action="/user/collectionsBrowser"><bean:message key="repositorycolbrowser"/></html:link></div> |
</baco:hasRole> |
</div> |
</div> |
/branches/v3/impl/src/web/user/repositoryDocuments/createInterface.jsp |
---|
New file |
0,0 → 1,9 |
<%-- |
Created by IntelliJ IDEA. |
User: jorgemachado |
Date: 17/03/17 |
Time: 17:20 |
To change this template use File | Settings | File Templates. |
--%> |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> |
/branches/v3/impl/src/web/user/repositoryDocuments/repositoryCollections.jsp |
---|
New file |
0,0 → 1,435 |
<%@ page import="jomm.dao.impl.AbstractDao" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocumentCollection" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocumentCollectionImpl" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocumentImpl" %> |
<%@ page import="pt.estgp.estgweb.domain.dao.DaoFactory" %> |
<%@ page import="java.util.List" %> |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> |
<%@ taglib prefix="bacoTags" tagdir="/WEB-INF/tags" %> |
<%@ taglib prefix="logic" uri="/WEB-INF/tlds/struts-logic.tld" %> |
<%@ taglib prefix="baco" uri="/WEB-INF/tlds/baco.tld" %> |
<style> |
.btn { |
margin-right: 8px; |
} |
.tree-node,.angular-ui-tree-handle { |
background: #f8faff; |
border: 1px solid #dae2ea; |
color: #7c9eb2; |
padding: 10px 10px; |
} |
.ui-tree-node |
{ |
padding: 10px; |
} |
.angular-ui-tree-handle:hover { |
color: #438eb9; |
background: #f4f6f7; |
border-color: #dce2e8; |
} |
.angular-ui-tree-placeholder { |
background: #f0f9ff; |
border: 2px dashed #bed2db; |
-webkit-box-sizing: border-box; |
-moz-box-sizing: border-box; |
box-sizing: border-box; |
} |
.nodeEmpty { |
height: 50px; |
margin:10px; |
margin-left: 30px; |
border: 1px dashed blue; |
} |
.group-title { |
background-color: #687074 !important; |
color: #FFF !important; |
} |
/* --- Tree --- */ |
.tree-node { |
border: 1px solid #dae2ea; |
background: #f8faff; |
color: #7c9eb2; |
} |
.nodrop { |
background-color: #f2dede; |
} |
.nodrag { |
background-color: #f2eec1; |
} |
.tree-node-content { |
margin: 10px; |
} |
/*Estilo adicionado por mim para os movidos*/ |
.moved |
{ |
border: 2px solid blue !important; |
} |
.modified |
{ |
border: 4px dashed orange !important; |
} |
</style> |
<div class="container-fluid"> |
<% |
AbstractDao.getCurrentSession().beginTransaction(); |
List<RepositoryDocumentCollection> collections = DaoFactory.getRepositoryDocumentCollectionDaoImpl().findRoots(); |
String collectionsJson = RepositoryDocumentCollectionImpl.toJson(collections); |
request.setAttribute("collectionsJson", collectionsJson); |
%> |
<div id="treeAppPageContent" ng-app="treeAppPageContent" ng-controller="treeAppPageContentController"> |
<script> |
var treeAppPageContent = angular.module('treeAppPageContent', ['ui.tree']); |
GLOBAL_BacoAngularAppDependencies.push('treeAppPageContent'); |
<!-- estes codigos todos do remove e do toggle e etc's não mechi em nada limitei-me a copiar dos gajos--> |
treeAppPageContent.controller('treeAppPageContentController', function ($scope) { |
$scope.data = ${collectionsJson}; |
/* |
$scope.data = [ |
{ |
"id" : 1, |
"name" : "Nao deixa fazer drag", |
"nodrag" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 2, |
"name" : "Nao deixa fazer drop", |
"nodrop" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 3, |
"name" : "Deixa fazer Tudo", |
"isDirectory" : true |
}, |
{ |
"id" : 4, |
"name" : "Deixa fazer Tudo e ja foi movido", |
"moved" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 5, |
"name" : "Exemplo de folha nao deixa abrir", |
"isDirectory" : false |
} |
];*/ |
$scope.treeOptions = { |
accept: function(sourceNodeScope, destNodesScope, destIndex) { |
return true; |
}, |
dropped: function(e) { |
//console.log (e.source.nodeScope.$modelValue); |
//alert ("Largado o nó com nome: " + e.source.nodeScope.$modelValue.name + " sobre " + e.dest.nodesScope.$parent.$modelValue.name); |
if(e.dest.nodesScope.$parent.$modelValue) |
{ |
widgetSimpleCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"changeParentCollection", |
{ |
"id" : e.source.nodeScope.$modelValue.id, |
"newParentId" : e.dest.nodesScope.$parent.$modelValue.id |
}, |
"#treeAppPageContent", |
function() |
{ |
e.source.nodeScope.$modelValue.moved = true; |
$scope.$apply(); |
} |
); |
} |
else |
{ |
//mover para a raiz |
widgetSimpleCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"changeToRootCollection", |
{ |
"id" : e.source.nodeScope.$modelValue.id |
}, |
"#treeAppPageContent", |
function() |
{ |
e.source.nodeScope.$modelValue.moved = true; |
$scope.$apply(); |
} |
); |
} |
} |
}; |
$scope.remove = function (scope) |
{ |
var nodeData = scope.$modelValue; |
alert("removendo item com id " + nodeData.id) |
scope.remove(); |
}; |
$scope.openedAndHasNotChilds = function(node) |
{ |
if(node.childs == null) |
return false; |
return node.childs.length == 0; |
} |
$scope.newSubItem = function (scope) |
{ |
var nodeData = scope.$modelValue; |
if(nodeData.open != null && nodeData.open == true) |
{ |
widgetCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"addCollection", |
{ |
"id" : nodeData.id |
}, |
"#treeAppPageContent", |
function(json) |
{ |
if(!nodeData.childs) |
{ |
nodeData.childs = []; |
} |
nodeData.childs.push(json); |
$scope.$apply(); |
} |
); |
} |
else |
{ |
alert("Abra primeiro o nó por favor!") |
} |
}; |
$scope.newRootItem = function () |
{ |
widgetCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"newRootCollection", |
{ |
}, |
"#treeAppPageContent", |
function(json) |
{ |
$scope.data.push(json); |
$scope.$apply(); |
} |
); |
}; |
$scope.collapseAll = function () { |
$scope.$broadcast('angular-ui-tree:collapse-all'); |
}; |
$scope.expandAll = function () { |
$scope.$broadcast('angular-ui-tree:expand-all'); |
}; |
$scope.openItem = function(item) |
{ |
//apenas deixa abrir neste caso |
if(item.open && item.open==true) |
{ |
item.open=false; |
delete item.childs; |
} |
else |
{ |
widgetCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"openRepositoryCollection", |
{ |
"id" : item.id |
}, |
"#treeAppPageContent", |
function(json) |
{ |
item.childs = json.collections; |
item.open = true; |
$scope.$apply(); |
}); |
} |
} |
$scope.updateItem = function(node) |
{ |
widgetSimpleCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"updateCollection", |
{ |
"collection": JSON.stringify(node) |
}, |
"#treeAppPageContent", |
function() |
{ |
delete node.modified; |
$scope.$apply(); |
} |
); |
} |
$scope.setModified = function(node) |
{ |
node.modified = "true"; |
} |
} |
); |
</script> |
<!--TEMPLATE RECURSIVO--> |
<script type="text/ng-template" id="childs_renderer.html"> |
<!--Para nao deixar fazer drag--> |
<div ng-attr-data-nodrag="{{node.nodrag}}" class="tree-node tree-node-content clearfix" ng-class="{modified: node.modified, nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved, bacoInvisible: !node.visible}"> |
<!--O ATRIBUTO ui-tree-handle DEVE SER COLOCADO ONDE É FEITO O CONTROLO DE ARRASTO DRAG AND DROP |
NORMALMENTE NOS EXEMPLOS DEFAULT ESTÁ NO NÓ INTEIRO MAS SE QUISERMOS OUTROS BOTOES TEMOS DE SEPARAR |
SE NAO NADA FUNCIONA POIS O DRAG SOBREPOEM-SE A TUDO--> |
<div class="col-md-1"> |
<i class="glyphicon glyphicon-resize-vertical" ui-tree-handle></i> |
</div> |
<!--O atributo isDirectory apenas deixa abrir ou nao |
data-nodrag significa que não é arrastavel este botão |
as setas são colocadas consoante esteja aberto ou fechado |
--> |
<div class="col-md-1"> |
<a class="btn btn-xs" ng-class="{ |
'btn-default': !node.open, |
'btn-success': node.open, |
}" data-nodrag ng-click="openItem(node)"> |
<span |
class="glyphicon" |
ng-class="{ |
'glyphicon-chevron-right': !node.open, |
'glyphicon-chevron-down': node.open |
}"> |
</span> |
</a> |
<a ng-show="node.modified" class="pull-right btn btn-warning btn-xs" data-nodrag ng-click="updateItem(node)" style="margin-right: 8px;"> |
<span class="glyphicon glyphicon-floppy-disk"></span> |
</a> |
</div> |
<div class="col-md-8"> |
<div class="row"> |
<div class="form-group"> |
<div class="col-md-2"> |
<label class="control-label">Nome:</label> |
</div> |
<div class="col-md-10"> |
<input ng-model="node.name" type="text" class="form-control" data-nodrag ng-change="setModified(node)"> |
</div> |
</div> |
<div class="form-group"> |
<div class="col-md-2"> |
<label class="control-label">URL Antigos:</label> |
</div> |
<div class="col-md-10"> |
<input ng-model="node.legacyUrl" type="text" class="form-control" data-nodrag ng-change="setModified(node)"> |
</div> |
</div> |
</div> |
<span ng-if="node.nodrop">* No drop</span> <span ng-if="node.nodrag">* No drag</span> |
</div> |
<!--BOTOES DE REMOVE E NEW SUBITEMS CHAMAM FUNCOES DO SCOPE--> |
<div class="col-md-2"> |
<select ng-change="setModified(node)" class="chosenOff" ng-model="node.visible" ng-options="o.v as o.n for o in [{ n: 'Visivel', v: true }, { n: 'Invisivel', v: false }]"> |
</select> |
<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> |
</div> |
<!-- 1) UMA LISTA PARA O NODROP data-nodrop-enabled="true" 2) (EM BAIXO) OUTRA PARA OS QUE DEIXAM FAZER DROP DROP--> |
<ol ng-if="node.nodrop" ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.childs" ng-class="{hidden: collapsed, nodeEmpty: openedAndHasNotChilds(node) }"> |
<li ng-repeat="node in node.childs" ui-tree-node ng-include="'childs_renderer.html'"> |
</li> |
</ol> |
<!-- 2) LISTA DO DROP--> |
<ol ng-if="!node.nodrop" ui-tree-nodes="" ng-model="node.childs" ng-class="{hidden: collapsed, nodeEmpty: openedAndHasNotChilds(node) }"> |
<li ng-repeat="node in node.childs" ui-tree-node ng-include="'childs_renderer.html'"> |
</li> |
</ol> |
</script> |
<div class="panel panel-default"> |
<div class="panel-heading clearfix"> |
Administração de Coleções do Repositório de Documentos Digitais |
<baco:isAdmin> |
<button type="button" class="btn btn-success pull-right" ng-click="newRootItem()"><span class="glyphicon glyphicon-plus"></span> Nova Raiz</button> |
</baco:isAdmin> |
</div> |
<div class="panel-body"> |
<div class="web-messages"></div> |
<!-- E finalmente este é o unico codigo dos gajos que metem no HTML puro--> |
<div class="row"> |
<div class="col-sm-12 form-horizontal"> |
<div ui-tree="treeOptions" id="page-content-root"> |
<ol ui-tree-nodes ng-model="data"> |
<li ng-repeat="node in data" ui-tree-node ng-include="'childs_renderer.html'"></li> |
</ol> |
</div> |
</div> |
</div> |
<%-- <div class="col-sm-12"> |
<pre class="code">{{ data | json }}</pre> |
</div>--%> |
</div> |
</div> |
</div> |
<%--AbstractDao.getCurrentSession().getTransaction().commit();--%> |
</div> |
/branches/v3/impl/src/web/user/repositoryDocuments/repositoryDocument.jsp |
---|
98,10 → 98,21 |
"uploadedFiles" : JSON.stringify($scope.jsonFiles) |
}, |
"#repoModule", |
function(json){ |
function(json) |
{ |
$scope.doc = json; |
$scope.jsonFiles = {"service":"ok","uploadedFiles": [] }; |
$scope.$apply(); |
$("#savedOpenNew").show(); |
$("#docEditPanel").hide(); |
}); |
} |
$scope.backEdit = function() |
{ |
$("#savedOpenNew").hide(); |
$("#docEditPanel").show(); |
} |
//<!--Seccao de uploadedFiles--> |
114,15 → 125,59 |
for(var i in uploadedIncomingJson.uploadedFiles) |
{ |
var file = uploadedIncomingJson.uploadedFiles[i]; |
file.visible = true; |
file.accessControl = "resource.access.publicDomain"; |
angular.element($("#repoModule")).scope().jsonFiles.uploadedFiles.push(file); |
} |
angular.element($("#repoModule")).scope().$apply(); |
}); |
$("#DOCUMENT_FILES_RESULT").change(function() |
{ |
var uploadedIncomingJson = JSON.parse($("#DOCUMENT_FILES_RESULT").val()); |
var file = uploadedIncomingJson.uploadedFiles[0]; |
file.id = uploadedIncomingJson.token; |
//Find document remove it from documents List add to uploadFiles |
var doc = angular.element($("#repoModule")).scope().doc; |
for(var i in doc.repositoryDocumentFiles) |
{ |
if(doc.repositoryDocumentFiles[i].id == file.id) |
{ |
var repoDoc = doc.repositoryDocumentFiles[i]; |
doc.repositoryDocumentFiles.splice(i,1); |
file.title = repoDoc.title; |
file.visible = repoDoc.visible; |
file.description = repoDoc.description; |
file.accessControl = repoDoc.repositoryFileProxy.repositoryFile.accessControl; |
file.repositoryStream = repoDoc.repositoryFileProxy.repositoryStream; |
break; |
} |
} |
angular.element($("#repoModule")).scope().jsonFiles.uploadedFiles.push(file); |
angular.element($("#repoModule")).scope().$apply(); |
}); |
}); |
$scope.removeFileFromModel = function($index) |
{ |
$scope.jsonFiles.uploadedFiles.splice($index,1); |
} |
$scope.setDocumentFileInvisible = function(docFile) |
{ |
docFile.visible=false; |
docFile.repositoryFileProxy.repositoryFile.accessControl ="resource.access.privateDomain"; |
} |
$scope.setDocumentFileVisible = function(docFile) |
{ |
docFile.visible=true; |
alert("As permissões do ficheiro estão definidas como privadas, por favor escolha as permissões novas."); |
docFile.repositoryFileProxy.repositoryFile.accessControl ="resource.access.privateDomain"; |
} |
//<!--Seccao de uploadedFiles--> |
}); |
</script> |
132,13 → 187,36 |
ng-app="repoModule" |
ng-controller="repoModuleController" |
class="form-horizontal"> |
<div class="web-messages"></div> |
<div class="panel panel-default"> |
<div id="savedOpenNew" class="panel panel-default" style="display: none"> |
<div class="panel-body"> |
<div class="web-messages"></div> |
<hr/> |
<div class="row"> |
<div class="col-md-4"> |
<button class="btn btn-default btn-lg btn-block btn-huge" ng-click="backEdit()"><span class="glyphicon glyphicon-chevron-left"></span> Voltar à edição</button> |
</div> |
<div class="col-md-4"> |
<a class="btn btn-success btn-lg btn-block btn-huge" href="<%=request.getContextPath()%>/user/editRepositoryDoc.do">Adicionar outro documento <span class="glyphicon glyphicon-chevron-right"></span></a> |
</div> |
</div> |
<hr/> |
<div class="row"> |
<div class="col-md-4"> |
<a class="btn btn-danger btn-lg btn-block btn-huge" href="<%=request.getContextPath()%>/user/homePae.do">Sair</a> |
</div> |
</div> |
</div> |
</div> |
<div id="docEditPanel" class="panel panel-default"> |
<div class="panel-heading"> |
Criar um novo documento digital |
</div> |
<div class="panel-body"> |
<div class="web-messages"></div> |
<hr/> |
<input class="form-control" type="hidden" ng-model="doc.id"> |
<div class="form-group"> |
159,7 → 237,7 |
<div class="form-group"> |
<label class="col-md-2 control-label">Coleção</label> |
<div class="col-md-10"> |
<select ng-model="doc.collection.id" class="form-control chosenOff" ng-options="c.id as c.name for c in collections"></select> |
<select ng-model="doc.collection.id" class="form-control chosenOff" ng-options="c.id as c.pathName for c in collections"></select> |
</div> |
</div> |
268,44 → 346,73 |
<!--Seccao de DocumentFiles--> |
<div class="panel panel-default" ng-show="doc.repositoryDocumentFiles.length > 0"> |
<div class="panel-heading">Ficheiros Já Anexados</div> |
<div class="panel-body"> |
<input type="hidden" id="UPLOADED_FILES_RESULT" value=""/> |
<a class="btn btn-default" href="#" |
data-title="Importação para a pasta XPTO" |
data-toggle="modal" |
data-target="#filesUploadModal" |
data-multiple="false" |
data-jsontargetid="#UPLOADED_FILES_RESULT"> |
Carregar Ficheiros <span class="glyphicon glyphicon-upload"/> |
</a> |
<input type="hidden" id="DOCUMENT_FILES_RESULT" value=""/> |
<div class="list-group"> |
<div class="list-group-item clearfix" ng-repeat="df in doc.repositoryDocumentFiles"> |
<div> |
<div class="list-group clearfix" ng-repeat="f in doc.repositoryDocumentFiles" ng-class="{'bacoInvisible': f.visible == false}"> |
<div class="list-group-item clearfix"> |
<div class="col-md-10"> |
<img src="<%=request.getContextPath()%>/imgs/mime/{{ f.extension }}.gif"/> - {{ f.fileName }} {{ (f.fileSize / 1024)| number:0 }}KB |
<div class="col-md-10" > |
<label ng-show="f.visible == false"> |
<span class="glyphicon glyphicon-ban-circle"/> |
</label> |
<img src="<%=request.getContextPath()%>/imgs/mime/{{ f.repositoryFileProxy.repositoryFile.lastVersion.extension }}.gif"/> - {{ f.repositoryFileProxy.repositoryFile.lastVersion.name }} {{ (f.repositoryFileProxy.repositoryFile.lastVersion.size / 1024)| number:0 }}KB |
</div> |
<div class="col-md-2"> |
<button class="btn btn-danger" type="button" ng-click="removeFileFromModel($index)"><span class="glyphicon glyphicon-remove"/></button> |
<bacoTags:repositoryFile staticTag="true" transactional="true" repositoryStream="{{f.repositoryFileProxy.repositoryStream}}"/> |
<button data-toggle="tooltip" title="Ocultar ficheiro" ng-show="f.visible == true" class="btn btn-danger pull-right" type="button" ng-click="setDocumentFileInvisible(f)"><span class="glyphicon glyphicon-ban-circle"/></button> |
<button data-toggle="tooltip" title="Repor ficheiro" ng-show="f.visible == false" class="btn btn-default pull-right" type="button" ng-click="setDocumentFileVisible(f)"><span class="glyphicon glyphicon-ok-circle"/></button> |
<a ng-disabled="f.visible == false" data-toggle="tooltip" title="Substituir ficheiro" class="btn btn-default pull-right" href="#" style="margin-right: 20px" |
data-title="Alteração do Ficheiro {{f.repositoryFileProxy.repositoryFile.lastVersion.name}}" |
data-toggle="modal" |
data-target="#filesUploadModal" |
data-multiple="false" |
data-token="{{f.id}}" |
data-showmetafields="false" |
data-jsontargetid="#DOCUMENT_FILES_RESULT"> |
<span class="glyphicon glyphicon-pencil"/> |
</a> |
</div> |
<div class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Controlo de Acesso:</div> |
<div class="col-md-6 control-label"> |
<select ng-disabled="f.visible == false" class="form-control chosenOff" type="text" ng-model="f.repositoryFileProxy.repositoryFile.accessControl" ng-options="o.v as o.n for o in [{ n: 'Publico', v: 'resource.access.publicDomain' }, { n: 'Privado', v: 'resource.access.privateDomain' }, { n: 'Interno', v: 'resource.access.authenticatedDomain' }]">> |
</select> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Visivel:</div> |
<div class="col-md-6 control-label"> |
<select ng-disabled="f.visible == false" class="form-control chosenOff" type="text" ng-model="f.visible" ng-options="o.v as o.n for o in [{ n: 'Sim', v: true }, { n: 'Não', v: false }]">> |
</select> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Titulo:</div> |
<div class="col-md-10 control-label"> |
<input type="text" class="form-control" ng-model="f.title"/> |
<input ng-disabled="f.visible == false" type="text" class="form-control" ng-model="f.title"/> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div class="col-md-2 control-label">Descrição:</div> |
<div class="col-md-10 control-label"> |
<textarea rows="3" class="form-control" ng-model="f.description"></textarea> |
<textarea ng-disabled="f.visible == false" rows="3" class="form-control" ng-model="f.description"></textarea> |
</div> |
</div> |
</div> |
326,20 → 433,21 |
<input type="hidden" id="UPLOADED_FILES_RESULT" value=""/> |
<a class="btn btn-default" href="#" |
data-title="Importação para a pasta XPTO" |
data-title="Importação de Ficheiros" |
data-toggle="modal" |
data-target="#filesUploadModal" |
data-multiple="false" |
data-multiple="true" |
data-jsontargetid="#UPLOADED_FILES_RESULT"> |
Carregar Ficheiros <span class="glyphicon glyphicon-upload"/> |
</a> |
<div ng-show="jsonFiles.uploadedFiles.length > 0"> |
<h2>Ficheiros Carregados Provisórios</h2> |
<div class="list-group"> |
<div class="list-group-item clearfix" ng-repeat="f in jsonFiles.uploadedFiles"> |
<div> |
<div class="list-group clearfix" ng-repeat="f in jsonFiles.uploadedFiles" > |
<div class="list-group-item clearfix"> |
<div class="col-md-10"> |
<div class="col-md-10" ng-class="{'alert-warning': f.id}"> |
<img src="<%=request.getContextPath()%>/imgs/mime/{{ f.extension }}.gif"/> - {{ f.fileName }} {{ (f.fileSize / 1024)| number:0 }}KB |
</div> |
<div class="col-md-2"> |
347,6 → 455,22 |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Controlo de Acesso:</div> |
<div class="col-md-6 control-label"> |
<select class="form-control chosenOff" type="text" ng-model="f.accessControl" ng-options="o.v as o.n for o in [{ n: 'Publico', v: 'resource.access.publicDomain' }, { n: 'Privado', v: 'resource.access.privateDomain' }, { n: 'Interno', v: 'resource.access.authenticatedDomain' }]">> |
</select> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Visivel:</div> |
<div class="col-md-6 control-label"> |
<select class="form-control chosenOff" type="text" ng-model="f.visible" ng-options="o.v as o.n for o in [{ n: 'Sim', v: true }, { n: 'Não', v: false }]">> |
</select> |
</div> |
</div> |
<div class="list-group-item clearfix"> |
<div class=" col-md-2 control-label">Titulo:</div> |
<div class="col-md-10 control-label"> |
<input type="text" class="form-control" ng-model="f.title"/> |
366,14 → 490,24 |
<!--Seccao de uploadedFiles--> |
<div class="row"> |
<div class="col-md-6"><button class="btn btn-success" ng-click="submitForm()">Salvar</button></div> |
<div class="col-md-6"><a class="btn btn-danger" href="<%=request.getContextPath()%>/user/homePae.do">Cancelar</a></div> |
</div> |
<button class="btn btn-success" ng-click="submitForm()">Salvar</button> |
</div> |
</div> |
<%-- |
<pre> |
{{doc | json}} |
</pre> |
<pre> |
{{jsonFiles | json}} |
</pre>--%> |
</div> |
<% |
/branches/v3/impl/src/web/user/repositoryDocuments/collectionsInterface.jsp |
---|
New file |
0,0 → 1,180 |
<%@ page import="jomm.dao.impl.AbstractDao" %> |
<%@ page import="org.hibernate.Criteria" %> |
<%@ page import="org.hibernate.criterion.Criterion" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocument" %> |
<%@ page import="pt.estgp.estgweb.web.controllers.repositorydocs.interfaces.InterfaceBlock" %> |
<%@ page import="pt.estgp.estgweb.web.controllers.repositorydocs.interfaces.InterfaceConfiguration" %> |
<%@ page import="java.util.List" %> |
<%@ page import="static org.hibernate.criterion.Restrictions.eq" %> |
<%@ page import="static org.hibernate.criterion.Restrictions.or" %> |
<%@ page import="org.hibernate.criterion.Order" %> |
<%@ taglib uri="/WEB-INF/tlds/struts-html.tld" prefix="html" %> |
<%@ taglib uri="/WEB-INF/tlds/struts-nested.tld" prefix="nested" %> |
<%@ taglib uri="/WEB-INF/tlds/struts-logic.tld" prefix="logic" %> |
<%@ taglib uri="/WEB-INF/tlds/struts-bean.tld" prefix="bean" %> |
<%@ taglib uri="/WEB-INF/tlds/struts-tiles.tld" prefix="tiles" %> |
<%@ taglib tagdir="/WEB-INF/tags" prefix="bacoTags" %> |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> |
<% |
String configuration = request.getParameter("configuration"); |
InterfaceConfiguration interfaceConfiguration = new InterfaceConfiguration(); |
interfaceConfiguration.setTitle("Regulamentação Interna"); |
interfaceConfiguration.setDescription("Descrição Geral"); |
InterfaceBlock interfaceBlock1 = new InterfaceBlock(); |
InterfaceBlock interfaceBlock2 = new InterfaceBlock(); |
interfaceConfiguration.getBlocks().add(interfaceBlock1); |
interfaceConfiguration.getBlocks().add(interfaceBlock2); |
interfaceBlock1.setTitle("bloco1"); |
interfaceBlock2.setTitle("bloco2"); |
interfaceBlock1.setDescription("bloco1desc"); |
interfaceBlock2.setDescription("bloco1desc"); |
interfaceBlock1.getCollectionId().add(new Long(1)); |
interfaceBlock1.getCollectionId().add(new Long(2)); |
interfaceBlock2.getCollectionId().add(new Long(3)); |
interfaceBlock2.getCollectionId().add(new Long(4)); |
InterfaceConfiguration loadedConfig = InterfaceConfiguration.loadFromJson(interfaceConfiguration.toJson()); |
int columns = 12 / interfaceConfiguration.getBlocks().size(); |
request.setAttribute("loadedConfig",loadedConfig); |
request.setAttribute("columns","" + columns); |
AbstractDao.getCurrentSession().beginTransaction(); |
%> |
<style> |
body |
{ |
background-color: white !important; |
} |
#repositoryInterface .section .title |
{ |
padding:20px; |
background-color: #fffef9; |
font-family: 'Roboto', sans-serif; |
font-size: 2.2em; |
} |
#repositoryInterface .section .section .title |
{ |
padding:10px; |
background-color: #fffef9; |
font-family: 'Roboto', sans-serif; |
font-size: 1.4em; |
} |
#repositoryInterface .section .description |
{ |
padding:20px; |
background-color: #e1e1df; |
} |
#repositoryInterface .section .content |
{ |
margin-top: 10px; |
} |
#repositoryInterface .section .item |
{ |
border: 1px dashed gray; |
} |
#repositoryInterface .section .item .title |
{ |
padding:5px; |
font-size: 0.9em; |
} |
#repositoryInterface .section .item .description |
{ |
padding:5px; |
font-size: 0.9em; |
border: 1px dashed #cfcfcf; |
} |
#repositoryInterface .section .item .description |
{ |
font-size: 0.8em; |
background-color: #ededeb; |
padding: 5px; |
} |
#repositoryInterface a |
{ |
color: #C79E00 !important; |
} |
</style> |
<div id="repositoryInterface"> |
<div class="section"> |
<div class="title"> |
${loadedConfig.title} |
</div> |
<div class="description"> |
${loadedConfig.description} |
</div> |
<div class="content row"> |
<logic:iterate id="block" name="loadedConfig" property="blocks" type="pt.estgp.estgweb.web.controllers.repositorydocs.interfaces.InterfaceBlock"> |
<div class="col-md-${columns}"> |
<div class="panel panel-default"> |
<div class="panel-body section"> |
<div class="title"> |
${block.title} |
</div> |
<div class="description"> |
${block.description} |
</div> |
<% |
List<Long> collections = block.getCollectionId(); |
Criteria c = AbstractDao.getCurrentSession().createCriteria(RepositoryDocument.class); |
RepositoryDocument d; |
Criterion clauses = null; |
for(Long collection : collections) |
{ |
if(clauses == null) |
clauses = eq("collection.id",collection); |
else |
{ |
clauses = or(clauses,eq("collection.id",collection)); |
} |
} |
c.add(clauses); |
c.add(eq("visible",true)); |
c.addOrder(Order.desc("publishDate")); |
List<RepositoryDocument> documents = c.list(); |
request.setAttribute("documents",documents); |
%> |
<logic:iterate id="doc" name="documents" type="pt.estgp.estgweb.domain.RepositoryDocument"> |
<hr/> |
<div class="item"> |
<div class="title"> |
${doc.title} |
<span class="badge pull-right"> |
${doc.publishDate} |
</span> |
</div> |
<div class="description">${doc.description}</div> |
<div class="list-group" style="width: 100%"> |
<logic:iterate id="docFile" name="doc" property="repositoryDocumentFiles" type="pt.estgp.estgweb.domain.RepositoryDocumentFile"> |
<logic:equal value="true" name="docFile" property="visible"> |
<div class="list-group-item" style="width: 100%"> |
<bacoTags:repositoryFile transactional="true" showHistory="false" iconClasses="pull-right" repositoryStream="${docFile.repositoryFileProxy.repositoryStream}" label="${docFile.repositoryFileProxy.repositoryFile.lastVersion.name}"/> |
</div> |
</logic:equal> |
</logic:iterate> |
</div> |
</div> |
</logic:iterate> |
</div> |
</div> |
</div> |
</logic:iterate> |
</div> |
</div> |
</div> |
<% |
AbstractDao.getCurrentSession().getTransaction().commit(); |
%> |
/branches/v3/impl/src/web/user/repositoryDocuments/topnavRepocolbrowser.jsp |
---|
New file |
0,0 → 1,11 |
<%@page contentType="text/html"%> |
<%@page pageEncoding="UTF-8"%> |
<%@page import="jomm.web.utils.NavPlaceServer"%> |
<%@ page import="jomm.web.utils.TopNav" %> |
<% |
TopNav topNav = NavPlaceServer.getInstance().createTopNav(request); |
topNav.addNavPlace("/user/homePae.do", "intranet.separator.home.back"); |
topNav.addNavPlace(null, "repositorycolbrowser"); |
%> |
<jsp:include page="/layout/topnav.jsp"/> |
/branches/v3/impl/src/web/user/repositoryDocuments/topnavEditRepocol.jsp |
---|
New file |
0,0 → 1,11 |
<%@page contentType="text/html"%> |
<%@page pageEncoding="UTF-8"%> |
<%@page import="jomm.web.utils.NavPlaceServer"%> |
<%@ page import="jomm.web.utils.TopNav" %> |
<% |
TopNav topNav = NavPlaceServer.getInstance().createTopNav(request); |
topNav.addNavPlace("/user/homePae.do", "intranet.separator.home.back"); |
topNav.addNavPlace(null, "repositorycol"); |
%> |
<jsp:include page="/layout/topnav.jsp"/> |
/branches/v3/impl/src/web/user/repositoryDocuments/collectionsbrowser.jsp |
---|
New file |
0,0 → 1,411 |
<%@ page import="jomm.dao.impl.AbstractDao" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocumentCollection" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocumentCollectionImpl" %> |
<%@ page import="pt.estgp.estgweb.domain.RepositoryDocumentImpl" %> |
<%@ page import="pt.estgp.estgweb.domain.dao.DaoFactory" %> |
<%@ page import="java.util.List" %> |
<%@ page import="pt.utl.ist.berserk.logic.serviceManager.IServiceManager" %> |
<%@ page import="pt.utl.ist.berserk.logic.serviceManager.ServiceManager" %> |
<%@ page import="org.json.JSONArray" %> |
<%@ page import="pt.estgp.estgweb.web.utils.RequestUtils" %> |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> |
<%@ taglib prefix="bacoTags" tagdir="/WEB-INF/tags" %> |
<%@ taglib prefix="logic" uri="/WEB-INF/tlds/struts-logic.tld" %> |
<%@ taglib prefix="baco" uri="/WEB-INF/tlds/baco.tld" %> |
<style> |
.btn { |
margin-right: 8px; |
} |
.tree-node,.angular-ui-tree-handle { |
background: #f8faff; |
border: 1px solid #dae2ea; |
color: #7c9eb2; |
padding: 10px 10px; |
} |
.ui-tree-node |
{ |
padding: 10px; |
} |
.angular-ui-tree-handle:hover { |
color: #438eb9; |
background: #f4f6f7; |
border-color: #dce2e8; |
} |
.angular-ui-tree-placeholder { |
background: #f0f9ff; |
border: 2px dashed #bed2db; |
-webkit-box-sizing: border-box; |
-moz-box-sizing: border-box; |
box-sizing: border-box; |
} |
.nodeEmpty { |
height: 50px; |
margin:10px; |
margin-left: 30px; |
border: 1px dashed blue; |
} |
.group-title { |
background-color: #687074 !important; |
color: #FFF !important; |
} |
/* --- Tree --- */ |
.tree-node { |
border: 1px solid #dae2ea; |
background: #f8faff; |
color: #7c9eb2; |
} |
.tree-node-document { |
border: 1px solid #9fea91; |
background: #e8ffdb; |
color: #0cb229; |
} |
.tree-node-file { |
border: 1px solid #e8ea99; |
background: #fffae7; |
color: #b2a418; |
} |
.tree-node-description { |
border: 1px dashed #7f7f7e; |
background: #e5e5e3; |
color: #0d0c01; |
} |
.nodrop { |
background-color: #f2dede; |
} |
.nodrag { |
background-color: #f2eec1; |
} |
.tree-node-content { |
margin: 10px; |
} |
/*Estilo adicionado por mim para os movidos*/ |
.moved |
{ |
border: 2px solid blue !important; |
} |
.modified |
{ |
border: 4px dashed orange !important; |
} |
</style> |
<div class="container-fluid"> |
<% |
IServiceManager sm = ServiceManager.getInstance(); |
String[] names = new String[]{}; |
Object[] args = new Object[]{null}; |
JSONArray roots = (JSONArray) sm.execute(RequestUtils.getRequester(request, response), "OpenRepositoryCollection", args, names); |
AbstractDao.getCurrentSession().beginTransaction(); |
String collectionsJson = roots.toString(); |
request.setAttribute("collectionsJson", collectionsJson); |
%> |
<div id="treeAppPageContent" ng-app="treeAppPageContent" ng-controller="treeAppPageContentController"> |
<script> |
ping(); |
var treeAppPageContent = angular.module('treeAppPageContent', ['ui.tree']); |
GLOBAL_BacoAngularAppDependencies.push('treeAppPageContent'); |
<!-- estes codigos todos do remove e do toggle e etc's não mechi em nada limitei-me a copiar dos gajos--> |
treeAppPageContent.controller('treeAppPageContentController', function ($scope) { |
$scope.data = ${collectionsJson}; |
/* |
$scope.data = [ |
{ |
"id" : 1, |
"name" : "Nao deixa fazer drag", |
"nodrag" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 2, |
"name" : "Nao deixa fazer drop", |
"nodrop" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 3, |
"name" : "Deixa fazer Tudo", |
"isDirectory" : true |
}, |
{ |
"id" : 4, |
"name" : "Deixa fazer Tudo e ja foi movido", |
"moved" : true, |
"isDirectory" : true |
}, |
{ |
"id" : 5, |
"name" : "Exemplo de folha nao deixa abrir", |
"isDirectory" : false |
} |
];*/ |
$scope.treeOptions = { |
accept: function(sourceNodeScope, destNodesScope, destIndex) { |
return true; |
}, |
dropped: function(e) { |
//console.log (e.source.nodeScope.$modelValue); |
//alert ("Largado o nó com nome: " + e.source.nodeScope.$modelValue.name + " sobre " + e.dest.nodesScope.$parent.$modelValue.name); |
} |
}; |
$scope.openedAndHasNotChilds = function(node) |
{ |
if(node.childs == null) |
return false; |
return node.childs.length == 0; |
} |
$scope.openItem = function(item) |
{ |
//apenas deixa abrir neste caso |
if(item.open && item.open==true) |
{ |
item.open=false; |
delete item.childs; |
delete item.documents; |
} |
else |
{ |
widgetCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"openRepositoryCollection", |
{ |
"id" : item.id |
}, |
"#treeAppPageContent", |
function(json) |
{ |
item.childs = json.collections; |
item.open = true; |
$scope.$apply(); |
}); |
widgetCallWithActionParameters( |
"<%=request.getContextPath()%>/user/repositoryDoc.do", |
"openRepositoryCollectionDocuments", |
{ |
"id" : item.id |
}, |
"#treeAppPageContent", |
function(json) |
{ |
item.documents = json.documents; |
item.open = true; |
$scope.$apply(); |
$('#treeAppPageContent [data-toggle="tooltip"]').tooltip(); |
}); |
} |
} |
$scope.openDocumentsItem = function(item) |
{ |
var collapseElement = $("#repositoryFiles" + item.id); |
if(item.open && item.open==true) |
{ |
item.open=false; |
collapseElement.collapse("hide"); |
} |
else |
{ |
item.open=true; |
collapseElement.collapse("show"); |
} |
} |
} |
); |
</script> |
<!--TEMPLATE RECURSIVO--> |
<script type="text/ng-template" id="childs_renderer.html"> |
<!--Para nao deixar fazer drag--> |
<div data-nodrag class="tree-node tree-node-content clearfix" ng-class="{modified: node.modified, nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved, bacoInvisible: !node.visible}"> |
<div class="col-md-1"> |
<a class="btn btn-xs" ng-class="{ |
'btn-default': !node.open, |
'btn-success': node.open, |
}" |
data-nodrag ng-click="openItem(node)"> |
<span |
class="glyphicon" |
ng-class="{ |
'glyphicon-chevron-right': !node.open, |
'glyphicon-chevron-down': node.open |
}"> |
</span> |
</a> |
</div> |
{{node.name}} |
</div> |
<ol data-nodrag ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.childs" ng-class="{hidden: collapsed }"> |
<li ng-repeat="node in node.childs" ui-tree-node ng-include="'childs_renderer.html'"> |
</li> |
</ol> |
<ol data-nodrag ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.documents" ng-class="{hidden: collapsed"> |
<li ng-repeat="node in node.documents" ui-tree-node ng-include="'documents_renderer.html'"> |
</li> |
</ol> |
</script> |
<!--TEMPLATE RECURSIVO--> |
<script type="text/ng-template" id="documents_renderer.html"> |
<!--Para nao deixar fazer drag--> |
<div data-nodrag class="tree-node tree-node-document tree-node-content clearfix" ng-class="{modified: node.modified, nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved, bacoInvisible: !node.visible}"> |
<a class="btn btn-xs" ng-class="{ |
'btn-default': !node.open, |
'btn-success': node.open, |
}" |
data-nodrag data-toggle="collapse" ng-click="openDocumentsItem(node)"> |
<span |
class="glyphicon" |
ng-class="{ |
'glyphicon-chevron-right': !node.open, |
'glyphicon-chevron-down': node.open |
}"> |
</span> |
</a> |
<span class="glyphicon glyphicon-file"></span> {{node.title}} |
<baco:hasRole role="admin,all,repositoryDocs"> |
<a target="_blank" class="pull-right btn btn-warning btn-xs" href="<%=request.getContextPath()%>/user/editRepositoryDoc.do?repositoryDocumentId={{node.id}}"> |
<span class="glyphicon glyphicon-pencil"></span> |
</a> |
</baco:hasRole> |
</div> |
<div id="repositoryFiles{{node.id}}" class="collapse"> |
<ol data-nodrag ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.repositoryDocumentFiles" ng-class="{hidden: collapsed }"> |
<li ui-tree-node> |
<div data-nodrag class="tree-node tree-node-description tree-node-content clearfix"> |
<div ng-if="node.description" class="panel panel-default"> |
<div class="panel-body"> |
<span class="label label-primary">Descrição:</span>{{node.description}} |
</div> |
</div> |
<div ng-if="node.internalIdentifier"> |
<span class="label label-primary">ID INTERNO:</span> |
<label > |
{{node.internalIdentifier}} |
</label> |
</div> |
<div ng-if="node.publishDateStr"> |
<span class="label label-primary">Data de Publicação:</span> |
<label > |
{{node.publishDateStr}} |
</label> |
</div> |
<div ng-if="node.authorsJson.persons"> |
<span class="label label-primary">Autores:</span> |
<label ng-repeat="autor in node.authorsJson.persons"> |
{{autor.firstNames}} {{autor.lastName}} |
</label> |
</div> |
<div ng-if="node.contributorsJson.persons"> |
<span class="label label-primary">Colaboradores:</span> |
<label ng-repeat="autor in node.contributorsJson.persons"> |
{{autor.firstNames}} {{autor.lastName}} ; |
</label> |
</div> |
</div> |
</li> |
<li ng-repeat="node in node.repositoryDocumentFiles" ui-tree-node ng-include="'files_renderer.html'"> |
</li> |
</ol> |
</div> |
</script> |
<script type="text/ng-template" id="files_renderer.html"> |
<!--Para nao deixar fazer drag--> |
<div data-nodrag class="tree-node tree-node-file tree-node-content clearfix" ng-class="{modified: node.modified, nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved, bacoInvisible: !node.visible}"> |
<label data-toggle="tooltip" title="Este ficheiro está oculto!" ng-show="node.visible == false"> |
<span class="glyphicon glyphicon-ban-circle"/> |
</label> |
<span class="glyphicon glyphicon-file"></span> <span ng-if="node.title"><i> {{node.title}} </i> - </span> {{node.repositoryFileProxy.repositoryFile.lastVersion.name}} |
</div> |
</script> |
<div class="panel panel-default"> |
<div class="panel-heading clearfix"> |
Administração de Coleções do Repositório de Documentos Digitais |
</div> |
<div class="panel-body"> |
<div class="web-messages"></div> |
<!-- E finalmente este é o unico codigo dos gajos que metem no HTML puro--> |
<div class="row"> |
<div class="col-sm-12 form-horizontal"> |
<div ui-tree="treeOptions" id="page-content-root"> |
<ol ui-tree-nodes ng-model="data"> |
<li ng-repeat="node in data" ui-tree-node ng-include="'childs_renderer.html'"></li> |
</ol> |
</div> |
</div> |
</div> |
<div class="col-sm-12"> |
<pre class="code">{{ data | json }}</pre> |
</div> |
</div> |
</div> |
</div> |
<%--AbstractDao.getCurrentSession().getTransaction().commit();--%> |
</div> |