ModalDocumentos.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <script setup>
  2. import DocumentList from "../components/DocumentList.vue";
  3. import DocumentUpload from "../components/DocumentUpload.vue";
  4. import SearchBox from "../components/SearchBox.vue";
  5. import { useSearch } from "../composables/useSearch.js";
  6. import { usePainelDocumentos } from "../composables/usePainelDocumentos.js";
  7. import { useDocumentos } from "../composables/useDocumentos.js";
  8. const { painelAberto, tituloModal, fecharModal } = usePainelDocumentos();
  9. const {
  10. results: searchResults,
  11. loading: searchLoading,
  12. error: searchError,
  13. run: runSearch,
  14. } = useSearch();
  15. const { docs, loadDocs, onIngested } = useDocumentos();
  16. </script>
  17. <template>
  18. <Teleport to="body">
  19. <Transition name="modal">
  20. <div v-if="painelAberto" class="fixed inset-0 z-[9999]">
  21. <div
  22. class="modal-backdrop absolute inset-0 bg-black/40 dark:bg-black/60"
  23. @click="fecharModal"
  24. />
  25. <div class="absolute inset-0 flex items-center justify-center p-4" @click="fecharModal">
  26. <div
  27. class="modal-panel w-full max-w-[980px] overflow-hidden rounded-2xl border border-gray-200 bg-background text-foreground shadow-xl dark:border-gray-700"
  28. @click.stop
  29. >
  30. <div
  31. class="flex items-center justify-between gap-3 border-b border-gray-200 px-5 py-4 dark:border-gray-700"
  32. >
  33. <div
  34. class="text-base font-semibold text-gray-900 dark:text-gray-100"
  35. >
  36. {{ tituloModal }}
  37. </div>
  38. <button
  39. type="button"
  40. class="rounded-lg border border-transparent p-1.5 text-gray-500 transition-colors hover:border-gray-200 hover:bg-gray-100 dark:text-gray-400 dark:hover:border-gray-700 dark:hover:bg-white/5"
  41. @click="fecharModal"
  42. >
  43. <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
  44. <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
  45. </svg>
  46. </button>
  47. </div>
  48. <div class="max-h-[calc(100vh-8rem)] overflow-auto p-5">
  49. <DocumentUpload
  50. v-if="painelAberto === 'update'"
  51. @ingested="onIngested"
  52. />
  53. <template v-else-if="painelAberto === 'documentos'">
  54. <SearchBox
  55. :results="searchResults"
  56. :loading="searchLoading"
  57. :error="searchError"
  58. @search="runSearch"
  59. />
  60. <div class="h-4" />
  61. <DocumentList
  62. :items="docs.items"
  63. :loading="docs.loading"
  64. :error="docs.error"
  65. @refresh="loadDocs"
  66. />
  67. </template>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </Transition>
  73. </Teleport>
  74. </template>
  75. <style scoped>
  76. .modal-enter-active,
  77. .modal-leave-active {
  78. transition: opacity 0.2s ease;
  79. }
  80. .modal-enter-from,
  81. .modal-leave-to {
  82. opacity: 0;
  83. }
  84. .modal-enter-active .modal-panel,
  85. .modal-leave-active .modal-panel {
  86. transition: transform 0.2s ease, opacity 0.2s ease;
  87. }
  88. .modal-enter-from .modal-panel,
  89. .modal-leave-to .modal-panel {
  90. transform: scale(0.96) translateY(8px);
  91. opacity: 0;
  92. }
  93. </style>