Skip to content

Commit

Permalink
Merge branch 'test' into feature/add-status-notification
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugoobx authored Nov 13, 2024
2 parents 0ae10da + cc80260 commit 8572d18
Show file tree
Hide file tree
Showing 16 changed files with 730 additions and 451 deletions.
3 changes: 3 additions & 0 deletions src/components/MainHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@
<li class="fr-nav__item">
<router-link to="/pro" class="fr-nav__link"> Agriculteur·ice </router-link>
</li>
<li class="fr-nav__item">
<router-link to="/stats" class="fr-nav__link"> Les chiffres </router-link>
</li>
</ul>
</nav>
</div>
Expand Down
47 changes: 45 additions & 2 deletions src/components/forms/SingleItemOperatorForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,41 @@
@change="($cultures) => (patch.cultures = $cultures)"
/>

<AccordionGroup v-if="!permissions.canChangeCulture">
<AccordionSection title="Culture">
<CultureSelector
:disabled-input="true"
:feature-id="feature.properties.id"
:cultures="patch.cultures"
@change="($cultures) => (patch.cultures = $cultures)"
/>
</AccordionSection>
<AccordionSection title="Annotations d'audit">
<div>
<ConversionLevelSelector
:feature-id="feature.properties.id"
:readonly="true"
v-model="patch.conversion_niveau"
/>

<div class="fr-input-group">
<label class="fr-label" for="engagement_date"
>Date de début de conversion <span v-if="!isEngagementDateRequired">(facultatif)</span></label
>
<input
type="date"
class="fr-input"
v-model="patch.engagement_date"
name="engagement_date"
id="engagement_date"
:disabled="true"
/>
</div>
</div>
</AccordionSection>
<br />
</AccordionGroup>

<div class="fr-input-group">
<label class="fr-label" for="feature-commentaires">
Vos notes
Expand All @@ -42,7 +77,9 @@
</div>
</form>

<template #title><slot name="title" /></template>
<template #title>
<slot name="title" />
</template>

<template #footer>
<div class="fr-input-group">
Expand All @@ -57,8 +94,12 @@
import { computed, onBeforeUnmount, reactive, ref, watch } from "vue";
import { useFocus } from "@vueuse/core";
import AccordionGroup from "@/components/widgets/AccordionGroup.vue";
import AccordionSection from "@/components/widgets/Accordion.vue";
import Modal from "@/components/widgets/Modal.vue";
import { LEVEL_C1, LEVEL_C2, LEVEL_C3 } from "@/referentiels/ab.js";
import CultureSelector from "@/components/forms/fields/CultureSelector.vue";
import ConversionLevelSelector from "@/components/forms/fields/ConversionLevelSelector.vue";
import { usePermissions } from "@/stores/permissions.js";
import { useFeaturesSetsStore } from "@/stores/features-sets.js";
import CancelModal from "@/components/forms/CancelModal.vue";
Expand All @@ -75,7 +116,6 @@ const props = defineProps({
},
});
const emit = defineEmits(["submit", "close"]);
const permissions = usePermissions();
const featuresSet = useFeaturesSetsStore();
const showCancelModal = ref(false);
Expand All @@ -86,10 +126,13 @@ const patch = reactive({
NOM: props.feature.properties.NOM || "",
cultures: props.feature.properties.cultures,
commentaires: props.feature.properties.commentaires || "",
conversion_niveau: props.feature.properties.conversion_niveau || "",
engagement_date: props.feature.properties.engagement_date || "",
});
const details = featureDetails(props.feature);
const nameErrors = computed(() => featuresSet.byFeatureProperty(props.feature.id, "name"));
const isEngagementDateRequired = computed(() => [LEVEL_C1, LEVEL_C2, LEVEL_C3].includes(patch.conversion_niveau));
const validate = () => {
const set = featuresSet.byFeature(props.feature.id, true);
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/fields/ConversionLevelSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
type="radio"
:id="'conversion-' + niveau.value"
:value="niveau.value"
:readonly="readonly"
:disabled="readonly"
:checked="niveau.value === modelValue"
@change="emit('update:modelValue', niveau.value)"
name="conversion_niveau"
Expand Down
11 changes: 11 additions & 0 deletions src/components/forms/fields/CultureSelector.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<fieldset class="culture-group fr-card fr-mb-1w fr-p-2w" v-for="culture in uuidedCultures" :key="culture.id">
<AsyncCultureTypeSelector
:disabled-input="disabledInput"
:feature-id="featureId"
:culture="culture"
:modelValue="culture.CPF"
Expand All @@ -19,6 +20,7 @@
:value="culture.variete"
@input="updateCulture(culture.id, 'variete', $event.target.value)"
name="variete"
:disabled="disabledInput"
/>
</div>
</div>
Expand All @@ -35,6 +37,7 @@
:value="culture.surface"
@input="updateCulture(culture.id, 'surface', $event.target.value)"
name="surface"
:disabled="disabledInput"
/>
<div class="fr-hint-text">Exprimée en <abbr title="hectare">ha</abbr>.</div>
</div>
Expand All @@ -48,12 +51,14 @@
:value="culture.date_semis"
@input="updateCulture(culture.id, 'date_semis', $event.target.value)"
name="date_semis"
:disabled="disabledInput"
/>
</div>
</div>

<button
type="button"
v-if="!disabledInput"
class="fr-btn fr-btn--sm fr-btn--tertiary-no-outline fr-icon-delete-line fr-btn--icon-left"
:disabled="!canBeDeleted"
@click="removeCulture(culture.id)"
Expand All @@ -64,6 +69,7 @@

<button
type="button"
v-if="!disabledInput"
class="fr-btn fr-btn--tertiary-no-outline fr-icon-add-line fr-btn--icon-left"
@click="appendEmptyCulture"
>
Expand All @@ -84,6 +90,10 @@ const props = defineProps({
featureId: {
type: String,
},
disabledInput: {
type: Boolean,
default: () => false,
},
});
const emit = defineEmits(["change"]);
Expand Down Expand Up @@ -147,6 +157,7 @@ function updateCulture(cultureId, field, value) {
gap: 1em;
margin-bottom: 1rem;
}
.horizontal-stack > .fr-input-group {
flex-grow: 1;
}
Expand Down
163 changes: 91 additions & 72 deletions src/components/forms/fields/CultureTypeSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
Culture «&nbsp;{{ fromCodeCpf(modelValue).libelle_code_cpf }}&nbsp;» à préciser
</div>

<div ref="autocompleteRef"></div>
<input
v-if="disabledInput && fromCodeCpf(culture.CPF)"
type="text"
:disabled="disabledInput"
class="fr-input"
:value="fromCodeCpf(culture.CPF).libelle_code_cpf"
/>

<div v-else ref="autocompleteRef"></div>

<div v-for="[id, result] in errors" :key="id" class="fr-hint-text fr-error-text">{{ result.errorMessage }}.</div>

Expand Down Expand Up @@ -43,10 +51,13 @@ const props = defineProps({
type: String,
required: true,
},
disabledInput: {
type: Boolean,
default: () => false,
},
});
const emit = defineEmits(["update:modelValue"]);
const autocompleteProps = shallowRef(null);
const autocompleteRef = ref(null);
const showMore = ref(false);
Expand Down Expand Up @@ -74,83 +85,89 @@ const choices = computed(() => {
const requirePrecision = computed(() => props.modelValue && !fromCodeCpf(props.modelValue)?.is_selectable);
onMounted(() => {
autocompleteProps.value = autocomplete({
container: autocompleteRef.value,
placeholder: props.placeholder,
openOnFocus: true,
id: `cpf-${props.culture.id}`,
classNames: {
form: "fr-input",
},
// helps react to query and isOpen changes
onStateChange({ state }) {
query.value = state.query;
},
getSources() {
return [
{
sourceId: "cultures",
getItems({ query }) {
let items;
if (query.length > 1) {
items = new Fuse(choices.value, {
keys: ["libelle_code_cpf"],
minMatchCharLength: 2,
threshold: 0.4,
})
.search(query)
.map(({ item: { libelle_code_cpf: libelle, code_cpf: code } }) => ({ code, libelle }));
} else if (requirePrecision.value || showMore.value) {
items = choices.value.map(({ libelle_code_cpf: libelle, code_cpf: code }) => ({ code, libelle }));
} else {
items = [];
}
if (requirePrecision.value && !showMore.value) {
items.push({
libelle: "Voir toutes les cultures",
code: "showMore",
});
}
return items;
},
templates: {
item({ item, html }) {
if (item.code === "showMore") {
return html`<span class="fr-link">Voir toutes les cultures</span>`;
if (!props.disabledInput) {
autocompleteProps.value = autocomplete({
container: autocompleteRef.value,
placeholder: props.placeholder,
openOnFocus: true,
id: `cpf-${props.culture.id}`,
classNames: {
form: "fr-input",
},
// helps react to query and isOpen changes
onStateChange({ state }) {
query.value = state.query;
},
getSources() {
return [
{
sourceId: "cultures",
getItems({ query }) {
let items;
if (query.length > 1) {
items = new Fuse(choices.value, {
keys: ["libelle_code_cpf"],
minMatchCharLength: 2,
threshold: 0.4,
})
.search(query)
.map(({ item: { libelle_code_cpf: libelle, code_cpf: code } }) => ({ code, libelle }));
} else if (requirePrecision.value || showMore.value) {
items = choices.value.map(({ libelle_code_cpf: libelle, code_cpf: code }) => ({ code, libelle }));
} else {
items = [];
}
return item.libelle;
if (requirePrecision.value && !showMore.value) {
items.push({
libelle: "Voir toutes les cultures",
code: "showMore",
});
}
return items;
},
templates: {
item({ item, html }) {
if (item.code === "showMore") {
return html`<span class="fr-link">Voir toutes les cultures</span>`;
}
return item.libelle;
},
},
onSelect: function (event) {
if (event.item.code === "showMore") {
showMore.value = true;
event.setQuery("");
event.setIsOpen(true);
return nextTick(() => {
event.refresh();
});
}
event.setQuery(event.item.libelle);
emit("update:modelValue", event.item.code);
},
},
onSelect: function (event) {
if (event.item.code === "showMore") {
showMore.value = true;
event.setQuery("");
event.setIsOpen(true);
return nextTick(() => {
event.refresh();
});
}
event.setQuery(event.item.libelle);
emit("update:modelValue", event.item.code);
},
},
];
},
];
},
renderer: { createElement: h, Fragment, render },
});
renderer: { createElement: h, Fragment, render },
});
autocompleteProps.value.setQuery?.(requirePrecision.value ? "" : query.value);
autocompleteProps.value.setQuery?.(requirePrecision.value ? "" : query.value);
}
});
onBeforeUnmount(() => autocompleteProps.value.setIsOpen(false));
onBeforeUnmount(() => {
if (!props.disabledInput) {
autocompleteProps.value.setIsOpen(false);
}
});
</script>
<style>
Expand Down Expand Up @@ -192,8 +209,10 @@ onBeforeUnmount(() => autocompleteProps.value.setIsOpen(false));
--border-width: 2px;
--aa-search-input-height: calc((0.5rem * 2) + 1.5rem - var(--border-width));
align-items: flex-start;
margin-top: calc(var(--border-width) * -1); /* to counteract the align-items: center of the container */
margin-top: calc(var(--border-width) * -1);
/* to counteract the align-items: center of the container */
}
.aa-ClearButton {
border-radius: 0 0.25rem 0 0;
}
Expand Down
Loading

0 comments on commit 8572d18

Please sign in to comment.