Browse Source

[192-webreport] Implemented blurring of not matched code and quicklinks to matches, sidebar can be hidden now

Evgeni 4 years ago
parent
commit
3f38aeae42

+ 1 - 0
report-viewer/src/App.vue

@@ -1,4 +1,5 @@
 <template>
+  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
   <router-view/>
 </template>
 

+ 10 - 3
report-viewer/src/components/CodePanel.vue

@@ -1,11 +1,12 @@
 <template>
   <div class="code-container">
-    <LineOfCode v-for="(line, index) in lines" :key="line" :is-blurred="notBlurred.includes(index)" :line-number="index" :text="line"/>
+    <LineOfCode v-for="(line, index) in lines" :key="index" :is-blurred="isBlurred(index)" :line-number="index" :text="line"
+    :id="panelId.concat(index)"/>
   </div>
 </template>
 
 <script>
-import { defineComponent } from "vue";
+import {computed, defineComponent} from "vue";
 import LineOfCode from "./LineOfCode";
 
 export default defineComponent({
@@ -19,10 +20,16 @@ export default defineComponent({
     notBlurred: {
       type: Array
     },
+    panelId: {
+      type: String
+    }
   },
   setup(props) {
+    const isBlurred = (index) => {
+      return !props.notBlurred.includes(index)
+    }
     return {
-
+      isBlurred
     }
   }
 })

+ 1 - 1
report-viewer/src/components/LineOfCode.vue

@@ -22,7 +22,6 @@ export default defineComponent({
     },
   },
   setup(props) {
-    console.log(props.lineNumber + " " + props.text)
     return {
 
     }
@@ -34,6 +33,7 @@ export default defineComponent({
 pre {
   margin: 0;
   padding: 0;
+  font-size: large;
 }
 .blurred {
   filter: blur(2px);

+ 44 - 8
report-viewer/src/components/MatchList.vue

@@ -1,7 +1,7 @@
 <template>
 <div class="wrapper">
-  <select v-model="selected" @change="this.$emit('selectionChanged', $event, selected)">
-    <option v-for="option in Object.keys(matches)" :value="option" :key="option">
+  <select v-model="selected" @change="this.$emit('selectionChanged', $event, selected.split(SEPARATOR)[0], selected.split(SEPARATOR)[1])">
+    <option v-for="option in generatedSelectOptions" :value="option" :key="option">
       {{ option }}
     </option>
   </select>
@@ -17,8 +17,8 @@
       </th>
       <th>Tokens</th>
     </tr>
-    <tr v-for="(match, index) in matches[selected]" :key="match.start_in_first + match.end_in_first"
-        @click="this.$emit('matchSelected', $event, index)">
+    <tr class="selectable-row" v-for="match in groupedMatches[selectedSplit[0]][selectedSplit[1]]" :key="match.start_in_first + match.end_in_first"
+        @click="this.$emit('matchSelected', $event, match.start_in_first, match.end_in_first, match.start_in_second, match.end_in_second)">
       <td>{{ match.start_in_first }} - {{ match.end_in_first }}</td>
       <td>{{ match.start_in_second }} - {{ match.end_in_second }}</td>
       <td>TODO</td>
@@ -47,16 +47,52 @@ export default defineComponent({
     }
   },
   setup(props) {
-    let selected = ref(Object.keys(props.matches)[0]);
-    let selectedSplit = ref(selected.value.split(" - "))
+    const SEPARATOR = " - "
+
+    const generateColour = () => {
+      let color = "#";
+      for (let i = 0; i < 3; i++)
+        color += ("0" + Math.floor(((1 + Math.random()) * Math.pow(16, 2)) / 2).toString(16)).slice(-2);
+      return color;
+    }
+
+    const groupedMatches = ref(props.matches.reduce( (acc, val) => {
+      let name = val.first_file_name
+      let subname = val.second_file_name
+      if(!acc[name]) {
+        acc[name] = {}
+      }
+      if(!acc[name][subname]) {
+        acc[name][subname] = []
+      }
+      let newVal = {...val, color: generateColour()}
+      acc[name][subname].push(newVal)
+      return acc;
+    }, {})
+    )
+
+    const generatedSelectOptions = ref([])
+    Object.keys(groupedMatches.value).forEach( (key) => {
+      Object.keys(groupedMatches.value[key]).forEach( (subkey) => {
+        generatedSelectOptions.value.push(key + SEPARATOR + subkey)
+      })
+    })
+
+    let selected = ref(generatedSelectOptions.value[0]);
+    let selectedSplit = selected.value.split(SEPARATOR)
+
 
     watchEffect(() => {
-      selectedSplit.value = selected.value.split(" - ")
+      selectedSplit.value = selected.value.split(SEPARATOR)
     })
 
     return {
       selected,
       selectedSplit,
+      generatedSelectOptions,
+      groupedMatches,
+
+      SEPARATOR
     }
   }
 })
@@ -105,7 +141,7 @@ td {
   padding: 2% 0;
 }
 
-tr:hover {
+.selectable-row:hover {
   background: #FF5353;
   color: white;
 }

+ 88 - 28
report-viewer/src/views/ComparisonView.vue

@@ -1,20 +1,24 @@
 <template>
 <div class="container">
-  <div id="leftPanel">
-    <img id="logo" src="@/assets/logo.png" alt="JPlag">
+  <div id="leftPanel" v-bind:class="{hidden : hideLeftPanel}">
+    <div class="logo-section">
+      <img id="logo" src="@/assets/logo.png" alt="JPlag">
+      <button id="hide-button" @click="togglePanel"><img src="@/assets/double_arrow_white_24dp.svg" alt="hide"></button>
+    </div>
     <TextInformation :has-additional-info="false" value="Match Report" label=""/>
     <TextInformation label="First Submission:" value="324567" :has-additional-info="false"/>
     <TextInformation label="Second Submission:" value="789223" :has-additional-info="false"/>
     <TextInformation label="Match percentage:" value="75.34%" :has-additional-info="false"/>
     <MatchList :submission1="json.first_submission_id"
                :submission2="json.second_submission_id"
-               :matches="groupedMatches"
+               :matches="json.matches"
                 @selection-changed="selectFiles"
                 @match-selected="selectMatch"/>
   </div>
-  <div id="rightPanel">
-    <CodePanel :lines="filesOfFirst[selectedFileOfFirst]" :not-blurred="[]"/>
-    <CodePanel :lines="filesOfSecond[selectedFileOfSecond]" :not-blurred="[]"/>
+  <div id="rightPanel" v-bind:class="{extended : hideLeftPanel}">
+    <button id="show-button" v-bind:class="{hidden : !hideLeftPanel}" @click="togglePanel"><img src="@/assets/double_arrow_white_24dp.svg" alt="hide"></button>
+    <CodePanel :lines="filesOfFirst[selectedFileOfFirst]" :not-blurred="notBlurredInFirst" panel-id="1"/>
+    <CodePanel :lines="filesOfSecond[selectedFileOfSecond]" :not-blurred="notBlurredInSecond" panel-id="2"/>
   </div>
 </div>
 </template>
@@ -34,9 +38,13 @@ export default defineComponent({
     }
   },
   setup(props) {
-    const selectedFileOfFirst = ref([])
-    const selectedFileOfSecond = ref([])
+    const selectedFileOfFirst = ref(0)
+    const selectedFileOfSecond = ref(0)
+    const hideLeftPanel = ref(false)
+    const notBlurredInFirst = ref([])
+    const notBlurredInSecond = ref([])
     const json = JSON.parse(props.jsonString)
+
     const filesOfFirst = json.files_of_first_submission.reduce( (acc, val) => {
       if(!acc[val.file_name]) {
         acc[val.file_name] = []
@@ -52,29 +60,38 @@ export default defineComponent({
       return acc
     }, {})
 
-    const groupedMatches = json.matches.reduce( (acc, val) => {
-      let name = val.first_file_name + " - " + val.second_file_name
-      if(!acc[name]) {
-        acc[name] = []
-      }
-      acc[name].push(val)
-      return acc;
-    }, {})
-
+    const selectFiles = (e , file1, file2) => {
+      console.log(file1, " ", file2)
+      selectedFileOfFirst.value = file1
+      selectedFileOfSecond.value = file2
+    }
 
-    const selectFiles = (e , s) => {
-      let split = s.split(" - ")
-      selectedFileOfFirst.value = split[0]
-      selectedFileOfSecond.value = split[1]
+    const selectMatch = (e, s1, e1, s2, e2) => {
+      let notBlurred1 = []
+      let notBlurred2 = []
+      for (let i = s1; i <= e1; i++) {
+        notBlurred1.push(i)
+      }
+      notBlurredInFirst.value = notBlurred1
+      for (let i = s2; i <= e2; i++) {
+        notBlurred2.push(i)
+      }
+      notBlurredInSecond.value = notBlurred2
+      document.getElementById("1".concat(notBlurred1[0])).scrollIntoView()
+      document.getElementById("2".concat(notBlurred2[0])).scrollIntoView()
     }
 
-    const selectMatch = (e, i) => {
-      console.log(e, i)
+    const togglePanel = () => {
+      console.log("hiding showing panel")
+      hideLeftPanel.value = !hideLeftPanel.value
     }
+
     return {
-      json, groupedMatches, filesOfFirst, filesOfSecond, selectedFileOfFirst, selectedFileOfSecond,
+      json, filesOfFirst, filesOfSecond, selectedFileOfFirst, selectedFileOfSecond, hideLeftPanel,
+      notBlurredInFirst, notBlurredInSecond,
       selectFiles,
       selectMatch,
+      togglePanel
     }
   }
 })
@@ -89,8 +106,21 @@ export default defineComponent({
   margin: 0;
 }
 
+.logo-section {
+  display: flex;
+  justify-content: space-between;
+}
+
+.hidden {
+  display: none !important;
+}
+
+.extended {
+  width: 100% !important;
+}
+
 #leftPanel {
-  width: 20%;
+  width: 25%;
   background: #FF5353;
   display: flex;
   flex-direction: column;
@@ -99,7 +129,7 @@ export default defineComponent({
 }
 
 #rightPanel {
-  width: 80%;
+  width: 75%;
   background: #ECECEC;
   display: flex;
   flex-wrap: nowrap;
@@ -108,8 +138,38 @@ export default defineComponent({
 }
 
 #logo {
-  width: 60%;
-  height: 20%;
   margin-bottom: 5%;
 }
+
+#hide-button {
+  height: 20%;
+  background: transparent;
+  border: none;
+  padding: 0;
+  margin: 0;
+}
+
+#show-button {
+  position: absolute;
+  z-index: 1000;
+  left: 0;
+  background: #FF5353;
+  border: none;
+  border-top-right-radius: 10px;
+  border-bottom-right-radius: 10px;
+  height: 5%;
+  width: 1%;
+}
+
+#show-button img {
+  display: none;
+}
+
+#show-button:hover {
+  width: 3%;
+}
+
+#show-button:hover img {
+  display: block;
+}
 </style>