additional hot fixes

This commit is contained in:
Nate Kelley 2025-07-10 09:30:52 -06:00
parent 1860a20f45
commit 834d75674a
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
4 changed files with 193 additions and 16 deletions

View File

@ -22,8 +22,10 @@ import type {
} from '@buster/server-shared/metrics'; } from '@buster/server-shared/metrics';
import { serverFetch } from '@/api/createServerInstance'; import { serverFetch } from '@/api/createServerInstance';
import { mainApi } from '../instances'; import { mainApi } from '../instances';
import { testMetricDataResponse, testMetricResponse } from './test';
export const getMetric = async (params: GetMetricRequest) => { export const getMetric = async (params: GetMetricRequest): Promise<GetMetricResponse> => {
// return testMetricResponse as unknown as GetMetricResponse;
return mainApi return mainApi
.get<GetMetricResponse>(`/metrics/${params.id}`, { .get<GetMetricResponse>(`/metrics/${params.id}`, {
params params
@ -37,7 +39,12 @@ export const getMetric_server = async ({ id, password }: Parameters<typeof getMe
}); });
}; };
export const getMetricData = async ({ id, version_number, password }: GetMetricDataRequest) => { export const getMetricData = async ({
id,
version_number,
password
}: GetMetricDataRequest): Promise<MetricDataResponse> => {
// return testMetricDataResponse as unknown as MetricDataResponse;
return mainApi return mainApi
.get<MetricDataResponse>(`/metrics/${id}/data`, { params: { password, version_number } }) .get<MetricDataResponse>(`/metrics/${id}/data`, { params: { password, version_number } })
.then((res) => res.data); .then((res) => res.data);

View File

@ -0,0 +1,167 @@
export const testMetricResponse = {
id: '23b15b8e-4e22-4980-83b5-0009e173f0e0',
type: 'metric',
name: 'Monthly Order Volume Decline',
version_number: 1,
description: 'Shows the declining trend in monthly order volume over the last 12 months',
file_name: 'Monthly Order Volume Decline',
time_frame: 'Last 12 months',
datasets: [],
data_source_id: '14d50bf5-6dee-42a7-bdff-a4a398156edf',
error: null,
chart_config: {
selectedChartType: 'line',
columnLabelFormats: {
order_count: {
columnType: 'number',
style: 'number',
numberSeparatorStyle: ',',
replaceMissingDataWith: 0
},
order_month: {
columnType: 'date',
style: 'date',
numberSeparatorStyle: null,
replaceMissingDataWith: null,
dateFormat: 'MMM YYYY'
}
},
barAndLineAxis: {
x: ['order_month'],
y: ['order_count']
}
},
data_metadata: {
column_count: 2,
row_count: 13,
column_metadata: [
{
name: 'order_month',
min_value: '2024-03-01T00:00:00.000Z',
max_value: '2025-03-01T00:00:00.000Z',
unique_values: 13,
simple_type: 'date',
type: 'timestamp'
},
{
name: 'order_count',
min_value: 375,
max_value: 2326,
unique_values: 13,
simple_type: 'number',
type: 'int4'
}
]
},
status: 'notRequested',
evaluation_score: null,
evaluation_summary: '',
file: "name: Monthly Order Volume Decline\ndescription: Shows the declining trend in monthly order volume over the last 12 months\ntimeFrame: Last 12 months\nsql: \"SELECT \\n DATE_TRUNC('month', soh.orderdate) as order_month,\\n COUNT(*) as order_count\\nFROM postgres.ont_ont.sales_order_header soh\\nWHERE soh.orderdate >= (SELECT MAX(orderdate) FROM postgres.ont_ont.sales_order_header) - INTERVAL '12 months'\\nGROUP BY DATE_TRUNC('month', soh.orderdate)\\nORDER BY order_month\\n\"\nchartConfig:\n selectedChartType: line\n columnLabelFormats:\n order_count:\n columnType: number\n style: number\n numberSeparatorStyle: ','\n replaceMissingDataWith: 0\n order_month:\n columnType: date\n style: date\n numberSeparatorStyle: null\n replaceMissingDataWith: null\n dateFormat: MMM YYYY\n barAndLineAxis:\n x:\n - order_month\n y:\n - order_count\n",
created_at: '2025-07-09T22:01:16.273Z',
updated_at: '2025-07-09T22:01:16.273Z',
sent_by_id: '1fe85021-e799-471b-8837-953e9ae06e4c',
sent_by_name: '',
sent_by_avatar_url: null,
code: null,
dashboards: [],
collections: [],
versions: [
{
version_number: 1,
updated_at: '2025-07-09T22:01:16.273Z'
}
],
permission: 'owner',
sql: "SELECT \n DATE_TRUNC('month', soh.orderdate) as order_month,\n COUNT(*) as order_count\nFROM postgres.ont_ont.sales_order_header soh\nWHERE soh.orderdate >= (SELECT MAX(orderdate) FROM postgres.ont_ont.sales_order_header) - INTERVAL '12 months'\nGROUP BY DATE_TRUNC('month', soh.orderdate)\nORDER BY order_month\n",
individual_permissions: [
{
email: 'blake@buster.so',
role: 'owner',
name: 'Blake Rouse'
}
],
public_expiry_date: null,
public_enabled_by: null,
publicly_accessible: false,
public_password: null
};
export const testMetricDataResponse = {
metric_id: '23b15b8e-4e22-4980-83b5-0009e173f0e0',
data: [
{
order_month: '2024-03-01T00:00:00',
order_count: 375
},
{
order_month: '2024-04-01T00:00:00',
order_count: 1707
},
{
order_month: '2024-05-01T00:00:00',
order_count: 1783
},
{
order_month: '2024-06-01T00:00:00',
order_count: 1815
},
{
order_month: '2024-07-01T00:00:00',
order_count: 1973
},
{
order_month: '2024-08-01T00:00:00',
order_count: 2139
},
{
order_month: '2024-09-01T00:00:00',
order_count: 2015
},
{
order_month: '2024-10-01T00:00:00',
order_count: 2130
},
{
order_month: '2024-11-01T00:00:00',
order_count: 2018
},
{
order_month: '2024-12-01T00:00:00',
order_count: 2300
},
{
order_month: '2025-01-01T00:00:00',
order_count: 2326
},
{
order_month: '2025-02-01T00:00:00',
order_count: 1982
},
{
order_month: '2025-03-01T00:00:00',
order_count: 871
}
],
data_metadata: {
column_count: 2,
row_count: 13,
column_metadata: [
{
name: 'order_month',
min_value: '2024-03-01T00:00:00.000Z',
max_value: '2025-03-01T00:00:00.000Z',
unique_values: 13,
simple_type: 'date',
type: 'timestamp'
},
{
name: 'order_count',
min_value: 375,
max_value: 2326,
unique_values: 13,
simple_type: 'number',
type: 'int4'
}
]
}
};

View File

@ -2,6 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { import {
DEFAULT_COLUMN_LABEL_FORMAT, DEFAULT_COLUMN_LABEL_FORMAT,
type BarAndLineAxis,
type ChartConfigProps,
type ColumnLabelFormat, type ColumnLabelFormat,
type ColumnSettings, type ColumnSettings,
type DataMetadata, type DataMetadata,
@ -2072,21 +2074,21 @@ const test = createDefaultChartConfig({
style: 'number', style: 'number',
numberSeparatorStyle: ',', numberSeparatorStyle: ',',
replaceMissingDataWith: 0 replaceMissingDataWith: 0
}, } as ColumnLabelFormat,
order_month: { order_month: {
columnType: 'date', columnType: 'date',
style: 'date', style: 'date',
numberSeparatorStyle: null, numberSeparatorStyle: null,
replaceMissingDataWith: null, replaceMissingDataWith: null,
dateFormat: 'MMM YYYY' dateFormat: 'MMM YYYY'
} } as ColumnLabelFormat
}, } as ChartConfigProps['columnLabelFormats'],
barAndLineAxis: { barAndLineAxis: {
x: ['order_month'], x: ['order_month'],
y: ['order_count'] y: ['order_count']
}, } as BarAndLineAxis,
selectedChartType: 'line' selectedChartType: 'line'
} } as ChartConfigProps
}); });
const data = [ const data = [
{ {

View File

@ -3,6 +3,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useMemoizedFn } from './useMemoizedFn'; import { useMemoizedFn } from './useMemoizedFn';
import { useMount } from './useMount'; import { useMount } from './useMount';
import { isServer } from '@tanstack/react-query';
type SetState<S> = S | ((prevState?: S) => S); type SetState<S> = S | ((prevState?: S) => S);
@ -38,20 +39,20 @@ export function useLocalStorageState<T>(
// Get initial value from localStorage or use default // Get initial value from localStorage or use default
const getInitialValue = useMemoizedFn((): T | undefined => { const getInitialValue = useMemoizedFn((): T | undefined => {
const letsBusterTheStorageBaby = () => { const gonnaBustTheStorage = () => {
window.localStorage.removeItem(key); if (!isServer) window.localStorage.removeItem(key);
return typeof defaultValue === 'function' ? (defaultValue as () => T)() : defaultValue; return typeof defaultValue === 'function' ? (defaultValue as () => T)() : defaultValue;
}; };
// If bustStorageOnInit is true, ignore localStorage and use default value // If bustStorageOnInit is true, ignore localStorage and use default value
if (bustStorageOnInit === true) { if (bustStorageOnInit === true) {
return letsBusterTheStorageBaby(); return gonnaBustTheStorage();
} }
try { try {
const item = window.localStorage.getItem(key); const item = window.localStorage.getItem(key);
if (item === null) { if (item === null) {
return letsBusterTheStorageBaby(); return gonnaBustTheStorage();
} }
// Parse the stored data which includes value and timestamp // Parse the stored data which includes value and timestamp
@ -65,7 +66,7 @@ export function useLocalStorageState<T>(
!('timestamp' in storageData) !('timestamp' in storageData)
) { ) {
// If the data doesn't have the expected structure (legacy data), treat as expired // If the data doesn't have the expected structure (legacy data), treat as expired
return letsBusterTheStorageBaby(); return gonnaBustTheStorage();
} }
// Check if the data has expired // Check if the data has expired
@ -74,20 +75,20 @@ export function useLocalStorageState<T>(
if (timeDifference > expirationTime) { if (timeDifference > expirationTime) {
// Data has expired, remove it and return default value // Data has expired, remove it and return default value
return letsBusterTheStorageBaby(); return gonnaBustTheStorage();
} }
// Data is still valid, deserialize and return the value // Data is still valid, deserialize and return the value
const deserializedValue = deserializer(JSON.stringify(storageData.value)); const deserializedValue = deserializer(JSON.stringify(storageData.value));
if (typeof bustStorageOnInit === 'function' && bustStorageOnInit(deserializedValue)) { if (typeof bustStorageOnInit === 'function' && bustStorageOnInit(deserializedValue)) {
return letsBusterTheStorageBaby(); return gonnaBustTheStorage();
} }
return deserializedValue; return deserializedValue;
} catch (error) { } catch (error) {
onError?.(error); onError?.(error);
return letsBusterTheStorageBaby(); return gonnaBustTheStorage();
} }
}); });
@ -101,7 +102,7 @@ export function useLocalStorageState<T>(
// Update localStorage when state changes // Update localStorage when state changes
useEffect(() => { useEffect(() => {
try { try {
if (state === undefined) { if (state === undefined && !isServer) {
window.localStorage.removeItem(key); window.localStorage.removeItem(key);
} else { } else {
// Create storage data with current timestamp // Create storage data with current timestamp