feat: add setup notebook and update env example for Athena
This commit is contained in:
81
app/main.py
81
app/main.py
@@ -48,6 +48,31 @@ def _safe_call(fn, *args, **kwargs):
|
||||
return None
|
||||
|
||||
|
||||
# CRM lookups, cached briefly so the cascading selects stay snappy.
|
||||
@st.cache_data(ttl=120, show_spinner=False)
|
||||
def _crm_clients(_client: TEIClient) -> list[dict]:
|
||||
try:
|
||||
return _client.list_clients()
|
||||
except AthenaAPIError:
|
||||
return []
|
||||
|
||||
|
||||
@st.cache_data(ttl=120, show_spinner=False)
|
||||
def _crm_proposals(_client: TEIClient, client_id: int) -> list[dict]:
|
||||
try:
|
||||
return _client.proposals_for_client(client_id)
|
||||
except AthenaAPIError:
|
||||
return []
|
||||
|
||||
|
||||
@st.cache_data(ttl=120, show_spinner=False)
|
||||
def _crm_engagements(_client: TEIClient, client_name: str) -> list[dict]:
|
||||
try:
|
||||
return _client.engagements_for_client(client_name)
|
||||
except AthenaAPIError:
|
||||
return []
|
||||
|
||||
|
||||
def sidebar_tool_picker(client: TEIClient) -> dict | None:
|
||||
"""Sidebar: pick an existing TEI tool or create one from a report template."""
|
||||
st.sidebar.title("🛡️ Palladium")
|
||||
@@ -71,24 +96,70 @@ def sidebar_tool_picker(client: TEIClient) -> dict | None:
|
||||
else:
|
||||
report_labels = {f"{r['name']} ({r['vendor']} {r['version']})": r for r in reports}
|
||||
r_choice = st.selectbox("Report template", list(report_labels.keys()))
|
||||
new_name = st.text_input("Tool name (optional)", "")
|
||||
proposal_id = st.number_input(
|
||||
"Proposal ID (optional)", min_value=0, value=0, step=1
|
||||
|
||||
# A TEI tool must attach to a Proposal OR an Engagement.
|
||||
# Cascade: client → proposal/engagement, pulled from the CRM.
|
||||
clients = _crm_clients(client)
|
||||
if not clients:
|
||||
st.warning("No CRM clients found — create one in Athena first.")
|
||||
return tool
|
||||
client_labels = {c["name"]: c for c in clients}
|
||||
c_choice = st.selectbox("Client", list(client_labels.keys()))
|
||||
crm_client = client_labels[c_choice]
|
||||
|
||||
attach_kind = st.radio(
|
||||
"Attach to", ["Proposal", "Engagement"], horizontal=True
|
||||
)
|
||||
if st.button("Create"):
|
||||
proposal_id: int | None = None
|
||||
engagement_id: int | None = None
|
||||
if attach_kind == "Proposal":
|
||||
proposals = _crm_proposals(client, crm_client["id"])
|
||||
if proposals:
|
||||
p_labels = {
|
||||
f"{p.get('name')} ({p.get('status')})": p for p in proposals
|
||||
}
|
||||
p_choice = st.selectbox("Proposal", list(p_labels.keys()))
|
||||
proposal_id = p_labels[p_choice]["id"]
|
||||
else:
|
||||
st.info(
|
||||
f"{crm_client['name']} has no proposals. Create one in "
|
||||
"Athena (or via 00_provision.ipynb) first."
|
||||
)
|
||||
else:
|
||||
engagements = _crm_engagements(client, crm_client["name"])
|
||||
if engagements:
|
||||
e_labels = {
|
||||
f"{e.get('name')} ({e.get('status')})": e for e in engagements
|
||||
}
|
||||
e_choice = st.selectbox("Engagement", list(e_labels.keys()))
|
||||
engagement_id = e_labels[e_choice]["id"]
|
||||
else:
|
||||
st.info(f"{crm_client['name']} has no engagements.")
|
||||
|
||||
default_name = f"{crm_client['name']} — {report_labels[r_choice]['name']}"
|
||||
new_name = st.text_input("Tool name", default_name)
|
||||
if st.button(
|
||||
"Create", disabled=proposal_id is None and engagement_id is None
|
||||
):
|
||||
report = report_labels[r_choice]
|
||||
created = _safe_call(
|
||||
client.create_tool,
|
||||
report_public_id=report["id"],
|
||||
proposal=int(proposal_id) or None,
|
||||
proposal=proposal_id,
|
||||
engagement=engagement_id,
|
||||
name=new_name or None,
|
||||
)
|
||||
if created:
|
||||
st.success(f"Created tool {created.get('id')}")
|
||||
st.cache_data.clear()
|
||||
st.rerun()
|
||||
|
||||
if tool:
|
||||
st.sidebar.divider()
|
||||
_opp = tool.get("opportunity") or {}
|
||||
_client_name = (_opp.get("client") or {}).get("name")
|
||||
if _client_name:
|
||||
st.sidebar.markdown(f"**Client**: {_client_name}")
|
||||
st.sidebar.markdown(f"**Public ID**: `{tool.get('id')}`")
|
||||
st.sidebar.markdown(f"**Status**: {tool.get('status', '?')}")
|
||||
st.sidebar.markdown(f"**Version**: {tool.get('current_version', 0)}")
|
||||
|
||||
Reference in New Issue
Block a user