REST Service for POPCORN - ILIAS
alex
2025-06-06 c82fec24c43ec50b6ec0cd6a4cc934836963131e
adding KeyboardToggle.vue
3 files added
3 files modified
145 ■■■■■ changed files
vue/src/assets/styles.styl 2 ●●●●● patch | view | raw | blame | history
vue/src/components/KeyboardToggle.vue 35 ●●●●● patch | view | raw | blame | history
vue/src/components/Pagination.vue 96 ●●●● patch | view | raw | blame | history
vue/src/components/icons/IconKeyboard.vue 5 ●●●●● patch | view | raw | blame | history
vue/src/components/icons/IconKeyboardStrikethrough.vue 5 ●●●●● patch | view | raw | blame | history
vue/src/pages/Users.vue 2 ●●● patch | view | raw | blame | history
vue/src/assets/styles.styl
@@ -31,3 +31,5 @@
.nowrap
   white-space nowrap
vue/src/components/KeyboardToggle.vue
New file
@@ -0,0 +1,35 @@
<script setup>
import IconKeyboard from "@/components/icons/IconKeyboard.vue"
import IconKeyboardStrikethrough from "@/components/icons/IconKeyboardStrikethrough.vue"
import {ref} from "vue"
const props = defineProps({
   initial: {
      type: Boolean,
      default: false
   },
})
const emit = defineEmits(["toggle"])
const strikethrough = ref(props.initial)
function toggle () {
   strikethrough.value = !strikethrough.value
   emit("toggle", strikethrough.value)
}
</script>
<template>
   <button @click="toggle" type="button">
      <IconKeyboard v-if="!strikethrough" />
      <IconKeyboardStrikethrough v-if="strikethrough" />
   </button>
</template>
<style scoped lang="stylus">
</style>
vue/src/components/Pagination.vue
@@ -2,6 +2,9 @@
import * as itemOffset from '../lib/itemOffset.js'
import {onKeyStroke} from "@vueuse/core"
import IconKeyboard from "@/components/icons/IconKeyboard.vue"
import KeyboardToggle from "@/components/KeyboardToggle.vue"
import {ref} from "vue"
const props = defineProps({
   total: Number,
@@ -33,7 +36,7 @@
/////// KEYBOARD ////////////////////////////////////////////////////////////////
onKeyStroke(["ArrowLeft", "ArrowRight", "Home", "End"], (e) => {
onKeyStroke(["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"], (e) => {
   let multiplier = 1
   switch (e.key) {
      case "ArrowLeft":
@@ -44,42 +47,99 @@
         multiplier = e.shiftKey ? 10 : 1
         goNext(multiplier)
         break
      case "Home":
      case "ArrowUp":
         goStart()
         break
      case "End":
      case "ArrowDown":
         goEnd()
         break
   }
})
/////// keyboard ////////////////////////////////////////////////////////////////
const keyboardVisible = ref(false)
function toggleKeyboard (value) {
   console.log("toggleKeyboard", value)
   keyboardVisible.value = value
}
</script>
<template>
   <div class="pagination">
      <input type="button" @click="goStart()" class="start" value="«">
      <input type="button" @click="goPrev()" class="prev" value="‹">
      <span class="current">
         {{ offset }} - {{ offset + limit }}
          / {{ total }}
      </span>
      <input type="button" @click="goNext()" class="next" value="›">
      <input type="button" @click="goEnd()" class="end" value="»">
      <div class="pagination-buttons">
         <input type="button" @click="goStart()" class="start" value="«">
         <input type="button" @click="goPrev()" class="prev" value="‹">
         <span class="current">{{ offset }} - {{ offset + limit }} / {{ total }}</span>
         <input type="button" @click="goNext()" class="next" value="›">
         <input type="button" @click="goEnd()" class="end" value="»">
         <KeyboardToggle :initial="false" @toggle="toggleKeyboard" style="color: #666" />
      </div>
      <small class="pagination-info" v-show="keyboardVisible">
         <em>Keyboard control:</em>
         <span class="spacer" />
         <kbd class="bigger">&ltri;</kbd> previous page
         <span class="spacer" />
         <kbd class="bigger">&rtri;</kbd> next page
         <span class="spacer" />
         <kbd>SHIFT</kbd> + <kbd class="bigger">&ltri;</kbd> {{limit * 10}} backward
         <span class="spacer" />
         <kbd>SHIFT</kbd> + <kbd class="bigger">&rtri;</kbd> {{limit * 10}} forward
         <span class="spacer" />
         <kbd class="bigger">&utri;</kbd> start
         <span class="spacer" />
         <kbd class="bigger">&dtri;</kbd> end
      </small>
   </div>
</template>
<style scoped lang="stylus">
.pagination-info
   margin-top .5em;
   display flex;
   gap .5em
   padding .33em .66em;
   align-items center;
   background-color #f1f1f1
   .spacer
      width 2em;
      height 1px
      display inline-block;
      //background-color black
kbd
   border 1px solid #777
   border-radius 4px
   font-size 120%;
   line-height 50%
   min-width 1rem;
   height 1rem
   padding 3px;
   display inline-flex;
   align-items center;
   justify-content center;
kbd.bigger
   font-size 220%
   line-height 0
.pagination
   display flex;
   flex-direction column
   align-items center;
   margin -1em 0 1em 0;
.pagination-buttons
   font-size 1.33rem
   display flex;
   gap 1em
   align-items center;
   justify-content center;
   margin -1em 0 1em 0;
   & > div
      cursor: pointer
@@ -102,4 +162,16 @@
   border none
   width 1em
button
   display inline-flex;
   align-items center;
   justify-content center;
   border none
   background-color transparent;
   cursor pointer
   &:hover
      background-color #eee;
</style>
vue/src/components/icons/IconKeyboard.vue
New file
@@ -0,0 +1,5 @@
<template>
   <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" d="M4 19q-.825 0-1.412-.587T2 17V7q0-.825.588-1.412T4 5h16q.825 0 1.413.588T22 7v10q0 .825-.587 1.413T20 19zm0-2h16V7H4zm4-1h8v-2H8zm-3-3h2v-2H5zm3 0h2v-2H8zm3 0h2v-2h-2zm3 0h2v-2h-2zm3 0h2v-2h-2zM5 10h2V8H5zm3 0h2V8H8zm3 0h2V8h-2zm3 0h2V8h-2zm3 0h2V8h-2zM4 17V7z" />
   </svg>
</template>
vue/src/components/icons/IconKeyboardStrikethrough.vue
New file
@@ -0,0 +1,5 @@
<template>
   <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" d="M19.85 22.525L1.475 4.15L2.9 2.725L21.275 21.1zM8 16v-2h6.175l2 2zm-3-3v-2h2v2zm3 0v-2h2v2zm9 0v-2h2v2zM5 10V8h2v2zm9 0V8h2v2zm3 0V8h2v2zm4.4 8.425L20 17V7h-9.975l-2-2H20q.825 0 1.413.588T22 7v10.025q0 .425-.162.775t-.438.625M4 19q-.825 0-1.412-.587T2 17V7q0-.825.588-1.412T4 5h1.175l2 2H4v10h13.175l2 2zm7.025-11H13v1.975zM14 11h2v1.975zm1 1" />
   </svg>
</template>
vue/src/pages/Users.vue
@@ -16,7 +16,7 @@
   data: [],
})
const offset = useRouteQuery("offset", 0, {transform: Number})
const limit = 24
const limit = 22
const error = ref(null)
onMounted(() => init(offset.value))