diff --git a/src/components/form/OptionDropdown.tsx b/src/components/form/OptionDropdown.tsx new file mode 100644 index 0000000..58df167 --- /dev/null +++ b/src/components/form/OptionDropdown.tsx @@ -0,0 +1,52 @@ +import { JSXOutput, QRL, component$, useVisibleTask$ } from '@builder.io/qwik'; +import { initFlowbite } from 'flowbite'; +import { Button } from '../Button'; + +interface optionDropdownInterface { + id: string; + icon: JSXOutput; + label?: string; + options: { value: string; onChange: QRL }[]; + hidden?: boolean; +} + +export const OptionDropdown = component$( + ({ id, icon, label, options, hidden }) => { + const buttonId = `dropdown-menu-icon-button-${id}`; + const dropdownId = `dropdown-dots-${id}`; + + useVisibleTask$(() => { + initFlowbite(); + }); + + return ( + + ); + } +); diff --git a/src/components/report/GropuByList.tsx b/src/components/report/GropuByList.tsx index aae047e..189a9be 100644 --- a/src/components/report/GropuByList.tsx +++ b/src/components/report/GropuByList.tsx @@ -1,11 +1,12 @@ -import { component$, Signal, useSignal } from '@builder.io/qwik'; +import { $, component$, Signal, useSignal } from '@builder.io/qwik'; import { ReportTimeEntry } from '@models/report'; import { useGroupList } from 'src/hooks/report/useGroupList'; import { t } from 'src/locale/labels'; import { getReportTotalHours } from 'src/utils/chart'; +import { handlePrint } from 'src/utils/handlePrint'; import { getFormattedHours } from 'src/utils/timesheet'; import { UUID } from 'src/utils/uuid'; -import { Button } from '../Button'; +import { OptionDropdown } from '../form/OptionDropdown'; import { Select } from '../form/Select'; import { getIcon } from '../icons'; @@ -29,10 +30,16 @@ export const GroupByList = component$(({ data, from, to }) => } = useGroupList(data, from, to); const _selectOptions = useSignal(selectOptions); + const groupByRef = useSignal(); return ( -
-
+
+ +
{t('GROUP_BY_LABEL')} @@ -61,11 +68,21 @@ export const GroupByList = component$(({ data, from, to }) =>
- + handlePrint(groupByRef)), + }, + ]} + />
diff --git a/src/components/report/ProjectReportDetails.tsx b/src/components/report/ProjectReportDetails.tsx index 32d4c7b..bbc91bc 100644 --- a/src/components/report/ProjectReportDetails.tsx +++ b/src/components/report/ProjectReportDetails.tsx @@ -19,121 +19,116 @@ interface ProjectReportDetailsProps { data: ReportTimeEntry[]; from: Signal; to: Signal; - ref: Signal; } -export const ProjectReportDetails = component$( - ({ data, from, to, ref }) => { - const daysSeries = useComputed$(() => { - return columnChartSeriesAdapter(data, from.value, to.value); - }); - // ____ PROJECTS _____ // - const groupByProjectSeries = useComputed$(() => { - return donutChartGroupByProjectsAdapter(data); - }); - - const listGroupByProjectSeries = useComputed$(() => { - return listGroupByProjectsAdapter(data); - }); - - // ____ USERS _____ // - - const groupByUserSeries = useComputed$(() => { - return donutChartGroupByUsesAdapter(data); - }); - - const listGroupByUserSeries = useComputed$(() => { - return listGroupByUsersAdapter(data); - }); - - // ____ TASK _____ // - - const groupByTaskSeries = useComputed$(() => { - return donutChartGroupByTaskAdapter(data); - }); - - const listGroupByTaskSeries = useComputed$(() => { - return listGroupByTaskAdapter(data); - }); - - return ( -
- - - {/* ____ PROJECTS _____ */} - - {groupByProjectSeries.value.series.length > 0 && - listGroupByProjectSeries.value.length > 0 && ( -
-
-

- {t('PROJECT_LABEL')} -

-
+export const ProjectReportDetails = component$(({ data, from, to }) => { + const daysSeries = useComputed$(() => { + return columnChartSeriesAdapter(data, from.value, to.value); + }); + // ____ PROJECTS _____ // + const groupByProjectSeries = useComputed$(() => { + return donutChartGroupByProjectsAdapter(data); + }); -
-
- -
-
+ const listGroupByProjectSeries = useComputed$(() => { + return listGroupByProjectsAdapter(data); + }); + + // ____ USERS _____ // + + const groupByUserSeries = useComputed$(() => { + return donutChartGroupByUsesAdapter(data); + }); + + const listGroupByUserSeries = useComputed$(() => { + return listGroupByUsersAdapter(data); + }); + + // ____ TASK _____ // + + const groupByTaskSeries = useComputed$(() => { + return donutChartGroupByTaskAdapter(data); + }); + + const listGroupByTaskSeries = useComputed$(() => { + return listGroupByTaskAdapter(data); + }); + + return ( +
+ + + {/* ____ PROJECTS _____ */} + + {groupByProjectSeries.value.series.length > 0 && + listGroupByProjectSeries.value.length > 0 && ( +
+
+

{t('PROJECT_LABEL')}

+
-
- +
+
+
- )} - {/* ____ USERS _____ */} +
+ +
+
+ )} - {groupByUserSeries.value.series.length > 0 && - listGroupByUserSeries.value.length > 0 && ( -
-
-

{t('USER_LABEL')}

-
+ {/* ____ USERS _____ */} -
-
- -
-
+ {groupByUserSeries.value.series.length > 0 && + listGroupByUserSeries.value.length > 0 && ( +
+
+

{t('USER_LABEL')}

+
-
- +
+
+
- )} - {/* ____ TASK _____ */} +
+ +
+
+ )} - {groupByTaskSeries.value.series.length > 0 && - listGroupByTaskSeries.value.length > 0 && ( -
-
-

{t('TASK_LABEL')}

-
+ {/* ____ TASK _____ */} -
-
- -
-
+ {groupByTaskSeries.value.series.length > 0 && + listGroupByTaskSeries.value.length > 0 && ( +
+
+

{t('TASK_LABEL')}

+
-
- +
+
+
- )} -
- ); - } -); + +
+ +
+
+ )} +
+ ); +}); diff --git a/src/components/report/ProjectReportPreview.tsx b/src/components/report/ProjectReportPreview.tsx index d4efddb..e818c85 100644 --- a/src/components/report/ProjectReportPreview.tsx +++ b/src/components/report/ProjectReportPreview.tsx @@ -14,41 +14,38 @@ interface ProjectReportPreviewProps { data: ReportTimeEntry[]; from: Signal; to: Signal; - ref: Signal; } -export const ProjectReportPreview = component$( - ({ data, from, to, ref }) => { - const daysSeries = useComputed$(() => { - return columnChartSeriesAdapter(data, from.value, to.value); - }); +export const ProjectReportPreview = component$(({ data, from, to }) => { + const daysSeries = useComputed$(() => { + return columnChartSeriesAdapter(data, from.value, to.value); + }); - // ____ PROJECTS _____ // - const groupByProjectSeries = useComputed$(() => { - return donutChartGroupByProjectsAdapter(data); - }); + // ____ PROJECTS _____ // + const groupByProjectSeries = useComputed$(() => { + return donutChartGroupByProjectsAdapter(data); + }); - const listGroupByProjectSeries = useComputed$(() => { - return listGroupByProjectsAdapter(data); - }); + const listGroupByProjectSeries = useComputed$(() => { + return listGroupByProjectsAdapter(data); + }); - return ( -
-
-
- -
- -
- -
+ return ( +
+
+
+
- +
+ +
- ); - } -); + + +
+ ); +}); diff --git a/src/components/report/ProjectsSection.tsx b/src/components/report/ProjectsSection.tsx index 686646f..43f99b6 100644 --- a/src/components/report/ProjectsSection.tsx +++ b/src/components/report/ProjectsSection.tsx @@ -4,6 +4,7 @@ import { ReportTab } from '@models/report'; import { Task } from '@models/task'; import { UserProfile } from '@models/user'; import { useReportProject } from 'src/hooks/report/useReportProject'; +import { getIcon } from '../icons'; import { GroupByList } from './GropuByList'; import { ProjectReportDetails } from './ProjectReportDetails'; import { ProjectReportPreview } from './ProjectReportPreview'; @@ -61,7 +62,13 @@ export const ProjectsSection = component$( return ( <> {showProjectsDetails.value ? ( -
+
+ + ( to={to} /> - + {projectResults.value.length > 0 && ( )}
) : ( -
+
+ + ( showTopProject /> - + {projectResults.value.length > 0 && ( diff --git a/src/components/report/ReportHeader.tsx b/src/components/report/ReportHeader.tsx index 60bd323..b995d2f 100644 --- a/src/components/report/ReportHeader.tsx +++ b/src/components/report/ReportHeader.tsx @@ -17,7 +17,7 @@ import { getReportCSV } from 'src/utils/report'; import { getFormattedHours } from 'src/utils/timesheet'; import { CSV_REPORT_PROJECTS_FILE_NAME } from '../../utils/constants'; import { capitalizeString } from '../../utils/string'; -import { Button } from '../Button'; +import { OptionDropdown } from '../form/OptionDropdown'; import { ToggleSwitch } from '../form/ToggleSwitch'; import { getIcon } from '../icons'; @@ -80,11 +80,12 @@ export const ReportHeader = component$(

{t('TIMESHEET_TABLE_PROJECT_COL_LABEL')}

- - +
+ +
@@ -118,18 +119,22 @@ export const ReportHeader = component$( )}
-
- - - +
+ handlePrint(printableComponent)), + }, + ]} + />
diff --git a/src/locale/en.json b/src/locale/en.json index b84549f..6b3b900 100644 --- a/src/locale/en.json +++ b/src/locale/en.json @@ -148,8 +148,9 @@ "NONE_LABEL": "(none)", "EMPTY_LABEL": "(empty)", "ADD_TIME_ENTRY_LABEL": "add time entry", - "REPORT_DOWNLOAD_PDF_LABEL": "Download report", - "REPORT_DOWNLOAD_CSV_LABEL": "Download CSV", + "PDF_LABEL": "PDF", + "CSV_LABEL": "CSV", + "REPORT_DOWNLOAD_LABEL": "Download report", "TIMESHEET_REPORT_AFTER_HOURS_ONLY": "Show after hours only", "SELECT_ALL_LABEL": "Select all" } diff --git a/src/utils/handlePrint.ts b/src/utils/handlePrint.ts index a44e301..4ed37ee 100644 --- a/src/utils/handlePrint.ts +++ b/src/utils/handlePrint.ts @@ -4,6 +4,12 @@ export const handlePrint = $((ref: Signal) => { const printContent = ref.value; if (printContent) { const originalContents = document.body.innerHTML; + + printContent + .querySelectorAll('.hide-on-pdf-download') + .forEach((el) => el.classList.add('hidden')); + printContent.querySelectorAll('.brickly-logo-pdf-download')[0].classList.remove('hidden'); + document.body.innerHTML = printContent.innerHTML; window.print(); document.body.innerHTML = originalContents;