Shortcuts.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <template>
  2. <AppSlideOver :show="show" @close="close()">
  3. <template #content>
  4. <div class="sticky top-0 z-10 flex flex-col bg-primary">
  5. <div
  6. class="flex items-center justify-between p-2 border-b border-dividerLight"
  7. >
  8. <h3 class="ml-4 heading">{{ t("app.shortcuts") }}</h3>
  9. <ButtonSecondary svg="x" @click.native="close()" />
  10. </div>
  11. <div class="flex flex-col px-6 py-4 border-b border-dividerLight">
  12. <input
  13. v-model="filterText"
  14. type="search"
  15. autocomplete="off"
  16. class="flex px-4 py-2 border rounded bg-primaryLight border-dividerLight focus-visible:border-divider"
  17. :placeholder="`${t('action.search')}`"
  18. />
  19. </div>
  20. </div>
  21. <div v-if="filterText" class="flex flex-col divide-y divide-dividerLight">
  22. <div
  23. v-for="(map, mapIndex) in searchResults"
  24. :key="`map-${mapIndex}`"
  25. class="px-6 py-4 space-y-4"
  26. >
  27. <h1 class="font-semibold text-secondaryDark">
  28. {{ t(map.item.section) }}
  29. </h1>
  30. <AppShortcutsEntry
  31. v-for="(shortcut, index) in map.item.shortcuts"
  32. :key="`shortcut-${index}`"
  33. :shortcut="shortcut"
  34. />
  35. </div>
  36. <div
  37. v-if="searchResults.length === 0"
  38. class="flex flex-col items-center justify-center p-4 text-secondaryLight"
  39. >
  40. <i class="pb-2 opacity-75 material-icons">manage_search</i>
  41. <span class="my-2 text-center">
  42. {{ t("state.nothing_found") }} "{{ filterText }}"
  43. </span>
  44. </div>
  45. </div>
  46. <div v-else class="flex flex-col divide-y divide-dividerLight">
  47. <div
  48. v-for="(map, mapIndex) in mappings"
  49. :key="`map-${mapIndex}`"
  50. class="px-6 py-4 space-y-4"
  51. >
  52. <h1 class="font-semibold text-secondaryDark">
  53. {{ t(map.section) }}
  54. </h1>
  55. <AppShortcutsEntry
  56. v-for="(shortcut, shortcutIndex) in map.shortcuts"
  57. :key="`map-${mapIndex}-shortcut-${shortcutIndex}`"
  58. :shortcut="shortcut"
  59. />
  60. </div>
  61. </div>
  62. </template>
  63. </AppSlideOver>
  64. </template>
  65. <script setup lang="ts">
  66. import { computed, ref } from "@nuxtjs/composition-api"
  67. import Fuse from "fuse.js"
  68. import mappings from "~/helpers/shortcuts"
  69. import { useI18n } from "~/helpers/utils/composables"
  70. const t = useI18n()
  71. defineProps<{
  72. show: boolean
  73. }>()
  74. const options = {
  75. keys: ["shortcuts.label"],
  76. }
  77. const fuse = new Fuse(mappings, options)
  78. const filterText = ref("")
  79. const searchResults = computed(() => fuse.search(filterText.value))
  80. const emit = defineEmits<{
  81. (e: "close"): void
  82. }>()
  83. const close = () => {
  84. filterText.value = ""
  85. emit("close")
  86. }
  87. </script>