first impl for household editor

This commit is contained in:
2021-06-02 00:32:55 +02:00
parent cd52f7e6e8
commit c6949490a4
10 changed files with 340 additions and 9 deletions

View File

@@ -0,0 +1,23 @@
<template>
<concerned></concerned>
</template>
<script>
import Concerned from './components/Concerned.vue';
import { mapState } from 'vuex';
export default {
name: 'App',
components: {
Concerned,
},
computed: {
// for debugging purpose
// (not working)
//...mapState({
// 'concerned', 'household', 'positions'
// })
}
}
</script>

View File

@@ -0,0 +1,118 @@
<template>
<h1>{{ $t('household_members_editor.concerned.title') }}</h1>
<div>
<div v-for="person in personsUnpositionned"
draggable="true"
@dragstart="onStartDragConcern($event, person.id)"
>
<span>{{ person.text }}</span>
</div>
</div>
<div>
<add-persons
buttonTitle="household_members_editor.concerned.add_persons"
modalTitle="household_members_editor.concerned.search"
v-bind:key="addPersons.key"
v-bind:options="addPersons.options"
@addNewPersons="addNewPersons"
ref="addPersons"> <!-- to cast child method -->
</add-persons>
</div>
<div class="positions">
<div v-for="position in positions">
<h2>{{ position.label.fr }}</h2>
<ul>
<li
v-for="person in personByPosition(position.id)"
draggable="true"
@dragstart="onStartDragConcern($event, person.id)"
>
{{ person.text }}, {{ person.id }}
</li>
<li
class="droppable"
@drop="onDropConcern($event, position.id)"
@dragover.prevent
@dragenter.prevent
>
</li>
</ul>
</div>
</div>
</template>
<style scoped>
.concerned_box {
cursor: move;
padding: 1.5em;
border: 1px solid black;
}
.concerned_box * {
cursor: move;
}
.droppable_zone {
min-height: 50px;
width: 100%;
border: 1px solid black;
}
</style>
<script>
import { mapGetters } from 'vuex';
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue'
export default {
name: 'Concerned',
components: {
AddPersons,
},
computed: {
...mapGetters([
'personsUnpositionned',
'positions',
'personByPosition',
])
},
data() {
return {
addPersons: {
key: 'household_members_editor_concerned',
options: {
type: ['person'],
priority: null,
uniq: false,
}
}
}
},
methods: {
addNewPersons({ selected, modal }) {
console.log(selected);
selected.forEach(function(item) {
this.$store.dispatch('addConcerned', item.result);
}, this);
this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false;
},
onStartDragConcern(evt, person_id) {
console.log(evt);
console.log(person_id);
evt.dataTransfer.dropEffect = 'move'
evt.dataTransfer.effectAllowed = 'move'
evt.dataTransfer.setData('application/x.person', person_id)
},
onDropConcern(evt, position_id) {
console.log(evt);
console.log('position_id', position_id);
const person_id = Number(evt.dataTransfer.getData('application/x.person'));
this.$store.dispatch('markPosition', { person_id, position_id });
}
}
}
</script>

View File

@@ -0,0 +1,16 @@
import { createApp } from 'vue';
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
import { appMessages } from './js/i18n';
import { store } from './store';
import App from './App.vue';
const i18n = _createI18n(appMessages);
const app = createApp({
template: `<app></app>`,
})
.use(store)
.use(i18n)
.component('app', App)
.mount('#household_members_editor');

View File

@@ -0,0 +1,20 @@
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
const appMessages = {
fr: {
household_members_editor: {
concerned: {
title: "Personnes concernées",
add_persons: "Ajouter d'autres usagers",
search: "Rechercher des usagers",
}
}
}
};
Object.assign(appMessages.fr, personMessages.fr);
export {
appMessages
};

View File

@@ -0,0 +1,74 @@
import { createStore } from 'vuex';
const debug = process.env.NODE_ENV !== 'production';
const concerned = window.household_members_editor_data.persons.map(p => {
return {
person: p,
position: null,
start_date: null
};
});
const store = createStore({
strict: debug,
state: {
concerned,
household: window.household_members_editor_data.household,
positions: window.household_members_editor_data.positions,
},
getters: {
persons(state) {
return state.concerned.map(conc => conc.person);
},
personsUnpositionned(state) {
return state.concerned
.filter(conc => conc.position === null)
.map(conc => conc.person)
;
},
personByPosition: (state) => (position_id) => {
return state.concerned
.filter(conc =>
conc.position !== null ? conc.position.id === position_id : false
)
.map(conc => conc.person)
;
},
positions(state) {
return state.positions;
}
},
mutations: {
addConcerned(state, person) {
console.log('from mutation addConcerned');
state.concerned.push({ person, position: null, start_date: null });
},
markPosition(state, { person_id, position_id}) {
console.log('from mutation markPosition');
console.log('person_id', person_id);
console.log('position_id', position_id);
console.log('state', state.concerned);
let
position = state.positions.find(pos => pos.id === position_id),
conc = state.concerned.find(c => c.person.id === person_id);
console.log(position);
console.log(conc);
conc.position = position;
}
},
actions: {
addConcerned({ commit }, person) {
console.log('from actions addConcerned');
commit('addConcerned', person);
},
markPosition({ commit, state }, { person_id, position_id }) {
console.log('from action markPosition');
console.log('person_id', person_id);
console.log('position_id', position_id);
commit('markPosition', { person_id, position_id });
}
}
});
export { store };