Subversion Repositories bacoAlunos

Compare Revisions

Ignore whitespace Rev 1674 → Rev 1675

/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>