Browse Source

feat: add truncation functionality to DefaultTable and DefaultTableServerSide components; update utils for consistent text handling

alvesantos 2 weeks ago
parent
commit
7475634ca4

+ 20 - 1
src/components/defaults/DefaultTable.vue

@@ -101,6 +101,16 @@
       </q-td>
     </template>
 
+    <template #body-cell="props">
+      <q-td :props="props">
+        {{ truncate(props.value) }}
+
+        <q-tooltip v-if="isTruncated(props.value)">
+          {{ props.value }}
+        </q-tooltip>
+      </q-td>
+    </template>
+
     <template #item="{ cols, row, index }">
       <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
         <q-card
@@ -175,9 +185,16 @@ import { useI18n } from "vue-i18n";
 import { useQuasar } from "quasar";
 import { useRouter } from "vue-router";
 
+import { truncate } from "src/helpers/utils";
+
 import DefaultInput from "./DefaultInput.vue";
 import DefaultSelect from "./DefaultSelect.vue";
 
+const TRUNCATE_LENGTH = 30;
+
+const isTruncated = (value) =>
+  String(value ?? "").length > TRUNCATE_LENGTH;
+
 const emit = defineEmits([
   "noRows",
   "onAddItem",
@@ -388,7 +405,9 @@ const usableSlots = (slots) => {
 
   return availableSlots.filter(
     (slot) =>
-      !["body-cell-actions", "loading", "no-data", "top"].includes(slot),
+      !["body-cell-actions", "body-cell", "loading", "no-data", "top"].includes(
+        slot,
+      ),
   );
 };
 

+ 17 - 0
src/components/defaults/DefaultTableServerSide.vue

@@ -81,6 +81,16 @@
       </q-td>
     </template>
 
+    <template #body-cell="props">
+      <q-td :props="props">
+        {{ truncate(props.value) }}
+
+        <q-tooltip v-if="isTruncated(props.value)">
+          {{ props.value }}
+        </q-tooltip>
+      </q-td>
+    </template>
+
     <template v-if="!hideNoDataLabel" #no-data>
       <div class="q-my-md row justify-center full-width">
         <q-spinner v-if="loading" color="primary" size="30px" />
@@ -160,9 +170,16 @@ import { computed, onMounted, ref, toRaw, watch } from "vue";
 import { useI18n } from "vue-i18n";
 import { useRouter } from "vue-router";
 
+import { truncate } from "src/helpers/utils";
+
 import DefaultInput from "./DefaultInput.vue";
 import DefaultSelect from "./DefaultSelect.vue";
 
+const TRUNCATE_LENGTH = 30;
+
+const isTruncated = (value) =>
+  String(value ?? "").length > TRUNCATE_LENGTH;
+
 const emit = defineEmits([
   "noRows",
   "onAddItem",

+ 0 - 15
src/css/table.scss

@@ -31,21 +31,6 @@
     &.q-table--loading thead tr:last-child th {
       top: 48px;
     }
-
-    // Trunca texto sem espaços (hashes, URLs, etc.) para não estourar a
-    // largura da coluna e desalinhar o cabeçalho sticky.
-    td,
-    th {
-      max-width: 260px;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-
-    td.q-table--col-auto-width {
-      max-width: none;
-      overflow: visible;
-    }
   }
 
   tr {

+ 11 - 11
src/helpers/utils.js

@@ -1,17 +1,17 @@
 import { useI18n } from "vue-i18n";
 
 /**
- * @description Corta uma string em um determinado tamanho.
- * @param {string} string string a ser cortada.
- * @param {string} size tamanho da string.
- * @returns {string} string cortada.
+ * @description Corta um valor em um determinado tamanho, adicionando "..." no final.
+ * @param {*} value valor a ser cortado (convertido para string).
+ * @param {number} maxLength tamanho máximo antes de truncar.
+ * @returns {string} string truncada.
  */
-const excerpt = (string, size = 30) => {
-  if (size == null) return string;
-  if (string.length > size) {
-    string = string.substring(0, size) + "...";
-  }
-  return string;
+const truncate = (value, maxLength = 40) => {
+  const text = value == null ? "" : String(value);
+
+  if (text.length <= maxLength) return text;
+
+  return `${text.slice(0, maxLength)}...`;
 };
 
 /**
@@ -154,7 +154,7 @@ const isUnderage = (birthDate, referenceDate = new Date()) => {
 export {
   formatDateDMYtoYMD,
   formatDateYMDtoDMY,
-  excerpt,
+  truncate,
   convertDateTime,
   formatToBRLCurrency,
   normalizeString,