Skip to content

Commit

Permalink
Update personio extension
Browse files Browse the repository at this point in the history
- Merge pull request raycast#29 from marcjulianschwarz/27-stats
- add stats to attendances command
- update cache logs
  • Loading branch information
Boosteblume committed Apr 11, 2024
1 parent db6b3ba commit 766a03e
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
41 changes: 40 additions & 1 deletion extensions/personio/src/api/attendances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface AttendancePeriod {
date: string;
start_time: string;
end_time: string;
duration: number;
break: number;
comment: string;
updated_at: string;
Expand All @@ -40,6 +41,43 @@ function daysInMonth(year: number, month: number) {
return new Date(year, month, 0).getDate();
}

function hoursBetween(time1: string, time2: string): number {
const date1 = Date.parse(`1970-01-01T${time1}Z`);
const date2 = Date.parse(`1970-01-01T${time2}Z`);

const diffInMs = Math.abs(date2 - date1);

return diffInMs / 1000 / 60 / 60;
}

export function hoursToNiceString(hours: number): string {
const whole_hours = Math.floor(hours);
const remaining_time = hours - whole_hours;
const minutes = Math.round(60 * remaining_time);
if (minutes > 0 && hours > 0) {
return `${whole_hours} hours and ${minutes} minutes`;
} else if (hours > 0 && minutes == 0) {
return `${whole_hours} hours`;
} else if (hours == 0 && minutes > 0) {
return `${minutes} minutes`;
} else {
return "0 minutes";
}
}

export function uniqueDateFilter(arr: AttendancePeriod[]) {
const dateSet = new Set<string>();

return arr.filter((obj) => {
if (dateSet.has(obj.date)) {
return false;
} else {
dateSet.add(obj.date);
return true;
}
});
}

export async function getAttendancesAPI(
employeeNumber: number,
token: string,
Expand Down Expand Up @@ -67,6 +105,7 @@ export async function getAttendancesAPI(
date: a.attributes.date,
start_time: a.attributes.start_time,
end_time: a.attributes.end_time,
duration: hoursBetween(a.attributes.end_time, a.attributes.start_time),
break: a.attributes.break,
comment: a.attributes.comment,
updated_at: a.attributes.updated_at,
Expand Down Expand Up @@ -100,7 +139,7 @@ export async function getAttendances(
return JSON.parse(attendances) as AttendancePeriod[];
} else {
const attendances = await getAttendancesAPI(employeeNumber, token, currentYear, selectedMonth);
cache.set(key, JSON.stringify(attendances), 23 * 60);
cache.set(key, JSON.stringify(attendances), 30);
return attendances;
}
}
5 changes: 4 additions & 1 deletion extensions/personio/src/api/cache.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ export class MyCache {
// Calculate whether the entry is expired (more living minutes than it should have)
// Return the entry only when it exists and when is is not yet expired
if (data) {
console.log(`Found ${key} in cache`);
const cacheEntry = JSON.parse(data) as CacheEntry;
const livingMinutes = getMinutesBetweenDates(new Date(cacheEntry.createdAt), new Date());
if (livingMinutes < cacheEntry.expiresInMinutes) {
console.log(`Found ${key} in cache`);
console.log(
`Cache is not yet expired, ${key} is expiring in ${cacheEntry.expiresInMinutes - livingMinutes} minutes.`,
);
return cacheEntry.data;
} else {
console.log(`${key} is expired`);
Expand Down
42 changes: 38 additions & 4 deletions extensions/personio/src/attendances.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { List, getPreferenceValues } from "@raycast/api";
import { Action, ActionPanel, List, getPreferenceValues } from "@raycast/api";
import { getPersonioToken } from "./api/api";
import { useEffect, useState } from "react";
import { AttendancePeriod, getAttendances } from "./api/attendances";
import { AttendancePeriod, getAttendances, hoursToNiceString, uniqueDateFilter } from "./api/attendances";

const months = [
"January",
Expand All @@ -25,6 +25,7 @@ export default function Attendances() {

const [attendances, setAttendances] = useState<AttendancePeriod[]>([]);
const [selectedMonth, setSelectedMonth] = useState(currentMonth);
const [rerunFetchTrigger, setRerunFetchTrigger] = useState(true);

const paddedMonth = (selectedMonth + 1).toString().padStart(2, "0");

Expand All @@ -44,12 +45,27 @@ export default function Attendances() {
setAttendances(sortedAttendances);
}
fetchAttendances();
}, [selectedMonth]);
}, [selectedMonth, rerunFetchTrigger]);

function computeTotalHours() {
let totalHours = 0;
for (const attendance of attendances) {
totalHours = totalHours + attendance.duration;
}
console.log(`Total hours this month: ${hoursToNiceString(totalHours)}`);
return totalHours;
}

function computeAttendanceDays() {
const attendanceDays = uniqueDateFilter(attendances).length;
console.log(`Total working days this month: ${attendanceDays}`);
return attendanceDays;
}

return (
<List
isShowingDetail={true}
isLoading={attendances.length == 0}
// isLoading={attendances.length == 0}
searchBarAccessory={
<List.Dropdown
tooltip="Select Month and Year"
Expand Down Expand Up @@ -78,6 +94,10 @@ export default function Attendances() {
<List.Item.Detail.Metadata.Label title="Date" text={attendance.date || "-"} />
<List.Item.Detail.Metadata.Label title="Start" text={attendance.start_time || "-"} />
<List.Item.Detail.Metadata.Label title="End" text={attendance.end_time || "-"} />
<List.Item.Detail.Metadata.Label
title="Duration"
text={hoursToNiceString(attendance.duration) || "-"}
/>
<List.Item.Detail.Metadata.Label title="Break" text={attendance.break.toString() + " minutes"} />
<List.Item.Detail.Metadata.Label title="Updated At" text={attendance.updated_at || "-"} />
<List.Item.Detail.Metadata.Label title="Acceptance Status" text={attendance.status || "-"} />
Expand All @@ -90,10 +110,24 @@ export default function Attendances() {
)}
</List.Item.Detail.Metadata.TagList>
<List.Item.Detail.Metadata.Label title="Comment" text={attendance.comment || "-"} />
<List.Item.Detail.Metadata.Separator />
<List.Item.Detail.Metadata.Label
title={`Total Hours in ${months[selectedMonth]}`}
text={hoursToNiceString(computeTotalHours())}
/>
<List.Item.Detail.Metadata.Label
title={`Total Attendances in ${months[selectedMonth]}`}
text={computeAttendanceDays().toString()}
/>
</List.Item.Detail.Metadata>
}
/>
}
actions={
<ActionPanel>
<Action title="Refresh Data" onAction={() => setRerunFetchTrigger(!rerunFetchTrigger)} />
</ActionPanel>
}
/>
))}
</List>
Expand Down

0 comments on commit 766a03e

Please sign in to comment.