mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-10 17:22:15 +01:00
use container queries for time entry table
This commit is contained in:
@@ -93,7 +93,7 @@ function onSelectChange(checked: boolean) {
|
||||
class="border-b border-default-background-separator bg-row-background min-w-0 transition"
|
||||
data-testid="time_entry_row">
|
||||
<MainContainer class="min-w-0">
|
||||
<div class="sm:flex py-2 items-center min-w-0 justify-between group">
|
||||
<div class="@sm:flex py-2 items-center min-w-0 justify-between group">
|
||||
<div class="flex space-x-3 items-center min-w-0">
|
||||
<Checkbox
|
||||
:checked="
|
||||
@@ -102,7 +102,7 @@ function onSelectChange(checked: boolean) {
|
||||
)
|
||||
"
|
||||
@update:checked="onSelectChange" />
|
||||
<div class="flex items-center min-w-0 space-x-1 lg:space-x-2">
|
||||
<div class="flex items-center min-w-0 space-x-1 @lg:space-x-2">
|
||||
<GroupedItemsCountButton :expanded="expanded" @click="expanded = !expanded">
|
||||
{{ timeEntry?.timeEntries?.length }}
|
||||
</GroupedItemsCountButton>
|
||||
@@ -125,7 +125,7 @@ function onSelectChange(checked: boolean) {
|
||||
@changed="updateProjectAndTask"></TimeTrackerProjectTaskDropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center font-medium space-x-1 lg:space-x-2">
|
||||
<div class="flex items-center font-medium space-x-1 @lg:space-x-2">
|
||||
<TimeEntryRowTagDropdown
|
||||
:create-tag
|
||||
:tags="tags"
|
||||
|
||||
@@ -137,79 +137,81 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-for="(value, key) in groupedTimeEntries" :key="key">
|
||||
<TimeEntryRowHeading
|
||||
:date="key"
|
||||
:duration="sumDuration(value)"
|
||||
:checked="
|
||||
value.every((timeEntry: TimeEntry) => selectedTimeEntries.includes(timeEntry))
|
||||
"
|
||||
@select-all="selectAllTimeEntries(value)"
|
||||
@unselect-all="unselectAllTimeEntries(value)"></TimeEntryRowHeading>
|
||||
<template v-for="entry in value" :key="entry.id">
|
||||
<TimeEntryAggregateRow
|
||||
v-if="'timeEntries' in entry && entry.timeEntries.length > 1"
|
||||
:create-project
|
||||
:can-create-project
|
||||
:enable-estimated-time
|
||||
:selected-time-entries="selectedTimeEntries"
|
||||
:create-client
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:on-start-stop-click="startTimeEntryFromExisting"
|
||||
:duplicate-time-entry="createTimeEntry"
|
||||
:update-time-entries
|
||||
:update-time-entry
|
||||
:delete-time-entries
|
||||
:create-tag
|
||||
:currency="currency"
|
||||
:time-entry="entry"
|
||||
@selected="
|
||||
(timeEntries: TimeEntry[]) => {
|
||||
selectedTimeEntries = [...selectedTimeEntries, ...timeEntries];
|
||||
}
|
||||
<div class="@container">
|
||||
<div v-for="(value, key) in groupedTimeEntries" :key="key">
|
||||
<TimeEntryRowHeading
|
||||
:date="key"
|
||||
:duration="sumDuration(value)"
|
||||
:checked="
|
||||
value.every((timeEntry: TimeEntry) => selectedTimeEntries.includes(timeEntry))
|
||||
"
|
||||
@unselected="
|
||||
(timeEntriesToUnselect: TimeEntry[]) => {
|
||||
@select-all="selectAllTimeEntries(value)"
|
||||
@unselect-all="unselectAllTimeEntries(value)"></TimeEntryRowHeading>
|
||||
<template v-for="entry in value" :key="entry.id">
|
||||
<TimeEntryAggregateRow
|
||||
v-if="'timeEntries' in entry && entry.timeEntries.length > 1"
|
||||
:create-project
|
||||
:can-create-project
|
||||
:enable-estimated-time
|
||||
:selected-time-entries="selectedTimeEntries"
|
||||
:create-client
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:on-start-stop-click="startTimeEntryFromExisting"
|
||||
:duplicate-time-entry="createTimeEntry"
|
||||
:update-time-entries
|
||||
:update-time-entry
|
||||
:delete-time-entries
|
||||
:create-tag
|
||||
:currency="currency"
|
||||
:time-entry="entry"
|
||||
@selected="
|
||||
(timeEntries: TimeEntry[]) => {
|
||||
selectedTimeEntries = [...selectedTimeEntries, ...timeEntries];
|
||||
}
|
||||
"
|
||||
@unselected="
|
||||
(timeEntriesToUnselect: TimeEntry[]) => {
|
||||
selectedTimeEntries = selectedTimeEntries.filter(
|
||||
(item: TimeEntry) =>
|
||||
!timeEntriesToUnselect.find(
|
||||
(filterEntry: TimeEntry) => filterEntry.id === item.id
|
||||
)
|
||||
);
|
||||
}
|
||||
"></TimeEntryAggregateRow>
|
||||
<TimeEntryRow
|
||||
v-else
|
||||
:create-client
|
||||
:enable-estimated-time
|
||||
:can-create-project
|
||||
:create-project
|
||||
:projects="projects"
|
||||
:selected="
|
||||
!!selectedTimeEntries.find(
|
||||
(filterEntry: TimeEntry) => filterEntry.id === entry.id
|
||||
)
|
||||
"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:create-tag
|
||||
:update-time-entry
|
||||
:on-start-stop-click="() => startTimeEntryFromExisting(entry)"
|
||||
:delete-time-entry="() => deleteTimeEntries([entry])"
|
||||
:duplicate-time-entry="() => createTimeEntry(entry)"
|
||||
:currency="currency"
|
||||
:time-entry="entry.timeEntries[0]"
|
||||
@selected="selectedTimeEntries.push(entry)"
|
||||
@unselected="
|
||||
selectedTimeEntries = selectedTimeEntries.filter(
|
||||
(item: TimeEntry) =>
|
||||
!timeEntriesToUnselect.find(
|
||||
(filterEntry: TimeEntry) => filterEntry.id === item.id
|
||||
)
|
||||
);
|
||||
}
|
||||
"></TimeEntryAggregateRow>
|
||||
<TimeEntryRow
|
||||
v-else
|
||||
:create-client
|
||||
:enable-estimated-time
|
||||
:can-create-project
|
||||
:create-project
|
||||
:projects="projects"
|
||||
:selected="
|
||||
!!selectedTimeEntries.find(
|
||||
(filterEntry: TimeEntry) => filterEntry.id === entry.id
|
||||
)
|
||||
"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:create-tag
|
||||
:update-time-entry
|
||||
:on-start-stop-click="() => startTimeEntryFromExisting(entry)"
|
||||
:delete-time-entry="() => deleteTimeEntries([entry])"
|
||||
:duplicate-time-entry="() => createTimeEntry(entry)"
|
||||
:currency="currency"
|
||||
:time-entry="entry.timeEntries[0]"
|
||||
@selected="selectedTimeEntries.push(entry)"
|
||||
@unselected="
|
||||
selectedTimeEntries = selectedTimeEntries.filter(
|
||||
(item: TimeEntry) => item.id !== entry.id
|
||||
)
|
||||
"></TimeEntryRow>
|
||||
</template>
|
||||
(item: TimeEntry) => item.id !== entry.id
|
||||
)
|
||||
"></TimeEntryRow>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ async function handleDeleteTimeEntry() {
|
||||
class="border-b border-default-background-separator transition min-w-0 bg-row-background"
|
||||
data-testid="time_entry_row">
|
||||
<MainContainer class="min-w-0">
|
||||
<div class="sm:flex py-2 min-w-0 items-center justify-between group">
|
||||
<div class="@sm:flex py-2 min-w-0 items-center justify-between group">
|
||||
<div class="flex items-center min-w-0">
|
||||
<Checkbox :checked="selected" @update:checked="onSelectChange" />
|
||||
<div v-if="indent === true" class="w-10 h-7"></div>
|
||||
@@ -134,7 +134,7 @@ async function handleDeleteTimeEntry() {
|
||||
:task="timeEntry.task_id"
|
||||
@changed="updateProjectAndTask"></TimeTrackerProjectTaskDropdown>
|
||||
</div>
|
||||
<div class="flex items-center font-medium space-x-1 lg:space-x-2">
|
||||
<div class="flex items-center font-medium space-x-1 @lg:space-x-2">
|
||||
<div v-if="showMember && members" class="text-sm px-2">
|
||||
{{ memberName }}
|
||||
</div>
|
||||
|
||||
@@ -32,13 +32,13 @@ function selectUnselectAll(value: boolean) {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="bg-row-heading-background border-t border-b border-row-heading-border py-1 text-xs sm:text-sm">
|
||||
class="bg-row-heading-background border-t border-b border-row-heading-border py-1 text-xs @sm:text-sm">
|
||||
<MainContainer>
|
||||
<div class="flex group justify-between items-center">
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="w-5">
|
||||
<svg
|
||||
class="w-3 sm:w-4 text-icon-default group-hover:hidden block"
|
||||
class="w-3 @sm:w-4 text-icon-default group-hover:hidden block"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none">
|
||||
@@ -61,7 +61,7 @@ function selectUnselectAll(value: boolean) {
|
||||
{{ formatDate(date, organization?.date_format) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-text-secondary pr-[87px] lg:pr-[92px]">
|
||||
<div class="text-text-secondary pr-[87px] @lg:pr-[92px]">
|
||||
<span class="font-medium">
|
||||
{{
|
||||
formatHumanReadableDuration(
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { TooltipRootEmits, TooltipRootProps } from "reka-ui"
|
||||
import { TooltipRoot, useForwardPropsEmits } from "reka-ui"
|
||||
import type { TooltipRootEmits, TooltipRootProps } from 'reka-ui';
|
||||
import { TooltipRoot, useForwardPropsEmits } from 'reka-ui';
|
||||
|
||||
const props = defineProps<TooltipRootProps>()
|
||||
const emits = defineEmits<TooltipRootEmits>()
|
||||
const props = defineProps<TooltipRootProps>();
|
||||
const emits = defineEmits<TooltipRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits)
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TooltipRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</TooltipRoot>
|
||||
<TooltipRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</TooltipRoot>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { TooltipProviderProps } from "reka-ui"
|
||||
import { TooltipProvider } from "reka-ui"
|
||||
import type { TooltipProviderProps } from 'reka-ui';
|
||||
import { TooltipProvider } from 'reka-ui';
|
||||
|
||||
const props = defineProps<TooltipProviderProps>()
|
||||
const props = defineProps<TooltipProviderProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TooltipProvider v-bind="props">
|
||||
<slot />
|
||||
</TooltipProvider>
|
||||
<TooltipProvider v-bind="props">
|
||||
<slot />
|
||||
</TooltipProvider>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { TooltipTriggerProps } from "reka-ui"
|
||||
import { TooltipTrigger } from "reka-ui"
|
||||
import type { TooltipTriggerProps } from 'reka-ui';
|
||||
import { TooltipTrigger } from 'reka-ui';
|
||||
|
||||
const props = defineProps<TooltipTriggerProps>()
|
||||
const props = defineProps<TooltipTriggerProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TooltipTrigger v-bind="props">
|
||||
<slot />
|
||||
</TooltipTrigger>
|
||||
<TooltipTrigger v-bind="props">
|
||||
<slot />
|
||||
</TooltipTrigger>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { default as Tooltip } from "./Tooltip.vue"
|
||||
export { default as TooltipContent } from "./TooltipContent.vue"
|
||||
export { default as TooltipProvider } from "./TooltipProvider.vue"
|
||||
export { default as TooltipTrigger } from "./TooltipTrigger.vue"
|
||||
export { default as Tooltip } from './Tooltip.vue';
|
||||
export { default as TooltipContent } from './TooltipContent.vue';
|
||||
export { default as TooltipProvider } from './TooltipProvider.vue';
|
||||
export { default as TooltipTrigger } from './TooltipTrigger.vue';
|
||||
|
||||
Reference in New Issue
Block a user