@nuxt-customer-portal/timesheets 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @nuxt-customer-portal/timesheets
2
2
 
3
+ ## 0.10.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [c2985a7]
8
+ - Updated dependencies [c2985a7]
9
+ - Updated dependencies [c2985a7]
10
+ - Updated dependencies [c2985a7]
11
+ - @nuxt-customer-portal/ui@0.10.2
12
+ - @nuxt-customer-portal/core@0.10.2
13
+ - @nuxt-customer-portal/clients@0.10.2
14
+ - @nuxt-customer-portal/organizations@0.10.2
15
+
16
+ ## 0.10.1
17
+
18
+ ### Patch Changes
19
+
20
+ - 91bd778: Turn the timesheet toolbar's week label into a localized calendar picker for jumping directly to any Monday–Sunday week.
21
+ - Updated dependencies [7c0f8df]
22
+ - @nuxt-customer-portal/ui@0.10.1
23
+ - @nuxt-customer-portal/clients@0.10.1
24
+ - @nuxt-customer-portal/core@0.10.1
25
+ - @nuxt-customer-portal/organizations@0.10.1
26
+
3
27
  ## 0.10.0
4
28
 
5
29
  ### Patch Changes
package/README.md CHANGED
@@ -4,6 +4,8 @@ An isolated PortalNuxt feature for weekly time entry, timers, approval, project
4
4
 
5
5
  All API access is scoped to the active organization through portal-core. Feature-owned database objects live in the PostgreSQL `timesheets` schema.
6
6
 
7
+ The timesheet toolbar's week number and date range open a calendar week picker. Select any date to view its Monday–Sunday week, or use the previous/next buttons. The picker highlights the displayed week and is disabled while a timesheet is loading.
8
+
7
9
  ### Approval email history and reminders
8
10
 
9
11
  Internal and provider client approval cards show approval request email history with the recipient name and address at send time, timestamp, message, and sending/sent/failed status. Sent means accepted by the email provider, not confirmed delivery or reading. Tracking begins with migration `0006_approval_email.sql`; earlier sends cannot be reconstructed.
@@ -1,5 +1,7 @@
1
1
  <script setup lang="ts">
2
- import { formatTimesheetPeriod } from '@nuxt-customer-portal/timesheets/shared/timesheet-dates'
2
+ import { parseDate } from '@internationalized/date'
3
+ import type { CalendarProps } from '@nuxt/ui'
4
+ import { formatTimesheetPeriod, mondayFor } from '@nuxt-customer-portal/timesheets/shared/timesheet-dates'
3
5
  import { addDays, addWeeks, format, getISOWeek, parseISO } from 'date-fns'
4
6
  import { z } from 'zod'
5
7
  import { submissionReplySchema } from '@nuxt-customer-portal/timesheets/shared/submission-reply'
@@ -49,6 +51,7 @@ const route = useRoute()
49
51
  const selectedWeek = ref<string | undefined>(
50
52
  typeof route.query.week === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(route.query.week) ? route.query.week : undefined
51
53
  )
54
+ const weekPickerOpen = ref(false)
52
55
  const selectedDay = ref('')
53
56
  const modalOpen = ref(false)
54
57
  const cellEntriesOpen = ref(false)
@@ -271,6 +274,22 @@ const formatWeekPeriod = (startsOn: string) =>
271
274
  parseISO(startsOn),
272
275
  addDays(parseISO(startsOn), 6)
273
276
  )
277
+ const calendarWeek = computed(() => (week.value ? parseDate(week.value.weekStartsOn) : undefined))
278
+ const weekLabel = computed(() =>
279
+ week.value
280
+ ? `${t('features.timesheets.weekNumber', { number: getISOWeek(parseISO(week.value.weekStartsOn)) })} · ${formatWeekPeriod(week.value.weekStartsOn)}`
281
+ : '—'
282
+ )
283
+ const selectWeek = (value: CalendarProps<boolean, boolean>['modelValue']) => {
284
+ weekPickerOpen.value = false
285
+ if (pending.value || !value || Array.isArray(value) || !('day' in value) || !week.value) {
286
+ return
287
+ }
288
+ const targetWeek = mondayFor(value.toString())
289
+ if (targetWeek !== week.value.weekStartsOn) {
290
+ selectedWeek.value = targetWeek
291
+ }
292
+ }
274
293
  const hasOtherUnsubmittedHours = (submission: TimesheetSubmissionDto) =>
275
294
  (week.value?.entries ?? []).some(
276
295
  (entry) =>
@@ -646,21 +665,30 @@ const runningDuration = computed(() => {
646
665
  :aria-label="t('features.timesheets.previousWeek')"
647
666
  @click="changeWeek(-1)"
648
667
  />
649
- <UBadge color="neutral" variant="subtle" size="lg" class="relative">
650
- <span
651
- v-if="pending && data"
652
- class="absolute inset-x-0 bottom-0 h-0.5 overflow-hidden rounded-full"
653
- role="status"
654
- :aria-label="t('features.timesheets.loading')"
655
- >
656
- <span class="block h-full w-full animate-pulse bg-primary" />
657
- </span>
658
- {{
659
- week
660
- ? `${t('features.timesheets.weekNumber', { number: getISOWeek(parseISO(week.weekStartsOn)) })} · ${formatWeekPeriod(week.weekStartsOn)}`
661
- : '—'
662
- }}
663
- </UBadge>
668
+ <UPopover v-model:open="weekPickerOpen">
669
+ <UButton
670
+ icon="i-lucide-calendar-days"
671
+ color="neutral"
672
+ variant="subtle"
673
+ :label="weekLabel"
674
+ :aria-label="t('features.timesheets.pickWeek', { week: weekLabel })"
675
+ :loading="pending && !!data"
676
+ :disabled="pending || !week"
677
+ />
678
+ <template #content>
679
+ <UCalendar
680
+ v-if="weekPickerOpen && week"
681
+ :model-value="calendarWeek"
682
+ :week-starts-on="1"
683
+ :locale="locale"
684
+ :aria-label="t('features.timesheets.selectWeek')"
685
+ :ui="{ gridRow: 'has-[[data-selected]]:bg-primary/10 rounded-md' }"
686
+ class="p-2"
687
+ week-numbers
688
+ @update:model-value="selectWeek"
689
+ />
690
+ </template>
691
+ </UPopover>
664
692
  <UButton
665
693
  icon="i-lucide-chevron-right"
666
694
  color="neutral"
@@ -10,6 +10,8 @@
10
10
  "subtitle": "Record your work while the details are still fresh.",
11
11
  "loading": "Loading timesheet…",
12
12
  "previousWeek": "Previous week",
13
+ "pickWeek": "Pick a week, currently {week}",
14
+ "selectWeek": "Select any date to view its week",
13
15
  "nextWeek": "Next week",
14
16
  "projectActivity": "Project / activity",
15
17
  "total": "Total",
@@ -10,6 +10,8 @@
10
10
  "subtitle": "Registreer je werk zolang de details nog vers zijn.",
11
11
  "loading": "Urenstaat laden…",
12
12
  "previousWeek": "Vorige week",
13
+ "pickWeek": "Kies een week, momenteel {week}",
14
+ "selectWeek": "Selecteer een datum om de bijbehorende week te bekijken",
13
15
  "nextWeek": "Volgende week",
14
16
  "projectActivity": "Project / activiteit",
15
17
  "total": "Totaal",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt-customer-portal/timesheets",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "license": "MIT",
5
5
  "homepage": "https://nuxt-customer-portal.com",
6
6
  "repository": {
@@ -36,6 +36,7 @@
36
36
  "access": "public"
37
37
  },
38
38
  "dependencies": {
39
+ "@internationalized/date": "^3.10.0",
39
40
  "@nuxtjs/i18n": "^10.6.0",
40
41
  "@types/pg": "8.15.5",
41
42
  "date-fns": "^4.4.0",
@@ -45,10 +46,10 @@
45
46
  "pg": "^8.22.0",
46
47
  "resend": "^6.18.1",
47
48
  "zod": "^4.4.3",
48
- "@nuxt-customer-portal/core": "^0.10.0",
49
- "@nuxt-customer-portal/clients": "^0.10.0",
50
- "@nuxt-customer-portal/ui": "^0.10.0",
51
- "@nuxt-customer-portal/organizations": "^0.10.0"
49
+ "@nuxt-customer-portal/core": "^0.10.2",
50
+ "@nuxt-customer-portal/clients": "^0.10.2",
51
+ "@nuxt-customer-portal/organizations": "^0.10.2",
52
+ "@nuxt-customer-portal/ui": "^0.10.2"
52
53
  },
53
54
  "peerDependencies": {
54
55
  "nuxt": "^4.5.1",
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  id: 'timesheets',
3
- version: '0.10.0',
3
+ version: '0.10.2',
4
4
  source: '@nuxt-customer-portal/timesheets',
5
5
  clientModuleId: 'timesheets',
6
6
  dependsOn: ['core', 'ui', 'organizations', 'clients'],