Vokturz commited on
Commit
a68c0b7
·
1 Parent(s): 91cc60b

enhance UI layout and responsiveness across pipelines

Browse files
src/components/pipelines/FeatureExtraction.tsx CHANGED
@@ -295,7 +295,8 @@ function FeatureExtraction() {
295
  </div>
296
  </div>
297
 
298
- <div className="flex flex-col lg:flex-row gap-4 flex-1 min-h-0">
 
299
  {/* Left Panel - Examples */}
300
  <div className="lg:w-1/2 flex flex-col min-h-0">
301
  {/* Add Example */}
@@ -303,26 +304,27 @@ function FeatureExtraction() {
303
  <label className="block text-sm font-medium text-gray-700 mb-2">
304
  Add Text Examples:
305
  </label>
306
- <div className="flex flex-col sm:flex-row gap-2">
307
  <textarea
308
  value={newExampleText}
309
  onChange={(e) => setNewExampleText(e.target.value)}
310
  onKeyPress={handleKeyPress}
311
  placeholder="Enter text to get embeddings... (Press Enter to add)"
312
- className="flex-1 p-3 border border-gray-300 rounded-lg resize-none focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed text-sm"
313
  rows={2}
314
  disabled={!hasBeenLoaded || isExtracting}
315
  />
316
  <button
317
  onClick={handleAddExample}
318
  disabled={!newExampleText.trim() || !hasBeenLoaded}
319
- className="px-4 py-2 bg-blue-500 hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed text-white rounded-lg transition-colors self-start sm:self-stretch"
320
  >
321
  <Plus className="w-4 h-4" />
322
  </button>
323
  </div>
324
  </div>
325
 
 
326
  {/* Extract Button */}
327
  {examples.some((ex) => !ex.embedding) && (
328
  <div className="mb-4">
@@ -344,8 +346,8 @@ function FeatureExtraction() {
344
  </div>
345
  )}
346
 
347
- {/* Examples List */}
348
- <div className="flex-1 overflow-y-auto border border-gray-300 rounded-lg bg-white min-h-0 max-h-[35vh] sm:max-h-[40vh] lg:max-h-none">
349
  <div className="p-4 h-full">
350
  <h3 className="text-sm font-medium text-gray-700 mb-3 sticky top-0 bg-white z-10">
351
  Examples ({examples.length})
@@ -415,11 +417,11 @@ function FeatureExtraction() {
415
  {/* Right Panel - Visualization and Similarities */}
416
  <div className="lg:w-1/2 flex flex-col min-h-0">
417
  {showVisualization && (
418
- <div className="mb-4">
419
  <h3 className="text-sm font-medium text-gray-700 mb-2">
420
  2D Visualization
421
  </h3>
422
- <div className="border border-gray-300 rounded-lg bg-white p-2 sm:p-4">
423
  <svg
424
  ref={chartRef}
425
  width="100%"
@@ -532,7 +534,7 @@ function FeatureExtraction() {
532
  )}
533
 
534
  {/* Similarity Results */}
535
- <div className="flex-1 overflow-y-auto border border-gray-300 rounded-lg bg-white min-h-0 max-h-[35vh] sm:max-h-[40vh] lg:max-h-none">
536
  <div className="p-4 h-full">
537
  <h3 className="text-sm font-medium text-gray-700 mb-3 sticky top-0 bg-white z-10">
538
  Cosine Similarities
@@ -560,8 +562,8 @@ function FeatureExtraction() {
560
  sim.similarity > 0.8
561
  ? 'text-green-600'
562
  : sim.similarity > 0.5
563
- ? 'text-yellow-600'
564
- : 'text-red-500'
565
 
566
  return (
567
  <div
@@ -585,8 +587,8 @@ function FeatureExtraction() {
585
  sim.similarity > 0.8
586
  ? 'bg-green-500'
587
  : sim.similarity > 0.5
588
- ? 'bg-yellow-500'
589
- : 'bg-red-500'
590
  }`}
591
  style={{
592
  width: `${Math.max(sim.similarity * 100, 5)}%`
 
295
  </div>
296
  </div>
297
 
298
+
299
+ <div className="flex flex-col lg:flex-row gap-4 flex-1 min-h-0 overflow-y-auto">
300
  {/* Left Panel - Examples */}
301
  <div className="lg:w-1/2 flex flex-col min-h-0">
302
  {/* Add Example */}
 
304
  <label className="block text-sm font-medium text-gray-700 mb-2">
305
  Add Text Examples:
306
  </label>
307
+ <div className="flex flex-row gap-2">
308
  <textarea
309
  value={newExampleText}
310
  onChange={(e) => setNewExampleText(e.target.value)}
311
  onKeyPress={handleKeyPress}
312
  placeholder="Enter text to get embeddings... (Press Enter to add)"
313
+ className="w-5/6 lg:w-full flex-1 p-3 border border-gray-300 rounded-lg resize-none focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed text-sm"
314
  rows={2}
315
  disabled={!hasBeenLoaded || isExtracting}
316
  />
317
  <button
318
  onClick={handleAddExample}
319
  disabled={!newExampleText.trim() || !hasBeenLoaded}
320
+ className="px-4 py-2 bg-blue-500 hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed text-white rounded-lg transition-colors self-stretch"
321
  >
322
  <Plus className="w-4 h-4" />
323
  </button>
324
  </div>
325
  </div>
326
 
327
+
328
  {/* Extract Button */}
329
  {examples.some((ex) => !ex.embedding) && (
330
  <div className="mb-4">
 
346
  </div>
347
  )}
348
 
349
+ {/* Examples List */}
350
+ <div className="flex-1 overflow-y-auto border border-gray-300 rounded-lg bg-white min-h-12 max-h-[35vh] sm:max-h-[40vh] lg:max-h-none">
351
  <div className="p-4 h-full">
352
  <h3 className="text-sm font-medium text-gray-700 mb-3 sticky top-0 bg-white z-10">
353
  Examples ({examples.length})
 
417
  {/* Right Panel - Visualization and Similarities */}
418
  <div className="lg:w-1/2 flex flex-col min-h-0">
419
  {showVisualization && (
420
+ <div className="mb-2">
421
  <h3 className="text-sm font-medium text-gray-700 mb-2">
422
  2D Visualization
423
  </h3>
424
+ <div className="border border-gray-300 rounded-lg bg-white p-2 sm:p-4 ">
425
  <svg
426
  ref={chartRef}
427
  width="100%"
 
534
  )}
535
 
536
  {/* Similarity Results */}
537
+ <div className="flex-1 overflow-y-auto border border-gray-300 rounded-lg bg-white min-h-32 max-h-[35vh] sm:max-h-[40vh] lg:max-h-none">
538
  <div className="p-4 h-full">
539
  <h3 className="text-sm font-medium text-gray-700 mb-3 sticky top-0 bg-white z-10">
540
  Cosine Similarities
 
562
  sim.similarity > 0.8
563
  ? 'text-green-600'
564
  : sim.similarity > 0.5
565
+ ? 'text-yellow-600'
566
+ : 'text-red-500'
567
 
568
  return (
569
  <div
 
587
  sim.similarity > 0.8
588
  ? 'bg-green-500'
589
  : sim.similarity > 0.5
590
+ ? 'bg-yellow-500'
591
+ : 'bg-red-500'
592
  }`}
593
  style={{
594
  width: `${Math.max(sim.similarity * 100, 5)}%`
src/components/pipelines/ImageClassification.tsx CHANGED
@@ -206,7 +206,7 @@ function ImageClassification() {
206
  </div>
207
  </div>
208
 
209
- <div className="flex flex-col lg:flex-row gap-4 flex-1 min-h-0">
210
  {/* Left Panel - Image Upload and List */}
211
  <div className="lg:w-1/2 flex flex-col">
212
  {/* Upload Area */}
@@ -219,22 +219,27 @@ function ImageClassification() {
219
  onDragOver={handleDragOver}
220
  onDragLeave={handleDragLeave}
221
  onDrop={handleDrop}
222
- className={`border-2 border-dashed rounded-lg p-6 text-center transition-colors cursor-pointer ${
223
  dragOver
224
  ? 'border-blue-500 bg-blue-50'
225
  : 'border-gray-300 hover:border-gray-400'
226
  } ${!hasBeenLoaded ? 'opacity-50 cursor-not-allowed' : ''}`}
227
  onClick={() => hasBeenLoaded && fileInputRef.current?.click()}
228
  >
229
- <Upload className="w-8 h-8 mx-auto mb-2 text-gray-400" />
230
- <p className="text-sm text-gray-600">
231
- {dragOver
232
- ? 'Drop images here'
233
- : 'Click to upload or drag and drop images'}
234
- </p>
235
- <p className="text-xs text-gray-500 mt-1">
 
 
236
  Supports JPG, PNG, GIF, WebP
237
  </p>
 
 
 
238
  <input
239
  ref={fileInputRef}
240
  type="file"
@@ -350,12 +355,12 @@ function ImageClassification() {
350
  <h3 className="text-sm font-medium text-gray-700 mb-2">
351
  Selected Image
352
  </h3>
353
- <div className="sm:border-none border border-gray-300 rounded-lg bg-white p-4 sm:p-0">
354
  <div className="flex flex-col items-center">
355
  <img
356
  src={selectedExample.url}
357
  alt={selectedExample.name}
358
- className="max-w-64 lg:max-w-full max-h-60 lg:max-h-64 object-contain rounded-lg mb-2"
359
  />
360
  <div className="text-sm text-gray-600 text-center">
361
  {selectedExample.name}
@@ -432,8 +437,8 @@ function ImageClassification() {
432
  isTopPrediction
433
  ? 'bg-green-500'
434
  : prediction.score > 0.5
435
- ? 'bg-blue-500'
436
- : 'bg-gray-400'
437
  }`}
438
  style={{
439
  width: `${Math.max(prediction.score * 100, 2)}%`
 
206
  </div>
207
  </div>
208
 
209
+ <div className="flex flex-col lg:flex-row gap-4 flex-1 min-h-0 overflow-y-auto">
210
  {/* Left Panel - Image Upload and List */}
211
  <div className="lg:w-1/2 flex flex-col">
212
  {/* Upload Area */}
 
219
  onDragOver={handleDragOver}
220
  onDragLeave={handleDragLeave}
221
  onDrop={handleDrop}
222
+ className={`border-2 border-dashed rounded-lg p-3 lg:p-6 text-center transition-colors cursor-pointer ${
223
  dragOver
224
  ? 'border-blue-500 bg-blue-50'
225
  : 'border-gray-300 hover:border-gray-400'
226
  } ${!hasBeenLoaded ? 'opacity-50 cursor-not-allowed' : ''}`}
227
  onClick={() => hasBeenLoaded && fileInputRef.current?.click()}
228
  >
229
+ <div className="flex flex-row lg:flex-col">
230
+ <Upload className="w-8 h-8 mx-auto mb-2 text-gray-400" />
231
+ <div className='flex flex-col'>
232
+ <p className="text-sm text-gray-600">
233
+ {dragOver
234
+ ? 'Drop images here'
235
+ : 'Click to upload or drag and drop images'}
236
+ </p>
237
+ <p className="text-xs text-gray-500 mt-1">
238
  Supports JPG, PNG, GIF, WebP
239
  </p>
240
+ </div>
241
+ </div>
242
+
243
  <input
244
  ref={fileInputRef}
245
  type="file"
 
355
  <h3 className="text-sm font-medium text-gray-700 mb-2">
356
  Selected Image
357
  </h3>
358
+ <div className="border-none sm:border border-gray-300 rounded-lg bg-white p-4 sm:p-0">
359
  <div className="flex flex-col items-center">
360
  <img
361
  src={selectedExample.url}
362
  alt={selectedExample.name}
363
+ className="max-w-24 lg:max-w-full max-h-60 lg:max-h-64 object-contain rounded-lg mb-2"
364
  />
365
  <div className="text-sm text-gray-600 text-center">
366
  {selectedExample.name}
 
437
  isTopPrediction
438
  ? 'bg-green-500'
439
  : prediction.score > 0.5
440
+ ? 'bg-blue-500'
441
+ : 'bg-gray-400'
442
  }`}
443
  style={{
444
  width: `${Math.max(prediction.score * 100, 2)}%`
src/components/pipelines/TextClassification.tsx CHANGED
@@ -87,19 +87,20 @@ function TextClassification() {
87
  }
88
 
89
  return (
90
- <div className="flex flex-col h-full max-h-[calc(100dvh-128px)] w-full p-4">
91
  <h1 className="text-2xl font-bold mb-4 shrink-0">Text Classification</h1>
92
 
93
  <div className="flex flex-col lg:flex-row gap-4 flex-1 min-h-0 overflow-hidden">
94
  {/* Input Section */}
95
- <div className="flex flex-col w-full lg:w-1/2 min-h-0 max-h-[50vh] lg:max-h-none">
96
  <label className="text-lg font-medium mb-2 shrink-0">
97
  Input Text ({numberExamples} examples):
98
  </label>
99
 
100
- <div className="flex flex-col flex-1 min-h-0">
101
  <textarea
102
- className="border border-gray-300 rounded-sm p-3 flex-1 resize-none min-h-[200px] lg:min-h-[250px]"
 
103
  value={text}
104
  onChange={(e) => setText(e.target.value)}
105
  placeholder="Enter text to classify (one per line)..."
@@ -128,12 +129,12 @@ function TextClassification() {
128
  </div>
129
 
130
  {/* Results Section */}
131
- <div className="flex flex-col w-full lg:w-1/2 min-h-0 max-h-[50vh] lg:max-h-none">
132
  <label className="text-lg font-medium mb-2 shrink-0">
133
  Classification Results ({results.length}):
134
  </label>
135
 
136
- <div className="border border-gray-300 rounded-sm p-3 flex-1 overflow-y-auto min-h-[200px] lg:min-h-[250px]">
137
  {results.length === 0 ? (
138
  <div className="text-gray-500 text-center py-8">
139
  No results yet. Click "Classify Text" to analyze your input.
 
87
  }
88
 
89
  return (
90
+ <div className="flex flex-col h-full max-h-[calc(100dvh-148px)] w-full p-4 overflow-hidden">
91
  <h1 className="text-2xl font-bold mb-4 shrink-0">Text Classification</h1>
92
 
93
  <div className="flex flex-col lg:flex-row gap-4 flex-1 min-h-0 overflow-hidden">
94
  {/* Input Section */}
95
+ <div className="flex flex-col w-full lg:w-1/2 min-h-0 overflow-hidden">
96
  <label className="text-lg font-medium mb-2 shrink-0">
97
  Input Text ({numberExamples} examples):
98
  </label>
99
 
100
+ <div className="flex flex-col flex-1 min-h-0 overflow-hidden">
101
  <textarea
102
+
103
+ className="border border-gray-300 rounded-sm p-3 flex-1 resize-none overflow-y-auto min-h-[150px] lg:min-h-[250px]"
104
  value={text}
105
  onChange={(e) => setText(e.target.value)}
106
  placeholder="Enter text to classify (one per line)..."
 
129
  </div>
130
 
131
  {/* Results Section */}
132
+ <div className="flex flex-col w-full lg:w-1/2 min-h-0 overflow-hidden">
133
  <label className="text-lg font-medium mb-2 shrink-0">
134
  Classification Results ({results.length}):
135
  </label>
136
 
137
+ <div className="border border-gray-300 rounded-sm p-3 flex-1 overflow-y-auto">
138
  {results.length === 0 ? (
139
  <div className="text-gray-500 text-center py-8">
140
  No results yet. Click "Classify Text" to analyze your input.