andrewbejjani commited on
Commit
dbee56e
·
1 Parent(s): 446ae13

Add collapsable user guide in the UI

Browse files

modified: requirements.txt
modified: ui/static/styles.css
modified: ui/templates/index.html
modified: ui_app.py

Files changed (4) hide show
  1. requirements.txt +1 -0
  2. ui/static/styles.css +72 -0
  3. ui/templates/index.html +12 -0
  4. ui_app.py +22 -0
requirements.txt CHANGED
@@ -9,3 +9,4 @@ tenacity
9
  flask
10
  gunicorn
11
  huggingface_hub
 
 
9
  flask
10
  gunicorn
11
  huggingface_hub
12
+ markdown
ui/static/styles.css CHANGED
@@ -34,6 +34,69 @@
34
  border-radius: 8px;
35
  padding: 16px;
36
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  label {
38
  display: block;
39
  margin: 14px 0 6px;
@@ -223,3 +286,12 @@
223
  border-top: 1px solid var(--line);
224
  margin: 18px 0;
225
  }
 
 
 
 
 
 
 
 
 
 
34
  border-radius: 8px;
35
  padding: 16px;
36
  }
37
+ .guide-panel {
38
+ grid-column: 1 / -1;
39
+ padding: 0;
40
+ overflow: hidden;
41
+ }
42
+ .guide-panel details {
43
+ padding: 0;
44
+ }
45
+ .guide-panel summary {
46
+ display: flex;
47
+ justify-content: space-between;
48
+ gap: 12px;
49
+ align-items: center;
50
+ cursor: pointer;
51
+ padding: 14px 16px;
52
+ font-weight: 700;
53
+ }
54
+ .guide-panel summary small {
55
+ color: var(--muted);
56
+ font-size: 12px;
57
+ font-weight: 400;
58
+ }
59
+ .guide-content {
60
+ border-top: 1px solid var(--line);
61
+ padding: 16px;
62
+ }
63
+ .readme-content {
64
+ max-height: 520px;
65
+ overflow: auto;
66
+ font-size: 14px;
67
+ line-height: 1.55;
68
+ }
69
+ .guide-content h2 {
70
+ margin: 18px 0 8px;
71
+ font-size: 15px;
72
+ }
73
+ .guide-content h1 {
74
+ margin: 0 0 12px;
75
+ font-size: 20px;
76
+ }
77
+ .guide-content p {
78
+ margin: 0 0 10px;
79
+ }
80
+ .guide-content ul,
81
+ .guide-content ol {
82
+ margin: 0 0 12px;
83
+ padding-left: 20px;
84
+ color: var(--muted);
85
+ }
86
+ .guide-content li + li {
87
+ margin-top: 4px;
88
+ }
89
+ .guide-content code {
90
+ background: #eef2f7;
91
+ border-radius: 4px;
92
+ padding: 1px 4px;
93
+ color: var(--text);
94
+ }
95
+ .guide-content pre {
96
+ margin: 0;
97
+ white-space: pre-wrap;
98
+ color: var(--muted);
99
+ }
100
  label {
101
  display: block;
102
  margin: 14px 0 6px;
 
286
  border-top: 1px solid var(--line);
287
  margin: 18px 0;
288
  }
289
+ @media (max-width: 900px) {
290
+ main {
291
+ grid-template-columns: 1fr;
292
+ }
293
+ .guide-panel summary {
294
+ align-items: flex-start;
295
+ flex-direction: column;
296
+ }
297
+ }
ui/templates/index.html CHANGED
@@ -12,6 +12,18 @@
12
  <h1>MasterMap Cleaner</h1>
13
  </header>
14
  <main>
 
 
 
 
 
 
 
 
 
 
 
 
15
  <section>
16
  <h2>Dataset to Clean</h2>
17
  {% if clean_filename %}
 
12
  <h1>MasterMap Cleaner</h1>
13
  </header>
14
  <main>
15
+ <section class="guide-panel">
16
+ <details>
17
+ <summary>
18
+ <span>User Guide</span>
19
+ <small>Open README instructions</small>
20
+ </summary>
21
+ <div class="guide-content readme-content">
22
+ {{ readme_guide_html|safe }}
23
+ </div>
24
+ </details>
25
+ </section>
26
+
27
  <section>
28
  <h2>Dataset to Clean</h2>
29
  {% if clean_filename %}
ui_app.py CHANGED
@@ -2,6 +2,7 @@ import os
2
  import secrets
3
  import sys
4
  import uuid
 
5
  from pathlib import Path
6
 
7
  from flask import Flask, Response, jsonify, render_template, request, send_file, session
@@ -128,6 +129,26 @@ def default_models() -> str:
128
  return ",".join(env_preferred_models or PREFERRED_PRODUCTION_CHAT_MODELS)
129
 
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  def render_page(message: str = "", error: str = ""):
132
  """Render the app with state scoped to the current browser session."""
133
  state = get_state()
@@ -142,6 +163,7 @@ def render_page(message: str = "", error: str = ""):
142
  **state,
143
  default_output_sheet=DEFAULT_OUTPUT_SHEET_NAME,
144
  default_models=default_models(),
 
145
  can_apply=can_apply_blueprint(),
146
  message=message,
147
  error=error,
 
2
  import secrets
3
  import sys
4
  import uuid
5
+ from html import escape
6
  from pathlib import Path
7
 
8
  from flask import Flask, Response, jsonify, render_template, request, send_file, session
 
129
  return ",".join(env_preferred_models or PREFERRED_PRODUCTION_CHAT_MODELS)
130
 
131
 
132
+ def read_readme_guide() -> str:
133
+ """Render README.md content for the in-app collapsible guide."""
134
+ readme_path = APP_ROOT / "README.md"
135
+ if not readme_path.is_file():
136
+ return "<p>User guide is not available.</p>"
137
+
138
+ text = readme_path.read_text(encoding="utf-8")
139
+ if text.startswith("---"):
140
+ parts = text.split("---", 2)
141
+ if len(parts) == 3:
142
+ text = parts[2].lstrip()
143
+
144
+ try:
145
+ import markdown
146
+ except ImportError:
147
+ return f"<pre>{escape(text)}</pre>"
148
+
149
+ return markdown.markdown(text, extensions=["extra", "sane_lists"])
150
+
151
+
152
  def render_page(message: str = "", error: str = ""):
153
  """Render the app with state scoped to the current browser session."""
154
  state = get_state()
 
163
  **state,
164
  default_output_sheet=DEFAULT_OUTPUT_SHEET_NAME,
165
  default_models=default_models(),
166
+ readme_guide_html=read_readme_guide(),
167
  can_apply=can_apply_blueprint(),
168
  message=message,
169
  error=error,