mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-13 18:52:14 +01:00
add format check, update prettier rules, apply rules consistently
This commit is contained in:
@@ -34,8 +34,7 @@ const iconSizeClasses = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const iconSizeWrapperClasses =
|
||||
props.size === 'small' ? 'w-6 sm:w-8 h-6 sm:h-8' : 'w-10 h-10';
|
||||
const iconSizeWrapperClasses = props.size === 'small' ? 'w-6 sm:w-8 h-6 sm:h-8' : 'w-10 h-10';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import {
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/packages/ui/src/utils/time';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/Components/ui/popover';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/Components/ui/popover';
|
||||
import { Button } from '@/Components/ui/button';
|
||||
import { RangeCalendar } from '@/Components/ui/range-calendar';
|
||||
import { CalendarDate } from '@internationalized/date';
|
||||
import { CalendarIcon } from 'lucide-vue-next';
|
||||
import { computed, ref, inject, type ComputedRef, watch } from 'vue';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import {
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/packages/ui/src/utils/time';
|
||||
import { type Organization } from '@/packages/api/src';
|
||||
import { getUserTimezone } from '@/packages/ui/src/utils/settings';
|
||||
import { formatDate } from '@/packages/ui/src/utils/time';
|
||||
@@ -72,128 +65,68 @@ const modelValue = computed<CalendarDateRange>({
|
||||
const open = ref(false);
|
||||
|
||||
function setToday() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().startOf('day').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().startOf('day').format());
|
||||
emit('update:end', getLocalizedDayJs().endOf('day').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setThisWeek() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().startOf('week').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().startOf('week').format());
|
||||
emit('update:end', getLocalizedDayJs().endOf('week').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLastWeek() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs()
|
||||
.subtract(1, 'week')
|
||||
.startOf('week')
|
||||
.format()
|
||||
);
|
||||
emit(
|
||||
'update:end',
|
||||
getLocalizedDayJs()
|
||||
.subtract(1, 'week')
|
||||
.endOf('week')
|
||||
.format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().subtract(1, 'week').startOf('week').format());
|
||||
emit('update:end', getLocalizedDayJs().subtract(1, 'week').endOf('week').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLast14Days() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().subtract(14, 'days').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().subtract(14, 'days').format());
|
||||
emit('update:end', getLocalizedDayJs().format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setThisMonth() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().startOf('month').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().startOf('month').format());
|
||||
emit('update:end', getLocalizedDayJs().endOf('month').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLastMonth() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs()
|
||||
.subtract(1, 'month')
|
||||
.startOf('month')
|
||||
.format()
|
||||
);
|
||||
emit(
|
||||
'update:end',
|
||||
getLocalizedDayJs()
|
||||
.subtract(1, 'month')
|
||||
.endOf('month')
|
||||
.format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().subtract(1, 'month').startOf('month').format());
|
||||
emit('update:end', getLocalizedDayJs().subtract(1, 'month').endOf('month').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLast30Days() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().subtract(30, 'days').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().subtract(30, 'days').format());
|
||||
emit('update:end', getLocalizedDayJs().format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLast90Days() {
|
||||
emit(
|
||||
'update:start',
|
||||
getDayJsInstance()().subtract(90, 'days').format()
|
||||
);
|
||||
emit('update:start', getDayJsInstance()().subtract(90, 'days').format());
|
||||
emit('update:end', getDayJsInstance()().format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLast12Months() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().subtract(12, 'months').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().subtract(12, 'months').format());
|
||||
emit('update:end', getLocalizedDayJs().format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setThisYear() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs().startOf('year').format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().startOf('year').format());
|
||||
emit('update:end', getLocalizedDayJs().endOf('year').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
function setLastYear() {
|
||||
emit(
|
||||
'update:start',
|
||||
getLocalizedDayJs()
|
||||
.subtract(1, 'year')
|
||||
.startOf('year')
|
||||
.format()
|
||||
);
|
||||
emit(
|
||||
'update:end',
|
||||
getLocalizedDayJs()
|
||||
.subtract(1, 'year')
|
||||
.endOf('year')
|
||||
.format()
|
||||
);
|
||||
emit('update:start', getLocalizedDayJs().subtract(1, 'year').startOf('year').format());
|
||||
emit('update:end', getLocalizedDayJs().subtract(1, 'year').endOf('year').format());
|
||||
open.value = false;
|
||||
}
|
||||
|
||||
@@ -220,27 +153,12 @@ watch(open, (value) => {
|
||||
<CalendarIcon class="-ml-0.5 text-text-quaternary h-4 w-4" />
|
||||
<template v-if="modelValue.start">
|
||||
<template v-if="modelValue.end">
|
||||
{{
|
||||
formatDate(
|
||||
modelValue.start.toString(),
|
||||
organization?.date_format
|
||||
)
|
||||
}}
|
||||
{{ formatDate(modelValue.start.toString(), organization?.date_format) }}
|
||||
-
|
||||
{{
|
||||
formatDate(
|
||||
modelValue.end.toString(),
|
||||
organization?.date_format
|
||||
)
|
||||
}}
|
||||
{{ formatDate(modelValue.end.toString(), organization?.date_format) }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{
|
||||
formatDate(
|
||||
modelValue.start.toString(),
|
||||
organization?.date_format
|
||||
)
|
||||
}}
|
||||
{{ formatDate(modelValue.start.toString(), organization?.date_format) }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else> Pick a date </template>
|
||||
@@ -250,17 +168,39 @@ watch(open, (value) => {
|
||||
<div class="flex divide-x divide-border-secondary">
|
||||
<div
|
||||
class="text-text-primary text-sm flex flex-col space-y-0.5 items-start py-2 px-2">
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setToday">Today</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setThisWeek">This Week</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLastWeek">Last Week</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast14Days">Last 14 days</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setThisMonth">This Month</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLastMonth">Last Month</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast30Days">Last 30 days</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast90Days">Last 90 days</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast12Months">Last 12 months</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setThisYear">This year</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLastYear">Last year</Button>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setToday"
|
||||
>Today</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setThisWeek"
|
||||
>This Week</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLastWeek"
|
||||
>Last Week</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast14Days"
|
||||
>Last 14 days</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setThisMonth"
|
||||
>This Month</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLastMonth"
|
||||
>Last Month</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast30Days"
|
||||
>Last 30 days</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast90Days"
|
||||
>Last 90 days</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLast12Months"
|
||||
>Last 12 months</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setThisYear"
|
||||
>This year</Button
|
||||
>
|
||||
<Button variant="ghost" size="sm" class="justify-start" @click="setLastYear"
|
||||
>Last year</Button
|
||||
>
|
||||
</div>
|
||||
<div class="pl-2">
|
||||
<RangeCalendar
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/Components/ui/popover';
|
||||
import { watch } from "vue";
|
||||
import { watch } from 'vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -42,7 +42,6 @@ watch(open, (value) => {
|
||||
emit('submit');
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import parse from 'parse-duration';
|
||||
import { onMounted, ref, watch, inject } from 'vue';
|
||||
import {
|
||||
formatHumanReadableDuration,
|
||||
getDayJsInstance,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { formatHumanReadableDuration, getDayJsInstance } from '@/packages/ui/src/utils/time';
|
||||
import dayjs from 'dayjs';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { TextInput } from '@/packages/ui/src';
|
||||
|
||||
@@ -61,8 +61,7 @@ function updateAndSubmit() {
|
||||
@blur="updateDuration"
|
||||
@keydown.enter="updateAndSubmit">
|
||||
</TextInput>
|
||||
<div
|
||||
class="absolute top-0 right-0 h-full flex items-center px-4 font-medium">
|
||||
<div class="absolute top-0 right-0 h-full flex items-center px-4 font-medium">
|
||||
<span> hours </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,8 +8,7 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label
|
||||
:class="twMerge('block font-medium text-sm text-text-primary', props.class)">
|
||||
<label :class="twMerge('block font-medium text-sm text-text-primary', props.class)">
|
||||
<span v-if="value">{{ value }}</span>
|
||||
<span v-else><slot /></span>
|
||||
</label>
|
||||
|
||||
@@ -44,17 +44,13 @@ watch(open, (isOpen) => {
|
||||
const aIsSelected = model.value.includes(props.getKeyFromItem(a));
|
||||
const bIsSelected = model.value.includes(props.getKeyFromItem(b));
|
||||
if (aIsSelected === bIsSelected) {
|
||||
return props
|
||||
.getNameForItem(a)
|
||||
.localeCompare(props.getNameForItem(b));
|
||||
return props.getNameForItem(a).localeCompare(props.getNameForItem(b));
|
||||
}
|
||||
return model.value.includes(props.getKeyFromItem(a)) ? -1 : 1;
|
||||
});
|
||||
nextTick(() => {
|
||||
if (filteredItems.value.length > 0) {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[0]
|
||||
);
|
||||
highlightedItemId.value = props.getKeyFromItem(filteredItems.value[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -85,9 +81,7 @@ function updateSearchValue(event: Event) {
|
||||
(item) => props.getKeyFromItem(item) === highlightedTagId
|
||||
);
|
||||
if (highlightedItem) {
|
||||
addOrRemoveItemFromSelection(
|
||||
props.getKeyFromItem(highlightedItem)
|
||||
);
|
||||
addOrRemoveItemFromSelection(props.getKeyFromItem(highlightedItem));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -110,9 +104,7 @@ function toggleItem(newValue: string | null) {
|
||||
|
||||
function moveHighlightUp() {
|
||||
if (highlightedItem.value) {
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(
|
||||
highlightedItem.value
|
||||
);
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(highlightedItem.value);
|
||||
if (currentHightlightedIndex === 0) {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[filteredItems.value.length - 1]
|
||||
@@ -127,13 +119,9 @@ function moveHighlightUp() {
|
||||
|
||||
function moveHighlightDown() {
|
||||
if (highlightedItem.value) {
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(
|
||||
highlightedItem.value
|
||||
);
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(highlightedItem.value);
|
||||
if (currentHightlightedIndex === filteredItems.value.length - 1) {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[0]
|
||||
);
|
||||
highlightedItemId.value = props.getKeyFromItem(filteredItems.value[0]);
|
||||
} else {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[currentHightlightedIndex + 1]
|
||||
@@ -144,9 +132,7 @@ function moveHighlightDown() {
|
||||
|
||||
const highlightedItemId = ref<string | null>(null);
|
||||
const highlightedItem = computed(() => {
|
||||
return props.items.find(
|
||||
(item) => props.getKeyFromItem(item) === highlightedItemId.value
|
||||
);
|
||||
return props.items.find((item) => props.getKeyFromItem(item) === highlightedItemId.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -165,9 +151,7 @@ const highlightedItem = computed(() => {
|
||||
@keydown.up.prevent="moveHighlightUp"
|
||||
@keydown.down.prevent="moveHighlightDown"
|
||||
@keydown.enter="toggleItem(highlightedItemId)" />
|
||||
<div
|
||||
ref="dropdownViewport"
|
||||
class="min-w-60 max-w-80 max-h-60 overflow-y-scroll">
|
||||
<div ref="dropdownViewport" class="min-w-60 max-w-80 max-h-60 overflow-y-scroll">
|
||||
<div
|
||||
v-for="item in filteredItems"
|
||||
:key="props.getKeyFromItem(item)"
|
||||
@@ -180,9 +164,7 @@ const highlightedItem = computed(() => {
|
||||
:data-item-id="props.getKeyFromItem(item)">
|
||||
<MultiselectDropdownItem
|
||||
:selected="isItemSelected(props.getKeyFromItem(item))"
|
||||
:name="
|
||||
props.getNameForItem(item)
|
||||
"
|
||||
:name="props.getNameForItem(item)"
|
||||
@click="toggleItem(props.getKeyFromItem(item))"></MultiselectDropdownItem>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,9 +21,7 @@ const iconClasses = computed(() => {
|
||||
<div
|
||||
class="flex items-center space-x-3 w-full px-3 py-2.5 text-start text-sm font-medium leading-5 text-text-primary hover:bg-card-background-active focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out">
|
||||
<CheckCircleIcon :class="twMerge(iconClasses, 'w-5')"></CheckCircleIcon>
|
||||
<span class="flex-1 min-w-0 overflow-ellipsis overflow-hidden">{{
|
||||
name
|
||||
}}</span>
|
||||
<span class="flex-1 min-w-0 overflow-ellipsis overflow-hidden">{{ name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts" generic="T">
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import {computed, nextTick, onMounted, ref, watch} from 'vue';
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import SelectDropdownItem from '@/packages/ui/src/Input/SelectDropdownItem.vue';
|
||||
import { onKeyStroke } from '@vueuse/core';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
@@ -42,7 +42,7 @@ const filteredItems = computed<T[]>(() => {
|
||||
const highlightedItemId = ref<string | null>(model.value);
|
||||
|
||||
watch(model, () => {
|
||||
if(model.value){
|
||||
if (model.value) {
|
||||
highlightedItemId.value = model.value;
|
||||
}
|
||||
});
|
||||
@@ -57,7 +57,7 @@ watch(filteredItems, () => {
|
||||
resetHightlightedItem();
|
||||
});
|
||||
|
||||
function resetHightlightedItem(){
|
||||
function resetHightlightedItem() {
|
||||
if (
|
||||
filteredItems.value.length > 0 &&
|
||||
filteredItems.value.find(
|
||||
@@ -91,9 +91,7 @@ function setItem(newValue: string | null) {
|
||||
|
||||
function moveHighlightUp() {
|
||||
if (highlightedItem.value) {
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(
|
||||
highlightedItem.value
|
||||
);
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(highlightedItem.value);
|
||||
if (currentHightlightedIndex === 0) {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[filteredItems.value.length - 1]
|
||||
@@ -108,13 +106,9 @@ function moveHighlightUp() {
|
||||
|
||||
function moveHighlightDown() {
|
||||
if (highlightedItem.value) {
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(
|
||||
highlightedItem.value
|
||||
);
|
||||
const currentHightlightedIndex = filteredItems.value.indexOf(highlightedItem.value);
|
||||
if (currentHightlightedIndex === filteredItems.value.length - 1) {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[0]
|
||||
);
|
||||
highlightedItemId.value = props.getKeyFromItem(filteredItems.value[0]);
|
||||
} else {
|
||||
highlightedItemId.value = props.getKeyFromItem(
|
||||
filteredItems.value[currentHightlightedIndex + 1]
|
||||
@@ -124,9 +118,7 @@ function moveHighlightDown() {
|
||||
}
|
||||
|
||||
const highlightedItem = computed(() => {
|
||||
return props.items.find(
|
||||
(item) => props.getKeyFromItem(item) === highlightedItemId.value
|
||||
);
|
||||
return props.items.find((item) => props.getKeyFromItem(item) === highlightedItemId.value);
|
||||
});
|
||||
|
||||
onKeyStroke('ArrowDown', (e) => {
|
||||
@@ -173,12 +165,7 @@ watch(open, () => {
|
||||
<template #content>
|
||||
<div
|
||||
ref="dropdownViewport"
|
||||
:class="
|
||||
twMerge(
|
||||
'w-60 py-1.5 max-h-60 overflow-y-scroll',
|
||||
props.class
|
||||
)
|
||||
">
|
||||
:class="twMerge('w-60 py-1.5 max-h-60 overflow-y-scroll', props.class)">
|
||||
<div
|
||||
v-for="item in filteredItems"
|
||||
:key="props.getKeyFromItem(item) ?? 'none'"
|
||||
@@ -187,14 +174,10 @@ watch(open, () => {
|
||||
:value="props.getKeyFromItem(item)"
|
||||
:data-item-id="props.getKeyFromItem(item)">
|
||||
<SelectDropdownItem
|
||||
:highlighted="
|
||||
props.getKeyFromItem(item) === highlightedItemId
|
||||
"
|
||||
:highlighted="props.getKeyFromItem(item) === highlightedItemId"
|
||||
:selected="props.getKeyFromItem(item) === model"
|
||||
:name="props.getNameForItem(item)"
|
||||
@mouseenter="
|
||||
highlightedItemId = props.getKeyFromItem(item)
|
||||
"
|
||||
@mouseenter="highlightedItemId = props.getKeyFromItem(item)"
|
||||
@click="setItem(props.getKeyFromItem(item))"></SelectDropdownItem>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,9 +15,7 @@ const props = defineProps<{
|
||||
twMerge(
|
||||
'flex items-center space-x-3 w-full px-1.5 py-1.5 rounded text-start text-sm font-medium leading-5 text-text-primary focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out cursor-pointer ',
|
||||
props.highlighted && 'bg-card-background-active',
|
||||
props.selected
|
||||
? 'bg-accent-300/20'
|
||||
: 'hover:bg-card-background-active'
|
||||
props.selected ? 'bg-accent-300/20' : 'hover:bg-card-background-active'
|
||||
)
|
||||
">
|
||||
<span>{{ name }}</span>
|
||||
|
||||
@@ -6,21 +6,24 @@ const model = defineModel<string | number>({
|
||||
default: '',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
id?: string;
|
||||
type?: string;
|
||||
class?: string;
|
||||
rows?: number;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
required?: boolean;
|
||||
}>(), {
|
||||
type: 'text',
|
||||
class: '',
|
||||
rows: 3,
|
||||
disabled: false,
|
||||
required: false,
|
||||
});
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
id?: string;
|
||||
type?: string;
|
||||
class?: string;
|
||||
rows?: number;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
required?: boolean;
|
||||
}>(),
|
||||
{
|
||||
type: 'text',
|
||||
class: '',
|
||||
rows: 3,
|
||||
disabled: false,
|
||||
required: false,
|
||||
}
|
||||
);
|
||||
|
||||
const classes = computed(() => {
|
||||
return twMerge(
|
||||
@@ -39,6 +42,5 @@ const classes = computed(() => {
|
||||
:rows="rows"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
/>
|
||||
:required="required" />
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import {
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/packages/ui/src/utils/time';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { SelectDropdown, TextInput } from '@/packages/ui/src';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
@@ -41,10 +38,7 @@ function updateTime(event: Event) {
|
||||
else if (/^\d+$/.test(newValue)) {
|
||||
if (newValue.length === 4) {
|
||||
// parse 1300 to 13:00
|
||||
const [hours, minutes] = [
|
||||
newValue.slice(0, 2),
|
||||
newValue.slice(2, 4),
|
||||
];
|
||||
const [hours, minutes] = [newValue.slice(0, 2), newValue.slice(2, 4)];
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
.set('hours', Math.min(parseInt(hours), 23))
|
||||
.set('minutes', Math.min(parseInt(minutes), 59))
|
||||
@@ -52,10 +46,7 @@ function updateTime(event: Event) {
|
||||
emit('changed', model.value);
|
||||
} else if (newValue.length === 3) {
|
||||
// parse 130 to 01:30
|
||||
const [hours, minutes] = [
|
||||
newValue.slice(0, 1),
|
||||
newValue.slice(1, 3),
|
||||
];
|
||||
const [hours, minutes] = [newValue.slice(0, 1), newValue.slice(1, 3)];
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
.set('hours', Math.min(parseInt(hours), 23))
|
||||
.set('minutes', Math.min(parseInt(minutes), 59))
|
||||
@@ -113,9 +104,7 @@ const getStartOptions = computed<TimeOption[]>(() => {
|
||||
}
|
||||
return options;
|
||||
});
|
||||
const inputValue = ref(
|
||||
model.value ? getLocalizedDayJs(model.value).format('HH:mm') : null
|
||||
);
|
||||
const inputValue = ref(model.value ? getLocalizedDayJs(model.value).format('HH:mm') : null);
|
||||
const open = ref(false);
|
||||
const closestValue = computed({
|
||||
get() {
|
||||
@@ -123,9 +112,7 @@ const closestValue = computed({
|
||||
let closestDiff: number | null = null;
|
||||
let closest = target;
|
||||
for (const option of getStartOptions.value) {
|
||||
const diff = Math.abs(
|
||||
getDayJsInstance()(option.timestamp).diff(target)
|
||||
);
|
||||
const diff = Math.abs(getDayJsInstance()(option.timestamp).diff(target));
|
||||
if (closestDiff === null || diff < closestDiff) {
|
||||
closestDiff = diff;
|
||||
closest = getDayJsInstance()(option.timestamp);
|
||||
@@ -153,12 +140,7 @@ const closestValue = computed({
|
||||
<TextInput
|
||||
ref="timeInput"
|
||||
v-model="inputValue"
|
||||
:class="
|
||||
twMerge(
|
||||
'text-center w-24 px-3 py-2',
|
||||
size === 'large' && 'w-28'
|
||||
)
|
||||
"
|
||||
:class="twMerge('text-center w-24 px-3 py-2', size === 'large' && 'w-28')"
|
||||
data-testid="time_picker_input"
|
||||
type="text"
|
||||
@blur="updateTime"
|
||||
|
||||
@@ -38,10 +38,7 @@ function updateTime(event: Event) {
|
||||
else if (/^\d+$/.test(newValue)) {
|
||||
if (newValue.length === 4) {
|
||||
// parse 1300 to 13:00
|
||||
const [hours, minutes] = [
|
||||
newValue.slice(0, 2),
|
||||
newValue.slice(2, 4),
|
||||
];
|
||||
const [hours, minutes] = [newValue.slice(0, 2), newValue.slice(2, 4)];
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
.set('hours', Math.min(parseInt(hours), 23))
|
||||
.set('minutes', Math.min(parseInt(minutes), 59))
|
||||
@@ -49,10 +46,7 @@ function updateTime(event: Event) {
|
||||
emit('changed', model.value);
|
||||
} else if (newValue.length === 3) {
|
||||
// parse 130 to 01:30
|
||||
const [hours, minutes] = [
|
||||
newValue.slice(0, 1),
|
||||
newValue.slice(1, 3),
|
||||
];
|
||||
const [hours, minutes] = [newValue.slice(0, 1), newValue.slice(1, 3)];
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
.set('hours', Math.min(parseInt(hours), 23))
|
||||
.set('minutes', Math.min(parseInt(minutes), 59))
|
||||
@@ -87,9 +81,7 @@ const emit = defineEmits(['changed']);
|
||||
|
||||
useFocus(timeInput, { initialValue: props.focus });
|
||||
|
||||
const inputValue = ref(
|
||||
model.value ? getLocalizedDayJs(model.value).format('HH:mm') : null
|
||||
);
|
||||
const inputValue = ref(model.value ? getLocalizedDayJs(model.value).format('HH:mm') : null);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -97,9 +89,7 @@ const inputValue = ref(
|
||||
v-bind="$attrs"
|
||||
ref="timeInput"
|
||||
v-model="inputValue"
|
||||
:class="
|
||||
twMerge('text-center w-24 px-3 py-2', size === 'large' && 'w-28')
|
||||
"
|
||||
:class="twMerge('text-center w-24 px-3 py-2', size === 'large' && 'w-28')"
|
||||
data-testid="time_picker_input"
|
||||
type="text"
|
||||
@blur="updateTime"
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
import { defineProps, nextTick, ref, watch } from 'vue';
|
||||
import { useFocusWithin } from '@vueuse/core';
|
||||
import DatePicker from '@/packages/ui/src/Input/DatePicker.vue';
|
||||
import {
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/packages/ui/src/utils/time';
|
||||
import dayjs from 'dayjs';
|
||||
import TimePickerSimple from '@/packages/ui/src/Input/TimePickerSimple.vue';
|
||||
|
||||
@@ -18,9 +15,7 @@ const props = defineProps<{
|
||||
// The timestamps for the changed event are UTC
|
||||
const emit = defineEmits(['changed', 'close']);
|
||||
|
||||
const tempStart = ref(
|
||||
props.start ? getLocalizedDayJs(props.start).format() : dayjs().format()
|
||||
);
|
||||
const tempStart = ref(props.start ? getLocalizedDayJs(props.start).format() : dayjs().format());
|
||||
const tempEnd = ref(props.end ? getLocalizedDayJs(props.end).format() : null);
|
||||
|
||||
watch(props, () => {
|
||||
@@ -29,9 +24,7 @@ watch(props, () => {
|
||||
});
|
||||
function updateTimeEntry() {
|
||||
const tempStartUtc = getDayJsInstance()(tempStart.value).utc().format();
|
||||
const tempEndUtc = tempEnd.value
|
||||
? getDayJsInstance()(tempEnd.value).utc().format()
|
||||
: null;
|
||||
const tempEndUtc = tempEnd.value ? getDayJsInstance()(tempEnd.value).utc().format() : null;
|
||||
if (tempStartUtc !== props.start || tempEndUtc !== props.end) {
|
||||
emit(
|
||||
'changed',
|
||||
@@ -55,9 +48,7 @@ watch(focused, (newValue, oldValue) => {
|
||||
<div
|
||||
ref="dropdownContent"
|
||||
class="grid grid-cols-2 divide-x divide-card-background-separator text-center py-2">
|
||||
<div
|
||||
class="px-2"
|
||||
@keydown.enter.prevent="nextTick(() => emit('close'))">
|
||||
<div class="px-2" @keydown.enter.prevent="nextTick(() => emit('close'))">
|
||||
<div class="font-semibold text-text-primary text-sm pb-2">Start</div>
|
||||
<div class="space-y-2">
|
||||
<TimePickerSimple
|
||||
|
||||
Reference in New Issue
Block a user