bbb

import json
from datetime import datetime
import ast

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode, DataReturnMode, JsCode

fr…


This content originally appeared on DEV Community and was authored by Armaan Khan

import json
from datetime import datetime
import ast

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode, DataReturnMode, JsCode

from core.query_executor import query_executor
from queries.QueryBuilder import QueryBuilder
from queries.filter import CommonUI
from queries.final_last import USER_360_QUERIES


def create_snowflake_dashboard(df):
    # Custom CSS for enhanced styling
    st.markdown(
        """
    <style>
        .main-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #667eea 100%);
            color: white;
            padding: 30px;
            border-radius: 15px;
            text-align: center;
            margin-bottom: 30px;
            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
            animation: gradient 15s ease infinite;
            background-size: 400% 400%;
        }

        @keyframes gradient {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }

        .metric-card {
            background: linear-gradient(145deg, #ffffff, #f0f2f6);
            padding: 25px;
            border-radius: 15px;
            box-shadow: 0 8px 20px rgba(0,0,0,0.1);
            border: 1px solid rgba(102, 126, 234, 0.1);
            margin: 15px 0;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .metric-card::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 4px;
            background: linear-gradient(90deg, #667eea, #764ba2);
        }

        .metric-card:hover {
            transform: translateY(-5px) scale(1.02);
            box-shadow: 0 12px 30px rgba(102, 126, 234, 0.2);
        }

        .metric-value {
            font-size: 2.5em;
            font-weight: 700;
            color: #2c3e50;
            margin-bottom: 8px;
            text-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .metric-label {
            color: #5a6c7d;
            font-size: 1.1em;
            font-weight: 500;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .back-button {
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 25px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
            margin-bottom: 20px;
        }

        .back-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
        }

        .query-detail-container {
            background: linear-gradient(145deg, #ffffff, #f8f9fa);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.15);
            margin: 20px 0;
            border: 1px solid rgba(102, 126, 234, 0.1);
        }

        .query-card {
            background: white;
            border-radius: 12px;
            padding: 20px;
            margin: 15px 0;
            box-shadow: 0 4px 15px rgba(0,0,0,0.08);
            border-left: 4px solid #667eea;
            transition: all 0.3s ease;
        }

        .query-card:hover {
            transform: translateX(5px);
            box-shadow: 0 6px 20px rgba(0,0,0,0.12);
        }

        .status-optimal {
            background: linear-gradient(135deg, #d4edda, #c3e6cb);
            color: #155724;
            padding: 8px 16px;
            border-radius: 20px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .status-warning {
            background: linear-gradient(135deg, #fff3cd, #ffeaa7);
            color: #856404;
            padding: 8px 16px;
            border-radius: 20px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .status-critical {
            background: linear-gradient(135deg, #f8d7da, #fab1a0);
            color: #721c24;
            padding: 8px 16px;
            border-radius: 20px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .recommendation-card {
            background: linear-gradient(135deg, #fff3cd, #ffeaa7);
            padding: 20px;
            border-radius: 12px;
            margin: 15px 0;
            border-left: 4px solid #ffc107;
            box-shadow: 0 4px 15px rgba(255, 193, 7, 0.2);
        }

        .metric-mini-card {
            background: linear-gradient(145deg, #f8f9fa, #e9ecef);
            border-radius: 10px;
            padding: 15px;
            text-align: center;
            margin: 5px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.05);
            border: 1px solid rgba(102, 126, 234, 0.1);
        }

        .section-title {
            font-size: 1.8em;
            font-weight: 700;
            color: #2c3e50;
            margin: 30px 0 20px 0;
            position: relative;
            padding-bottom: 10px;
        }

        .section-title::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 50px;
            height: 3px;
            background: linear-gradient(90deg, #667eea, #764ba2);
            border-radius: 2px;
        }

        .stButton > button {
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            border: none;
            border-radius: 10px;
            padding: 12px 24px;
            font-weight: 600;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
        }

        .stButton > button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
        }

        .ag-theme-streamlit {
            --ag-header-background-color: linear-gradient(135deg, #667eea, #764ba2);
            --ag-header-foreground-color: white;
            --ag-odd-row-background-color: #f8f9fa;
            --ag-row-hover-color: rgba(102, 126, 234, 0.1);
        }

        .fade-in {
            animation: fadeIn 0.5s ease-in;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }
    </style>
    """,
        unsafe_allow_html=True,
    )

    # Initialize session state
    if "view_mode" not in st.session_state:
        st.session_state.view_mode = "table"  # "table" or "details"
    if "selected_user" not in st.session_state:
        st.session_state.selected_user = None
    if "selected_metric" not in st.session_state:
        st.session_state.selected_metric = None

    # Header
    st.markdown(
        """
    <div class="main-header fade-in">
        <h1>❄️ Snowflake Query Analytics Dashboard</h1>
        <p style="font-size: 1.2em; margin-top: 15px;">Monitor, analyze, and optimize your Snowflake query performance with intelligent insights</p>
    </div>
    """,
        unsafe_allow_html=True,
    )

    # Sidebar for data input
    with st.sidebar:
        st.header("πŸ“Š Data Management")
        uploaded_file = st.file_uploader("Upload JSON Data", type=["json"])
        if uploaded_file is not None:
            try:
                new_data = json.load(uploaded_file)
                if isinstance(new_data, list):
                    df = pd.DataFrame(new_data)
                    st.success("βœ… Data loaded successfully!")
                else:
                    df = pd.DataFrame([new_data])
                    st.success("βœ… Data loaded successfully!")
            except Exception as e:
                st.error(f"❌ Error loading data: {e}")

        st.subheader("Or paste JSON data:")
        json_input = st.text_area(
            "JSON Data", height=200, placeholder="Paste your JSON data here..."
        )
        if st.button("Load JSON Data"):
            try:
                new_data = json.loads(json_input)
                if isinstance(new_data, list):
                    df = pd.DataFrame(new_data)
                else:
                    df = pd.DataFrame([new_data])
                st.success("βœ… Data loaded successfully!")
                st.rerun()
            except Exception as e:
                st.error(f"❌ Error parsing JSON: {e}")

    if not df.empty:
        # Show different views based on mode
        if st.session_state.view_mode == "table":
            show_table_view(df)
        else:
            show_details_view(df)
    else:
        show_empty_state()


def show_table_view(df):
    """Display the main table view with metrics and AgGrid table"""

    # Overall metrics cards
    st.markdown('<div class="section-title fade-in">πŸ“ˆ Overall Performance Metrics</div>', unsafe_allow_html=True)

    # First row of metrics
    col1, col2, col3, col4 = st.columns(4)
    with col1:
        total_users = len(df)
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{total_users}</div>
            <div class="metric-label">πŸ‘₯ Total Users</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col2:
        total_queries = df["TOTAL_QUERIES"].sum()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{total_queries:,}</div>
            <div class="metric-label">πŸ” Total Queries</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col3:
        total_credits = df["TOTAL_CREDITS"].sum()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">${total_credits:,.2f}</div>
            <div class="metric-label">πŸ’° Total Credits</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col4:
        avg_score = df["WEIGHTED_SCORE"].mean()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{avg_score:.1f}</div>
            <div class="metric-label">⭐ Avg Score</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    # Second row of metrics
    col5, col6, col7, col8 = st.columns(4)
    with col5:
        total_spilled = df["SPILLED_QUERIES"].sum()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{total_spilled}</div>
            <div class="metric-label">πŸ’Ύ Spilled Queries</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col6:
        total_slow = df["SLOW_QUERIES"].sum()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{total_slow}</div>
            <div class="metric-label">🐌 Slow Queries</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col7:
        total_select_star = df["SELECT_STAR_QUERIES"].sum()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{total_select_star}</div>
            <div class="metric-label">⭐ SELECT * Queries</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col8:
        avg_failure_rate = df["FAILURE_CANCELLATION_RATE_PCT"].mean()
        st.markdown(
            f"""
        <div class="metric-card fade-in">
            <div class="metric-value">{avg_failure_rate:.1f}%</div>
            <div class="metric-label">❌ Avg Failure Rate</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    # Enhanced AgGrid Table
    st.markdown('<div class="section-title fade-in">πŸ‘₯ User Analytics Table</div>', unsafe_allow_html=True)
    st.markdown('<p style="color: #666; margin-bottom: 20px;">Click on any user row to view detailed query analysis and recommendations</p>', unsafe_allow_html=True)

    # Prepare data for AgGrid
    display_df = df.copy()

    # Format columns for better display
    display_df["TOTAL_CREDITS"] = display_df["TOTAL_CREDITS"].apply(lambda x: f"${x:,.2f}")
    display_df["AVG_EXECUTION_TIME_MS"] = display_df["AVG_EXECUTION_TIME_MS"].apply(lambda x: f"{x:,.1f}ms")
    display_df["TOTAL_DATA_SCANNED_GB"] = display_df["TOTAL_DATA_SCANNED_GB"].apply(lambda x: f"{x:,.2f}GB")
    display_df["FAILURE_CANCELLATION_RATE_PCT"] = display_df["FAILURE_CANCELLATION_RATE_PCT"].apply(lambda x: f"{x:.2f}%")

    # Configure AgGrid
    gb = GridOptionsBuilder.from_dataframe(display_df)

    # Configure selection
    gb.configure_selection("single", use_checkbox=False, rowMultiSelectWithClick=False)

    # Configure columns
    gb.configure_column("USER_NAME", headerName="πŸ‘€ User Name", width=200, pinned="left")
    gb.configure_column("TOTAL_QUERIES", headerName="πŸ” Total Queries", width=120)
    gb.configure_column("TOTAL_CREDITS", headerName="πŸ’° Credits", width=120)
    gb.configure_column("WEIGHTED_SCORE", headerName="⭐ Score", width=100, type=["numericColumn", "numberColumnFilter"])
    gb.configure_column("COST_STATUS", headerName="πŸ“Š Status", width=120)
    gb.configure_column("SPILLED_QUERIES", headerName="πŸ’Ύ Spilled", width=100)
    gb.configure_column("SLOW_QUERIES", headerName="🐌 Slow", width=100)
    gb.configure_column("SELECT_STAR_QUERIES", headerName="⭐ SELECT *", width=120)
    gb.configure_column("AVG_EXECUTION_TIME_MS", headerName="⏱️ Avg Time", width=120)
    gb.configure_column("TOTAL_DATA_SCANNED_GB", headerName="πŸ“Š Data Scanned", width=140)
    gb.configure_column("FAILURE_CANCELLATION_RATE_PCT", headerName="❌ Failure Rate", width=130)

    # Hide some columns to keep the table manageable
    columns_to_hide = [
        "OVER_PROVISIONED_QUERIES", "PEAK_HOUR_LONG_RUNNING_QUERIES", 
        "UNPARTITIONED_SCAN_QUERIES", "REPEATED_QUERIES", "COMPLEX_JOIN_QUERIES",
        "ZERO_RESULT_QUERIES", "HIGH_COMPILE_QUERIES", "UNTAGGED_QUERIES",
        "UNLIMITED_ORDER_BY_QUERIES", "LARGE_GROUP_BY_QUERIES", 
        "EXPENSIVE_DISTINCT_QUERIES", "INEFFICIENT_LIKE_QUERIES",
        "NO_RESULTS_WITH_SCAN_QUERIES", "CARTESIAN_JOIN_QUERIES",
        "HIGH_COMPILE_RATIO_QUERIES", "QUERY_SAMPLES", "RECOMMENDATIONS"
    ]

    for col in columns_to_hide:
        if col in display_df.columns:
            gb.configure_column(col, hide=True)

    # Configure grid options
    gb.configure_grid_options(
        domLayout='normal',
        enableRangeSelection=True,
        enableRowGrouping=True,
        enablePivot=True,
        enableValue=True,
        rowHeight=50,
        headerHeight=60
    )

    grid_options = gb.build()

    # Display the grid
    grid_response = AgGrid(
        display_df,
        gridOptions=grid_options,
        data_return_mode=DataReturnMode.FILTERED_AND_SORTED,
        update_mode=GridUpdateMode.SELECTION_CHANGED,
        fit_columns_on_grid_load=False,
        theme="streamlit",
        height=500,
        width='100%',
        reload_data=False
    )

    # Handle row selection
    if grid_response['selected_rows'] is not None and len(grid_response['selected_rows']) > 0:
        selected_row = grid_response['selected_rows'][0]
        st.session_state.selected_user = selected_row['USER_NAME']
        st.session_state.view_mode = "details"
        st.rerun()

    # Charts section
    st.markdown('<div class="section-title fade-in">πŸ“Š Analytics Visualizations</div>', unsafe_allow_html=True)

    col1, col2 = st.columns(2)

    with col1:
        fig_scatter = px.scatter(
            df,
            x="TOTAL_QUERIES",
            y="TOTAL_CREDITS",
            hover_data=["USER_NAME", "WEIGHTED_SCORE"],
            title="πŸ’° Credits vs Total Queries",
            color="WEIGHTED_SCORE",
            size="TOTAL_DATA_SCANNED_GB",
            color_continuous_scale="Viridis"
        )
        fig_scatter.update_layout(
            height=500,
            title_font_size=16,
            plot_bgcolor='rgba(0,0,0,0)',
            paper_bgcolor='rgba(0,0,0,0)'
        )
        st.plotly_chart(fig_scatter, use_container_width=True)

    with col2:
        status_counts = df["COST_STATUS"].value_counts()
        fig_pie = px.pie(
            values=status_counts.values,
            names=status_counts.index,
            title="πŸ“Š Cost Status Distribution",
            color_discrete_sequence=px.colors.qualitative.Set3
        )
        fig_pie.update_layout(
            height=500,
            title_font_size=16,
            plot_bgcolor='rgba(0,0,0,0)',
            paper_bgcolor='rgba(0,0,0,0)'
        )
        st.plotly_chart(fig_pie, use_container_width=True)


def show_details_view(df):
    """Display detailed view for selected user"""

    # Back button
    if st.button("← Back to Table", key="back_button"):
        st.session_state.view_mode = "table"
        st.session_state.selected_user = None
        st.session_state.selected_metric = None
        st.rerun()

    user_data = df[df["USER_NAME"] == st.session_state.selected_user].iloc[0]

    # User header
    st.markdown(
        f"""
    <div class="query-detail-container fade-in">
        <h1>πŸ” Detailed Analysis for {st.session_state.selected_user}</h1>
        <div style="display: flex; justify-content: space-between; align-items: center; margin: 20px 0;">
            <div>
                <span style="font-size: 1.2em; color: #666;">Overall Performance Score:</span>
                <span style="font-size: 2em; font-weight: bold; color: #667eea; margin-left: 10px;">{user_data['WEIGHTED_SCORE']:.1f}</span>
            </div>
            <div>
                <span class="status-{'optimal' if user_data['COST_STATUS'] == 'Optimal' else 'warning' if user_data['COST_STATUS'] == 'Warning' else 'critical'}">
                    {user_data['COST_STATUS']}
                </span>
            </div>
        </div>
    </div>
    """,
        unsafe_allow_html=True,
    )

    # User metrics overview
    st.markdown('<div class="section-title">πŸ“Š User Performance Overview</div>', unsafe_allow_html=True)

    col1, col2, col3, col4 = st.columns(4)
    with col1:
        st.markdown(
            f"""
        <div class="metric-mini-card">
            <div style="font-size: 1.8em; font-weight: bold; color: #667eea;">{user_data['TOTAL_QUERIES']:,}</div>
            <div style="color: #666; font-size: 0.9em;">Total Queries</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col2:
        st.markdown(
            f"""
        <div class="metric-mini-card">
            <div style="font-size: 1.8em; font-weight: bold; color: #667eea;">${user_data['TOTAL_CREDITS']:,.2f}</div>
            <div style="color: #666; font-size: 0.9em;">Total Credits</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col3:
        st.markdown(
            f"""
        <div class="metric-mini-card">
            <div style="font-size: 1.8em; font-weight: bold; color: #667eea;">{user_data['AVG_EXECUTION_TIME_MS']:,.1f}ms</div>
            <div style="color: #666; font-size: 0.9em;">Avg Execution Time</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    with col4:
        st.markdown(
            f"""
        <div class="metric-mini-card">
            <div style="font-size: 1.8em; font-weight: bold; color: #667eea;">{user_data['TOTAL_DATA_SCANNED_GB']:,.2f}GB</div>
            <div style="color: #666; font-size: 0.9em;">Data Scanned</div>
        </div>
        """,
            unsafe_allow_html=True,
        )

    # Query type breakdown
    st.markdown('<div class="section-title">πŸ” Query Type Analysis</div>', unsafe_allow_html=True)

    query_metrics = [
        ("SPILLED_QUERIES", "πŸ’Ύ Spilled Queries", "Queries that spilled to disk"),
        ("SLOW_QUERIES", "🐌 Slow Queries", "Queries with high execution time"),
        ("SELECT_STAR_QUERIES", "⭐ SELECT * Queries", "Queries using SELECT *"),
        ("COMPLEX_JOIN_QUERIES", "πŸ”— Complex Join Queries", "Queries with complex joins"),
        ("REPEATED_QUERIES", "πŸ”„ Repeated Queries", "Frequently repeated queries"),
        ("HIGH_COMPILE_QUERIES", "βš™οΈ High Compile Queries", "Queries with high compile time")
    ]

    cols = st.columns(3)
    for i, (metric, title, description) in enumerate(query_metrics):
        with cols[i % 3]:
            value = user_data.get(metric, 0)
            percentage = (value / user_data['TOTAL_QUERIES'] * 100) if user_data['TOTAL_QUERIES'] > 0 else 0

            st.markdown(
                f"""
            <div class="query-card">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                    <div>
                        <h4 style="margin: 0; color: #2c3e50;">{title}</h4>
                        <p style="margin: 5px 0; color: #666; font-size: 0.9em;">{description}</p>
                    </div>
                    <div style="text-align: right;">
                        <div style="font-size: 1.5em; font-weight: bold; color: #667eea;">{value}</div>
                        <div style="color: #666; font-size: 0.9em;">{percentage:.1f}%</div>
                    </div>
                </div>
            </div>
            """,
                unsafe_allow_html=True,
            )

    # Sample queries section
    if "QUERY_SAMPLES" in user_data and user_data["QUERY_SAMPLES"]:
        st.markdown('<div class="section-title">πŸ“‹ Sample Query Analysis</div>', unsafe_allow_html=True)

        query_samples = user_data["QUERY_SAMPLES"]
        if isinstance(query_samples, str):
            try:
                query_samples = ast.literal_eval(query_samples)
            except Exception as e:
                st.error(f"Failed to parse query samples: {e}")
                query_samples = {}

        # Create tabs for different query types
        if query_samples:
            tabs = st.tabs([key.replace('_', ' ').title() for key in query_samples.keys()])

            for i, (sample_key, samples) in enumerate(query_samples.items()):
                with tabs[i]:
                    for j, sample in enumerate(samples[:3]):  # Show top 3 samples
                        with st.expander(f"Query {j+1}: {sample.get('query_id', 'N/A')}", expanded=j==0):
                            st.code(
                                sample.get("query_text", "No query text available"),
                                language="sql",
                            )

                            # Metrics in columns
                            metric_cols = st.columns(4)
                            with metric_cols[0]:
                                execution_time = sample.get("execution_time_ms", 0)
                                color = "#28a745" if execution_time < 1000 else "#dc3545"
                                st.markdown(f"**⏱️ Execution Time**<br><span style='color: {color}; font-size: 1.2em; font-weight: bold;'>{execution_time:,}ms</span>", unsafe_allow_html=True)

                            with metric_cols[1]:
                                st.markdown(f"**πŸ“Š Bytes Scanned**<br><span style='font-size: 1.2em; font-weight: bold;'>{sample.get('bytes_scanned', 0):,}</span>", unsafe_allow_html=True)

                            with metric_cols[2]:
                                st.markdown(f"**🏭 Warehouse**<br><span style='font-size: 1.2em; font-weight: bold;'>{sample.get('warehouse_size', 'N/A')}</span>", unsafe_allow_html=True)

                            with metric_cols[3]:
                                st.markdown(f"**πŸ“… Start Time**<br><span style='font-size: 1.2em; font-weight: bold;'>{sample.get('start_time', 'N/A')}</span>", unsafe_allow_html=True)

                            # Spill information if available
                            if "bytes_spilled_to_local_storage" in sample:
                                st.markdown("**πŸ’Ύ Spill Information:**")
                                spill_cols = st.columns(2)
                                with spill_cols[0]:
                                    st.info(f"Local Spill: {sample.get('bytes_spilled_to_local_storage', 0):,} bytes")
                                with spill_cols[1]:
                                    st.info(f"Remote Spill: {sample.get('bytes_spilled_to_remote_storage', 0):,} bytes")

    # Recommendations section
    if "RECOMMENDATIONS" in user_data and user_data["RECOMMENDATIONS"]:
        st.markdown('<div class="section-title">πŸ’‘ Optimization Recommendations</div>', unsafe_allow_html=True)

        recommendations = user_data["RECOMMENDATIONS"]
        if isinstance(recommendations, str):
            try:
                recommendations = ast.literal_eval(recommendations)
            except Exception as e:
                st.error(f"Failed to parse recommendations: {e}")
                recommendations = []

        for i, rec in enumerate(recommendations):
            st.markdown(
                f"""
            <div class="recommendation-card">
                <h4 style="margin: 0 0 10px 0; color: #856404;">πŸ’‘ Recommendation {i+1}</h4>
                <p style="margin: 0; font-size: 1.1em; line-height: 1.6;">{rec}</p>
            </div>
            """,
                unsafe_allow_html=True,
            )


def show_empty_state():
    """Display empty state when no data is available"""
    st.markdown(
        """
    <div class="query-detail-container fade-in" style="text-align: center; padding: 50px;">
        <h2>πŸ“Š Welcome to Snowflake Analytics Dashboard</h2>
        <p style="font-size: 1.2em; color: #666; margin: 20px 0;">
            No data available. Please upload JSON data using the sidebar to get started!
        </p>
        <div style="background: #f8f9fa; padding: 30px; border-radius: 15px; margin: 30px 0; text-align: left; max-width: 600px; margin: 30px auto;">
            <h3>πŸ“‹ Expected JSON Format:</h3>
            <p>Your JSON should contain user analytics data with the following structure:</p>
            <ul style="text-align: left; color: #666;">
                <li><strong>USER_NAME</strong> - Name of the user</li>
                <li><strong>TOTAL_QUERIES</strong> - Total number of queries executed</li>
                <li><strong>TOTAL_CREDITS</strong> - Total credits consumed</li>
                <li><strong>WEIGHTED_SCORE</strong> - Performance score</li>
                <li><strong>Various query metrics</strong> (SPILLED_QUERIES, SELECT_STAR_QUERIES, etc.)</li>
                <li><strong>QUERY_SAMPLES</strong> - Detailed query information with examples</li>
                <li><strong>RECOMMENDATIONS</strong> - Optimization suggestions</li>
            </ul>
        </div>
    </div>
    """,
        unsafe_allow_html=True,
    )


# Run the dashboard with sample data
if __name__ == "__main__":
    st.subheader("πŸ”§ Filters")
    col1, col2 = st.columns(2)

    with col1:
        date_filter, custom_start, custom_end = CommonUI.render_date_filter()

    with col2:
        selected_user = CommonUI.render_object_filter("user", query_executor)

    # === PREPARE QUERY PARAMETERS ===
    # Get date range
    start_date, end_date = query_executor.get_date_range(
        date_filter, custom_start, custom_end
    )

    # Build object filter
    object_filter = QueryBuilder.build_object_filter("user", selected_user)
    print(f"this is the meeee {object_filter}")
    st.markdown("---")
    query_key = "user_all_quries"
    df = {}
    query = QueryBuilder.prepare_query(
        USER_360_QUERIES, query_key, start_date, end_date, object_filter
    )

    if not query:
        st.error(f"Failed to prepare query for {query_key}")
        # continue

    # Execute query
    try:
        data = query_executor._execute_single_query(
            query, {}, query_key  # Already formatted
        )
        df = data
    except Exception as e:
        st.error(f"Query execution failed for {query_key}: {str(e)}")

    # Analysis type selection
    s = len(df)
    # sample_data = load_sample_data()
    # df = pd.DataFrame(sample_data)

    create_snowflake_dashboard(df)


This content originally appeared on DEV Community and was authored by Armaan Khan


Print Share Comment Cite Upload Translate Updates
APA

Armaan Khan | Sciencx (2025-07-30T05:50:44+00:00) bbb. Retrieved from https://www.scien.cx/2025/07/30/bbb/

MLA
" » bbb." Armaan Khan | Sciencx - Wednesday July 30, 2025, https://www.scien.cx/2025/07/30/bbb/
HARVARD
Armaan Khan | Sciencx Wednesday July 30, 2025 » bbb., viewed ,<https://www.scien.cx/2025/07/30/bbb/>
VANCOUVER
Armaan Khan | Sciencx - » bbb. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/07/30/bbb/
CHICAGO
" » bbb." Armaan Khan | Sciencx - Accessed . https://www.scien.cx/2025/07/30/bbb/
IEEE
" » bbb." Armaan Khan | Sciencx [Online]. Available: https://www.scien.cx/2025/07/30/bbb/. [Accessed: ]
rf:citation
» bbb | Armaan Khan | Sciencx | https://www.scien.cx/2025/07/30/bbb/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.