refactor(poc4): modularize HMM interface
This commit is contained in:
@@ -52,6 +52,11 @@ from src.oci_genai_sdk import (
|
||||
)
|
||||
from src.poc3.model_registry import load_model_registry, resolve_model_profile
|
||||
from src.poc3.questions import COMMON_DEMO_QUESTIONS
|
||||
from src.poc4.hmm_ui import (
|
||||
apply_hmm_theme,
|
||||
render_hmm_header,
|
||||
render_hmm_login_brand,
|
||||
)
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -1359,6 +1364,89 @@ html, body, [data-testid="stAppViewContainer"], .stApp {
|
||||
</style>
|
||||
"""
|
||||
|
||||
HMM_CLEAN_THEME_CSS = """
|
||||
<style>
|
||||
:root {
|
||||
--hmm-navy: #003b70;
|
||||
--hmm-ink: #172b3a;
|
||||
--hmm-muted: #667785;
|
||||
--hmm-line: #dfe7ed;
|
||||
--hmm-surface: #ffffff;
|
||||
}
|
||||
|
||||
html, body, [data-testid="stAppViewContainer"], .stApp {
|
||||
background: var(--hmm-surface) !important;
|
||||
color: var(--hmm-ink) !important;
|
||||
font-family: "Noto Sans KR", "Malgun Gothic", sans-serif;
|
||||
}
|
||||
|
||||
#MainMenu, header [data-testid="stToolbar"] { display: none !important; }
|
||||
.block-container { max-width: 1180px; padding: 2rem 3rem 4rem; }
|
||||
|
||||
section[data-testid="stSidebar"] {
|
||||
background: #ffffff !important;
|
||||
border-right: 1px solid var(--hmm-line);
|
||||
}
|
||||
section[data-testid="stSidebar"] > div { background: #ffffff !important; }
|
||||
section[data-testid="stSidebar"] [data-testid="stMarkdownContainer"] p { color: var(--hmm-ink); }
|
||||
|
||||
input, textarea, [data-baseweb="select"] > div {
|
||||
border-radius: 4px !important;
|
||||
border-color: #cfdbe4 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
div[data-testid="stButton"] > button,
|
||||
div[data-testid="stFormSubmitButton"] > button {
|
||||
border-radius: 4px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
div[data-testid="stButton"] > button[kind="primary"],
|
||||
div[data-testid="stFormSubmitButton"] > button[data-testid="stBaseButton-primaryFormSubmit"] {
|
||||
background: var(--hmm-navy) !important;
|
||||
border-color: var(--hmm-navy) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.hmm-app-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 18px;
|
||||
margin: 0 0 28px;
|
||||
padding: 0 0 22px;
|
||||
border-bottom: 1px solid var(--hmm-line);
|
||||
}
|
||||
.hmm-app-wordmark, .hmm-login-wordmark {
|
||||
color: var(--hmm-navy);
|
||||
font-size: 1.35rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.hmm-app-header h1 { margin: 0; color: var(--hmm-ink); font-size: 1.7rem; }
|
||||
.hmm-app-header p { margin: 0; color: var(--hmm-muted); font-size: 0.92rem; }
|
||||
|
||||
.st-key-kb_login_container { max-width: 440px; margin: 12vh auto 0; }
|
||||
.kb-login-brand { text-align: left; }
|
||||
.kb-login-kicker { margin-top: 12px; color: var(--hmm-muted); font-size: 0.76rem; font-weight: 700; }
|
||||
.kb-login-brand h1 { margin: 12px 0 8px; color: var(--hmm-ink); font-size: 1.7rem; }
|
||||
.kb-login-brand p { margin: 0 0 22px; color: var(--hmm-muted); }
|
||||
.st-key-kb_login_container [data-testid="stForm"] {
|
||||
padding: 0; border: 0; background: transparent; box-shadow: none;
|
||||
}
|
||||
.st-key-kb_login_container [data-testid="stFormSubmitButton"] button {
|
||||
min-height: 44px; background: var(--hmm-navy); border-color: var(--hmm-navy);
|
||||
color: #ffffff; box-shadow: none;
|
||||
}
|
||||
.kb-login-note { color: var(--hmm-muted); }
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.block-container { padding: 1.25rem 1.25rem 3rem; }
|
||||
.hmm-app-header { display: block; }
|
||||
.hmm-app-header h1 { margin-top: 10px; }
|
||||
.st-key-kb_login_container { margin-top: 8vh; }
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class McpServer:
|
||||
@@ -1799,8 +1887,8 @@ def _question_label(question: object) -> str:
|
||||
return f"{question_id} · {category} · {text}"
|
||||
|
||||
|
||||
def _apply_kb_theme() -> None:
|
||||
st.markdown(HMM_MINIMAL_THEME_CSS, unsafe_allow_html=True)
|
||||
def _apply_hmm_theme() -> None:
|
||||
apply_hmm_theme(st)
|
||||
|
||||
|
||||
def _portal_auth_value(name: str) -> str:
|
||||
@@ -1900,17 +1988,7 @@ def _clear_portal_remembered_session() -> None:
|
||||
|
||||
def _render_portal_login() -> None:
|
||||
with st.container(key="kb_login_container"):
|
||||
st.markdown(
|
||||
f"""
|
||||
<section class="kb-login-brand">
|
||||
<div class="hmm-login-wordmark" aria-label="HMM">HMM</div>
|
||||
<div class="kb-login-kicker">HMM SHIPPING & LOGISTICS DEMO</div>
|
||||
<h1>HMM AI 업무 에이전트</h1>
|
||||
<p>사용자 인증 후 해운·물류 AI 질의와 보안 관리 기능을 이용할 수 있습니다.</p>
|
||||
</section>
|
||||
""",
|
||||
unsafe_allow_html=True,
|
||||
)
|
||||
render_hmm_login_brand(st)
|
||||
if not _portal_auth_configured():
|
||||
st.error("포털 로그인 설정을 확인해 주세요.")
|
||||
return
|
||||
@@ -1963,27 +2041,8 @@ def _logout_portal() -> None:
|
||||
st.rerun()
|
||||
|
||||
|
||||
def _render_kb_header() -> None:
|
||||
st.markdown(
|
||||
f"""
|
||||
<section class="kb-hero">
|
||||
<div class="kb-hero-main">
|
||||
<div class="kb-brand-row">
|
||||
<div>
|
||||
<div class="kb-brand-name">HMM Digital Operations Demo</div>
|
||||
<div class="kb-brand-sub">Connect Values · Navigate Growth · AI 업무 질의</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1>HMM AI 업무 에이전트</h1>
|
||||
<p>
|
||||
사용자 권한을 기준으로 해운·물류 업무의 AI 질의 응답과 보안 관리를 수행하는
|
||||
DEMO 화면입니다.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
""",
|
||||
unsafe_allow_html=True,
|
||||
)
|
||||
def _render_hmm_header() -> None:
|
||||
render_hmm_header(st)
|
||||
|
||||
|
||||
def _render_vpd_user_card(preset: VpdTokenPreset) -> None:
|
||||
@@ -6859,7 +6918,7 @@ def main() -> None:
|
||||
st.set_page_config(
|
||||
page_title="HMM AI Operations Console", page_icon="⛴️", layout="wide"
|
||||
)
|
||||
_apply_kb_theme()
|
||||
_apply_hmm_theme()
|
||||
_restore_portal_remembered_session()
|
||||
if not st.session_state.get(PORTAL_AUTHENTICATED_KEY, False):
|
||||
_render_portal_login()
|
||||
@@ -6923,7 +6982,7 @@ def main() -> None:
|
||||
)
|
||||
if st.session_state.get(query_model_profile_key) not in model_profile_keys:
|
||||
st.session_state[query_model_profile_key] = default_query_model_profile
|
||||
_render_kb_header()
|
||||
_render_hmm_header()
|
||||
with st.sidebar:
|
||||
st.caption(
|
||||
f"포털 사용자 · {st.session_state.get(PORTAL_AUTH_USER_KEY, '')}"
|
||||
|
||||
Reference in New Issue
Block a user