soojeongcrystal commited on
Commit
f3879d0
·
verified ·
1 Parent(s): 8b0b417

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -55
app.py CHANGED
@@ -156,81 +156,89 @@ from streamlit_dnd_list import dnd_list
156
  import json
157
 
158
  # ------------------------------
159
- # PAGE 3. 그룹 조정 (도메인 간 드래그 가능)
160
  # ------------------------------
161
  elif st.session_state.page == "그룹 조정":
162
- st.title("3️⃣ 업무 그룹 ")
163
  st.markdown("""
164
- 드래그앤드랍으로 업무를 자유롭게 이동하세요.
165
- - **도메인 간 이동 가능**
166
- - 도메인은 색상으로 구분되어 있습니다.
167
- - 항목 더블클릭 시 삭제, 하단에서 새 업무 추가 가능.
168
  """)
169
 
170
  st.divider()
171
-
172
- # 도메인 데이터 준비
173
  domains = st.session_state.domains + ["기타"]
174
- grouped = {d: st.session_state.grouped_tasks.get(d, []) for d in domains}
175
-
176
- # 도메인별 색상 팔레트 (파스텔톤)
177
- colors = ["#E3F2FD", "#E8F5E9", "#FFF8E1", "#FCE4EC", "#E0F7FA"]
178
- color_map = {d: colors[i % len(colors)] for i, d in enumerate(domains)}
179
 
180
- # dnd_list를 위한
181
- dnd_data = [{"header": d, "items": grouped[d]} for d in domains]
 
182
 
183
- # CSS (깔끔한 카드형)
184
  st.markdown("""
185
  <style>
186
- .stApp {background-color:#f4f6f8;}
187
- div[data-testid="stVerticalBlock"]>div>div>div>div>div {
188
- background-color: transparent !important;
 
 
 
 
 
 
 
 
 
 
189
  }
190
  </style>
191
  """, unsafe_allow_html=True)
192
 
193
- # DnD 리스트 렌더링
194
- result = dnd_list(
195
- dnd_data,
196
- direction="horizontal", # 도메인 가로 배치
197
- titles=[d for d in domains], # 도메인 이름 표시
198
- background_color="#f4f6f8",
199
- container_style={"padding": "10px"},
200
- card_style={
201
- "padding": "8px 10px",
202
- "margin": "4px",
203
- "borderRadius": "6px",
204
- "backgroundColor": "#fff",
205
- "border": "1px solid #ddd",
206
- "boxShadow": "0 1px 2px rgba(0,0,0,0.1)",
207
- },
208
- header_style={
209
- "fontWeight": "600",
210
- "textAlign": "center",
211
- "padding": "6px",
212
- "borderRadius": "6px",
213
- },
214
- header_colors=[color_map[d] for d in domains],
215
- key="dragdrop",
216
- )
217
-
218
- # 결과 반영 (result는 리스트 구조)
219
- if result:
220
- updated_grouped = {block["header"]: block["items"] for block in result}
221
- st.session_state.grouped_tasks = updated_grouped
222
-
223
- # 업무 추가 영역
224
- st.markdown("---")
225
- st.markdown("### ➕ 새 업무 추가")
226
  cols = st.columns(len(domains))
227
  for i, d in enumerate(domains):
228
  with cols[i]:
229
- new_task = st.text_input(f"{d} 추가", key=f"add_{i}")
230
- if st.button("추가", key=f"btn_add_{i}") and new_task.strip():
231
- st.session_state.grouped_tasks[d].append(new_task.strip())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  st.rerun()
233
 
 
 
 
 
 
234
  st.divider()
235
  c1, c2 = st.columns(2)
236
  if c1.button("⬅️ 이전: 발산 다시보기"):
 
156
  import json
157
 
158
  # ------------------------------
159
+ # PAGE 3. 그룹 조정 (도메인 간 이동 지원, 안정형)
160
  # ------------------------------
161
  elif st.session_state.page == "그룹 조정":
162
+ st.title("3️⃣ 업무 그룹 정리하기")
163
  st.markdown("""
164
+ 도메인별 업무를 확인하고 정리하세요.
165
+ - 각 열은 **도메인**을 나타냅니다.
166
+ - **드래그로 순서 조정**, **다른 도메인으로 이동**, **삭제 및 추가** 모두 가능합니다.
 
167
  """)
168
 
169
  st.divider()
 
 
170
  domains = st.session_state.domains + ["기타"]
171
+ updated_grouped = {d: list(st.session_state.grouped_tasks.get(d, [])) for d in domains}
 
 
 
 
172
 
173
+ # 도메인별 색상 팔레트 (시각 분)
174
+ palette = ["#E3F2FD", "#E8F5E9", "#FFF8E1", "#FCE4EC", "#E0F7FA"]
175
+ domain_colors = {d: palette[i % len(palette)] for i, d in enumerate(domains)}
176
 
177
+ # CSS - 카드 스타일
178
  st.markdown("""
179
  <style>
180
+ .task-card {
181
+ background-color: white;
182
+ border: 1px solid #ccc;
183
+ border-radius: 8px;
184
+ padding: 6px 10px;
185
+ margin-bottom: 6px;
186
+ font-size: 14px;
187
+ box-shadow: 0 1px 2px rgba(0,0,0,0.05);
188
+ }
189
+ .domain-box {
190
+ border-radius: 10px;
191
+ padding: 8px;
192
+ margin: 4px;
193
  }
194
  </style>
195
  """, unsafe_allow_html=True)
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  cols = st.columns(len(domains))
198
  for i, d in enumerate(domains):
199
  with cols[i]:
200
+ bg_color = domain_colors[d]
201
+ st.markdown(f"<div class='domain-box' style='background-color:{bg_color};'>", unsafe_allow_html=True)
202
+ st.markdown(f"### 📦 {d}")
203
+
204
+ tasks = updated_grouped.get(d, [])
205
+ new_task_list = []
206
+
207
+ # 정렬
208
+ sorted_tasks = sort_items(tasks, direction="vertical", key=f"sort_{d}")
209
+
210
+ for t in sorted_tasks:
211
+ c1, c2, c3 = st.columns([4, 1, 1])
212
+ with c1:
213
+ st.markdown(f"<div class='task-card'>{t}</div>", unsafe_allow_html=True)
214
+ with c2:
215
+ if st.button("🗑", key=f"del_{d}_{t}"):
216
+ continue # 삭제
217
+ with c3:
218
+ move_target = st.selectbox(
219
+ "→",
220
+ ["(이동)"] + [x for x in domains if x != d],
221
+ key=f"move_{d}_{t}",
222
+ )
223
+ if move_target != "(이동)":
224
+ # 도메인 간 이동 처리
225
+ st.session_state.grouped_tasks.setdefault(move_target, []).append(t)
226
+ st.session_state.grouped_tasks[d] = [x for x in sorted_tasks if x != t]
227
+ st.rerun()
228
+ new_task_list.append(t)
229
+
230
+ # 새 업무 추가
231
+ new_task = st.text_input(f"{d} 새 업무", key=f"add_{i}")
232
+ if st.button(f"➕ 추가 ({d})", key=f"btn_add_{i}") and new_task.strip():
233
+ new_task_list.append(new_task.strip())
234
+ st.session_state.grouped_tasks[d] = new_task_list
235
  st.rerun()
236
 
237
+ updated_grouped[d] = new_task_list
238
+ st.markdown("</div>", unsafe_allow_html=True)
239
+
240
+ st.session_state.grouped_tasks = updated_grouped
241
+
242
  st.divider()
243
  c1, c2 = st.columns(2)
244
  if c1.button("⬅️ 이전: 발산 다시보기"):