feat: updates to the timeline

This commit is contained in:
Andre Henriques 2024-10-17 19:01:11 +01:00
parent 4890508be8
commit dd047c0bcf
5 changed files with 104 additions and 35 deletions

View File

@ -12,7 +12,8 @@ export const ApplicationStatus = Object.freeze({
Expired: 5, Expired: 5,
TasksToDo: 6, TasksToDo: 6,
LinkedApplication: 7, LinkedApplication: 7,
InterviewStep1: 8 InterviewStep1: 8,
InterviewStep2: 9
}); });
export const ApplicationStatusIconMaping: Record<AsEnum<typeof ApplicationStatus>, string> = Object.freeze({ export const ApplicationStatusIconMaping: Record<AsEnum<typeof ApplicationStatus>, string> = Object.freeze({
@ -24,7 +25,8 @@ export const ApplicationStatusIconMaping: Record<AsEnum<typeof ApplicationStatus
5: 'hourglass-bottom', 5: 'hourglass-bottom',
6: 'list-check', 6: 'list-check',
7: 'link-45deg', 7: 'link-45deg',
8: 'person' 8: 'person',
9: 'people'
}); });
export const ApplicationStatusMaping: Record<AsEnum<typeof ApplicationStatus>, string> = Object.freeze({ export const ApplicationStatusMaping: Record<AsEnum<typeof ApplicationStatus>, string> = Object.freeze({
@ -36,7 +38,8 @@ export const ApplicationStatusMaping: Record<AsEnum<typeof ApplicationStatus>, s
5: 'Expired', 5: 'Expired',
6: 'Tasks To Do', 6: 'Tasks To Do',
7: 'Linked Application', 7: 'Linked Application',
8: 'Interview 1' 8: 'Interview 1',
9: 'Interview 2'
}); });
export type View = { export type View = {

View File

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import { applicationStore } from '$lib/ApplicationsStore.svelte'; import { applicationStore } from '$lib/ApplicationsStore.svelte';
import { get } from '$lib/utils';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
onMount(() => { onMount(() => {
@ -30,7 +31,9 @@
}) as item} }) as item}
<button <button
class="card p-2 my-2 bg-slate-100 w-full text-left" class="card p-2 my-2 bg-slate-100 w-full text-left"
onclick={() => { onclick={async () => {
item.views = await get(`view/${item.id}`);
item.events = await get(`events/${item.id}`);
applicationStore.loadItem = item; applicationStore.loadItem = item;
window.scrollTo({ window.scrollTo({
top: 0, top: 0,

View File

@ -112,6 +112,12 @@
return; return;
} }
} }
if (history.includes(`${ApplicationStatus.InterviewStep2}`)) {
source = addGraph(source, ApplicationStatus.InterviewStep2);
if (a.status == ApplicationStatus.InterviewStep2) {
return;
}
}
addGraph(source, ApplicationStatus.ApplyedButSaidNo); addGraph(source, ApplicationStatus.ApplyedButSaidNo);
}); });

View File

@ -5,9 +5,7 @@
ApplicationStatus, ApplicationStatus,
EventType, EventType,
ApplicationStatusIconMaping, ApplicationStatusIconMaping,
ApplicationStatusMaping ApplicationStatusMaping
} from '$lib/ApplicationsStore.svelte'; } from '$lib/ApplicationsStore.svelte';
let { application }: { application: Application } = $props(); let { application }: { application: Application } = $props();
@ -51,7 +49,6 @@
for (let event of application.events) { for (let event of application.events) {
let time = ''; let time = '';
if (lastEvent) { if (lastEvent) {
let d1 = new Date(lastEvent.time).getTime(); let d1 = new Date(lastEvent.time).getTime();
let d2 = new Date(event.time).getTime(); let d2 = new Date(event.time).getTime();
@ -62,19 +59,42 @@
status = ApplicationStatus.ToApply; status = ApplicationStatus.ToApply;
} }
if (event.event_type !== EventType.StatusUpdate) { if (event.event_type !== EventType.StatusUpdate) {
_events.push({ ...event, timeDiff: time }); if (time) {
_events[_events.length - 1].timeDiff = time;
}
_events.push({ ...event, timeDiff: '' });
lastEvent = event; lastEvent = event;
continue; continue;
} }
if (checkArray.includes(status) && checkArray.includes(event.new_status) && lastEvent?.event_type !== EventType.Creation ) { if (
checkArray.includes(status) &&
checkArray.includes(event.new_status) &&
lastEvent?.event_type !== EventType.Creation
) {
continue; continue;
} }
if (lastEvent) {
let d1 = new Date(lastEvent.time).getTime();
let d2 = new Date(event.time).getTime();
time = calcDiff(d2 - d1);
}
if (time) {
_events[_events.length - 1].timeDiff = time;
}
status = event.new_status; status = event.new_status;
_events.push({ ...event, timeDiff: time }); _events.push({ ...event, timeDiff: '' });
lastEvent = event; lastEvent = event;
} }
if (_events.length > 0 && !endable.includes(_events[_events.length - 1].new_status)) {
let d1 = new Date(_events[_events.length - 1].time).getTime();
let d2 = new Date().getTime();
_events[_events.length - 1].timeDiff = calcDiff(d2 - d1);
}
events = _events; events = _events;
}); });
@ -91,9 +111,7 @@
<div class="flex p-5 items-center"> <div class="flex p-5 items-center">
{#each events as event, i} {#each events as event, i}
{#if i === 0 && event.event_type !== EventType.Creation} {#if i === 0 && event.event_type !== EventType.Creation}
<div class="min-w-[70px] h-[15px] bg-blue-500 -mx-[10px]"> <div class="min-w-[70px] h-[15px] bg-blue-500 -mx-[10px]"></div>
{event.timeDiff}
</div>
{/if} {/if}
<div <div
@ -102,15 +120,30 @@
{#if event.event_type == EventType.Creation} {#if event.event_type == EventType.Creation}
<span class="bi bi-plus"></span> <span class="bi bi-plus"></span>
{:else if event.event_type == EventType.View} {:else if event.event_type == EventType.View}
<span class="bi bi-eye"></span> <span
title="Views {new Date(event.time).toLocaleString()}"
class="bi bi-eye"
></span>
{:else} {:else}
<span title={ApplicationStatusMaping[event.new_status]} class="bi bi-{ApplicationStatusIconMaping[event.new_status]}"></span> <span
title={`${ApplicationStatusMaping[event.new_status]}\n${new Date(
event.time
).toLocaleString()}`}
class="bi bi-{ApplicationStatusIconMaping[event.new_status]}"
></span>
{/if} {/if}
</div> </div>
{#if i != events.length - 1 || !endable.includes(event.new_status)} {#if i != events.length - 1 || !endable.includes(event.new_status)}
<div class="min-w-[70px] h-[13px] bg-blue-500 -mx-[10px] flex-grow"> <div
class="min-w-[70px] h-[18px] bg-blue-500 -mx-[10px] px-[20px] flex-grow text-center"
>
{#if event.timeDiff}
<div class="-mt-[3px] text-white">
<span class="bi bi-clock"></span>
{event.timeDiff} {event.timeDiff}
</div> </div>
{/if}
</div>
{#if i == events.length - 1} {#if i == events.length - 1}
<!--div class="h-[15px] w-[15px] bg-blue-500 rotate-45"></div--> <!--div class="h-[15px] w-[15px] bg-blue-500 rotate-45"></div-->
{/if} {/if}

View File

@ -449,6 +449,7 @@
class="flex w-full flex-grow rounded-lg p-3 gap-2 absolute bottom-0 left-0 right-0 bg-white" class="flex w-full flex-grow rounded-lg p-3 gap-2 absolute bottom-0 left-0 right-0 bg-white"
> >
<!-- Do nothing --> <!-- Do nothing -->
{#if activeItem.status === ApplicationStatus.WorkingOnIt}
<DropZone <DropZone
icon="box-arrow-down" icon="box-arrow-down"
ondrop={() => { ondrop={() => {
@ -459,6 +460,7 @@
> >
To apply To apply
</DropZone> </DropZone>
{/if}
{#if activeItem.status === ApplicationStatus.WorkingOnIt} {#if activeItem.status === ApplicationStatus.WorkingOnIt}
<!-- Ignore --> <!-- Ignore -->
@ -537,13 +539,32 @@
</DropZone> </DropZone>
{/if} {/if}
{#if [ApplicationStatus.InterviewStep1].includes(activeItem.status)}
<!-- Tasks to do -->
<DropZone
icon="server text-confirm"
ondrop={async () => {
await moveStatus(ApplicationStatus.InterviewStep2);
applicationStore.loadAll(true);
applicationStore.loadAplyed(true);
}}
>
Interview 2
</DropZone>
{/if}
{#if ![ApplicationStatus.ApplyedButSaidNo].includes(activeItem.status)}
<!-- Rejected --> <!-- Rejected -->
<DropZone <DropZone
icon="fire text-danger" icon="fire text-danger"
ondrop={() => moveStatus(ApplicationStatus.ApplyedButSaidNo)} ondrop={() => {
moveStatus(ApplicationStatus.ApplyedButSaidNo)
applicationStore.loadAll(true);
}}
> >
I was rejeted :( I was rejeted :(
</DropZone> </DropZone>
{/if}
</div> </div>
{/if} {/if}
{:else} {:else}
@ -576,7 +597,10 @@
<NewUrlDialog <NewUrlDialog
id={activeItem?.id ?? ''} id={activeItem?.id ?? ''}
bind:dialog={changeUrl} bind:dialog={changeUrl}
onreload={(item) => (activeItem = item)} onreload={async (item) => {
item.events = await get(`events/${item.id}`);
activeItem = item;
}}
/> />
{/if} {/if}