mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 16:22:16 +01:00
Compare commits
2 Commits
feature/fr
...
feature/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9ffa9899f | ||
|
|
aa588196ee |
@@ -8,6 +8,7 @@ import { twMerge } from 'tailwind-merge';
|
|||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
class?: string;
|
class?: string;
|
||||||
|
tabindex?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// This has to be a localized timestamp, not UTC
|
// This has to be a localized timestamp, not UTC
|
||||||
@@ -50,6 +51,7 @@ const emit = defineEmits(['changed']);
|
|||||||
<input
|
<input
|
||||||
id="start"
|
id="start"
|
||||||
ref="datePicker"
|
ref="datePicker"
|
||||||
|
:tabindex="tabindex"
|
||||||
:class="
|
:class="
|
||||||
twMerge(
|
twMerge(
|
||||||
'bg-input-background border text-white border-input-border focus-visible:outline-0 focus-visible:border-input-border-active focus-visible:ring-0 rounded-md',
|
'bg-input-background border text-white border-input-border focus-visible:outline-0 focus-visible:border-input-border-active focus-visible:ring-0 rounded-md',
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import TagCreateModal from '@/packages/ui/src/Tag/TagCreateModal.vue';
|
|||||||
import MultiselectDropdownItem from '@/packages/ui/src/Input/MultiselectDropdownItem.vue';
|
import MultiselectDropdownItem from '@/packages/ui/src/Input/MultiselectDropdownItem.vue';
|
||||||
import type { Tag } from '@/packages/api/src';
|
import type { Tag } from '@/packages/api/src';
|
||||||
import type { Placement } from '@floating-ui/vue';
|
import type { Placement } from '@floating-ui/vue';
|
||||||
|
import {UseFocusTrap} from "@vueuse/integrations/useFocusTrap/component";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@@ -177,46 +178,50 @@ const showCreateTagModal = ref(false);
|
|||||||
<slot name="trigger"></slot>
|
<slot name="trigger"></slot>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<input
|
<UseFocusTrap
|
||||||
ref="searchInput"
|
v-if="open"
|
||||||
:value="searchValue"
|
:options="{ immediate: true, allowOutsideClick: true }">
|
||||||
data-testid="tag_dropdown_search"
|
<input
|
||||||
class="bg-card-background border-0 placeholder-muted text-sm text-white py-2.5 focus:ring-0 border-b border-card-background-separator focus:border-card-background-separator w-full"
|
ref="searchInput"
|
||||||
placeholder="Search for a Tag..."
|
:value="searchValue"
|
||||||
@input="updateSearchValue"
|
data-testid="tag_dropdown_search"
|
||||||
@keydown.enter="addTagIfNoneExists"
|
class="bg-card-background border-0 placeholder-muted text-sm text-white py-2.5 focus:ring-0 border-b border-card-background-separator focus:border-card-background-separator w-full"
|
||||||
@keydown.up.prevent="moveHighlightUp"
|
placeholder="Search for a Tag..."
|
||||||
@keydown.down.prevent="moveHighlightDown" />
|
@input="updateSearchValue"
|
||||||
<div ref="dropdownViewport" class="w-60 max-h-60 overflow-y-scroll">
|
@keydown.enter="addTagIfNoneExists"
|
||||||
<div
|
@keydown.up.prevent="moveHighlightUp"
|
||||||
v-for="tag in filteredTags"
|
@keydown.down.prevent="moveHighlightDown" />
|
||||||
:key="tag.id"
|
<div ref="dropdownViewport" class="w-60 max-h-60 overflow-y-scroll">
|
||||||
role="option"
|
<div
|
||||||
:value="tag.id"
|
v-for="tag in filteredTags"
|
||||||
:class="{
|
:key="tag.id"
|
||||||
|
role="option"
|
||||||
|
:value="tag.id"
|
||||||
|
:class="{
|
||||||
'bg-card-background-active':
|
'bg-card-background-active':
|
||||||
tag.id === highlightedItemId,
|
tag.id === highlightedItemId,
|
||||||
}"
|
}"
|
||||||
data-testid="tag_dropdown_entries"
|
data-testid="tag_dropdown_entries"
|
||||||
:data-tag-id="tag.id">
|
:data-tag-id="tag.id">
|
||||||
<MultiselectDropdownItem
|
<MultiselectDropdownItem
|
||||||
:selected="isTagSelected(tag.id)"
|
:selected="isTagSelected(tag.id)"
|
||||||
:name="tag.name"
|
:name="tag.name"
|
||||||
@click="toggleTag(tag.id)"></MultiselectDropdownItem>
|
@click="toggleTag(tag.id)"></MultiselectDropdownItem>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="hover:bg-card-background-active rounded-b-lg">
|
||||||
<div class="hover:bg-card-background-active rounded-b-lg">
|
<button
|
||||||
<button
|
class="text-white w-full flex space-x-3 items-center px-4 py-3 text-xs font-semibold border-t border-card-background-separator"
|
||||||
class="text-white w-full flex space-x-3 items-center px-4 py-3 text-xs font-semibold border-t border-card-background-separator"
|
@click="
|
||||||
@click="
|
|
||||||
open = false;
|
open = false;
|
||||||
showCreateTagModal = true;
|
showCreateTagModal = true;
|
||||||
">
|
">
|
||||||
<PlusCircleIcon
|
<PlusCircleIcon
|
||||||
class="w-5 flex-shrink-0 text-icon-default"></PlusCircleIcon>
|
class="w-5 flex-shrink-0 text-icon-default"></PlusCircleIcon>
|
||||||
<span>Create new Tag</span>
|
<span>Create new Tag</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</UseFocusTrap>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import type {
|
|||||||
Client,
|
Client,
|
||||||
CreateTimeEntryBody,
|
CreateTimeEntryBody,
|
||||||
} from '@/packages/api/src';
|
} from '@/packages/api/src';
|
||||||
import TimePicker from '@/packages/ui/src/Input/TimePicker.vue';
|
|
||||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||||
import { canCreateProjects } from '@/utils/permissions';
|
import { canCreateProjects } from '@/utils/permissions';
|
||||||
import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue';
|
import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue';
|
||||||
@@ -30,6 +29,7 @@ import DurationHumanInput from '@/packages/ui/src/Input/DurationHumanInput.vue';
|
|||||||
|
|
||||||
import { InformationCircleIcon } from '@heroicons/vue/20/solid';
|
import { InformationCircleIcon } from '@heroicons/vue/20/solid';
|
||||||
import type { Tag, Task } from '@/packages/api/src';
|
import type { Tag, Task } from '@/packages/api/src';
|
||||||
|
import TimePickerSimple from "@/packages/ui/src/Input/TimePickerSimple.vue";
|
||||||
|
|
||||||
const show = defineModel('show', { default: false });
|
const show = defineModel('show', { default: false });
|
||||||
const saving = ref(false);
|
const saving = ref(false);
|
||||||
@@ -244,30 +244,34 @@ type BillableOption = {
|
|||||||
<div class="">
|
<div class="">
|
||||||
<InputLabel>Start</InputLabel>
|
<InputLabel>Start</InputLabel>
|
||||||
<div class="flex flex-col items-center space-y-2 mt-1">
|
<div class="flex flex-col items-center space-y-2 mt-1">
|
||||||
<TimePicker
|
<TimePickerSimple
|
||||||
|
|
||||||
v-model="localStart"
|
v-model="localStart"
|
||||||
size="large"></TimePicker>
|
size="large"></TimePickerSimple>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
v-model="localStart"
|
v-model="localStart"
|
||||||
|
tabindex="1"
|
||||||
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"></DatePicker>
|
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"></DatePicker>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<InputLabel>End</InputLabel>
|
<InputLabel>End</InputLabel>
|
||||||
<div class="flex flex-col items-center space-y-2 mt-1">
|
<div class="flex flex-col items-center space-y-2 mt-1">
|
||||||
<TimePicker
|
<TimePickerSimple
|
||||||
v-model="localEnd"
|
v-model="localEnd"
|
||||||
size="large"></TimePicker>
|
size="large"></TimePickerSimple>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
v-model="localEnd"
|
v-model="localEnd"
|
||||||
|
tabindex="1"
|
||||||
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"></DatePicker>
|
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"></DatePicker>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<SecondaryButton @click="show = false"> Cancel</SecondaryButton>
|
<SecondaryButton tabindex="2" @click="show = false"> Cancel</SecondaryButton>
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
|
tabindex="2"
|
||||||
class="ms-3"
|
class="ms-3"
|
||||||
:class="{ 'opacity-25': saving }"
|
:class="{ 'opacity-25': saving }"
|
||||||
:disabled="saving"
|
:disabled="saving"
|
||||||
|
|||||||
Reference in New Issue
Block a user