This commit is contained in:
78
src/api.d.ts
vendored
Normal file
78
src/api.d.ts
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* This file was auto-generated by openapi-typescript.
|
||||
* Do not make direct changes to the file.
|
||||
*/
|
||||
|
||||
|
||||
export interface paths {
|
||||
"/type/{type}/startDate/{start_date}/endDate/{end_date}/sample/{sample}": {
|
||||
/** Get Sensor Data */
|
||||
get: operations["get_sensor_data_type__type__startDate__start_date__endDate__end_date__sample__sample__get"];
|
||||
};
|
||||
}
|
||||
|
||||
export type webhooks = Record<string, never>;
|
||||
|
||||
export interface components {
|
||||
schemas: {
|
||||
/** Document */
|
||||
Document: {
|
||||
/** Date */
|
||||
date: number;
|
||||
/** Value */
|
||||
value: number;
|
||||
};
|
||||
/** HTTPValidationError */
|
||||
HTTPValidationError: {
|
||||
/** Detail */
|
||||
detail?: components["schemas"]["ValidationError"][];
|
||||
};
|
||||
/** ValidationError */
|
||||
ValidationError: {
|
||||
/** Location */
|
||||
loc: (string | number)[];
|
||||
/** Message */
|
||||
msg: string;
|
||||
/** Error Type */
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
responses: never;
|
||||
parameters: never;
|
||||
requestBodies: never;
|
||||
headers: never;
|
||||
pathItems: never;
|
||||
}
|
||||
|
||||
export type $defs = Record<string, never>;
|
||||
|
||||
export type external = Record<string, never>;
|
||||
|
||||
export interface operations {
|
||||
|
||||
/** Get Sensor Data */
|
||||
get_sensor_data_type__type__startDate__start_date__endDate__end_date__sample__sample__get: {
|
||||
parameters: {
|
||||
path: {
|
||||
type: "temperature" | "humidity";
|
||||
start_date: number;
|
||||
end_date: number;
|
||||
sample: number;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["Document"][];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
<template>
|
||||
<div class="chart-container">
|
||||
<Loader v-if="loading"></Loader>
|
||||
<Loader v-if="isLoading"></Loader>
|
||||
<div class="chart" id="chart" ref="chart" v-else></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import * as Highcharts from 'highcharts'
|
||||
import 'highcharts/css/highcharts.scss'
|
||||
import Loader from '@/components/Loader.vue'
|
||||
import { capitalizeFirstLetter } from '@/utils/helpers'
|
||||
import type { Window, NavType } from '@/utils/types'
|
||||
import { typeApi } from '@/utils/types'
|
||||
import { useFetch } from '@vueuse/core'
|
||||
import type { Window, NavTypes } from '@/utils/types'
|
||||
import { useApi } from '@/composables/api'
|
||||
|
||||
Highcharts.setOptions({
|
||||
time: {
|
||||
@@ -22,26 +21,12 @@ Highcharts.setOptions({
|
||||
|
||||
const props = defineProps<{
|
||||
activeWindow: Window
|
||||
activeType: NavType | undefined
|
||||
activeType: NavTypes | undefined
|
||||
}>()
|
||||
|
||||
const chart = ref<HTMLElement | null>(null)
|
||||
|
||||
const fetchUrl = computed(() => {
|
||||
const [start, end] = [props.activeWindow.getStart(), props.activeWindow.getEnd()]
|
||||
const sample = Math.round((end - start) / 60 / 288) || 1
|
||||
const host = import.meta.env.MODE === 'development' ? 'http://localhost:3000' : ''
|
||||
const fetchUrl = `${host}/type/${
|
||||
typeApi[props.activeType || 'temperatuur']
|
||||
}/startDate/${start}/endDate/${end}/sample/${sample}`
|
||||
return fetchUrl
|
||||
})
|
||||
|
||||
interface ChartDataPoint {
|
||||
date: Number
|
||||
value: Number
|
||||
}
|
||||
const { data: chartData, isFetching: loading } = useFetch(fetchUrl, { refetch: true }).json<ChartDataPoint[]>()
|
||||
const { chartData, isLoading } = useApi(props)
|
||||
|
||||
watch([chart, chartData], () => {
|
||||
if (chart.value && chartData.value) renderChart()
|
||||
|
||||
@@ -15,11 +15,13 @@ import NavBar from '@/components/NavBar.vue'
|
||||
import TimeWindows from '@/components/TimeWindows.vue'
|
||||
import Chart from '@/components/Chart.vue'
|
||||
import { windows } from '@/utils/helpers'
|
||||
import type { Window, NavType } from '@/utils/types'
|
||||
import type { Window, NavTypes } from '@/utils/types'
|
||||
import { navTypes } from '@/utils/types'
|
||||
|
||||
const defaultWindow = windows[1]
|
||||
const defaultType = navTypes[0]
|
||||
|
||||
const activeType = ref<NavType>()
|
||||
const activeType = ref<NavTypes>()
|
||||
const activeWindow = ref<Window>(defaultWindow)
|
||||
|
||||
const router = useRouter()
|
||||
@@ -27,9 +29,10 @@ const route = useRoute()
|
||||
|
||||
const urlEncodeWindow = (label: string) => label.replace(' ', '-')
|
||||
|
||||
if (route.params.type) activeType.value = route.params.type as NavType
|
||||
if (route.params.type)
|
||||
// activeType.value = (navTypes.includes(route.params.type.toString()) ? route.params.type : navTypes[0]) as NavTypes
|
||||
activeType.value = (navTypes.find((t) => t === route.params.type) || defaultType) as NavTypes
|
||||
if (route.params.window) {
|
||||
console.log(route.params.window, windows)
|
||||
activeWindow.value = windows.find((w) => urlEncodeWindow(w.label) === route.params.window) || defaultWindow
|
||||
}
|
||||
|
||||
|
||||
@@ -34,17 +34,17 @@
|
||||
<script setup lang="ts">
|
||||
import { capitalizeFirstLetter } from '@/utils/helpers'
|
||||
import { ref } from 'vue'
|
||||
import type { NavType } from '@/utils/types'
|
||||
import type { NavTypes } from '@/utils/types'
|
||||
|
||||
const activeType = defineModel<NavType>()
|
||||
const activeType = defineModel<NavTypes>()
|
||||
|
||||
const setType = (type: NavType) => {
|
||||
const setType = (type: NavTypes) => {
|
||||
toggled.value = false
|
||||
activeType.value = type
|
||||
}
|
||||
|
||||
const toggled = ref(false)
|
||||
const navTypes: NavType[] = ['temperatuur', 'luchtvochtigheid']
|
||||
const navTypes: NavTypes[] = ['temperatuur', 'luchtvochtigheid']
|
||||
if (!activeType.value) setType(navTypes[0])
|
||||
const toggleMenu = () => (toggled.value = !toggled.value)
|
||||
</script>
|
||||
|
||||
56
src/composables/api.ts
Normal file
56
src/composables/api.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import createClient from 'openapi-fetch'
|
||||
import { navTypeToApiTypeMapping } from '@/utils/types'
|
||||
import type { Window, NavTypes } from '@/utils/types'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import type { paths } from '@/api'
|
||||
|
||||
type Props = {
|
||||
activeWindow: Window
|
||||
activeType: NavTypes | undefined
|
||||
}
|
||||
|
||||
type ApiParameters =
|
||||
paths['/type/{type}/startDate/{start_date}/endDate/{end_date}/sample/{sample}']['get']['parameters']['path']
|
||||
|
||||
type ApiResponse =
|
||||
paths['/type/{type}/startDate/{start_date}/endDate/{end_date}/sample/{sample}']['get']['responses']['200']['content']['application/json']
|
||||
|
||||
type ApiError =
|
||||
paths['/type/{type}/startDate/{start_date}/endDate/{end_date}/sample/{sample}']['get']['responses']['422']['content']['application/json']
|
||||
|
||||
export function useApi(props: Props) {
|
||||
const client = createClient<paths>({ baseUrl: import.meta.env.MODE === 'development' ? 'http://localhost:3000' : '' })
|
||||
|
||||
const chartData = ref<ApiResponse | null>(null)
|
||||
const chartError = ref<ApiError | null>(null)
|
||||
const isLoading = ref(false)
|
||||
|
||||
const apiParameters = computed<ApiParameters>(() => {
|
||||
const [start_date, end_date] = [props.activeWindow.getStart(), props.activeWindow.getEnd()]
|
||||
|
||||
return {
|
||||
type: navTypeToApiTypeMapping[props.activeType || 'temperatuur'],
|
||||
start_date,
|
||||
end_date,
|
||||
sample: Math.round((start_date - end_date) / 60 / 288) || 1
|
||||
}
|
||||
})
|
||||
|
||||
const getData = async () => {
|
||||
isLoading.value = true
|
||||
const { data } = await client.GET('/type/{type}/startDate/{start_date}/endDate/{end_date}/sample/{sample}', {
|
||||
params: { path: apiParameters.value }
|
||||
})
|
||||
if (data) chartData.value = data
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
watch([() => [props.activeType, props.activeWindow]], () => getData(), { immediate: true })
|
||||
|
||||
return {
|
||||
chartData,
|
||||
chartError,
|
||||
isLoading
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { paths } from '@/api'
|
||||
|
||||
export interface Window {
|
||||
label: string
|
||||
getStart: { (): number }
|
||||
@@ -6,9 +8,18 @@ export interface Window {
|
||||
interval: number
|
||||
}
|
||||
|
||||
export const typeApi = {
|
||||
export type ApiTypes =
|
||||
paths['/type/{type}/startDate/{start_date}/endDate/{end_date}/sample/{sample}']['get']['parameters']['path']['type']
|
||||
|
||||
export type NavTypes = 'temperatuur' | 'luchtvochtigheid'
|
||||
|
||||
type NavTypeToApiTypeMapping = {
|
||||
[key in NavTypes]: ApiTypes
|
||||
}
|
||||
|
||||
export const navTypeToApiTypeMapping: NavTypeToApiTypeMapping = {
|
||||
temperatuur: 'temperature',
|
||||
luchtvochtigheid: 'humidity'
|
||||
}
|
||||
|
||||
export type NavType = keyof typeof typeApi
|
||||
export const navTypes = Object.keys(navTypeToApiTypeMapping)
|
||||
|
||||
Reference in New Issue
Block a user