web: easier to navigate around + a lot of minor ui improvements
This commit is contained in:
@@ -1,16 +1,19 @@
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { toast } from '@/components/ui/use-toast';
|
||||
import { pushModal } from '@/modals';
|
||||
import { useSelector } from '@/redux';
|
||||
import { useDispatch, useSelector } from '@/redux';
|
||||
import { api, handleError } from '@/utils/api';
|
||||
import { SaveIcon } from 'lucide-react';
|
||||
|
||||
import { useReportId } from './hooks/useReportId';
|
||||
import { resetDirty } from './reportSlice';
|
||||
|
||||
export function ReportSaveButton() {
|
||||
const { reportId } = useReportId();
|
||||
const dispatch = useDispatch();
|
||||
const update = api.report.update.useMutation({
|
||||
onSuccess() {
|
||||
dispatch(resetDirty());
|
||||
toast({
|
||||
title: 'Success',
|
||||
description: 'Report updated.',
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import airplane from '@/lottie/airplane.json';
|
||||
import ballon from '@/lottie/ballon.json';
|
||||
import noData from '@/lottie/no-data.json';
|
||||
import { cn } from '@/utils/cn';
|
||||
import type { LottieComponentProps } from 'lottie-react';
|
||||
import Lottie from 'lottie-react';
|
||||
|
||||
const animations = {
|
||||
airplane,
|
||||
ballon,
|
||||
noData,
|
||||
};
|
||||
type Animations = keyof typeof animations;
|
||||
|
||||
@@ -15,3 +18,12 @@ export const ChartAnimation = ({
|
||||
}: Omit<LottieComponentProps, 'animationData'> & {
|
||||
name: Animations;
|
||||
}) => <Lottie animationData={animations[name]} loop={true} {...props} />;
|
||||
|
||||
export const ChartAnimationContainer = (
|
||||
props: React.ButtonHTMLAttributes<HTMLDivElement>
|
||||
) => (
|
||||
<div
|
||||
{...props}
|
||||
className={cn('border border-border rounded-md p-8', props.className)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useOrganizationParams } from '@/hooks/useOrganizationParams';
|
||||
import type { IChartInput } from '@/types';
|
||||
import { api } from '@/utils/api';
|
||||
|
||||
import { ChartAnimation } from './ChartAnimation';
|
||||
import { ChartAnimation, ChartAnimationContainer } from './ChartAnimation';
|
||||
import { withChartProivder } from './ChartProvider';
|
||||
import { ReportBarChart } from './ReportBarChart';
|
||||
import { ReportLineChart } from './ReportLineChart';
|
||||
@@ -45,15 +45,32 @@ export const Chart = memo(
|
||||
const anyData = Boolean(chart.data?.series?.[0]?.data);
|
||||
|
||||
if (!enabled) {
|
||||
return <p>Select events & filters to begin</p>;
|
||||
return (
|
||||
<ChartAnimationContainer>
|
||||
<ChartAnimation name="ballon" className="w-96 mx-auto" />
|
||||
<p className="text-center font-medium">
|
||||
Please select at least one event to see the chart.
|
||||
</p>
|
||||
</ChartAnimationContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (chart.isFetching) {
|
||||
return <ChartAnimation name="airplane" className="w-96 mx-auto" />;
|
||||
return (
|
||||
<ChartAnimationContainer>
|
||||
<ChartAnimation name="airplane" className="w-96 mx-auto" />
|
||||
<p className="text-center font-medium">Loading...</p>
|
||||
</ChartAnimationContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (chart.isError) {
|
||||
return <p>Error</p>;
|
||||
return (
|
||||
<ChartAnimationContainer>
|
||||
<ChartAnimation name="noData" className="w-96 mx-auto" />
|
||||
<p className="text-center font-medium">Something went wrong...</p>
|
||||
</ChartAnimationContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (!chart.isSuccess) {
|
||||
@@ -61,7 +78,12 @@ export const Chart = memo(
|
||||
}
|
||||
|
||||
if (!anyData) {
|
||||
return <ChartAnimation name="ballon" className="w-96 mx-auto" />;
|
||||
return (
|
||||
<ChartAnimationContainer>
|
||||
<ChartAnimation name="noData" className="w-96 mx-auto" />
|
||||
<p className="text-center font-medium">No data</p>
|
||||
</ChartAnimationContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (chartType === 'bar') {
|
||||
@@ -72,6 +94,13 @@ export const Chart = memo(
|
||||
return <ReportLineChart interval={interval} data={chart.data} />;
|
||||
}
|
||||
|
||||
return <p>Chart type "{chartType}" is not supported yet.</p>;
|
||||
return (
|
||||
<ChartAnimationContainer>
|
||||
<ChartAnimation name="ballon" className="w-96 mx-auto" />
|
||||
<p className="text-center font-medium">
|
||||
Chart type "{chartType}" is not supported yet.
|
||||
</p>
|
||||
</ChartAnimationContainer>
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -33,6 +33,12 @@ export const reportSlice = createSlice({
|
||||
name: 'counter',
|
||||
initialState,
|
||||
reducers: {
|
||||
resetDirty(state) {
|
||||
return {
|
||||
...state,
|
||||
dirty: false,
|
||||
};
|
||||
},
|
||||
reset() {
|
||||
return initialState;
|
||||
},
|
||||
@@ -165,6 +171,7 @@ export const {
|
||||
changeInterval,
|
||||
changeDateRanges,
|
||||
changeChartType,
|
||||
resetDirty,
|
||||
} = reportSlice.actions;
|
||||
|
||||
export default reportSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user