refactor: rename DTree to DValue
This commit is contained in:
@@ -6,7 +6,7 @@ COMPONENT(Request& context)
|
||||
String subtitle = first(context.props["subtitle"].to_string(), "Choose your preferred authentication method");
|
||||
String callback_url = first(context.props["callback_url"].to_string(), app_link("auth/callback", context));
|
||||
|
||||
DTree services = context.props["services"];
|
||||
DValue services = context.props["services"];
|
||||
if(services.get_type_name() != "array" || services["google"]["name"].to_string() == "")
|
||||
{
|
||||
services["google"]["name"] = "Google";
|
||||
@@ -40,7 +40,7 @@ COMPONENT(Request& context)
|
||||
<h2><?= title ?></h2>
|
||||
<label><?= subtitle ?></label>
|
||||
</div>
|
||||
<? services.each([&](DTree service, String service_key) {
|
||||
<? services.each([&](DValue service, String service_key) {
|
||||
String client_id = context.props[service_key + "_client_id"].to_string();
|
||||
String handler_name = ascii_safe_name(service_key);
|
||||
String service_name = service["name"].to_string();
|
||||
|
||||
@@ -34,9 +34,9 @@ String data_format_bytes(String raw, bool disk = false)
|
||||
return(String(buf) + " " + units[unit_index]);
|
||||
}
|
||||
|
||||
DTree data_format_value(DTree value, DTree row, DTree column)
|
||||
DValue data_format_value(DValue value, DValue row, DValue column)
|
||||
{
|
||||
DTree result;
|
||||
DValue result;
|
||||
String format = column["format"].to_string();
|
||||
String raw = value.to_string();
|
||||
String sort_value = raw;
|
||||
@@ -98,7 +98,7 @@ COMPONENT:SUMMARY_METRICS(Request& context)
|
||||
</div>
|
||||
<? } ?>
|
||||
<div class="dashboard-stat-grid">
|
||||
<? context.props["items"].each([&](DTree item, String key) {
|
||||
<? context.props["items"].each([&](DValue item, String key) {
|
||||
String tone = first(item["tone"].to_string(), "info");
|
||||
String href = item["href"].to_string();
|
||||
String tag = href != "" ? "a" : "div";
|
||||
@@ -162,7 +162,7 @@ COMPONENT:SORTABLE_TABLE(Request& context)
|
||||
String subtitle = context.props["subtitle"].to_string();
|
||||
String empty_label = first(context.props["empty_label"].to_string(), "No data available");
|
||||
|
||||
DTree init_options;
|
||||
DValue init_options;
|
||||
init_options["storageKey"] = first(context.props["storage_key"].to_string(), "starter.sort." + table_id);
|
||||
if(context.props["sort"]["column"].to_string() != "")
|
||||
{
|
||||
@@ -182,7 +182,7 @@ COMPONENT:SORTABLE_TABLE(Request& context)
|
||||
<table id="<?= table_id ?>" class="u-sortable-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<? context.props["columns"].each([&](DTree column, String key) {
|
||||
<? context.props["columns"].each([&](DValue column, String key) {
|
||||
String align = first(column["align"].to_string(), "left");
|
||||
bool sortable = column["sortable"].to_string() == "" || column["sortable"].to_string() == "1";
|
||||
?><th scope="col" class="align-<?= align ?>"<?= sortable ? "" : " data-sortable=\"false\"" ?>><?= first(column["label"].to_string(), column["key"].to_string(), "Column") ?></th><?
|
||||
@@ -193,13 +193,13 @@ COMPONENT:SORTABLE_TABLE(Request& context)
|
||||
<? if(context.props["rows"].get_type_name() != "array" || context.props["rows"]["0"].get_type_name() != "array") { ?>
|
||||
<tr data-empty-row="1"><td colspan="<?= context.props["columns"]._map.size() == 0 ? "1" : std::to_string(context.props["columns"]._map.size()) ?>" class="muted"><?= empty_label ?></td></tr>
|
||||
<? } ?>
|
||||
<? context.props["rows"].each([&](DTree row, String key) {
|
||||
<? context.props["rows"].each([&](DValue row, String key) {
|
||||
if(row.get_type_name() != "array")
|
||||
return;
|
||||
?><tr><?
|
||||
context.props["columns"].each([&](DTree column, String ckey) {
|
||||
context.props["columns"].each([&](DValue column, String ckey) {
|
||||
String col_key = column["key"].to_string();
|
||||
DTree formatted = data_format_value(row[col_key], row, column);
|
||||
DValue formatted = data_format_value(row[col_key], row, column);
|
||||
?><td class="align-<?= first(column["align"].to_string(), "left") ?>" data-sort-value="<?= formatted["sort"].to_string() ?>"><?= formatted["display"].to_string() ?></td><?
|
||||
});
|
||||
?></tr><?
|
||||
@@ -221,7 +221,7 @@ COMPONENT:DATA_TABLE(Request& context)
|
||||
{
|
||||
String table_id = first(context.props["id"].to_string(), "data-grid-" + std::to_string((u64)time()));
|
||||
|
||||
DTree columns = context.props["columns"];
|
||||
DValue columns = context.props["columns"];
|
||||
if(columns.get_type_name() != "array")
|
||||
columns.set_array();
|
||||
bool has_explicit_columns = columns.is_list() &&
|
||||
@@ -230,8 +230,8 @@ COMPONENT:DATA_TABLE(Request& context)
|
||||
columns["0"]["field"].to_string() != "";
|
||||
if(!has_explicit_columns && context.props["items"]["0"].get_type_name() == "array")
|
||||
{
|
||||
context.props["items"]["0"].each([&](DTree value, String key) {
|
||||
DTree col;
|
||||
context.props["items"]["0"].each([&](DValue value, String key) {
|
||||
DValue col;
|
||||
col["field"] = key;
|
||||
col["headerName"] = key;
|
||||
col["sortable"].set_bool(true);
|
||||
@@ -242,30 +242,30 @@ COMPONENT:DATA_TABLE(Request& context)
|
||||
}
|
||||
if(!columns.is_list())
|
||||
{
|
||||
DTree normalized_columns;
|
||||
DValue normalized_columns;
|
||||
normalized_columns.set_array();
|
||||
columns.each([&](DTree column, String key) {
|
||||
columns.each([&](DValue column, String key) {
|
||||
if(column.get_type_name() == "array")
|
||||
normalized_columns.push(column);
|
||||
});
|
||||
columns = normalized_columns;
|
||||
}
|
||||
|
||||
DTree row_data = context.props["items"];
|
||||
DValue row_data = context.props["items"];
|
||||
if(row_data.get_type_name() != "array")
|
||||
row_data.set_array();
|
||||
if(!row_data.is_list())
|
||||
{
|
||||
DTree normalized_rows;
|
||||
DValue normalized_rows;
|
||||
normalized_rows.set_array();
|
||||
row_data.each([&](DTree row, String key) {
|
||||
row_data.each([&](DValue row, String key) {
|
||||
if(row.get_type_name() == "array")
|
||||
normalized_rows.push(row);
|
||||
});
|
||||
row_data = normalized_rows;
|
||||
}
|
||||
|
||||
DTree grid_options;
|
||||
DValue grid_options;
|
||||
grid_options["pagination"].set_bool(true);
|
||||
grid_options["paginationPageSize"] = first(context.props["options"]["paginationPageSize"].to_string(), "20");
|
||||
grid_options["paginationPageSizeSelector"].set_bool(false);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
void marketing_default_features(DTree& features)
|
||||
void marketing_default_features(DValue& features)
|
||||
{
|
||||
if(features.get_type_name() == "array" && features["0"]["title"].to_string() != "")
|
||||
return;
|
||||
DTree item;
|
||||
DValue item;
|
||||
|
||||
item["icon"] = "⚡";
|
||||
item["title"] = "Lightning Fast";
|
||||
@@ -194,7 +194,7 @@ COMPONENT:HERO_SECTION(Request& context)
|
||||
|
||||
COMPONENT:FEATURES_GRID(Request& context)
|
||||
{
|
||||
DTree features = context.props["features"];
|
||||
DValue features = context.props["features"];
|
||||
marketing_default_features(features);
|
||||
|
||||
<>
|
||||
@@ -204,7 +204,7 @@ COMPONENT:FEATURES_GRID(Request& context)
|
||||
<p>Discover the powerful features that make development a breeze</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<? features.each([&](DTree feature, String key) {
|
||||
<? features.each([&](DValue feature, String key) {
|
||||
?><div class="feature-card">
|
||||
<div class="feature-icon"><?: feature["icon"].to_string() ?></div>
|
||||
<h3 class="feature-title"><?= feature["title"].to_string() ?></h3>
|
||||
@@ -288,10 +288,10 @@ COMPONENT:FEATURES_GRID(Request& context)
|
||||
|
||||
COMPONENT:STATS_SECTION(Request& context)
|
||||
{
|
||||
DTree stats = context.props["stats"];
|
||||
DValue stats = context.props["stats"];
|
||||
if(stats.get_type_name() != "array" || stats["0"]["label"].to_string() == "")
|
||||
{
|
||||
DTree item;
|
||||
DValue item;
|
||||
item["number"] = "99.9%"; item["label"] = "Uptime"; stats.push(item); item.clear();
|
||||
item["number"] = "500ms"; item["label"] = "Average Response"; stats.push(item); item.clear();
|
||||
item["number"] = "50K+"; item["label"] = "Active Users"; stats.push(item); item.clear();
|
||||
@@ -306,7 +306,7 @@ COMPONENT:STATS_SECTION(Request& context)
|
||||
<p>Join thousands of developers who have chosen our framework</p>
|
||||
</div>
|
||||
<div class="stats-grid">
|
||||
<? stats.each([&](DTree stat, String key) {
|
||||
<? stats.each([&](DValue stat, String key) {
|
||||
?><div class="stat-item">
|
||||
<div class="stat-number"><?= stat["number"].to_string() ?></div>
|
||||
<div class="stat-label"><?= stat["label"].to_string() ?></div>
|
||||
@@ -364,10 +364,10 @@ COMPONENT:STATS_SECTION(Request& context)
|
||||
|
||||
COMPONENT:BRANDS_SHOWCASE(Request& context)
|
||||
{
|
||||
DTree logos = context.props["logos"];
|
||||
DValue logos = context.props["logos"];
|
||||
if(logos.get_type_name() != "array" || logos["0"]["name"].to_string() == "")
|
||||
{
|
||||
DTree item;
|
||||
DValue item;
|
||||
for(s32 i = 1; i <= 6; i++)
|
||||
{
|
||||
item["name"] = "Brand " + std::to_string(i);
|
||||
@@ -383,7 +383,7 @@ COMPONENT:BRANDS_SHOWCASE(Request& context)
|
||||
<div class="brands-container">
|
||||
<h3 class="brands-title"><?= title ?></h3>
|
||||
<div class="brands-grid">
|
||||
<? logos.each([&](DTree logo, String key) {
|
||||
<? logos.each([&](DValue logo, String key) {
|
||||
?><div class="brand-item">
|
||||
<img src="<?= logo["url"].to_string() ?>" alt="<?= logo["name"].to_string() ?>" />
|
||||
</div><?
|
||||
@@ -410,10 +410,10 @@ COMPONENT:BRANDS_SHOWCASE(Request& context)
|
||||
|
||||
COMPONENT:TESTIMONIALS(Request& context)
|
||||
{
|
||||
DTree testimonials = context.props["testimonials"];
|
||||
DValue testimonials = context.props["testimonials"];
|
||||
if(testimonials.get_type_name() != "array" || testimonials["0"]["name"].to_string() == "")
|
||||
{
|
||||
DTree item;
|
||||
DValue item;
|
||||
item["name"] = "Sarah Johnson"; item["role"] = "Senior Developer at TechCorp"; item["avatar"] = "img/cat01.jpg"; item["content"] = "This framework has revolutionized our development process."; item["rating"] = "5"; testimonials.push(item); item.clear();
|
||||
item["name"] = "Michael Chen"; item["role"] = "CTO at StartupX"; item["avatar"] = "img/cat02.jpg"; item["content"] = "We switched from our legacy system and saw immediate improvements."; item["rating"] = "5"; testimonials.push(item); item.clear();
|
||||
item["name"] = "Emily Rodriguez"; item["role"] = "Full Stack Developer"; item["avatar"] = "img/cat03.jpg"; item["content"] = "The documentation is excellent and the learning curve is gentle."; item["rating"] = "5"; testimonials.push(item);
|
||||
@@ -427,7 +427,7 @@ COMPONENT:TESTIMONIALS(Request& context)
|
||||
<p>Don't just take our word for it - hear from the community</p>
|
||||
</div>
|
||||
<div class="testimonials-grid">
|
||||
<? testimonials.each([&](DTree testimonial, String key) {
|
||||
<? testimonials.each([&](DValue testimonial, String key) {
|
||||
?><div class="testimonial-card">
|
||||
<div class="testimonial-content">
|
||||
<div class="quote-icon">"</div>
|
||||
@@ -473,11 +473,11 @@ COMPONENT:TESTIMONIALS(Request& context)
|
||||
|
||||
COMPONENT:PRICING_TABLE(Request& context)
|
||||
{
|
||||
DTree plans = context.props["plans"];
|
||||
DValue plans = context.props["plans"];
|
||||
if(plans.get_type_name() != "array" || plans["0"]["name"].to_string() == "")
|
||||
{
|
||||
DTree plan;
|
||||
DTree feature;
|
||||
DValue plan;
|
||||
DValue feature;
|
||||
|
||||
plan["name"] = "Starter"; plan["price"] = "Free"; plan["period"] = ""; plan["description"] = "Perfect for small projects and learning"; plan["cta"] = "Start Free"; feature = "Up to 3 projects"; plan["features"].push(feature); feature = "Community support"; plan["features"].push(feature); feature = "Basic components"; plan["features"].push(feature); plans.push(plan); plan.clear();
|
||||
plan["name"] = "Pro"; plan["price"] = "$24"; plan["period"] = "/mo"; plan["description"] = "For serious products and teams"; plan["cta"] = "Choose Pro"; plan["popular"].set_bool(true); feature = "Unlimited projects"; plan["features"].push(feature); feature = "Priority support"; plan["features"].push(feature); feature = "Advanced components"; plan["features"].push(feature); plans.push(plan); plan.clear();
|
||||
@@ -492,7 +492,7 @@ COMPONENT:PRICING_TABLE(Request& context)
|
||||
<p>Choose the plan that fits your product stage.</p>
|
||||
</div>
|
||||
<div class="pricing-grid">
|
||||
<? plans.each([&](DTree plan, String key) {
|
||||
<? plans.each([&](DValue plan, String key) {
|
||||
bool popular = plan["popular"].to_string() != "";
|
||||
?><div class="pricing-card<?= popular ? " popular" : "" ?>">
|
||||
<? if(popular) { ?><div class="popular-badge">Most Popular</div><? } ?>
|
||||
@@ -505,7 +505,7 @@ COMPONENT:PRICING_TABLE(Request& context)
|
||||
<p class="plan-description"><?= plan["description"].to_string() ?></p>
|
||||
</div>
|
||||
<ul class="plan-features">
|
||||
<? plan["features"].each([&](DTree feature, String feature_key) { ?><li><?= feature.to_string() ?></li><? }); ?>
|
||||
<? plan["features"].each([&](DValue feature, String feature_key) { ?><li><?= feature.to_string() ?></li><? }); ?>
|
||||
</ul>
|
||||
<div class="plan-footer">
|
||||
<button class="btn <?= popular ? "btn-primary" : "btn-outline" ?> btn-large plan-cta"><?= first(plan["cta"].to_string(), "Choose Plan") ?></button>
|
||||
|
||||
@@ -107,7 +107,7 @@ COMPONENT(Request& context)
|
||||
<div id="theme-menu" class="theme-menu" hidden>
|
||||
<div class="theme-menu-title">Available Themes</div>
|
||||
<div class="theme-menu-list">
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DTree theme_info, String theme_key) {
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DValue theme_info, String theme_key) {
|
||||
StringMap params;
|
||||
params["theme"] = theme_key;
|
||||
String href = app_link(route_path == "index" ? "" : route_path, params, context);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "themes/common/css/gauges.css";
|
||||
asset_props["js"]["0"] = "components/gauges/common.js";
|
||||
print(component("../theme/assets", asset_props, context));
|
||||
@@ -11,7 +11,7 @@ COMPONENT(Request& context)
|
||||
String title = context.props["title"].to_string();
|
||||
String subtitle = context.props["subtitle"].to_string();
|
||||
String style = context.props["style"].to_string();
|
||||
DTree scale = context.props["scale"];
|
||||
DValue scale = context.props["scale"];
|
||||
|
||||
<>
|
||||
<div class="arcgauge-set" id="<?= gauge_attr_id(gauge_id) ?>" style="<?= style ?>">
|
||||
@@ -22,9 +22,9 @@ COMPONENT(Request& context)
|
||||
</div>
|
||||
<? } ?>
|
||||
<div class="arcgauge-grid">
|
||||
<? context.props["items"].each([&](DTree item, String item_id_raw) {
|
||||
DTree merged = scale;
|
||||
item.each([&](DTree value, String key) { merged[key] = value; });
|
||||
<? context.props["items"].each([&](DValue item, String item_id_raw) {
|
||||
DValue merged = scale;
|
||||
item.each([&](DValue value, String key) { merged[key] = value; });
|
||||
String item_id = gauge_attr_id(item_id_raw);
|
||||
f64 value = float_val(first(merged["value"].to_string(), "0"));
|
||||
f64 max_value = float_val(first(merged["max"].to_string(), "100"));
|
||||
|
||||
@@ -21,10 +21,10 @@ String gauge_attr_id(String value)
|
||||
return(ascii_safe_name(value));
|
||||
}
|
||||
|
||||
String gauge_range_color(DTree ranges, f64 value)
|
||||
String gauge_range_color(DValue ranges, f64 value)
|
||||
{
|
||||
String matched = "";
|
||||
ranges.each([&](DTree range, String key) {
|
||||
ranges.each([&](DValue range, String key) {
|
||||
f64 from_value = float_val(first(range["from"].to_string(), "-999999999"));
|
||||
f64 to_value = float_val(first(range["to"].to_string(), "999999999"));
|
||||
if(value >= from_value && value <= to_value && matched == "")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "themes/common/css/gauges.css";
|
||||
asset_props["js"]["0"] = "components/gauges/common.js";
|
||||
print(component("../theme/assets", asset_props, context));
|
||||
@@ -12,7 +12,7 @@ COMPONENT(Request& context)
|
||||
String title = context.props["title"].to_string();
|
||||
String subtitle = context.props["subtitle"].to_string();
|
||||
f64 size = float_val(first(context.props["size"].to_string(), "200"));
|
||||
DTree scale = context.props["scale"];
|
||||
DValue scale = context.props["scale"];
|
||||
f64 scale_angle_start = float_val(first(scale["angle_start"].to_string(), std::to_string(-gauge_pi())));
|
||||
f64 scale_angle_end = float_val(first(scale["angle_end"].to_string(), "0"));
|
||||
f64 img_height = float_val(first(context.props["img_height"].to_string(), std::to_string(size * std::max(cos(scale_angle_start), cos(scale_angle_end)))));
|
||||
@@ -26,9 +26,9 @@ COMPONENT(Request& context)
|
||||
</div>
|
||||
<? } ?>
|
||||
<div class="needlegauge-grid">
|
||||
<? context.props["items"].each([&](DTree item, String item_id_raw) {
|
||||
DTree merged = scale;
|
||||
item.each([&](DTree value, String key) { merged[key] = value; });
|
||||
<? context.props["items"].each([&](DValue item, String item_id_raw) {
|
||||
DValue merged = scale;
|
||||
item.each([&](DValue value, String key) { merged[key] = value; });
|
||||
String item_id = gauge_attr_id(item_id_raw);
|
||||
String label = first(merged["label"].to_string(), item_id_raw);
|
||||
String tooltip = merged["tooltip"].to_string();
|
||||
@@ -85,7 +85,7 @@ COMPONENT(Request& context)
|
||||
String segments_html = "";
|
||||
if(merged["color"].get_type_name() == "array")
|
||||
{
|
||||
merged["color"].each([&](DTree range, String key) {
|
||||
merged["color"].each([&](DValue range, String key) {
|
||||
f64 range_from = std::max(float_val(first(range["from"].to_string(), std::to_string(min_value))), min_value);
|
||||
f64 range_to = std::min(float_val(first(range["to"].to_string(), std::to_string(max_value))), max_value);
|
||||
f64 angle_from = angle_start + ((range_from - min_value) / vrange) * (angle_end - angle_start);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "themes/common/css/gauges.css";
|
||||
asset_props["js"]["0"] = "components/gauges/common.js";
|
||||
print(component("../theme/assets", asset_props, context));
|
||||
@@ -17,8 +17,8 @@ COMPONENT(Request& context)
|
||||
String subtitle = context.props["subtitle"].to_string();
|
||||
String layout = first(context.props["layout"].to_string(), "horizontal");
|
||||
String bar_color_default = context.props["bar-color"].to_string();
|
||||
DTree scale = context.props["scale"];
|
||||
DTree markers = context.props["markers"];
|
||||
DValue scale = context.props["scale"];
|
||||
DValue markers = context.props["markers"];
|
||||
|
||||
StringList default_palette;
|
||||
default_palette.push_back("var(--success, #10b981)");
|
||||
@@ -37,9 +37,9 @@ COMPONENT(Request& context)
|
||||
<? } ?>
|
||||
<? if(layout == "horizontal") { ?>
|
||||
<div class="progressbar-grid progressbar-grid-horizontal">
|
||||
<? context.props["items"].each([&](DTree bar, String bar_id) {
|
||||
DTree merged = scale;
|
||||
bar.each([&](DTree item, String key) { merged[key] = item; });
|
||||
<? context.props["items"].each([&](DValue bar, String bar_id) {
|
||||
DValue merged = scale;
|
||||
bar.each([&](DValue item, String key) { merged[key] = item; });
|
||||
String item_id = gauge_attr_id(bar_id);
|
||||
String merged_item_style = item_style;
|
||||
if(merged["style"].to_string() != "")
|
||||
@@ -73,7 +73,7 @@ COMPONENT(Request& context)
|
||||
<div class="progressbar-background progressbar-background-horizontal">
|
||||
<div class="progressbar-bar" id="<?= gauge_attr_id(gauge_id) ?>-<?= item_id ?>-bar"
|
||||
style="background-color: <?= resolved_color ?>; <?= bar_style ?> opacity: <?= opacity ?>; width: <?= std::to_string(pct_value) ?>%;"></div>
|
||||
<? markers.each([&](DTree marker, String marker_id) {
|
||||
<? markers.each([&](DValue marker, String marker_id) {
|
||||
f64 marker_value = float_val(first(marker["value"].to_string(), "0"));
|
||||
f64 marker_pct = gauge_clamp_value(((marker_value - min_value) / vrange) * 100.0, 0.0, 100.0);
|
||||
String marker_color = first(marker["color"].to_string(), "var(--primary-light)");
|
||||
@@ -89,9 +89,9 @@ COMPONENT(Request& context)
|
||||
</div>
|
||||
<? } else { ?>
|
||||
<div class="progressbar-grid progressbar-grid-vertical" style="--progressbar-height: <?= first(context.props["height"].to_string(), "240") ?>px;">
|
||||
<? context.props["items"].each([&](DTree bar, String bar_id) {
|
||||
DTree merged = scale;
|
||||
bar.each([&](DTree item, String key) { merged[key] = item; });
|
||||
<? context.props["items"].each([&](DValue bar, String bar_id) {
|
||||
DValue merged = scale;
|
||||
bar.each([&](DValue item, String key) { merged[key] = item; });
|
||||
String item_id = gauge_attr_id(bar_id);
|
||||
String merged_item_style = item_style;
|
||||
if(merged["style"].to_string() != "")
|
||||
@@ -122,7 +122,7 @@ COMPONENT(Request& context)
|
||||
<div class="progressbar-background progressbar-background-vertical">
|
||||
<div class="progressbar-bar" id="<?= gauge_attr_id(gauge_id) ?>-<?= item_id ?>-bar"
|
||||
style="background-color: <?= resolved_color ?>; <?= bar_style ?> opacity: <?= opacity ?>; height: <?= std::to_string(pct_value) ?>%;"></div>
|
||||
<? markers.each([&](DTree marker, String marker_id) {
|
||||
<? markers.each([&](DValue marker, String marker_id) {
|
||||
f64 marker_value = float_val(first(marker["value"].to_string(), "0"));
|
||||
f64 marker_pct = gauge_clamp_value(((marker_value - min_value) / vrange) * 100.0, 0.0, 100.0);
|
||||
String marker_color = first(marker["color"].to_string(), "var(--primary-light)");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
StarterUser users(context);
|
||||
DTree user = users.current();
|
||||
DValue user = users.current();
|
||||
bool signed_in = user["email"].to_string() != "";
|
||||
String theme_key = context.cfg.get_by_path("theme/key").to_string();
|
||||
String wrapper_class = first(context.props["wrapper_class"].to_string(), theme_key == "localfirst" ? "admin-account-card" : "nav-account nav-menu");
|
||||
|
||||
@@ -18,7 +18,7 @@ void app_asset_tag_once(Request& context, String kind, String path)
|
||||
}
|
||||
}
|
||||
|
||||
void app_asset_tags(Request& context, String kind, DTree assets)
|
||||
void app_asset_tags(Request& context, String kind, DValue assets)
|
||||
{
|
||||
String scalar = assets.to_string();
|
||||
if(scalar != "")
|
||||
@@ -26,7 +26,7 @@ void app_asset_tags(Request& context, String kind, DTree assets)
|
||||
app_asset_tag_once(context, kind, scalar);
|
||||
return;
|
||||
}
|
||||
assets.each([&](const DTree& item, String key) {
|
||||
assets.each([&](const DValue& item, String key) {
|
||||
app_asset_tag_once(context, kind, item.to_string());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ COMPONENT(Request& context)
|
||||
if(nav_class == "" && (context.cfg.get_by_path("theme/key").to_string() == "portal-dark" || context.cfg.get_by_path("theme/key").to_string() == "dark" || context.cfg.get_by_path("theme/key").to_string() == "retro-gaming"))
|
||||
nav_class = "nav-shell";
|
||||
|
||||
DTree account_props;
|
||||
DValue account_props;
|
||||
if(context.props["account_wrapper_class"].to_string() != "")
|
||||
account_props["wrapper_class"] = context.props["account_wrapper_class"];
|
||||
if(context.props["links_wrapper_class"].to_string() != "")
|
||||
@@ -18,7 +18,7 @@ COMPONENT(Request& context)
|
||||
<nav<?: nav_class != "" ? " class=\"" + html_escape(nav_class) + "\"" : "" ?>>
|
||||
<div class="nav-menu">
|
||||
<a href="<?= app_link("", context) ?>"><?= context.cfg.get_by_path("site/name").to_string() ?></a>
|
||||
<? context.cfg.get_by_path("menu").each([&](DTree menu_item, String menu_key) {
|
||||
<? context.cfg.get_by_path("menu").each([&](DValue menu_item, String menu_key) {
|
||||
if(menu_item["hidden"].to_string() == "1")
|
||||
return;
|
||||
String href = menu_item["external"].to_string() != "" ? "/" + menu_key : app_link(menu_key, context);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
DTree get_config()
|
||||
DValue get_config()
|
||||
{
|
||||
DTree config;
|
||||
DValue config;
|
||||
|
||||
config["site"]["name"] = "UCE Starter";
|
||||
config["site"]["default_page_title"] = "Home";
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#load "lib/app.uce"
|
||||
|
||||
DTree starter_router_result(String file, String param = "")
|
||||
DValue starter_router_result(String file, String param = "")
|
||||
{
|
||||
DTree result;
|
||||
DValue result;
|
||||
result["file"] = file;
|
||||
if(param != "")
|
||||
result["param"] = param;
|
||||
return(result);
|
||||
}
|
||||
|
||||
DTree starter_router_resolve(Request& context)
|
||||
DValue starter_router_resolve(Request& context)
|
||||
{
|
||||
String lpath = context.call["route"]["l_path"].to_string();
|
||||
if(lpath == "")
|
||||
return(DTree());
|
||||
return(DValue());
|
||||
|
||||
String exact = "views/" + lpath + ".uce";
|
||||
if(file_exists(exact))
|
||||
@@ -34,14 +34,14 @@ DTree starter_router_resolve(Request& context)
|
||||
return(starter_router_result(parent_index, param));
|
||||
}
|
||||
|
||||
return(DTree());
|
||||
return(DValue());
|
||||
}
|
||||
|
||||
RENDER(Request& context)
|
||||
{
|
||||
app_init(context);
|
||||
|
||||
DTree resolved = starter_router_resolve(context);
|
||||
DValue resolved = starter_router_resolve(context);
|
||||
|
||||
ob_start();
|
||||
if(resolved["file"].to_string() != "")
|
||||
@@ -52,7 +52,7 @@ RENDER(Request& context)
|
||||
}
|
||||
else
|
||||
{
|
||||
DTree notfound_props;
|
||||
DValue notfound_props;
|
||||
notfound_props["message"] = "The requested page does not exist.";
|
||||
print(component("components/basic/notfound", notfound_props, context));
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void app_init(Request& context)
|
||||
context.call["route"]["page"] = context.params["ROUTE_PAGE"];
|
||||
context.call["route"]["valid"].set_bool(context.params["ROUTE_VALID"] != "0");
|
||||
|
||||
DTree config = get_config();
|
||||
DValue config = get_config();
|
||||
session_start();
|
||||
String requested_theme = first(context.get["theme"], context.session["app_theme"], config["theme"]["key"].to_string());
|
||||
if(config["theme"]["options"][requested_theme].get_type_name() != "array")
|
||||
@@ -53,8 +53,8 @@ void app_init(Request& context)
|
||||
if(context.get["theme"] != "")
|
||||
context.session["app_theme"] = requested_theme;
|
||||
|
||||
DTree selected_theme = config["theme"]["options"][requested_theme];
|
||||
selected_theme.each([&](DTree item, String key) {
|
||||
DValue selected_theme = config["theme"]["options"][requested_theme];
|
||||
selected_theme.each([&](DValue item, String key) {
|
||||
config["theme"][key] = item;
|
||||
});
|
||||
config["theme"]["key"] = requested_theme;
|
||||
|
||||
@@ -50,9 +50,9 @@ struct AppUser
|
||||
return(hash);
|
||||
}
|
||||
|
||||
static DTree read_json_file(String file_name)
|
||||
static DValue read_json_file(String file_name)
|
||||
{
|
||||
DTree result;
|
||||
DValue result;
|
||||
if(!file_exists(file_name))
|
||||
return(result);
|
||||
String raw = trim(file_get_contents(file_name));
|
||||
@@ -61,24 +61,24 @@ struct AppUser
|
||||
return(json_decode(raw));
|
||||
}
|
||||
|
||||
static bool write_json_file(String file_name, DTree data)
|
||||
static bool write_json_file(String file_name, DValue data)
|
||||
{
|
||||
mkdir(dirname(file_name));
|
||||
return(file_put_contents(file_name, json_encode(data)));
|
||||
}
|
||||
|
||||
DTree load(String email)
|
||||
DValue load(String email)
|
||||
{
|
||||
DTree user = read_json_file(file_name(email));
|
||||
DValue user = read_json_file(file_name(email));
|
||||
if(user.get_type_name() != "array")
|
||||
return(DTree());
|
||||
return(DValue());
|
||||
user["id"] = normalize_email(email);
|
||||
return(user);
|
||||
}
|
||||
|
||||
DTree create(String email, String password)
|
||||
DValue create(String email, String password)
|
||||
{
|
||||
DTree result;
|
||||
DValue result;
|
||||
email = normalize_email(email);
|
||||
password = trim(password);
|
||||
result["message"] = "";
|
||||
@@ -95,7 +95,7 @@ struct AppUser
|
||||
return(result);
|
||||
}
|
||||
|
||||
DTree existing = load(email);
|
||||
DValue existing = load(email);
|
||||
if(existing.get_type_name() == "array" && existing["email"].to_string() != "")
|
||||
{
|
||||
result["message"] = "user_exists";
|
||||
@@ -103,12 +103,12 @@ struct AppUser
|
||||
}
|
||||
|
||||
String salt = gen_sha1(std::to_string((u64)time()) + ":" + std::to_string((u64)(time_precise() * 1000000.0)) + ":" + session_id_create()).substr(0, 24);
|
||||
DTree user;
|
||||
DValue user;
|
||||
user["email"] = email;
|
||||
user["salt"] = salt;
|
||||
user["password_hash"] = password_hash(password, salt);
|
||||
user["created"] = std::to_string((u64)time());
|
||||
DTree role;
|
||||
DValue role;
|
||||
role = "user";
|
||||
user["roles"].push(role);
|
||||
|
||||
@@ -120,14 +120,14 @@ struct AppUser
|
||||
return(result);
|
||||
}
|
||||
|
||||
DTree sign_in(String email, String password)
|
||||
DValue sign_in(String email, String password)
|
||||
{
|
||||
DTree result;
|
||||
DValue result;
|
||||
result["result"].set_bool(false);
|
||||
email = normalize_email(email);
|
||||
password = trim(password);
|
||||
|
||||
DTree user = load(email);
|
||||
DValue user = load(email);
|
||||
if(user.get_type_name() != "array" || user["email"].to_string() == "")
|
||||
{
|
||||
result["message"] = "no_such_user";
|
||||
@@ -161,7 +161,7 @@ struct AppUser
|
||||
String user_id = context.session[session_key()];
|
||||
if(user_id == "")
|
||||
return(false);
|
||||
DTree user = load(user_id);
|
||||
DValue user = load(user_id);
|
||||
if(user["email"].to_string() == "")
|
||||
{
|
||||
context.session.erase(session_key());
|
||||
@@ -171,11 +171,11 @@ struct AppUser
|
||||
return(true);
|
||||
}
|
||||
|
||||
DTree current()
|
||||
DValue current()
|
||||
{
|
||||
if(is_signed_in())
|
||||
return(context.call["app"]["current_user"]);
|
||||
return(DTree());
|
||||
return(DValue());
|
||||
}
|
||||
|
||||
void logout()
|
||||
|
||||
@@ -4,10 +4,10 @@ COMPONENT(Request& context)
|
||||
{
|
||||
String main_html = context.call["fragments"]["main"].to_string();
|
||||
|
||||
DTree nav_props;
|
||||
DValue nav_props;
|
||||
nav_props["account_wrapper_class"] = "nav-account nav-menu";
|
||||
|
||||
DTree footer_props;
|
||||
DValue footer_props;
|
||||
|
||||
<>
|
||||
<!doctype html>
|
||||
|
||||
@@ -4,7 +4,7 @@ COMPONENT(Request& context)
|
||||
{
|
||||
String main_html = context.call["fragments"]["main"].to_string();
|
||||
|
||||
DTree footer_props;
|
||||
DValue footer_props;
|
||||
|
||||
<>
|
||||
<!doctype html>
|
||||
|
||||
@@ -5,10 +5,10 @@ COMPONENT(Request& context)
|
||||
String main_html = context.call["fragments"]["main"].to_string();
|
||||
String current_path = context.call["route"]["l_path"].to_string();
|
||||
|
||||
DTree global_props;
|
||||
DValue global_props;
|
||||
global_props["cookie_consent"].set_bool(false);
|
||||
|
||||
DTree account_props;
|
||||
DValue account_props;
|
||||
account_props["wrapper_class"] = "admin-account-card";
|
||||
account_props["links_wrapper_class"] = "admin-account-links";
|
||||
account_props["name_class"] = "admin-account-name";
|
||||
@@ -28,7 +28,7 @@ COMPONENT(Request& context)
|
||||
<img class="admin-nav-logo-img" src="<?= app_asset_url("themes/localfirst/img/local_first_logo.png", context) ?>" alt="<?= context.cfg.get_by_path("site/name").to_string() ?>" />
|
||||
</a>
|
||||
</div>
|
||||
<? context.cfg.get_by_path("menu").each([&](DTree menu_item, String menu_key) {
|
||||
<? context.cfg.get_by_path("menu").each([&](DValue menu_item, String menu_key) {
|
||||
if(menu_item["hidden"].to_string() == "1")
|
||||
return;
|
||||
bool active = menu_key != "" && (current_path == menu_key || current_path.rfind(menu_key + "/", 0) == 0);
|
||||
|
||||
@@ -4,10 +4,10 @@ COMPONENT(Request& context)
|
||||
{
|
||||
String main_html = context.call["fragments"]["main"].to_string();
|
||||
|
||||
DTree nav_props;
|
||||
DValue nav_props;
|
||||
nav_props["account_wrapper_class"] = "nav-account nav-menu";
|
||||
|
||||
DTree footer_props;
|
||||
DValue footer_props;
|
||||
|
||||
<>
|
||||
<!doctype html>
|
||||
|
||||
@@ -4,7 +4,7 @@ COMPONENT(Request& context)
|
||||
{
|
||||
String main_html = context.call["fragments"]["main"].to_string();
|
||||
|
||||
DTree footer_props;
|
||||
DValue footer_props;
|
||||
footer_props["inner_class"] = "footer-inner";
|
||||
|
||||
<>
|
||||
|
||||
@@ -4,10 +4,10 @@ COMPONENT(Request& context)
|
||||
{
|
||||
String main_html = context.call["fragments"]["main"].to_string();
|
||||
|
||||
DTree nav_props;
|
||||
DValue nav_props;
|
||||
nav_props["account_wrapper_class"] = "nav-account nav-menu";
|
||||
|
||||
DTree footer_props;
|
||||
DValue footer_props;
|
||||
|
||||
<>
|
||||
<!doctype html>
|
||||
|
||||
@@ -4,7 +4,7 @@ COMPONENT(Request& context)
|
||||
{
|
||||
context.call["app"]["page_title"] = "Login";
|
||||
StarterUser users(context);
|
||||
DTree result;
|
||||
DValue result;
|
||||
if(context.params["REQUEST_METHOD"] == "POST")
|
||||
{
|
||||
result = users.sign_in(context.post["email"], context.post["password"]);
|
||||
|
||||
@@ -9,9 +9,9 @@ COMPONENT(Request& context)
|
||||
return;
|
||||
}
|
||||
context.call["app"]["page_title"] = "Profile";
|
||||
DTree user = users.current();
|
||||
DValue user = users.current();
|
||||
String roles = "";
|
||||
user["roles"].each([&](DTree role, String key) {
|
||||
user["roles"].each([&](DValue role, String key) {
|
||||
if(roles != "")
|
||||
roles += ", ";
|
||||
roles += role.to_string();
|
||||
|
||||
@@ -4,7 +4,7 @@ COMPONENT(Request& context)
|
||||
{
|
||||
context.call["app"]["page_title"] = "Register";
|
||||
StarterUser users(context);
|
||||
DTree result;
|
||||
DValue result;
|
||||
if(context.params["REQUEST_METHOD"] == "POST")
|
||||
result = users.create(context.post["email"], context.post["password"]);
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "views/marketing.css";
|
||||
print(component("../../components/theme/assets", asset_props, context));
|
||||
context.call["app"]["page_title"] = "Auth";
|
||||
|
||||
DTree props;
|
||||
DValue props;
|
||||
props["title"] = "Sign In to Your Account";
|
||||
props["subtitle"] = "Choose your preferred authentication method to continue";
|
||||
props["google_client_id"] = "YOUR_GOOGLE_CLIENT_ID";
|
||||
|
||||
@@ -4,8 +4,8 @@ COMPONENT(Request& context)
|
||||
{
|
||||
context.call["app"]["page_type"] = "json";
|
||||
|
||||
DTree response;
|
||||
DTree body = json_decode(context.in);
|
||||
DValue response;
|
||||
DValue body = json_decode(context.in);
|
||||
if(context.params["REQUEST_METHOD"] == "POST" && body["oauth_service"].to_string() != "" && body["oauth_state"].to_string() != "")
|
||||
{
|
||||
context.session["oauth_service"] = body["oauth_service"].to_string();
|
||||
|
||||
@@ -9,8 +9,8 @@ COMPONENT(Request& context)
|
||||
{
|
||||
context.call["app"]["page_title"] = "Dashboard";
|
||||
|
||||
DTree props;
|
||||
DTree item;
|
||||
DValue props;
|
||||
DValue item;
|
||||
item["label"] = "24h Requests"; item["value"] = "18,420"; item["meta"] = "+12.8% vs yesterday"; item["tone"] = "info"; props["items"].push(item); item.clear();
|
||||
item["label"] = "Median Latency"; item["value"] = "182 ms"; item["meta"] = "stable over last 7 samples"; item["tone"] = "success"; props["items"].push(item); item.clear();
|
||||
item["label"] = "Resident Memory"; item["value"] = "2.4 GB"; item["meta"] = "combined across workers"; item["tone"] = "warning"; props["items"].push(item); item.clear();
|
||||
@@ -25,9 +25,9 @@ COMPONENT(Request& context)
|
||||
print(component("../components/data/widgets:SUMMARY_METRICS", props, context));
|
||||
|
||||
props.clear();
|
||||
DTree series;
|
||||
DTree values;
|
||||
DTree entry;
|
||||
DValue series;
|
||||
DValue values;
|
||||
DValue entry;
|
||||
entry["key"] = "requests"; entry["label"] = "Requests"; entry["color"] = "#60a5fa"; entry["axis"] = "left"; entry["format"] = "count";
|
||||
values = "240"; entry["values"].push(values); values = "268"; entry["values"].push(values); values = "294"; entry["values"].push(values); values = "322"; entry["values"].push(values); values = "301"; entry["values"].push(values); values = "356"; entry["values"].push(values); values = "388"; entry["values"].push(values);
|
||||
props["series"].push(entry); entry.clear();
|
||||
@@ -53,14 +53,14 @@ COMPONENT(Request& context)
|
||||
props["storage_key"] = "starter.dashboard.services";
|
||||
props["sort"]["column"] = "2";
|
||||
props["sort"]["direction"] = "desc";
|
||||
DTree col;
|
||||
DValue col;
|
||||
col["key"] = "service"; col["label"] = "Service"; props["columns"].push(col); col.clear();
|
||||
col["key"] = "uptime"; col["label"] = "Uptime"; props["columns"].push(col); col.clear();
|
||||
col["key"] = "requests"; col["label"] = "Requests"; col["align"] = "right"; col["format"] = "number"; props["columns"].push(col); col.clear();
|
||||
col["key"] = "memory"; col["label"] = "Memory"; col["align"] = "right"; col["format"] = "bytes"; props["columns"].push(col); col.clear();
|
||||
col["key"] = "p95_latency"; col["label"] = "P95 Latency"; col["align"] = "right"; col["format"] = "duration-ms"; props["columns"].push(col); col.clear();
|
||||
col["key"] = "healthy"; col["label"] = "Healthy"; col["align"] = "center"; col["format"] = "bool"; props["columns"].push(col);
|
||||
DTree row;
|
||||
DValue row;
|
||||
row["service"] = "router"; row["uptime"] = "12 days"; row["requests"] = "142890"; row["memory"] = "402653184"; row["p95_latency"] = "148"; row["healthy"] = "true"; props["rows"].push(row); row.clear();
|
||||
row["service"] = "queue-worker"; row["uptime"] = "8 days"; row["requests"] = "98214"; row["memory"] = "654311424"; row["p95_latency"] = "231"; row["healthy"] = "true"; props["rows"].push(row); row.clear();
|
||||
row["service"] = "vector-index"; row["uptime"] = "5 days"; row["requests"] = "44892"; row["memory"] = "1241513984"; row["p95_latency"] = "312"; row["healthy"] = "true"; props["rows"].push(row); row.clear();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "views/marketing.css";
|
||||
print(component("../components/theme/assets", asset_props, context));
|
||||
context.call["app"]["page_title"] = "Features";
|
||||
|
||||
@@ -5,8 +5,8 @@ COMPONENT(Request& context)
|
||||
context.call["app"]["page_title"] = "Gauges";
|
||||
f64 pi = 3.14159265358979323846;
|
||||
|
||||
DTree props;
|
||||
DTree item;
|
||||
DValue props;
|
||||
DValue item;
|
||||
|
||||
<>
|
||||
<h1>Gauge Components Demo</h1>
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "views/marketing.css";
|
||||
print(component("../components/theme/assets", asset_props, context));
|
||||
context.call["app"]["page_title"] = "Home";
|
||||
|
||||
DTree props;
|
||||
DValue props;
|
||||
|
||||
props["title"] = "Stunning Apps";
|
||||
props["subtitle"] = "Experience the power of super bloated PHP development with our gigantic and truly unwieldy component-based framework. Seriously though, this page only serves as an example repository of different styles and blocks.";
|
||||
@@ -17,7 +17,7 @@ COMPONENT(Request& context)
|
||||
print(component("../components/example/marketing_blocks:FEATURES_GRID", context));
|
||||
|
||||
props.clear();
|
||||
DTree stat;
|
||||
DValue stat;
|
||||
stat["number"] = "10K+"; stat["label"] = "Happy Vibe Coders"; props["stats"].push(stat); stat.clear();
|
||||
stat["number"] = "<1s"; stat["label"] = "Page Load Time"; props["stats"].push(stat); stat.clear();
|
||||
stat["number"] = "99.9%"; stat["label"] = "Uptime"; props["stats"].push(stat); stat.clear();
|
||||
@@ -72,7 +72,7 @@ COMPONENT(Request& context)
|
||||
<h2>Theme Families</h2>
|
||||
<p>Compare the starter’s built-in theme families and jump to the live gallery.</p>
|
||||
<div class="theme-grid">
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DTree theme, String key) {
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DValue theme, String key) {
|
||||
if(key != "portal-light" && key != "portal-dark" && key != "localfirst")
|
||||
return;
|
||||
StringMap theme_params;
|
||||
@@ -99,7 +99,7 @@ COMPONENT(Request& context)
|
||||
props["secondary_text"] = "View GitHub";
|
||||
print(component("../components/example/marketing_blocks:CTA_SECTION", props, context));
|
||||
|
||||
DTree island_props;
|
||||
DValue island_props;
|
||||
island_props["name"] = "StarterGuidelines";
|
||||
island_props["id"] = "starter-guidelines-island";
|
||||
island_props["props"]["route"] = context.call["route"]["l_path"].to_string();
|
||||
@@ -120,7 +120,7 @@ COMPONENT(Request& context)
|
||||
</>
|
||||
|
||||
props.clear();
|
||||
DTree row;
|
||||
DValue row;
|
||||
row["name"] = "John Doe"; row["age"] = "25"; row["gender"] = "male"; row["department"] = "Engineering"; row["salary"] = "75000"; row["active"] = "true"; props["items"].push(row); row.clear();
|
||||
row["name"] = "Jane Smith"; row["age"] = "30"; row["gender"] = "female"; row["department"] = "Design"; row["salary"] = "82000"; row["active"] = "true"; props["items"].push(row); row.clear();
|
||||
row["name"] = "Bob Johnson"; row["age"] = "35"; row["gender"] = "male"; row["department"] = "Marketing"; row["salary"] = "68000"; row["active"] = "false"; props["items"].push(row); row.clear();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "views/marketing.css";
|
||||
print(component("../components/theme/assets", asset_props, context));
|
||||
context.call["app"]["page_title"] = "Components";
|
||||
@@ -51,7 +51,7 @@ COMPONENT(Request& context)
|
||||
<div class="window-dot green"></div>
|
||||
<span class="mono-text">views/index.uce</span>
|
||||
</div>
|
||||
<pre class="code-block"><code>DTree props;
|
||||
<pre class="code-block"><code>DValue props;
|
||||
props["title"] = "Stunning Apps";
|
||||
<><?: component("example/marketing_blocks:HERO_SECTION", props, context) ?></></code></pre>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "views/themes.css";
|
||||
print(component("../components/theme/assets", asset_props, context));
|
||||
context.call["app"]["page_title"] = "Theme Preview";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
DTree asset_props;
|
||||
DValue asset_props;
|
||||
asset_props["css"]["0"] = "views/themes.css";
|
||||
print(component("../components/theme/assets", asset_props, context));
|
||||
context.call["app"]["page_title"] = "Themes";
|
||||
@@ -16,7 +16,7 @@ COMPONENT(Request& context)
|
||||
<p>Open each theme preview directly to judge shell fit, typography, and token balance.</p>
|
||||
</section>
|
||||
<div class="theme-gallery-grid">
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DTree theme_info, String theme_key) {
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DValue theme_info, String theme_key) {
|
||||
StringMap params;
|
||||
params["theme"] = theme_key;
|
||||
String preview_href = app_link("theme-preview", params, context);
|
||||
|
||||
@@ -25,35 +25,35 @@ COMPONENT(Request& context)
|
||||
<div class="ws-demo-sidebar-copy"><p>This sidebar and mobile shell pattern was extracted from the AI portal app and normalized against starter theme tokens.</p></div>
|
||||
</>
|
||||
sidebar_body = ob_get_close();
|
||||
DTree sidebar_note;
|
||||
DValue sidebar_note;
|
||||
sidebar_note["icon_class"] = "fas fa-circle-info";
|
||||
sidebar_note["text"] = "Use workspace/overview, workspace/projects, or workspace/activity";
|
||||
sidebar_body += component("../../components/workspace/primitives:LIST_STATE", sidebar_note, context);
|
||||
|
||||
DTree toolbar_props;
|
||||
DValue toolbar_props;
|
||||
toolbar_props["action_html"] = "<a class=\"ws-sidebar-action-btn\" href=\"" + app_link("workspace/overview", context) + "\"><i class=\"fas fa-grid-2\"></i><span>Open shell</span></a>";
|
||||
toolbar_props["search_input_id"] = "workspace-demo-search";
|
||||
toolbar_props["search_input_name"] = "workspace_demo_search";
|
||||
toolbar_props["search_placeholder"] = "Search workspace sections";
|
||||
String sidebar_top = component("../../components/workspace/primitives:SIDEBAR_TOOLBAR", toolbar_props, context);
|
||||
|
||||
DTree sidebar_props;
|
||||
DValue sidebar_props;
|
||||
sidebar_props["id"] = "workspace-demo-sidebar";
|
||||
sidebar_props["top_html"] = sidebar_top;
|
||||
sidebar_props["body_html"] = sidebar_body;
|
||||
String sidebar = component("../../components/workspace/primitives:SIDEBAR_SHELL", sidebar_props, context);
|
||||
|
||||
DTree mobile_props;
|
||||
DValue mobile_props;
|
||||
mobile_props["button_id"] = "workspace-demo-toggle";
|
||||
mobile_props["title"] = "Starter Workspace";
|
||||
String mobile_bar = component("../../components/workspace/primitives:MOBILE_BAR", mobile_props, context);
|
||||
|
||||
DTree pill_props;
|
||||
DValue pill_props;
|
||||
pill_props["label"] = status_label;
|
||||
pill_props["variant"] = status_variant;
|
||||
String status_html = component("../../components/workspace/primitives:STATUS_PILL", pill_props, context);
|
||||
|
||||
DTree header_props;
|
||||
DValue header_props;
|
||||
header_props["title"] = title;
|
||||
header_props["subtitle"] = subtitle;
|
||||
header_props["actions_html"] = status_html;
|
||||
@@ -81,10 +81,10 @@ COMPONENT(Request& context)
|
||||
</>
|
||||
detail_html = ob_get_close();
|
||||
|
||||
DTree section_head;
|
||||
DValue section_head;
|
||||
section_head["title"] = "Why this belongs in the starter";
|
||||
String why_head = component("../../components/workspace/primitives:SECTION_HEAD", section_head, context);
|
||||
DTree section_props;
|
||||
DValue section_props;
|
||||
section_props["header_html"] = why_head;
|
||||
section_props["body_html"] = "<p class=\"ws-section-copy\">" + html_escape(description) + "</p>" + stats_html;
|
||||
String main_body = component("../../components/workspace/primitives:SECTION", section_props, context);
|
||||
@@ -99,7 +99,7 @@ COMPONENT(Request& context)
|
||||
|
||||
if(section == "activity")
|
||||
{
|
||||
DTree empty_props;
|
||||
DValue empty_props;
|
||||
empty_props["icon_class"] = "fas fa-clock-rotate-left";
|
||||
empty_props["title"] = "No live stream wired yet";
|
||||
empty_props["text"] = "The shell is generic. Add your own websocket, polling, or event-driven runtime behind it when a real product needs one.";
|
||||
@@ -107,12 +107,12 @@ COMPONENT(Request& context)
|
||||
main_body += component("../../components/workspace/primitives:EMPTY_STATE", empty_props, context);
|
||||
}
|
||||
|
||||
DTree panel_props;
|
||||
DValue panel_props;
|
||||
panel_props["header_html"] = header;
|
||||
panel_props["body_html"] = main_body;
|
||||
String main = mobile_bar + component("../../components/workspace/primitives:PANEL", panel_props, context);
|
||||
|
||||
DTree app_props;
|
||||
DValue app_props;
|
||||
app_props["id"] = "workspace-demo-shell";
|
||||
app_props["overlay_id"] = "workspace-demo-overlay";
|
||||
app_props["sidebar_html"] = sidebar;
|
||||
|
||||
Reference in New Issue
Block a user