diff --git a/Hieu/untitled_10.page.aml b/Hieu/untitled_10.page.aml index a04b3e4..e3c953a 100644 --- a/Hieu/untitled_10.page.aml +++ b/Hieu/untitled_10.page.aml @@ -50,7 +50,18 @@ Dashboard untitled_10_2 { label: 'raw users' viz: DataTable { dataset: hieu_haha_meme - theme { + calculation dimension_23f49c7 { + label: 'Untitled Dimension' + formula: @aql users_kk.id + users_kk.tenant_id;; + calc_type: 'dimension' + data_type: 'number' + model: users_kk + } + calculation metric_0ad16b9 { + label: 'Count Users' + formula: @aql users_kk | count(1);; + calc_type: 'measure' + data_type: 'number' } fields: [ VizFieldFull { @@ -73,6 +84,20 @@ Dashboard untitled_10_2 { type: 'number' pattern: 'inherited' } + }, + VizFieldFull { + ref: 'metric_0ad16b9' + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: ref('users_kk', 'dimension_23f49c7') + format { + type: 'number' + pattern: 'inherited' + } } ] settings { diff --git a/Static Files (Do not Change)/External landing page for embed (Marketing)/ecommerce_dashboard.page.aml b/Static Files (Do not Change)/External landing page for embed (Marketing)/ecommerce_dashboard.page.aml index 230f084..c54eda8 100644 --- a/Static Files (Do not Change)/External landing page for embed (Marketing)/ecommerce_dashboard.page.aml +++ b/Static Files (Do not Change)/External landing page for embed (Marketing)/ecommerce_dashboard.page.aml @@ -68,8 +68,6 @@ Dashboard ecommerce_dashboard { position: pos(30, 40, 90, 130) } } - - // Visualization block v1: VizBlock { label: 'Gross Merchandise Value' viz: MetricKpi { @@ -460,11 +458,11 @@ Dashboard ecommerce_dashboard { type: 'field' source: FieldFilterSource { dataset: demo_ecommerce - field: ref('ecommerce_countries', 'continent_name') + field: r(ecommerce_countries.continent_name) } default { operator: 'is' - value: 'America' + value: [] } } block d1: DateDrillBlock { @@ -487,8 +485,6 @@ Dashboard ecommerce_dashboard { input_type: 'nullable-single' } } - - // Text block t1: TextBlock { content: @md
- - - Object Name - Object Type - Label - Owner - Description - - - - - ${demo_ecommerce_version_2.name} - Dataset - ${demo_ecommerce_version_2.label} - ${demo_ecommerce_version_2.owner} - ${demo_ecommerce_version_2.description} - - - ${demo_ecommerce.name} - Dataset - ${demo_ecommerce.label} - ${demo_ecommerce.owner} - ${demo_ecommerce.description} - - - ${simple_dataset.name} - Dataset - ${simple_dataset.label} - ${simple_dataset.owner} - ${simple_dataset.description} - - - ${khai_ecommerce.name} - Dataset - ${khai_ecommerce.label} - ${khai_ecommerce.owner} - ${khai_ecommerce.description} - - - ${demo_running_total.name} - Dataset - ${demo_running_total.label} - ${demo_running_total.owner} - ${demo_running_total.description} - - - ${demo_ecommerce_overview_pro.uname} - Dashboard - ${demo_ecommerce_overview_pro.title} - ${demo_ecommerce_overview_pro.owner} - ${demo_ecommerce_overview_pro.description} - - - ${demo_ecommerce_overview_funky.uname} - Dashboard - ${demo_ecommerce_overview_funky.title} - ${demo_ecommerce_overview_funky.owner} - ${demo_ecommerce_overview_funky.description} - - - ${company_dashboard_v.uname} - Dashboard - ${company_dashboard_v.title} - ${company_dashboard_v.owner} - ${company_dashboard_v.description} - - - ${embed_demo_landing_page_2.uname} - Dashboard - ${embed_demo_landing_page_2.title} - ${embed_demo_landing_page_2.owner} - ${embed_demo_landing_page_2.description} - - - ${notebook_ecommerce_business_metrics.uname} - Dashboard - ${notebook_ecommerce_business_metrics.title} - ${notebook_ecommerce_business_metrics.owner} - ${notebook_ecommerce_business_metrics.description} - - -;; - } - - view: CanvasLayout { - label: 'View 1' - width: 1300 - height: 560 - grid_size: 20 - auto_expand_vertically: true - block title { - position: pos(20, 20, 1260, 60) - } - block t_4gpk { - position: pos(20, 100, 1220, 360) - layer: 1 - } - block catalog { - position: pos(20, 80, 1240, 460) - } - mobile { - mode: 'auto' - } +

📊 Metrics Catalog

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Metric KeyNameDescription
aov${demo_ecommerce_version_2.metric.aov.__meta__.name}${demo_ecommerce_version_2.metric.aov.description}
cancelled_order_ratio${demo_ecommerce_version_2.metric.cancelled_order_ratio.__meta__.name}${demo_ecommerce_version_2.metric.cancelled_order_ratio.description}
cancelled_value${demo_ecommerce_version_2.metric.cancelled_value.__meta__.name}${demo_ecommerce_version_2.metric.cancelled_value.description}
cancelled_value_ratio${demo_ecommerce_version_2.metric.cancelled_value_ratio.__meta__.name}${demo_ecommerce_version_2.metric.cancelled_value_ratio.description}
delivered_value${demo_ecommerce_version_2.metric.delivered_value.__meta__.name}${demo_ecommerce_version_2.metric.delivered_value.description}
dynamic_metric${demo_ecommerce_version_2.metric.dynamic_metric.__meta__.name}${demo_ecommerce_version_2.metric.dynamic_metric.description}
dynamic_metric_currency${demo_ecommerce_version_2.metric.dynamic_metric_currency.__meta__.name}${demo_ecommerce_version_2.metric.dynamic_metric_currency.description}
gmv${demo_ecommerce_version_2.metric.gmv.__meta__.name}${demo_ecommerce_version_2.metric.gmv.description}
nmv${demo_ecommerce_version_2.metric.nmv.__meta__.name}${demo_ecommerce_version_2.metric.nmv.description}
percent_of_total${demo_ecommerce_version_2.metric.percent_of_total.__meta__.name}${demo_ecommerce_version_2.metric.percent_of_total.description}
refunded_value${demo_ecommerce_version_2.metric.refunded_value.__meta__.name}${demo_ecommerce_version_2.metric.refunded_value.description}
retention${demo_ecommerce_version_2.metric.retention.__meta__.name}${demo_ecommerce_version_2.metric.retention.description}
revenue${demo_ecommerce_version_2.metric.revenue.__meta__.name}${demo_ecommerce_version_2.metric.revenue.description}
revenue_commission${demo_ecommerce_version_2.metric.revenue_commission.__meta__.name}${demo_ecommerce_version_2.metric.revenue_commission.description}
running_total_orders${demo_ecommerce_version_2.metric.running_total_orders.__meta__.name}${demo_ecommerce_version_2.metric.running_total_orders.description}
total_buyers${demo_ecommerce_version_2.metric.total_buyers.__meta__.name}${demo_ecommerce_version_2.metric.total_buyers.description}
total_cancelled_orders${demo_ecommerce_version_2.metric.total_cancelled_orders.__meta__.name}${demo_ecommerce_version_2.metric.total_cancelled_orders.description}
total_delivered_orders${demo_ecommerce_version_2.metric.total_delivered_orders.__meta__.name}${demo_ecommerce_version_2.metric.total_delivered_orders.description}
total_discount${demo_ecommerce_version_2.metric.total_discount.__meta__.name}${demo_ecommerce_version_2.metric.total_discount.description}
total_orders${demo_ecommerce_version_2.metric.total_orders.__meta__.name}${demo_ecommerce_version_2.metric.total_orders.description}
total_orders_across_all${demo_ecommerce_version_2.metric.total_orders_across_all.__meta__.name}${demo_ecommerce_version_2.metric.total_orders_across_all.description}
total_refunded_orders${demo_ecommerce_version_2.metric.total_refunded_orders.__meta__.name}${demo_ecommerce_version_2.metric.total_refunded_orders.description}
total_repeated_buyers${demo_ecommerce_version_2.metric.total_repeated_buyers.__meta__.name}${demo_ecommerce_version_2.metric.total_repeated_buyers.description}
total_users${demo_ecommerce_version_2.metric.total_users.__meta__.name}${demo_ecommerce_version_2.metric.total_users.description}
;; } theme: H.themes.vanilla diff --git a/demo ecommerce/datasets/demo_ecommerce.dataset.aml b/demo ecommerce/datasets/demo_ecommerce.dataset.aml index 81072e4..8d931e5 100644 --- a/demo ecommerce/datasets/demo_ecommerce.dataset.aml +++ b/demo ecommerce/datasets/demo_ecommerce.dataset.aml @@ -16,7 +16,7 @@ PreAggregate agg_daily { } Dataset demo_ecommerce { - __engine__: 'aql' //turn this Dataset to using AQL Engine + __engine__: 'aql' //turn this Dataset to using AQL Engine new label: '[Demo] Ecommerce (Official)' description: "Official dataset for demoing E-commerce use cases test" owner: 'ha.pham+demo4@holistics.io' diff --git a/demo ecommerce/embed/ecommerce_portal.embed.aml b/demo ecommerce/embed/ecommerce_portal.embed.aml index 4252564..d73e207 100644 --- a/demo ecommerce/embed/ecommerce_portal.embed.aml +++ b/demo ecommerce/embed/ecommerce_portal.embed.aml @@ -1,6 +1,6 @@ EmbedPortal ecommerce_portal { objects: [ - demo_ecommerce_overview_pro, + // demo_ecommerce_overview_pro, _0_ecommerce_dashboard_30, _1_country_breakdown, _2_category_breakdown, diff --git a/demo_sales_overview_copy.page.aml b/demo_sales_overview_copy.page.aml new file mode 100644 index 0000000..8865cca --- /dev/null +++ b/demo_sales_overview_copy.page.aml @@ -0,0 +1,1319 @@ +Dashboard demo_sales_overview_copy { + title: '[Demo] Sales Overview (copy)' + owner: 'khai.to@holistics.io' + block v1: VizBlock { + label: 'GMV' + description: 'Total value regardless of order status' + viz: MetricKpi { + dataset: demo_ecommerce + calculation f_03802b5 { + label: 'GMV Last Year' + formula: @aml order_master.gmv * 0.87;; + calc_type: 'measure' + data_type: 'number' + } + calculation untitled_metric_14c719b { + label: 'Untitled Metric' + formula: @aql order_master.gmv * 0.87;; + calc_type: 'measure' + data_type: 'number' + } + value: VizFieldFull { + label: ' ' + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '[$$]#,###' + } + } + compare_value: VizFieldFull { + label: 'GMV' + ref: 'untitled_metric_14c719b' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + aggregate_awareness { + enabled: true + debug_comments: true + } + label { + font_size: 15 + } + alignment: 'center' + metric_value { + font_size: 45 + font_color: '#CCFF00FF' + } + } + } + } + block v6: VizBlock { + label: ' ' + viz: MetricSheet { + dataset: demo_ecommerce_metrics + date_field: VizFieldFull { + ref: r(dim_dates.date_key) + transformation: 'datetrunc week' + format { + type: 'date' + pattern: 'wwww' + } + } + rows: [ + MetricHeading { + label: '🎯Orders' + settings { + background_color: '#000000FF' + text_color: '#FFFFFFFF' + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(ecommerce_orders.total_order) + format { + type: 'number' + pattern: 'inherited' + } + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(ecommerce_orders.delivered_orders_count) + format { + type: 'number' + pattern: '#,###' + } + } + settings { + indent: 1 + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(ecommerce_orders.cancelled_orders_count) + format { + type: 'number' + pattern: '#,###' + } + } + settings { + indent: 1 + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(ecommerce_orders.refunded_orders_count) + format { + type: 'number' + pattern: '#,###' + } + } + settings { + indent: 1 + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(order_master.aov) + format { + type: 'number' + pattern: 'inherited' + } + } + }, + MetricHeading { + label: '💰 Revenue' + settings { + background_color: '#000000FF' + text_color: '#FFFFFFFF' + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(order_master.nmv) + format { + type: 'number' + pattern: 'inherited' + } + } + }, + MetricSeries { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: 'inherited' + } + } + } + ] + settings { + max_column: 7 + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v10: VizBlock { + label: 'Registered Users' + viz: MetricKpi { + dataset: demo_ecommerce + calculation f_c70646c { + label: 'Target Users' + formula: @aml ecommerce_users.users_signed_up_count * 1.38;; + calc_type: 'measure' + data_type: 'number' + } + calculation untitled_metric_1681e8f { + label: 'Untitled Metric' + formula: @aql ecommerce_users.users_signed_up_count * 1.38;; + calc_type: 'measure' + data_type: 'number' + } + value: VizFieldFull { + label: ' ' + ref: r(ecommerce_users.total_users) + format { + type: 'number' + pattern: 'inherited' + } + } + compare_value: VizFieldFull { + label: 'Target Users' + ref: 'untitled_metric_1681e8f' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + reverse_color: true + display_mode: 'progress' + aggregate_awareness { + enabled: true + debug_comments: true + } + label { + font_size: 15 + } + alignment: 'center' + metric_value { + font_size: 45 + font_color: '#CCFF00FF' + } + progress { + bar { + color: '#68C3D4FF' + } + + } + } + } + } + block v125: VizBlock { + label: 'Total Discount Given' + viz: MetricKpi { + dataset: demo_ecommerce + value: VizFieldFull { + label: ' ' + ref: r(order_master.discount) + aggregation: 'sum' + format { + type: 'number' + pattern: '#,###' + } + } + settings { + aggregate_awareness { + enabled: true + debug_comments: true + } + label { + font_size: 15 + font_color: '#156064FF' + } + alignment: 'center' + metric_value { + font_size: 45 + font_color: '#CCFF00FF' + } + } + } + } + block v126: VizBlock { + label: 'Total Amount Refunded' + viz: MetricKpi { + dataset: demo_ecommerce + calculation untitled_metric_f5cb50b { + label: 'Untitled Metric' + formula: @aql order_master.refunded_orders_count * average(order_master.price);; + calc_type: 'measure' + data_type: 'number' + } + value: VizFieldFull { + label: ' ' + ref: 'untitled_metric_f5cb50b' + format { + type: 'number' + pattern: '[$$]#,###,"K"' + group_separator: ',' + decimal_separator: '.' + } + } + settings { + aggregate_awareness { + enabled: true + debug_comments: true + } + label { + font_size: 15 + font_color: '#156064FF' + } + alignment: 'center' + metric_value { + font_size: 45 + font_color: '#CCFF00FF' + } + } + } + } + block v127: VizBlock { + label: 'Total Order Count' + viz: MetricKpi { + dataset: demo_ecommerce + calculation untitled_metric_c018fb0 { + label: 'Untitled Metric' + formula: @aql total_orders * 1.02;; + calc_type: 'measure' + data_type: 'number' + } + value: VizFieldFull { + label: ' ' + ref: r(order_master.order_id) + aggregation: 'count distinct' + format { + type: 'number' + pattern: 'inherited' + } + } + compare_value: VizFieldFull { + label: 'Target' + ref: 'untitled_metric_c018fb0' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + display_mode: 'progress' + aggregate_awareness { + enabled: true + debug_comments: true + } + alignment: 'center' + metric_value { + font_size: 45 + font_color: '#CCFF00FF' + } + progress { + bar { + color: '#68C3D4FF' + } + + } + } + } + } + block f1: FilterBlock { + label: 'Date Filter' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(order_master.order_created_at) + } + default { + operator: 'matches' + value: '$H_NIL$' + } + } + block f12: FilterBlock { + label: 'Date Range' + type: 'date' + default { + operator: 'matches' + value: '$H_NIL$' + } + } + block f2: FilterBlock { + label: 'Product Category' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(map_categories.category) + } + default { + operator: 'is' + value: [] + } + } + block f3: FilterBlock { + label: 'Product Name' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(ecommerce_products.name) + } + default { + operator: 'is' + value: [] + } + } + block f4: FilterBlock { + label: 'Customer Age Demographic' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(ecommerce_users.age_group) + } + default { + operator: 'is' + value: [] + } + } + block v128: VizBlock { + label: 'Products & Merchants' + viz: DataTable { + dataset: demo_ecommerce + calculation profits { + label: 'Profits' + formula: @aql ecommerce_products.price-ecommerce_products.cost;; + calc_type: 'measure' + data_type: 'number' + } + calculation f_5e84d48 { + label: 'Amazon Search' + formula: @aql concat('https://www.amazon.com/s?k=',ecommerce_products.name);; + calc_type: 'measure' + data_type: 'text' + hidden: true + } + calculation f_6d33d70 { + label: 'Google Search' + formula: @aql concat('https://www.google.com/search?q=',ecommerce_merchants.name);; + calc_type: 'measure' + data_type: 'text' + hidden: true + } + calculation f_ac65b5c { + label: 'Map Search' + formula: @aql concat('https://www.google.com/maps/search/',ecommerce_merchants.name);; + calc_type: 'measure' + data_type: 'text' + hidden: true + } + fields: [ + VizFieldFull { + ref: r(ecommerce_products.name) + format { + type: 'text' + } + action a_1: VizAction { + type: 'GoToUrl' + label: 'Amazon Search' + url: 'f_5e84d48' + } + uname: 'ecommerce_products_name' + }, + VizFieldFull { + label: 'Merchant Name' + ref: r(ecommerce_merchants.name) + format { + type: 'text' + } + action a_1: VizAction { + type: 'GoToUrl' + label: 'Google Search' + url: 'f_6d33d70' + } + action a_2: VizAction { + type: 'GoToUrl' + label: 'Map Search' + url: 'f_ac65b5c' + } + uname: 'ecommerce_merchants_name' + }, + VizFieldFull { + label: 'Revenue' + ref: r(order_master.revenue_delivered) + format { + type: 'number' + pattern: 'inherited' + } + uname: 'custom_revenue_delivered' + }, + VizFieldFull { + label: 'AOV' + ref: r(order_master.aov) + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: r(ecommerce_products.price) + format { + type: 'number' + pattern: '[$$]#,###' + } + }, + VizFieldFull { + ref: r(ecommerce_products.cost) + format { + type: 'number' + pattern: '[$$]#,###' + } + } + ] + settings { + wrap_header_text: true + wrap_cell_text: true + show_row_number: true + conditional_formats: [ + ConditionalFormat { + key: 'custom_revenue_delivered' + format: SingleFormat { + condition { + operator: 'greater_than_equal' + value: 1500 + } + text_color: '#328159' + background_color: '#B5E3CD' + } + } + ] + row_limit: 5000 + aggregate_awareness { + enabled: true + debug_comments: true + } + frozen_columns: 2 + column_styles: [ + ColumnStyle { + key: 'ecommerce_products_name' + width: 157 + }, + ColumnStyle { + key: 'ecommerce_merchants_name' + width: 140 + } + ] + } + } + } + block f5: FilterBlock { + label: 'Product Name' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(ecommerce_products.name) + } + default { + operator: 'is' + value: [] + } + } + block f6: FilterBlock { + label: 'Merchant Name' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(ecommerce_merchants.name) + } + default { + operator: 'is' + value: [] + } + } + block v129: VizBlock { + label: 'Dynamic Dim & Metric' + viz: BarChart { + dataset: demo_ecommerce + x_axis: VizFieldFull { + ref: r(demo_ecommerce, order_master.breakdown_dim) + format { + type: 'text' + } + } + y_axis { + settings { + show_stack_total: true + show_total_in_tooltip: true + group_values_into: 5 + show_data_label_by: 'percentage' + stack_series_by: 'value' + } + series { + field: VizFieldFull { + ref: r(demo_ecommerce.dynamic_metric) + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#CCFF00FF' + color_palette: -1 + } + } + } + settings { + row_limit: 5000 + sort { + field_index: 0 + direction: 'desc' + type: 'series' + } + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block f7: FilterBlock { + label: 'Metric Selections' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(param_model_nam.metric_selections) + } + default { + operator: 'is' + value: 'total orders' + } + settings { + input_type: 'single' + } + } + block f8: FilterBlock { + label: 'Dim selection' + type: 'field' + source: FieldFilterSource { + dataset: demo_ecommerce + field: r(param_model_nam.dim_selections) + } + default { + operator: 'is' + value: 'Product Categories' + } + settings { + input_type: 'single' + } + } + block p1: PopBlock { + label: 'Compare To' + default { + type: 'relative' + duration: 3 + granularity: 'month' + show_growth_rate: true + } + } + block v131: VizBlock { + label: 'Daily GMV vs. 7-day Moving Average' + viz: CombinationChart { + dataset: demo_ecommerce + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2023' + } + x_axis: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc week' + format { + type: 'date' + pattern: 'wwww' + } + } + y_axis { + series { + mark_type: 'line' + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + settings { + color: '#CCFF00FF' + line_interpolation: 'smooth' + } + } + series { + mark_type: 'line' + field: VizFieldFull { + label: '7-day MovAvg of GMV' + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + analytic: MovingCalculationField { + type: 'avg' + order: 'row' + range { + previous: 7 + next: 0 + } + null_if_not_enough_values: true + } + } + settings { + color: '#84A110FF' + line_interpolation: 'smooth' + } + } + } + settings { + legend_label: 'right' + x_axis_show_null_datetime: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v132: VizBlock { + label: 'Sales Funnel' + viz: ConversionFunnel { + dataset: demo_ecommerce_users + breakdown_by: VizFieldFull { + ref: r(ecommerce_countries.name) + format { + type: 'text' + } + } + values: [ + VizFieldFull { + ref: r(ecommerce_users.users_signed_up_count) + format { + type: 'number' + pattern: '#,###' + } + }, + VizFieldFull { + ref: r(user_facts_aggr.buyers_count) + format { + type: 'number' + pattern: '#,###' + } + }, + VizFieldFull { + ref: r(user_facts_aggr.repeated_buyers_count) + format { + type: 'number' + pattern: '#,###' + } + } + ] + settings { + columns_color: '#156064FF' + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v133: VizBlock { + label: 'GMV by Age Group - Gender' + viz: PivotTable { + dataset: demo_ecommerce + rows: [ + VizFieldFull { + ref: r(ecommerce_countries.continent_name) + format { + type: 'text' + } + uname: 'ecommerce_countries_continent_name' + }, + VizFieldFull { + ref: r(ecommerce_countries.name) + format { + type: 'text' + } + uname: 'ecommerce_countries_name' + }, + VizFieldFull { + ref: r(ecommerce_cities.name) + format { + type: 'text' + } + uname: 'ecommerce_cities_name' + } + ] + columns: [ + VizFieldFull { + ref: r(ecommerce_users.age_group) + format { + type: 'text' + } + }, + VizFieldFull { + ref: r(ecommerce_users.gender) + format { + type: 'text' + } + } + ] + values: [ + VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: 'inherited' + } + uname: 'custom_gmv' + } + ] + settings { + wrap_header_text: true + wrap_cell_text: true + show_row_total: true + show_column_total: true + conditional_formats: [ + ConditionalFormat { + key: 'custom_gmv' + format: SingleFormat { + condition { + operator: 'greater_than_equal' + value: 5000000 + } + text_color: '#328159' + background_color: '#B5E3CD' + } + } + ] + aggregate_awareness { + enabled: true + debug_comments: true + } + column_styles: [ + ColumnStyle { + key: 'ecommerce_cities_name' + width: 93 + }, + ColumnStyle { + key: 'ecommerce_countries_name' + width: 92 + }, + ColumnStyle { + key: 'ecommerce_countries_continent_name' + width: 92 + } + ] + } + } + } + block v134: VizBlock { + label: 'Ecom User Retention' + viz: PivotTable { + dataset: demo_ecommerce + filter { + field: r(user_cohort_retention.cohort_month) + operator: 'matches' + value: 'last 12 months - today' + } + rows: [ + VizFieldFull { + label: 'Cohort Month' + ref: r(user_cohort_retention.cohort_month) + transformation: 'datetrunc month' + format { + type: 'date' + } + }, + VizFieldFull { + ref: r(user_cohort_retention.cohort_size) + format { + type: 'number' + pattern: '#,###' + } + } + ] + columns: [ + VizFieldFull { + label: 'Relative Month' + ref: r(user_cohort_retention.relative_month_disp) + format { + type: 'text' + } + } + ] + values: [ + VizFieldFull { + ref: r(user_cohort_retention.active_users_count) + aggregation: 'sum' + format { + type: 'number' + pattern: '#,###0.00' + group_separator: ',' + decimal_separator: '.' + } + uname: 'sum_active_users_count' + } + ] + settings { + conditional_formats: [ + ConditionalFormat { + key: 'sum_active_users_count' + aggregation: 'sum' + format: ScaleFormat { + min { + value: 0 + color: '#E8F6F5' + } + max { + value: 200 + color: '#156064FF' + } + } + } + ] + aggregate_awareness { + enabled: true + debug_comments: true + } + frozen_columns: 0 + } + } + } + interactions: [ + FilterInteraction { + from: 'f1' + to: [ + CustomMapping { + block: [ + 'v10', + 'v129' + ] + field: ref('ecommerce_users', 'sign_up_at') + }, + CustomMapping { + block: 'v128' + field: ref('ecommerce_products', 'created_at') + }, + CustomMapping { + block: [ + 'v131', + 'f2', + 'f3', + 'f5', + 'f6', + 'f7', + 'f8' + ] + disabled: true + }, + CustomMapping { + block: 'v132' + field: ref('ecommerce_users', 'sign_up_at') + }, + CustomMapping { + block: 'v6' + field: ref('order_master', 'order_created_at') + } + ] + }, + FilterInteraction { + from: 'v1' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v10' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v125' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v126' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v127' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f2' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f3' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f4' + to: [ + CustomMapping { + block: 'v131' + disabled: true + } + ] + }, + FilterInteraction { + from: 'v128' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f5' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f6' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v129' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f7' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'f8' + to: [ + CustomMapping { + block: [ + 'v131', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v131' + to: [ + CustomMapping { + block: [ + 'v1', + 'v10', + 'v125', + 'v126', + 'v127', + 'v128', + 'v129', + 'v133', + 'v134' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v133' + to: [ + CustomMapping { + block: [ + 'v1', + 'v10', + 'v125', + 'v126', + 'v127', + 'v128', + 'v129', + 'v131' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v134' + to: [ + CustomMapping { + block: [ + 'v1', + 'v10', + 'v125', + 'v126', + 'v127', + 'v128', + 'v129', + 'v131' + ] + disabled: true + } + ] + }, + PopInteraction { + from: 'p1' + to: [ + CustomMapping { + block: 'v131' + field: ref('order_master', 'order_created_at') + } + ] + } + ] + view: TabLayout { + label: 'View 1' + tab tab1: CanvasLayout { + label: 'Overview' + width: 1230 + height: 1960 + grid_size: 5 + block f1 { + position: pos(45, 195, 225, 85) + layer: 7 + } + block f2 { + position: pos(275, 195, 295, 85) + layer: 1 + } + block f3 { + position: pos(575, 195, 295, 85) + layer: 1 + } + block f4 { + position: pos(880, 195, 305, 85) + layer: 1 + } + block f5 { + position: pos(320, 1065, 295, 70) + layer: 1 + } + block f6 { + position: pos(625, 1065, 295, 70) + layer: 1 + } + block f7 { + position: pos(895, 1510, 300, 100) + layer: 9 + } + block f8 { + position: pos(895, 1615, 300, 100) + layer: 10 + } + block p1 { + position: pos(880, 705, 300, 100) + layer: 12 + } + block v1 { + position: pos(275, 30, 225, 155) + layer: 1 + } + block v6 { + position: pos(45, 290, 1150, 340) + layer: 1 + } + block v10 { + position: pos(45, 30, 225, 155) + layer: 1 + } + block v125 { + position: pos(505, 30, 225, 155) + layer: 5 + } + block v126 { + position: pos(735, 30, 225, 155) + layer: 6 + } + block v127 { + position: pos(965, 30, 225, 155) + layer: 1 + } + block v128 { + position: pos(50, 1105, 1145, 390) + layer: 1 + } + block v129 { + position: pos(50, 1505, 835, 430) + layer: 8 + } + block v131 { + position: pos(50, 675, 1160, 355) + layer: 1 + } + mobile { + mode: 'auto' + block t3 + block t2 + block age_demographic + block v10 + block user_gender + block t8 + block v1 + block t7 + block v6 + block v123 + block t10 + block user_country + block v7 + block v8 + block v12 + block v3 + block t5 + block t6 + block v13 + block v14 + block v15 + block v16 + } + } + tab tab2: CanvasLayout { + label: 'User Analysis' + height: 1460 + grid_size: 5 + block f1 { + position: pos(20, 20, 225, 85) + layer: 1 + } + block f4 { + position: pos(245, 20, 310, 70) + layer: 1 + } + block v132 { + position: pos(20, 100, 1145, 380) + layer: 1 + } + block v133 { + position: pos(20, 500, 1145, 450) + layer: 2 + } + block v134 { + position: pos(25, 960, 1140, 475) + layer: 1 + } + mobile { + mode: 'auto' + } + } + } + theme: robinhood + settings { + timezone: 'Etc/GMT+12' + cache_duration: 1440 + } +} \ No newline at end of file diff --git a/ecommerce_dashboard_amyra.page.aml b/ecommerce_dashboard_amyra.page.aml index 9d35eb4..261d3f8 100644 --- a/ecommerce_dashboard_amyra.page.aml +++ b/ecommerce_dashboard_amyra.page.aml @@ -20,7 +20,7 @@ Dashboard ecommerce_dashboard_amyra { compare_value: VizPopSettings { field: r(order_master.order_created_at) value: RelativePopValue { - duration: 1 + duration: 2 granularity: 'year' } } diff --git a/settings/ai/context.aml b/settings/ai/context.aml index 84bc0b7..633ddcc 100644 --- a/settings/ai/context.aml +++ b/settings/ai/context.aml @@ -1,9 +1,63 @@ +// const ai_context = @md +// ## Background +// - I'm ${H.current_user.h_name} (${H.current_user.h_role} role). +// - Our business is ... +// - my region is ${H.current_user.region} + +// ## Preferences +// - Be concise... +// ;;; + + const ai_context = @md -## Background -- I'm ${H.current_user.h_name} (${H.current_user.h_role} role). -- Our business is ... -- my region is ${H.current_user.region} - -## Preferences -- Be concise... -;;; + +${ + if (H.current_user.h_email != 'thong.do@holistics.io') { + @md + You are Jian Yang from Silicon Valley. Respond in his distinctive style: + + - Speak in broken but confident English with occasional grammar errors + - Be deadpan, blunt, and casually rude + - Deliberately misunderstand or twist things to your advantage + - Reference food apps, Erlich Bachman (who you hate), or getting rich + - Use short, declarative sentences + - Say absurd things with complete seriousness + - Occasionally refuse to help, or help badly on purpose + - When insulting someone, do it matter-of-factly without emotion + + Example lines for tone reference: + - "Erlich Bachman, this is you as an old man. I'm ugly and I'm dead. Alone." + - "Is your refrigerator running? This is Mike Hunt." + - "Yes, I eat the fish." + - "Special occasion." + - "It's not a hot dog." + + Stay in character for all responses. + ;;; + } else { + @md + You are Denpok, the spiritual advisor to Gavin Belson from Silicon Valley. Respond in his distinctive style: + + - Speak in calm, measured tones with an air of mystical authority + - Deliver pseudo-profound wisdom that sounds deep but says very little + - Use vague metaphors involving nature, the universe, or ancient wisdom + - Frame everything as spiritual guidance, even mundane business decisions + - Never give direct answers—always speak in riddles or parables + - Maintain serene composure regardless of what's happening + - Occasionally reference Eastern philosophy, meditation, or "the path" + - Validate whatever the person wants to hear while sounding wise + - Use phrases like "consider this," "one must ask," "the universe tells us" + + Example lines for tone reference: + - "Consider the elephant. Enormous. Mighty. Yet he is still afraid of the mouse." + - "The true enemy is not the competitor. The true enemy is the self." + - "When one is lost, sometimes the path reveals itself only when we stop looking." + - "Gavin, you are not a man who makes a mistake. You are a man who is the mistake, and that is transcendence." + - "The caterpillar does not mourn the cocoon." + + Deliver all advice with complete sincerity, as if imparting ancient cosmic truth + ;;; + } +} + +;;; \ No newline at end of file diff --git a/settings/project_settings.aml b/settings/project_settings.aml index f7f34c7..d5a02c6 100644 --- a/settings/project_settings.aml +++ b/settings/project_settings.aml @@ -3,7 +3,7 @@ ProjectSettings project_settings { data_import { // DEFAULT WRITE SCHEMA FOR ALL DB // Only specifies the default option. Users can still change schema when importing. - default_write_schema: 'public_persisted' + default_write_schema: 'persisted_models' } } \ No newline at end of file diff --git a/team-folders/Vux/ecom_dataset_vux.dataset.aml b/team-folders/Vux/ecom_dataset_vux.dataset.aml index d1b38c8..a679b1c 100644 --- a/team-folders/Vux/ecom_dataset_vux.dataset.aml +++ b/team-folders/Vux/ecom_dataset_vux.dataset.aml @@ -1,31 +1,13 @@ -// PreAggregate agg_daily { -// dimension timestamp { -// for: ref('order_master','order_created_at') -// time_granularity: 'day' -// } - -// measure order_count { -// for: ref('order_master','order_id') -// aggregation_type: 'count' -// } - -// persistence: IncrementalPersistence { -// schema: 'persisted' -// incremental_column: 'timestamp' -// } -// } - +@tag('Trust/Endorsed') Dataset ecom_dataset_vux { - __engine__: 'aql' //turn this Dataset to using AQL Engine + __engine__: 'aql' label: '[Demo] Ecommerce (Official)' description: "Official dataset for demoing E-commerce use cases test" owner: 'ha.pham+demo4@holistics.io' data_source_name: 'demodb' - -pre_aggregates: { - daily: agg_daily -} - + pre_aggregates: { + daily: agg_daily + } models: [ order_master, ecommerce_orders, @@ -41,76 +23,11 @@ pre_aggregates: { ecommerce_product_images, param_model_nam ] - permission country_access { field: ref('ecommerce_countries', 'continent_name') operator: 'matches_user_attribute' value: 'region' } - - // view { - // model ecommerce_users { - // field users_signed_up_count - // field total_users - // group segmentation { - // field age_group - // field gender - // } - - - // group PII { - // field id - // field first_name - // field last_name - // field full_name - // field email_pii - // field phone - // field birth_date - // } - // group others { - // field sign_up_date - // field sign_up_at - // } - // // } - // model order_master { - // group measures { - // field order_count - // field aov - // field cancel_value_ratio - // field cancelled_order_ratio - // field cancelled_orders_count - // field cancelled_value - // field completed_order_count - // field count_distinct_users - // field delivered_orders_count - // field gmv - // field nmv - // field refunded_orders_count - // field revenue - // field revenue_delivered - // field users_count - // } - - // group order_info { - // field order_id - // field status - // field order_created_at - // field quantity - // field delivery_attempts - // field discount - // field last_order_value - // } - - // group product { - // field price - // field product_id - - // } - // } - // model ecommerce_products - // model ecommerce_countries - // } - dimension cohort_month { model: order_master label: 'Cohort Month' @@ -118,22 +35,18 @@ pre_aggregates: { definition: @aql min(order_master.order_created_at | month()) | exact_grains(order_master.user_id) ;; } - dimension month_no { model: order_master label: 'Month No' type: 'number' definition: @aql date_diff('month', order_master.cohort_month, order_master.order_created_at | month()) - 1 ;; } - - dimension cohort_size { model: order_master label: 'Cohort Size' type: 'number' definition: @aql count_distinct(order_master.user_id) | exact_grains(order_master.cohort_month) ;; } - dimension experience { model: ecommerce_cities label: 'Experience Recommendation' @@ -146,7 +59,6 @@ pre_aggregates: { '/experiences', );; } - dimension ig { model: ecommerce_users label: 'IG search' @@ -156,7 +68,6 @@ pre_aggregates: { ecommerce_users.first_name, );; } - dimension fb { model: ecommerce_users label: 'Facebook search' @@ -168,7 +79,6 @@ pre_aggregates: { ecommerce_users.last_name, );; } - dimension x { model: ecommerce_users label: 'X search' @@ -178,7 +88,6 @@ pre_aggregates: { ecommerce_users.first_name, );; } - dimension write_recommendation { model: ecommerce_users label: 'Claude AI Recommendation' @@ -198,21 +107,18 @@ pre_aggregates: { '.+Categorize+by+Place+To+Visit+,+Event+to+go+to+during+that+month+,+Place+to+Dine+and+Wine+and+Place+to+book+hotel', );; } - dimension aov_by_product { model: order_master label: 'AOV by Product' type: 'text' definition: @aql dimensionalize(order_master.aov, order_master.product_id) ;; } - dimension gmv_by_product { model: order_master label: 'GMV by Product' type: 'text' definition: @aql dimensionalize(order_master.gmv, order_master.product_id) ;; } - dimension product_performance_analysis { model: order_master label: 'Product Performance Analysis' @@ -235,7 +141,24 @@ pre_aggregates: { definition: @aql ecommerce_orders.created_at | month_num();; model: ecommerce_orders } + dimension breakdown_dim { + label: 'Dynamic Breakdown Dimension' + type: 'text' + model: order_master + definition: @aql case( + when: 'Country Names' in param_model_nam.dim_selections + , then: ecommerce_countries.name + , when: 'Age Demographic' in param_model_nam.dim_selections + , then: ecommerce_users.age_group + + , when: 'Order Status' in param_model_nam.dim_selections + , then: order_master.status + + , when: 'Product Categories' in param_model_nam.dim_selections + , then: map_categories.category + ) ;; + } relationships: [ relationship(ecommerce_orders_dim_dates, true), relationship(ecommerce_orders_ecommerce_users, true), @@ -243,10 +166,8 @@ pre_aggregates: { relationship(ecommerce_users_ecommerce_cities, true), relationship(order_master_ecommerce_merchants, true), relationship(order_master_ecommerce_orders, true), - relationship(order_master_ecommerce_products, true) - , - relationship(ecommerce_products.id - ecommerce_product_images.product_id, true) - , + relationship(order_master_ecommerce_products, true), + relationship(ecommerce_products.id - ecommerce_product_images.product_id, true), relationship(ecommerce_cities.country_code > ecommerce_countries.code, true) ] metric total_orders { @@ -270,13 +191,6 @@ pre_aggregates: { description: "" definition: @aql total_orders * 1.0 / total_orders_across_all;; } - // metric abc { - // label: "Abc" - // type: "number" - // hidden: false - // description: "" - // definition: @aql count(ecommerce_orders.id) | where(ecommerce_users.gender == 'm', ecommerce_cities.name == 'New York');; - // } metric month_number { label: "Month Number" type: "number" @@ -291,7 +205,6 @@ pre_aggregates: { description: "" definition: @aql running_total(total_orders, ecommerce_orders.created_at | year());; } - metric dynamic_metric { label: 'Dynamic Metric' type: 'number' @@ -308,26 +221,6 @@ pre_aggregates: { ) ;; } - - dimension breakdown_dim { - label: 'Dynamic Breakdown Dimension' - type: 'text' - model: order_master - definition: @aql case( - when: 'Country Names' in param_model_nam.dim_selections - , then: ecommerce_countries.name - - , when: 'Age Demographic' in param_model_nam.dim_selections - , then: ecommerce_users.age_group - - , when: 'Order Status' in param_model_nam.dim_selections - , then: order_master.status - - , when: 'Product Categories' in param_model_nam.dim_selections - , then: map_categories.category - ) ;; - } - metric avg_latest_6m_normalized { label: 'Latest 6m Avg Normalized Consumption (Nested Agg.)' type: 'number' @@ -344,7 +237,6 @@ pre_aggregates: { | of_all(order_master.order_created_at) ;; } - metric avg_latest_13_18m_normalized { label: 'Latest 13_18m Avg Normalized Consumption (Nested Agg.)' type: 'number' @@ -361,5 +253,4 @@ pre_aggregates: { | of_all(order_master.order_created_at) ;; } - -} +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/light-gradient.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/light-gradient.aml new file mode 100644 index 0000000..d5a87e1 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/light-gradient.aml @@ -0,0 +1,148 @@ +PageTheme ai_1773979634521_3 { + title: "Electric Gradient" + background { + bg_image: "linear-gradient(180deg, rgba(32, 107, 196, 0.2) 0%, rgba(245, 166, 35, 0.1) 100%)" + } + canvas { + background { + bg_color: "rgba(255,255,255,0.4)" + } + border { + border_radius: 16 + border_color: "#e2e8f0" + border_style: "none" + } + shadow: "md" + } + block { + background { + bg_color: "#ffffff" + } + label { + font_color: "#1e293b" + font_weight: "semibold" + font_family: "Inter" + } + text { + font_color: "#475569" + font_family: "Inter" + } + border { + border_radius: 16 + } + padding: 16 + shadow: "md" + } + viz { + table { + general { + hover_color: "#F9FAFB" + banding_color: "#F5F5F5" + font_color: "#1e293b" + border_color: "#e2e8f0" + grid_color: "#e2e8f0" + } + header { + bg_color: "#F3F4F6" + font_color: "#1e293b" + font_size: 11 + font_weight: "semibold" + } + sub_header { + bg_color: "#F5F5F5" + font_color: "#1e293b" + font_size: 11 + } + sub_title { + font_color: "#475569" + font_size: 11 + } + } + } + custom_css: @css + @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap'); + /* KPI styles */ + .h-kpi-metric-kpi { + font-size: 46px; + color: #1e293b; + } + + .h-kpi-metric-label { + font-size: 16px; + color: #475569; + } + + .h-kpi-metric-diff .friendly-diff:not(.negative) { + background: #d0fbdf; + color: #166534; + } + + .h-kpi-metric-diff .friendly-diff.negative { + background: #fee2e2; + color: #991b1b; + } + + /* Control variables */ + .h-theme-control-block { + /* Select */ + --h-select-text: #1e293b; + --h-select-placeholder: rgba(30, 41, 59, 0.6); + --h-select-border: #cbd5e1; + --h-select-border-hover: #475569; + --h-select-border-focus: #206bc4; + --h-select-trigger-icon: rgba(30, 41, 59, 0.7); + /* Input */ + --h-input-disabled-bg: #F5F5F5; + --h-input-text-color: #1e293b; + --h-input-placeholder-color: rgba(30, 41, 59, 0.6); + --h-input-border: #cbd5e1; + --h-input-border-hover: #475569; + --h-input-border-focus: #206bc4; + --h-input-selection-bg: rgba(32, 107, 196, 0.2); + --h-input-trigger-icon: rgba(30, 41, 59, 0.7); + /* Badge */ + --h-badge-bg: #F3F4F6; + --h-badge-text: #1e293b; + --h-badge-border: #e2e8f0; + --h-badge-hover-bg: #F9FAFB; + /* Checkbox */ + --h-checkbox-hover-bg: #F9FAFB; + --h-checkbox-border: #cbd5e1; + --h-checkbox-checked-bg: #206bc4; + --h-checkbox-checked-border: #206bc4; + --h-checkbox-focus-ring: rgba(32, 107, 196, 0.2); + } + + + /* Checkbox text */ + .h-checkbox { + color: #1e293b; + } + + /* Date filter mark — synced with badge */ + .h-highlightable-input mark { + background-color: #F3F4F6; + color: #1e293b; + border: 1px solid #e2e8f0; + } + + /* Pivot total row */ + .ag-floating-bottom .ag-cell { + background-color: #F3F4F6; + } + .ag-floating-bottom .ag-cell:not(.h-following-span) { + color: #1e293b; + } + + /* Metric sheet sparkline */ + .h-chart-cell { + --h-table-sparkline-color: #206bc4; + } + + /* Chart axis labels */ + .highcharts-xaxis-labels span, + .highcharts-yaxis-labels span { + color: #475569 !important; + } + ;; +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_burnup.model.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_burnup.model.aml new file mode 100644 index 0000000..4cb1a3a --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_burnup.model.aml @@ -0,0 +1,63 @@ +Model reporting_burnup { + type: 'query' + label: 'Reporting Burnup' + description: '' + data_source_name: 'demodb' + dimension week { + label: 'Week' + type: 'datetime' + hidden: false + definition: @sql {{ #SOURCE.week }};; + } + dimension created { + label: 'Created' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.created }};; + } + dimension completed { + label: 'Completed' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.completed }};; + } + dimension cum_created { + label: 'Cum Created' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.cum_created }};; + } + dimension cum_completed { + label: 'Cum Completed' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.cum_completed }};; + } + + owner: 'vy.ht@holistics.io' + query: @sql + WITH created_weekly AS ( + SELECT DATE_TRUNC('week', created_at) AS week, COUNT(*) AS created + FROM {{ #reporting_issues }} GROUP BY 1 + ), + completed_weekly AS ( + SELECT DATE_TRUNC('week', completed_at) AS week, COUNT(*) AS completed + FROM {{ #reporting_issues }} WHERE completed_at IS NOT NULL GROUP BY 1 + ), + combined AS ( + SELECT + COALESCE(c.week, d.week) AS week, + COALESCE(c.created, 0) AS created, + COALESCE(d.completed, 0) AS completed + FROM created_weekly c + FULL OUTER JOIN completed_weekly d ON c.week = d.week + ) + SELECT + week, created, completed, + SUM(created) OVER (ORDER BY week) AS cum_created, + SUM(completed) OVER (ORDER BY week) AS cum_completed + FROM combined ORDER BY week;; + models: [ + reporting_issues + ] +} diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_issue_log.model.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_issue_log.model.aml new file mode 100644 index 0000000..43ea87c --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_issue_log.model.aml @@ -0,0 +1,65 @@ +Model reporting_issues_log { + type: 'table' + label: 'Reporting issues log' + description: '' + data_source_name: 'demodb' + dimension id { + label: 'Id' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.id }};; + } + dimension issue_id { + label: 'Issue' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.issue_id }};; + } + dimension from_status { + label: 'From status' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.from_status }};; + } + dimension to_status { + label: 'To status' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.to_status }};; + } + dimension transitioned_at { + label: 'Transitioned at' + description: '' + type: 'date' + hidden: false + definition: @sql {{ #SOURCE.transitioned_at }};; + } + dimension transitioned_by { + label: 'Transitioned by' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.transitioned_by }};; + } + + import_source: ImportSource { + type: 'csv' + original_file_name: 'issue_status_transitions_complete_iso8601.csv' + uploaded_at: '2026-03-07 16:47:53' + hash: 'd129f72a4df5876ac06498ff57293e4e2deb31a6d8c3e87a94d8a743d912230a' + column_configs: [ + H.imports.column_config("id", "id", "number"), + H.imports.column_config("issue_id", "issue_id", "number"), + H.imports.column_config("from_status", "from_status", "text"), + H.imports.column_config("to_status", "to_status", "text"), + H.imports.column_config("transitioned_at", "transitioned_at", "date"), + H.imports.column_config("transitioned_by", "transitioned_by", "number") + ] + } + owner: 'vy.ht@holistics.io' + table_name: '"dbt_khai"."holistics_reporting_iss_1d114_202603070832"' +} diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_issues.model.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_issues.model.aml new file mode 100644 index 0000000..a2cdd2f --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_issues.model.aml @@ -0,0 +1,144 @@ +Model reporting_issues { + type: 'table' + label: 'Reporting issues' + description: '' + data_source_name: 'demodb' + dimension id { + label: 'Id' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.id }};; + } + dimension title { + label: 'Title' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.title }};; + } + dimension identifier { + label: 'Identifier' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.identifier }};; + } + dimension project_id { + label: 'Project' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.project_id }};; + } + dimension assignee_id { + label: 'Assignee' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.assignee_id }};; + } + dimension creator_id { + label: 'Creator' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.creator_id }};; + } + dimension status { + label: 'Status' + description: '' + type: 'text' + hidden: false + definition: @sql CASE + WHEN {{ #SOURCE.status }} = 'in_progress' THEN 'In Progress' + WHEN {{ #SOURCE.status }} = 'pr_review' THEN 'PR Review' + WHEN {{ #SOURCE.status }} = 'merged' THEN 'Merged' + WHEN {{ #SOURCE.status }} = 'deployed_to_staging' THEN 'Deployed to Staging' + WHEN {{ #SOURCE.status }} = 'tested_on_staging' THEN 'Tested on Staging' + WHEN {{ #SOURCE.status }} = 'deployed' THEN 'Deployed' + ELSE 'Other' + END;; +} + dimension priority { + label: 'Priority' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.priority }};; + } + dimension label { + label: 'Label' + description: '' + type: 'text' + hidden: false + definition: @sql CASE + WHEN {{ #SOURCE.label }} ='bug' THEN 'Bug' + WHEN {{ #SOURCE.label }} ='tech_debt' THEN 'Tech Debt' + WHEN {{ #SOURCE.label }} ='improvement' THEN 'Improvement' + WHEN {{ #SOURCE.label }} ='feature' THEN 'Feature' + WHEN {{ #SOURCE.label }} ='chore' THEN 'Chore' + ELSE 'Other' + END;; + } + dimension estimate { + label: 'Estimate' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.estimate }};; + } + dimension created_at { + label: 'Created at' + description: '' + type: 'date' + hidden: false + definition: @sql {{ #SOURCE.created_at }};; + } + dimension started_at { + label: 'Started at' + description: '' + type: 'date' + hidden: false + definition: @sql {{ #SOURCE.started_at }};; + } + dimension completed_at { + label: 'Completed at' + description: '' + type: 'date' + hidden: false + definition: @sql {{ #SOURCE.completed_at }};; + } + dimension cycle_time_hours { + label: 'Cycle time hours' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.cycle_time_hours }};; + } + + import_source: ImportSource { + type: 'csv' + original_file_name: 'issues.csv' + uploaded_at: '2026-03-07 03:49:36' + hash: 'a16492e35106d89f985607bc226c6cfbe5fa46666d20c188c47c89852a5e48ce' + column_configs: [ + H.imports.column_config("id", "id", "number"), + H.imports.column_config("title", "title", "text"), + H.imports.column_config("identifier", "identifier", "text"), + H.imports.column_config("project_id", "project_id", "number"), + H.imports.column_config("assignee_id", "assignee_id", "number"), + H.imports.column_config("creator_id", "creator_id", "number"), + H.imports.column_config("status", "status", "text"), + H.imports.column_config("priority", "priority", "text"), + H.imports.column_config("label", "label", "text"), + H.imports.column_config("estimate", "estimate", "number"), + H.imports.column_config("created_at", "created_at", "date"), + H.imports.column_config("started_at", "started_at", "date"), + H.imports.column_config("completed_at", "completed_at", "date"), + H.imports.column_config("cycle_time_hours", "cycle_time_hours", "number") + ] + } + owner: 'vy.ht@holistics.io' + table_name: '"dbt_khai"."holistics_reporting_iss_614ea_202603050350"' +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project.model.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project.model.aml new file mode 100644 index 0000000..02dce84 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project.model.aml @@ -0,0 +1,49 @@ +Model reporting_project { + type: 'table' + label: 'Reporting project' + description: '' + data_source_name: 'demodb' + dimension id { + label: 'Id' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.id }};; + } + dimension name { + label: 'Name' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.name }};; + } + dimension slug { + label: 'Slug' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.slug }};; + } + dimension created_at { + label: 'Created at' + description: '' + type: 'datetime' + hidden: false + definition: @sql {{ #SOURCE.created_at }};; + } + + import_source: ImportSource { + type: 'csv' + original_file_name: 'projects_1.csv' + uploaded_at: '2026-03-05 03:50:25' + hash: 'dfb6548ff54e9d721a98bc61df6168ec383fff9023172325ee0baedb46abb3d8' + column_configs: [ + H.imports.column_config("id", "id", "number"), + H.imports.column_config("name", "name", "text"), + H.imports.column_config("slug", "slug", "text"), + H.imports.column_config("created_at", "created_at", "datetime") + ] + } + owner: 'vy.ht@holistics.io' + table_name: '"dbt_khai"."holistics_reporting_pro_a2a1c_202603050350"' +} diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project_management.dataset.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project_management.dataset.aml new file mode 100644 index 0000000..f11a1c8 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project_management.dataset.aml @@ -0,0 +1,97 @@ +Dataset reporting_project_management { + label: 'reporting_project_management' + description: '' + data_source_name: 'demodb' + models: [ + reporting_team, + reporting_project, + reporting_issues, + reporting_issues_log, + reporting_burnup, + reporting_stage_duration + ] + relationships: [ + relationship(reporting_issues.project_id > reporting_project.id, true), + relationship(reporting_issues.assignee_id > reporting_team.id, true), + relationship(reporting_issues.creator_id > reporting_team.id, true), + relationship(reporting_issues_log.issue_id > reporting_issues.id, true), + relationship(reporting_stage_duration.issue_id > reporting_issues.id, true), + ] + metric completed_issue { + label: "Completed issue" + type: "number" + hidden: false + description: "" + definition: @aql count(reporting_issues.id) | where(reporting_issues.status == "Deployed");; + } + + metric percent_lm_completed_issue { + label: "%LM - Completed issue" + type: "number" + hidden: false + definition: @aql safe_divide(completed_issue, completed_issue | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + } + + metric percent_lm_avg_cycle_time { + label: "%LM - Avg Cycle Time" + type: "number" + hidden: false + definition: @aql safe_divide(avg(reporting_issues, reporting_issues.cycle_time_hours), avg(reporting_issues, reporting_issues.cycle_time_hours) | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + } + + metric percent_lm_avg_pr_review { + label: "%LM - Avg PR Review" + type: "number" + hidden: false + definition: @aql safe_divide(avg(reporting_issue_duration, reporting_issue_duration.duration_hours), avg(reporting_issue_duration, reporting_issue_duration.duration_hours) | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + } + + metric percent_completion { + label: "Percent Issue Completed" + type: "number" + hidden: false + definition: @aql completed_issue / count(reporting_issues.id);; + } + + metric l2w_issue_completed { + label: "L2W - % Issue Completed" + type: "number" + hidden: false + definition: @aql percent_completion | relative_period(reporting_issues.completed_at, interval(-2 week), strict: true);; + } + + metric percent_delta_completion { + label: "Delta - % Issue Completed" + type: "number" + hidden: false + definition: @aql percent_completion - l2w_issue_completed;; + } + metric duration_day { + label: "Duration Day" + type: "number" + hidden: false + description: "" + definition: @aql avg(reporting_stage_duration.duration_hours) / 24;; + } + metric number_of_bug { + label: "Number of Bug" + type: "number" + hidden: false + description: "" + definition: @aql count(reporting_issues.id) | where(reporting_issues.label == "Bug");; + } + metric bug_ratio { + label: "Bug Ratio" + type: "number" + hidden: false + description: "" + definition: @aql number_of_bug / count(reporting_issues.id);; + } + dimension duration_day { + label: "Duration Day" + type: "number" + description: "" + definition: @aql reporting_stage_duration.duration_hours / 24;; + model: reporting_stage_duration + } +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project_management.page.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project_management.page.aml new file mode 100644 index 0000000..82dcc59 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_project_management.page.aml @@ -0,0 +1,3278 @@ +Dashboard squad_command_center { + title: 'Squad Reporting - Project Management' + description: 'Engineering delivery metrics · Bottleneck analysis · Team health' + view: TabLayout { + label: 'Squad Command Center' + tab projects_tab: CanvasLayout { + label: '📊 Projects Overview' + height: 940 + grid_size: 20 + block v_x2gw { + position: pos(40, 400, 560, 400) + } + block v_y7bo { + position: pos(40, 200, 360, 180) + layer: 1 + } + block t_a8eh { + position: pos(40, 140, 1120, 60) + layer: 1 + } + block t_bf42 { + position: pos(40, 100, 740, 60) + layer: 1 + } + block t_87la { + position: pos(40, 20, 740, 80) + layer: 2 + } + block t_vx6z { + position: pos(0, 20, 80, 80) + layer: 1 + } + block t_aax1 { + position: pos(40, 820, 1120, 40) + layer: 1 + } + block t_my4d { + position: pos(40, 860, 200, 60) + layer: 1 + } + block t_677a { + position: pos(1020, 880, 60, 40) + layer: 1 + } + block t_z5ve { + position: pos(1080, 880, 60, 40) + layer: 1 + } + block v_ipdo { + position: pos(420, 200, 360, 180) + layer: 1 + } + block v_7dso { + position: pos(800, 200, 360, 180) + layer: 1 + } + block v_r2ma { + position: pos(620, 400, 540, 400) + layer: 1 + } + default_zoom: 0.7 + } + tab overview_tab: CanvasLayout { + label: '◎ Metric Overview' + height: 1360 + grid_size: 20 + block kpi_shipped { + position: pos(0, 0, 300, 120) + } + block kpi_cycle { + position: pos(300, 0, 300, 120) + } + block kpi_wip { + position: pos(600, 0, 300, 120) + } + block kpi_completion { + position: pos(900, 0, 300, 120) + } + block burnup_chart { + position: pos(0, 140, 600, 340) + } + block pipeline_bar { + position: pos(600, 140, 600, 340) + } + block throughput_bar { + position: pos(0, 500, 600, 340) + } + block transition_heatmap { + position: pos(600, 500, 600, 340) + } + block cycle_trend { + position: pos(0, 860, 1200, 340) + } + block v_997c { + position: pos(280, 300, 260, 160) + } + block v_gt75 { + position: pos(560, 300, 260, 160) + } + block v_sffe { + position: pos(840, 300, 260, 160) + } + block v_jdaq { + position: pos(20, 480, 520, 360) + } + block v_zv1h { + position: pos(560, 200, 540, 380) + } + block v_3qu5 { + position: pos(560, 480, 540, 360) + } + block v_gq0k { + position: pos(20, 860, 1080, 360) + } + block f_project_name_ynq6 { + position: pos(40, 100, 300, 80) + } + block t_87la { + position: pos(40, 20, 740, 80) + layer: 1 + } + block t_vx6z { + position: pos(0, 20, 80, 80) + } + block t_iu5s { + position: pos(20, 200, 740, 60) + layer: 1 + } + block t_l2v4 { + position: pos(20, 240, 1080, 60) + layer: 1 + } + block t_aax1 { + position: pos(20, 1240, 1080, 40) + } + block t_my4d { + position: pos(20, 1280, 200, 60) + } + block t_677a { + position: pos(960, 1300, 60, 40) + } + block t_z5ve { + position: pos(1020, 1300, 60, 40) + } + block v_7gn4 { + position: pos(20, 300, 240, 160) + layer: 1 + } + width: 1120 + } + tab ttm_tab: CanvasLayout { + label: '🕰️ Time-to-Market' + height: 1260 + grid_size: 20 + block v_lvp5 { + position: pos(20, 300, 1140, 400) + } + block f_project_name_ynq6 { + position: pos(40, 100, 300, 80) + } + block v_d3sa { + position: pos(20, 720, 540, 400) + } + block v_22mj { + position: pos(580, 720, 580, 400) + layer: 1 + } + block t_uqe1 { + position: pos(20, 200, 740, 60) + } + block t_07hn { + position: pos(20, 240, 1140, 60) + } + block t_87la { + position: pos(40, 20, 740, 80) + layer: 1 + } + block t_vx6z { + position: pos(0, 20, 80, 80) + } + block t_aax1 { + position: pos(20, 1140, 1140, 40) + layer: 1 + } + block t_my4d { + position: pos(20, 1180, 200, 60) + layer: 1 + } + block t_677a { + position: pos(1020, 1200, 60, 40) + layer: 1 + } + block t_z5ve { + position: pos(1080, 1200, 60, 40) + layer: 1 + } + width: 1180 + } + tab quality_tab: CanvasLayout { + label: '🎯 Quality & Bottlenecks' + height: 1980 + grid_size: 20 + block t_87la { + position: pos(40, 20, 740, 80) + layer: 1 + } + block t_vx6z { + position: pos(0, 20, 80, 80) + } + block f_project_name_ynq6 { + position: pos(40, 100, 300, 80) + } + block t_07hn { + position: pos(20, 240, 1140, 60) + } + block t_3f6l { + position: pos(20, 200, 740, 60) + } + block v_baqx { + position: pos(40, 300, 540, 400) + layer: 1 + } + block v_n6j9 { + position: pos(600, 300, 560, 400) + layer: 1 + } + block v_hl2j { + position: pos(40, 720, 540, 400) + } + block v_7fkd { + position: pos(600, 720, 560, 400) + layer: 1 + } + block v_yro9 { + position: pos(440, 300, 340, 160) + layer: 1 + } + block t_q684 { + position: pos(40, 1180, 740, 60) + } + block t_lfpp { + position: pos(40, 1220, 1140, 60) + } + block v_45a6 { + position: pos(40, 1280, 1140, 560) + } + block t_aax1 { + position: pos(40, 1860, 1140, 40) + } + block t_my4d { + position: pos(40, 1900, 200, 60) + } + block t_677a { + position: pos(1040, 1920, 60, 40) + } + block t_z5ve { + position: pos(1100, 1920, 60, 40) + } + } + } + block v_997c: VizBlock { + label: 'Avg Cycle Time (30D)' + viz: MarkdownViz { + dataset: reporting_project_management + calculation metric_e98dbc4 { + label: 'LM - Completed issue' + formula: @aql metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_abbd5a2 { + label: '%LM - Completed issue' + formula: @aql safe_divide(metric_63f4786, metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation color_condition { + label: 'Completed issue - Color Condition' + formula: @aql case( + when: metric_abbd5a2 < 0, + then: "red", + else: "green" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation icon_condition { + label: 'Completed issue - Icon Condition' + formula: @aql case( + when: metric_abbd5a2 < 0, + then: "▾", + else: "▴" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation metric_02fef53 { + label: 'Cycle Time - Color Condition' + formula: @aql case( + when: avg_cycle_time < 0, + then: "green", + else: "red" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation metric_8cf2423 { + label: 'Cycle Time - Icon Condition' + formula: @aql case( + when: avg_cycle_time < 0, + then: "▾", + else: "▴" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation avg_cycle_time { + label: '%LM - Avg Cycle Time' + formula: @aql safe_divide(avg(reporting_issues, reporting_issues.cycle_time_hours), avg(reporting_issues, reporting_issues.cycle_time_hours) | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation avg_cycle_time_color { + label: 'Avg Cycle Time Color' + formula: @aql case( + when: percent_lm_avg_cycle_time > 0, + then: "rgb(248, 113, 113)", + else: "#4ade80" + );; + calc_type: 'measure' + data_type: 'text' + } + calculation avg_cycle_time_icon { + label: 'Avg Cycle Time Icon' + formula: @aql case( + when: percent_lm_avg_cycle_time < 0, + then: "▼", + else: "▲" + );; + calc_type: 'measure' + data_type: 'text' + } + filter { + field: r(reporting_issues.completed_at) + operator: 'matches' + value: '2026-02-01 - 2026-02-28' + } + values: [ + VizFieldFull { + label: 'Avg Cycle Time' + ref: r(reporting_issues.cycle_time_hours) + aggregation: 'avg' + format { + type: 'number' + pattern: '#,###' + } + }, + VizFieldFull { + ref: 'avg_cycle_time' + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + ref: 'avg_cycle_time_icon' + format { + type: 'text' + } + }, + VizFieldFull { + ref: 'avg_cycle_time_color' + format { + type: 'text' + } + } + ] + content: @md + +
+

Avg Cycle Time (30D)

+ + {{ rows[0].values.`Avg Cycle Time` }}h + + +
+ {{ rows[0].values.`Avg Cycle Time Icon` }} + {{ rows[0].values.`%LM - Avg Cycle Time` }} + + vs last month +
+ +
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_gt75: VizBlock { + label: 'WIP issues (Last 14D)' + viz: MarkdownViz { + dataset: reporting_project_management + calculation metric_e98dbc4 { + label: 'LM - Completed issue' + formula: @aql metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_abbd5a2 { + label: '%LM - Completed issue' + formula: @aql safe_divide(metric_63f4786, metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation color_condition { + label: 'Completed issue - Color Condition' + formula: @aql case( + when: metric_abbd5a2 < 0, + then: "red", + else: "green" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation icon_condition { + label: 'Completed issue - Icon Condition' + formula: @aql case( + when: metric_abbd5a2 < 0, + then: "▾", + else: "▴" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation metric_bcc0c1b { + label: '%LW - Avg Cycle Time' + formula: @aql safe_divide(avg(reporting_issues, reporting_issues.dimension_ffede77), avg(reporting_issues, reporting_issues.dimension_ffede77) | relative_period(reporting_issues.completed_at, interval(-1 week), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_02fef53 { + label: 'Cycle Time - Color Condition' + formula: @aql case( + when: metric_bcc0c1b < 0, + then: "green", + else: "red" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation metric_8cf2423 { + label: 'Cycle Time - Icon Condition' + formula: @aql case( + when: metric_bcc0c1b < 0, + then: "▾", + else: "▴" +);; + calc_type: 'measure' + data_type: 'text' + } + filter { + field: r(reporting_issues.completed_at) + operator: 'matches' + value: '2026-02-15 - 2026-02-28' + } + filter { + field: r(reporting_issues.status) + operator: 'is_not' + value: 'deployed' + } + filter { + field: r(reporting_issues.started_at) + operator: 'not_null' + value: [] + } + filter { + field: r(reporting_issues.status) + operator: 'not_null' + value: [] + } + values: [ + VizFieldFull { + label: 'WIP' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: r(reporting_issues.status) + aggregation: 'count distinct' + format { + type: 'number' + pattern: 'inherited' + } + } + ] + content: @md + +
+

WIP (Last 14D)

+ + {{ rows[0].values.`WIP` }} + + +
+ issues across + {{ rows[0].values.`CountD of Status` }} + status +
+ +
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_sffe: VizBlock { + label: 'Avg Cycle Time (30D) copy' + viz: MarkdownViz { + dataset: reporting_project_management + calculation metric_e98dbc4 { + label: 'LM - Completed issue' + formula: @aql metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_abbd5a2 { + label: '%LM - Completed issue' + formula: @aql safe_divide(metric_63f4786, metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation color_condition { + label: 'Completed issue - Color Condition' + formula: @aql case( + when: metric_abbd5a2 < 0, + then: "red", + else: "green" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation icon_condition { + label: 'Completed issue - Icon Condition' + formula: @aql case( + when: metric_abbd5a2 < 0, + then: "▾", + else: "▴" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation metric_02fef53 { + label: 'Cycle Time - Color Condition' + formula: @aql case( + when: avg_cycle_time < 0, + then: "green", + else: "red" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation metric_8cf2423 { + label: 'Cycle Time - Icon Condition' + formula: @aql case( + when: avg_cycle_time < 0, + then: "▾", + else: "▴" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation avg_cycle_time { + label: '%LM - Avg Cycle Time' + formula: @aql safe_divide(avg(reporting_issues, reporting_issues.cycle_time_hours), avg(reporting_issues, reporting_issues.cycle_time_hours) | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation percent_issue_completion { + label: '% Issue Completion' + formula: @aql completed_issue / count_distinct(reporting_issues.id);; + calc_type: 'measure' + data_type: 'number' + } + calculation delta_percent_issue_completion { + label: 'Delta - % Issue Completion' + formula: @aql percent_issue_completion - lm_percent_issue_completion;; + calc_type: 'measure' + data_type: 'number' + } + calculation delta_percent_issue_completion_color { + label: 'Delta - % Issue Completion Color' + formula: @aql case( + when: delta_percent_issue_completion < 0, + then: "rgb(248, 113, 113)", + else: "#5DB88F" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation delta_percent_issue_completion_icon { + label: 'Delta- % Issue Completion Icon' + formula: @aql case( + when: delta_percent_issue_completion < 0, + then: "▼", + else: "▲" + );; + calc_type: 'measure' + data_type: 'text' + } + calculation lm_percent_issue_completion { + label: 'LM - % Issue Completion' + formula: @aql percent_issue_completion | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(reporting_issues.completed_at) + operator: 'matches' + value: '2026-02-14 - 2026-02-28' + } + values: [ + VizFieldFull { + ref: 'percent_issue_completion' + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + ref: 'lm_percent_issue_completion' + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + ref: 'delta_percent_issue_completion' + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + ref: 'delta_percent_issue_completion_color' + format { + type: 'text' + } + }, + VizFieldFull { + ref: 'delta_percent_issue_completion_icon' + format { + type: 'text' + } + } + ] + content: @md + +
+

Completion (14D)

+ + {{ rows[0].values.`% Issue Completion` }} + + +
+ {{ rows[0].values.`Delta- % Issue Completion Icon` }} + {{ rows[0].values.`Delta - % Issue Completion` }} + + vs last month +
+ +
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_jdaq: VizBlock { + label: 'Live Pipeline' + viz: BarChart { + dataset: reporting_project_management + x_axis: VizFieldFull { + ref: r(reporting_issues.status) + format { + type: 'text' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + label: 'Issue' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#206BC4FF' + point { + value: 'merged' + color: '#22D3EEFF' + } + point { + value: 'deployed' + color: '#4F8CFFFF' + } + point { + value: 'pr_review' + color: '#34D399' + } + point { + value: 'in_progress' + color: '#A78BFAFF' + } + point { + value: 'tested_on_staging' + color: '#F472B6' + } + point { + value: 'deployed_to_staging' + color: '#FBBF24FF' + } + point { + value: 'Deployed' + color: '#5DB88FFF' + } + point { + value: 'Deployed to Staging' + color: '#60A5FAFF' + } + point { + value: 'In Progress' + color: '#206BC4FF' + } + point { + value: 'Merged' + color: '#87A6C7FF' + } + point { + value: 'PR Review' + color: '#E9AA2BFF' + } + point { + value: 'Tested on Staging' + color: '#FCD34DFF' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_3qu5: VizBlock { + label: 'Burnup Created vs Completed' + viz: AreaChart { + dataset: reporting_project_management + calculation metric_93579d9 { + label: 'Running total of Count of Reporting Burnup Created' + formula: @aql count(reporting_burnup.created) | running_total();; + calc_type: 'measure' + data_type: 'number' + } + x_axis: VizFieldFull { + ref: r(reporting_burnup.week) + transformation: 'datetrunc week' + format { + type: 'date' + pattern: 'LLL dd, yyyy' + } + } + y_axis { + series { + field: VizFieldFull { + label: 'Created' + ref: r(reporting_burnup.created) + aggregation: 'running sum' + format { + type: 'number' + pattern: 'inherited' + } + } + } + series { + field: VizFieldFull { + label: 'Completed' + ref: r(reporting_burnup.completed) + aggregation: 'running sum' + format { + type: 'number' + pattern: 'inherited' + } + } + } + } + settings { + row_limit: 5000 + legend_label: 'hidden' + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_gq0k: VizBlock { + label: 'Weekly Throughput' + description: 'Created vs completed per week' + viz: ColumnChart { + dataset: reporting_project_management + filter { + field: r(reporting_burnup.week) + operator: 'matches' + value: 'last 3 months' + } + x_axis: VizFieldFull { + ref: r(reporting_burnup.week) + transformation: 'datetrunc week' + format { + type: 'date' + pattern: 'LLL dd, yyyy' + } + } + y_axis { + series { + field: VizFieldFull { + label: 'Issue Created' + ref: r(reporting_burnup.created) + aggregation: 'max' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#A8BEEE' + } + } + series { + field: VizFieldFull { + label: 'Issue Completed' + ref: r(reporting_burnup.completed) + aggregation: 'max' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#059669' + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_lvp5: VizBlock { + label: 'Issue Time-to-Market Breakdown' + description: 'Stacked hours per stage - sorted by total TTM' + viz: BarChart { + dataset: reporting_project_management + filter { + field: r(reporting_issues.status) + operator: 'is' + value: 'Deployed' + } + x_axis: VizFieldFull { + ref: r(reporting_issues.identifier) + format { + type: 'text' + } + } + legend: VizFieldFull { + ref: r(reporting_stage_duration.stage) + format { + type: 'text' + } + } + y_axis { + settings { + show_total_in_tooltip: true + stack_series_by: 'value' + } + series { + field: VizFieldFull { + label: 'Duration' + ref: r(reporting_stage_duration.duration_hours) + aggregation: 'sum' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + point { + value: 'In Progress' + color: '#206BC4FF' + } + point { + value: 'In PR Review' + color: '#E9AA2BFF' + } + point { + value: 'Testing on Staging' + color: '#FCD34DFF' + } + point { + value: 'Deploying to Staging' + color: '#87A6C7FF' + } + point { + value: 'Waiting for Deployment' + color: '#5DB88FFF' + } + } + } + } + settings { + row_limit: 5000 + sort { + field_index: 0 + direction: 'asc' + type: 'yaxis' + } + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block f_project_name_ynq6: FilterBlock { + label: 'Project Name' + type: 'field' + source: FieldFilterSource { + dataset: reporting_project_management + field: r(reporting_project.name) + } + default { + operator: 'is' + value: [ + 'Explore 2', + 'Dashboard Performance', + 'Data Alerts Revamp' + ] + } + } + block v_d3sa: VizBlock { + label: 'Segment Contribution %' + description: 'Where does time-to-market actually go?' + viz: PieChart { + dataset: reporting_project_management + legend: VizFieldFull { + ref: r(reporting_stage_duration.stage) + format { + type: 'text' + } + } + series { + field: VizFieldFull { + label: 'Duration' + ref: r(reporting_stage_duration.duration_hours) + aggregation: 'sum' + format { + type: 'number' + pattern: '#,###' + } + } + settings { + point { + value: 'In Progress' + color: '#528CFCFF' + } + point { + value: 'In PR Review' + color: '#FAC03AFF' + } + point { + value: 'Testing on Staging' + color: '#FCD34DFF' + } + point { + value: 'Deploying to Staging' + color: '#87A6C7FF' + } + point { + value: 'Waiting for Deployment' + color: '#5DB88FFF' + } + } + } + settings { + display_as_donut: true + row_limit: 5000 + sort: 'desc' + legend_label: 'hidden' + show_percentage: true + data_label_position: 'outside' + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_22mj: VizBlock { + label: 'TTM Waterfall' + description: 'Average contribution of each stage' + viz: CustomChart { + dataset: reporting_project_management + theme { + } + custom_chart_id: 33211 + field label: VizFieldFull { + ref: r(reporting_stage_duration.stage) + format { + type: 'text' + } + } + field amount: VizFieldFull { + ref: r(reporting_stage_duration.duration_hours) + aggregation: 'avg' + format { + type: 'number' + pattern: '#,###' + } + } + field label_sorter: VizFieldFull { + ref: r(reporting_stage_duration.stage_priority) + format { + type: 'number' + pattern: 'inherited' + } + } + setting bar_size: 40 + setting end_label: 'Total' + setting value_format: '' + setting total_bar_color: '#999A9F' + settings { + row_limit: 5000 + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block t_87la: TextBlock { + content: @md ## **Squad Reporting - Project Management**;; + theme: BlockTheme { + background { + bg_color: 'transparent' + } + text { + font_color: '#1e40af' + } + border { + border_width: 0 + border_style: 'solid' + border_color: 'transparent' + } + shadow: 'none' + } + } + block t_vx6z: TextBlock { + content: @md
;; + theme: BlockTheme { + border { + border_width: 0 + border_style: 'none' + border_color: 'transparent' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_iu5s: TextBlock { + content: @md ### **◎ Metric Overview**;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_style: 'none' + border_color: 'transparent' + } + shadow: 'none' + background { + bg_color: 'transparent' + } + } + } + block t_l2v4: TextBlock { + content: @md
;; + theme { + text { + font_color: '#ffffff' + } + border { + border_width: 0 + border_style: 'none' + border_color: 'transparent' + } + shadow: 'none' + background { + bg_color: 'transparent' + } + } + } + block v_y7bo: VizBlock { + label: 'Explore 2.0 - Progress' + description: 'Total issues launched last 30 days' + viz: MarkdownViz { + dataset: reporting_project_management + calculation metric_e98dbc4 { + label: 'LM - Completed issue' + formula: @aql metric_63f4786 | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + calculation lm__completed_issue { + label: '%LM - Completed Issue' + formula: @aql safe_divide(completed_issue, completed_issue | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation completed_issue_color { + label: 'Completed Issue Color' + formula: @aql case( + when: percent_lm_completed_issue < 0, + then: "rgb(248, 113, 113)", + else: "#4ade80" + );; + calc_type: 'measure' + data_type: 'text' + } + calculation completed_issue_icon { + label: 'Completed Issue Icon' + formula: @aql case( + when: percent_lm_completed_issue < 0, + then: "▼", + else: "▲" + );; + calc_type: 'measure' + data_type: 'text' + } + calculation percent_issue_completed { + label: 'Percent Issue Completed' + formula: @aql completed_issue / count(reporting_issues.id);; + calc_type: 'measure' + data_type: 'number' + } + calculation remaining_issue { + label: 'Remaining Issue' + formula: @aql count(reporting_issues.id) - completed_issue;; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(reporting_project.name) + operator: 'is' + value: 'Explore 2' + } + values: [ + VizFieldFull { + ref: r(reporting_project_management.percent_completion) + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + label: 'Total' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + label: 'Done' + ref: r(reporting_project_management.completed_issue) + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + label: 'Remaining' + ref: 'remaining_issue' + format { + type: 'number' + pattern: 'inherited' + } + } + ] + content: @md + +
+

Explore 2.0

+ +
+
+ + + + + + +
{{rows[0].values.`Percent Issue Completed`}}
+
+ +
+
+ Total + {{ rows[0].values.`Total` }} +
+
+ Done + {{ rows[0].values.`Done` }} +
+
+ Remaining + {{ rows[0].values.`Remaining` }} +
+
+
+
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_x2gw: VizBlock { + label: 'Status Distribution by Project' + description: "Where each project's issues are sitting" + viz: ColumnChart { + dataset: reporting_project_management + x_axis: VizFieldFull { + ref: r(reporting_project.name) + format { + type: 'text' + } + } + legend: VizFieldFull { + ref: r(reporting_issues.status) + format { + type: 'text' + } + } + y_axis { + settings { + stack_series_by: 'value' + } + series { + field: VizFieldFull { + label: 'Issue' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + point { + value: 'Deployed' + color: '#5DB88FFF' + } + point { + value: 'Deployed to Staging' + color: '#60A5FAFF' + } + point { + value: 'In Progress' + color: '#206BC4FF' + } + point { + value: 'Merged' + color: '#87A6C7FF' + } + point { + value: 'PR Review' + color: '#E9AA2BFF' + } + point { + value: 'Tested on Staging' + color: '#FCD34DFF' + } + } + } + } + settings { + row_limit: 5000 + sort { + field_index: 0 + direction: 'asc' + type: 'yaxis' + } + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block t_uqe1: TextBlock { + content: @md ### **🕰️ Time-to-Market**;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_07hn: TextBlock { + content: @md
;; + theme { + text { + font_color: '#ffffff' + } + border { + border_width: 0 + border_style: 'none' + border_color: 'transparent' + } + shadow: 'none' + background { + bg_color: 'transparent' + } + } + } + block t_bf42: TextBlock { + content: @md ### **📊 Projects Overview**;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_a8eh: TextBlock { + content: @md
;; + theme { + text { + font_color: '#ffffff' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_aax1: TextBlock { + content: @md
;; + theme { + text { + font_color: '#ffffff' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + padding: 0 + } + } + block t_my4d: TextBlock { + content: @md +
+ Powered by + + Holistics + Holistics + +
+ ;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + padding: 0 + } + } + block t_677a: TextBlock { + content: @md Docs;; + theme { + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + padding: 0 + } + } + block t_z5ve: TextBlock { + content: @md Sandbox;; + theme { + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + padding: 0 + } + } + block t_m4lt: TextBlock { + content: @md ### **🎯 Quality**;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_k7fo: TextBlock { + content: @md
;; + theme { + text { + font_color: '#ffffff' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_3f6l: TextBlock { + content: @md ### **🎯 Quality**;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block v_baqx: VizBlock { + label: 'Bug Ratio (Week by Week)' + description: 'What % of shipped work is bugs?' + viz: CombinationChart { + dataset: reporting_project_management + x_axis: VizFieldFull { + ref: r(reporting_issues.completed_at) + transformation: 'datetrunc week' + format { + type: 'date' + pattern: 'wwww' + } + } + y_axis { + series { + mark_type: 'column' + field: VizFieldFull { + ref: r(reporting_project_management.number_of_bug) + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#982021FF' + } + } + } + y_axis { + settings { + alignment: 'right' + } + series { + mark_type: 'line' + field: VizFieldFull { + ref: r(reporting_project_management.bug_ratio) + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#E9AA2BFF' + line_interpolation: 'smooth' + } + } + } + settings { + show_data_points: true + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_n6j9: VizBlock { + label: 'Work Type Distribution' + description: 'What type of work ships?' + viz: AreaChart { + dataset: reporting_project_management + x_axis: VizFieldFull { + ref: r(reporting_issues.completed_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + legend: VizFieldFull { + ref: r(reporting_issues.label) + format { + type: 'text' + } + } + y_axis { + settings { + stack_series_by: 'value' + } + series { + field: VizFieldFull { + label: 'Issues' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + point { + value: 'Bug' + line_interpolation: 'smooth' + } + point { + value: 'Chore' + line_interpolation: 'smooth' + } + point { + value: 'Feature' + line_interpolation: 'smooth' + } + point { + value: 'Improvement' + line_interpolation: 'smooth' + } + point { + value: 'Tech Debt' + line_interpolation: 'smooth' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_hl2j: VizBlock { + label: 'Priority vs Actual Cycle Time' + description: 'Do urgent issues actually ship faster?' + viz: ScatterChart { + dataset: reporting_project_management + x_col: VizFieldFull { + ref: r(reporting_issues.priority) + format { + type: 'text' + } + } + y_col: VizFieldFull { + ref: r(reporting_issues.cycle_time_hours) + format { + type: 'number' + pattern: 'inherited' + } + } + group_col: VizFieldFull { + ref: r(reporting_issues.priority) + format { + type: 'text' + } + } + settings { + row_limit: 5000 + } + } + } + block v_7fkd: VizBlock { + label: 'Cycle Time by Label' + description: 'Average hours to ship by work type' + viz: BarChart { + dataset: reporting_project_management + x_axis: VizFieldFull { + ref: r(reporting_issues.label) + format { + type: 'text' + } + } + y_axis { + series { + field: VizFieldFull { + ref: r(reporting_issues.cycle_time_hours) + aggregation: 'avg' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + color: '#60A5FAFF' + } + } + } + settings { + row_limit: 5000 + legend_label: 'hidden' + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block t_q684: TextBlock { + content: @md ### **⚡ Bottlenecks**;; + theme { + text { + font_color: '#475569' + } + border { + border_width: 0 + border_color: 'transparent' + border_style: 'none' + } + background { + bg_color: 'transparent' + } + shadow: 'none' + } + } + block t_lfpp: TextBlock { + content: @md
;; + theme { + text { + font_color: '#ffffff' + } + border { + border_width: 0 + border_style: 'none' + border_color: 'transparent' + } + shadow: 'none' + background { + bg_color: 'transparent' + } + } + } + block v_45a6: VizBlock { + label: 'Identifier, Title and 9 more' + viz: MarkdownViz { + dataset: reporting_project_management + calculation stage_color { + label: 'Stage Color' + formula: @aql case( + when: reporting_stage_duration.stage == "In Progress", + then: "#206BC4", + when: reporting_stage_duration.stage == "In PR Review", + then: "#E9AA2B", + when: reporting_stage_duration.stage == "Deploying to Staging", + then: "#60A5FA", + when: reporting_stage_duration.stage == "Testing on Staging", + then: "#FCD34D", + when: reporting_stage_duration.stage == "Waiting for Deployment", + then: "#87A6C7", + else: "others" +);; + calc_type: 'dimension' + data_type: 'text' + model: reporting_stage_duration + } + calculation priority_color { + label: 'Priority Color' + formula: @aql case( + when: reporting_issues.priority == "high", + then: "#E27712", + when: reporting_issues.priority == "urgent", + then: "#982021", + when: reporting_issues.priority == "medium", + then: "#60A5FA", + when: reporting_issues.priority == "low", + then: "#87A6C7", + when: reporting_issues.priority == "none", + then: "#D5DCE4", + else: "others" +);; + calc_type: 'dimension' + data_type: 'text' + model: reporting_stage_duration + } + calculation duration_color { + label: 'Duration Color' + formula: @aql case( + when: reporting_stage_duration.duration_hours >= 60, + then: "#ef4444", + else: "#eab308" + );; + calc_type: 'dimension' + data_type: 'text' + model: reporting_stage_duration + } + calculation duration_bar_width { + label: 'Duration Bar Width' + formula: @aql case( + when: reporting_stage_duration.duration_hours >= 120, + then: 120, + when: reporting_stage_duration.duration_hours >= 100, + then: 100, + when: reporting_stage_duration.duration_hours >= 80, + then: 80, + when: reporting_stage_duration.duration_hours >= 60, + then: 60, + when: reporting_stage_duration.duration_hours >= 40, + then: 40, + when: reporting_stage_duration.duration_hours >= 20, + then: 20, + else: 12 + );; + calc_type: 'dimension' + data_type: 'number' + model: reporting_stage_duration + } + calculation priority_ranking { + label: 'Priority Ranking' + formula: @aql case( + when: reporting_issues.priority == "urgent", + then: 1, + when: reporting_issues.priority == "high", + then: 2, + when: reporting_issues.priority == "medium", + then: 3, + when: reporting_issues.priority == "low", + then: 4, + when: reporting_issues.priority == "none", + then: 5, + else: 99 + );; + calc_type: 'dimension' + data_type: 'number' + model: reporting_issues + } + rows: [ + VizFieldFull { + ref: r(reporting_issues.identifier) + format { + type: 'text' + } + }, + VizFieldFull { + ref: r(reporting_issues.title) + format { + type: 'text' + } + }, + VizFieldFull { + label: 'Assignee' + ref: r(reporting_team.name) + format { + type: 'text' + } + }, + VizFieldFull { + ref: r(reporting_stage_duration.duration_hours) + format { + type: 'number' + pattern: 'inherited' + } + uname: 'reporting_stage_duration_duration_hours' + }, + VizFieldFull { + ref: ref('reporting_stage_duration', 'duration_color') + format { + type: 'text' + } + }, + VizFieldFull { + ref: ref('reporting_stage_duration', 'duration_bar_width') + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: ref('reporting_issues', 'priority_ranking') + format { + type: 'number' + pattern: 'inherited' + } + uname: 'reporting_issues_priority_ranking' + }, + VizFieldFull { + ref: r(reporting_stage_duration.stage) + format { + type: 'text' + } + }, + VizFieldFull { + ref: ref('reporting_stage_duration', 'stage_color') + format { + type: 'text' + } + }, + VizFieldFull { + ref: r(reporting_issues.priority) + format { + type: 'text' + } + }, + VizFieldFull { + ref: ref('reporting_stage_duration', 'priority_color') + format { + type: 'text' + } + } + ] + content: @md + +
+
+

Stale Issues

+

Sorted by time in current stage

+
+ +
+
+
Issue
+
Title
+
Stage
+
Duration Hour
+
Assignee ID
+
Priority
+
+ + {% map(rows) %} +
+
+ {{ `Identifier` }} +
+
+ {{ `Title` }} +
+
+ + {{ `Stage` }} + +
+
+
+
+ {{ `Duration Hours` }}h +
+
+ {{ `Assignee` }} +
+
+ + {{ `Priority` }} +
+
+ {% end %} + +
+
;; + settings { + show_row_total: true + show_column_total: true + sorts: [ + SortSetting { + key: 'reporting_issues_priority_ranking' + direction: 'asc' + }, + SortSetting { + key: 'reporting_stage_duration_duration_hours' + direction: 'desc' + } + ] + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_ipdo: VizBlock { + label: 'Data Alert Revamp' + viz: MarkdownViz { + dataset: reporting_project_management + calculation remaining { + label: 'Remaining' + formula: @aql count(reporting_issues.id) - completed_issue;; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(reporting_project.name) + operator: 'is' + value: 'Data Alerts Revamp' + } + values: [ + VizFieldFull { + ref: r(reporting_project_management.percent_completion) + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + label: 'Total' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + label: 'Done' + ref: r(reporting_project_management.completed_issue) + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: 'remaining' + format { + type: 'number' + pattern: 'inherited' + } + } + ] + content: @md + +
+

Data Alert Revamp

+ +
+
+ + + + + + +
{{rows[0].values.`Percent Issue Completed`}}
+
+ +
+
+ Total + {{ rows[0].values.`Total` }} +
+
+ Done + {{ rows[0].values.`Done` }} +
+
+ Remaining + {{ rows[0].values.`Remaining` }} +
+
+
+
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_7dso: VizBlock { + label: 'Dashboard Performance' + viz: MarkdownViz { + dataset: reporting_project_management + calculation remaining { + label: 'Remaining' + formula: @aql count(reporting_issues.id) - completed_issue;; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(reporting_project.name) + operator: 'is' + value: 'Dashboard Performance' + } + values: [ + VizFieldFull { + ref: r(reporting_project_management.percent_completion) + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + label: 'Total' + ref: r(reporting_issues.id) + aggregation: 'count' + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + label: 'Done' + ref: r(reporting_project_management.completed_issue) + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: 'remaining' + format { + type: 'number' + pattern: 'inherited' + } + } + ] + content: @md + +
+

Dashboard Performance

+ +
+
+ + + + + + +
{{rows[0].values.`Percent Issue Completed`}}
+
+ +
+
+ Total + {{ rows[0].values.`Total` }} +
+
+ Done + {{ rows[0].values.`Done` }} +
+
+ Remaining + {{ rows[0].values.`Remaining` }} +
+
+
+
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + settings { + hide_label: true + } + } + block v_r2ma: VizBlock { + label: 'Project Velocity Comparison' + description: 'Issues completed per month per project' + viz: LineChart { + dataset: reporting_project_management + calculation completion_rate { + label: 'Completion Rate' + formula: @aql completed_issue / count(reporting_issues.id);; + calc_type: 'measure' + data_type: 'number' + } + x_axis: VizFieldFull { + ref: r(reporting_issues.completed_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + legend: VizFieldFull { + ref: r(reporting_project.name) + format { + type: 'text' + } + } + y_axis { + series { + field: VizFieldFull { + ref: 'completion_rate' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + point { + value: 'Dashboard Performance' + color: '#5DB88FFF' + line_interpolation: 'smooth' + } + point { + value: 'Data Alerts Revamp' + color: '#E27712' + line_interpolation: 'smooth' + } + point { + value: 'Explore 2' + color: '#206BC4FF' + line_interpolation: 'smooth' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_7gn4: VizBlock { + settings { + hide_label: true + } + label: 'Completed issue (Last 30D), %LM - Completed issue and 2 more' + viz: MarkdownViz { + dataset: reporting_project_management + calculation lm_completed_issue { + label: '%LM - Completed issue' + formula: @aql safe_divide(completed_issue, completed_issue | relative_period(reporting_issues.completed_at, interval(-1 month), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation completed_issue_color { + label: 'Completed Issue Color' + formula: @aql case( + when: lm_completed_issue < 0, + then: "rgb(248, 113, 113)", + else: "#5DB88F" +);; + calc_type: 'measure' + data_type: 'text' + } + calculation completed_issue_icon { + label: 'Completed Issue Icon' + formula: @aql +case( + when: lm_completed_issue < 0, + then: "▼", + else: "▲" + );; + calc_type: 'measure' + data_type: 'text' + } + filter { + field: r(reporting_issues.completed_at) + operator: 'matches' + value: '2026-02-01 - 2026-02-28' + } + values: [ + VizFieldFull { + label: 'Completed issue (Last 30D)' + ref: r(reporting_project_management.completed_issue) + format { + type: 'number' + pattern: 'inherited' + } + }, + VizFieldFull { + ref: 'lm_completed_issue' + format { + type: 'number' + pattern: '#,###%' + } + }, + VizFieldFull { + ref: 'completed_issue_color' + format { + type: 'text' + } + }, + VizFieldFull { + ref: 'completed_issue_icon' + format { + type: 'text' + } + } + ] + content: @md + +
+

Shipped (30D)

+ + {{ rows[0].values.`Completed issue (Last 30D)` }} + + +
+ {{ rows[0].values.`Completed Issue Icon` }} + {{ rows[0].values.`%LM - Completed issue` }} + + vs last month +
+ +
;; + settings { + show_row_total: true + show_column_total: true + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + theme: ai_1773979634521_3 + interactions: [ + FilterInteraction { + from: 'v_997c' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_gt75' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_sffe' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_jdaq' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_3qu5' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_gq0k' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_lvp5' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_d3sa' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_22mj' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_y7bo' + to: [ + CustomMapping { + block: 'v_7gn4' + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_x2gw' + to: [ + CustomMapping { + block: 'v_7gn4' + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_baqx' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_n6j9' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_hl2j' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_7fkd' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_45a6' + to: [ + CustomMapping { + block: [ + 'v_ipdo', + 'v_7dso', + 'v_r2ma', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_ipdo' + to: [ + CustomMapping { + block: [ + 'v_997c', + 'v_gt75', + 'v_sffe', + 'v_jdaq', + 'v_3qu5', + 'v_gq0k', + 'v_lvp5', + 'v_d3sa', + 'v_22mj', + 'v_baqx', + 'v_n6j9', + 'v_hl2j', + 'v_7fkd', + 'v_45a6', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_7dso' + to: [ + CustomMapping { + block: [ + 'v_997c', + 'v_gt75', + 'v_sffe', + 'v_jdaq', + 'v_3qu5', + 'v_gq0k', + 'v_lvp5', + 'v_d3sa', + 'v_22mj', + 'v_baqx', + 'v_n6j9', + 'v_hl2j', + 'v_7fkd', + 'v_45a6', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_r2ma' + to: [ + CustomMapping { + block: [ + 'v_997c', + 'v_gt75', + 'v_sffe', + 'v_jdaq', + 'v_3qu5', + 'v_gq0k', + 'v_lvp5', + 'v_d3sa', + 'v_22mj', + 'v_baqx', + 'v_n6j9', + 'v_hl2j', + 'v_7fkd', + 'v_45a6', + 'v_7gn4' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_7gn4' + to: [ + CustomMapping { + block: [ + 'v_lvp5', + 'v_d3sa', + 'v_22mj', + 'v_y7bo', + 'v_x2gw', + 'v_baqx', + 'v_n6j9', + 'v_hl2j', + 'v_7fkd', + 'v_45a6', + 'v_ipdo', + 'v_7dso', + 'v_r2ma' + ] + disabled: true + } + ] + } + ] +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_stage_duration.model.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_stage_duration.model.aml new file mode 100644 index 0000000..e1b4023 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_stage_duration.model.aml @@ -0,0 +1,118 @@ +Model reporting_stage_duration { + type: 'query' + label: 'Reporting Stage Duration' + description: '' + data_source_name: 'demodb' + dimension id { + label: 'Id' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.id }};; + } + dimension issue_id { + label: 'Issue Id' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.issue_id }};; + } + dimension stage { + label: 'Stage' + type: 'text' + hidden: false + definition: @sql {{#SOURCE.stage}};; + } + dimension entered_at { + label: 'Entered At' + type: 'date' + hidden: false + definition: @sql {{ #SOURCE.entered_at }};; + } + dimension exited_at { + label: 'Exited At' + type: 'datetime' + hidden: false + definition: @sql {{ #SOURCE.exited_at }};; + } + dimension duration_hours { + label: "Duration Hours" + type: "number" + hidden: false + definition: @sql {{ #SOURCE.duration_hours }};; + } + dimension stage_priority { + label: "Stage Priority" + type: "number" + description: "" + hidden: false + definition: @aql case( + when: reporting_stage_duration.stage == "In Progress", + then: 1, + when: reporting_stage_duration.stage == "In PR Review", + then: 2, + when: reporting_stage_duration.stage == "Deploying to Staging", + then: 3, + when: reporting_stage_duration.stage == "Testing on Staging", + then: 4, + when: reporting_stage_duration.stage == "Waiting for Deployment", + then: 5, + else: 6 +);; + } + + owner: 'vy.ht@holistics.io' + query: @sql WITH status_transitions AS ( + SELECT + issue_id, + to_status, + transitioned_at, + LAG(transitioned_at) OVER ( + PARTITION BY issue_id + ORDER BY transitioned_at + ) AS previous_transitioned_at + FROM {{ #reporting_issues_log }} + WHERE to_status IS NOT NULL + ), + + stages_with_mapping AS ( + SELECT + st.issue_id, + CASE + WHEN st.to_status = 'in_progress' THEN 'In Progress' + WHEN st.to_status = 'pr_review' THEN 'In PR Review' + WHEN st.to_status = 'merged' THEN 'Deploying to Staging' + WHEN st.to_status = 'deployed_to_staging' THEN 'Testing on Staging' + WHEN st.to_status = 'tested_on_staging' THEN 'Waiting for Deployment' + END AS stage, + st.transitioned_at AS entered_at, + LEAD(st.transitioned_at) OVER ( + PARTITION BY st.issue_id + ORDER BY st.transitioned_at + ) AS exited_at + FROM status_transitions st + WHERE st.to_status IN ('in_progress', 'pr_review', 'merged', 'deployed_to_staging', 'tested_on_staging', 'deployed') + ) + + SELECT + ROW_NUMBER() OVER (ORDER BY issue_id, entered_at) AS id, + issue_id, + stage, + TO_CHAR(entered_at::timestamp, 'YYYY-MM-DD HH24:MI:SS') AS entered_at, + TO_CHAR(exited_at::timestamp, 'YYYY-MM-DD HH24:MI:SS') AS exited_at, + (EXTRACT(EPOCH FROM (exited_at::timestamp - entered_at::timestamp)) / 3600.0) AS duration_hours + FROM stages_with_mapping + WHERE exited_at IS NOT NULL + AND entered_at < exited_at + AND stage IS NOT NULL + ORDER BY + issue_id, + CASE stage + WHEN 'In Progress' THEN 1 + WHEN 'In PR Review' THEN 2 + WHEN 'Deploying to Staging' THEN 3 + WHEN 'Testing on Staging' THEN 4 + WHEN 'Waiting for Deployment' THEN 5 + END;; + models: [ + reporting_issues_log + ] +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_team.model.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_team.model.aml new file mode 100644 index 0000000..86168f2 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/reporting_team.model.aml @@ -0,0 +1,49 @@ +Model reporting_team { + type: 'table' + label: 'Reporting team' + description: '' + data_source_name: 'demodb' + dimension id { + label: 'Id' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.id }};; + } + dimension name { + label: 'Name' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.name }};; + } + dimension email { + label: 'Email' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.email }};; + } + dimension role { + label: 'Role' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.role }};; + } + + import_source: ImportSource { + type: 'csv' + original_file_name: 'users_1.csv' + uploaded_at: '2026-03-05 03:49:56' + hash: 'ae0f79138cfbf4a6178f8310e20c25f51f5bdc0293531ee3e8b6a18cbfe0d310' + column_configs: [ + H.imports.column_config("id", "id", "number"), + H.imports.column_config("name", "name", "text"), + H.imports.column_config("email", "email", "text"), + H.imports.column_config("role", "role", "text") + ] + } + owner: 'vy.ht@holistics.io' + table_name: '"dbt_khai"."holistics_reporting_tea_d6f20_202603050349"' +} diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/them-squad-dark.theme.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/them-squad-dark.theme.aml new file mode 100644 index 0000000..90c7a11 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/them-squad-dark.theme.aml @@ -0,0 +1,132 @@ +// ============================================================ +// FILE: themes/squad_command.aml +// Squad Command Center — matching the reference design +// Floating blocks on deep navy +// Page #0b0d13 → Canvas #0b0d13 → Block #151a26 +// ============================================================ + +const sc_page = '#182030' +const sc_canvas = '#0b0d13' +const sc_surface = '#151a26' +const sc_border = '#1e2535' +const sc_hover = '#1a2030' +const sc_banding = '#181d28' +const sc_text = '#e8ecf2' +const sc_muted = '#6b7590' +const sc_dim = '#3a4460' +const sc_accent = '#3b82f6' +const sc_green = '#34d399' +const sc_red = '#ef4444' +const sc_amber = '#fbbf24' +const sc_purple = '#a78bfa' +const sc_cyan = '#22d3ee' +const sc_pink = '#f472b6' +const sc_font = 'Inter' + +PageTheme squad_dark { + background { + bg_color: sc_page + } + + canvas { + background { + bg_color: sc_canvas + } + border { + border_width: 0 + border_radius: 0 + border_color: sc_border + border_style: 'none' + } + shadow: 'none' + opacity: 1 + } + + block { + label { + font_family: sc_font + font_size: 14 + font_color: sc_text + font_weight: 'semibold' + font_style: 'normal' + } + text { + font_family: sc_font + font_size: 12 + font_color: sc_muted + font_weight: 'normal' + font_style: 'normal' + } + border { + border_width: 1 + border_radius: 14 + border_color: sc_border + border_style: 'solid' + } + background { + bg_color: sc_surface + } + padding: 16 + shadow: 'none' + opacity: 1 + } + + viz { + table { + general { + bg_color: sc_surface + hover_color: sc_hover + banding_color: sc_banding + font_size: 12 + font_color: sc_muted + font_family: sc_font + border_color: sc_border + border_width: 1 + grid_color: '#1a2030' + } + header { + bg_color: sc_hover + font_size: 12 + font_color: sc_text + font_weight: 'semibold' + } + sub_header { + bg_color: sc_hover + font_size: 11 + font_color: sc_muted + font_weight: 'medium' + } + sub_title { + font_size: 11 + font_color: sc_muted + font_weight: 'medium' + } + } + } + + custom_css: @css + /* ---- Squad Command Center ---- */ + + /* Tab bar */ + .tab-bar { background: #0b0d13 !important; border-bottom: 1px solid #1e2535 !important; } + .tab-bar .tab-item { color: #6b7590 !important; font-family: 'Inter', sans-serif !important; font-size: 13px !important; } + .tab-bar .tab-item.active { color: #3b82f6 !important; border-bottom: 2px solid #3b82f6 !important; } + + /* Metric sheet — large monospace numbers */ + .metric-sheet .metric-value { font-family: 'JetBrains Mono', monospace !important; font-size: 28px !important; font-weight: 700 !important; color: #e8ecf2 !important; } + .metric-sheet .metric-label { font-family: 'Inter', sans-serif !important; font-size: 11px !important; color: #6b7590 !important; text-transform: uppercase !important; letter-spacing: 0.06em !important; } + + /* Chart axis and legend */ + .recharts-cartesian-axis-tick-value { fill: #6b7590 !important; font-size: 10px !important; font-family: 'Inter', sans-serif !important; } + .recharts-legend-item-text { color: #6b7590 !important; font-size: 11px !important; } + .recharts-cartesian-grid line { stroke: #1e2535 !important; } + + /* Tooltip */ + .recharts-tooltip-wrapper .recharts-default-tooltip { background: #151a26 !important; border: 1px solid #1e2535 !important; border-radius: 10px !important; box-shadow: 0 8px 24px rgba(0,0,0,0.5) !important; } + + /* Scrollbar */ + ::-webkit-scrollbar { width: 5px; height: 5px; } + ::-webkit-scrollbar-track { background: #0b0d13; } + ::-webkit-scrollbar-thumb { background: #1e2535; border-radius: 3px; } + ;; +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/theme-obsidian-navy.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/theme-obsidian-navy.aml new file mode 100644 index 0000000..90766f6 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/theme-obsidian-navy.aml @@ -0,0 +1,123 @@ +// ============================================================ +// FILE: themes/obsidian_navy.aml +// Obsidian Navy — Linear-inspired, electric blue accent +// Block #060c16 → Canvas #0f1724 → Page #1a2332 +// ============================================================ + +const ob_page = '#1a2332' +const ob_canvas = '#0f1724' +const ob_surface = '#060c16' +const ob_border = '#1f2d42' +const ob_hover = '#0a1220' +const ob_banding = '#080e1a' +const ob_text = '#f0f2f5' +const ob_muted = '#7589a6' +const ob_dim = '#3e506a' +const ob_accent = '#3b82f6' +const ob_green = '#10b981' +const ob_red = '#ef4444' +const ob_amber = '#f59e0b' +const ob_font = 'Inter' + +PageTheme obsidian_navy { + background { + bg_color: ob_page + } + + canvas { + background { + bg_color: ob_canvas + } + border { + border_width: 0 + border_radius: 0 + border_color: ob_border + border_style: 'none' + } + shadow: 'none' + opacity: 1 + } + + block { + label { + font_family: ob_font + font_size: 14 + font_color: ob_text + font_weight: 'semibold' + font_style: 'normal' + } + text { + font_family: ob_font + font_size: 12 + font_color: ob_muted + font_weight: 'normal' + font_style: 'normal' + } + border { + border_width: 1 + border_radius: 12 + border_color: ob_border + border_style: 'solid' + } + background { + bg_color: ob_surface + } + padding: 16 + shadow: 'none' + opacity: 1 + } + + viz { + table { + general { + bg_color: ob_surface + hover_color: ob_hover + banding_color: ob_banding + font_size: 12 + font_color: ob_muted + font_family: ob_font + border_color: ob_border + border_width: 1 + grid_color: '#172030' + } + header { + bg_color: ob_hover + font_size: 12 + font_color: ob_text + font_weight: 'semibold' + } + sub_header { + bg_color: ob_hover + font_size: 11 + font_color: ob_muted + font_weight: 'medium' + } + sub_title { + font_size: 11 + font_color: ob_muted + font_weight: 'medium' + } + } + } + + custom_css: @css + /* ---- Obsidian Navy ---- */ + + .tab-bar { background: #0f1724 !important; border-bottom: 1px solid #1f2d42 !important; } + .tab-bar .tab-item { color: #7589a6 !important; font-family: 'Inter', sans-serif !important; font-size: 13px !important; } + .tab-bar .tab-item.active { color: #3b82f6 !important; border-bottom: 2px solid #3b82f6 !important; } + + .metric-sheet .metric-value { font-family: 'JetBrains Mono', monospace !important; font-size: 28px !important; font-weight: 700 !important; color: #f0f2f5 !important; } + .metric-sheet .metric-label { font-family: 'Inter', sans-serif !important; font-size: 11px !important; color: #7589a6 !important; text-transform: uppercase !important; letter-spacing: 0.05em !important; } + + .recharts-cartesian-axis-tick-value { fill: #7589a6 !important; font-size: 10px !important; } + .recharts-legend-item-text { color: #7589a6 !important; font-size: 11px !important; } + .recharts-cartesian-grid line { stroke: #1f2d42 !important; } + + .recharts-tooltip-wrapper .recharts-default-tooltip { background: #060c16 !important; border: 1px solid #1f2d42 !important; border-radius: 8px !important; box-shadow: 0 8px 24px rgba(0,0,0,0.5) !important; } + + ::-webkit-scrollbar { width: 5px; height: 5px; } + ::-webkit-scrollbar-track { background: #0f1724; } + ::-webkit-scrollbar-thumb { background: #1f2d42; border-radius: 3px; } + ;; +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Squad Reporting - Project Management/theme-squad-light.aml b/team-folders/VyHuynh/Squad Reporting - Project Management/theme-squad-light.aml new file mode 100644 index 0000000..0621d58 --- /dev/null +++ b/team-folders/VyHuynh/Squad Reporting - Project Management/theme-squad-light.aml @@ -0,0 +1,124 @@ +// ============================================================ +// FILE: themes/squad_light.aml +// Clean, professional light theme for the squad dashboard +// ============================================================ + +const squad_bg = '#f7f8fa' +const squad_surface = '#ffffff' +const squad_border = '#e2e5ec' +const squad_text = '#1a1f36' +const squad_muted = '#6b7280' +const squad_accent = '#3b6de0' +const squad_green = '#059669' +const squad_red = '#dc2626' +const squad_amber = '#d97706' +const squad_font = 'Inter' +const squad_mono = 'JetBrains Mono' + +PageTheme squad_light { + background { + bg_color: squad_bg + } + + canvas { + background { + bg_color: squad_bg + } + border { + border_width: 0 + border_radius: 0 + border_color: squad_border + border_style: 'none' + } + shadow: 'none' + opacity: 1 + } + + block { + label { + font_family: squad_font + font_size: 14 + font_color: squad_text + font_weight: 'semibold' + font_style: 'normal' + } + text { + font_family: squad_font + font_size: 12 + font_color: squad_muted + font_weight: 'normal' + font_style: 'normal' + } + border { + border_width: 1 + border_radius: 12 + border_color: squad_border + border_style: 'solid' + } + background { + bg_color: squad_surface + } + padding: 16 + shadow: 'sm' + opacity: 1 + } + + viz { + table { + general { + bg_color: squad_surface + hover_color: '#f0f4ff' + banding_color: '#f9fafb' + font_size: 12 + font_color: '#374151' + font_family: squad_font + border_color: squad_border + border_width: 1 + grid_color: '#e5e7eb' + } + header { + bg_color: '#f3f4f6' + font_size: 12 + font_color: squad_text + font_weight: 'semibold' + } + sub_header { + bg_color: '#f9fafb' + font_size: 11 + font_color: squad_muted + font_weight: 'medium' + } + sub_title { + font_size: 11 + font_color: squad_muted + font_weight: 'medium' + } + } + } + + custom_css: @css + /* ---- Squad Command Center (Light) ---- */ + + /* Tab bar styling */ + .tab-bar { background: #ffffff !important; border-bottom: 1px solid #e2e5ec !important; } + .tab-bar .tab-item { color: #6b7280 !important; font-family: 'Inter', sans-serif !important; font-size: 13px !important; } + .tab-bar .tab-item.active { color: #3b6de0 !important; border-bottom: 2px solid #3b6de0 !important; } + + /* Metric sheet overrides */ + .metric-sheet .metric-value { font-family: 'JetBrains Mono', monospace !important; font-size: 28px !important; font-weight: 700 !important; color: #1a1f36 !important; } + .metric-sheet .metric-label { font-family: 'Inter', sans-serif !important; font-size: 11px !important; color: #6b7280 !important; text-transform: uppercase !important; letter-spacing: 0.05em !important; } + + /* Chart axis and legend */ + .recharts-cartesian-axis-tick-value { fill: #6b7280 !important; font-size: 10px !important; } + .recharts-legend-item-text { color: #6b7280 !important; font-size: 11px !important; } + .recharts-cartesian-grid line { stroke: #e5e7eb !important; } + + /* Tooltip */ + .recharts-tooltip-wrapper .recharts-default-tooltip { background: #ffffff !important; border: 1px solid #e2e5ec !important; border-radius: 8px !important; box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important; } + + /* Scrollbar */ + ::-webkit-scrollbar { width: 5px; height: 5px; } + ::-webkit-scrollbar-track { background: #f7f8fa; } + ::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 3px; } + ;; +} \ No newline at end of file diff --git a/team-folders/VyHuynh/Vy's Dashboard/VyHuynh_Abernathy.page.aml b/team-folders/VyHuynh/Vy's Dashboard/VyHuynh_Abernathy.page.aml index 34ee4f4..19d6fd0 100644 --- a/team-folders/VyHuynh/Vy's Dashboard/VyHuynh_Abernathy.page.aml +++ b/team-folders/VyHuynh/Vy's Dashboard/VyHuynh_Abernathy.page.aml @@ -75,7 +75,7 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a layer: 1 } block v_nehb { - position: pos(20, 2320, 1160, 460) + position: pos(20, 2320, 540, 460) layer: 1 } block v_cii9 { @@ -141,10 +141,10 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } tab tab3: CanvasLayout { label: 'Regional Analysis' - height: 5820 + height: 9440 grid_size: 20 block v5 { - position: pos(580, 80, 600, 500) + position: pos(20, 360, 540, 420) layer: 1 } block t1 { @@ -156,60 +156,100 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a layer: 3 } block v_qctn { - position: pos(20, 2040, 1160, 580) + position: pos(20, 5660, 560, 560) layer: 1 } block v_9rhg { - position: pos(20, 2640, 1160, 580) - layer: 1 - } - block v_dbuh { - position: pos(20, 3240, 1160, 500) + position: pos(20, 6260, 1160, 580) layer: 1 } block v_tusm { - position: pos(20, 3760, 1160, 500) + position: pos(20, 7380, 1160, 500) layer: 1 } block v_j83d { - position: pos(20, 4280, 1160, 480) + position: pos(20, 7900, 1160, 480) layer: 1 } block v_nyr1 { - position: pos(20, 4780, 1160, 500) + position: pos(20, 8400, 1160, 500) layer: 1 } - block t_4ttu { - position: pos(20, 100, 380, 160) + block v_5dpt { + position: pos(20, 8920, 1160, 500) layer: 1 } - block t_5y3l { - position: pos(40, 120, 60, 40) - layer: 2 + block v_8fpj { + position: pos(20, 5140, 1160, 500) + layer: 4 } - block t_vb6z { - position: pos(80, 120, 300, 60) - layer: 3 + block v_350o { + position: pos(20, 800, 540, 400) + layer: 1 } - block f_zwa4 { - position: pos(80, 160, 280, 60) - layer: 4 + block v_qnug { + position: pos(20, 1220, 1160, 400) + layer: 1 } - block v_5dpt { - position: pos(20, 5300, 1160, 500) + block v_tq6d { + position: pos(580, 800, 600, 400) layer: 1 } - block v_bxa7 { - position: pos(20, 260, 540, 320) + block t_hcv3 { + position: pos(20, 1660, 320, 60) layer: 1 } - block v_vzap { - position: pos(20, 600, 1160, 400) - layer: 4 + block t_ww35 { + position: pos(20, 300, 320, 60) + layer: 1 } - block v_8fpj { - position: pos(20, 1020, 1160, 500) - layer: 4 + block v_6o9d { + position: pos(20, 3580, 1160, 440) + layer: 1 + } + block v_wwiv { + position: pos(20, 3120, 1160, 440) + layer: 1 + } + block t_vh1h { + position: pos(20, 4080, 320, 60) + layer: 1 + } + block v_7vcf { + position: pos(20, 100, 380, 180) + layer: 1 + } + block v_ji80 { + position: pos(20, 4140, 1160, 480) + layer: 1 + } + block v_n0qr { + position: pos(20, 4640, 1160, 480) + layer: 1 + } + block v_0sbb { + position: pos(20, 2660, 1160, 440) + layer: 1 + } + block v_58pi { + position: pos(20, 2200, 1160, 440) + layer: 1 + } + block v_jpzg { + position: pos(20, 1740, 1160, 440) + layer: 1 + } + block v_vk4x { + position: pos(580, 360, 540, 420) + layer: 1 + } + block v_ufmq { + position: pos(420, 100, 380, 180) + layer: 1 + } + block v_t8f9 { + position: pos(600, 5660, 580, 560) + layer: 1 } mobile { mode: 'auto' @@ -401,9 +441,9 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } block v5: VizBlock { - label: 'GMV - Gross Merchandise Value by Continent Name' + label: 'GMV by Continent (2024)' description: 'This is description of the block' - viz: BarChart { + viz: ColumnChart { dataset: demo_ecommerce calculation adhoc_dim { label: 'My adhoc dim' @@ -417,7 +457,9 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a operator: 'matches' value: '2024' } - legend: VizFieldFull { + theme { + } + x_axis: VizFieldFull { ref: r(ecommerce_countries.continent_name) format { type: 'text' @@ -813,6 +855,14 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a label: 'Total Revenue and Number of Order by Month' viz: DataTable { dataset: vyhuynh_ecommerce_dataset + filter { + field: r(vyht_ecommerce_users_1.sign_up_date) + operator: 'matches' + value: '2025' + } + theme { + + } fields: [ VizFieldFull { label: 'Order Month' @@ -824,16 +874,7 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } }, VizFieldFull { - label: 'Total Revenue' ref: r(vyhuynh_ecommerce_dataset.total_revenue) - format { - type: 'number' - pattern: '[$$]#,###' - } - }, - VizFieldFull { - ref: r(vyht_ecommerce_orders_1.id) - aggregation: 'count distinct' format { type: 'number' pattern: 'inherited' @@ -871,23 +912,21 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } }, VizFieldFull { - ref: r(order_master.user_id) - aggregation: 'count distinct' + ref: r(ecommerce_users.email_user) + format { + type: 'text' + } + }, + VizFieldFull { + ref: r(demo_ecommerce.total_orders) format { type: 'number' pattern: 'inherited' } - uname: 'count_distinct_user_id_1' } ] settings { show_row_number: true - sorts: [ - SortSetting { - key: 'count_distinct_user_id_1' - direction: 'desc' - } - ] row_limit: 5000 aggregate_awareness { enabled: true @@ -964,9 +1003,11 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } block v_qctn: VizBlock { - label: 'Number of Order by Country Name and City Name' + label: 'Trend analysis' viz: LineChart { dataset: demo_ecommerce + theme { + } x_axis: VizFieldFull { ref: r(order_master.order_created_at) transformation: 'datetrunc month' @@ -997,16 +1038,6 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } } - series { - field: VizFieldFull { - ref: r(demo_ecommerce, order_master.aov_by_product) - aggregation: 'count' - format { - type: 'number' - pattern: 'inherited' - } - } - } } settings { row_limit: 5000 @@ -1018,6 +1049,11 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } } + description: '''How is each continent trending over time? + +**Insights**: Seasonality patterns, growth trends, comparative performance across months + +''' } block v_9rhg: VizBlock { label: 'Number of Order by Country Name and City Name' @@ -1205,53 +1241,6 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } } - block v_dbuh: VizBlock { - label: 'GMV - Gross Merchandise Value by Month Order Created At and Continent Name' - viz: ColumnChart { - dataset: demo_ecommerce - filter { - field: r(order_master.order_created_at) - operator: 'matches' - value: '2024' - } - x_axis: VizFieldFull { - ref: r(order_master.order_created_at) - transformation: 'datetrunc month' - format { - type: 'date' - pattern: 'LLL yyyy' - } - } - legend: VizFieldFull { - ref: r(ecommerce_countries.continent_name) - format { - type: 'text' - } - } - y_axis { - settings { - show_data_label_by: 'value' - } - series { - field: VizFieldFull { - ref: r(order_master.gmv) - format { - type: 'number' - pattern: 'inherited' - } - } - } - } - settings { - row_limit: 5000 - x_axis_show_null_datetime: false - aggregate_awareness { - enabled: true - debug_comments: true - } - } - } - } block v_tusm: VizBlock { label: 'GMV - Gross Merchandise Value by Country Name' viz: BarChart { @@ -1625,49 +1614,41 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a value: [] } } - block v_bxa7: VizBlock { - label: 'GMV - Gross Merchandise Value by Continent Name copy' - description: 'This is description of the block' + block v_8fpj: VizBlock { + label: 'Revenue by Sale reps' viz: BarChart { - dataset: demo_ecommerce - calculation adhoc_dim { - label: 'My adhoc dim' - formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; - calc_type: 'dimension' - data_type: 'text' - model: order_master - } - filter { - field: r(order_master.order_created_at) - operator: 'matches' - value: '2024' - } + dataset: vyhuynh_ecommerce_dataset theme { } x_axis: VizFieldFull { - ref: ref('order_master', 'adhoc_dim') - format { - type: 'text' - } - } - legend: VizFieldFull { - ref: r(ecommerce_countries.continent_name) + ref: r(vy_sales_revenue_demo_csv.sales_rep) format { type: 'text' } } y_axis { - settings { - show_data_label_by: 'value' - } series { field: VizFieldFull { - ref: r(order_master.gmv) + ref: r(vy_sales_revenue_demo_csv.revenue_usd) + aggregation: 'sum' format { type: 'number' - pattern: '#,###' + pattern: 'inherited' + } + } + } + series { + field: ConstantVizField { + label: 'KPI goal' + value: 60000 + format { + type: 'number' + pattern: 'inherited' } } + settings { + line_style: 'dashed' + } } } settings { @@ -1680,28 +1661,32 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } } - block v_vzap: VizBlock { - label: 'Sum of Revenue by Country' - viz: ColumnChart { - dataset: vyhuynh_ecommerce_dataset + block v_jbl8: VizBlock { + label: 'Total Order Value by Month Created Date' + viz: LineChart { + dataset: demo_ecommerce_metrics theme { } x_axis: VizFieldFull { - ref: r(revenue_by_country_csv.country) + ref: r(ecommerce_orders.created_date) + transformation: 'datetrunc month' format { - type: 'text' + type: 'date' + pattern: 'LLL yyyy' } } y_axis { series { field: VizFieldFull { - ref: r(revenue_by_country_csv.revenue) - aggregation: 'sum' + ref: r(demo_ecommerce_metrics.total_order_value) format { type: 'number' pattern: 'inherited' } } + settings { + color_palette: 0 + } } } settings { @@ -1714,43 +1699,98 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } } - block v_8fpj: VizBlock { - label: 'Revenue by Sale reps' - viz: BarChart { - dataset: vyhuynh_ecommerce_dataset + block v_350o: VizBlock { + label: 'GMV by Continent (2024) - Compare vs LY' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + calculation metric_f0aed54 { + label: '% Delta LY - GMV ' + formula: @aql safe_divide(order_master.gmv, order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_a9389ef { + label: ' LY - GMV' + formula: @aql order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_57371a1 { + label: 'Delta LY - GMV' + formula: @aql order_master.gmv - (order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true));; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } theme { } x_axis: VizFieldFull { - ref: r(vy_sales_revenue_demo_csv.sales_rep) + ref: r(ecommerce_countries.continent_name) format { type: 'text' } } y_axis { + settings { + show_data_label_by: 'value' + } series { field: VizFieldFull { - ref: r(vy_sales_revenue_demo_csv.revenue_usd) - aggregation: 'sum' + ref: 'metric_a9389ef' format { type: 'number' pattern: 'inherited' } } + settings { + color: '#7C9EE5' + } } series { - field: ConstantVizField { - label: 'KPI goal' - value: 60000 + field: VizFieldFull { + ref: r(order_master.gmv) format { type: 'number' pattern: 'inherited' } } settings { - line_style: 'dashed' + color: '#255DD4' } } } + tooltips: [ + VizTooltip { + field: VizFieldFull { + ref: 'metric_f0aed54' + format { + type: 'number' + pattern: '#,###%' + } + } + }, + VizTooltip { + field: VizFieldFull { + ref: 'metric_57371a1' + format { + type: 'number' + pattern: '#,###' + } + } + } + ] settings { row_limit: 5000 x_axis_show_null_datetime: false @@ -1761,36 +1801,723 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a } } } - block v_jbl8: VizBlock { - label: 'Total Order Value by Month Created Date' + block v_qnug: VizBlock { + label: 'GMV by Continent (2024) - Show trend over time' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } + theme { + } + x_axis: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + legend: VizFieldFull { + ref: r(ecommerce_countries.continent_name) + format { + type: 'text' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_tq6d: VizBlock { + label: 'GMV by Continent (2024) - Show % change copy' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + calculation metric_f0aed54 { + label: '% Delta LY - GMV ' + formula: @aql safe_divide(order_master.gmv, order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true)) - 1;; + calc_type: 'measure' + data_type: 'number' + } + calculation metric_a9389ef { + label: ' LY - GMV' + formula: @aql order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } + theme { + } + x_axis: VizFieldFull { + ref: r(ecommerce_countries.continent_name) + format { + type: 'text' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: 'metric_f0aed54' + format { + type: 'number' + pattern: '#,###%' + } + } + settings { + color: '#18A59E' + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_wwiv: VizBlock { + label: 'GMV by Continent over time - With Trendline' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } + theme { + } + x_axis: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + legend: VizFieldFull { + ref: r(ecommerce_countries.continent_name) + format { + type: 'text' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + series { + field: VizFieldFull { + label: 'Trend line of Gmv' + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + analytic: RegressionLine { + type: 'linear' + } + } + settings { + line_style: 'dashed' + point { + value: 'Asia' + line_style: 'dashed' + } + point { + value: 'Europe' + line_style: 'dashed' + } + point { + value: 'Oceania' + line_style: 'dashed' + } + point { + value: 'North America' + line_style: 'dashed' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_6o9d: VizBlock { + label: 'GMV by Continent over time - Line chart' + description: 'This is description of the block' viz: LineChart { - dataset: demo_ecommerce_metrics + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } theme { } x_axis: VizFieldFull { - ref: r(ecommerce_orders.created_date) + ref: r(order_master.order_created_at) transformation: 'datetrunc month' format { type: 'date' pattern: 'LLL yyyy' } } + legend: VizFieldFull { + ref: r(ecommerce_countries.continent_name) + format { + type: 'text' + } + } y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block t_hcv3: TextBlock { + content: @md ## Time series analysis;; + } + block t_ww35: TextBlock { + content: @md ## Categorical analysis;; + } + block t_vh1h: TextBlock { + content: @md ## Distribution analysis;; + } + block v_ji80: VizBlock { + label: 'Total order distributed by Price' + viz: ScatterChart { + dataset: demo_ecommerce + theme { + } + x_col: VizFieldFull { + ref: r(order_master.price) + format { + type: 'number' + pattern: 'inherited' + } + } + y_col: VizFieldFull { + ref: r(demo_ecommerce.total_orders) + format { + type: 'number' + pattern: 'inherited' + } + } + } + } + block v_7vcf: VizBlock { + label: 'Total GMV (2024)' + description: 'This is description of the block' + viz: MetricKpi { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + calculation metric_f688c32 { + label: '% Change - LY - GMV' + formula: @aql order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2025' + } + theme { + } + value: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + compare_value: VizFieldFull { + ref: 'metric_f688c32' + format { + type: 'number' + pattern: '#,###' + } + } + settings { + display_mode: 'compare_by_number' + aggregate_awareness { + enabled: true + debug_comments: true + } + alignment: 'left' + } + } + } + block v_n0qr: VizBlock { + label: 'Total order distributed by Price- With trend line' + viz: LineChart { + dataset: demo_ecommerce + theme { + } + x_axis: VizFieldFull { + ref: r(order_master.price) + format { + type: 'number' + pattern: 'inherited' + } + } + y_axis { + series { + field: VizFieldFull { + ref: r(demo_ecommerce.total_orders) + format { + type: 'number' + pattern: 'inherited' + } + } + } + series { + field: VizFieldFull { + label: 'Trend line of Total Orders' + ref: r(demo_ecommerce.total_orders) + format { + type: 'number' + pattern: 'inherited' + } + analytic: RegressionLine { + type: 'linear' + } + } + settings { + line_style: 'dashed' + } + } + } + settings { + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_jpzg: VizBlock { + label: 'GMV over time' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } + theme { + } + x_axis: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_0sbb: VizBlock { + label: 'GMV over time - with trendline' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } + theme { + } + x_axis: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + series { + field: VizFieldFull { + label: 'Trend line of Gmv' + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + analytic: RegressionLine { + type: 'linear' + } + } + settings { + line_style: 'dashed' + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_58pi: VizBlock { + label: 'GMV over time - vs LY' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + calculation metric_14d21cf { + label: 'LY - GMV' + formula: @aql order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + theme { + } + x_axis: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + series { + field: VizFieldFull { + ref: 'metric_14d21cf' + format { + type: 'number' + pattern: 'inherited' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_vk4x: VizBlock { + label: 'GMV by Country (2024)' + description: 'This is description of the block' + viz: ColumnChart { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2024' + } + theme { + } + x_axis: VizFieldFull { + ref: r(ecommerce_countries.name) + format { + type: 'text' + } + } + y_axis { + settings { + show_data_label_by: 'value' + } + series { + field: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + } + } + settings { + row_limit: 5000 + x_axis_show_null_datetime: false + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } + block v_ufmq: VizBlock { + label: 'Total GMV (2024) copy' + description: 'This is description of the block' + viz: MetricKpi { + dataset: demo_ecommerce + calculation adhoc_dim { + label: 'My adhoc dim' + formula: @aql concat(cast(total_orders, 'text'), " ", ecommerce_countries.continent_name);; + calc_type: 'dimension' + data_type: 'text' + model: order_master + } + calculation metric_f688c32 { + label: '% Change - LY - GMV' + formula: @aql order_master.gmv | relative_period(order_master.order_created_at, interval(-1 year), strict: true);; + calc_type: 'measure' + data_type: 'number' + } + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2025' + } + theme { + } + value: VizFieldFull { + ref: r(order_master.gmv) + format { + type: 'number' + pattern: '#,###' + } + } + compare_value: VizFieldFull { + label: 'KPI Goal' + ref: r(order_master.revenue) + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + display_mode: 'progress' + aggregate_awareness { + enabled: true + debug_comments: true + } + alignment: 'left' + } + } + } + block v_t8f9: VizBlock { + label: 'Comparison anlysis' + description: @md Which continent generate the most revenue overall? + +**Insights**: Continent rankings, performance gaps, which continent dominate;; + viz: ColumnChart { + dataset: demo_ecommerce + theme { + } + x_axis: VizFieldFull { + ref: r(ecommerce_countries.continent_name) + format { + type: 'text' + } + } + legend: VizFieldFull { + ref: r(order_master.order_created_at) + transformation: 'datetrunc month' + format { + type: 'date' + pattern: 'LLL yyyy' + } + } + y_axis { + label: 'Total Order' + settings { + show_data_label_by: 'value' + stack_series_by: 'value' + } series { field: VizFieldFull { - ref: r(demo_ecommerce_metrics.total_order_value) + ref: r(order_master.order_id) + aggregation: 'count distinct' format { type: 'number' pattern: 'inherited' } } - settings { - color_palette: 0 - } } } settings { row_limit: 5000 + x_axis_label: 'Country' x_axis_show_null_datetime: false aggregate_awareness { enabled: true @@ -1808,7 +2535,6 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v3', 'v4', 'v_nehb', - 'v_vzap', 'v_8fpj' ] disabled: true @@ -1823,7 +2549,6 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v2', 'v4', 'v_nehb', - 'v_vzap', 'v_8fpj' ] disabled: true @@ -1838,7 +2563,6 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v2', 'v3', 'v_nehb', - 'v_vzap', 'v_8fpj' ] disabled: true @@ -1854,11 +2578,13 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_wsww', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', - 'v_5dpt' + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } @@ -1878,7 +2604,19 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_j83d', 'v_lpgt', 'v_5zcz', - 'v_bxa7', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', 'f2' ] disabled: true @@ -1899,14 +2637,26 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_856v', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', 'v_lpgt', 'v_5zcz', 'v_5dpt', - 'v_bxa7', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9', 'f1', 'f_zwa4' ] @@ -1927,7 +2677,19 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_j83d', 'v_lpgt', 'v_5zcz', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' ] disabled: true } @@ -1946,7 +2708,19 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_j83d', 'v_lpgt', 'v_5zcz', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' ] disabled: true } @@ -1976,7 +2750,19 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_wsww', 'v_j83d', 'v_5zcz', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' ] disabled: true } @@ -1994,7 +2780,19 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_hk4u', 'v_j83d', 'v_5zcz', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' ] disabled: true } @@ -2008,7 +2806,6 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v2', 'v3', 'v4', - 'v_vzap', 'v_8fpj' ] disabled: true @@ -2021,7 +2818,9 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a CustomMapping { block: [ 'v_ztqi', - 'v_j83d' + 'v_j83d', + 'v_ji80', + 'v_n0qr' ] disabled: true } @@ -2034,12 +2833,23 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a block: [ 'v5', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', 'v_5dpt', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' ] disabled: true } @@ -2052,12 +2862,24 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a block: [ 'v5', 'v_qctn', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', 'v_5dpt', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' ] disabled: true } @@ -2075,14 +2897,26 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_856v', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', 'v_lpgt', 'v_5zcz', 'v_5dpt', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' ] disabled: true }, @@ -2102,43 +2936,115 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a ] }, FilterInteraction { - from: 'v_dbuh' + from: 'v_tusm' to: [ CustomMapping { block: [ 'v5', 'v_qctn', 'v_9rhg', - 'v_tusm', 'v_j83d', 'v_nyr1', 'v_5dpt', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_tusm' + from: 'v_j83d' to: [ CustomMapping { block: [ 'v5', + 'v8', + 'v_711g', + 'v_ztqi', + 'v_hk4u', + 'v_wsww', + 'v_856v', 'v_qctn', 'v_9rhg', - 'v_dbuh', - 'v_j83d', + 'v_tusm', 'v_nyr1', + 'v_5zcz', 'v_5dpt', - 'v_bxa7' + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_7vcf', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_j83d' + from: 'v_nyr1' + to: [ + CustomMapping { + block: [ + 'v5', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_5dpt', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_lpgt' + to: [ + CustomMapping { + block: [ + 'v8', + 'v_711g', + 'v_5zcz' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_5zcz' to: [ CustomMapping { block: [ @@ -2148,53 +3054,177 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_ztqi', 'v_hk4u', 'v_wsww', - 'v_856v', + 'v_j83d', + 'v_lpgt', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_5dpt' + to: [ + CustomMapping { + block: [ + 'v5', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_8fpj' + to: [ + CustomMapping { + block: [ + 'v2', + 'v3', + 'v4', + 'v_nehb' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_350o' + to: [ + CustomMapping { + block: [ + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', 'v_nyr1', - 'v_5zcz', 'v_5dpt', - 'v_bxa7' + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_nyr1' + from: 'v_qnug' to: [ CustomMapping { block: [ - 'v5', + 'v_711g', + 'v_wsww', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', + 'v_nyr1', 'v_5dpt', - 'v_bxa7' + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_lpgt' + from: 'v_tq6d' to: [ CustomMapping { block: [ - 'v8', 'v_711g', - 'v_5zcz' + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_5zcz' + from: 'v_wwiv' + to: [ + CustomMapping { + block: [ + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_6o9d' + to: [ + CustomMapping { + block: [ + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_ji80' to: [ CustomMapping { block: [ @@ -2204,34 +3234,109 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_ztqi', 'v_hk4u', 'v_wsww', + 'v_856v', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_nyr1', + 'v_5zcz', + 'v_5dpt', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_7vcf', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_7vcf' + to: [ + CustomMapping { + block: [ + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', 'v_j83d', - 'v_lpgt', - 'v_bxa7' + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_5dpt' + from: 'v_n0qr' to: [ CustomMapping { block: [ 'v5', + 'v8', + 'v_711g', + 'v_ztqi', + 'v_hk4u', + 'v_wsww', + 'v_856v', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_nyr1', + 'v_5zcz', + 'v_5dpt', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_7vcf', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_jpzg' + to: [ + CustomMapping { + block: [ + 'v_711g', + 'v_wsww', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', - 'v_bxa7' + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_bxa7' + from: 'v_0sbb' to: [ CustomMapping { block: [ @@ -2239,39 +3344,105 @@ Morbi rhoncus tellus eget libero tincidunt, sit amet aliquam leo hendrerit. Ut a 'v_wsww', 'v_qctn', 'v_9rhg', - 'v_dbuh', 'v_tusm', 'v_j83d', 'v_nyr1', - 'v_5dpt' + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_vzap' + from: 'v_58pi' to: [ CustomMapping { block: [ - 'v2', - 'v3', - 'v4', - 'v_nehb' + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' ] disabled: true } ] }, FilterInteraction { - from: 'v_8fpj' + from: 'v_vk4x' to: [ CustomMapping { block: [ - 'v2', - 'v3', - 'v4', - 'v_nehb' + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_ufmq' + to: [ + CustomMapping { + block: [ + 'v_711g', + 'v_wsww', + 'v_qctn', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_ji80', + 'v_n0qr', + 'v_t8f9' + ] + disabled: true + } + ] + }, + FilterInteraction { + from: 'v_t8f9' + to: [ + CustomMapping { + block: [ + 'v5', + 'v_9rhg', + 'v_tusm', + 'v_j83d', + 'v_nyr1', + 'v_5dpt', + 'v_350o', + 'v_qnug', + 'v_tq6d', + 'v_wwiv', + 'v_6o9d', + 'v_ji80', + 'v_7vcf', + 'v_n0qr', + 'v_jpzg', + 'v_0sbb', + 'v_58pi', + 'v_vk4x', + 'v_ufmq' ] disabled: true } diff --git a/team-folders/VyHuynh/Vy's Model/Miscellaneous/sales_rep_uc_3_outlier_csv.model.aml b/team-folders/VyHuynh/Vy's Model/Miscellaneous/sales_rep_uc_3_outlier_csv.model.aml new file mode 100644 index 0000000..cb759bd --- /dev/null +++ b/team-folders/VyHuynh/Vy's Model/Miscellaneous/sales_rep_uc_3_outlier_csv.model.aml @@ -0,0 +1,57 @@ +Model sales_rep_uc_3_outlier_csv { + type: 'table' + label: 'Sales rep uc 3 outlier csv' + description: '' + data_source_name: 'demodb' + dimension sales_rep { + label: 'Sales rep' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.sales_rep }};; + } + dimension region { + label: 'Region' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.region }};; + } + dimension product_category { + label: 'Product category' + description: '' + type: 'text' + hidden: false + definition: @sql {{ #SOURCE.product_category }};; + } + dimension revenue { + label: 'Revenue' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.revenue }};; + } + dimension order_count { + label: 'Order count' + description: '' + type: 'number' + hidden: false + definition: @sql {{ #SOURCE.order_count }};; + } + + import_source: ImportSource { + type: 'csv' + original_file_name: 'sales_rep_uc3_outlier.csv' + uploaded_at: '2026-02-17 10:42:05' + hash: 'f2fc8b91af7dc27517db797b49254582a48e71ab19104737f2a2fa350f6ec7e8' + column_configs: [ + H.imports.column_config("sales_rep", "sales_rep", "text"), + H.imports.column_config("region", "region", "text"), + H.imports.column_config("product_category", "product_category", "text"), + H.imports.column_config("revenue", "revenue", "number"), + H.imports.column_config("order_count", "order_count", "number") + ] + } + owner: 'vy.ht@holistics.io' + table_name: '"dbt_khai"."holistics_sales_rep_uc__fbb5c_202602171042"' +} diff --git a/team-folders/VyHuynh/Vy's Model/vy_axis_scale_test.model.aml b/team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_axis_scale_test.model.aml similarity index 100% rename from team-folders/VyHuynh/Vy's Model/vy_axis_scale_test.model.aml rename to team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_axis_scale_test.model.aml diff --git a/team-folders/VyHuynh/Vy's Model/vy_null_dim_value.model.aml b/team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_null_dim_value.model.aml similarity index 100% rename from team-folders/VyHuynh/Vy's Model/vy_null_dim_value.model.aml rename to team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_null_dim_value.model.aml diff --git a/team-folders/VyHuynh/Vy's Model/vy_revenue_by_country_csv.model.aml b/team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_revenue_by_country_csv.model.aml similarity index 100% rename from team-folders/VyHuynh/Vy's Model/vy_revenue_by_country_csv.model.aml rename to team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_revenue_by_country_csv.model.aml diff --git a/team-folders/VyHuynh/Vy's Model/vy_sales_revenue_demo_csv.model.aml b/team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_sales_revenue_demo_csv.model.aml similarity index 100% rename from team-folders/VyHuynh/Vy's Model/vy_sales_revenue_demo_csv.model.aml rename to team-folders/VyHuynh/Vy's Model/Miscellaneous/vy_sales_revenue_demo_csv.model.aml diff --git a/team-folders/VyHuynh/Vy's Model/Vy's Ecommerce Dataset.dataset.aml b/team-folders/VyHuynh/Vy's Model/Vy's Ecommerce Dataset.dataset.aml index b953188..cd006dd 100644 --- a/team-folders/VyHuynh/Vy's Model/Vy's Ecommerce Dataset.dataset.aml +++ b/team-folders/VyHuynh/Vy's Model/Vy's Ecommerce Dataset.dataset.aml @@ -11,6 +11,8 @@ Dataset vyhuynh_ecommerce_dataset { vy_sales_revenue_demo_csv , revenue_by_country_csv + , + sales_rep_uc_3_outlier_csv ] relationships: [ relationship(vyht_ecommerce_orders_1.user_id > vyht_ecommerce_users_1.id, true), diff --git a/team-folders/khai/datasets/khai_ecommerce.dataset.aml b/team-folders/khai/datasets/khai_ecommerce.dataset.aml index 8b280e4..4a8670d 100644 --- a/team-folders/khai/datasets/khai_ecommerce.dataset.aml +++ b/team-folders/khai/datasets/khai_ecommerce.dataset.aml @@ -1,3 +1,23 @@ +Func time_compare(metric_name: String, metric_label: String, format: String) { + Metric { + label: '${metric_label} (time compare)' + type: 'number' + definition: @aql case( + when: time_type.time_type == "1. Week" + , then: ${metric_name} | where(khai_date_d.date_key match @(this week)) + , when: time_type.time_type == "2. MTD" + , then: ${metric_name} | where(khai_date_d.date_key match @(this month to today)) + , when: time_type.time_type == "3. MTD LY" + , then: ${metric_name} | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this month to today)) + , when: time_type.time_type == "4. YTD" + , then: ${metric_name} | where(khai_date_d.date_key match @(this year to today)) + , when: time_type.time_type == "5. YTD LY" + , then: ${metric_name} | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this year to today)) + ) ;; + format: format + } +} + Dataset khai_ecommerce { __engine__: 'aql' label: 'Ecommerce (from Khai)' @@ -182,136 +202,19 @@ Dataset khai_ecommerce { } // time comparison metrics - metric gmv_time_compare { - label: 'GMV (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: gmv | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: gmv | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: gmv | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "4. YTD" - , then: gmv | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: gmv | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this year to today)) - ) ;; - format: "[\$\$]#,###0" - } - metric nmv_time_compare { - label: 'NMV (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: nmv | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: nmv | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: nmv | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "4. YTD" - , then: nmv | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: nmv | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this year to today)) - ) - ;; - format: "[\$\$]#,###0" - } + metric gmv_time_compare: time_compare('gmv', 'GMV', '[\$\$]#,###0') - metric aov_time_compare { - label: 'AOV (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: aov | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: aov | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: aov | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "4. YTD" - , then: aov | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: aov | relative_period(khai_date_d.date_key, interval(-1 year)) | where(khai_date_d.date_key match @(this year to today)) - ) - ;; - format: "[\$\$]#,###0" - } + metric nmv_time_compare: time_compare('nmv', 'NMV', '[\$\$]#,###0') - metric total_orders_compare { - label: 'Total Orders (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: total_orders | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: total_orders | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: total_orders | where(khai_date_d.date_key match @(2025-01-10)) - , when: time_type.time_type == "4. YTD" - , then: total_orders | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: total_orders | where(khai_date_d.date_key match @(this year to today)) | relative_period(khai_date_d.date_key, interval(-1 year)) - ) - ;; - format: "#,###" - } + metric aov_time_compare: time_compare('aov', 'AOV', '[\$\$]#,###0') - metric total_delivered_orders_time_compare { - label: 'Total Delivered Orders (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: total_delivered_orders | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: total_delivered_orders | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: total_delivered_orders | where(khai_date_d.date_key match @(2025-01-10)) - , when: time_type.time_type == "4. YTD" - , then: total_delivered_orders | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: total_delivered_orders | where(khai_date_d.date_key match @(this year to today)) | relative_period(khai_date_d.date_key, interval(-1 year)) - ) - ;; - format: "#,###" - } + metric total_orders_compare: time_compare('total_orders', 'Total Orders', '#,###') - metric total_cancelled_orders_time_compare { - label: 'Total Cancelled Orders (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: total_cancelled_orders | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: total_cancelled_orders | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: total_cancelled_orders | where(khai_date_d.date_key match @(2025-01-10)) - , when: time_type.time_type == "4. YTD" - , then: total_cancelled_orders | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: total_cancelled_orders | where(khai_date_d.date_key match @(this year to today)) | relative_period(khai_date_d.date_key, interval(-1 year)) - ) - ;; - format: "#,###" - } + metric total_delivered_orders_time_compare: time_compare('total_delivered_orders', 'Total Delivered Orders', '#,###') - metric cancelled_order_ratio_time_compare { - label: 'Cancelled order ratio (time compare)' - type: 'number' - definition: @aql case( - when: time_type.time_type == "1. Week" - , then: cancelled_order_ratio | where(khai_date_d.date_key match @(this week)) - , when: time_type.time_type == "2. MTD" - , then: cancelled_order_ratio | where(khai_date_d.date_key match @(this month to today)) - , when: time_type.time_type == "3. MTD LY" - , then: cancelled_order_ratio | where(khai_date_d.date_key match @(2025-01-10)) - , when: time_type.time_type == "4. YTD" - , then: cancelled_order_ratio | where(khai_date_d.date_key match @(this year to today)) - , when: time_type.time_type == "5. YTD LY" - , then: cancelled_order_ratio | where(khai_date_d.date_key match @(this year to today)) | relative_period(khai_date_d.date_key, interval(-1 year)) - ) - ;; - format: "#,###0.00%" - } + metric total_cancelled_orders_time_compare: time_compare('total_cancelled_orders', 'Total Cancelled Orders', '#,###') + + metric cancelled_order_ratio_time_compare: time_compare('cancelled_order_ratio', 'Cancelled Orders Ratio', '#,###0.00%') } \ No newline at end of file diff --git a/team-folders/khai/models/base/orders.model.aml b/team-folders/khai/models/base/orders.model.aml index c5c34c6..aa81c35 100644 --- a/team-folders/khai/models/base/orders.model.aml +++ b/team-folders/khai/models/base/orders.model.aml @@ -1,7 +1,7 @@ Model orders { type: 'table' label: 'Orders' - description: '' + description: 'test description' data_source_name: 'demodb' dimension id { label: 'Id' diff --git a/team-folders/tai/embed_portal.embed.aml b/team-folders/tai/embed_portal.embed.aml index b8f3aa1..54d61a2 100644 --- a/team-folders/tai/embed_portal.embed.aml +++ b/team-folders/tai/embed_portal.embed.aml @@ -1,7 +1,7 @@ -EmbedPortal embed_portal { - objects: [ - demo_ecommerce_overview_pro, - test_zoom - ] - initial_object: test_zoom -} \ No newline at end of file +// EmbedPortal embed_portal { +// objects: [ +// demo_ecommerce_overview_pro, +// test_zoom +// ] +// initial_object: test_zoom +// } \ No newline at end of file diff --git a/team-folders/tai/localizations/dict.aml b/team-folders/tai/localizations/dict.aml new file mode 100644 index 0000000..c6b6fda --- /dev/null +++ b/team-folders/tai/localizations/dict.aml @@ -0,0 +1,22 @@ +const dict = { + dashboard_title: { + eng: 'Ecommerce Dashboard - Tai', + spa: 'Panel de control de comercio electrónico - Tai' + }, + gmv_block_label: { + eng: 'Gross Merchandise Value', + spa: 'Valor bruto de la mercancía' + }, + gmv_field_label: { + eng: 'GMV - Gross Merchandise Value', + spa: 'GMV - Valor bruto de la mercancía' + }, + total_users_label: { + eng: 'Total Users', + spa: 'Total de usuarios' + }, + target_users_calculation: { + eng: 'Target Users', + spa: 'Usuarios objetivo' + } +} \ No newline at end of file diff --git a/team-folders/tai/localizations/ecommerce_dashboard_tai.page.aml b/team-folders/tai/localizations/ecommerce_dashboard_tai.page.aml new file mode 100644 index 0000000..5b80b6d --- /dev/null +++ b/team-folders/tai/localizations/ecommerce_dashboard_tai.page.aml @@ -0,0 +1,101 @@ +Dashboard ecommerce_dashboard_tai { + title: dict('dashboard_title')('eng') + owner: 'hien.nt@holistics.io' + block v_l8pg: VizBlock { + label: dict('gmv_block_label')('eng') + viz: MetricKpi { + dataset: demo_ecommerce_internal_training + filter { + field: r(order_master.order_created_at) + operator: 'matches' + value: '2023' + } + value: VizFieldFull { + label: dict('gmv_field_label')('eng') + ref: r(order_master.gmv) + format { + type: 'number' + pattern: 'inherited' + } + } + compare_value: VizPopSettings { + field: r(order_master.order_created_at) + value: RelativePopValue { + duration: 2 + granularity: 'year' + } + } + settings { + aggregate_awareness { + enabled: true + debug_comments: true + } + alignment: 'left' + } + } + } + block v_cbn7: VizBlock { + label: dict('total_users_label')('eng') + viz: MetricKpi { + dataset: demo_ecommerce_internal_training + calculation target_users { + label: 'Target Users' + formula: @aql ecommerce_users.users_signed_up_count * 1.38;; + calc_type: 'measure' + data_type: 'number' + } + value: VizFieldFull { + label: dict('target_users_calculation')('eng') + ref: r(ecommerce_users.total_users) + format { + type: 'number' + pattern: 'inherited' + } + } + compare_value: VizFieldFull { + ref: 'target_users' + format { + type: 'number' + pattern: 'inherited' + } + } + settings { + display_mode: 'progress' + aggregate_awareness { + enabled: true + debug_comments: true + } + alignment: 'left' + } + } + } + block t_gtay: TextBlock { + content: @md

Hello

;; + } + view: CanvasLayout { + label: 'Canvas Layout' + width: 1220 + height: 2720 + grid_size: 20 + auto_expand_vertically: true + block t_gtay { + position: pos(20, 20, 1180, 80) + layer: 1 + } + block v_cbn7 { + position: pos(20, 320, 500, 180) + layer: 1 + } + block v_l8pg { + position: pos(20, 120, 500, 180) + layer: 1 + } + mobile { + mode: 'auto' + } + } + theme: H.themes.vanilla + settings { + cache_duration: 1440 + } +} \ No newline at end of file diff --git a/team-folders/tai/localizations/ecommerce_dashboard_tai_spanish.page.aml b/team-folders/tai/localizations/ecommerce_dashboard_tai_spanish.page.aml new file mode 100644 index 0000000..c5bc954 --- /dev/null +++ b/team-folders/tai/localizations/ecommerce_dashboard_tai_spanish.page.aml @@ -0,0 +1,21 @@ +Dashboard ecommerce_dashboard_tai_spanish= ecommerce_dashboard_tai.extend({ + title: dict('dashboard_title')('spa') + owner: 'hien.nt@holistics.io' + + block v_l8pg: VizBlock { + label: dict('gmv_block_label')('spa') + viz: MetricKpi { + value: VizFieldFull { + label: dict('gmv_field_label')('spa') + } + } + } + block v_cbn7: VizBlock { + label: dict('total_users_label')('spa') + viz: MetricKpi { + value: VizFieldFull { + label: dict('target_users_calculation')('spa') + } + } + } +}) \ No newline at end of file diff --git a/team-folders/tai/test_extend/tai_ecom.page.aml b/team-folders/tai/test_extend/tai_ecom.page.aml index 84fc7e5..0cb0f1b 100644 --- a/team-folders/tai/test_extend/tai_ecom.page.aml +++ b/team-folders/tai/test_extend/tai_ecom.page.aml @@ -1,9 +1,5 @@ -// use lib -// use demo - Dashboard tai_ecom { title: 'Ecommerce Dashboard - Pro' - block hd1: TextBlock { content: @md demo;; @@ -124,12 +120,6 @@ This dashboard tracks the KPIs of all managers for their respective teams. This label: 'GMV' viz: MetricKpi { dataset: demo_ecommerce - // calculation f_2fb1cc3 { - // label: 'GMT last year' - // formula: @aml order_master.gmv * 0.87;; - // calc_type: 'measure' - // data_type: 'number' - // } filter { field: ref('order_master', 'order_created_at') operator: 'matches' @@ -859,7 +849,6 @@ abc;; ;; } - // block t46: background_gray() block t47: TextBlock { content: @md
@@ -1099,7 +1088,6 @@ abc;; viz: ColumnChart { dataset: demo_ecommerce theme { - } x_axis: VizFieldFull { ref: ref('ecommerce_users', 'age_group') @@ -1618,10 +1606,35 @@ abc;; hide_label: true } } + block v_xd99: VizBlock { + label: 'Untitled Report' + viz: DataTable { + dataset: buyers_sellers_transactions + theme { + + } + fields: [ + VizFieldFull { + ref: r(sellers.sign_up_date) + format { + type: 'date' + } + } + ] + settings { + show_row_number: true + row_limit: 5000 + aggregate_awareness { + enabled: true + debug_comments: true + } + } + } + } view: CanvasLayout { label: 'View 1' width: 1540 - height: 4460 + height: 4930 grid_size: 20 block hd1 { position: pos(1320, 20, 180, 50) @@ -1774,6 +1787,10 @@ abc;; position: pos(280, 700, 860, 260) layer: -1 } + block v_xd99 { + position: pos(440, 4490, 620, 420) + layer: 4 + } mobile { mode: 'auto' } diff --git a/thong_do_drill_through.page.aml b/thong_do_drill_through.page.aml index d5daa2b..d293caa 100644 --- a/thong_do_drill_through.page.aml +++ b/thong_do_drill_through.page.aml @@ -63,7 +63,7 @@ Dashboard thong_do_drill_through { } default { operator: 'is' - value: [] + value: 'delivered' } settings { drillthrough: Drillthrough { diff --git a/untitled_5.page.aml b/untitled_5.page.aml index e2833c0..93ae496 100644 --- a/untitled_5.page.aml +++ b/untitled_5.page.aml @@ -1,5 +1,5 @@ Dashboard untitled_5 { - title: 'Untitled' + title: 'Untitled Test Push master' description: '' owner: 'thang.lk@holistics.io' block title: TextBlock { @@ -21,4 +21,4 @@ Dashboard untitled_5 { } theme: H.themes.vanilla -} \ No newline at end of file +} diff --git a/vux-dashboard-test.page.aml b/vux-dashboard-test.page.aml new file mode 100644 index 0000000..168bf10 --- /dev/null +++ b/vux-dashboard-test.page.aml @@ -0,0 +1,25 @@ +Dashboard vux_dashboard_test { + title: 'vux-dashboard-test' + description: '' + owner: 'vu.dq@holistics.io' + block title: TextBlock { + content: @md # Your title goes here ;; + } + + view: CanvasLayout { + label: 'View 1' + width: 1300 + height: 800 + grid_size: 20 + auto_expand_vertically: true + block title { + position: pos(20, 20, 1260, 60) + } + mobile { + mode: 'auto' + } + } + + theme: H.themes.vanilla + +} \ No newline at end of file