-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Candidature : postuler pour un candidat depuis l'espace "Mes candidats" #4860
base: master
Are you sure you want to change the base?
Conversation
dba9517
to
1670526
Compare
fa19835
to
5f62cce
Compare
🥁 La recette jetable est prête ! 👉 Je veux tester cette PR ! |
5f62cce
to
9e00177
Compare
<p class="mb-0 text-start w-100"> | ||
<i class="ri-arrow-right-line pe-2"></i><strong>Vous postulez actuellement pour {{ job_seeker.get_full_name }}</strong> | ||
</p> | ||
<a href="{% if request.user.is_prescriber %}{% url "job_seekers_views:list" %}{% else %}{% url "apply:list_prescriptions" %}{% endif %}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quitter :
Si prescripteur : retour à la liste des candidats
Si employeur : retour à la liste des orientations
5cad6b6
to
17d7693
Compare
{ | ||
"fields": { | ||
"address_filled_at": null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Une utilisatrice en plus, orientée par une entreprise vers une autre entreprise
(ça permet de tester des choses là : http://127.0.0.1:8000/apply/prescriptions/list)
@@ -32,7 +49,7 @@ <h2 class="visually-hidden">Actions rapides</h2> | |||
</div> | |||
{% else %} | |||
<div class="form-group col-12 col-lg-auto"> | |||
<a href="{% url 'apply:start' company_pk=siae.pk %}" | |||
<a href="{% url 'apply:start' company_pk=siae.pk %}{% if job_seeker %}?job_seeker={{ job_seeker.public_id }}{% endif %}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pas mal d'ajouts de ?job_seeker=
dans les liens jusqu'à apply:start
.
@@ -245,6 +245,37 @@ def get(self, request, *args, **kwargs): | |||
else: | |||
self.apply_session.init({"selected_jobs": [job_description.pk]}) | |||
|
|||
# Go directly to step ApplicationJobsView if we're carrying the job seeker public id with us. | |||
if job_seeker_public_id := request.GET.get("job_seeker"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On vérifie ici si on a job_seeker=
passé en paramètre.
On vérifie s'il est valide, s'il correspond à un candidat et si l'utilisateur actuel peut voir ses informations personnelles.
A priori, si on peut "Postuler pour ce candidat", on voit ses informations personnelles ?
Je ne suis pas sûr, cela dit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- added a link in job seekers list ("Mes candidats") to apply in the name of a specific job seeker - all the links up to `apply:start` have been updated with a GET param (`job_seeker={public_id}`), this allows to keep track of the job seeker we are applying for - when a `job_seeker` GET param is present, and when the current `user` is allowed to, an alert is displayed at the top of the page to remind that we're applying for this job seeker
17d7693
to
621e398
Compare
# Create an empty variable to avoid unknown variable template errors in tests | ||
context["job_seeker"] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bonne pratique ou pas ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je trouve ça mieux que de devoir mettre des default partout dans les templates en tout cas :)
'<a class="btn btn-ico btn-link" data-bs-toggle="tooltip" data-bs-placement="top" ' | ||
'title="Postuler pour ce candidat" ' | ||
f'href="{reverse("search:employers_results")}?job_seeker={public_id}">' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Peut-être un peu trop de markup ?
f'<a href="{reverse("search:job_descriptions_results")}?city={guerande.slug}' | ||
f'&job_seeker={job_seeker_public_id}" ' | ||
'class="btn btn-ico btn-dropdown-filter" aria-label="Réinitialiser les filtres actifs">' | ||
'<i class="ri-eraser-line fw-bold" aria-hidden="true"></i>' | ||
'<span>Effacer tout</span></a>' | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Peut-être beaucoup trop de markup ?
Le moindre changement de classe fait capoter le test…
Mais en même temps je voudrais être sûr que le bouton "Effacet tout" contient bien l'attribut href avec job_seeker
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Un nouveau fichier de test, séparé du reste (vu que tout va être séparé par la suite).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ça m'a l'air très efficace comme solution :)
Le mixin mérite d'être retravaillé je pense pour gérer la gestion de l'argument au début et non à la fin du traitement de la requête
{% if job_seeker %} | ||
<div class="alert alert-primary fade show " role="status"> | ||
<p class="mb-0 text-start w-100"> | ||
<i class="ri-arrow-right-line pe-2"></i><strong>Vous postulez actuellement pour {{ job_seeker.get_full_name }}</strong> | ||
</p> | ||
<a href="{% if request.user.is_prescriber %}{% url "job_seekers_views:list" %}{% else %}{% url "apply:list_prescriptions" %}{% endif %}" | ||
class="btn btn-link-white btn-ico position-absolute top-0 end-0" | ||
aria-label="Quitter"> | ||
<i class="ri-close-line ri-lg pe-2" aria-hidden="true"></i> | ||
Quitter | ||
</a> | ||
</div> | ||
{% endif %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c'est présent plusieurs fois : tu devrais le mettre dans un template séparé et l'importer à chaque fois avec un include
@@ -7,7 +7,13 @@ | |||
<div class="col-12"> | |||
{% include "search/includes/siaes_search_subtitle.html" %} | |||
<div class="d-block w-100"> | |||
<form hx-get="{{ request.path }}" hx-trigger="change delay:.5s" hx-include="#id_city" hx-indicator="#job-search-results" hx-target="#job-search-results" hx-swap="outerHTML" hx-push-url="true"> | |||
<form hx-get="{{ request.path }}{% if job_seeker %}?job_seeker={{ job_seeker.public_id }}{% endif %}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tu as besoin de transmettre le job_seeker dans hx-get ?
# Create an empty variable to avoid unknown variable template errors in tests | ||
context["job_seeker"] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je trouve ça mieux que de devoir mettre des default partout dans les templates en tout cas :)
.select_related("jobseeker_profile") | ||
.first() | ||
) | ||
except ValidationError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je pense que si le job_seeker n'existe pas (le public_id n'est pas valide) il faudrait lever une 404, ou ou rediriger avec une erreur.
Du coup j'aurais tendance à traiter le query params job_seeker
dans le setup()
du mixin (ou dans le dispatch()
peut-être, j'ai un doute) et à l'enregistrer dans self.job_seeker
Dans get_context_data()
tu n'auras qu'à ajouter job_seeker
au context s'il a été trouvé dans le setup()
# If anonymous user, do not show the alert (meaning the context does not contain the job_seeker) | ||
response = self.client.get(url) | ||
self.assertNotContains( | ||
response, f"Vous postulez actuellement pour {job_application.job_seeker.get_full_name()}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tu devrais définir cette variable une fois au début du test, et la réutiliser par la suite :
BANNER_TXT = f"Vous postulez actuellement pour {job_application.job_seeker.get_full_name()}"
Comme ça, tu auras des assertContains(response, BANNER_TXT)
et assertNotContains(response, BANNER_TXT)
ce qui t'assures que le jour où ça change, tu modifies bien tout en même temps.
# If anonymous user, do not show the alert (meaning the context does not contain the job_seeker) | ||
response = self.client.get(url) | ||
self.assertNotContains( | ||
response, f"Vous postulez actuellement pour {job_application.job_seeker.get_full_name()}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idem dans ce test-ci
@@ -997,7 +997,7 @@ | |||
|
|||
</ul> | |||
|
|||
<a class="btn btn-secondary btn-block mt-4" href="/company/[PK of Company]/card">Voir la fiche de l'entreprise</a> | |||
<a class="btn btn-secondary btn-block mt-4" href="/company/[PK of Company]/card?">Voir la fiche de l'entreprise</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c'est normal que le ? apparaisse même quand il n'y a pas de job_seeker ?
@@ -22,7 +22,7 @@ <h3>{{ company.display_name }}</h3> | |||
<a href="{% url 'apply:job_application_external_transfer_step_1_company_card' job_application_id=job_app_to_transfer company_pk=company.pk %}{% if back_url|default:"" %}?back_url={{ back_url|urlencode }}{% endif %}" | |||
class="btn btn-secondary btn-block mt-4">Voir la fiche de l'entreprise</a> | |||
{% else %} | |||
<a href="{% url 'companies_views:card' siae_id=company.pk %}{% if back_url|default:"" and not open_in_tab|default:False %}?back_url={{ back_url|urlencode }}{% endif %}" | |||
<a href="{% url 'companies_views:card' siae_id=company.pk %}?{% if job_seeker|default:None %}job_seeker={{ job_seeker.public_id }}&{% endif %}{% if back_url|default:"" and not open_in_tab|default:False %}back_url={{ back_url|urlencode }}{% endif %}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hum... ça donne envie d'ajouter un template tag à qui on passe les arguments et qui les ajoute si la valeur est non nulle.
genre {% add_params job_seeker=job_seeker|default:None, back_url=back_url|default:"" %}
# Has link to company card with job_seeker public_id | ||
company_url_with_job_seeker_id = ( | ||
f"{guerande_company.get_card_url()}?job_seeker={job_seeker_public_id}" | ||
f"&back_url={urlencode_filter(response.wsgi_request.get_full_path())}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tu peux utiliser urllib.parse.quote
à la place de urlencode_filter
(c'est la fonction qui est utilisée en dessous)
cf tests/www/apply/test_process_external_transfer.py
.select_related("jobseeker_profile") | ||
.first() | ||
) | ||
except (User.DoesNotExist, ValueError, ValidationError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User.DoesNotExist
ne peut pas avoir lieu avec un first().
Le code ressemble beaucoup à celui dans le Mixin du commit précédent.
Il y a peut être moyen de mutualiser dans une fonction séparée ?
# Entry point: job seeker details | ||
# ---------------------------------------------------------------------- | ||
|
||
response = self.client.get(reverse("job_seekers_views:details", kwargs={"public_id": job_seeker.public_id})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
les employeurs n'y ont pas vraiment accès, si ?
Je ne vois pas de lien pour y arriver
🤔 Pourquoi ?
ETQU, lorsque je clique sur le bouton postuler depuis une ligne de la liste candidat ou depuis une page de détail d’un candidat,
je peux faire une recherche d’emploi et postuler sans avoir à renseigner l’adresse e-mail, le NIR du candidat ou les informations personnelles du candidat.
🍰 Comment ?
On passe l'identifiant public du candidat en paramètre
GET
(job_seeker=UUID
).Une mixin permet d'ajouter aux vues utilisées la variable
job_seeker
dans le contexte, si l'utilisateur connecté a la permission (user.can_view_personal_info
). Quand cette variable existe, les URLs utilisées contiennent paramètreGET
, et un bandeau d'information rappelle que l'on postule pour un candidat.🚨 À vérifier
🏝️ Comment tester
💻 Captures d'écran