Skip to content

Commit cbde8c2

Browse files
committed
update app
1 parent d9a1285 commit cbde8c2

9 files changed

Lines changed: 366 additions & 182 deletions

File tree

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ At the core of PROBEst is an AI-enhanced workflow that combines Primer3 for init
1717
```bash
1818
git clone https://github.com/CTLab-ITMO/PROBEst.git
1919
cd PROBEst
20-
conda env create -f environment.yml
21-
conda activate probest
2220
python setup.py install
2321
```
2422

23+
## Dependencies
24+
```bash
25+
conda install bioconda::primer3
26+
conda install bioconda::blast
27+
```
28+
2529
### Validate installation
2630

2731
```bash

app/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ def process():
360360
# Optional parameters
361361
args_dict['threads'] = request.form.get('threads', '1')
362362
args_dict['algorithm'] = request.form.get('algorithm', 'FISH')
363-
args_dict['iterations'] = request.form.get('iterations', '5')
363+
args_dict['iterations'] = request.form.get('iterations', '10')
364364
args_dict['top'] = request.form.get('top', '10')
365365
args_dict['mutation_rate'] = request.form.get('mutation_rate', '0.05')
366366
args_dict['indel_rate'] = request.form.get('indel_rate', '0.05')

app/static/ctlab_probest.jpg

309 KB
Loading

app/static/ctlab_probest_white.png

107 KB
Loading

app/static/probest_logo.ico

221 KB
Binary file not shown.

app/static/script.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ document.addEventListener('DOMContentLoaded', function() {
55
const resultsSection = document.getElementById('resultsSection');
66
const resultsContent = document.getElementById('resultsContent');
77
const downloadBtn = document.getElementById('downloadBtn');
8+
const statusText = document.getElementById('statusText');
9+
const progressContainer = document.getElementById('progressContainer');
810

911
form.addEventListener('submit', async function(e) {
1012
e.preventDefault();
@@ -13,6 +15,8 @@ document.addEventListener('DOMContentLoaded', function() {
1315
loadingOverlay.style.display = 'flex';
1416
resultsSection.style.display = 'none';
1517
submitBtn.disabled = true;
18+
statusText.textContent = 'Waiting to finish...';
19+
progressContainer.style.display = 'block';
1620

1721
// Create FormData
1822
const formData = new FormData(form);
@@ -39,6 +43,7 @@ document.addEventListener('DOMContentLoaded', function() {
3943
} finally {
4044
loadingOverlay.style.display = 'none';
4145
submitBtn.disabled = false;
46+
progressContainer.style.display = 'none';
4247
}
4348
});
4449

@@ -78,6 +83,7 @@ document.addEventListener('DOMContentLoaded', function() {
7883

7984
function displayResults(topProbes, totalProbes) {
8085
resultsContent.innerHTML = '';
86+
statusText.textContent = 'Completed.';
8187

8288
// Add summary
8389
const summary = document.createElement('div');
@@ -148,6 +154,7 @@ document.addEventListener('DOMContentLoaded', function() {
148154
resultsContent.appendChild(errorDiv);
149155
resultsSection.style.display = 'block';
150156
resultsSection.scrollIntoView({ behavior: 'smooth' });
157+
statusText.textContent = 'Error during generation.';
151158
}
152159
});
153160

app/static/style.css

Lines changed: 166 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
body {
88
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
9-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
9+
background: linear-gradient(135deg, #0f5390 0%, #127ed1 100%);
1010
min-height: 100vh;
1111
padding: 20px;
1212
color: #333;
@@ -21,11 +21,31 @@ body {
2121
overflow: hidden;
2222
}
2323

24+
.logo-title {
25+
display: flex;
26+
align-items: center;
27+
gap: 16px;
28+
}
29+
30+
.logo {
31+
width: 56px;
32+
height: 56px;
33+
border-radius: 12px;
34+
background: rgba(255, 255, 255, 0.15);
35+
padding: 6px;
36+
object-fit: contain;
37+
}
38+
2439
header {
25-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
40+
background: linear-gradient(135deg, #0f5390 0%, #127ed1 100%);
2641
color: white;
27-
padding: 40px;
28-
text-align: center;
42+
padding: 24px 40px;
43+
}
44+
45+
.header-inner {
46+
display: flex;
47+
align-items: center;
48+
justify-content: space-between;
2949
}
3050

3151
header h1 {
@@ -51,7 +71,7 @@ header h1 {
5171
.form-section h2 {
5272
font-size: 1.5em;
5373
margin-bottom: 20px;
54-
color: #667eea;
74+
color: #0f5390;
5575
font-weight: 600;
5676
}
5777

@@ -97,15 +117,15 @@ input[type="file"] {
97117
}
98118

99119
input[type="file"]:hover {
100-
border-color: #667eea;
120+
border-color: #0f5390;
101121
}
102122

103123
input[type="text"]:focus,
104124
input[type="number"]:focus,
105125
select:focus {
106126
outline: none;
107-
border-color: #667eea;
108-
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
127+
border-color: #0f5390;
128+
box-shadow: 0 0 0 3px rgba(15, 83, 144, 0.12);
109129
}
110130

111131
small {
@@ -117,8 +137,55 @@ small {
117137

118138
.form-actions {
119139
padding: 30px 40px;
120-
text-align: center;
121140
background: #f8f9fa;
141+
border-top: 1px solid #e0e0e0;
142+
}
143+
144+
.action-row {
145+
display: flex;
146+
align-items: center;
147+
justify-content: flex-end;
148+
gap: 24px;
149+
}
150+
151+
.status-area {
152+
display: flex;
153+
flex-direction: column;
154+
align-items: flex-start;
155+
gap: 6px;
156+
}
157+
158+
.status-text {
159+
font-size: 0.9em;
160+
color: #555;
161+
min-height: 1.2em;
162+
}
163+
164+
.progress-container {
165+
width: 180px;
166+
height: 6px;
167+
border-radius: 999px;
168+
background: #e1e9f2;
169+
overflow: hidden;
170+
}
171+
172+
.progress-bar {
173+
width: 40%;
174+
height: 100%;
175+
background: linear-gradient(90deg, #0f5390, #127ed1);
176+
animation: progress-indeterminate 1.2s infinite;
177+
}
178+
179+
@keyframes progress-indeterminate {
180+
0% {
181+
transform: translateX(-100%);
182+
}
183+
50% {
184+
transform: translateX(0%);
185+
}
186+
100% {
187+
transform: translateX(100%);
188+
}
122189
}
123190

124191
.btn {
@@ -134,13 +201,13 @@ small {
134201
}
135202

136203
.btn-primary {
137-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
204+
background: linear-gradient(135deg, #0f5390 0%, #127ed1 100%);
138205
color: white;
139206
}
140207

141208
.btn-primary:hover {
142209
transform: translateY(-2px);
143-
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
210+
box-shadow: 0 10px 20px rgba(15, 83, 144, 0.35);
144211
}
145212

146213
.btn-primary:active {
@@ -160,11 +227,11 @@ small {
160227
.results-section {
161228
padding: 40px;
162229
background: #f8f9fa;
163-
border-top: 3px solid #667eea;
230+
border-top: 3px solid #0f5390;
164231
}
165232

166233
.results-section h2 {
167-
color: #667eea;
234+
color: #0f5390;
168235
margin-bottom: 30px;
169236
font-size: 2em;
170237
}
@@ -188,7 +255,7 @@ small {
188255
}
189256

190257
.probe-card h3 {
191-
color: #667eea;
258+
color: #0f5390;
192259
margin-bottom: 15px;
193260
font-size: 1.3em;
194261
}
@@ -227,7 +294,7 @@ small {
227294
font-size: 14px;
228295
word-break: break-all;
229296
color: #2c3e50;
230-
border-left: 4px solid #667eea;
297+
border-left: 4px solid #0f5390;
231298
}
232299

233300
.results-actions {
@@ -280,11 +347,68 @@ small {
280347

281348
.success-message {
282349
background: #efe;
283-
color: #3c3;
350+
color: #248a3d;
284351
padding: 15px;
285352
border-radius: 8px;
286353
margin-bottom: 20px;
287-
border-left: 4px solid #3c3;
354+
border-left: 4px solid #248a3d;
355+
}
356+
357+
.advanced-section {
358+
margin: 0 40px 30px 40px;
359+
border-radius: 12px;
360+
border: 1px dashed #c5d3e3;
361+
background: #f7f9fc;
362+
padding: 0 0 10px 0;
363+
}
364+
365+
.advanced-section > summary {
366+
padding: 14px 20px;
367+
cursor: pointer;
368+
font-weight: 600;
369+
color: #0f5390;
370+
list-style: none;
371+
}
372+
373+
.advanced-section[open] > summary {
374+
border-bottom: 1px solid #dde5f0;
375+
}
376+
377+
.advanced-section > summary::marker,
378+
.advanced-section > summary::-webkit-details-marker {
379+
display: none;
380+
}
381+
382+
.advanced-section > summary::before {
383+
content: '▸';
384+
display: inline-block;
385+
margin-right: 8px;
386+
transition: transform 0.2s ease;
387+
}
388+
389+
.advanced-section[open] > summary::before {
390+
transform: rotate(90deg);
391+
}
392+
393+
.advanced-section .form-section {
394+
padding: 20px 20px 10px 20px;
395+
}
396+
397+
.footer {
398+
padding: 20px 40px 24px 40px;
399+
font-size: 0.9em;
400+
color: #666;
401+
border-top: 1px solid #e0e0e0;
402+
background: #fff;
403+
}
404+
405+
.footer a {
406+
color: #0f5390;
407+
text-decoration: none;
408+
}
409+
410+
.footer a:hover {
411+
text-decoration: underline;
288412
}
289413

290414
@media (max-width: 768px) {
@@ -294,11 +418,16 @@ small {
294418
}
295419

296420
header {
297-
padding: 20px;
421+
padding: 16px 20px;
298422
}
299423

300424
header h1 {
301-
font-size: 1.8em;
425+
font-size: 1.6em;
426+
}
427+
428+
.logo {
429+
width: 44px;
430+
height: 44px;
302431
}
303432

304433
.form-section {
@@ -308,6 +437,24 @@ small {
308437
.form-row {
309438
grid-template-columns: 1fr;
310439
}
440+
441+
.advanced-section {
442+
margin: 0 20px 20px 20px;
443+
}
444+
445+
.form-actions {
446+
padding: 20px;
447+
}
448+
449+
.action-row {
450+
flex-direction: column-reverse;
451+
align-items: stretch;
452+
gap: 12px;
453+
}
454+
455+
.status-area {
456+
align-items: flex-start;
457+
}
311458
}
312459

313460

0 commit comments

Comments
 (0)