chore: added stauts_history

This commit is contained in:
Andre Henriques 2024-10-07 21:27:25 +01:00
parent 5ff8fc1d83
commit 9f9b335557
9 changed files with 182 additions and 53 deletions

View File

@ -33,6 +33,7 @@ data class Application(
var recruiter: String, var recruiter: String,
var message: String, var message: String,
var linked_application: String, var linked_application: String,
var status_history: String,
var flairs: List<Flair>, var flairs: List<Flair>,
var views: List<View>, var views: List<View>,
) { ) {
@ -52,6 +53,7 @@ data class Application(
rs.getString("recruiter"), rs.getString("recruiter"),
rs.getString("message"), rs.getString("message"),
rs.getString("linked_application"), rs.getString("linked_application"),
rs.getString("status_history"),
emptyList(), emptyList(),
emptyList(), emptyList(),
) )
@ -182,6 +184,7 @@ class ApplicationsController(
"", "",
"", "",
"", "",
"",
emptyList(), emptyList(),
emptyList(), emptyList(),
) )
@ -259,6 +262,13 @@ class ApplicationsController(
} }
application.status = info.status application.status = info.status
val status_string = "${info.status}";
var status_history = application.status_history.split(",").filter { it.length >= 1 }
if (status_history.indexOf(status_string) == -1) {
status_history = status_history.plus("${info.status}");
}
application.status_history = status_history.joinToString(",") { it }
applicationService.update(application) applicationService.update(application)
@ -466,7 +476,7 @@ class ApplicationService(
} }
db.update( db.update(
"insert into applications (id, url, original_url, unique_url, title, user_id, extra_data, payrange, status, company, recruiter, message, linked_application) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", "insert into applications (id, url, original_url, unique_url, title, user_id, extra_data, payrange, status, company, recruiter, message, linked_application, status_history) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
application.id, application.id,
application.url, application.url,
application.original_url, application.original_url,
@ -480,6 +490,7 @@ class ApplicationService(
application.recruiter, application.recruiter,
application.message, application.message,
application.linked_application, application.linked_application,
application.status_history,
) )
return true return true
@ -516,7 +527,7 @@ class ApplicationService(
public fun update(application: Application): Application { public fun update(application: Application): Application {
db.update( db.update(
"update applications set url=?, original_url=?, unique_url=?, title=?, user_id=?, extra_data=?, payrange=?, status=?, company=?, recruiter=?, message=?, linked_application=? where id=?", "update applications set url=?, original_url=?, unique_url=?, title=?, user_id=?, extra_data=?, payrange=?, status=?, company=?, recruiter=?, message=?, linked_application=?, status_history=? where id=?",
application.url, application.url,
application.original_url, application.original_url,
application.unique_url, application.unique_url,
@ -529,6 +540,7 @@ class ApplicationService(
application.recruiter, application.recruiter,
application.message, application.message,
application.linked_application, application.linked_application,
application.status_history,
application.id, application.id,
) )
return application return application

View File

@ -20,6 +20,7 @@ create table if not exists applications (
recruiter text, recruiter text,
title text, title text,
mesasge text default '', mesasge text default '',
status_history text default '',
user_id text, user_id text,
extra_data text, extra_data text,
status integer, status integer,

View File

@ -80,6 +80,7 @@ async function startup() {
}); });
browser.menus.onClicked.addListener(async function (e, tab) { browser.menus.onClicked.addListener(async function (e, tab) {
console.log("here")
if (e.menuItemId === "mark-page") { if (e.menuItemId === "mark-page") {
console.log("set mark-page", tab.id) console.log("set mark-page", tab.id)
await browser.storage.local.set({ await browser.storage.local.set({
@ -90,4 +91,4 @@ async function startup() {
} }
browser.runtime.onInstalled.addListener(startup); browser.runtime.onInstalled.addListener(startup);
browser.runtime.onStartup.addListener(startup); browser.runtime.onConnect.addListener(startup);

View File

@ -9,7 +9,8 @@ export const ApplicationStatus = Object.freeze({
Ignore: 2, Ignore: 2,
ApplyedButSaidNo: 3, ApplyedButSaidNo: 3,
Applyed: 4, Applyed: 4,
Expired: 5 Expired: 5,
TasksToDo: 6,
}); });
export const ApplicationStatusMaping: Record< export const ApplicationStatusMaping: Record<
@ -21,7 +22,8 @@ export const ApplicationStatusMaping: Record<
2: 'Ignore', 2: 'Ignore',
3: 'Applyed But Said No', 3: 'Applyed But Said No',
4: 'Applyed', 4: 'Applyed',
5: 'Expired' 5: 'Expired',
6: 'Tasks To Do',
}); });
export type View = { export type View = {
@ -51,9 +53,12 @@ export type Application = {
function createApplicationStore() { function createApplicationStore() {
let applications: Application[] = $state([]); let applications: Application[] = $state([]);
let applyed: Application[] = $state([]); let applyed: Application[] = $state([]);
let tasksToDo: Application[] = $state([]);
let dragApplication: Application | undefined = $state(undefined); let dragApplication: Application | undefined = $state(undefined);
let loadItem: Application | undefined = $state(undefined);
return { return {
/** /**
* @throws {Error} * @throws {Error}
@ -69,12 +74,22 @@ function createApplicationStore() {
* @throws {Error} * @throws {Error}
*/ */
async loadAplyed(force = false) { async loadAplyed(force = false) {
if (!force && applications.length > 1) { if (!force && applyed.length > 1) {
return; return;
} }
applyed = await post('application/list', { status: ApplicationStatus.Applyed }); applyed = await post('application/list', { status: ApplicationStatus.Applyed });
}, },
/**
* @throws {Error}
*/
async loadTasksToDo(force = false) {
if (!force && tasksToDo.length > 1) {
return;
}
tasksToDo = await post('application/list', { status: ApplicationStatus.TasksToDo });
},
clear() { clear() {
applications = []; applications = [];
}, },
@ -97,7 +112,19 @@ function createApplicationStore() {
get applyed() { get applyed() {
return applyed; return applyed;
} },
get tasksToDo() {
return tasksToDo;
},
get loadItem() {
return loadItem;
},
set loadItem(item: Application | undefined) {
loadItem = item;
},
}; };
} }

View File

@ -4,6 +4,7 @@
import ApplicationsList from './ApplicationsList.svelte'; import ApplicationsList from './ApplicationsList.svelte';
import WorkArea from './work-area/WorkArea.svelte'; import WorkArea from './work-area/WorkArea.svelte';
import AppliyedList from './AppliyedList.svelte'; import AppliyedList from './AppliyedList.svelte';
import TasksToDoList from './TasksToDoList.svelte';
</script> </script>
<HasUser redirect="/cv"> <HasUser redirect="/cv">
@ -14,6 +15,7 @@
<ApplicationsList /> <ApplicationsList />
<WorkArea /> <WorkArea />
</div> </div>
<TasksToDoList />
<AppliyedList /> <AppliyedList />
</div> </div>
</div> </div>

View File

@ -11,18 +11,17 @@
<h1>Applied</h1> <h1>Applied</h1>
<div class="overflow-auto flex-grow"> <div class="overflow-auto flex-grow">
{#each applicationStore.applyed as item} {#each applicationStore.applyed as item}
<div <button
class="card p-2 my-2 bg-slate-100" class="card p-2 my-2 bg-slate-100 w-full text-left"
draggable="true" onclick={() => {
ondragstart={() => applicationStore.dragStart(item)} applicationStore.loadItem = item;
ondragend={() => { window.scrollTo({
window.requestAnimationFrame(() => { top: 0,
applicationStore.dragEnd(); behavior: 'smooth',
}); });
}} }}
role="none"
> >
<div class:animate-pulse={applicationStore.dragging?.id === item.id}> <div>
<h2 class="text-lg text-blue-500"> <h2 class="text-lg text-blue-500">
{item.title} {item.title}
{#if item.company} {#if item.company}
@ -38,7 +37,7 @@
{item.url} {item.url}
</a> </a>
</div> </div>
</div> </button>
{/each} {/each}
</div> </div>
</div> </div>

View File

@ -0,0 +1,45 @@
<script lang="ts">
import { applicationStore } from '$lib/ApplicationsStore.svelte';
import { onMount } from 'svelte';
onMount(() => {
applicationStore.loadTasksToDo();
});
</script>
{#if applicationStore.tasksToDo.length > 0}
<div class="card p-3 rounded-lg flex flex-col">
<h1>Tasks To Do</h1>
<div class="overflow-auto flex-grow">
{#each applicationStore.tasksToDo as item}
<button
class="card p-2 my-2 bg-slate-100 w-full text-left"
onclick={() => {
applicationStore.loadItem = item;
window.scrollTo({
top: 0,
behavior: 'smooth'
});
}}
>
<div>
<h2 class="text-lg text-blue-500">
{item.title}
{#if item.company}
<div class="text-violet-800">
@ {item.company}
</div>
{/if}
</h2>
<a
href={item.url}
class="text-violet-600 overflow-hidden whitespace-nowrap block"
>
{item.url}
</a>
</div>
</button>
{/each}
</div>
</div>
{/if}

View File

@ -31,6 +31,7 @@
[ApplicationStatus.ApplyedButSaidNo]: 0, [ApplicationStatus.ApplyedButSaidNo]: 0,
[ApplicationStatus.Expired]: 0, [ApplicationStatus.Expired]: 0,
[ApplicationStatus.Applyed]: 0, [ApplicationStatus.Applyed]: 0,
[ApplicationStatus.TasksToDo]: 0,
Linkedin: 0, Linkedin: 0,
Glassdoor: 0, Glassdoor: 0,
'Unknown Source': 0, 'Unknown Source': 0,
@ -51,6 +52,11 @@
source: ApplicationStatus.Applyed, source: ApplicationStatus.Applyed,
target: ApplicationStatus.ApplyedButSaidNo, target: ApplicationStatus.ApplyedButSaidNo,
value: 1 value: 1
},
{
source: ApplicationStatus.Applyed,
target: ApplicationStatus.TasksToDo,
value: 1
} }
]; ];
@ -63,7 +69,7 @@
nodeTypes['Unknown Source'] += 1; nodeTypes['Unknown Source'] += 1;
} }
nodeTypes[a.status] += 1; nodeTypes[a.status] += 1;
if (a.status === ApplicationStatus.ApplyedButSaidNo) { if ([ApplicationStatus.ApplyedButSaidNo, ApplicationStatus.TasksToDo].includes(a.status) ) {
nodeTypes[ApplicationStatus.Applyed] += 1; nodeTypes[ApplicationStatus.Applyed] += 1;
} }
}); });

View File

@ -14,6 +14,7 @@
import DropZone from './DropZone.svelte'; import DropZone from './DropZone.svelte';
import { userStore } from '$lib/UserStore.svelte'; import { userStore } from '$lib/UserStore.svelte';
import LinkApplication from './LinkApplication.svelte'; import LinkApplication from './LinkApplication.svelte';
import ApplicationsList from '../ApplicationsList.svelte';
let activeItem: Application | undefined = $state(); let activeItem: Application | undefined = $state();
@ -148,6 +149,14 @@
loadActive(); loadActive();
}); });
$effect(() => {
if (!applicationStore.loadItem) {
return;
}
activeItem = applicationStore.loadItem;
applicationStore.loadItem = undefined;
});
async function moveStatus(status: number) { async function moveStatus(status: number) {
if (!activeItem) return; if (!activeItem) return;
// Deactivate active item // Deactivate active item
@ -372,7 +381,13 @@
{#if activeItem.original_url != null} {#if activeItem.original_url != null}
<button class="btn-danger" onclick={resetUrl}> Reset Url </button> <button class="btn-danger" onclick={resetUrl}> Reset Url </button>
{/if} {/if}
<button class:btn-primary={drag} class:btn-danger={!drag} onclick={() => (drag = !drag)}> 👋 </button> <button
class:btn-primary={drag}
class:btn-danger={!drag}
onclick={() => (drag = !drag)}
>
👋
</button>
</div> </div>
</div> </div>
{#if applicationStore.dragging} {#if applicationStore.dragging}
@ -384,48 +399,69 @@
icon="box-arrow-down" icon="box-arrow-down"
ondrop={() => { ondrop={() => {
moveStatus(ApplicationStatus.ToApply); moveStatus(ApplicationStatus.ToApply);
applicationStore.loadAplyed(true);
applicationStore.loadTasksToDo(true);
}} }}
> >
To apply To apply
</DropZone> </DropZone>
<!-- Ignore --> {#if activeItem.status === ApplicationStatus.WorkingOnIt}
<DropZone <!-- Ignore -->
icon="trash-fill" <DropZone
ondrop={() => { icon="trash-fill"
moveStatus(ApplicationStatus.Ignore); ondrop={() => {
}} moveStatus(ApplicationStatus.Ignore);
> }}
Ignore it >
</DropZone> Ignore it
</DropZone>
<!-- Expired --> <!-- Expired -->
<DropZone <DropZone
icon="clock-fill text-orange-500" icon="clock-fill text-orange-500"
ondrop={() => { ondrop={() => {
if (activeItem && activeItem.status === ApplicationStatus.Expired) { if (activeItem && activeItem.status === ApplicationStatus.Expired) {
moveStatus(ApplicationStatus.ToApply); moveStatus(ApplicationStatus.ToApply);
} else { } else {
moveStatus(ApplicationStatus.Expired); moveStatus(ApplicationStatus.Expired);
} }
}} }}
> >
Mark as expired Mark as expired
</DropZone> </DropZone>
<!-- Repeated --> <!-- Repeated -->
<DropZone icon="trash-fill text-danger" ondrop={() => remove()}>Delete it</DropZone> <DropZone icon="trash-fill text-danger" ondrop={() => remove()}
>Delete it</DropZone
>
<!-- Applyed --> <!-- Applyed -->
<DropZone <DropZone
icon="server text-confirm" icon="server text-confirm"
ondrop={async () => { ondrop={async () => {
await moveStatus(ApplicationStatus.Applyed); await moveStatus(ApplicationStatus.Applyed);
applicationStore.loadAplyed(true); applicationStore.loadAplyed(true);
}} applicationStore.loadTasksToDo(true);
> }}
Apply >
</DropZone> Apply
</DropZone>
{/if}
{#if activeItem.status === ApplicationStatus.Applyed}
<!-- Tasks to do -->
<DropZone
icon="server text-confirm"
ondrop={async () => {
await moveStatus(ApplicationStatus.TasksToDo);
applicationStore.loadTasksToDo(true);
applicationStore.loadAplyed(true);
}}
>
Tasks To Do
</DropZone>
{/if}
<!-- Rejected --> <!-- Rejected -->
<DropZone <DropZone