AdnanElAssadi commited on
Commit
f93396e
·
verified ·
1 Parent(s): fb3320c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -189
app.py CHANGED
@@ -11,151 +11,89 @@ def create_reranking_interface(task_data):
11
 
12
  # Define helper functions before UI elements are created
13
  def generate_sortable_html(candidates, existing_ranks=None):
14
- """Generate the HTML for simple ranking with numbered buttons."""
 
 
15
  if existing_ranks and len(existing_ranks) == len(candidates):
16
- # Use existing ranks to determine the current order
17
- order = sorted(range(len(candidates)), key=lambda i: existing_ranks[i])
18
- else:
19
- # Default to original order
20
- order = list(range(len(candidates)))
21
-
22
- # Create an array to hold the documents in their current order
23
- ordered_docs = []
24
- for idx in order:
25
- if idx < len(candidates):
26
- ordered_docs.append({"doc_id": idx, "text": candidates[idx]})
27
-
28
- # Generate the HTML for the ranking interface
29
- html = """
30
- <div class="ranking-container">
31
- <div class="docs-container">
32
  """
33
 
34
- # Add each document with rank selection buttons
35
- for i, doc in enumerate(ordered_docs):
36
  import html as html_escaper
37
- escaped_doc = html_escaper.escape(doc["text"])
38
- current_rank = i + 1
39
 
40
  html += f"""
41
- <div class="doc-item" data-doc-id="{doc['doc_id']}">
42
  <div class="rank-selector">
43
- <div class="rank-number">{current_rank}</div>
44
- <div class="rank-buttons">
45
  """
46
 
47
- # Add numbered rank buttons
48
- for rank_btn in range(1, len(candidates) + 1):
49
- selected = "selected" if rank_btn == current_rank else ""
50
- html += f'<button class="rank-btn {selected}" data-rank="{rank_btn}" onclick="setRank({doc["doc_id"]}, {rank_btn})">{rank_btn}</button>'
51
-
52
- html += """
53
- </div>
54
- </div>
55
- <div class="doc-content">
56
- """ + escaped_doc + """
57
  </div>
 
58
  </div>
59
  """
60
-
61
- html += """
62
- </div>
63
- </div>
64
 
 
 
65
  <script>
66
- function setRank(docId, newRank) {
67
- // Convert to numbers to ensure proper comparison
68
- docId = parseInt(docId);
69
- newRank = parseInt(newRank);
70
-
71
- // Get all doc items
72
- const docItems = document.querySelectorAll('.doc-item');
73
-
74
- // First, find the document that currently has the requested rank
75
- let targetDocItem = null;
76
- let currentDocRank = 0;
77
-
78
- docItems.forEach((item, index) => {
79
- const itemDocId = parseInt(item.getAttribute('data-doc-id'));
80
-
81
- // Find the current rank of the document we want to change
82
- if (itemDocId === docId) {
83
- targetDocItem = item;
84
- currentDocRank = index + 1;
85
- }
86
-
87
- // Update the selected button for this doc
88
- const buttons = item.querySelectorAll('.rank-btn');
89
- buttons.forEach(btn => {
90
- const btnRank = parseInt(btn.getAttribute('data-rank'));
91
- if (btnRank === newRank && itemDocId === docId) {
92
- btn.classList.add('selected');
93
- } else if (btnRank !== newRank && itemDocId === docId) {
94
- btn.classList.remove('selected');
95
- }
96
- });
97
- });
98
-
99
- // If we're not changing the rank, do nothing more
100
- if (currentDocRank === newRank) {
101
- updateOrderState();
102
- return;
103
- }
104
-
105
- // Get the container and convert nodelist to array so we can manipulate it
106
- const container = document.querySelector('.docs-container');
107
- const itemsArray = Array.from(docItems);
108
-
109
- // Remove the target doc from its current position
110
- itemsArray.splice(currentDocRank - 1, 1);
111
-
112
- // Insert it at the new rank position
113
- itemsArray.splice(newRank - 1, 0, targetDocItem);
114
-
115
- // Clear the container
116
- while (container.firstChild) {
117
- container.removeChild(container.firstChild);
118
- }
119
-
120
- // Add items back in their new order
121
- itemsArray.forEach((item, index) => {
122
- // Update the displayed rank number
123
- const rankNumber = item.querySelector('.rank-number');
124
- rankNumber.textContent = index + 1;
125
 
126
- // Add back to container
127
- container.appendChild(item);
128
- });
129
-
130
- // Update the hidden state for submission
131
- updateOrderState();
132
- }
133
-
134
- function updateOrderState() {
135
- // Get the current order of documents
136
- const docItems = document.querySelectorAll('.doc-item');
137
- const order = Array.from(docItems).map(item =>
138
- parseInt(item.getAttribute('data-doc-id')));
139
-
140
- // Find the input field and update its value
141
  const orderInput = document.querySelector('#current-order textarea');
142
- if (orderInput) {
143
- orderInput.value = JSON.stringify(order);
144
-
145
- // Trigger input event to notify Gradio
146
- const event = new Event('input', { bubbles: true });
147
  orderInput.dispatchEvent(event);
148
- }
149
- }
150
 
151
- // Initialize the order state when the page loads
152
- window.addEventListener('DOMContentLoaded', function() {
153
- updateOrderState();
154
- });
155
 
156
  // Backup initialization for iframe environments
157
- setTimeout(updateOrderState, 1000);
 
 
158
  </script>
 
159
  """
160
 
161
  return html
@@ -269,94 +207,50 @@ def create_reranking_interface(task_data):
269
 
270
  js_code = """
271
  <style>
272
- /* Simple and reliable ranking interface styles */
273
- .ranking-container {
274
  width: 100%;
275
  max-width: 100%;
276
  margin: 0 auto;
277
  }
278
 
279
- .docs-container {
280
- display: flex;
281
- flex-direction: column;
282
- gap: 15px;
 
 
283
  }
284
 
285
- .doc-item {
286
  display: flex;
287
- padding: 15px;
 
 
288
  background: white;
289
  border: 1px solid #e0e0e0;
290
- border-radius: 8px;
291
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
292
  }
293
 
294
  .rank-selector {
295
- display: flex;
296
- flex-direction: column;
297
- align-items: center;
298
  margin-right: 15px;
299
- min-width: 40px;
300
- }
301
-
302
- .rank-number {
303
- font-size: 18px;
304
- font-weight: bold;
305
- width: 30px;
306
- height: 30px;
307
- display: flex;
308
- align-items: center;
309
- justify-content: center;
310
- background: #3b82f6;
311
- color: white;
312
- border-radius: 50%;
313
- margin-bottom: 8px;
314
- }
315
-
316
- .rank-buttons {
317
- display: flex;
318
- flex-wrap: wrap;
319
- gap: 3px;
320
- max-width: 120px;
321
- justify-content: center;
322
  }
323
 
324
- .rank-btn {
325
- width: 26px;
326
- height: 26px;
327
- padding: 0;
328
- font-size: 12px;
329
  border: 1px solid #d1d5db;
330
- background: #f9fafb;
331
  border-radius: 4px;
332
- cursor: pointer;
333
- display: flex;
334
- align-items: center;
335
- justify-content: center;
336
- }
337
-
338
- .rank-btn:hover {
339
- background: #e5e7eb;
340
- }
341
-
342
- .rank-btn.selected {
343
- background: #3b82f6;
344
- color: white;
345
- border-color: #2563eb;
346
  }
347
 
348
  .doc-content {
349
  flex: 1;
350
- padding: 5px;
351
  line-height: 1.5;
 
352
  }
353
-
354
- /* Color coding the rank numbers by position */
355
- .doc-item:nth-child(1) .rank-number { background-color: #10b981; /* green */ }
356
- .doc-item:nth-child(2) .rank-number { background-color: #3b82f6; /* blue */ }
357
- .doc-item:nth-child(3) .rank-number { background-color: #f59e0b; /* yellow */ }
358
- .doc-item:nth-child(4) .rank-number { background-color: #ef4444; /* red */ }
359
- .doc-item:nth-child(5) .rank-number { background-color: #8b5cf6; /* purple */ }
360
  </style>
361
  """
362
  gr.HTML(js_code)
@@ -627,7 +521,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
627
  return filename
628
  return None
629
 
630
- # Update the dropdown when refreshing results
631
  def update_result_dropdown():
632
  return gr.Dropdown.update(choices=[f for f in os.listdir(".") if f.endswith("_human_results.json")])
633
 
 
11
 
12
  # Define helper functions before UI elements are created
13
  def generate_sortable_html(candidates, existing_ranks=None):
14
+ """Generate HTML with simple dropdowns for ranking."""
15
+ # Use existing ranks if available
16
+ ranks = [0] * len(candidates)
17
  if existing_ranks and len(existing_ranks) == len(candidates):
18
+ ranks = existing_ranks.copy()
19
+
20
+ # Generate a unique ID for this set of dropdowns to avoid conflicts
21
+ import random
22
+ import time
23
+ dropdown_group_id = f"rank_group_{int(time.time())}_{random.randint(1000, 9999)}"
24
+
25
+ html = f"""
26
+ <div class="ranking-simple">
27
+ <input type="hidden" id="rank-order-state" value="">
28
+ <div class="rank-instructions">Select a rank (1-{len(candidates)}) for each document.</div>
 
 
 
 
 
29
  """
30
 
31
+ # Add each document with a dropdown selector
32
+ for i, doc in enumerate(candidates):
33
  import html as html_escaper
34
+ escaped_doc = html_escaper.escape(doc)
35
+ current_rank = ranks[i] if ranks[i] > 0 else i + 1
36
 
37
  html += f"""
38
+ <div class="rank-item" data-doc-id="{i}">
39
  <div class="rank-selector">
40
+ <select class="rank-dropdown" data-doc-id="{i}" onchange="updateRankOrder('{dropdown_group_id}')">
 
41
  """
42
 
43
+ # Add options 1 through N
44
+ for rank in range(1, len(candidates) + 1):
45
+ selected = "selected" if rank == current_rank else ""
46
+ html += f'<option value="{rank}" {selected}>{rank}</option>'
47
+
48
+ html += f"""
49
+ </select>
 
 
 
50
  </div>
51
+ <div class="doc-content">{escaped_doc}</div>
52
  </div>
53
  """
 
 
 
 
54
 
55
+ # Add the JavaScript for handling rank updates
56
+ html += f"""
57
  <script>
58
+ // Function to update the hidden state when dropdowns change
59
+ function updateRankOrder(groupId) {{
60
+ const items = document.querySelectorAll('.rank-item');
61
+ const selectedRanks = new Map();
62
+ const docOrder = [];
63
+
64
+ // First collect all selected ranks
65
+ items.forEach(item => {{
66
+ const docId = parseInt(item.getAttribute('data-doc-id'));
67
+ const dropdown = item.querySelector('.rank-dropdown');
68
+ const rank = parseInt(dropdown.value);
69
+ selectedRanks.set(docId, rank);
70
+ }});
71
+
72
+ // Sort documents by their selected rank
73
+ const sortedDocs = Array.from(selectedRanks.entries())
74
+ .sort((a, b) => a[1] - b[1])
75
+ .map(entry => entry[0]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
+ // Update the order state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  const orderInput = document.querySelector('#current-order textarea');
79
+ if (orderInput) {{
80
+ orderInput.value = JSON.stringify(sortedDocs);
81
+ const event = new Event('input', {{ bubbles: true }});
 
 
82
  orderInput.dispatchEvent(event);
83
+ }}
84
+ }}
85
 
86
+ // Initialize on page load
87
+ document.addEventListener('DOMContentLoaded', function() {{
88
+ updateRankOrder('{dropdown_group_id}');
89
+ }});
90
 
91
  // Backup initialization for iframe environments
92
+ setTimeout(function() {{
93
+ updateRankOrder('{dropdown_group_id}');
94
+ }}, 1000);
95
  </script>
96
+ </div>
97
  """
98
 
99
  return html
 
207
 
208
  js_code = """
209
  <style>
210
+ /* Simple dropdown ranking styles */
211
+ .ranking-simple {
212
  width: 100%;
213
  max-width: 100%;
214
  margin: 0 auto;
215
  }
216
 
217
+ .rank-instructions {
218
+ margin-bottom: 15px;
219
+ padding: 10px;
220
+ background-color: #f0f9ff;
221
+ border-left: 4px solid #3b82f6;
222
+ border-radius: 4px;
223
  }
224
 
225
+ .rank-item {
226
  display: flex;
227
+ align-items: flex-start;
228
+ padding: 12px;
229
+ margin-bottom: 10px;
230
  background: white;
231
  border: 1px solid #e0e0e0;
232
+ border-radius: 6px;
 
233
  }
234
 
235
  .rank-selector {
 
 
 
236
  margin-right: 15px;
237
+ min-width: 70px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
 
240
+ .rank-dropdown {
241
+ width: 60px;
242
+ padding: 6px;
 
 
243
  border: 1px solid #d1d5db;
 
244
  border-radius: 4px;
245
+ background-color: white;
246
+ font-size: 14px;
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
248
 
249
  .doc-content {
250
  flex: 1;
 
251
  line-height: 1.5;
252
+ padding: 5px 0;
253
  }
 
 
 
 
 
 
 
254
  </style>
255
  """
256
  gr.HTML(js_code)
 
521
  return filename
522
  return None
523
 
524
+ # Update dropdown when refreshing results
525
  def update_result_dropdown():
526
  return gr.Dropdown.update(choices=[f for f in os.listdir(".") if f.endswith("_human_results.json")])
527