feat: load year and month from page, and provide link to planning

This commit is contained in:
Pihkaal
2025-11-05 18:15:51 +01:00
parent eb08d76bf2
commit d6850fb2cb
3 changed files with 86 additions and 49 deletions

View File

@@ -1,10 +1,16 @@
<script setup lang="ts">
import { ref } from "vue";
import { extractData } from "@/utils/data";
import { generateIcsCalendar } from "ts-ics";
import { extractData } from "@/utils/data";
import { isPlanningUrl } from "@/utils/url";
import { onMounted } from "vue";
const error = ref<string | null>(null);
const onPlanningPage = ref(false);
onMounted(async () => (onPlanningPage.value = await isPlanningUrl()));
const downloadCalendar = async () => {
error.value = null;
@@ -60,7 +66,7 @@ const downloadCalendar = async () => {
</template>
<div class="space-y-4">
<div class="space-y-2">
<div v-if="onPlanningPage" class="space-y-2">
<UButton
loading-auto
label="Download Calendar"
@@ -79,6 +85,18 @@ const downloadCalendar = async () => {
/>
</div>
<UButton
v-else
label="Go to my planning"
icon="i-lucide-calendar"
size="lg"
block
color="secondary"
variant="subtle"
to="https://gestime.aphp.fr/planning/agent"
target="_blank"
/>
<UButton
label="Import in Google Calendar"
icon="i-lucide-external-link"

View File

@@ -1,4 +1,5 @@
import type { IcsCalendar, IcsEvent } from "ts-ics";
import { isPlanningUrl } from "./url";
type WorkEvent = {
day: number;
@@ -47,29 +48,16 @@ const makeIcsCalendar = (events: IcsEvent[]): IcsCalendar => ({
events,
});
export async function extractData(): Promise<{
name: string;
data: IcsCalendar;
}> {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
if (!tab?.id) {
throw new Error("URL incorrecte");
}
const dataExtractor = () => {
// extract year and month
const monthSelect = document.getElementById(
"select-pagemois",
) as HTMLSelectElement;
const yearSelect = document.getElementById(
"select-pagean",
) as HTMLSelectElement;
const urlMatch = tab.url?.match(/\/(\d{2})-(\d{4})$/);
if (!urlMatch) {
throw new Error("URL incorrecte");
}
const year = parseInt(urlMatch[2]!);
const month = parseInt(urlMatch[1]!);
try {
const [eventsQuery] = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: () => {
// extract events
const trs = document.querySelectorAll("#clearfix-individuel table tr");
const events: WorkEvent[] = [];
@@ -100,17 +88,38 @@ export async function extractData(): Promise<{
});
}
return events;
},
return {
month: parseInt(monthSelect.value),
year: parseInt(yearSelect.value),
events,
};
};
export async function extractData(): Promise<{
name: string;
data: IcsCalendar;
}> {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
if (!eventsQuery?.result) throw undefined;
if (!tab?.id || !(await isPlanningUrl())) {
throw new Error("URL incorrecte");
}
try {
const [query] = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: dataExtractor,
});
if (!query?.result) throw undefined;
const { year, month, events } = query.result;
return {
name: `gestime-${urlMatch[1]}-${urlMatch[2]}.ics`,
name: `gestime-${year}-${month}.ics`,
data: makeIcsCalendar(
eventsQuery.result.map((event) =>
makeIcsEvent({ year, month, ...event }),
),
events.map((event) => makeIcsEvent({ year, month, ...event })),
),
};
} catch {

10
src/utils/url.ts Normal file
View File

@@ -0,0 +1,10 @@
export const isPlanningUrl = async () => {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
return (
tab?.url !== undefined &&
tab.url.startsWith("https://gestime.aphp.fr/planning/agent")
);
};