Skip to content

Commit 6ac1dad

Browse files
committed
Templates
1 parent 9fde535 commit 6ac1dad

File tree

72 files changed

+7621
-1755
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+7621
-1755
lines changed

frontend/src/components/widgets/MarkdownRendererWidget.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const MarkdownRendererWidget = ({ markdown, value, error, className }) => {
4646

4747
return (
4848
<Card className={cn('overflow-hidden', className)}>
49-
<CardContent className="prose max-w-none prose-pre:p-0 prose-pre:bg-transparent prose-pre:m-0 prose-code:bg-muted prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:text-foreground prose-code:before:content-none prose-code:after:content-none">
49+
<CardContent className="prose max-w-none prose-pre:p-0 prose-pre:bg-transparent prose-pre:m-0 prose-code:bg-muted prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:text-foreground prose-code:before:content-none prose-code:after:content-none prose-headings:mt-2 prose-headings:mb-2 prose-p:my-0 prose-p:mb-0.5">
5050
<ReactMarkdown
5151
remarkPlugins={[remarkGfm, remarkSlug]}
5252
components={{
Lines changed: 100 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,105 @@
1-
import pandas as pd
2-
import plotly.express as px
3-
from preswald import (
4-
Workflow,
5-
get_df,
6-
text,
7-
selectbox,
8-
table,
9-
progress,
10-
plotly,
11-
separator,
12-
checkbox,
13-
alert,
14-
)
1+
from preswald import Workflow, text
152

163
workflow = Workflow()
174

18-
# 1. Load and normalize data
195
@workflow.atom()
20-
def load_data():
21-
df = get_df("sample_csv")
22-
23-
# Normalize column names: snake_case, stripped
24-
df.columns = (
25-
df.columns
26-
.str.strip()
27-
.str.lower()
28-
.str.replace(" ", "_")
29-
.str.replace("%", "", regex=False)
30-
)
31-
32-
# Parse progress column if it exists
33-
if "strategic_goals_progress" in df.columns:
34-
try:
35-
df["strategic_goals_progress"] = (
36-
df["strategic_goals_progress"]
37-
.astype(str)
38-
.str.replace('%', '', regex=False)
39-
.str.strip()
40-
.astype(float)
41-
)
42-
except Exception as e:
43-
alert(f"⚠️ Failed to parse strategic progress: {e}", level="error")
44-
45-
return df
46-
47-
# 2. Quarter selector
48-
@workflow.atom(dependencies=["load_data"])
49-
def quarter_selector(load_data):
50-
if "quarter" not in load_data.columns:
51-
alert("❌ Missing 'quarter' column.", level="error")
52-
return None
53-
54-
quarters = sorted(load_data["quarter"].dropna().unique())
55-
return selectbox("📅 Select a Quarter", options=quarters, default=quarters[-1])
56-
57-
# 3. Filtered snapshot
58-
@workflow.atom(dependencies=["load_data", "quarter_selector"])
59-
def filtered_snapshot(load_data, quarter_selector):
60-
if quarter_selector is None:
61-
return pd.DataFrame()
62-
63-
df_q = load_data[load_data["quarter"] == quarter_selector]
64-
if df_q.empty:
65-
alert(f"No data found for quarter: {quarter_selector}", level="warning")
66-
return df_q
67-
68-
# 4. Executive summary
69-
@workflow.atom(dependencies=["filtered_snapshot"])
70-
def executive_summary(filtered_snapshot):
71-
if filtered_snapshot.empty:
72-
return
73-
74-
qtr = filtered_snapshot["quarter"].iloc[0]
75-
avg_rev = filtered_snapshot["revenue"].mean()
76-
avg_profit = filtered_snapshot["profit"].mean()
77-
78-
text(f"# 📊 Executive Summary — {qtr}")
79-
text(f"**Average Revenue:** ${avg_rev:,.0f} &nbsp;&nbsp;&nbsp; **Average Profit:** ${avg_profit:,.0f}")
80-
separator()
81-
82-
# 5. Financial bar chart
83-
@workflow.atom(dependencies=["filtered_snapshot"])
84-
def financial_chart(filtered_snapshot):
85-
if filtered_snapshot.empty:
86-
return
87-
88-
text("## 💰 Financial Performance")
89-
fig = px.bar(
90-
filtered_snapshot,
91-
x="quarter",
92-
y=["revenue", "profit"],
93-
barmode="group",
94-
title="Revenue & Profit",
95-
labels={"value": "USD", "variable": "Metric"},
96-
)
97-
plotly(fig)
98-
separator()
99-
100-
# 6. Strategic goals progress
101-
@workflow.atom(dependencies=["filtered_snapshot"])
102-
def strategy_progress(filtered_snapshot):
103-
if "strategic_goals_progress" not in filtered_snapshot.columns:
104-
alert("Missing 'strategic_goals_progress' column.", level="info")
105-
return
106-
107-
text("## 🎯 Strategic Goals Progress")
108-
for _, row in filtered_snapshot.iterrows():
109-
progress(label=f"{row['quarter']}", value=row["strategic_goals_progress"])
110-
separator()
111-
112-
# 7. Key initiatives & risks
113-
@workflow.atom(dependencies=["filtered_snapshot"])
114-
def initiatives_summary(filtered_snapshot):
115-
text("## 📌 Key Initiatives and Risk Factors")
116-
expected_cols = ["quarter", "key_initiatives_status", "risk_factors"]
117-
for col in expected_cols:
118-
if col not in filtered_snapshot.columns:
119-
alert(f"Column '{col}' is missing from the data.", level="warning")
120-
return
121-
122-
table(filtered_snapshot[expected_cols])
123-
separator()
124-
125-
# 8. Talent & hiring overview
126-
@workflow.atom(dependencies=["filtered_snapshot"])
127-
def hiring_summary(filtered_snapshot):
128-
text("## 🧑‍💼 Talent & Hiring Overview")
129-
130-
if "open_positions" in filtered_snapshot.columns:
131-
avg_open = filtered_snapshot["open_positions"].mean()
132-
text(f"**Avg. Open Positions:** {avg_open:.1f}")
133-
134-
if "hiring_plan_status" in filtered_snapshot.columns:
135-
fig = px.bar(
136-
filtered_snapshot,
137-
x="quarter",
138-
y="open_positions",
139-
color="hiring_plan_status",
140-
title="Hiring Plan Status by Quarter"
141-
)
142-
plotly(fig)
143-
else:
144-
alert("Missing 'open_positions' column.", level="warning")
145-
146-
separator()
147-
148-
# 9. Optional raw table view
149-
@workflow.atom(dependencies=["filtered_snapshot"])
150-
def optional_table(filtered_snapshot):
151-
if checkbox("🔍 Show raw data for selected quarter"):
152-
table(filtered_snapshot, title="Raw Data Snapshot")
153-
154-
# Run it!
6+
def intro():
7+
text("# Board Meeting Report")
8+
text("**Company:** NimbusFlow, Inc. \n**Prepared for:** Board of Directors \n**Purpose:** Quarterly update covering financial results, strategic milestones, customer growth, and operational highlights for Q1.")
9+
10+
@workflow.atom()
11+
def executive_summary():
12+
text("## Executive Summary")
13+
text("""
14+
NimbusFlow, a SaaS platform for automating approval workflows, saw accelerated adoption in Q1, particularly among mid-market and international accounts. With revenue growing faster than expected and churn reaching an all-time low, we enter Q2 with strong momentum.
15+
""")
16+
17+
@workflow.atom()
18+
def financial_results():
19+
text("## Financial Results")
20+
text("""
21+
- **MRR:** $720K (Q/Q +22%)
22+
- **ARR:** $8.64M
23+
- **Gross Margin:** 78%
24+
- **Operating Expenses:** $1.9M
25+
- **Cash Position:** $11.2M
26+
- **Runway:** 18+ months at current burn
27+
28+
We exceeded our MRR forecast by 7% and maintained healthy margins despite increased R&D spending.
29+
""")
30+
31+
@workflow.atom()
32+
def strategic_initiatives():
33+
text("## Strategic Initiatives")
34+
text("""
35+
Key strategic workstreams advanced this quarter:
36+
37+
- **Workflow Templates Library** – Launched with 40+ plug-and-play use cases.
38+
- **AI Suggest** – Beta feature that recommends approval paths based on historical patterns.
39+
- **Data Residency Controls** – Early access enabled for select EU customers ahead of full GDPR compliance rollout in Q2.
40+
""")
41+
42+
@workflow.atom()
43+
def product_updates():
44+
text("## Product Updates")
45+
text("""
46+
- **New Integrations:** Slack, HubSpot, and Azure AD added to the integration hub.
47+
- **Admin Console Redesign:** Modern UI with role-based access control and audit logs.
48+
- **Mobile Enhancements:** Push notifications and offline mode now live for iOS and Android.
49+
50+
Customer feedback on the new features has been positive, especially in high-volume ops teams.
51+
""")
52+
53+
@workflow.atom()
54+
def customer_growth():
55+
text("## Customer Growth")
56+
text("""
57+
- **New Customers:** 89 logos added in Q1, including FinchBank, CoastalRX, and Alignly.
58+
- **Churn:** 2.3% (vs. 3.1% last quarter)
59+
- **Expansion Revenue:** $370K from seat and usage-based upgrades
60+
61+
The SMB segment remains our highest-volume engine, while enterprise accounts drove most upsell revenue.
62+
""")
63+
64+
@workflow.atom()
65+
def hiring_and_team():
66+
text("## Team & Hiring")
67+
text("""
68+
We added 14 new employees this quarter across:
69+
70+
- **Engineering (7)** – Platform, security, and mobile
71+
- **Customer Success (3)** – US and EMEA
72+
- **Go-To-Market (4)** – AE, BDR, and content
73+
74+
Time-to-productivity for new hires is down 20% thanks to an improved onboarding track.
75+
""")
76+
77+
@workflow.atom()
78+
def operational_risks():
79+
text("## Operational Risks")
80+
text("""
81+
- **Load Spikes in EU Datacenter:** Mitigated by migrating shared tenants to scalable node pools.
82+
- **Onboarding Drop-off (SMB):** New cohort analysis revealed a sharp decline in activation by day 7. CX is investigating.
83+
- **Talent Competition:** Backend hiring in SF and NY is slower than forecast. Exploring remote-first roles in LATAM and Canada.
84+
""")
85+
86+
@workflow.atom()
87+
def q2_roadmap():
88+
text("## Q2 Roadmap Priorities")
89+
text("""
90+
- **General Availability: AI Suggest**
91+
- **SOC 2 Type II Audit Completion**
92+
- **Self-Serve Billing & Plan Management**
93+
- **Partnership Launch with Zenith HRIS**
94+
95+
These efforts align with our goals around automation, compliance, and monetization flexibility.
96+
""")
97+
98+
@workflow.atom()
99+
def closing_notes():
100+
text("## Closing Remarks")
101+
text("""
102+
NimbusFlow is entering Q2 with clear direction, strong team execution, and continued market pull. As we build on our product and customer base, our focus will remain on scalability, security, and delivering fast value to every team that runs on Nimbus.
103+
""")
104+
155105
workflow.execute()

0 commit comments

Comments
 (0)