Skip to content

Commit 8f494b7

Browse files
authored
Merge pull request #5 from solidtime-io/feature/data_handling
improve data handling
2 parents 06d4643 + 66a5a1a commit 8f494b7

File tree

10 files changed

+1397
-1919
lines changed

10 files changed

+1397
-1919
lines changed

dev-app-update.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
provider: generic
2-
url: https://solidtime.io/auto-updates
3-
updaterCacheDirName: solidtime-updater
1+
provider: github

package-lock.json

+1,063-1,695
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
"@electron-toolkit/utils": "^3.0.0",
3434
"@sentry/electron": "^5.3.0",
3535
"@sentry/vite-plugin": "^2.22.2",
36-
"@solidtime/api": "^0.0.3",
37-
"@solidtime/ui": "^0.0.8",
36+
"@solidtime/api": "^0.0.4",
37+
"@solidtime/ui": "^0.0.9",
3838
"electron-updater": "^6.1.7"
3939
},
4040
"devDependencies": {
@@ -69,7 +69,7 @@
6969
"postcss": "^8.4.39",
7070
"prettier": "^3.3.2",
7171
"tailwindcss": "^3.4.4",
72-
"typescript": "^5.5.2",
72+
"typescript": "~5.5.2",
7373
"vite": "^5.3.1",
7474
"vue": "^3.4.30",
7575
"vue-tsc": "^2.0.22",

src/main/autoUpdater.ts

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export function getAutoUpdater(): AppUpdater {
99
const { autoUpdater } = electronUpdater
1010
log.transports.file.level = 'debug'
1111
autoUpdater.logger = log
12-
autoUpdater.forceDevUpdateConfig = true
1312
return autoUpdater
1413
}
1514

src/renderer/src/App.vue

-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ declare global {
66
interface Window {
77
getTimezoneSetting: () => string
88
getWeekStartSetting: () => string
9-
__TAURI__: Record<string, unknown>
109
}
1110
}
1211
@@ -60,7 +59,6 @@ import { useQueryClient } from '@tanstack/vue-query'
6059
<template>
6160
<VueQueryDevtools></VueQueryDevtools>
6261
<AutoUpdaterOverlay></AutoUpdaterOverlay>
63-
6462
<div class="h-10 w-full border-b border-border-primary flex justify-end items-center pr-3">
6563
<div class="flex-1 h-full" style="-webkit-app-region: drag"></div>
6664
<div v-if="isLoggedIn" class="flex items-center space-x-2">

src/renderer/src/Mini.vue

+2-204
Original file line numberDiff line numberDiff line change
@@ -1,218 +1,16 @@
11
<script setup lang="ts">
2-
import { computed, watch, watchEffect } from 'vue'
3-
import { useQuery, useQueryClient } from '@tanstack/vue-query'
4-
import { emptyTimeEntry } from './utils/timeEntries.ts'
5-
import { useStorage } from '@vueuse/core'
6-
import { getAllProjects } from './utils/projects.ts'
7-
import { getAllTasks } from './utils/tasks.ts'
8-
import { TimeTrackerStartStop, ProjectBadge } from '@solidtime/ui'
9-
import { ChevronRightIcon } from '@heroicons/vue/16/solid'
10-
import { useLiveTimer } from './utils/liveTimer.ts'
11-
import { time } from '@solidtime/ui'
12-
import { useMyMemberships } from './utils/myMemberships.ts'
132
import { isLoggedIn } from './utils/oauth.ts'
14-
import { dayjs } from './utils/dayjs.ts'
15-
import { sendEventToWindow } from './utils/events.ts'
163
import { showMainWindow } from './utils/window.ts'
17-
18-
const { liveTimer, startLiveTimer, stopLiveTimer } = useLiveTimer()
19-
const { currentOrganizationId } = useMyMemberships()
20-
21-
const isRunning = computed(
22-
() => currentTimeEntry.value.start !== '' && currentTimeEntry.value.start !== null
23-
)
24-
25-
const organizationIdToLoad = computed(() => {
26-
if (currentTimeEntry.value.organization_id && currentTimeEntry.value.organization_id !== '') {
27-
return currentTimeEntry.value.organization_id
28-
}
29-
return currentOrganizationId.value
30-
})
31-
32-
const currentOrganizationLoaded = computed(() => !!organizationIdToLoad.value)
33-
34-
const currentTimeEntry = useStorage('currentTimeEntry', { ...emptyTimeEntry })
35-
const { data: projectsResponse } = useQuery({
36-
queryKey: ['projects', organizationIdToLoad],
37-
queryFn: () => getAllProjects(organizationIdToLoad.value),
38-
enabled: currentOrganizationLoaded,
39-
})
40-
41-
const { data: tasksResponse } = useQuery({
42-
queryKey: ['tasks', organizationIdToLoad],
43-
queryFn: () => getAllTasks(organizationIdToLoad.value),
44-
enabled: currentOrganizationLoaded,
45-
})
46-
47-
const { data: currentTimeEntryTasksResponse } = useQuery({
48-
queryKey: ['tasks', currentTimeEntry.value.organization_id],
49-
queryFn: () => getAllTasks(currentTimeEntry.value.organization_id),
50-
enabled: currentOrganizationLoaded,
51-
})
52-
53-
const lastTimeEntry = useStorage('lastTimeEntry', { ...emptyTimeEntry })
54-
55-
const tasks = computed(() => {
56-
if (isRunning.value) {
57-
return currentTimeEntryTasksResponse.value?.data
58-
}
59-
return tasksResponse.value?.data
60-
})
61-
const projects = computed(() => {
62-
return projectsResponse.value?.data
63-
})
64-
65-
const shownDescription = computed(() => {
66-
if (isRunning.value) {
67-
return currentTimeEntry.value.description !== ''
68-
? currentTimeEntry.value.description
69-
: currentTask.value?.name
70-
} else if (!isRunning.value) {
71-
return lastTimeEntry.value.description !== ''
72-
? lastTimeEntry.value.description
73-
: currentTask.value?.name
74-
}
75-
return null
76-
})
77-
const currentTask = computed(() => {
78-
if (isRunning.value) {
79-
return tasks.value?.find((task) => task.id === currentTimeEntry.value.task_id)
80-
} else {
81-
return tasks.value?.find((task) => task.id === lastTimeEntry.value.task_id)
82-
}
83-
})
84-
const shownProject = computed(() => {
85-
if (isRunning.value) {
86-
return projects.value?.find((project) => project.id === currentTimeEntry.value.project_id)
87-
} else {
88-
return projects.value?.find((project) => project.id === lastTimeEntry.value.project_id)
89-
}
90-
})
91-
92-
const queryClient = useQueryClient()
93-
94-
// invalidate queries if we encounter projects or tasks that are not in the store
95-
// because stores are currently not synced between mini and main window
96-
// (future, currentlyexperimental: https://tanstack.com/query/latest/docs/framework/vue/plugins/createPersister)
97-
watch(currentTimeEntry, () => {
98-
console.log('currentTimeEntry changed')
99-
if (
100-
currentTimeEntry.value.project_id &&
101-
projects.value &&
102-
!projects.value.some((project) => project.id === currentTimeEntry.value.project_id)
103-
) {
104-
console.log('project invalidate')
105-
queryClient.invalidateQueries({ queryKey: ['projects'] })
106-
}
107-
if (
108-
currentTimeEntry.value.task_id &&
109-
tasks.value &&
110-
!tasks.value.some((task) => task.id === currentTimeEntry.value.task_id)
111-
) {
112-
queryClient.invalidateQueries({ queryKey: ['tasks'] })
113-
}
114-
})
115-
watch(lastTimeEntry, () => {
116-
if (
117-
lastTimeEntry.value.project_id &&
118-
projects.value &&
119-
!projects.value.some((project) => project.id === lastTimeEntry.value.project_id)
120-
) {
121-
queryClient.invalidateQueries({ queryKey: ['projects'] })
122-
}
123-
if (
124-
lastTimeEntry.value.task_id &&
125-
tasks.value &&
126-
!tasks.value.some((task) => task.id === lastTimeEntry.value.task_id)
127-
) {
128-
queryClient.invalidateQueries({ queryKey: ['tasks'] })
129-
}
130-
})
131-
132-
watchEffect(() => {
133-
if (isRunning.value) {
134-
startLiveTimer()
135-
} else {
136-
stopLiveTimer()
137-
}
138-
})
139-
140-
function onToggleButtonPress(newState: boolean) {
141-
if (newState) {
142-
sendEventToWindow('main', 'startTimer')
143-
} else {
144-
showMainWindow()
145-
sendEventToWindow('main', 'stopTimer')
146-
}
147-
}
4+
import MiniControls from './components/MiniControls.vue'
1485
1496
function focusMainWindow() {
1507
showMainWindow()
1518
}
152-
153-
const currentTimer = computed(() => {
154-
if (liveTimer.value && currentTimeEntry.value.start) {
155-
const startTime = dayjs(currentTimeEntry.value.start)
156-
const diff = liveTimer.value.diff(startTime, 'seconds')
157-
return time.formatDuration(diff)
158-
}
159-
return '00:00:00'
160-
})
1619
</script>
16210

16311
<template>
16412
<div v-if="!isLoggedIn" @click="focusMainWindow">Log in with solidtime</div>
165-
<div
166-
v-else
167-
class="h-screen relative w-screen border-border-secondary border bg-primary rounded-[10px] text-white py-1 flex items-center cursor-default justify-between select-none">
168-
<div class="text-sm text-muted flex items-center relative flex-1 min-w-0">
169-
<div class="pl-1 pr-1 z-20 relative block" style="-webkit-app-region: drag">
170-
<svg
171-
class="h-5"
172-
viewBox="0 0 25 25"
173-
fill="none"
174-
xmlns="http://www.w3.org/2000/svg"
175-
data-tauri-drag-region>
176-
<path
177-
fill-rule="evenodd"
178-
clip-rule="evenodd"
179-
d="M9.5 8C10.3284 8 11 7.32843 11 6.5C11 5.67157 10.3284 5 9.5 5C8.67157 5 8 5.67157 8 6.5C8 7.32843 8.67157 8 9.5 8ZM9.5 14C10.3284 14 11 13.3284 11 12.5C11 11.6716 10.3284 11 9.5 11C8.67157 11 8 11.6716 8 12.5C8 13.3284 8.67157 14 9.5 14ZM11 18.5C11 19.3284 10.3284 20 9.5 20C8.67157 20 8 19.3284 8 18.5C8 17.6716 8.67157 17 9.5 17C10.3284 17 11 17.6716 11 18.5ZM15.5 8C16.3284 8 17 7.32843 17 6.5C17 5.67157 16.3284 5 15.5 5C14.6716 5 14 5.67157 14 6.5C14 7.32843 14.6716 8 15.5 8ZM17 12.5C17 13.3284 16.3284 14 15.5 14C14.6716 14 14 13.3284 14 12.5C14 11.6716 14.6716 11 15.5 11C16.3284 11 17 11.6716 17 12.5ZM15.5 20C16.3284 20 17 19.3284 17 18.5C17 17.6716 16.3284 17 15.5 17C14.6716 17 14 17.6716 14 18.5C14 19.3284 14.6716 20 15.5 20Z"
180-
fill="currentColor"
181-
data-tauri-drag-region />
182-
</svg>
183-
</div>
184-
<div
185-
class="cursor-pointer rounded-lg flex items-center shrink min-w-0"
186-
@click="focusMainWindow">
187-
<div class="flex items-center flex-1 space-x-0.5 min-w-0">
188-
<ProjectBadge
189-
class="px-0 whitespace-nowrap overflow-ellipsis"
190-
:border="false"
191-
:color="shownProject?.color"
192-
:name="shownProject?.name ?? 'No Project'"></ProjectBadge>
193-
<div class="flex text-xs flex-1 truncate items-center space-x-0.5 shrink">
194-
<ChevronRightIcon class="w-4 shrink-0 text-muted"></ChevronRightIcon>
195-
<span
196-
class="truncate shrink text-muted opacity-50 hover:opacity-100 transition-opacity min-w-0"
197-
>{{ shownDescription ?? 'No Description' }}</span
198-
>
199-
</div>
200-
</div>
201-
</div>
202-
<div class="flex-1 h-6 w-full" style="-webkit-app-region: drag"></div>
203-
</div>
204-
<div class="pr-1 flex items-center space-x-1">
205-
<div
206-
class="text-xs font-semibold text-muted px-2 w-[65px] text-left"
207-
style="-webkit-app-region: drag">
208-
{{ currentTimer }}
209-
</div>
210-
<TimeTrackerStartStop
211-
:active="isRunning"
212-
size="small"
213-
@changed="onToggleButtonPress"></TimeTrackerStartStop>
214-
</div>
215-
</div>
13+
<MiniControls v-else></MiniControls>
21614
</template>
21715

21816
<style scoped></style>

0 commit comments

Comments
 (0)