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"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import { extractData } from "@/utils/data";
import { generateIcsCalendar } from "ts-ics"; 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 error = ref<string | null>(null);
const onPlanningPage = ref(false);
onMounted(async () => (onPlanningPage.value = await isPlanningUrl()));
const downloadCalendar = async () => { const downloadCalendar = async () => {
error.value = null; error.value = null;
@@ -60,7 +66,7 @@ const downloadCalendar = async () => {
</template> </template>
<div class="space-y-4"> <div class="space-y-4">
<div class="space-y-2"> <div v-if="onPlanningPage" class="space-y-2">
<UButton <UButton
loading-auto loading-auto
label="Download Calendar" label="Download Calendar"
@@ -79,6 +85,18 @@ const downloadCalendar = async () => {
/> />
</div> </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 <UButton
label="Import in Google Calendar" label="Import in Google Calendar"
icon="i-lucide-external-link" icon="i-lucide-external-link"

View File

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