Commit 7750bfc1 authored by ZeMKI's avatar ZeMKI
Browse files

Qsort new export + UI improve

* now you can see the value below the graph in the export.
* during the interview, you can move the graph up and down.
parent 5840cc0d
<?php
namespace App\Exports;
use App\Interview;
use App\InterviewTokens;
use App\Study;
use App\Token;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class InterviewQsortExport implements FromCollection, WithMapping, WithHeadings
{
use Exportable;
/**
* @var array
*/
private $head;
private $id;
private $sorting;
/**
* @var null
*/
private $columnValues;
/**
* InterviewQsortExport constructor.
* @param $id
* @param array $headings
*/
public function __construct($id, $headings = [], $sorting)
{
$this->id = $id;
$this->head = $headings;
$this->sorting = $sorting;
$this->columnValues = null;
}
public function headings(): array
{
$columnNames = ["token_id"];
array_push($columnNames, "token_name");
array_push($columnNames, "position column/row");
array_push($columnNames, "position base");
array_push($columnNames, "token description");
$columns = explode('|separator|', substr($this->study()->sortings[0]->pivot->details, strpos($this->study()->sortings[0]->pivot->details, 'qsort|') + 6));
array_pop($columns);
$baseArray = [];
foreach ($columns as $key => $value)
{
$c = explode('|',$value);
$columns[$key] = $c;
array_push($baseArray,$c[1]);
}
$this->columnValues = $baseArray;
foreach ($this->head as $column)
{
array_push($columnNames, $column);
}
return $columnNames;
}
/**
* @return array
* @var Token $token
*/
public function map($token): array
{
ray($this->columnValues);
if ($this->invalidData($token)) return [];
$position = $token->valutation->position;
$tempValuesArray = [];
$tempValuesArray["token_id"] = $token->token_id;
$tempValuesArray["token_name"] = Token::where('id', $token->token_id)->first()->name;
$tempValuesArray["position column/row"] = $position;
$tempValuesArray["position base"] = $this->columnValues[$position[0]];
$tempValuesArray["token description"] = json_decode($token->properties) ? json_decode($token->properties)->description : '';
$tempValuesArray["interviewee name"] = $token->interview->interviewed;
return $tempValuesArray;
}
/**
* @param $token
* @return bool
*/
private function invalidData($token): bool
{
return !is_object($token->valutation->position) && $token->valutation->position == 0 && $token->valutation->distance == 0 && $token->valutation->circle == 0 && $token->interview->study->sortings[0]->id === 2;
}
/**
* @return Collection
*/
public function collection()
{
return InterviewTokens::where('interview_id', $this->id)->join('tokens', 'token_id', 'tokens.id')->get();
}
public function study()
{
return Interview::whereId($this->id)->first()->study;
}
}
......@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Answer;
use App\Exports\InterviewQsortExport;
use App\Exports\InterviewTokenExport;
use App\Files;
use App\Interview;
......@@ -207,7 +208,8 @@ class InterviewController extends Controller
abort(403, "You are not authorized to download these data.");
}
$headings = $this->getHeadings($interview->study);
return (new InterviewTokenExport($interview->id, $headings, $interview->study->sortings[0]->id))->download($interview->interviewed . ' tokens.xlsx');
if( $interview->study->sortings[0]->id === 3) return (new InterviewQsortExport($interview->id, $headings, $interview->study->sortings[0]->id))->download($interview->interviewed . ' tokens.xlsx');
else return (new InterviewTokenExport($interview->id, $headings, $interview->study->sortings[0]->id))->download($interview->interviewed . ' tokens.xlsx');
}
public function getHeadings($study)
......
......@@ -54,17 +54,14 @@ Vue.mixin({
return document.URL.split('/').pop();
},
}, methods: {
checkPassword()
{
checkPassword() {
this.registration.password_length = this.registration.password.length;
const special_chars = /[ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/;
if (this.registration.password_length >
5)
{
5) {
this.registration.contains_six_characters = true;
}
else
{
else {
this.registration.contains_six_characters = false;
}
this.registration.contains_number = /\d/.test(
......@@ -78,12 +75,10 @@ Vue.mixin({
this.registration.contains_letters ===
true &&
this.registration.contains_number ===
true)
{
true) {
this.registration.valid_password = true;
}
else
{
else {
this.registration.valid_password = false;
}
},
......@@ -169,7 +164,8 @@ window.app = new Vue({
sortingType: (state) => state.newinterview.sortingType,
toggleCards: (state) => state.newinterview.toggleCards,
selectedToken: (state) => state.newinterview.selectedToken,
qsortSizeIndex: (state) => state.newinterview.qsortSizeIndex
qsortSizeIndex: (state) => state.newinterview.qsortSizeIndex,
qsortDistanceIndex: (state) => state.newinterview.qsortDistanceIndex,
}),
}, data: {
......@@ -327,9 +323,8 @@ window.app = new Vue({
self.loading = false;
self.$buefy.snackbar.open(error.response.data);
});
}, toggleCardsWindow: function()
{
store.commit('updateToggleCards',!this.toggleCards);
}, toggleCardsWindow: function () {
store.commit('updateToggleCards', !this.toggleCards);
},
interviewconfirmpreviouspage: function () {
this.$refs.thenewinterview.confirmpreviouspage();
......@@ -399,15 +394,17 @@ window.app = new Vue({
}, showtoast: function (message) {
window.app.$buefy.snackbar.open(message);
},
updateqsortSizeIndex: function(val){
updateqsortSizeIndex: function (val) {
console.log("clicked "+val);
console.log("clicked "+this.qsortSizeIndex);
let self = this;
if(val === 'plus' && self.qsortSizeIndex < 4) this.$store.commit('updateqsortSizeIndex', self.qsortSizeIndex+1);
else if(val === 'minus' && self.qsortSizeIndex > 0) this.$store.commit('updateqsortSizeIndex', self.qsortSizeIndex-1);
if (val === 'plus' && self.qsortSizeIndex < 4) this.$store.commit('updateqsortSizeIndex', self.qsortSizeIndex + 1);
else if (val === 'minus' && self.qsortSizeIndex > 0) this.$store.commit('updateqsortSizeIndex', self.qsortSizeIndex - 1);
},
updateqsortDistanceIndex: function (val) {
console.log(val);
let self = this;
if (val === 'plus' && self.qsortDistanceIndex < 8) this.$store.commit('updateqsortDistanceIndex', self.qsortDistanceIndex + 1);
else if (val === 'minus' && self.qsortDistanceIndex > 0) this.$store.commit('updateqsortDistanceIndex', self.qsortDistanceIndex - 1);
}
},
});
......
......@@ -28,18 +28,18 @@
<div
id="qsort"
:class="'grid grid-cols-'+itemsnumber+ ' gap-0 text-center absolute mx-auto w-auto'"
style="left: 50%;transform: translateX(-50%);top:15%;"
:style="'left: 50%;transform: translateX(-50%);'+'top:'+top.toString()+'%;'"
>
<div v-for="(column,key) in columns" :style="'height:'+ eachContainerHeight+'px'" class="grid grid-cols-1 gap-0 align-middle">
<div :class="'qsortlg:w-'+sizes[qsortSizeIndex]+' qsortmd:w-16 qsortsm:w-12 grid grid-rows-'+(maxnumber+1)+' grid-flow-row gap-0 '">
<div :class="'qsortlg:w-'+sizes[qsortSizeIndex]+' qsortmd:w-16 qsortsm:w-12 grid grid-rows-'+(maxnumber+1)+' grid-flow-row gap-0 '">
<div v-for="index in column.length-2" v-model="arrayOfQsort[key][index]"
:class="(column[index-1] === '---blank---')?
'bg-pink-400 opacity-0 qsortlg:w-'+sizes[qsortSizeIndex]+' qsortmd:w-16 qsortsm:w-12 qsortlg:h-'+sizes[qsortSizeIndex]+' qsortmd:h-16 qsortsm:h-12' :
'bg-gray-900 text-white border border-solid border-white qsortlg:w-'+sizes[qsortSizeIndex]+' qsortmd:w-16 qsortsm:w-12 qsortlg:h-'+sizes[qsortSizeIndex]+' qsortmd:h-16 qsortsm:h-12 select-none inline-block align-middle justify-center' "
'bg-pink-400 opacity-0 qsortlg:w-'+sizes[qsortSizeIndex]+' qsortmd:w-16 qsortsm:w-12 qsortlg:h-'+sizes[qsortSizeIndex]+' qsortmd:h-16 qsortsm:h-12' :
'bg-gray-900 text-white border border-solid border-white qsortlg:w-'+sizes[qsortSizeIndex]+' qsortmd:w-16 qsortsm:w-12 qsortlg:h-'+sizes[qsortSizeIndex]+' qsortmd:h-16 qsortsm:h-12 select-none inline-block align-middle justify-center' "
@click="assignTokenToCell(key,index,(column[index-1] === '---blank---'))"
>
<img v-if="arrayOfQsort[key][index]" :src="arrayOfQsort[key][index].image_path" class="w-full h-full">
......@@ -71,6 +71,8 @@ export default {
data() {
return {
sizes: [8, 12, 16, 24, 32],
distance: [0,2,3,4,5,6,7,8],
baseTop: 6,
tokens: [],
descriptionShowninToken: {},
arrayOfQsort: []
......@@ -85,6 +87,9 @@ export default {
'basicWidth': function () {
return this.sizes[this.qsortSizeIndex];
},
'top': function(){
return this.baseTop * this.distance[this.qsortDistanceIndex];
},
'containerWidth': function () {
return this.sizes[this.qsortSizeIndex] * this.itemsnumber * 2 * 2;
},
......@@ -97,7 +102,8 @@ export default {
currentsorting: state => state.newinterview.sorting,
currentpage: state => state.newinterview.page,
selectedToken: state => state.newinterview.selectedToken,
qsortSizeIndex: (state) => state.newinterview.qsortSizeIndex
qsortSizeIndex: (state) => state.newinterview.qsortSizeIndex,
qsortDistanceIndex: (state) => state.newinterview.qsortDistanceIndex
})
},
mounted() {
......@@ -146,27 +152,25 @@ export default {
setCellSize: function () {
let windowSize = window.innerWidth;
let self = this;
let widthMultiplier = self.sizes[this.qsortSizeIndex];
let widthMultiplier = this.sizes[this.qsortSizeIndex];
let top = 6;
let mediaQuerySM = windowSize > 639 && windowSize < 768;
let mediaQueryMD = windowSize >= 768 && windowSize < 1366;
let mediaQueryLG = windowSize >= 1366;
top *= this.distance[this.qsortDistanceIndex];
if (mediaQuerySM) {
widthMultiplier = 12;
top *= 3;
console.log("SM")
}
else if (mediaQueryMD) {
console.log("MD")
widthMultiplier = 16;
top *= 2;
}
else if (mediaQueryLG) {
console.log("LG?")
//@todo check the resolution on various tablets
top *= 2
widthMultiplier = sizes[qsortSizeIndex];
}
......
......@@ -13,6 +13,7 @@ export default new Vuex.Store(
newinterview: {
toggleCards: false,
qsortSizeIndex: 3,
qsortDistanceIndex: 2,
center_x: 0,
center_y: 0,
bounds: {},
......@@ -183,6 +184,9 @@ export default new Vuex.Store(
},
updateqsortSizeIndex: function (state, value) {
state.newinterview.qsortSizeIndex = value;
},
updateqsortDistanceIndex: function (state, value) {
state.newinterview.qsortDistanceIndex = value;
}
},
......
......@@ -84,17 +84,29 @@
<div class="flex flex-shrink-1 ml-2 items-center" v-if="sortingType == 3">
<img v-if="selectedToken" :src="selectedToken.image_path" style="width: 50px;height: 50px;z-index:100;">
<button
class="bg-green-500 text-gray-500 hover:text-gray-300 hover:bg-green-800 h-8 w-16 rounded-0 cursor-pointer ml-2"
class="bg-green-500 text-white hover:text-gray-300 hover:bg-green-800 h-8 w-16 rounded-0 cursor-pointer ml-2"
@click.prevent="updateqsortSizeIndex('minus')">
<span
class="m-auto text-2xl font-thin">-</span>
</button>
<button
class="bg-green-500 text-gray-500 hover:text-gray-300 hover:bg-green-800 h-8 w-16 rounded-0 cursor-pointer ml-2"
class="bg-green-500 text-white hover:text-gray-300 hover:bg-green-800 h-8 w-16 rounded-0 cursor-pointer ml-2"
@click.prevent="updateqsortSizeIndex('plus')">
<span
class="m-auto text-2xl font-thin">+</span>
</button>
<button
class="bg-green-500 text-white hover:text-gray-300 hover:bg-green-800 h-8 w-16 rounded-0 cursor-pointer ml-2"
@click.prevent="updateqsortDistanceIndex('plus')">
<span
class="m-auto text-2xl font-thin">⬇️</span>
</button>
<button
class="bg-green-500 text-white hover:text-gray-300 hover:bg-green-800 h-8 w-16 rounded-0 cursor-pointer ml-2"
@click.prevent="updateqsortDistanceIndex('minus')">
<span
class="m-auto text-2xl font-thin">⬆️</span>
</button>
</div>
</span>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment