Format and indent AnalyticsView.vue for improved readability
This commit is contained in:
@@ -11,13 +11,26 @@
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="p-2 bg-blue-100 rounded-lg">
|
||||
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
<svg
|
||||
class="w-6 h-6 text-blue-600"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<p class="text-sm font-medium text-gray-600">System Status</p>
|
||||
<p class="text-lg font-semibold" :class="healthStatus?.status === 'healthy' ? 'text-green-600' : 'text-red-600'">
|
||||
<p
|
||||
class="text-lg font-semibold"
|
||||
:class="healthStatus?.status === 'healthy' ? 'text-green-600' : 'text-red-600'"
|
||||
>
|
||||
{{ healthStatus?.status || 'Unknown' }}
|
||||
</p>
|
||||
</div>
|
||||
@@ -27,8 +40,18 @@
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="p-2 bg-green-100 rounded-lg">
|
||||
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
|
||||
<svg
|
||||
class="w-6 h-6 text-green-600"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 10V3L4 14h7v7l9-11h-7z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
@@ -41,8 +64,18 @@
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="p-2 bg-yellow-100 rounded-lg">
|
||||
<svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
<svg
|
||||
class="w-6 h-6 text-yellow-600"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
@@ -55,13 +88,25 @@
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="p-2 bg-purple-100 rounded-lg">
|
||||
<svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
|
||||
<svg
|
||||
class="w-6 h-6 text-purple-600"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<p class="text-sm font-medium text-gray-600">Total Readings</p>
|
||||
<p class="text-lg font-semibold text-gray-900">{{ formatNumber(sensorStore.totalReadings) }}</p>
|
||||
<p class="text-lg font-semibold text-gray-900">
|
||||
{{ formatNumber(sensorStore.totalReadings) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,7 +125,11 @@
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
@@ -127,20 +176,29 @@
|
||||
No sensors found from API
|
||||
</div>
|
||||
<div v-else class="space-y-3">
|
||||
<div v-for="sensor in apiSensors" :key="sensor.sensor_id"
|
||||
class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
|
||||
<div
|
||||
v-for="sensor in apiSensors"
|
||||
:key="sensor.sensor_id"
|
||||
class="flex items-center justify-between p-3 bg-gray-50 rounded-lg"
|
||||
>
|
||||
<div>
|
||||
<p class="font-medium text-gray-900">{{ sensor.sensor_id }}</p>
|
||||
<p class="text-sm text-gray-500">{{ sensor.room || 'No room assigned' }}</p>
|
||||
<p class="text-xs text-gray-400">{{ sensor.sensor_type }} • {{ sensor.total_readings }} readings</p>
|
||||
<p class="text-xs text-gray-400">
|
||||
{{ sensor.sensor_type }} • {{ sensor.total_readings }} readings
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<span :class="[
|
||||
'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium',
|
||||
sensor.status === 'online' ? 'bg-green-100 text-green-800' :
|
||||
sensor.status === 'offline' ? 'bg-red-100 text-red-800' :
|
||||
'bg-yellow-100 text-yellow-800'
|
||||
]">
|
||||
<span
|
||||
:class="[
|
||||
'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium',
|
||||
sensor.status === 'online'
|
||||
? 'bg-green-100 text-green-800'
|
||||
: sensor.status === 'offline'
|
||||
? 'bg-red-100 text-red-800'
|
||||
: 'bg-yellow-100 text-yellow-800',
|
||||
]"
|
||||
>
|
||||
{{ sensor.status }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -159,8 +217,11 @@
|
||||
No rooms found from API
|
||||
</div>
|
||||
<div v-else class="space-y-3">
|
||||
<div v-for="room in apiRooms" :key="room.name || room.room"
|
||||
class="p-3 bg-gray-50 rounded-lg">
|
||||
<div
|
||||
v-for="room in apiRooms"
|
||||
:key="room.name || room.room"
|
||||
class="p-3 bg-gray-50 rounded-lg"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<p class="font-medium text-gray-900">{{ room.name || room.room }}</p>
|
||||
<span class="text-sm text-gray-500">{{ room.sensor_count }} sensors</span>
|
||||
@@ -169,7 +230,8 @@
|
||||
<p v-if="room.sensor_types">Types: {{ room.sensor_types.join(', ') }}</p>
|
||||
<div v-if="room.latest_metrics">
|
||||
<span v-if="room.latest_metrics.energy" class="mr-4">
|
||||
Energy: {{ room.latest_metrics.energy.current }} {{ room.latest_metrics.energy.unit }}
|
||||
Energy: {{ room.latest_metrics.energy.current }}
|
||||
{{ room.latest_metrics.energy.unit }}
|
||||
</span>
|
||||
<span v-if="room.latest_metrics.co2">
|
||||
CO2: {{ room.latest_metrics.co2.current }} {{ room.latest_metrics.co2.unit }}
|
||||
@@ -187,31 +249,53 @@
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-900 mb-4">API Actions</h2>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button @click="refreshAllData"
|
||||
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading">
|
||||
<svg v-if="!isLoading" class="-ml-1 mr-2 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
|
||||
<button
|
||||
@click="refreshAllData"
|
||||
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
<svg
|
||||
v-if="!isLoading"
|
||||
class="-ml-1 mr-2 h-4 w-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
||||
></path>
|
||||
</svg>
|
||||
<div v-else class="animate-spin -ml-1 mr-2 h-4 w-4 border-2 border-white border-t-transparent rounded-full"></div>
|
||||
<div
|
||||
v-else
|
||||
class="animate-spin -ml-1 mr-2 h-4 w-4 border-2 border-white border-t-transparent rounded-full"
|
||||
></div>
|
||||
Refresh All Data
|
||||
</button>
|
||||
|
||||
<button @click="fetchSensorsOnly"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading">
|
||||
<button
|
||||
@click="fetchSensorsOnly"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Fetch Sensors
|
||||
</button>
|
||||
|
||||
<button @click="fetchRoomsOnly"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading">
|
||||
<button
|
||||
@click="fetchRoomsOnly"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Fetch Rooms
|
||||
</button>
|
||||
|
||||
<button @click="fetchAnalyticsOnly"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading">
|
||||
<button
|
||||
@click="fetchAnalyticsOnly"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Fetch Analytics
|
||||
</button>
|
||||
</div>
|
||||
@@ -240,14 +324,15 @@ const healthStatus = computed(() => analyticsStore.healthStatus)
|
||||
|
||||
// Combined loading and error states
|
||||
const isLoading = computed(
|
||||
() => sensorStore.apiLoading || roomStore.apiLoading || analyticsStore.apiLoading
|
||||
() => sensorStore.apiLoading || roomStore.apiLoading || analyticsStore.apiLoading,
|
||||
)
|
||||
const apiError = computed(
|
||||
() => sensorStore.apiError || roomStore.apiError || analyticsStore.apiError
|
||||
() => sensorStore.apiError || roomStore.apiError || analyticsStore.apiError,
|
||||
)
|
||||
|
||||
// Helper functions
|
||||
const formatNumber = (num: number): string => {
|
||||
console.log(num)
|
||||
if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M'
|
||||
if (num >= 1000) return (num / 1000).toFixed(1) + 'K'
|
||||
return num.toString()
|
||||
@@ -279,4 +364,4 @@ const fetchAnalyticsOnly = async () => {
|
||||
onMounted(async () => {
|
||||
await refreshAllData()
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user