Skip to content

Commit 62d8492

Browse files
committed
More work on the file input workflow (tabbed forms, updated backend).
There are now two input forms: "New Trace" and "Import Trace". They have similar UIs, and can be accessed by tabs on the page. Each form sends data to its own URL, handled by the TraceFileUploadHandler.
1 parent c43bb5a commit 62d8492

File tree

6 files changed

+168
-34
lines changed

6 files changed

+168
-34
lines changed

codepulse/src/main/resources/toserve/common/desktop.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
padding-bottom: 25px;
3333
}
3434

35+
.header-push {
36+
height: 60px;
37+
min-height: 60px;
38+
}
39+
40+
.footer-push {
41+
height: 25px;
42+
min-height: 25px;
43+
}
44+
3545
#footer .half {
3646
padding: 2px 5px;
3747
width: 50%;

codepulse/src/main/resources/toserve/pages/TraceInputForm/TraceInputForm.css

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,53 @@ trace-input-form .form-field {
4646
left: 0;
4747
}
4848

49+
#new-analysis-form:not(.active),
50+
#new-import-form:not(.active) {
51+
display: none;
52+
}
53+
54+
/***********\
55+
| Form Tabs |
56+
\***********/
57+
58+
#trace-input-form ul.form-tabs-list {
59+
list-style: none;
60+
margin: 0 0 20px 0;
61+
border-bottom: 1px solid lightgray;
62+
}
63+
64+
#trace-input-form .form-tab {
65+
display: inline-block;
66+
box-sizing: border-box;
67+
padding: 5px 10px;
68+
background-color: lightgray;
69+
cursor: pointer;
70+
position: relative;
71+
}
72+
73+
#trace-input-form .form-tab a {
74+
/* overriding bootstrap styles*/
75+
text-decoration: none;
76+
color: #323232;
77+
}
78+
79+
#trace-input-form .form-tab.active {
80+
background-color: steelblue;
81+
}
82+
83+
#trace-input-form .form-tab.active a {
84+
color: white;
85+
}
86+
87+
#trace-input-form .form-tab.active:after {
88+
content: '';
89+
position: absolute;
90+
top: 100%;
91+
left: calc(50% - 4px);
92+
border: 8px solid transparent;
93+
border-top-color: steelblue;
94+
}
95+
4996
/***************\
5097
| Feedback Area |
5198
\***************/

codepulse/src/main/resources/toserve/pages/TraceInputForm/TraceInputForm.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
$(document).ready(function(){
22

3-
// to be used in setup
4-
var uploadUrl = '/trace-api/file-upload'
3+
// wire up the new analysis form to submit to the trace creation url, with a mandatory name
4+
setupUploadForm($('#new-analysis-form'), '/trace-api/trace/create', false)
55

6-
setupUploadForm($('#new-analysis-form'), uploadUrl, false)
6+
// wire up the new import form to submit to the trace import url, with an optional name
7+
setupUploadForm($('#new-import-form'), '/trace-api/trace/import', true)
78

89
function setupUploadForm($form, uploadUrl, nameOptional){
910
/*

codepulse/src/main/scala/com/secdec/codepulse/tracer/TraceFileUploadHandler.scala

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import net.liftweb.common.Failure
3434
import com.secdec.codepulse.pages.traces.TraceDetailsPage
3535
import net.liftweb.http.JsonResponse
3636
import net.liftweb.json.JsonDSL._
37+
import net.liftweb.common.Box
38+
import com.secdec.codepulse.data.trace.TraceId
3739

3840
class TraceFileUploadHandler(traceManager: TraceManager) extends RestHelper {
3941

@@ -44,45 +46,54 @@ class TraceFileUploadHandler(traceManager: TraceManager) extends RestHelper {
4446

4547
object UploadPath {
4648
def unapply(path: List[String]) = path match {
47-
case "trace-api" :: "file-upload" :: tail => Some(tail)
49+
case "trace-api" :: "trace" :: method :: Nil => Some(method)
4850
case _ => None
4951
}
5052
}
5153

5254
serve {
53-
case UploadPath(Nil) Post req => serveFileUpload(req)
54-
}
55+
case UploadPath("create") Post req =>
56+
for {
57+
inputFile <- getReqFile(req) ?~! "Creating a new trace requires a file"
58+
if TraceUploadData.checkForBinaryZip(inputFile)
59+
name <- req.param("name") ?~ "You must specify a name"
60+
} yield {
61+
val traceId = TraceUploadData.handleBinaryZip(inputFile)
5562

56-
def serveFileUpload(req: Req): LiftResponse = req.uploadedFiles match {
57-
case List(upfile: OnDiskFileParamHolder) =>
58-
serveFileUpload(upfile.localFile)
63+
// set the new trace's name
64+
traceManager.getTrace(traceId) foreach {
65+
_.traceData.metadata.name = name
66+
}
5967

60-
case Nil => req.param("path").toOption match {
61-
case None => BadResponse()
62-
case Some(path) =>
63-
val file = new File(path)
64-
println(s"Not actually uploading: analyzing file $file")
65-
serveFileUpload(file)
66-
}
67-
}
68+
hrefResponse(traceId)
69+
}
6870

69-
def serveFileUpload(upfile: File): LiftResponse = {
70-
println(s"Uploaded file ${upfile.getName}")
71+
case UploadPath("import") Post req =>
72+
for {
73+
inputFile <- getReqFile(req) ?~! "Importing a trace requires a file"
74+
if TraceUploadData.checkForTraceExport(inputFile)
75+
} yield {
76+
val traceId = TraceUploadData.handleTraceExport(inputFile)
7177

72-
val uploadedTraceId = TraceUploadData.handleUpload(upfile)
73-
println(s"Upload resulted in trace: $uploadedTraceId")
78+
hrefResponse(traceId)
79+
}
80+
}
7481

75-
uploadedTraceId match {
76-
case Full(traceId) =>
77-
val target = traceManager.getTrace(traceId)
78-
val href = TraceDetailsPage.traceHref(traceId)
79-
JsonResponse("href" -> href)
80-
case Empty =>
81-
NotFoundResponse()
82-
case Failure(msg, _, _) =>
83-
NotFoundResponse(msg)
82+
def getReqFile(req: Req): Box[File] = req.uploadedFiles match {
83+
case List(upfile: OnDiskFileParamHolder) =>
84+
Full(upfile.localFile)
85+
86+
case Nil => req.param("path") flatMap { path =>
87+
val file = new File(path)
88+
if (file.canRead) Some(file) else None
8489
}
8590

91+
case _ => Empty
92+
}
93+
94+
def hrefResponse(traceId: TraceId) = {
95+
val href = TraceDetailsPage.traceHref(traceId)
96+
JsonResponse("href" -> href)
8697
}
8798

8899
}

codepulse/src/main/webapp/templates-hidden/TraceInputForm.html

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
<link class="lift:Includes.TraceInputForm"></link>
55
</lift:head>
66

7+
<ul class="form-tabs-list">
8+
<li class="form-tab active"><a data-toggle="tab" href="#new-analysis-form">New Trace</a></li>
9+
<li class="form-tab"><a data-toggle="tab" href="#new-import-form">Import Trace</a></li>
10+
</ul>
11+
712
<!-- NEW ANALYSIS UPLOAD -->
8-
<div id="new-analysis-form">
13+
<div id="new-analysis-form" class="active">
914
<!-- NAME -->
1015
<div class="form-field clearfix">
1116
<div class="input-label">Trace Name</div>
@@ -85,6 +90,63 @@
8590
</div>
8691
<!-- END OF ANALYSIS FORM -->
8792

88-
<!-- TODO: NEW IMPORT UPLOAD -->
93+
<!-- TRACE IMPORT FORM -->
94+
<div id="new-import-form">
95+
96+
<!-- FILE -->
97+
<div class="form-field clearfix">
98+
<div class="input-label">File</div>
99+
100+
<div class="input-area">
101+
102+
<div class="file-input-area clearfix">
103+
104+
<div class="file-input-button btn btn-flat btn-secondary">
105+
<input type="file" name="file-input"></input>
106+
<div class="prompt">
107+
<i class="fa fa-folder-open-o"></i>
108+
Browse for a file
109+
</div>
110+
</div>
111+
112+
<div class="file-or-msg">OR</div>
113+
114+
<div class="file-dropzone">
115+
<div class="dropzone-msg">
116+
<!-- see TraceInputForm.css for content -->
117+
</div>
118+
</div>
119+
</div>
120+
121+
<div class="file-input-result">
122+
The trace will be imported from
123+
<span name="file-input-choice-label">
124+
the file you choose or drag
125+
</span>
126+
</div>
127+
128+
<div class="input-help">
129+
<i class="fa fa-comment"></i>
130+
This is the file that will be imported. Trace files are exported as
131+
<span class="filetype">.pulse</span> files.
132+
</div>
133+
</div>
134+
<div class="feedback-area" name="file-feedback">
135+
<!-- file feedback, e.g.
136+
<div class="feedback">That file is lame, try a different one!</div>
137+
-->
138+
</div>
139+
</div>
140+
141+
<!-- OK/CANCEL -->
142+
<div class="form-field clearfix align-right">
143+
<div class="input-area">
144+
<div class="btn btn-flat btn-secondary" name="cancel-button">Cancel</div>
145+
<div class="btn btn-flat btn-primary" name="submit-button">OK</div>
146+
</div>
147+
</div>
148+
149+
</div>
150+
<!-- END TRACE IMPORT FORM -->
89151

90152
</div>

codepulse/src/main/webapp/templates-hidden/desktop.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
</head>
1818
<body>
1919

20-
<div id="content-wrapper">
20+
<!-- <div id="content-wrapper"> -->
2121
<div id="content">The main content will be bound here</div>
22-
</div>
22+
<!-- </div> -->
23+
24+
<!-- same height as the footer, to make sure content doesn't go behind it -->
25+
<div class="footer-push"></div>
2326

2427
<div id="footer">
2528
<span class="subtle">

0 commit comments

Comments
 (0)