Skip to content

Commit 3474b84

Browse files
CopilotkarpikplCopilot
authored
Add option to exclude holidays from copilot metrics (#234)
* Initial plan * Initial exploration and planning for holiday exclusion feature Co-authored-by: karpikpl <[email protected]> * Add holiday exclusion feature with date-holidays integration Co-authored-by: karpikpl <[email protected]> * Fix linting issues and complete holiday exclusion feature Co-authored-by: karpikpl <[email protected]> * Add UI controls for holiday exclusion in DateRangeSelector Co-authored-by: karpikpl <[email protected]> * fixes to holidays features * Update tests/weekends-filtering.spec.ts Co-authored-by: Copilot <[email protected]> * Update app/components/DateRangeSelector.vue Co-authored-by: Copilot <[email protected]> * code review updates --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: karpikpl <[email protected]> Co-authored-by: Piotr Karpala <[email protected]> Co-authored-by: Piotr Karpala <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent b8a6f3f commit 3474b84

15 files changed

+571
-73
lines changed

app/components/CopilotChatViewer.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<div class="tiles-text">
66
<div class="spacing-25"/>
77
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
8-
<template v-slot:activator="{ props }">
8+
<template #activator="{ props }">
99
<div v-bind="props" class="text-h6 mb-1">Cumulative Number of Turns</div>
1010
</template>
1111
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -23,7 +23,7 @@
2323
<div class="tiles-text">
2424
<div class="spacing-10"/>
2525
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
26-
<template v-slot:activator="{ props }">
26+
<template #activator="{ props }">
2727
<div v-bind="props" class="text-h6 mb-1">Cumulative Number of Acceptances</div>
2828
</template>
2929
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -41,7 +41,7 @@
4141
<v-container style="min-height: 300px;" class="px-4 elevation-2">
4242

4343
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
44-
<template v-slot:activator="{ props }">
44+
<template #activator="{ props }">
4545
<h2 v-bind="props" class="mb-1">Total Acceptances | Total Turns Count</h2>
4646
</template>
4747
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -51,7 +51,7 @@
5151
<Line :data="totalNumberAcceptancesAndTurnsChartData" :options="chartOptions" />
5252

5353
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
54-
<template v-slot:activator="{ props }">
54+
<template #activator="{ props }">
5555
<h2 v-bind="props" class="mb-1">Total Active Copilot Chat Users</h2>
5656
</template>
5757
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">

app/components/DateRangeSelector.vue

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<v-card class="pa-4 ma-4" elevation="2">
33
<v-card-title class="text-h6 pb-2">Date Range Filter</v-card-title>
44
<v-row align="end">
5-
<v-col cols="12" sm="4">
5+
<v-col cols="6" sm="3">
66
<v-text-field
77
v-model="fromDate"
88
label="From Date"
@@ -12,7 +12,7 @@
1212
@update:model-value="updateDateRange"
1313
/>
1414
</v-col>
15-
<v-col cols="12" sm="4">
15+
<v-col cols="6" sm="3">
1616
<v-text-field
1717
v-model="toDate"
1818
label="To Date"
@@ -22,7 +22,14 @@
2222
@update:model-value="updateDateRange"
2323
/>
2424
</v-col>
25-
<v-col cols="12" sm="4" class="d-flex align-center justify-start" style="padding-bottom: 35px;">
25+
<v-col cols="6" sm="2">
26+
<v-checkbox
27+
v-model="excludeHolidays"
28+
label="Exclude holidays from metrics"
29+
density="compact"
30+
/>
31+
</v-col>
32+
<v-col cols="6" sm="4" class="d-flex align-center justify-start" style="padding-bottom: 35px;">
2633
<v-btn
2734
color="primary"
2835
variant="outlined"
@@ -42,6 +49,8 @@
4249
</v-btn>
4350
</v-col>
4451
</v-row>
52+
53+
4554
<v-card-text class="pt-2">
4655
<span class="text-caption text-medium-emphasis">
4756
{{ dateRangeText }}
@@ -51,12 +60,19 @@
5160
</template>
5261

5362
<script setup lang="ts">
63+
import { ref } from 'vue'
64+
5465
interface Props {
5566
loading?: boolean
5667
}
5768
5869
interface Emits {
59-
(e: 'date-range-changed', value: { since?: string; until?: string; description: string }): void
70+
(e: 'date-range-changed', value: {
71+
since?: string;
72+
until?: string;
73+
description: string;
74+
excludeHolidays?: boolean;
75+
}): void
6076
}
6177
6278
withDefaults(defineProps<Props>(), {
@@ -71,6 +87,8 @@ const defaultFromDate = new Date(today.getTime() - 27 * 24 * 60 * 60 * 1000) //
7187
7288
const fromDate = ref(formatDate(defaultFromDate))
7389
const toDate = ref(formatDate(today))
90+
const excludeHolidays = ref(false)
91+
7492
7593
function formatDate(date: Date): string {
7694
return date.toISOString().split('T')[0] || ''
@@ -141,11 +159,12 @@ function applyDateRange() {
141159
toDate.value = temp
142160
}
143161
144-
// Emit the date range change
162+
// Emit the date range change with holiday options
145163
emit('date-range-changed', {
146164
since: fromDate.value,
147165
until: toDate.value,
148-
description: dateRangeText.value
166+
description: dateRangeText.value,
167+
excludeHolidays: excludeHolidays.value,
149168
})
150169
}
151170

app/components/MainComponent.vue

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
</v-toolbar>
3636

3737
<!-- Date Range Selector - Hidden for seats tab -->
38-
<DateRangeSelector v-show="tab !== 'seat analysis' && !signInRequired" :loading="isLoading"
38+
<DateRangeSelector
39+
v-show="tab !== 'seat analysis' && !signInRequired" :loading="isLoading"
3940
@date-range-changed="handleDateRangeChange" />
4041

4142
<!-- Organization info for seats tab -->
@@ -69,14 +70,18 @@
6970
<v-window-item v-for="item in tabItems" :key="item" :value="item">
7071
<v-card flat>
7172
<MetricsViewer v-if="item === itemName" :metrics="metrics" :date-range-description="dateRangeDescription" />
72-
<BreakdownComponent v-if="item === 'languages'" :metrics="metrics" :breakdown-key="'language'"
73+
<BreakdownComponent
74+
v-if="item === 'languages'" :metrics="metrics" :breakdown-key="'language'"
7375
:date-range-description="dateRangeDescription" />
74-
<BreakdownComponent v-if="item === 'editors'" :metrics="metrics" :breakdown-key="'editor'"
76+
<BreakdownComponent
77+
v-if="item === 'editors'" :metrics="metrics" :breakdown-key="'editor'"
7578
:date-range-description="dateRangeDescription" />
76-
<CopilotChatViewer v-if="item === 'copilot chat'" :metrics="metrics"
79+
<CopilotChatViewer
80+
v-if="item === 'copilot chat'" :metrics="metrics"
7781
:date-range-description="dateRangeDescription" />
7882
<SeatsAnalysisViewer v-if="item === 'seat analysis'" :seats="seats" />
79-
<ApiResponse v-if="item === 'api response'" :metrics="metrics" :original-metrics="originalMetrics"
83+
<ApiResponse
84+
v-if="item === 'api response'" :metrics="metrics" :original-metrics="originalMetrics"
8085
:seats="seats" />
8186
</v-card>
8287
</v-window-item>
@@ -123,13 +128,23 @@ export default defineNuxtComponent({
123128
this.seats = [];
124129
clear();
125130
},
126-
async handleDateRangeChange(newDateRange: { since?: string; until?: string; description: string }) {
131+
async handleDateRangeChange(newDateRange: {
132+
since?: string;
133+
until?: string;
134+
description: string;
135+
excludeHolidays?: boolean;
136+
}) {
127137
this.dateRangeDescription = newDateRange.description;
128138
this.dateRange = {
129139
since: newDateRange.since,
130140
until: newDateRange.until
131141
};
132142
143+
// Store holiday options
144+
this.holidayOptions = {
145+
excludeHolidays: newDateRange.excludeHolidays,
146+
};
147+
133148
await this.fetchMetrics();
134149
},
135150
async fetchMetrics() {
@@ -142,6 +157,12 @@ export default defineNuxtComponent({
142157
143158
try {
144159
const options = Options.fromRoute(this.route, this.dateRange.since, this.dateRange.until);
160+
161+
// Add holiday options if they're set
162+
if (this.holidayOptions?.excludeHolidays) {
163+
options.excludeHolidays = this.holidayOptions.excludeHolidays;
164+
}
165+
145166
const params = options.toParams();
146167
147168
const queryString = new URLSearchParams(params).toString();
@@ -200,7 +221,10 @@ export default defineNuxtComponent({
200221
seatsReady: false,
201222
seats: [] as Seat[],
202223
apiError: undefined as string | undefined,
203-
config: null as ReturnType<typeof useRuntimeConfig> | null
224+
config: null as ReturnType<typeof useRuntimeConfig> | null,
225+
holidayOptions: {
226+
excludeHolidays: false,
227+
}
204228
}
205229
},
206230
created() {

app/components/MetricsViewer.vue

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<div class="tiles-text">
99
<div class="spacing-25"/>
1010
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
11-
<template v-slot:activator="{ props }">
11+
<template #activator="{ props }">
1212
<div v-bind="props" class="text-h6 mb-1">Acceptance Rate (by count)</div>
1313
</template>
1414
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -28,7 +28,7 @@
2828
<div class="tiles-text">
2929
<div class="spacing-10"/>
3030
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
31-
<template v-slot:activator="{ props }">
31+
<template #activator="{ props }">
3232
<div v-bind="props" class="text-h6 mb-1">Total count of Suggestions (Prompts)</div>
3333
</template>
3434
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -48,7 +48,7 @@
4848
<div class="spacing-25"/>
4949
<div class="tiles-text">
5050
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
51-
<template v-slot:activator="{ props }">
51+
<template #activator="{ props }">
5252
<div v-bind="props" class="text-h6 mb-1">Acceptance Rate (by lines)</div>
5353
</template>
5454
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -68,7 +68,7 @@
6868
<div class="tiles-text">
6969
<div class="spacing-10"/>
7070
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
71-
<template v-slot:activator="{ props }">
71+
<template #activator="{ props }">
7272
<div v-bind="props" class="text-h6 mb-1">Total Lines of code Suggested</div>
7373
</template>
7474
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -88,7 +88,7 @@
8888

8989
<v-container style="min-height: 300px;" class="px-4 elevation-2">
9090
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
91-
<template v-slot:activator="{ props }">
91+
<template #activator="{ props }">
9292
<h2 v-bind="props">Acceptance rate by count (%)</h2>
9393
</template>
9494
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -98,7 +98,7 @@
9898
<Bar :data="acceptanceRateByCountChartData" :options="chartOptions" />
9999

100100
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
101-
<template v-slot:activator="{ props }">
101+
<template #activator="{ props }">
102102
<h2 v-bind="props" class="mb-1">Total Suggestions Count | Total Acceptances Count</h2>
103103
</template>
104104
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -108,7 +108,7 @@
108108
<Line :data="totalSuggestionsAndAcceptanceChartData" :options="chartOptions" />
109109

110110
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
111-
<template v-slot:activator="{ props }">
111+
<template #activator="{ props }">
112112
<h2 v-bind="props">Acceptance rate by lines (%)</h2>
113113
</template>
114114
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -118,7 +118,7 @@
118118
<Bar :data="acceptanceRateByLinesChartData" :options="chartOptions" />
119119

120120
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
121-
<template v-slot:activator="{ props }">
121+
<template #activator="{ props }">
122122
<h2 v-bind="props" class="mb-1">Total Lines Suggested | Total Lines Accepted</h2>
123123
</template>
124124
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -128,7 +128,7 @@
128128
<Line :data="chartData" :options="chartOptions" />
129129

130130
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
131-
<template v-slot:activator="{ props }">
131+
<template #activator="{ props }">
132132
<h2 v-bind="props" class="mb-1">Total Active Users</h2>
133133
</template>
134134
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">

app/components/SeatsAnalysisViewer.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ elevation="4" color="white" variant="elevated" class="mx-auto my-4"
77
<div class="tiles-text">
88
<div class="text-overline mb-1" style="visibility: hidden;">filler</div>
99
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
10-
<template v-slot:activator="{ props }">
10+
<template #activator="{ props }">
1111
<div v-bind="props" class="text-h6 mb-1">Total Assigned </div>
1212
</template>
1313
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -29,7 +29,7 @@ elevation="4" color="white" variant="elevated" class="mx-auto my-3"
2929
<div class="tiles-text">
3030
<div class="text-overline mb-1" style="visibility: hidden;">filler</div>
3131
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
32-
<template v-slot:activator="{ props }">
32+
<template #activator="{ props }">
3333
<div v-bind="props" class="text-h6 mb-1">Assigned But Never Used</div>
3434
</template>
3535
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -48,7 +48,7 @@ elevation="4" color="white" variant="elevated" class="mx-auto my-3"
4848
<div class="tiles-text">
4949
<div class="text-overline mb-1" style="visibility: hidden;">filler</div>
5050
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
51-
<template v-slot:activator="{ props }">
51+
<template #activator="{ props }">
5252
<div v-bind="props" class="text-h6 mb-1">No Activity in the Last 7 days </div>
5353
</template>
5454
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -67,7 +67,7 @@ elevation="4" color="white" variant="elevated" class="mx-auto my-3"
6767
<div class="tiles-text">
6868
<div class="text-overline mb-1" style="visibility: hidden;">filler</div>
6969
<v-tooltip location="bottom start" open-on-hover open-delay="200" close-delay="200">
70-
<template v-slot:activator="{ props }">
70+
<template #activator="{ props }">
7171
<div v-bind="props" class="text-h6 mb-1">No Activity in the Last 30 days </div>
7272
</template>
7373
<v-card class="pa-2" style="background-color: #f0f0f0; max-width: 350px;">
@@ -164,7 +164,7 @@ setup(props) {
164164
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
165165
166166
props.seats.forEach(seat => {
167-
if(!Boolean(seat.last_activity_at)) {
167+
if(!seat.last_activity_at) {
168168
noshowCount++;
169169
} else {
170170
const lastActivityDate = new Date(seat.last_activity_at);

0 commit comments

Comments
 (0)