diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html
index c4eb604..b74736b 100644
--- a/src/app/components/settings/settings.component.html
+++ b/src/app/components/settings/settings.component.html
@@ -12,10 +12,18 @@
Basic settings
Export
+ Export everything
This will export everything, all tracked times, all your settings.
+ CSV Export
+ This will export your times as CSV.
+
+
+
+
+
diff --git a/src/app/components/settings/settings.component.ts b/src/app/components/settings/settings.component.ts
index 7554403..beeb10b 100644
--- a/src/app/components/settings/settings.component.ts
+++ b/src/app/components/settings/settings.component.ts
@@ -5,7 +5,7 @@ import { SettingsFormComponent } from './settings-form/settings-form.component';
import { PageTitleComponent } from '../page-title/page-title.component';
import { DatabaseService } from '../../services/database/database.service';
import { DateTime } from 'luxon';
-import { dateTimeToLocaleData } from '../../services/time.utils';
+import { dateTimeToLocaleData, millisecondsToHumanReadable } from '../../services/time.utils';
import { FileDirective } from '../../directives/file.directive';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { TauriService } from '../../services/tauri.service';
@@ -13,6 +13,8 @@ import { CardComponent } from '../card/card.component';
import { CardSectionTitleComponent } from '../card/card-section-title/card-section-title.component';
import { Settings } from '../../services/settings/settings';
import { LoadingSpinnerComponent } from '../loading-spinner/loading-spinner.component';
+import { TimeTable } from '../../services/time-tracking/time.table';
+import { firstValueFrom } from 'rxjs';
@Component({
selector: 'kw-settings',
@@ -37,12 +39,47 @@ export default class SettingsComponent {
private readonly settingsTable = inject(SettingsTable);
protected readonly settings$ = this.settingsTable.current$;
private readonly tauriService = inject(TauriService);
+ private readonly timeTable = inject(TimeTable);
protected async export(): Promise {
const blob = await this.databaseService.exportToBlob();
await this.tauriService.save(blob, `KuwakaWakati-${dateTimeToLocaleData(DateTime.now())}.json`);
}
+ protected async exportCSV(days: number): Promise {
+ const today = DateTime.now().set({ hour: 0, minute: 0, second: 0, millisecond: 0 });
+ const startDay = today.minus({ day: days });
+ const items = await firstValueFrom(this.timeTable.groupByDay$(startDay.toMillis(), today.toMillis()));
+ const rows = items.flatMap(item => [
+ ['Date', 'Start Time', 'End Time', 'Duration', 'Is A Day Off?', 'Is a non work day?', 'description'],
+ ...item.items.map(timeEntry => [
+ DateTime.fromMillis(item.utcDate).toISODate(),
+ DateTime.fromMillis(timeEntry.start).toISOTime({
+ includeOffset: false,
+ includePrefix: false,
+ suppressMilliseconds: true,
+ suppressSeconds: true,
+ extendedZone: false,
+ }),
+ DateTime.fromMillis(timeEntry.end).toISOTime({
+ includeOffset: false,
+ includePrefix: false,
+ suppressMilliseconds: true,
+ suppressSeconds: true,
+ extendedZone: false,
+ }),
+ millisecondsToHumanReadable(timeEntry.duration.toMillis()),
+ timeEntry.isADayOff,
+ timeEntry.isNonWorkday,
+ timeEntry.description,
+ ]),
+ ]);
+
+ const csv = rows.map(row => row.join(',')).join('\n');
+ const csvBlob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
+ await this.tauriService.save(csvBlob, `KuwakaWakati-${days}days-${dateTimeToLocaleData(DateTime.now())}.csv`);
+ }
+
protected async import(): Promise {
if (!this.fileControl.value) {
return;
diff --git a/src/app/services/time-tracking/time.table.ts b/src/app/services/time-tracking/time.table.ts
index 1dde353..206b27d 100644
--- a/src/app/services/time-tracking/time.table.ts
+++ b/src/app/services/time-tracking/time.table.ts
@@ -43,7 +43,7 @@ export class TimeTable implements DatabaseTable {
todayGroup$(): Observable {
const todayDate = todayDateMilliseconds();
- return this.groupByDay$(todayDate, todayDate + 1).pipe(
+ return this.groupByDay$(todayDate, todayDate).pipe(
map(([today]) => {
if (!today) {
return {
@@ -61,7 +61,7 @@ export class TimeTable implements DatabaseTable {
}
private async items(fromTimestamp: Milliseconds = 0, toTimestamp: Milliseconds = Number.MAX_SAFE_INTEGER): Promise {
- const items = await this.times.where('utcDate').between(fromTimestamp, toTimestamp, true).toArray();
+ const items = await this.times.where('utcDate').between(fromTimestamp, toTimestamp, true, true).toArray();
items.sort((a, b) => {
if (a.utcDate < b.utcDate) {
return 1;