From 941875ff215104690a4388de5d01d408d8b59d16 Mon Sep 17 00:00:00 2001 From: Andre Henriques Date: Tue, 21 Jan 2025 11:16:32 +0000 Subject: [PATCH] feat: a lot --- .../applications/ApplicationsController.kt | 309 +++++++----------- .../com/andr3h3nriqu3s/applications/Events.kt | 16 +- .../com/andr3h3nriqu3s/applications/Flair.kt | 34 +- .../applications/UserStatusNode.kt | 16 +- .../com/andr3h3nriqu3s/applications/View.kt | 103 ------ api/src/main/resources/schema.sql | 123 ++++--- site/src/lib/ApplicationsStore.svelte.ts | 152 +++------ site/src/lib/FlairStore.svelte.ts | 38 ++- site/src/lib/Types.svelte.ts | 80 +++++ site/src/routes/+page.svelte | 24 +- site/src/routes/ApplicationTypesList.svelte | 17 + site/src/routes/ApplicationsList.svelte | 13 +- site/src/routes/AppliyedList.svelte | 59 ---- site/src/routes/NavBar.svelte | 5 +- site/src/routes/PApplicationList.svelte | 52 --- site/src/routes/SmartApplicationList.svelte | 64 ++++ site/src/routes/cv/+page.svelte | 133 ++++---- site/src/routes/cv/pill.svelte | 17 + site/src/routes/flair/+page.svelte | 17 +- site/src/routes/flow/+page.svelte | 34 +- site/src/routes/flow/NodeRect.svelte | 37 +++ site/src/routes/flow/types.ts | 99 +++--- ...{+page.svelte => temp_+page.svelte.ignore} | 0 site/src/routes/submit/+page.svelte | 2 +- site/src/routes/work-area/AutoDropZone.svelte | 63 ++++ site/src/routes/work-area/CompanyField.svelte | 21 +- site/src/routes/work-area/DropingZone.svelte | 198 ----------- .../routes/work-area/ExtractTextDialog.svelte | 2 +- .../routes/work-area/LinkApplication.svelte | 57 ++-- .../routes/work-area/NewApplication.svelte | 69 +++- site/src/routes/work-area/NewUrlDialog.svelte | 9 +- .../routes/work-area/SearchApplication.svelte | 18 +- site/src/routes/work-area/Timeline.svelte | 67 +--- site/src/routes/work-area/WorkArea.svelte | 213 +++++------- 34 files changed, 956 insertions(+), 1205 deletions(-) delete mode 100644 api/src/main/kotlin/com/andr3h3nriqu3s/applications/View.kt create mode 100644 site/src/lib/Types.svelte.ts create mode 100644 site/src/routes/ApplicationTypesList.svelte delete mode 100644 site/src/routes/AppliyedList.svelte delete mode 100644 site/src/routes/PApplicationList.svelte create mode 100644 site/src/routes/SmartApplicationList.svelte create mode 100644 site/src/routes/cv/pill.svelte rename site/src/routes/graphs/{+page.svelte => temp_+page.svelte.ignore} (100%) create mode 100644 site/src/routes/work-area/AutoDropZone.svelte delete mode 100644 site/src/routes/work-area/DropingZone.svelte diff --git a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/ApplicationsController.kt b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/ApplicationsController.kt index a71fdf7..e2d1f39 100644 --- a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/ApplicationsController.kt +++ b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/ApplicationsController.kt @@ -1,8 +1,6 @@ package com.andr3h3nriqu3s.applications import java.sql.ResultSet -import java.text.SimpleDateFormat -import java.util.Date import java.util.UUID import kotlin.collections.emptyList import kotlin.collections.setOf @@ -23,27 +21,35 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import org.springframework.web.server.ResponseStatusException +data class ApplicationUrl( + var application_id: String, + var url: String, +) { + companion object : RowMapper { + override public fun mapRow(rs: ResultSet, rowNum: Int): ApplicationUrl { + return ApplicationUrl( + rs.getString("application_id"), + rs.getString("url"), + ) + } + } +} + data class Application( var id: String, var url: String, - var original_url: String?, - var unique_url: String?, var title: String, var user_id: String, var extra_data: String, var payrange: String, - var status: Int, var status_id: String?, var company: String, var recruiter: String, var agency: Boolean, var message: String, - var linked_application: String, - var status_history: String, - var application_time: String, var create_time: String, + var simple_url: String, var flairs: List, - var views: List, var events: List, ) { companion object : RowMapper { @@ -51,23 +57,17 @@ data class Application( return Application( rs.getString("id"), rs.getString("url"), - rs.getString("original_url"), - rs.getString("unique_url"), rs.getString("title"), rs.getString("user_id"), rs.getString("extra_data"), rs.getString("payrange"), - rs.getInt("status"), rs.getString("status_id"), rs.getString("company"), rs.getString("recruiter"), rs.getBoolean("agency"), rs.getString("message"), - rs.getString("linked_application"), - rs.getString("status_history"), - rs.getString("application_time"), rs.getString("create_time"), - emptyList(), + rs.getString("simple_url"), emptyList(), emptyList(), ) @@ -77,9 +77,7 @@ data class Application( data class SubmitRequest(val text: String) -data class ListRequest(val status: Int? = null, val views: Boolean? = null) - -data class StatusRequest(val id: String, val status: Int) +data class StatusRequest(val id: String, val status_id: String?) data class FlairRequest(val id: String, val text: String) @@ -100,7 +98,6 @@ class ApplicationsController( val sessionService: SessionService, val applicationService: ApplicationService, val flairService: FlairService, - val viewService: ViewService, val eventService: EventService, ) { @@ -118,7 +115,13 @@ class ApplicationsController( val flairs = application.flairs.map { it.toFlairSimple() } - return CVData(application.company, application.recruiter, application.message, application.agency, flairs) + return CVData( + application.company, + application.recruiter, + application.message, + application.agency, + flairs + ) } /** Create a new application from the link */ @@ -133,13 +136,10 @@ class ApplicationsController( Application( UUID.randomUUID().toString(), submit.text, - submit.text, - submit.text, "New Application", user.id, "", "", - 0, null, "", "", @@ -147,9 +147,6 @@ class ApplicationsController( "", "", "", - "", - "", - emptyList(), emptyList(), emptyList(), ) @@ -199,7 +196,7 @@ class ApplicationsController( public fun submitText( @RequestBody submit: SubmitRequest, @RequestHeader("token") token: String - ): Int { + ): List { val user = sessionService.verifyTokenThrow(token) var text = submit.text.replace("=\n", "") @@ -263,23 +260,17 @@ class ApplicationsController( Application( UUID.randomUUID().toString(), if (elm.contains("linkedin")) elm.split("?")[0] else elm, - if (elm.contains("linkedin")) elm.split("?")[0] else null, - if (elm.contains("linkedin")) elm.split("?")[0] else null, "New Application", user.id, "", "", - 0, null, "", "", false, "", "", - "", - "", - "", - emptyList(), + if (elm.contains("linkedin")) elm.split("?")[0] else "", emptyList(), emptyList(), ) @@ -292,26 +283,46 @@ class ApplicationsController( print(applications.size) print(" links\n") - return applications.size + return applications } - @PostMapping(path = ["/list"], produces = [MediaType.APPLICATION_JSON_VALUE]) - public fun list( - @RequestBody info: ListRequest, - @RequestHeader("token") token: String - ): List { + @GetMapping(path = ["/list"], produces = [MediaType.APPLICATION_JSON_VALUE]) + public fun list(@RequestHeader("token") token: String): List { val user = sessionService.verifyTokenThrow(token) - return applicationService.findAll(user, info) + return applicationService.findAll(user) } - @GetMapping(path = ["/active"], produces = [MediaType.APPLICATION_JSON_VALUE]) - public fun active(@RequestHeader("token") token: String): Application? { + @GetMapping(path = ["/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) + public fun get(@PathVariable id: String, @RequestHeader("token") token: String): Application? { val user = sessionService.verifyTokenThrow(token) - val possibleApplications = applicationService.findAll(user, ListRequest(1)) - if (possibleApplications.size == 0) { - return null + val app = applicationService.findApplicationById(user, id) + if (app == null) { + throw ResponseStatusException(HttpStatus.NOT_FOUND, "Application not found", null) } - return applicationService.findApplicationById(user, possibleApplications[0].id) + return app + } + + @PostMapping( + path = ["/link/application/{toLink}/{surviving}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + public fun get( + @PathVariable toLink: String, + @PathVariable surviving: String, + @RequestHeader("token") token: String + ): Application { + val user = sessionService.verifyTokenThrow(token) + val toLinkApp = applicationService.findApplicationById(user, toLink) + val app = applicationService.findApplicationById(user, surviving) + + if (app == null || toLinkApp == null) { + throw ResponseStatusException(HttpStatus.NOT_FOUND, "Application not found", null) + } + + applicationService.linkApplications(toLinkApp, app) + applicationService.delete(toLinkApp) + + return app } @PutMapping(path = ["/status"], produces = [MediaType.APPLICATION_JSON_VALUE]) @@ -325,11 +336,11 @@ class ApplicationsController( throw NotFound() } - if (application.status == info.status) { - return application; + if (application.status_id == info.status_id) { + return application } - application.status = info.status + application.status_id = info.status_id applicationService.updateStatus(application) @@ -362,68 +373,28 @@ class ApplicationsController( throw ResponseStatusException(HttpStatus.NOT_FOUND, "Application not found", null) } - if (application.unique_url != null) { - throw ResponseStatusException( - HttpStatus.BAD_REQUEST, - "Application already has unique_url", - null - ) - } - - application.original_url = application.url application.url = info.url - application.unique_url = info.url.split("?")[0] + application.simple_url = info.url.split("?")[0] var maybe_exists = - applicationService.findApplicationByUrl( - user, - application.url, - application.unique_url - ) - if (maybe_exists != null) { + applicationService.findApplicationByUrl(user, application.url) + ?: applicationService.findApplicationByUrl(user, application.simple_url) + + if (maybe_exists != null && maybe_exists.id != application.id) { applicationService.delete(application) - if (maybe_exists.status == 0 && application.status == 1) { - maybe_exists.status = 1 - applicationService.update(maybe_exists) - } - maybe_exists.flairs = flairService.listFromLinkApplicationId(maybe_exists.id) + maybe_exists.events = eventService.listFromApplicationId(maybe_exists.id).toList() return maybe_exists } + applicationService.addUrl(application.id, info.url) + applicationService.addUrl(application.id, info.url.split("?")[0]) applicationService.update(application) application.flairs = flairService.listFromLinkApplicationId(application.id) - application.views = viewService.listFromApplicationId(application.id) - - return application - } - - @PostMapping(path = ["/reset/url/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - public fun updateUrl( - @PathVariable id: String, - @RequestHeader("token") token: String - ): Application { - val user = sessionService.verifyTokenThrow(token) - var application = applicationService.findApplicationById(user, id) - - if (application == null) { - throw NotFound() - } - - if (application.unique_url == null) { - throw BadRequest() - } - - application.url = application.original_url!! - application.original_url = null - application.unique_url = null - - applicationService.update(application) - - application.flairs = flairService.listFromLinkApplicationId(application.id) + application.events = eventService.listFromApplicationId(application.id).toList() return application } @@ -466,28 +437,13 @@ class ApplicationsController( class ApplicationService( val db: JdbcTemplate, val flairService: FlairService, - val viewService: ViewService, val eventService: EventService, ) { - public fun findApplicationByUrl(user: UserDb, url: String, unique_url: String?): Application? { - if (unique_url != null) { - val unique: List = - db.query( - "select * from applications where unique_url=? and user_id=?", - arrayOf(unique_url, user.id), - Application - ) - .toList() - - if (unique.size != 0) { - return unique[0] - } - } - - val applications: List = + public fun findApplicationByUrl(user: UserDb, url: String): Application? { + val applications = db.query( - "select * from applications where url=? and user_id=?", + "select * from applications as app inner join applications_urls as app_url on app_url.application_id=app.id where app_url.url=? and user_id=?", arrayOf(url, user.id), Application ) @@ -516,7 +472,6 @@ class ApplicationService( var application = applications[0] application.flairs = flairService.listFromLinkApplicationId(application.id) - application.views = viewService.listFromApplicationId(application.id) application.events = eventService.listFromApplicationId(application.id).toList() return application @@ -538,106 +493,80 @@ class ApplicationService( return application } + public fun addUrl(id: String, url: String) { + val applications = + db.query( + "select * from applications_urls as app_url where app_url.url=? and app_url.application_id=?", + arrayOf(url, id), + ApplicationUrl + ) + .toList() + + if (applications.size > 0) { + return + } + + db.update("insert into applications_urls (application_id, url) values (?, ?);", id, url) + } + public fun createApplication(user: UserDb, application: Application): Boolean { - if (this.findApplicationByUrl(user, application.url, application.unique_url) != null) { + if (this.findApplicationByUrl(user, application.url) != null) { return false } // Create time is auto created by the database - // The default status is null db.update( - "insert into applications (id, url, original_url, unique_url, title, user_id, extra_data, payrange, status, company, recruiter, message, linked_application, status_history, application_time, agency) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + "insert into applications (id, url, title, user_id, extra_data, payrange, status_id, company, recruiter, message, agency, simple_url) values (?,?,?,?,?,?,?,?,?,?,?,?);", application.id, application.url, - application.original_url, - application.unique_url, application.title, application.user_id, application.extra_data, application.payrange, - application.status, + application.status_id, application.company, application.recruiter, application.message, - application.linked_application, - application.status_history, - application.application_time, application.agency, + application.simple_url, ) eventService.create(application.id, EventType.Creation) + addUrl(application.id, application.url) return true } - private fun internalFindAll(user: UserDb, info: ListRequest): Iterable { - if (info.status == null) { - return db.query( - "select * from applications where user_id=? order by title asc;", - arrayOf(user.id), - Application - ) - } - - // If it's to apply also remove the linked_application to only show the main - if (info.status == 0) { - return db.query( - "select * from applications where user_id=? and linked_application='' and status=0 order by title asc;", - arrayOf(user.id), - Application - ) - } - + private fun internalFindAll(user: UserDb): Iterable { return db.query( - "select * from applications where user_id=? and status=? order by title asc;", - arrayOf(user.id, info.status), - Application, - ) + "select * from applications where user_id=? order by title asc;", + arrayOf(user.id), + Application + ) } - public fun findAll(user: UserDb, info: ListRequest): List { - var iter = internalFindAll(user, info); - if (info.views == true) { - iter = iter.map { - it.views = viewService.listFromApplicationId(it.id) - it - } - } + public fun findAll(user: UserDb): List { + var iter = internalFindAll(user) return iter.toList() } public fun findAllByUserStatusId(statusId: String, user: UserDb): List { - return db.query( - "select * from applications where status_id=? and user_id=? order by title asc;", - arrayOf(statusId, user.id), - Application - ) + return db.query( + "select * from applications where status_id=? and user_id=? order by title asc;", + arrayOf(statusId, user.id), + Application + ) } // Update the stauts on the application object before giving it to this function // TODO how status history works public fun updateStatus(application: Application): Application { - val status_string = "${application.status}" - var status_history = application.status_history.split(",").filter { it.length >= 1 } - if (status_history.indexOf(status_string) == -1) { - status_history = status_history.plus(status_string) - } - - application.status_history = status_history.joinToString(",") { it } - - if (application.status == 4) { - val sdf = SimpleDateFormat("dd/MM/yyyy hh:mm:ss") - application.application_time = sdf.format(Date()) - } - - eventService.create(application.id, EventType.StatusUpdate, application.status) + eventService.create(application.id, EventType.StatusUpdate, application.status_id) db.update( - "update applications set status=?, status_history=?, application_time=? where id=?", - application.status, - application.status_history, - application.application_time, + "update applications set status_id=? where id=?", + application.status_id, application.id, ) return application @@ -647,10 +576,8 @@ class ApplicationService( public fun update(application: Application): Application { // I don't want ot update create_time db.update( - "update applications set url=?, original_url=?, unique_url=?, title=?, user_id=?, extra_data=?, payrange=?, company=?, recruiter=?, message=?, linked_application=?, agency=? where id=?", + "update applications set url=?, title=?, user_id=?, extra_data=?, payrange=?, company=?, recruiter=?, message=?, agency=?, simple_url=? where id=?", application.url, - application.original_url, - application.unique_url, application.title, application.user_id, application.extra_data, @@ -658,17 +585,29 @@ class ApplicationService( application.company, application.recruiter, application.message, - application.linked_application, application.agency, + application.simple_url, application.id, ) return application } + public fun linkApplications(toLink: Application, surviving: Application) { + db.update( + "update applications_urls set application_id=? where application_id=?;", + surviving.id, + toLink.id, + ) + } + public fun delete(application: Application) { db.update( "delete from applications where id=?", application.id, ) + db.update( + "delete from applications_urls where application_id=?", + application.id, + ) } } diff --git a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Events.kt b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Events.kt index 98db4ad..4e0c704 100644 --- a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Events.kt +++ b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Events.kt @@ -25,7 +25,7 @@ data class Event( var id: String, var application_id: String, var event_type: Int, - var new_status: Int?, + var new_status_id: String?, var time: Timestamp ) { companion object : RowMapper { @@ -34,7 +34,7 @@ data class Event( rs.getString("id"), rs.getString("application_id"), rs.getInt("event_type"), - rs.getInt("new_status"), + rs.getString("new_status_id"), rs.getTimestamp("time"), ) } @@ -93,23 +93,19 @@ public class EventService(val db: JdbcTemplate) { public fun create( application_id: String, event_type: EventType, - new_status: Int? = null + new_status_id: String? = null ): Event { val id = UUID.randomUUID().toString() - if (event_type == EventType.StatusUpdate && new_status == null) { - throw Exception("When event_type == StatusUpdate new_status must be set") - } - var new_event = - Event(id, application_id, event_type.value, new_status, Timestamp(Date().getTime())) + Event(id, application_id, event_type.value, new_status_id, Timestamp(Date().getTime())) db.update( - "insert into events (id, application_id, event_type, new_status) values (?, ?, ? ,?)", + "insert into events (id, application_id, event_type, new_status_id) values (?, ?, ? ,?)", new_event.id, new_event.application_id, new_event.event_type, - new_event.new_status, + new_event.new_status_id, ) return new_event diff --git a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Flair.kt b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Flair.kt index 5afaa65..9f54624 100644 --- a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Flair.kt +++ b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/Flair.kt @@ -2,8 +2,8 @@ package com.andr3h3nriqu3s.applications import java.sql.ResultSet import java.util.UUID -import org.springframework.http.MediaType import org.springframework.http.HttpStatus +import org.springframework.http.MediaType import org.springframework.jdbc.core.JdbcTemplate import org.springframework.jdbc.core.RowMapper import org.springframework.stereotype.Service @@ -52,10 +52,6 @@ class FlairController( throw NotFound() } - if (old_flair.user_id != user.id) { - throw NotAuth() - } - flair.user_id = old_flair.user_id return flairService.updateFlair(flair) @@ -88,6 +84,8 @@ data class SimpleFlair( val name: String, val description: String, val color: String, + val sort: Int, + val showFullDescription: Int, ) data class Flair( @@ -97,6 +95,8 @@ data class Flair( var name: String, var expr: String, var description: String, + var sort: Int, + var showFullDescription: Int, ) { companion object : RowMapper { override public fun mapRow(rs: ResultSet, rowNum: Int): Flair { @@ -107,12 +107,20 @@ data class Flair( rs.getString("name"), rs.getString("expr"), rs.getString("description"), + rs.getInt("sort"), + rs.getInt("showFullDescription"), ) } } fun toFlairSimple(): SimpleFlair { - return SimpleFlair(this.name, this.description, this.color) + return SimpleFlair( + this.name, + this.description, + this.color, + this.sort, + this.showFullDescription + ) } } @@ -160,7 +168,7 @@ public class FlairService(val db: JdbcTemplate) { public fun listFromLinkApplicationId(id: String): List = db.query( - "select f.id, f.user_id, f.color, f.name, f.expr, f.description from flair_link as fl inner join flair as f on f.id = fl.flair_id where application_id=? order by name asc;", + "select f.id, f.user_id, f.color, f.name, f.expr, f.description, f.sort, f.showFullDescription from flair_link as fl inner join flair as f on f.id = fl.flair_id where application_id=? order by name asc;", arrayOf(id), Flair ) @@ -210,12 +218,14 @@ public class FlairService(val db: JdbcTemplate) { public fun updateFlair(flair: Flair): Flair { db.update( - "update flair set user_id=?, color=?, name=?, expr=?, description=? where id=?;", + "update flair set user_id=?, color=?, name=?, expr=?, description=?, sort=?, showFullDescription=? where id=?;", flair.user_id, flair.color, flair.name, flair.expr, flair.description, + flair.sort, + flair.showFullDescription, flair.id, ) @@ -231,16 +241,18 @@ public class FlairService(val db: JdbcTemplate) { description = flair.description!! } - var new_flair = Flair(id, user.id, flair.color, flair.name, flair.expr, description) + var new_flair = Flair(id, user.id, flair.color, flair.name, flair.expr, description, 0, 1) db.update( - "insert into flair (id, user_id, color, name, expr, description) values (?, ?, ?, ?, ?, ?)", + "insert into flair (id, user_id, color, name, expr, description, sort, showFullDescription) values (?, ?, ?, ?, ?, ?, ?, ?)", new_flair.id, new_flair.user_id, new_flair.color, new_flair.name, new_flair.expr, - new_flair.description + new_flair.description, + new_flair.showFullDescription, + new_flair.sort, ) return new_flair diff --git a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/UserStatusNode.kt b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/UserStatusNode.kt index 6590303..68ddafb 100644 --- a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/UserStatusNode.kt +++ b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/UserStatusNode.kt @@ -28,7 +28,9 @@ data class UserStatusNode( var y: Int, var width: Int, var height: Int, - var permission: Int + var permission: Int, + var visible: Boolean, + var endable: Boolean, ) { companion object : RowMapper { override public fun mapRow(rs: ResultSet, rowNum: Int): UserStatusNode { @@ -42,6 +44,8 @@ data class UserStatusNode( rs.getInt("width"), rs.getInt("height"), rs.getInt("permission"), + rs.getBoolean("visible"), + rs.getBoolean("endable"), ) } } @@ -211,7 +215,7 @@ public class UserStatusNodeService(val db: JdbcTemplate) { public fun update(node: UserStatusNode): UserStatusNode { db.update( - "update user_status_node set name=?, icon=?, x=?, y=?, width=?, height=?, permission=? where id=?;", + "update user_status_node set name=?, icon=?, x=?, y=?, width=?, height=?, permission=?, visible=?, endable=? where id=?;", node.name, node.icon, node.x, @@ -219,6 +223,8 @@ public class UserStatusNodeService(val db: JdbcTemplate) { node.width, node.height, node.permission, + node.visible, + node.endable, node.id, ) @@ -230,7 +236,7 @@ public class UserStatusNodeService(val db: JdbcTemplate) { node.id = id db.update( - "insert into user_status_node (id, user_id, name, icon, x, y, width, height, permission) values (?, ?, ?, ?, ?, ?, ?, ?, ?);", + "insert into user_status_node (id, user_id, name, icon, x, y, width, height, permission, visible, endable) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", node.id, node.user_id, node.name, @@ -239,7 +245,9 @@ public class UserStatusNodeService(val db: JdbcTemplate) { node.y, node.width, node.height, - node.permission + node.permission, + node.visible, + node.endable, ) return node diff --git a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/View.kt b/api/src/main/kotlin/com/andr3h3nriqu3s/applications/View.kt deleted file mode 100644 index 89eba09..0000000 --- a/api/src/main/kotlin/com/andr3h3nriqu3s/applications/View.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.andr3h3nriqu3s.applications - -import java.sql.ResultSet -import java.sql.Timestamp -import java.util.Date -import java.util.UUID -import org.springframework.http.MediaType -import org.springframework.jdbc.core.JdbcTemplate -import org.springframework.jdbc.core.RowMapper -import org.springframework.stereotype.Service -import org.springframework.web.bind.annotation.ControllerAdvice -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestHeader -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -data class View(var id: String, var application_id: String, var time: Timestamp) { - companion object : RowMapper { - override public fun mapRow(rs: ResultSet, rowNum: Int): View { - return View( - rs.getString("id"), - rs.getString("application_id"), - rs.getTimestamp("time"), - ) - } - } -} - -@RestController -@ControllerAdvice -@RequestMapping("/api/view") -class ViewController( - val sessionService: SessionService, - val applicationService: ApplicationService, - val flairService: FlairService, - val viewService: ViewService, -) { - - @GetMapping(path = ["/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - public fun getCV(@PathVariable id: String, @RequestHeader("token") token: String): List { - val user = sessionService.verifyTokenThrow(token) - - val application = applicationService.findApplicationById(user, id) - - if (application == null) { - throw NotFound() - } - - return application.views - } -} - -@Service -public class ViewService(val db: JdbcTemplate) { - - public fun listFromApplicationId(id: String): List = - db.query("select * from views where application_id=?;", arrayOf(id), View).toList() - - public fun getById(id: String): View? { - val items = db.query("select * from views where id=?;", arrayOf(id), View).toList() - if (items.size == 0) { - return null - } - return items[0] - } - - public fun deleteById(id: String): View { - val view = this.getById(id) - if (view == null) { - throw NotFound() - } - - db.update("delete from views where id=?", id) - - return view - } - - public fun update(view: View): View { - db.update( - "update views set application_id=?, time=? where id=?;", - view.application_id, - view.time, - view.id, - ) - - return view - } - - public fun create(application_id: String): View { - val id = UUID.randomUUID().toString() - - var new_view = View(id, application_id, Timestamp(Date().getTime())) - - db.update( - "insert into views (id, application_id) values (?, ?)", - new_view.id, - new_view.application_id - ) - - return new_view - } -} diff --git a/api/src/main/resources/schema.sql b/api/src/main/resources/schema.sql index b712a14..15a4c4c 100644 --- a/api/src/main/resources/schema.sql +++ b/api/src/main/resources/schema.sql @@ -1,61 +1,53 @@ CREATE TABLE IF NOT EXISTS users ( - id VARCHAR PRIMARY KEY, - username VARCHAR NOT NULL, - email VARCHAR NOT NULL, - passwd VARCHAR NOT NULL, - level INT NOT NULL + id VARCHAR PRIMARY KEY, + username VARCHAR NOT NULL, + email VARCHAR NOT NULL, + passwd VARCHAR NOT NULL, + level INT NOT NULL ); -CREATE TABLE IF NOT EXISTS tokens ( - token VARCHAR PRIMARY KEY, - user_id VARCHAR -); +CREATE TABLE IF NOT EXISTS tokens (token VARCHAR PRIMARY KEY, user_id VARCHAR); create table if not exists applications ( - id text primary key, - url text not null, - original_url text, - unique_url text, - company text, - recruiter text, - title text, - mesasge text default '', - status_history text default '', - user_id text, - extra_data text, - -- this status will be deprecated in favor of the node style status - status integer, - status_id text default null, - linked_application text default '', - application_time text default '', - agency boolean default false, - create_time timestamp default now() + id text primary key, + url text not null, + simple_url text not null, + company text, + recruiter text, + title text, + mesasge text default '', + user_id text, + extra_data text, + status_id text default null, + agency boolean default false, + create_time timestamp default now () ); --- Views are deprecated will be removed in the future -create table if not exists views ( - id text primary key, - application_id text not null, - time timestamp default now() +create table if not exists applications_urls ( + application_id text, + url text not null, + primary key (application_id, url) ); create table if not exists flair ( - id text primary key, - user_id text not null, - color text default '#ff0000', - name text default 'New Flair', - expr text default 'flair', - description text default '' + id text primary key, + user_id text not null, + color text default '#ff0000', + name text default 'New Flair', + expr text default 'flair', + description text default '', + showFullDescription integer default 1, + sort integer default 0 ); create table if not exists flair_link ( - id text primary key, - application_id text not null, - flair_id text not null + id text primary key, + application_id text not null, + flair_id text not null ); create table if not exists events ( - id text primary key, + id text primary key, application_id text not null, -- -- Event Types @@ -64,46 +56,41 @@ create table if not exists events ( -- Creation(0), -- StatusUpdate(1), -- Page(2) - event_type integer not null, - + event_type integer not null, -- This only matters when event_type == 1 - new_status integer, - - time timestamp default now() + new_status_id text, + time timestamp default now () ); -- -- User Controlled Status -- - create table if not exists user_status_node ( - id text primary key, - user_id text not null, - name text not null, - icon text not null, - x integer default 0, - y integer default 0, - width integer default 0, - height integer default 0, - permission integer default 0 + id text primary key, + user_id text not null, + name text not null, + icon text not null, + x integer default 0, + y integer default 0, + width integer default 0, + height integer default 0, + permission integer default 0, + visible boolean default true, + endable boolean default false ); create table if not exists user_status_link ( - id text primary key, + id text primary key, -- You technically can get this by loking a the source and target nodes but that seams more complicated - user_id text not null, - + user_id text not null, -- This can be null because null means creation source_node text, -- This can be null because null means creation target_node text, - - source_x integer default 0, - source_y integer default 0, - - target_x integer default 0, - target_y integer default 0, - + source_x integer default 0, + source_y integer default 0, + target_x integer default 0, + target_y integer default 0, -- If this link is bidiretoral - bi boolean + bi boolean ); diff --git a/site/src/lib/ApplicationsStore.svelte.ts b/site/src/lib/ApplicationsStore.svelte.ts index 7c33ed0..362012d 100644 --- a/site/src/lib/ApplicationsStore.svelte.ts +++ b/site/src/lib/ApplicationsStore.svelte.ts @@ -1,138 +1,67 @@ import type { Flair } from './FlairStore.svelte'; -import { post } from './utils'; +import { get } from './utils'; export type AsEnum = T[keyof T]; -export const ApplicationStatus = Object.freeze({ - ToApply: 0, - WorkingOnIt: 1, - Ignore: 2, - ApplyedButSaidNo: 3, - Applyed: 4, - Expired: 5, - TasksToDo: 6, - TasksToDo2: 10, - LinkedApplication: 7, - InterviewStep1: 8, - InterviewStep2: 9, - FinalInterview: 11 -}); - -export const ApplicationStatusIconMaping: Record, string> = Object.freeze({ - 0: 'clock', - 1: 'search', - 2: 'trash3', - 3: 'fire', - 4: 'send', - 5: 'hourglass-bottom', - 6: 'list-check', - 10: 'list-check', - 7: 'link-45deg', - 8: 'person', - 9: 'people', - 11: 'badge-vo-fill' -}); - -export const ApplicationStatusMaping: Record, string> = Object.freeze({ - 0: 'To Apply', - 1: 'Working On It', - 2: 'Ignore', - 3: 'Applyed But Said No', - 4: 'Applyed', - 5: 'Expired', - 6: 'Tasks To Do', - 10: 'Tasks To Do 2', - 7: 'Linked Application', - 8: 'Interview 1', - 9: 'Interview 2', - 11: 'Final Interview' -}); - -export type View = { - id: string; - application_id: string; - time: string; -}; - export const EventType = Object.freeze({ Creation: 0, StatusUpdate: 1, - View: 2, + View: 2 }); export type ApplicationEvent = { - id: string, - application_id: string, - event_type: AsEnum, - new_status: number, - time: string -} + id: string; + application_id: string; + event_type: AsEnum; + new_status_id: string; + time: string; +}; export type Application = { id: string; url: string; - original_url: string | null; - unique_url: string | null; + simple_url: string; title: string; user_id: string; extra_data: string; payrange: string; - status: AsEnum; + status_id: string; recruiter: string; agency: boolean; company: string; message: string; linked_application: string; - application_time: string; create_time: string; status_history: string; flairs: Flair[]; - views: View[]; events: ApplicationEvent[]; }; function createApplicationStore() { - let applications: Application[] = $state([]); - let applyed: Application[] = $state([]); let all: Application[] = $state([]); let dragApplication: Application | undefined = $state(undefined); let loadItem: Application | undefined = $state(undefined); + let loadItemOpen = $state(true); + + let req = false; return { - /** - * @throws {Error} - */ - async loadApplications(force = false) { - if (!force && applications.length > 1) { - return; - } - applications = await post('application/list', { status: 0 }); - }, - - /** - * @throws {Error} - */ - async loadAplyed(force = false) { - if (!force && applyed.length > 1) { - return; - } - applyed = await post('application/list', { status: ApplicationStatus.Applyed, views: true }); - }, - /** * @throws {Error} */ async loadAll(force = false) { + if (req) return; if (!force && all.length > 1) { return; } - all = await post('application/list', {}); - }, - - clear() { - applications = []; + req = true; + try { + all = await get('application/list'); + } finally { + req = false; + } }, dragStart(application: Application | undefined) { @@ -146,28 +75,53 @@ function createApplicationStore() { dragApplication = undefined; }, + removeByID(uuid: string) { + all = all.filter((i) => i.id !== uuid); + }, + + getIndexById(uuid: string): number | undefined { + return all + .map((a, i) => [a, i] as [Application, number]) + .filter((i) => i[0].id === uuid)[0]?.[1]; + }, + get dragging() { return dragApplication; }, - get applications() { - return applications; - }, - - get applyed() { - return applyed; - }, - get all() { return all; }, + reset() { + // This just tells svelte that we changed all + all = all; + }, + + set(item: Application, index?: number) { + if (index === undefined) { + index = this.getIndexById(item.id); + } + if (index === undefined) return; + all[index] = item; + this.reset(); + }, + get loadItem() { return loadItem; }, set loadItem(item: Application | undefined) { loadItem = item; + loadItemOpen = true; + }, + + get loadItemOpen() { + return loadItemOpen; + }, + + set loadItemOpen(_loadItemOpen: boolean) { + loadItemOpen = _loadItemOpen; } }; } diff --git a/site/src/lib/FlairStore.svelte.ts b/site/src/lib/FlairStore.svelte.ts index 9224d28..4bb6ea8 100644 --- a/site/src/lib/FlairStore.svelte.ts +++ b/site/src/lib/FlairStore.svelte.ts @@ -1,29 +1,31 @@ import { get } from './utils'; export type Flair = { - id: string; - user_id: string; - color: string; - name: string; - expr: string; - description: string; + id: string; + user_id: string; + color: string; + name: string; + expr: string; + description: string; + showFullDescription: number; + sort: number; }; function createFlairStore() { - let flairList: Flair[] = $state([]); + let flairList: Flair[] = $state([]); - return { - get flairs() { - return flairList; - }, + return { + get flairs() { + return flairList; + }, - async loadItems(force?: boolean) { - if (flairList.length > 0 && !force) { - return; - } - flairList = await get('flair/'); - } - }; + async loadItems(force?: boolean) { + if (flairList.length > 0 && !force) { + return; + } + flairList = await get('flair/'); + } + }; } export const flairStore = createFlairStore(); diff --git a/site/src/lib/Types.svelte.ts b/site/src/lib/Types.svelte.ts new file mode 100644 index 0000000..dd1aa69 --- /dev/null +++ b/site/src/lib/Types.svelte.ts @@ -0,0 +1,80 @@ +import { get } from './utils'; +import type { Node, FullLinkApi } from '../routes/flow/types'; + +function createStatusStore() { + let nodes: Node[] = $state([]); + let links: FullLinkApi[] = $state([]); + + let nodesR: Record = $state({}); + let dirLinks: Record = $state({}); + + let request = false; + + return { + /** + * @throws {Error} + **/ + async load(clear = false) { + if (!clear && nodes.length !== 0) { + return; + } + if (request) return; + + request = true; + + try { + nodes = await get('user/status/node'); + links = await get('user/status/link'); + } catch (e) { + request = false; + throw e; + } + + dirLinks = {}; + nodesR = {}; + + nodes.sort((a, b) => { + if (a.y !== b.y) return a.y - b.y; + return b.x - a.x; + }); + + for (const node of nodes) { + nodesR[node.id] = node; + } + + const nodesId: string[] = [null as any, ...Object.keys(nodesR)]; + + nodesR[null as any] = { + icon: 'plus', + id: null as any, + name: 'Created' + } as any; + + for (const nodeId of nodesId) { + const targets = []; + for (const link of links) { + if (link.source_node === nodeId) { + targets.push(nodesR[link.target_node as any]); + } + } + dirLinks[nodeId] = targets; + } + + request = false; + }, + + get nodes() { + return nodes; + }, + + get nodesR() { + return nodesR; + }, + + get dirLinks() { + return dirLinks; + } + }; +} + +export const statusStore = createStatusStore(); diff --git a/site/src/routes/+page.svelte b/site/src/routes/+page.svelte index 230b803..1e9d1ae 100644 --- a/site/src/routes/+page.svelte +++ b/site/src/routes/+page.svelte @@ -3,9 +3,7 @@ import HasUser from '$lib/HasUser.svelte'; import ApplicationsList from './ApplicationsList.svelte'; import WorkArea from './work-area/WorkArea.svelte'; - import AppliyedList from './AppliyedList.svelte'; - import PApplicationList from './PApplicationList.svelte'; - import { ApplicationStatus } from '$lib/ApplicationsStore.svelte'; + import ApplicationTypesList from './ApplicationTypesList.svelte'; @@ -13,25 +11,11 @@
- +
- - Interview Final - - - Interview II - - - Interview I - - - Tasks To do 2 - - - Tasks To do - - + +
diff --git a/site/src/routes/ApplicationTypesList.svelte b/site/src/routes/ApplicationTypesList.svelte new file mode 100644 index 0000000..a7ffafd --- /dev/null +++ b/site/src/routes/ApplicationTypesList.svelte @@ -0,0 +1,17 @@ + + +{#if statusStore.nodes.length > 0} + {#each statusStore.nodes as node} + {#if node.visible} + + {/if} + {/each} +{/if} diff --git a/site/src/routes/ApplicationsList.svelte b/site/src/routes/ApplicationsList.svelte index c6435ff..f0f5c98 100644 --- a/site/src/routes/ApplicationsList.svelte +++ b/site/src/routes/ApplicationsList.svelte @@ -5,11 +5,15 @@ let filter = $state(''); onMount(() => { - applicationStore.loadApplications(); + applicationStore.loadAll(); }); + let apps = $derived( + applicationStore.all.filter((i) => i.status_id === null && !i.linked_application) + ); + let internal = $derived( - applicationStore.applications.filter((i) => { + apps.filter((i) => { if (!filter) { return true; } @@ -47,10 +51,7 @@ }} role="none" > -
+

diff --git a/site/src/routes/AppliyedList.svelte b/site/src/routes/AppliyedList.svelte deleted file mode 100644 index 7a1bfc1..0000000 --- a/site/src/routes/AppliyedList.svelte +++ /dev/null @@ -1,59 +0,0 @@ - - -
-

- Applied -

-
- {#each applicationStore.applyed.filter((i) => { - if (!filter) { - return true; - } - const f = new RegExp(filter, 'ig'); - - let x = i.title; - - if (i.company) { - x = `${x} @ ${i.company}`; - } - - return x.match(f); - }) as item} - - {/each} -
-
-
-
diff --git a/site/src/routes/NavBar.svelte b/site/src/routes/NavBar.svelte index 3100614..89c9bd2 100644 --- a/site/src/routes/NavBar.svelte +++ b/site/src/routes/NavBar.svelte @@ -5,9 +5,8 @@
- - - {/each} -
-
-{/if} diff --git a/site/src/routes/SmartApplicationList.svelte b/site/src/routes/SmartApplicationList.svelte new file mode 100644 index 0000000..0d1c8bd --- /dev/null +++ b/site/src/routes/SmartApplicationList.svelte @@ -0,0 +1,64 @@ + + +{#if sorted.length > 0} +
+

+ {title} +

+
+ {#each sorted.filter((i) => { + if (!filter) { + return true; + } + const f = new RegExp(filter, 'ig'); + + let x = i.title; + + if (i.company) { + x = `${x} @ ${i.company}`; + } + + return x.match(f); + }) as item} + + {/each} +
+
+{/if} diff --git a/site/src/routes/cv/+page.svelte b/site/src/routes/cv/+page.svelte index 825d408..8385e0c 100644 --- a/site/src/routes/cv/+page.svelte +++ b/site/src/routes/cv/+page.svelte @@ -2,7 +2,7 @@ import { userStore } from '$lib/UserStore.svelte'; import { get } from '$lib/utils'; import { onMount } from 'svelte'; - import ApplicationsList from '../ApplicationsList.svelte'; + import Pill from './pill.svelte'; let id: string | undefined | null = $state(undefined); @@ -18,13 +18,15 @@ name: string; description: string; color: string; + sort: number; + showFullDescription: number; }; type Application = { recruiter: string; message: string; company: string; - agency: boolean, + agency: boolean; flairs: SimpleFlair[]; }; @@ -40,16 +42,19 @@ } application.flairs.sort((a, b) => { - if (a.description && b.description) { - return 0; + const aDesc = a.description && a.showFullDescription === 1; + const bDesc = b.description && b.showFullDescription === 1; + + if (aDesc && bDesc) { + return b.sort - a.sort; } - if (a.description) { + if (aDesc) { return -1; } - if (b.description) { + if (bDesc) { return 1; } - return 0; + return b.sort - a.sort; }); loadFlairs(); @@ -82,7 +87,7 @@
-
+

Andre Henriques

@@ -113,7 +118,7 @@
-
+
I am a dedicated and versatile programmer with four years of professional experience.
@@ -128,18 +133,21 @@
+ {#if application} - {#if !application.agency} -

- 👋 Hello - {#if application.recruiter} - {application.recruiter} @ - {application.company} - {:else if application.company} - recruiter @ {application.company} - {/if} -

- {/if} + {#if !application.agency} +

+ 👋 Hello + {#if application.recruiter} + {application.recruiter} @ + {application.company} + {:else if application.company} + recruiter @ {application.company} + {/if} +

+ {:else} +
+ {/if} {#if application.message}
@@ -153,41 +161,44 @@ {#if application.flairs.length > 0}

- Your Ad & My skills {#if flairs.length > 0} 0} - + {/if}

-
+
{#if otherSearch === ''} {#each application.flairs as flair} -
- {#if flair.description} + {@const hasDesc = flair.description && flair.showFullDescription === 1} +
+ {#if hasDesc}
-
{flair.name} -
+
{flair.description}
{:else} -
+ {flair.name} -
+ {/if}
{/each} @@ -196,10 +207,10 @@ a.name.match(new RegExp(otherSearch, 'i')) )} {#if filtered_list.length == 0} -
- Could not find the skill you are looking for. -
- {:else} +
+ Could not find the skill you are looking for. +
+ {:else} {#each filtered_list as flair}
{#if flair.description} @@ -234,20 +245,18 @@
{/if} {/if} -
+
-

+

Work Expericence

-
-
-
+

Senior Software Developer @ Planum Solucoes

+

4 years - May 2020 - Present

-

4 years - May 2020 - Present

Developed various projects:

  • Developing various websites using React and Svelte.
  • @@ -255,30 +264,20 @@
  • Implemented an ORM system using Java Reflection
  • Implemented automatic deployment with GitLab CI/CD tools.
  • Linux Server Administration
  • -
  • Technologies used: React, WebRTC, WebSockets, Rest, Google Maps AP
-
+
-
+

Associate Devops Engineer @ Sky UK

-
-

1 year - July 2022 - June 2023

-

Working with:

-
    -
  • Python
  • -
  • Jenkins
  • -
  • GitLab CI
  • -
  • Ansible
  • -
  • Docker
  • -
-

Associated Software Developer / DevOps Engineer:

+

1 year - July 2022 - June 2023

+
  • Developed web-based tools for the DevOps team to use
  • @@ -298,13 +297,15 @@
-
- -
-

Education

+
+

+ Education +

+
+
-

Bachelors of science in Computer Science @ University of Surrey

+

BCompSc with First Class Honours @ University of Surrey

July 2020 - June 2024

@@ -312,6 +313,8 @@
+
+ +
+ + +
{/if}
diff --git a/site/src/routes/flow/types.ts b/site/src/routes/flow/types.ts index 8301815..6fe0058 100644 --- a/site/src/routes/flow/types.ts +++ b/site/src/routes/flow/types.ts @@ -1,60 +1,69 @@ export type Node = { - id: string, - user_id: string, - x: number; - y: number; - width: number; - height: number; - name: string; - icon: string; - // 1 disables editing - permission: number; + id: string; + user_id: string; + x: number; + y: number; + width: number; + height: number; + name: string; + icon: string; + // 1 disables editing + permission: number; + visible: boolean; + endable: boolean; }; export type LinkNode = { - node: Node; - x: number; - y: number; -} + node: Node; + x: number; + y: number; +}; export type FullLink = { - sourceNode: LinkNode; - targetNode: LinkNode; - bi?: boolean; -} + sourceNode: LinkNode; + targetNode: LinkNode; + bi?: boolean; +}; export type FullLinkApi = { - id: string, - user_id: string, - target_node: string | null, - source_node: string | null, - bi: boolean, - source_x: number, - source_y: number, - - target_x: number, - target_y: number -} + id: string; + user_id: string; + target_node: string | null; + source_node: string | null; + bi: boolean; + source_x: number; + source_y: number; + target_x: number; + target_y: number; +}; export type ActionType = undefined | 'drag' | 'create' | 'move' | 'link'; -export function extractLinkNodePosX(canvasX: (x: number) => number, node: LinkNode, grid_size: number) { - if (node.x === -1) { - return canvasX(node.node.x); - } - if (node.x === node.node.width) { - return canvasX(node.node.x) + node.node.width * grid_size; - } - return canvasX(node.node.x) + node.x * grid_size + grid_size / 2; +export function extractLinkNodePosX( + canvasX: (x: number) => number, + node: LinkNode, + grid_size: number +) { + if (node.x === -1) { + return canvasX(node.node.x); + } + if (node.x === node.node.width) { + return canvasX(node.node.x) + node.node.width * grid_size; + } + return canvasX(node.node.x) + node.x * grid_size + grid_size / 2; } -export function extractLinkNodePosY(canvasY: (x: number) => number, node: LinkNode, grid_size: number) { - if (node.y === -1) { - return canvasY(node.node.y); - } - if (node.y === node.node.height) { - return canvasY(node.node.y) + node.node.height * grid_size; - } - return canvasY(node.node.y) + node.y * grid_size + grid_size / 2; +export function extractLinkNodePosY( + canvasY: (x: number) => number, + node: LinkNode, + grid_size: number +) { + if (node.y === -1) { + return canvasY(node.node.y); + } + if (node.y === node.node.height) { + return canvasY(node.node.y) + node.node.height * grid_size; + } + return canvasY(node.node.y) + node.y * grid_size + grid_size / 2; } diff --git a/site/src/routes/graphs/+page.svelte b/site/src/routes/graphs/temp_+page.svelte.ignore similarity index 100% rename from site/src/routes/graphs/+page.svelte rename to site/src/routes/graphs/temp_+page.svelte.ignore diff --git a/site/src/routes/submit/+page.svelte b/site/src/routes/submit/+page.svelte index 347993b..cca620d 100644 --- a/site/src/routes/submit/+page.svelte +++ b/site/src/routes/submit/+page.svelte @@ -11,7 +11,7 @@ async function submit() { try { await post('application/text', text); - applicationStore.loadApplications(true); + applicationStore.loadAll(true); goto('/'); } catch (e) { console.log(e); diff --git a/site/src/routes/work-area/AutoDropZone.svelte b/site/src/routes/work-area/AutoDropZone.svelte new file mode 100644 index 0000000..15f4fa6 --- /dev/null +++ b/site/src/routes/work-area/AutoDropZone.svelte @@ -0,0 +1,63 @@ + + +{#if applicationStore.dragging && derivedItem} +
+ {#each statusStore.dirLinks[derivedItem.status_id] as node} + moveStatus(node.id, node.endable)} + >{node.name} + {/each} + + remove()}>Delete it +
+{/if} diff --git a/site/src/routes/work-area/CompanyField.svelte b/site/src/routes/work-area/CompanyField.svelte index 79f27ee..51b6cb2 100644 --- a/site/src/routes/work-area/CompanyField.svelte +++ b/site/src/routes/work-area/CompanyField.svelte @@ -1,26 +1,37 @@
- +
{#each fcomps as comp} - {/each} diff --git a/site/src/routes/work-area/DropingZone.svelte b/site/src/routes/work-area/DropingZone.svelte deleted file mode 100644 index be98eb3..0000000 --- a/site/src/routes/work-area/DropingZone.svelte +++ /dev/null @@ -1,198 +0,0 @@ - - -{#if applicationStore.dragging && activeItem} -
- - {#if activeItem.status === ApplicationStatus.WorkingOnIt} - { - await moveStatus(ApplicationStatus.ToApply); - applicationStore.loadAplyed(true); - applicationStore.loadAll(true); - }} - > - To apply - - {/if} - - {#if activeItem.status === ApplicationStatus.WorkingOnIt} - - moveStatus(ApplicationStatus.Ignore)}> - Ignore it - - {/if} - - {#if ([ApplicationStatus.WorkingOnIt, ApplicationStatus.Expired] as number[]).includes(activeItem.status)} - - { - if (activeItem && activeItem.status === ApplicationStatus.Expired) { - moveStatus(ApplicationStatus.ToApply, false); - } else { - moveStatus(ApplicationStatus.Expired); - } - }} - > - Mark as expired - - {/if} - - {#if activeItem.status === ApplicationStatus.WorkingOnIt} - - remove()}>Delete it - {/if} - - {#if ([ApplicationStatus.WorkingOnIt, ApplicationStatus.TasksToDo] as number[]).includes(activeItem.status)} - - { - await moveStatus(ApplicationStatus.Applyed); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - Apply - - {/if} - - {#if activeItem.status === ApplicationStatus.Applyed} - - { - await moveStatus(ApplicationStatus.TasksToDo); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - Tasks To Do - - {/if} - - {#if activeItem.status === ApplicationStatus.TasksToDo} - - { - await moveStatus(ApplicationStatus.TasksToDo2); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - Tasks To Do 2 - - {/if} - - {#if ([ApplicationStatus.TasksToDo, ApplicationStatus.Applyed] as number[]).includes(activeItem.status)} - - { - await moveStatus(ApplicationStatus.InterviewStep1); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - Interview 1 - - {/if} - - {#if ([ApplicationStatus.InterviewStep1] as number[]).includes(activeItem.status)} - - { - await moveStatus(ApplicationStatus.InterviewStep2); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - Interview 2 - - {/if} - - {#if ([ApplicationStatus.InterviewStep1, ApplicationStatus.InterviewStep2] as number[]).includes(activeItem.status)} - - { - await moveStatus(ApplicationStatus.FinalInterview); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - Interview Final - - {/if} - - {#if !([ApplicationStatus.ApplyedButSaidNo] as number[]).includes(activeItem.status)} - - { - moveStatus(ApplicationStatus.ApplyedButSaidNo); - applicationStore.loadAll(true); - applicationStore.loadAplyed(true); - }} - > - I was rejeted :( - - {/if} -
-{/if} diff --git a/site/src/routes/work-area/ExtractTextDialog.svelte b/site/src/routes/work-area/ExtractTextDialog.svelte index 3ab8e20..3d8c212 100644 --- a/site/src/routes/work-area/ExtractTextDialog.svelte +++ b/site/src/routes/work-area/ExtractTextDialog.svelte @@ -22,7 +22,7 @@ onreload(); } catch (e) { // Show message to the user - console.log(e); + console.log('TODO inform the user', e); } } diff --git a/site/src/routes/work-area/LinkApplication.svelte b/site/src/routes/work-area/LinkApplication.svelte index 1476589..1ebfd45 100644 --- a/site/src/routes/work-area/LinkApplication.svelte +++ b/site/src/routes/work-area/LinkApplication.svelte @@ -1,6 +1,7 @@ - -
- -
- {applications.length} -
-
-
- {#each applications.filter((i) => { + let internal = $derived( + applicationStore.all.filter((i) => { if (!filter) { return true; } @@ -62,7 +41,19 @@ } return x.match(f); - }) as item} + }) + ); + + + +
+ +
+ {internal.length} +
+
+
+ {#each internal as item}
{/if}

- - {ApplicationStatusMaping[item.status]} - + + {statusStore.nodesR[item.status_id].name} +
{/each} diff --git a/site/src/routes/work-area/NewApplication.svelte b/site/src/routes/work-area/NewApplication.svelte index 92baa04..f6d9532 100644 --- a/site/src/routes/work-area/NewApplication.svelte +++ b/site/src/routes/work-area/NewApplication.svelte @@ -1,8 +1,8 @@ - + { + dialogAddMultiple = false; + }} +>
- - + + {#if dialogAddMultiple} + + {:else} + + {/if}
+
+ {#if dialogAddMultiple} + + {/if} +
diff --git a/site/src/routes/work-area/NewUrlDialog.svelte b/site/src/routes/work-area/NewUrlDialog.svelte index 34c58e5..4b4292e 100644 --- a/site/src/routes/work-area/NewUrlDialog.svelte +++ b/site/src/routes/work-area/NewUrlDialog.svelte @@ -1,16 +1,18 @@ {#if events.length > 0} @@ -118,28 +85,24 @@ class="shadow-sm shadow-violet-500 border rounded-full min-w-[50px] min-h-[50px] grid place-items-center bg-white z-10" > {#if event.event_type == EventType.Creation} - {:else if event.event_type == EventType.View} - {:else} {/if}
- {#if i != events.length - 1 || !endable.includes(event.new_status)} -
+ + + {#if i != events.length - 1 || !statusStore.nodesR[event.new_status_id].endable} +
{#if event.timeDiff}
diff --git a/site/src/routes/work-area/WorkArea.svelte b/site/src/routes/work-area/WorkArea.svelte index b7b6297..559f516 100644 --- a/site/src/routes/work-area/WorkArea.svelte +++ b/site/src/routes/work-area/WorkArea.svelte @@ -1,10 +1,5 @@
- {#if activeItem && (!applicationStore.dragging || applicationStore.dragging?.id === activeItem.id)} + {#if activeItem !== undefined && (!applicationStore.dragging || applicationStore.dragging?.id === derivedItem.id)}
{ - applicationStore.dragStart(activeItem); + applicationStore.dragStart(derivedItem); }} ondragend={() => { window.requestAnimationFrame(() => { @@ -218,35 +198,34 @@ class="flex flex-col p-2 h-full gap-2 card min-w-0 flex-grow min-h-[50vh]" >
- {#if activeItem.status != 1} + + {#if derivedItem.status_id !== null}
- {(ApplicationStatusMaping[ - activeItem?.status as (typeof ApplicationStatus)[keyof typeof ApplicationStatus] - ] as string) ?? ''} + {statusStore.nodesR[derivedItem.status_id].name}
{/if} {#if showExtraData}
Id
- {activeItem.id} + {derivedItem.id}
Create Time
- {activeItem.create_time} + {derivedItem.create_time}
{/if}
- +
@@ -256,7 +235,7 @@ class="finput" id="title" type="checkbox" - bind:checked={activeItem.agency} + bind:checked={applicationStore.all[activeItem].agency} onchange={save} /> @@ -266,7 +245,7 @@ @@ -275,51 +254,36 @@ - {#if !activeItem.unique_url || showExtraData} + {#if !derivedItem.simple_url || showExtraData}
Url
- {activeItem.url} + {derivedItem.url}
{/if} - {#if activeItem.unique_url} -
-
Unique Url
-
- {activeItem.unique_url} -
-
- {/if} - {#if activeItem.linked_application} -
-
Linked Application
-
- {activeItem.linked_application} -
-
- {/if} - {#if activeItem.application_time} -
-
Application Time
-
- {activeItem.application_time} + {#if derivedItem.simple_url} +
+
Simple Url
+
+ {derivedItem.simple_url}
{/if}
Tags
- {#each activeItem.flairs as item} + {#each derivedItem.flairs as item} (activeItem = item)} + application={derivedItem} + updateApplication={(item) => + (applicationStore.all[activeItem ?? -1] = item)} /> {/each}
@@ -329,7 +293,7 @@
@@ -338,24 +302,16 @@ - {#if activeItem.views.length > 0} -

Non Loggedin Views Time ({activeItem.views.length})

- {#each activeItem.views as view} -
- {view.time} -
- {/each} - {/if}
{/if} - {#if activeItem.original_url == null} - - {/if} +
- {#if activeItem.original_url != null} - - {/if}
- +
- + {:else}
- + activate(derivedItem, false)} +/> -{#if !activeItem?.original_url} +{#if derivedItem} { - item.events = await get(`events/${item.id}`); - activeItem = item; + activate(item, false); }} /> {/if} -{#if activeItem} +{#if derivedItem} (activeItem = item)} + onreload={(item) => activate(item, false)} /> {/if} { - item.events = await get(`events/${item.id}`); - activeItem = item; + activate(item); }} />