|
1 | 1 | <template>
|
2 |
| - <div class="tiles-container"> |
3 |
| - <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-3" style="width: 300px; height: 175px;"> |
| 2 | + <div class="tiles-container"> |
| 3 | + <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-4" |
| 4 | + style="width: 330px; height: 175px;"> |
4 | 5 | <v-card-item class="d-flex justify-center align-center">
|
5 | 6 | <div class="tiles-text">
|
6 | 7 | <div class="text-overline mb-1" style="visibility: hidden;">filler</div>
|
7 |
| - <div class="text-h6 mb-1">Total Assigned </div> |
| 8 | + <div class="text-h6 mb-1">Total Assigned </div> |
8 | 9 | <div class="text-caption">
|
9 | 10 | Currently assigned seats
|
10 | 11 | </div>
|
|
13 | 14 | </v-card-item>
|
14 | 15 | </v-card>
|
15 | 16 |
|
16 |
| - <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-3" style="width: 300px; height: 175px;"> |
| 17 | + <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-3" |
| 18 | + style="width: 300px; height: 175px;"> |
17 | 19 | <v-card-item class="d-flex justify-center align-center">
|
18 | 20 | <div class="tiles-text">
|
19 | 21 | <div class="text-overline mb-1" style="visibility: hidden;">filler</div>
|
20 | 22 | <div class="text-h6 mb-1">Assigned But Never Used</div>
|
21 | 23 | <div class="text-caption">
|
22 | 24 | No show seats
|
23 | 25 | </div>
|
24 |
| - <p class="text-h4">{{ NoshowSeats.length }}</p> |
| 26 | + <p class="text-h4">{{ noshowSeats }}</p> |
25 | 27 | </div>
|
26 | 28 | </v-card-item>
|
27 | 29 | </v-card>
|
28 |
| - <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-3" style="width: 300px; height: 175px;"> |
| 30 | + <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-4" style="width: 330px; height: 175px;"> |
29 | 31 | <v-card-item class="d-flex justify-center align-center">
|
30 | 32 | <div class="tiles-text">
|
31 | 33 | <div class="text-overline mb-1" style="visibility: hidden;">filler</div>
|
32 | 34 | <div class="text-h6 mb-1">No Activity in the Last 7 days </div>
|
33 | 35 | <div class="text-caption">
|
34 | 36 | No use in the last 7 days
|
35 | 37 | </div>
|
36 |
| - <p class="text-h4">{{ unusedSeats.length }}</p> |
| 38 | + <p class="text-h4">{{ unusedSeatsInSevenDays }}</p> |
| 39 | + </div> |
| 40 | + </v-card-item> |
| 41 | + </v-card> |
| 42 | + <v-card elevation="4" color="white" variant="elevated" class="mx-auto my-4" style="width: 330px; height: 175px;"> |
| 43 | + <v-card-item class="d-flex justify-center align-center"> |
| 44 | + <div class="tiles-text"> |
| 45 | + <div class="text-overline mb-1" style="visibility: hidden;">filler</div> |
| 46 | + <div class="text-h6 mb-1">No Activity in the Last 30 days </div> |
| 47 | + <div class="text-caption"> |
| 48 | + No use in the last 30 days |
| 49 | + </div> |
| 50 | + <p class="text-h4">{{ unusedSeatsInThirtyDays }}</p> |
37 | 51 | </div>
|
38 | 52 | </v-card-item>
|
39 | 53 | </v-card>
|
40 | 54 | </div>
|
41 |
| - |
| 55 | + |
42 | 56 | <div>
|
43 | 57 | <v-main class="p-1" style="min-height: 300px;">
|
44 | 58 | <v-container style="min-height: 300px;" class="px-4 elevation-2">
|
45 | 59 | <br>
|
46 | 60 | <h2>All assigned seats </h2>
|
47 | 61 | <br>
|
48 |
| - <v-data-table :headers="headers" :items="totalSeats" :items-per-page="10" class="elevation-2"> |
49 |
| - <template v-slot:item="{ item, index }"> |
50 |
| - <tr> |
51 |
| - <td>{{ index + 1 }}</td> |
52 |
| - <td>{{ item.login }}</td> |
53 |
| - <td>{{ item.id }}</td> |
54 |
| - <td>{{ item.team }}</td> |
55 |
| - <td>{{ item.created_at }}</td> |
56 |
| - <td>{{ item.last_activity_at }}</td> |
57 |
| - <td>{{ item.last_activity_editor }}</td> |
58 |
| - </tr> |
59 |
| - </template> |
| 62 | + <v-data-table :headers="headers" :items="totalSeats" :items-per-page="10" class="elevation-2"> |
| 63 | + <template v-slot:item="{ item, index }"> |
| 64 | + <tr> |
| 65 | + <td>{{ index + 1 }}</td> |
| 66 | + <td>{{ item.login }}</td> |
| 67 | + <td>{{ item.id }}</td> |
| 68 | + <td>{{ item.team }}</td> |
| 69 | + <td>{{ item.created_at }}</td> |
| 70 | + <td>{{ item.last_activity_at }}</td> |
| 71 | + <td>{{ item.last_activity_editor }}</td> |
| 72 | + </tr> |
| 73 | + </template> |
60 | 74 | </v-data-table>
|
61 | 75 | </v-container>
|
62 | 76 | </v-main>
|
63 | 77 | </div>
|
64 | 78 | </template>
|
65 |
| - |
| 79 | + |
66 | 80 | <script lang="ts">
|
67 |
| - import { defineComponent, ref, toRef , watchEffect } from 'vue'; |
68 |
| - import { Seat } from '../model/Seat'; |
69 |
| - import { |
| 81 | +import { defineComponent, ref, watchEffect } from 'vue'; |
| 82 | +import { Seat } from '../model/Seat'; |
| 83 | +import { |
70 | 84 | Chart as ChartJS,
|
71 | 85 | ArcElement,
|
72 | 86 | CategoryScale,
|
|
77 | 91 | Title,
|
78 | 92 | Tooltip,
|
79 | 93 | Legend
|
80 |
| - } from 'chart.js' |
| 94 | +} from 'chart.js' |
81 | 95 |
|
82 | 96 | ChartJS.register(
|
83 |
| - ArcElement, |
84 |
| - CategoryScale, |
85 |
| - LinearScale, |
86 |
| - BarElement, |
87 |
| - PointElement, |
88 |
| - LineElement, |
89 |
| - Title, |
90 |
| - Tooltip, |
91 |
| - Legend |
| 97 | + ArcElement, |
| 98 | + CategoryScale, |
| 99 | + LinearScale, |
| 100 | + BarElement, |
| 101 | + PointElement, |
| 102 | + LineElement, |
| 103 | + Title, |
| 104 | + Tooltip, |
| 105 | + Legend |
92 | 106 | )
|
93 | 107 |
|
94 | 108 | export default defineComponent({
|
95 |
| -name: 'SeatsAnalysisViewer', |
96 |
| -props: { |
| 109 | + name: 'SeatsAnalysisViewer', |
| 110 | + props: { |
97 | 111 | seats: {
|
98 | 112 | type: Array as () => Seat[],
|
99 | 113 | required: true,
|
100 |
| - default: () => [] |
| 114 | + default: () => [] |
101 | 115 | }
|
102 | 116 | },
|
103 |
| -data() { |
104 |
| - return { |
105 |
| - headers: [ |
106 |
| - { title: 'S.No', key: 'serialNumber'}, |
107 |
| - { title: 'Login', key: 'login' }, |
108 |
| - { title: 'GitHub ID', key: 'id' }, |
109 |
| - { title: 'Assigning team', key: 'team' }, |
110 |
| - { title: 'Assigned time', key: 'created_at' }, |
111 |
| - { title: 'Last Activity At', key: 'last_activity_at' }, |
112 |
| - { title: 'Last Activity Editor', key: 'last_activity_editor' }, |
113 |
| - ], |
114 |
| - }; |
115 |
| -}, |
116 |
| -setup(props) { |
117 |
| - let totalSeats = ref<Seat[]>([]); |
118 |
| - let NoshowSeats = ref<Seat[]>([]); |
119 |
| - const unusedSeats = ref<Seat[]>([]); |
| 117 | + data() { |
| 118 | + return { |
| 119 | + headers: [ |
| 120 | + { title: 'S.No', key: 'serialNumber' }, |
| 121 | + { title: 'Login', key: 'login' }, |
| 122 | + { title: 'GitHub ID', key: 'id' }, |
| 123 | + { title: 'Assigning team', key: 'team' }, |
| 124 | + { title: 'Assigned time', key: 'created_at' }, |
| 125 | + { title: 'Last Activity At', key: 'last_activity_at' }, |
| 126 | + { title: 'Last Activity Editor', key: 'last_activity_editor' }, |
| 127 | + ], |
| 128 | + }; |
| 129 | + }, |
| 130 | + setup(props) { |
| 131 | + let totalSeats = ref<Seat[]>([]); |
| 132 | + const noshowSeats = ref<number>(0); |
| 133 | + const unusedSeatsInSevenDays = ref<number>(0); |
| 134 | + const unusedSeatsInThirtyDays = ref<number>(0); |
120 | 135 |
|
121 |
| - watchEffect(() => { |
122 |
| - if (props.seats && Array.isArray(props.seats)) { |
123 |
| - totalSeats.value = props.seats; |
| 136 | + let noshowCount = 0; |
| 137 | + let unusedIn7Count = 0; |
| 138 | + let unusedIn30Count = 0; |
124 | 139 |
|
125 |
| - const oneWeekAgo = new Date(); |
126 |
| - oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); |
| 140 | + watchEffect(() => { |
| 141 | + if (props.seats && Array.isArray(props.seats)) { |
| 142 | + totalSeats.value = props.seats; |
127 | 143 |
|
128 |
| - NoshowSeats.value = props.seats.filter(seat => seat.last_activity_at == null); |
| 144 | + const oneWeekAgo = new Date(); |
| 145 | + const thirtyDaysAgo = new Date(); |
| 146 | + oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); |
| 147 | + thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); |
129 | 148 |
|
130 |
| - unusedSeats.value = totalSeats.value.filter(seat => { |
131 |
| - if (seat.last_activity_at === null) { |
132 |
| - return true; // consider to include the last activity date is null to the unused seats |
133 |
| - } |
| 149 | + props.seats.forEach(seat => { |
| 150 | + if (seat.last_activity_at === null) { |
| 151 | + noshowCount++; |
| 152 | + } else { |
| 153 | + const lastActivityDate = new Date(seat.last_activity_at); |
| 154 | + if (lastActivityDate < oneWeekAgo) { |
| 155 | + unusedIn7Count++; |
| 156 | + } |
| 157 | + if (lastActivityDate < thirtyDaysAgo) { |
| 158 | + unusedIn30Count++; |
| 159 | + } |
| 160 | + } |
| 161 | + }); |
134 | 162 |
|
135 |
| - const lastActivityDate = new Date(seat.last_activity_at); |
136 |
| - return lastActivityDate < oneWeekAgo; |
137 |
| - }); |
138 |
| - // to sort unusedSeats by last_activity_at |
139 |
| - unusedSeats.value.sort((a, b) => { |
140 |
| - if (a.last_activity_at === null) { |
141 |
| - return -1; |
142 |
| - } |
143 |
| - if (b.last_activity_at === null) { |
144 |
| - return 1; |
145 |
| - } |
146 |
| - return new Date(a.last_activity_at) > new Date(b.last_activity_at) ? 1 : -1; |
147 |
| - }); |
148 |
| - } else { |
149 |
| - throw new Error('Invalid number of seats'); |
150 |
| - } |
| 163 | + // to sort totalSeats by last_activity_at |
| 164 | + totalSeats.value.sort((a, b) => { |
| 165 | + if (a.last_activity_at === null) { |
| 166 | + return -1; |
| 167 | + } |
| 168 | + if (b.last_activity_at === null) { |
| 169 | + return 1; |
| 170 | + } |
| 171 | + return new Date(a.last_activity_at) > new Date(b.last_activity_at) ? 1 : -1; |
| 172 | + }); |
| 173 | + } else { |
| 174 | + throw new Error('Invalid number of seats'); |
| 175 | + } |
151 | 176 |
|
152 |
| - }); |
| 177 | + }); |
153 | 178 |
|
154 |
| - return { |
155 |
| - totalSeats, |
156 |
| - NoshowSeats, |
157 |
| - unusedSeats |
| 179 | + noshowSeats.value = noshowCount; |
| 180 | + unusedSeatsInSevenDays.value = unusedIn7Count; |
| 181 | + unusedSeatsInThirtyDays.value = unusedIn30Count; |
| 182 | +
|
| 183 | + return { |
| 184 | + totalSeats, |
| 185 | + noshowSeats: noshowSeats, |
| 186 | + unusedSeatsInSevenDays: unusedSeatsInSevenDays, |
| 187 | + unusedSeatsInThirtyDays: unusedSeatsInThirtyDays |
| 188 | + } |
158 | 189 | }
|
159 |
| -} |
160 |
| - |
| 190 | +
|
161 | 191 | });
|
162 | 192 | </script>
|
0 commit comments