Skip to content
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

Recherche de structures par le nom pour les admins et managers #21

Merged
merged 13 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions front/src/lib/components/forms/fields/select-field.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

// Spécifique du select
export let choices: Choice[];
export let searchFunction:
| ((searchText: string) => Promise<Choice[]>)
| undefined = undefined;
export let sort = false;
export let onChange = undefined;
export let placeholderMulti = "Choisir";
Expand Down Expand Up @@ -47,6 +50,7 @@
{id}
{choices}
{sort}
{searchFunction}
bind:value
on:blur={onBlur}
{onChange}
Expand Down
9 changes: 6 additions & 3 deletions front/src/lib/components/inputs/select/select.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<script lang="ts">
import AutoComplete from "./simple-autocomplete.svelte";

type Choice = { value: string | number; label: string };

export let id: string;
export let choices: { value: string | number; label: string }[] | undefined =
undefined;
export let choices: Choice[] | undefined = undefined;
export let fixedItemsValues: string[] = [];
export let sort = false;
export let value: string | number | string[] | number[] | undefined =
Expand All @@ -15,7 +16,9 @@
export let placeholderMulti = "";
export let multiple = false;
export let hideArrow = false;
export let searchFunction = undefined;
export let searchFunction:
| ((searchTxt: string) => Promise<Choice[]>)
| undefined = undefined;
export let delay = undefined;
export let localFiltering = undefined;
export let minCharactersToSearch = undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
export let fixedItemsValues: string[] = [];

// function to use to get all items (alternative to providing items)
export let searchFunction = null;
export let searchFunction:
| ((searchText: string) => Promise<any[]>)
| undefined = undefined;

export let textCleanFunction = function (userEnteredText) {
return userEnteredText;
Expand Down
7 changes: 5 additions & 2 deletions front/src/lib/requests/structures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ export async function siretWasAlreadyClaimed(siret: string) {
return result;
}

export async function getManagedStructures(): Promise<ShortStructure[]> {
const url = `${getApiURL()}/structures/?managed=1`;
export async function getManagedStructures(
searchText?: string
): Promise<ShortStructure[]> {
const searchParam = searchText ? `&search=${searchText}` : "";
const url = `${getApiURL()}/structures/?managed=1${searchParam}`;
return (await fetchData<ShortStructure[]>(url)).data;
}

Expand Down
22 changes: 22 additions & 0 deletions front/src/lib/utils/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,25 @@ export function clickOutside(node: HTMLElement) {
},
};
}

// Helper type pour aplatir les promesses
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;

export function debounce<T extends (...args: any[]) => any>(
func: T,
delay = 300
): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> {
let timeoutId: ReturnType<typeof setTimeout>;

return (...args: Parameters<T>) => {
return new Promise<Awaited<ReturnType<T>>>((resolve) => {
if (timeoutId) {
clearTimeout(timeoutId);
} // Réinitialiser le timeout s'il existe déjà
timeoutId = setTimeout(() => {
const result = func(...args);
resolve(result); // Résout avec le résultat, qui peut être une promesse ou une valeur simple
}, delay);
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
import FieldSet from "$lib/components/display/fieldset.svelte";
import SelectField from "$lib/components/forms/fields/select-field.svelte";
import { getModel, getServicesOptions } from "$lib/requests/services";
import { getStructure } from "$lib/requests/structures";
import { getManagedStructures, getStructure } from "$lib/requests/structures";
import type {
Choice,
Model,
Service,
ServicesOptions,
ShortStructure,
} from "$lib/types";
import { debounce } from "$lib/utils/misc";
import { onMount } from "svelte";

export let servicesOptions: ServicesOptions;
export let service: Service;
export let managedStructureSearchMode = false;
export let structures: ShortStructure[];
export let structure: ShortStructure | undefined;
export let isModel = false;
Expand Down Expand Up @@ -100,8 +103,20 @@
}
}

async function searchFunction(searchText: string): Promise<Choice[]> {
if (searchText.length < 3) {
return [];
}
return (await getManagedStructures(searchText)).map((struct) => ({
value: struct.slug,
label: struct.name,
}));
}

// Il s'agit d'une édition de service existant
const showStructures = service.structure ? false : structures.length > 1;
const showStructures = service.structure
? false
: structures.length > 1 || managedStructureSearchMode;

onMount(() => {
if (structure && service.structure) {
Expand All @@ -120,7 +135,13 @@
}))}
onChange={handleStructureChange}
sort
searchFunction={managedStructureSearchMode
? debounce(searchFunction)
: undefined}
disabled={!showStructures}
placeholder="Sélectionnez la structure…"
description={managedStructureSearchMode
? "Tapez au moins 3 lettres pour lancer la recherche."
: ""}
/>
</FieldSet>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<CenteredGrid>
<h1>Création d’un service</h1>

{#if !data.structures.length}
{#if !data.managedStructureSearchMode && !data.structures.length}
<Notice title="Impossible de créer un nouveau service" type="error">
<p class="text-f14">Vous n’êtes rattaché à aucune structure.</p>
</Notice>
Expand All @@ -22,6 +22,7 @@
<ServiceEditionForm
service={data.service}
servicesOptions={data.servicesOptions}
managedStructureSearchMode={data.managedStructureSearchMode}
structures={data.structures}
structure={data.structure}
model={data.model}
Expand Down
9 changes: 6 additions & 3 deletions front/src/routes/(modeles-services)/services/creer/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getNewService } from "$lib/utils/forms";
import { getModel, getServicesOptions } from "$lib/requests/services";
import { userInfo } from "$lib/utils/auth";
import { get } from "svelte/store";
import { getStructure, getManagedStructures } from "$lib/requests/structures";
import { getStructure } from "$lib/requests/structures";
import type { PageLoad } from "./$types";
import type { Model, Service, ShortStructure } from "$lib/types";
import { error } from "@sveltejs/kit";
Expand All @@ -22,6 +22,8 @@ export const load: PageLoad = async ({ url, parent }) => {
return {};
}

const managedStructureSearchMode = user.isStaff || user.isManager;

let structures: ShortStructure[] = user.structures;
let service: Service;
let model: Model | undefined = undefined;
Expand Down Expand Up @@ -49,8 +51,8 @@ export const load: PageLoad = async ({ url, parent }) => {
error(404, "Page Not Found");
}
} else {
if (user.isStaff || user.isManager) {
structures = await getManagedStructures();
if (managedStructureSearchMode) {
structures = [];
} else {
structures = user.structures;
}
Expand All @@ -67,6 +69,7 @@ export const load: PageLoad = async ({ url, parent }) => {
noIndex: true,
title: "Création d’un service | DORA",
servicesOptions: await getServicesOptions(),
managedStructureSearchMode,
structures,
structure,
service,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

export let service: Service;
export let servicesOptions: ServicesOptions;
export let managedStructureSearchMode = false;
export let structures: ShortStructure[];
export let structure: ShortStructure | undefined;
export let model: Model | undefined;
Expand Down Expand Up @@ -165,13 +166,14 @@
</div>
{/if}

{#if structures.length}
{#if managedStructureSearchMode || structures.length}
<div class="lg:w-2/3">
<FieldsStructure
bind:structure
bind:service
bind:servicesOptions
bind:model
{managedStructureSearchMode}
{structures}
/>
</div>
Expand Down
Loading