azkaban-aplcache
Changes
src/java/azkaban/project/Project.java 198(+106 -92)
src/java/azkaban/user/Permission.java 12(+5 -7)
src/java/azkaban/utils/Utils.java 13(+13 -0)
src/web/css/azkaban.css 91(+81 -10)
src/web/js/azkaban.project.view.js 49(+49 -0)
Details
diff --git a/src/java/azkaban/project/FileProjectManager.java b/src/java/azkaban/project/FileProjectManager.java
index b26b3a1..84dea0d 100644
--- a/src/java/azkaban/project/FileProjectManager.java
+++ b/src/java/azkaban/project/FileProjectManager.java
@@ -3,6 +3,7 @@ package azkaban.project;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -87,15 +88,26 @@ public class FileProjectManager implements ProjectManager {
public List<Project> getProjects(User user) {
ArrayList<Project> array = new ArrayList<Project>();
for(Project project : projects.values()) {
- if (project.hasPermission(user, Type.READ)) {
+ Permission perm = project.getUserPermission(user);
+ if (perm.isPermissionSet(Type.ADMIN) || perm.isPermissionSet(Type.READ)) {
array.add(project);
}
}
return array;
}
- public Project getProject(String name, User user) {
- return projects.get(name);
+ public Project getProject(String name, User user) throws AccessControlException {
+ Project project = projects.get(name);
+ if (project != null) {
+ Permission perm = project.getUserPermission(user);
+ if (perm.isPermissionSet(Type.ADMIN) || perm.isPermissionSet(Type.READ)) {
+ return project;
+ }
+ else {
+ throw new AccessControlException("Permission denied. Do not have read access.");
+ }
+ }
+ return null;
}
@Override
src/java/azkaban/project/Project.java 198(+106 -92)
diff --git a/src/java/azkaban/project/Project.java b/src/java/azkaban/project/Project.java
index 2662fbd..12a4934 100644
--- a/src/java/azkaban/project/Project.java
+++ b/src/java/azkaban/project/Project.java
@@ -10,49 +10,60 @@ import azkaban.user.Permission.Type;
import azkaban.user.User;
public class Project {
- private final String name;
- private String description;
- private long createTimestamp;
- private long lastModifiedTimestamp;
- private String lastModifiedUser;
- private HashMap<String, Permission> userToPermission = new HashMap<String, Permission>();
-
- public Project(String name) {
- this.name = name;
- }
+ private final String name;
+ private String description;
+ private long createTimestamp;
+ private long lastModifiedTimestamp;
+ private String lastModifiedUser;
+ private HashMap<String, Permission> userToPermission = new HashMap<String, Permission>();
+
+ public Project(String name) {
+ this.name = name;
+ }
public String getName() {
- return name;
- }
-
+ return name;
+ }
+
public boolean hasPermission(User user, Type type) {
Permission perm = userToPermission.get(user.getUserId());
if (perm == null) {
return false;
}
-
+
if (perm.isPermissionSet(Type.ADMIN) || perm.isPermissionSet(type)) {
return true;
}
return false;
}
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setUserPermission(String userid, Permission perm) {
- userToPermission.put(userid, perm);
- }
-
- public Permission getUserPermission(User user) {
- return userToPermission.get(user.getUserId());
- }
+
+ public List<String> getUsersWithPermission(Type type) {
+ ArrayList<String> users = new ArrayList<String>();
+ for (Map.Entry<String, Permission> entry : userToPermission.entrySet()) {
+ Permission perm = entry.getValue();
+ if (perm.isPermissionSet(type)) {
+ users.add(entry.getKey());
+ }
+ }
+ return users;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setUserPermission(String userid, Permission perm) {
+ userToPermission.put(userid, perm);
+ }
+
+ public Permission getUserPermission(User user) {
+ return userToPermission.get(user.getUserId());
+ }
public long getCreateTimestamp() {
return createTimestamp;
@@ -69,67 +80,70 @@ public class Project {
public void setLastModifiedTimestamp(long lastModifiedTimestamp) {
this.lastModifiedTimestamp = lastModifiedTimestamp;
}
-
- public Object toObject() {
- HashMap<String,Object> projectObject = new HashMap<String, Object>();
- projectObject.put("name", name);
- projectObject.put("description", description);
- projectObject.put("createTimestamp", createTimestamp);
- projectObject.put("lastModifiedTimestamp",lastModifiedTimestamp);
- projectObject.put("lastModifiedUser", lastModifiedUser);
-
- ArrayList<Map<String,Object>> users = new ArrayList<Map<String,Object>>();
- for (Map.Entry<String, Permission> entry: userToPermission.entrySet()) {
- HashMap<String,Object> userMap = new HashMap<String,Object>();
- userMap.put("userid", entry.getKey());
- userMap.put("permissions", entry.getValue().toStringArray());
- users.add(userMap);
- }
-
- projectObject.put("users", users);
- return projectObject;
- }
-
- @SuppressWarnings("unchecked")
+
+ public Object toObject() {
+ HashMap<String, Object> projectObject = new HashMap<String, Object>();
+ projectObject.put("name", name);
+ projectObject.put("description", description);
+ projectObject.put("createTimestamp", createTimestamp);
+ projectObject.put("lastModifiedTimestamp", lastModifiedTimestamp);
+ projectObject.put("lastModifiedUser", lastModifiedUser);
+
+ ArrayList<Map<String, Object>> users = new ArrayList<Map<String, Object>>();
+ for (Map.Entry<String, Permission> entry : userToPermission.entrySet()) {
+ HashMap<String, Object> userMap = new HashMap<String, Object>();
+ userMap.put("userid", entry.getKey());
+ userMap.put("permissions", entry.getValue().toStringArray());
+ users.add(userMap);
+ }
+
+ projectObject.put("users", users);
+ return projectObject;
+ }
+
+ @SuppressWarnings("unchecked")
public static Project projectFromObject(Object object) {
- Map<String,Object> projectObject = (Map<String,Object>)object;
- String name = (String)projectObject.get("name");
- String description = (String)projectObject.get("description");
- String lastModifiedUser = (String)projectObject.get("lastModifiedUser");
- long createTimestamp = coerceToLong(projectObject.get("createTimestamp"));
- long lastModifiedTimestamp = coerceToLong(projectObject.get("lastModifiedTimestamp"));
-
- Project project = new Project(name);
- project.setDescription(description);
- project.setCreateTimestamp(createTimestamp);
- project.setLastModifiedTimestamp(lastModifiedTimestamp);
- project.setLastModifiedUser(lastModifiedUser);
-
- List<Map<String,Object>> users = (List<Map<String,Object>>)projectObject.get("users");
-
- for (Map<String, Object> user: users) {
- String userid = (String)user.get("userid");
- Permission perm = new Permission();
- List<String> list = (List<String>)user.get("permissions");
- perm.setPermissionsByName(list);
-
- project.setUserPermission(userid, perm);
- }
-
- return project;
- }
-
- private static long coerceToLong(Object obj) {
- if (obj == null) {
- return 0;
- }
- else if (obj instanceof Integer) {
- return (Integer)obj;
- }
-
- return (Long)obj;
- }
-
+ Map<String, Object> projectObject = (Map<String, Object>) object;
+ String name = (String) projectObject.get("name");
+ String description = (String) projectObject.get("description");
+ String lastModifiedUser = (String) projectObject
+ .get("lastModifiedUser");
+ long createTimestamp = coerceToLong(projectObject
+ .get("createTimestamp"));
+ long lastModifiedTimestamp = coerceToLong(projectObject
+ .get("lastModifiedTimestamp"));
+
+ Project project = new Project(name);
+ project.setDescription(description);
+ project.setCreateTimestamp(createTimestamp);
+ project.setLastModifiedTimestamp(lastModifiedTimestamp);
+ project.setLastModifiedUser(lastModifiedUser);
+
+ List<Map<String, Object>> users = (List<Map<String, Object>>) projectObject
+ .get("users");
+
+ for (Map<String, Object> user : users) {
+ String userid = (String) user.get("userid");
+ Permission perm = new Permission();
+ List<String> list = (List<String>) user.get("permissions");
+ perm.setPermissionsByName(list);
+
+ project.setUserPermission(userid, perm);
+ }
+
+ return project;
+ }
+
+ private static long coerceToLong(Object obj) {
+ if (obj == null) {
+ return 0;
+ } else if (obj instanceof Integer) {
+ return (Integer) obj;
+ }
+
+ return (Long) obj;
+ }
+
public String getLastModifiedUser() {
return lastModifiedUser;
}
@@ -137,8 +151,8 @@ public class Project {
public void setLastModifiedUser(String lastModifiedUser) {
this.lastModifiedUser = lastModifiedUser;
}
-
- @Override
+
+ @Override
public int hashCode() {
final int prime = 31;
int result = 1;
diff --git a/src/java/azkaban/project/ProjectManager.java b/src/java/azkaban/project/ProjectManager.java
index 73fda78..890363c 100644
--- a/src/java/azkaban/project/ProjectManager.java
+++ b/src/java/azkaban/project/ProjectManager.java
@@ -1,5 +1,6 @@
package azkaban.project;
+import java.security.AccessControlException;
import java.util.List;
import azkaban.user.User;
@@ -10,7 +11,7 @@ public interface ProjectManager {
public List<Project> getProjects(User user);
- public Project getProject(String name, User user);
+ public Project getProject(String name, User user) throws AccessControlException;
public Project createProjects(String projectName, String description, User creator) throws ProjectManagerException;
diff --git a/src/java/azkaban/project/ProjectManagerException.java b/src/java/azkaban/project/ProjectManagerException.java
index fe16a8c..a7b3575 100644
--- a/src/java/azkaban/project/ProjectManagerException.java
+++ b/src/java/azkaban/project/ProjectManagerException.java
@@ -2,6 +2,9 @@ package azkaban.project;
public class ProjectManagerException extends Exception{
private static final long serialVersionUID = 1L;
+ public enum Type {
+
+ }
public ProjectManagerException(String message) {
super(message);
src/java/azkaban/user/Permission.java 12(+5 -7)
diff --git a/src/java/azkaban/user/Permission.java b/src/java/azkaban/user/Permission.java
index b816b65..df4adac 100644
--- a/src/java/azkaban/user/Permission.java
+++ b/src/java/azkaban/user/Permission.java
@@ -2,9 +2,12 @@ package azkaban.user;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import azkaban.utils.Utils;
+
public class Permission {
public enum Type {
READ,
@@ -83,17 +86,12 @@ public class Permission {
list.add(type.toString());
count++;
}
+
return list.toArray(new String[count]);
}
public String toString() {
- StringBuffer buffer = new StringBuffer();
- for (Type perm: permissions) {
- buffer.append(perm.toString());
- buffer.append(",");
- }
-
- return buffer.toString();
+ return Utils.flattenToString(permissions, ",");
}
@Override
src/java/azkaban/utils/Utils.java 13(+13 -0)
diff --git a/src/java/azkaban/utils/Utils.java b/src/java/azkaban/utils/Utils.java
index bfb0432..1d22bb7 100644
--- a/src/java/azkaban/utils/Utils.java
+++ b/src/java/azkaban/utils/Utils.java
@@ -24,6 +24,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.Random;
import java.util.zip.ZipEntry;
@@ -147,4 +148,16 @@ public class Utils {
}
}
+ public static String flattenToString(Collection<?> collection, String delimiter) {
+ StringBuffer buffer = new StringBuffer();
+ for (Object obj: collection) {
+ buffer.append(obj.toString());
+ buffer.append(',');
+ }
+
+ if (buffer.length() > 0) {
+ buffer.setLength(buffer.length() - 1);
+ }
+ return buffer.toString();
+ }
}
\ No newline at end of file
diff --git a/src/java/azkaban/webapp/AzkabanWebServer.java b/src/java/azkaban/webapp/AzkabanWebServer.java
index 599c376..89ead27 100644
--- a/src/java/azkaban/webapp/AzkabanWebServer.java
+++ b/src/java/azkaban/webapp/AzkabanWebServer.java
@@ -318,8 +318,16 @@ public class AzkabanWebServer {
Context root = new Context(server, "/", Context.SESSIONS);
root.setResourceBase(staticDir);
- root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
- root.addServlet(new ServletHolder(new IndexServlet()), "/index");
+ ServletHolder index = new ServletHolder(new IndexServlet());
+ root.addServlet(index, "/index");
+ root.addServlet(index, "/");
+
+ ServletHolder staticServlet = new ServletHolder(new DefaultServlet());
+ root.addServlet(staticServlet, "/css/*");
+ root.addServlet(staticServlet, "/js/*");
+ root.addServlet(staticServlet, "/images/*");
+ root.addServlet(staticServlet, "/favicon.ico");
+
root.addServlet(new ServletHolder(new ProjectManagerServlet()), "/manager");
root.setAttribute(AzkabanServletContextListener.AZKABAN_SERVLET_CONTEXT_KEY, app);
diff --git a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 028e519..960fa83 100644
--- a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -1,8 +1,15 @@
package azkaban.webapp.servlet;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.Writer;
+import java.security.AccessControlException;
import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipFile;
import javax.servlet.ServletConfig;
@@ -10,41 +17,87 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
+import azkaban.project.Project;
import azkaban.project.ProjectManager;
import azkaban.project.ProjectManagerException;
+import azkaban.user.Permission.Type;
import azkaban.user.User;
+import azkaban.utils.Utils;
import azkaban.webapp.session.Session;
+import azkaban.webapp.servlet.MultipartParser;
public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
private static final long serialVersionUID = 1;
private static final Logger logger = Logger.getLogger(ProjectManagerServlet.class);
-
+ private static final int DEFAULT_UPLOAD_DISK_SPOOL_SIZE = 20 * 1024 * 1024;
+
private ProjectManager manager;
+ private MultipartParser multipartParser;
+ private File tempDir;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
manager = this.getApplication().getProjectManager();
+ tempDir = this.getApplication().getTempDirectory();
+ multipartParser = new MultipartParser(DEFAULT_UPLOAD_DISK_SPOOL_SIZE);
}
@Override
protected void handleGet(HttpServletRequest req, HttpServletResponse resp,
Session session) throws ServletException, IOException {
Page page = newPage(req, resp, session, "azkaban/webapp/servlet/velocity/projectmanager.vm");
+ User user = session.getUser();
+ if ( hasParam(req, "project") ) {
+ String projectName = getParam(req, "project");
+ Project project = null;
+ try {
+ project = manager.getProject(projectName, user);
+ if (project == null) {
+ page.add("errorMsg", "Project " + projectName + " not found.");
+ }
+ else {
+ page.add("project", project);
+ page.add("admins", Utils.flattenToString(project.getUsersWithPermission(Type.ADMIN), ","));
+ page.add("permissions", project.getUserPermission(user));
+ }
+
+ }
+ catch (AccessControlException e) {
+ page.add("errorMsg", e.getMessage());
+ }
+
+ }
+ else {
+ page.add("errorMsg", "No project set.");
+ }
page.render();
}
@Override
protected void handlePost(HttpServletRequest req, HttpServletResponse resp,
Session session) throws ServletException, IOException {
- if (hasParam(req, "action")) {
+ if (ServletFileUpload.isMultipartContent(req)) {
+ logger.info("Post is multipart");
+ Map<String, Object> params = multipartParser.parseMultipart(req);
+ if (params.containsKey("action")) {
+ String action = (String)params.get("action");
+ if (action.equals("upload")) {
+ handleUpload(req, resp, params, session);
+ }
+ }
+ }
+ else if (hasParam(req, "action")) {
String action = getParam(req, "action");
if (action.equals("create")) {
handleCreate(req, resp, session);
- }
+ }
}
}
@@ -83,5 +136,51 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
e.printStackTrace();
}
}
+
+ private void handleUpload(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> multipart,
+ Session session) throws ServletException, IOException {
+
+ User user = session.getUser();
+ String projectName = (String) multipart.get("project");
+ FileItem item = (FileItem) multipart.get("file");
+ if (projectName == null || projectName.isEmpty()) {
+ setErrorMessageInCookie(resp, "No project name found.");
+ }
+ else if (item == null) {
+ setErrorMessageInCookie(resp, "No file found.");
+ }
+ else {
+ try {
+ File jobDir = extractFile(item);
+ } catch (Exception e) {
+ logger.info("Installation Failed.", e);
+ setErrorMessageInCookie(resp, "Installation Failed.");
+ }
+
+ resp.sendRedirect(req.getRequestURI() + "?project=" + projectName);
+ }
+ }
+
+ private File extractFile(FileItem item) throws IOException, ServletException {
+ final String contentType = item.getContentType();
+ if (contentType.startsWith("application/zip")) {
+ return unzipFile(item);
+ }
+
+ throw new ServletException(String.format("Unsupported file type[%s].", contentType));
+ }
+
+ private File unzipFile(FileItem item) throws ServletException, IOException {
+ File temp = File.createTempFile("job-temp", ".zip");
+ temp.deleteOnExit();
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(temp));
+ IOUtils.copy(item.getInputStream(), out);
+ out.close();
+ ZipFile zipfile = new ZipFile(temp);
+ File unzipped = Utils.createTempDir(tempDir);
+ Utils.unzip(zipfile, unzipped);
+ temp.delete();
+ return unzipped;
+ }
}
diff --git a/src/java/azkaban/webapp/servlet/velocity/projectmanager.vm b/src/java/azkaban/webapp/servlet/velocity/projectmanager.vm
index ee315b1..50bfc2f 100644
--- a/src/java/azkaban/webapp/servlet/velocity/projectmanager.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/projectmanager.vm
@@ -8,7 +8,7 @@
<script type="text/javascript" src="${context}/js/backbone-0.5.3-min.js"></script>
<script type="text/javascript" src="${context}/js/jquery.simplemodal.js"></script>
<script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
- <script type="text/javascript" src="${context}/js/azkaban.job.view.js"></script>
+ <script type="text/javascript" src="${context}/js/azkaban.project.view.js"></script>
<script type="text/javascript">
var contextURL = "${context}";
var currentTime = ${currentTime};
@@ -23,12 +23,64 @@
<div class="messaging"><p id="messageClose">X</p><p id="message"></p></div>
<div class="content">
- <div id="all-jobs-content">
- <div class="section-hd">
- <h2>Project</h2>
- </div><!-- end .section-hd -->
+ #if($errorMsg)
+ <div class="box-error-message">$errorMsg</div>
+ #else
+ <div id="all-jobs-content">
+ <div class="section-hd">
+ <h2>Project <span>$project.name</span></h2>
+
+ <a id="project-upload-btn" class="btn1 projectupload" href="#">Upload</a>
+ <a id="project-permission-btn" class="btn5 projectpermission" href="#">Permissions</a>
+ </div><!-- end .section-hd -->
+ </div>
+
+ <div id="project-users">
+ <table class="user-table">
+ <tr><td class="first">Project Admins:</td><td>$admins</td></tr>
+ <tr><td class="first">User ${user_id} Permissions:</td><td>$permissions.toString()</td></tr>
+ </table>
+ </div>
+ <div id="project-summary">
+ <table class="summary-table">
+ <tr><td class="first">Name:</td><td>$project.name</td></tr>
+ <tr><td class="first">Created Date:</td><td>$utils.formatDate($project.lastModifiedTimestamp)</td></tr>
+ <tr><td class="first">Modified Date:</td><td>$utils.formatDate($project.createTimestamp)</td></tr>
+ <tr><td class="first">Last Modified by:</td><td>$project.lastModifiedUser</td></tr>
+ <tr><td class="first">Description:</td><td>$project.description</td></tr>
+ </table>
+ </div>
+ #end
</div>
- <div class="content">
+
+ <div id="upload-project" class="modal">
+ <h3>Upload Project Files</h3>
+ <div id="errorMsg" class="box-error-message">$errorMsg</div>
+ <div class="message">
+ <form id="upload-form" enctype="multipart/form-data" method="post" action="$!context/manager">
+ <fieldset>
+ <dl>
+ <dt>Job Archive</dt>
+ <dd><input id="file" name="file" class="file" type="file" onChange="changeFile()" /></dd>
+ <input type="hidden" name="project" value="$project.name" />
+ <input type="hidden" name="action" value="upload" />
+ </dl>
+ </fieldset>
+ </form>
+
+ </div>
+ <div class="actions">
+ <a class="yes btn2" id="upload-btn" href="#">Upload</a>
+ <a class="no simplemodal-close btn3" href="#">Cancel</a>
+ </div>
+ </div>
+ <div id="invalid-session" class="modal">
+ <h3>Invalid Session</h3>
+ <p>Session has expired. Please re-login.</p>
+ <div class="actions">
+ <a class="yes btn2" id="login-btn" href="#">Re-login</a>
+ </div>
+ </div>
</body>
</html>
src/web/css/azkaban.css 91(+81 -10)
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index 9e44903..11ba190 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -132,6 +132,12 @@ textarea {
font-weight: bold;
}
+.section-hd h2 span{
+ padding-left: 5px;
+ font-weight: normal;
+ font-size: 90%;
+}
+
table {
background-color: #fff;
font-family: Arial;
@@ -229,7 +235,8 @@ tr:hover td {
.btn1,
.btn2,
.btn3,
-.btn4 {
+.btn4,
+.btn5 {
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
@@ -256,10 +263,16 @@ tr:hover td {
background: -webkit-gradient(linear, center top, center bottom, color-stop(0,#AFE47B), color-stop(5%,#8BD03F),color-stop(100%,#69B219));
}
-.section-hd .btn1,
.section-hd .btn4,
-.section-ft .btn1,
-.section-ft .btn4 {
+.section-hd .btn5,
+.section-ft .btn4,
+.section-ft .btn5{
+ float: right;
+ margin-right: 10px;
+}
+
+.section-hd .btn1,
+.section-ft .btn1 {
float: right;
margin-right: 25px;
}
@@ -296,6 +309,23 @@ tr:hover td {
display: inline-block;
font-weight: normal;
}
+
+/* grey right */
+.btn5 {
+ background: #CECECE;
+ background: -moz-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+ background: -o-linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#F2F2F2), color-stop(5%,#F2F2F2), color-stop(5%,#E4E4E4), color-stop(100%,#CECECE));
+ background: linear-gradient(top, #F2F2F2 0, #F2F2F2 1px, #E4E4E4 1px, #CECECE 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E4E4E4', endColorstr='#CECECE',GradientType=0 );
+ border-color: #999;
+ color: #666;
+}
+.btn5:hover {
+ background: -moz-linear-gradient(center top , white 0pt, #ECECEC 100%) repeat scroll 0 0 transparent;
+ background: -webkit-gradient(linear, center top, center bottom, from(#FFF), to(#ECECEC));
+}
+
/* confirm modal */
.modal {
display: none;
@@ -402,6 +432,8 @@ tr:hover td {
background-color: #fff;
border: 1px solid #9c9c9c;
border-radius: 10px;
+ -moz-border-radius: 10px;
+
overflow: hidden;
}
@@ -444,7 +476,7 @@ tr:hover td {
float: left;
padding: 0 10px 6px 0;
text-align: right;
- width: 80px;
+ width: 100px;
}
.modal dd {
@@ -452,11 +484,6 @@ tr:hover td {
padding-bottom: 6px;
}
-.modal dd input {
- float: left;
- padding-bottom: 6px;
-}
-
#create-project #overwrite {
width: 12px;
}
@@ -700,6 +727,50 @@ tr:hover td {
top: 20px;
}
+/*project manager page*/
+#project-summary {
+ margin-left: 30px;
+ margin-bottom: 10px;
+ width: 60%;
+}
+
+#project-users {
+ float: right;
+ margin-right: 30px;
+ margin-bottom: 10px;
+ width: 30%;
+}
+
+.summary-table {
+ font-size: 12px;
+ background: none;
+ border-style: none;
+ border-width: 0px;
+}
+.summary-table .first {
+ width: 100px;
+ font-weight: bold;
+}
+
+.summary-table td {
+ border-style: none;
+}
+
+.user-table {
+ font-size: 12px;
+ background: none;
+ border-style: none;
+ border-width: 0px;
+}
+.user-table .first {
+ width: 150px;
+ font-weight: bold;
+}
+
+.user-table td {
+ border-style: none;
+}
+
/* old styles */
.azkaban-charts .hitarea {
src/web/js/azkaban.project.view.js 49(+49 -0)
diff --git a/src/web/js/azkaban.project.view.js b/src/web/js/azkaban.project.view.js
new file mode 100644
index 0000000..3e51e2a
--- /dev/null
+++ b/src/web/js/azkaban.project.view.js
@@ -0,0 +1,49 @@
+$.namespace('azkaban');
+
+var projectView;
+azkaban.ProjectView= Backbone.View.extend({
+ events : {
+ "click #project-upload-btn":"handleUploadProjectJob"
+ },
+ initialize : function(settings) {
+
+ },
+ handleUploadProjectJob : function(evt) {
+ console.log("click upload project");
+ $('#upload-project').modal({
+ closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+ position: ["20%",],
+ containerId: 'confirm-container',
+ containerCss: {
+ 'height': '220px',
+ 'width': '565px'
+ },
+ onShow: function (dialog) {
+ var modal = this;
+ $("#errorMsg").hide();
+ }
+ });
+ },
+ render: function() {
+ }
+});
+
+var uploadProjectView;
+azkaban.UploadProjectView= Backbone.View.extend({
+ events : {
+ "click #upload-btn": "handleCreateProject"
+ },
+ initialize : function(settings) {
+ $("#errorMsg").hide();
+ },
+ handleCreateProject : function(evt) {
+ $("#upload-form").submit();
+ },
+ render: function() {
+ }
+});
+
+$(function() {
+ projectView = new azkaban.ProjectView({el:$( '#all-jobs-content'), successMsg: successMessage, errorMsg: errorMessage });
+ uploadView = new azkaban.UploadProjectView({el:$('#upload-project')});
+});