Skip to content

Commit

Permalink
Migrated ActieWijzer components to vue3
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamieljv committed Nov 30, 2024
1 parent 1ea987b commit 8c53074
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 472 deletions.
4 changes: 4 additions & 0 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ app.component("LMap", LMap)

// Import and register Vue components that are used in blade files
import CoordinatesFormField from "./components/CoordinatesFormField.vue"
import EditAnswersFormField from "./components/EditAnswersFormField.vue"
import ScoreRelationFormField from "./components/ScoreRelationFormField.vue"
import StatsDashboard from "./components/StatsDashboard.vue"
app.component("CoordinatesFormField", CoordinatesFormField)
app.component("EditAnswersFormField", EditAnswersFormField)
app.component("ScoreRelationFormField", ScoreRelationFormField)
app.component("StatsDashboard", StatsDashboard)

app.mount("#app")
132 changes: 64 additions & 68 deletions resources/js/components/EditAnswersFormField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<button
v-if="!a.editable"
class="edit-btn"
@click.prevent="$set(a, 'editable', !a.editable)"
@click.prevent="handleEdit($event, a.id)"
>
Bewerken
</button>
Expand Down Expand Up @@ -46,75 +46,71 @@
</div>
</template>

<script>
import ScoreRelationFormField from './ScoreRelationFormField.vue';
<script setup lang="ts">
import { ref } from 'vue';
import ScoreRelationFormField from './ScoreRelationFormField.vue';
import axios from 'axios';
export default {
name: "EditAnswersFormField",
props: {
answers: {
type: Array,
required: true,
},
editRoute: {
type: String,
required: true,
},
deleteRoute: {
type: String,
required: true,
},
scoreRoute: {
type: String,
required: true,
},
scoreDeleteRoute: {
type: String,
required: true,
},
editAnswerRoute: {
type: String,
required: true,
},
dimensions: {
type: Array,
required: true,
},
},
data() {
return {
answersToEdit: [],
}
},
mounted() {
this.answersToEdit = this.answers.map(a => {
a.editable = false
return a
});
},
methods: {
handleSave(e, id) {
var val = e.target.closest('div').querySelector('input').value;
this.$set(this.answersToEdit.find((a) => a.id == id), 'value', val);
this.$http.post(this.editAnswerRoute, {
'id': id,
'answer': val,
}).then((response) => {
this.$set(this.answersToEdit.find((a) => a.id == id), 'editable', false);
if (response.data.status === "success") {
// reset the inner html of the error element in the row
e.target.closest('div').querySelector('.error').innerHTML = '';
} else {
throw new Error(response.message);
}
}).catch((error) => {
// set the inner html of the error element in the row
e.target.closest('div').querySelector('.error').innerHTML = error.response.data.message;
});
},
const props = defineProps({
answers: {
type: Array,
required: true,
},
editRoute: {
type: String,
required: true,
},
deleteRoute: {
type: String,
required: true,
},
scoreRoute: {
type: String,
required: true,
},
scoreDeleteRoute: {
type: String,
required: true,
},
editAnswerRoute: {
type: String,
required: true,
},
dimensions: {
type: Array,
required: true,
},
});
const answersToEdit = ref(props.answers.map(a => {
a.editable = false;
return a;
}));
const handleEdit = (e, id) => {
answersToEdit.value.find((a) => a.id == id).editable = true;
}
const handleSave = (e, id) => {
var val = e.target.closest('div').querySelector('input').value;
answersToEdit.value.find((a) => a.id == id).answer = val;
axios.post(props.editAnswerRoute, {
'id': id,
'answer': val,
}).then((response) => {
answersToEdit.value.find((a) => a.id == id).editable = false;
if (response.data.status === "success") {
// reset the inner html of the error element in the row
e.target.closest('div').querySelector('.error').innerHTML = '';
} else {
throw new Error(response.message);
}
}
}).catch((error) => {
// set the inner html of the error element in the row
e.target.closest('div').querySelector('.error').innerHTML = error.response.data.message;
});
}
</script>

<style lang="scss" scoped>
Expand Down
182 changes: 92 additions & 90 deletions resources/js/components/ScoreRelationFormField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,97 +28,99 @@
</div>
</template>

<script>
export default {
name: "ScoreRelationFormField",
props: {
dimensions: {
type: Array,
required: true,
},
entityClass: {
type: String,
required: true,
},
scoreRoute: {
type: String,
required: true,
},
scoreDeleteRoute: {
type: String,
required: true,
},
currentScores: {
type: Array,
required: true,
},
currentId: {
type: Number,
required: true,
},
minScore: {
type: Number,
required: true,
},
maxScore: {
type: Number,
required: true,
},
},
data() {
return {
dimensionsWithValues: []
}
},
mounted() {
// deep copy this.dimensions
var dims = JSON.parse(JSON.stringify(this.dimensions));
this.dimensionsWithValues = dims.map((e) => {
var current = this.currentScores.find((c) => c.id === e.id);
e.value = current ? current.pivot.score : null;
return e
});
},
methods: {
handleChange(e) {
this.$set(this.dimensionsWithValues.find((c) => c.id == e.target.dataset.dimId), 'value', e.target.value);
this.$http.post(this.scoreRoute, {
'entity_class': this.entityClass,
'entity_id': this.currentId,
'dimension_id': parseInt(e.target.dataset.dimId),
'score': parseInt(this.dimensionsWithValues.find((c) => c.id == e.target.dataset.dimId).value)
}).then((response) => {
if (response.data.status === "success") {
// reset the inner html of the error element in the row
e.target.closest('tr').querySelector('.error').innerHTML = '';
// remove the invalid class from the input element in the row
e.target.closest('tr').querySelector('input').classList.remove('invalid');
} else {
throw new Error(response.message);
}
}).catch((error) => {
// set the inner html of the error element in the row
e.target.closest('tr').querySelector('.error').innerHTML = error.response.data.message;
// toggle the invalid class on the input element in the row
e.target.closest('tr').querySelector('input').classList.add('invalid');
});
},
handleDelete(dimension_id, e) {
var tr = e.target.closest('tr');
this.$http.post(this.scoreDeleteRoute, {
'entity_class': this.entityClass,
'entity_id': this.currentId,
'dimension_id': parseInt(dimension_id),
}).then((response) => {
// reset the inner html of the error element in the row
tr.querySelector('.error').innerHTML = '';
// remove the invalid class from the input element in row
tr.querySelector('input').classList.remove('invalid');
});
this.$set(this.dimensionsWithValues.find((c) => c.id == dimension_id), 'value', null);
}
<script setup lang="ts">
import axios from 'axios';
import { onMounted, ref } from 'vue';
const props = defineProps({
dimensions: {
type: Array,
required: true,
},
entityClass: {
type: String,
required: true,
},
scoreRoute: {
type: String,
required: true,
},
scoreDeleteRoute: {
type: String,
required: true,
},
currentScores: {
type: Array,
required: true,
},
currentId: {
type: Number,
required: true,
},
minScore: {
type: Number,
required: true,
},
maxScore: {
type: Number,
required: true,
},
})
const dimensionsWithValues = ref([]);
onMounted(() => {
// deep copy props.dimensions
var dims = JSON.parse(JSON.stringify(props.dimensions));
// add the current score to the dimension
dimensionsWithValues.value = dims.map((e) => {
var current = props.currentScores.find((c) => c.id === e.id);
e.value = current ? current.pivot.score : null;
return e
});
});
const handleChange = (e) => {
dimensionsWithValues.value.find((c) => c.id == e.target.dataset.dimId).value = e.target.value;
axios.post(props.scoreRoute, {
'entity_class': props.entityClass,
'entity_id': props.currentId,
'dimension_id': parseInt(e.target.dataset.dimId),
'score': parseInt(dimensionsWithValues.value.find((c) => c.id == e.target.dataset.dimId).value)
}).then((response) => {
if (response.data.status === "success") {
// reset the inner html of the error element in the row
e.target.closest('tr').querySelector('.error').innerHTML = '';
// remove the invalid class from the input element in the row
e.target.closest('tr').querySelector('input').classList.remove('invalid');
} else {
throw new Error(response.message);
}
}
}).catch((error) => {
// set the inner html of the error element in the row
e.target.closest('tr').querySelector('.error').innerHTML = error.response.data.message;
// toggle the invalid class on the input element in the row
e.target.closest('tr').querySelector('input').classList.add('invalid');
});
}
const handleDelete = (dimension_id, e) => {
var tr = e.target.closest('tr');
axios.post(props.scoreDeleteRoute, {
'entity_class': props.entityClass,
'entity_id': props.currentId,
'dimension_id': parseInt(dimension_id),
}).then((response) => {
// reset the inner html of the error element in the row
tr.querySelector('.error').innerHTML = '';
// remove the invalid class from the input element in row
tr.querySelector('input').classList.remove('invalid');
});
dimensionsWithValues.value.find((c) => c.id == dimension_id).value = null;
}
</script>

<style lang="scss" scoped>
Expand Down
10 changes: 1 addition & 9 deletions resources/views/actiewijzer/referentie_type.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,4 @@
</div>
</div>

@endsection

@push('scripts')
<script type="application/javascript">
var app = new Vue({
el: '#app',
});
</script>
@endpush
@endsection
10 changes: 1 addition & 9 deletions resources/views/actiewijzer/result.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,4 @@ class="relative self-start inline-block px-2 py-1 mr-1 mb-1 text-xs font-medium
</div>
</div>

@endsection

@push('scripts')
<script type="application/javascript">
var app = new Vue({
el: '#app',
});
</script>
@endpush
@endsection
Loading

0 comments on commit 8c53074

Please sign in to comment.