diff --git a/resources/js/Components/Common/Reporting/ReportingGroupBySelect.vue b/resources/js/Components/Common/Reporting/ReportingGroupBySelect.vue
index 73a48eaa..1a1a0763 100644
--- a/resources/js/Components/Common/Reporting/ReportingGroupBySelect.vue
+++ b/resources/js/Components/Common/Reporting/ReportingGroupBySelect.vue
@@ -1,50 +1,19 @@
diff --git a/resources/js/Pages/Reporting.vue b/resources/js/Pages/Reporting.vue
index 91c528ed..c8437b03 100644
--- a/resources/js/Pages/Reporting.vue
+++ b/resources/js/Pages/Reporting.vue
@@ -14,7 +14,7 @@ import ReportingChart from '@/Components/Common/Reporting/ReportingChart.vue';
import BillableIcon from '@/Components/Common/Icons/BillableIcon.vue';
import { onMounted, ref } from 'vue';
import { formatHumanReadableDuration, getDayJsInstance } from '@/utils/time';
-import { useReportingStore } from '@/utils/useReporting';
+import { type GroupingOption, useReportingStore } from '@/utils/useReporting';
import { storeToRefs } from 'pinia';
import TagDropdown from '@/Components/Common/Tag/TagDropdown.vue';
import type { AggregatedTimeEntriesQueryParams } from '@/utils/api';
@@ -42,11 +42,16 @@ const selectedClients = ref([]);
const billable = ref<'true' | 'false' | null>(null);
-type GroupingOption = 'project' | 'task' | 'user' | 'billable' | 'client';
-
const group = ref('project');
const subGroup = ref('task');
+const reportingStore = useReportingStore();
+
+const { aggregatedGraphTimeEntries, aggregatedTableTimeEntries } =
+ storeToRefs(reportingStore);
+
+const { groupByOptions } = reportingStore;
+
function getFilterAttributes() {
let params: AggregatedTimeEntriesQueryParams = {
start: getDayJsInstance()(startDate.value).utc().format(),
@@ -90,6 +95,14 @@ function updateGraphReporting() {
function updateTableReporting() {
const params = getFilterAttributes();
+ if (group.value === subGroup.value) {
+ const fallbackOption = groupByOptions.find(
+ (el) => el.value !== group.value
+ );
+ if (fallbackOption?.value) {
+ subGroup.value = fallbackOption.value;
+ }
+ }
if (getCurrentRole() === 'employee') {
params.member_id = getCurrentMembershipId();
}
@@ -103,11 +116,6 @@ function updateReporting() {
updateTableReporting();
}
-const reportingStore = useReportingStore();
-
-const { aggregatedGraphTimeEntries, aggregatedTableTimeEntries } =
- storeToRefs(reportingStore);
-
function getOptimalGroupingOption(diff: number): 'day' | 'week' | 'month' {
if (diff <= 31) {
return 'day';
@@ -248,10 +256,16 @@ onMounted(() => {
class="text-sm flex text-white items-center space-x-3 font-medium px-6 border-b border-card-background-separator pb-3">
Group by
and
diff --git a/resources/js/utils/useReporting.ts b/resources/js/utils/useReporting.ts
index 5b7ac402..bb7d39c3 100644
--- a/resources/js/utils/useReporting.ts
+++ b/resources/js/utils/useReporting.ts
@@ -1,6 +1,6 @@
import { defineStore, storeToRefs } from 'pinia';
import { api } from '../../../openapi.json.client';
-import { computed, ref } from 'vue';
+import { type Component, computed, ref } from 'vue';
import type {
AggregatedTimeEntries,
AggregatedTimeEntriesQueryParams,
@@ -12,6 +12,20 @@ import { useProjectsStore } from '@/utils/useProjects';
import { useMembersStore } from '@/utils/useMembers';
import { useTasksStore } from '@/utils/useTasks';
import { useClientsStore } from '@/utils/useClients';
+import {
+ CheckCircleIcon,
+ UserCircleIcon,
+ UserGroupIcon,
+} from '@heroicons/vue/20/solid';
+import { FolderIcon } from '@heroicons/vue/16/solid';
+import BillableIcon from '@/Components/Common/Icons/BillableIcon.vue';
+
+export type GroupingOption =
+ | 'project'
+ | 'task'
+ | 'user'
+ | 'billable'
+ | 'client';
export const useReportingStore = defineStore('reporting', () => {
const reportingGraphResponse = ref(null);
@@ -112,11 +126,44 @@ export const useReportingStore = defineStore('reporting', () => {
return key;
}
+ const groupByOptions: {
+ label: string;
+ value: GroupingOption;
+ icon: Component;
+ }[] = [
+ {
+ label: 'Members',
+ value: 'user',
+ icon: UserGroupIcon,
+ },
+ {
+ label: 'Projects',
+ value: 'project',
+ icon: FolderIcon,
+ },
+ {
+ label: 'Tasks',
+ value: 'task',
+ icon: CheckCircleIcon,
+ },
+ {
+ label: 'Clients',
+ value: 'client',
+ icon: UserCircleIcon,
+ },
+ {
+ label: 'Billable',
+ value: 'billable',
+ icon: BillableIcon,
+ },
+ ];
+
return {
aggregatedGraphTimeEntries,
fetchGraphReporting,
fetchTableReporting,
aggregatedTableTimeEntries,
getNameForReportingRowEntry,
+ groupByOptions,
};
});