Skip to content

Commit b82ab17

Browse files
committed
[ui] Add interval selector components
Creates an IntervalSelector component to handle set and custom schedule intervals. Signed-off-by: Eva Millán <[email protected]>
1 parent 2e6fd19 commit b82ab17

File tree

4 files changed

+141
-1
lines changed

4 files changed

+141
-1
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<template>
2+
<div>
3+
<v-btn-toggle
4+
:model-value="selected"
5+
:density
6+
mandatory
7+
shaped
8+
divided
9+
variant="outlined"
10+
base-color="#898B8E"
11+
height="40"
12+
block
13+
@update:model-value="handleToggle"
14+
>
15+
<v-btn class="text-subtitle-2 text-medium-emphasis" color="primary" value="86400">
16+
Daily
17+
</v-btn>
18+
<v-btn class="text-subtitle-2 text-medium-emphasis" color="primary" value="604800">
19+
Weekly
20+
</v-btn>
21+
<v-btn class="text-subtitle-2 text-medium-emphasis" color="primary" value="2629746">
22+
Monthly
23+
</v-btn>
24+
<v-btn
25+
class="text-subtitle-2 text-medium-emphasis"
26+
color="primary"
27+
value="custom"
28+
data-test="selector-custom"
29+
>
30+
Custom interval
31+
</v-btn>
32+
</v-btn-toggle>
33+
<div v-if="selected == 'custom'" class="pt-3 reduced-input">
34+
<v-text-field
35+
v-model="custom"
36+
:density
37+
data-test="input"
38+
label="Every"
39+
variant="outlined"
40+
hide-details
41+
@update:model-value="handleInput"
42+
>
43+
<template #append-inner>
44+
<span class="text-medium-emphasis">seconds</span>
45+
</template>
46+
</v-text-field>
47+
</div>
48+
</div>
49+
</template>
50+
<script>
51+
export default {
52+
name: 'IntervalSelector',
53+
emits: ['update:model-value'],
54+
props: {
55+
modelValue: {
56+
type: [String, Number],
57+
required: false,
58+
default: ''
59+
},
60+
density: {
61+
type: String,
62+
required: false,
63+
default: 'compact'
64+
}
65+
},
66+
data() {
67+
return {
68+
selected: this.modelValue,
69+
custom: ''
70+
}
71+
},
72+
methods: {
73+
handleToggle(event) {
74+
const value = event === 'custom' ? this.custom : event
75+
this.selected = event
76+
this.$emit('update:model-value', value)
77+
},
78+
handleInput(event) {
79+
if (this.selected === 'custom') {
80+
this.$emit('update:model-value', event)
81+
}
82+
}
83+
}
84+
}
85+
</script>
86+
<style lang="scss" scoped>
87+
.reduced-input {
88+
max-width: 366px;
89+
}
90+
</style>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import IntervalSelector from '@/components/IntervalSelector.vue'
2+
3+
export default {
4+
title: 'Components/IntervalSelector',
5+
component: IntervalSelector,
6+
tags: ['autodocs'],
7+
argTypes: {
8+
density: {
9+
control: { type: 'select' },
10+
options: ['compact', 'comfortable', 'default']
11+
}
12+
}
13+
}
14+
15+
export const Default = {
16+
args: {
17+
density: 'compact',
18+
modelValue: '604800'
19+
}
20+
}
21+
22+
export const CustomInterval = {
23+
args: {
24+
density: 'compact',
25+
modelValue: 'custom'
26+
}
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import IntervalSelector from '@/components/IntervalSelector.vue'
2+
import vuetify from '@/plugins/vuetify'
3+
import { describe, expect, test } from 'vitest'
4+
import { mount } from '@vue/test-utils'
5+
6+
describe('components/IntervalSelector', () => {
7+
test('Emits custom value', async () => {
8+
const wrapper = mount(IntervalSelector, {
9+
global: {
10+
plugins: [vuetify]
11+
}
12+
})
13+
14+
await wrapper.get('[data-test="selector-custom"]').trigger('click')
15+
16+
expect(wrapper.get('[data-test="input"]').isVisible()).toBe(true)
17+
18+
wrapper.get('[data-test="input"] input').setValue('1234')
19+
20+
expect(wrapper.emitted('update:model-value')[1]).toEqual(['1234'])
21+
})
22+
})

ui/vitest.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export default mergeConfig(
88
test: {
99
environment: 'jsdom',
1010
exclude: [...configDefaults.exclude, 'e2e/*'],
11-
root: fileURLToPath(new URL('./', import.meta.url))
11+
root: fileURLToPath(new URL('./', import.meta.url)),
12+
pool: 'vmThreads'
1213
}
1314
})
1415
)

0 commit comments

Comments
 (0)