Просмотр исходного кода

Maintenance: Desktop view - Sorting indicator is not visible if column is truncated

Benjamin Scharf 2 недель назад
Родитель
Сommit
e66e1dbcbf

+ 41 - 30
app/frontend/apps/desktop/components/CommonTable/CommonAdvancedTable.vue

@@ -58,11 +58,11 @@ const emit = defineEmits<{
   sort: [string, EnumOrderDirection]
   sort: [string, EnumOrderDirection]
 }>()
 }>()
 
 
-//  Styling
+//  justify-* applies to the table header, text-* applies to the table cell.
 const cellAlignmentClasses = {
 const cellAlignmentClasses = {
-  right: 'ltr:text-right rtl:text-left',
-  center: 'text-center',
-  left: 'ltr:text-left rtl:text-right',
+  right: 'justify-end text-end',
+  center: 'justify-center text-center',
+  left: 'justify-start text-left',
 }
 }
 
 
 const { attributesLookup: objectAttributesLookup } = props.object
 const { attributesLookup: objectAttributesLookup } = props.object
@@ -141,6 +141,7 @@ const tableAttributes = computed(() => {
 
 
     table.push(mergedAttribute)
     table.push(mergedAttribute)
   })
   })
+
   return table
   return table
 })
 })
 
 
@@ -466,7 +467,7 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
           :class="[
           :class="[
             tableAttribute.headerPreferences.headerClass,
             tableAttribute.headerPreferences.headerClass,
             cellAlignmentClasses[
             cellAlignmentClasses[
-              tableAttribute.columnPreferences.alignContent || 'left'
+              tableAttribute.columnPreferences.alignContent ?? 'left'
             ],
             ],
           ]"
           ]"
         >
         >
@@ -489,27 +490,18 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
               :name="`column-header-${tableAttribute.name}`"
               :name="`column-header-${tableAttribute.name}`"
               :attribute="tableAttribute"
               :attribute="tableAttribute"
             >
             >
-              <CommonLabel
-                class="block truncate font-normal text-gray-100 select-none dark:text-neutral-400"
+              <!-- eslint-disable vuejs-accessibility/no-static-element-interactions,vuejs-accessibility/mouse-events-have-key-events-->
+              <div
+                class="flex items-center gap-1"
                 :class="[
                 :class="[
                   cellAlignmentClasses[
                   cellAlignmentClasses[
                     tableAttribute.columnPreferences.alignContent || 'left'
                     tableAttribute.columnPreferences.alignContent || 'left'
                   ],
                   ],
-                  tableAttribute.headerPreferences.labelClass || '',
                   {
                   {
-                    'sr-only': tableAttribute.headerPreferences.hideLabel,
-                    'text-black! dark:text-white!': isSorted(
-                      tableAttribute.name,
-                    ),
-                    'hover:cursor-pointer hover:text-black focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800 dark:hover:text-white':
+                    'hover:cursor-pointer focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800':
                       !tableAttribute.headerPreferences.noSorting,
                       !tableAttribute.headerPreferences.noSorting,
                   },
                   },
                 ]"
                 ]"
-                :aria-label="
-                  orderDirection === EnumOrderDirection.Ascending
-                    ? $t('Sorted ascending')
-                    : $t('Sorted descending')
-                "
                 :role="
                 :role="
                   tableAttribute.headerPreferences.noSorting
                   tableAttribute.headerPreferences.noSorting
                     ? undefined
                     ? undefined
@@ -518,7 +510,11 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
                 :tabindex="
                 :tabindex="
                   tableAttribute.headerPreferences.noSorting ? undefined : '0'
                   tableAttribute.headerPreferences.noSorting ? undefined : '0'
                 "
                 "
-                size="small"
+                :aria-label="
+                  orderDirection === EnumOrderDirection.Ascending
+                    ? $t('Sorted ascending')
+                    : $t('Sorted descending')
+                "
                 @click="
                 @click="
                   tableAttribute.headerPreferences.noSorting
                   tableAttribute.headerPreferences.noSorting
                     ? undefined
                     ? undefined
@@ -535,23 +531,39 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
                     : sort(tableAttribute.name)
                     : sort(tableAttribute.name)
                 "
                 "
               >
               >
-                {{
-                  $t(
-                    tableAttribute.label,
-                    ...(tableAttribute.labelPlaceholder || []),
-                  )
-                }}
+                <CommonLabel
+                  class="relative block! truncate font-normal text-gray-100! select-none dark:text-neutral-400!"
+                  :class="[
+                    tableAttribute.headerPreferences.labelClass,
+                    {
+                      'sr-only': tableAttribute.headerPreferences.hideLabel,
+                      'text-black! dark:text-white!': isSorted(
+                        tableAttribute.name,
+                      ),
+                      'hover:text-black! dark:hover:text-white!':
+                        !tableAttribute.headerPreferences.noSorting,
+                    },
+                  ]"
+                  size="small"
+                >
+                  {{
+                    $t(
+                      tableAttribute.label,
+                      ...(tableAttribute.labelPlaceholder || []),
+                    )
+                  }}
+                </CommonLabel>
                 <CommonIcon
                 <CommonIcon
                   v-if="
                   v-if="
                     !tableAttribute.headerPreferences.noSorting &&
                     !tableAttribute.headerPreferences.noSorting &&
                     isSorted(tableAttribute.name)
                     isSorted(tableAttribute.name)
                   "
                   "
-                  class="inline text-blue-800"
+                  class="shrink-0 text-blue-800"
                   :name="sortIcon"
                   :name="sortIcon"
                   size="xs"
                   size="xs"
                   decorative
                   decorative
                 />
                 />
-              </CommonLabel>
+              </div>
             </slot>
             </slot>
           </template>
           </template>
 
 
@@ -591,7 +603,6 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
       <template v-for="item in localItems" :key="item.id">
       <template v-for="item in localItems" :key="item.id">
         <TableRowGroupBy
         <TableRowGroupBy
           v-if="groupByAttribute && showGroupByRow(item)"
           v-if="groupByAttribute && showGroupByRow(item)"
-          ref=""
           :item="item"
           :item="item"
           :attribute="groupByAttribute"
           :attribute="groupByAttribute"
           :table-column-length="tableColumnLength"
           :table-column-length="tableColumnLength"
@@ -677,7 +688,7 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
                       },
                       },
                       getLinkColorClasses(item),
                       getLinkColorClasses(item),
                     ]"
                     ]"
-                    class="block truncate text-sm group-hover:text-black group-focus-visible:text-white group-active:text-white hover:no-underline! group-hover:dark:text-white"
+                    class="block! truncate text-sm group-hover:text-black group-focus-visible:text-white group-active:text-white hover:no-underline! group-hover:dark:text-white"
                     @click.stop
                     @click.stop
                     @keydown.stop
                     @keydown.stop
                   >
                   >
@@ -690,7 +701,7 @@ const getLinkColorClasses = (item: TableAdvancedItem) => {
                   <CommonLabel
                   <CommonLabel
                     v-else
                     v-else
                     v-tooltip.truncate="getTooltipText(item, tableAttribute)"
                     v-tooltip.truncate="getTooltipText(item, tableAttribute)"
-                    class="block truncate text-gray-100! group-hover:text-black! group-focus-visible:text-white! group-active:text-white! dark:text-neutral-400! group-hover:dark:text-white!"
+                    class="block! truncate text-gray-100! group-hover:text-black! group-focus-visible:text-white! group-active:text-white! dark:text-neutral-400! group-hover:dark:text-white!"
                     :class="[
                     :class="[
                       {
                       {
                         'text-black! dark:text-white!': isRowSelected,
                         'text-black! dark:text-white!': isRowSelected,

+ 1 - 1
app/frontend/apps/desktop/components/CommonTable/CommonSimpleTable.vue

@@ -188,7 +188,7 @@ const {
               <CommonLabel
               <CommonLabel
                 v-else
                 v-else
                 v-tooltip.truncate="getTooltipText(item, header)"
                 v-tooltip.truncate="getTooltipText(item, header)"
-                class="inline text-gray-100 group-hover:text-black group-focus-visible:text-white group-active:text-white dark:text-neutral-400 group-hover:dark:text-white"
+                class="inline! text-gray-100 group-hover:text-black group-focus-visible:text-white group-active:text-white dark:text-neutral-400 group-hover:dark:text-white"
                 :class="[
                 :class="[
                   {
                   {
                     'text-black dark:text-white': isRowSelected,
                     'text-black dark:text-white': isRowSelected,

+ 1 - 1
app/frontend/apps/desktop/components/CommonTable/HeaderResizeLine.vue

@@ -128,7 +128,7 @@ const id = getUuid()
     v-tooltip="$t('Resize column')"
     v-tooltip="$t('Resize column')"
     :aria-describedby="id"
     :aria-describedby="id"
     tabindex="0"
     tabindex="0"
-    class="!focus-visible:bg-blue-800 absolute end-0 top-1/2 h-5 w-1 -translate-y-2.5 cursor-col-resize! rounded-xs bg-neutral-100 hover:bg-blue-600 focus:outline-none dark:bg-gray-200 dark:hover:bg-blue-900"
+    class="absolute end-0 top-1/2 h-5 w-1 -translate-y-2.5 cursor-col-resize! rounded-xs bg-neutral-100 hover:bg-blue-600 focus:outline-none focus-visible:bg-blue-800! dark:bg-gray-200 dark:hover:bg-blue-900"
     :class="{
     :class="{
       '!bg-blue-800': resizing,
       '!bg-blue-800': resizing,
     }"
     }"

+ 65 - 30
app/frontend/apps/desktop/components/CommonTable/__tests__/CommonAdvancedTable.spec.ts.snapshot.txt

@@ -15,21 +15,28 @@
     >
     >
       
       
       <th
       <th
-        class="relative h-10 p-2.5 text-xs ltr:text-left rtl:text-right"
+        class="relative h-10 p-2.5 text-xs justify-start text-left"
         data-v-fd04734e=""
         data-v-fd04734e=""
         id="title-header"
         id="title-header"
       >
       >
         <!-- TODO: Implement with bulk edit -->
         <!-- TODO: Implement with bulk edit -->
         
         
-        <common-label-stub
+        <!-- eslint-disable vuejs-accessibility/no-static-element-interactions,vuejs-accessibility/mouse-events-have-key-events-->
+        <div
           aria-label="Sorted descending"
           aria-label="Sorted descending"
-          class="block truncate font-normal text-gray-100 select-none dark:text-neutral-400 ltr:text-left rtl:text-right hover:cursor-pointer hover:text-black focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800 dark:hover:text-white"
+          class="flex items-center gap-1 justify-start text-left hover:cursor-pointer focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800"
           data-v-fd04734e=""
           data-v-fd04734e=""
           role="button"
           role="button"
-          size="small"
           tabindex="0"
           tabindex="0"
-          tag="span"
-        />
+        >
+          <common-label-stub
+            class="relative block! truncate font-normal text-gray-100! select-none dark:text-neutral-400! hover:text-black! dark:hover:text-white!"
+            data-v-fd04734e=""
+            size="small"
+            tag="span"
+          />
+          <!--v-if-->
+        </div>
         
         
         
         
         
         
@@ -38,21 +45,28 @@
         />
         />
       </th>
       </th>
       <th
       <th
-        class="relative h-10 p-2.5 text-xs ltr:text-left rtl:text-right"
+        class="relative h-10 p-2.5 text-xs justify-start text-left"
         data-v-fd04734e=""
         data-v-fd04734e=""
         id="owner_id-header"
         id="owner_id-header"
       >
       >
         <!-- TODO: Implement with bulk edit -->
         <!-- TODO: Implement with bulk edit -->
         
         
-        <common-label-stub
+        <!-- eslint-disable vuejs-accessibility/no-static-element-interactions,vuejs-accessibility/mouse-events-have-key-events-->
+        <div
           aria-label="Sorted descending"
           aria-label="Sorted descending"
-          class="block truncate font-normal text-gray-100 select-none dark:text-neutral-400 ltr:text-left rtl:text-right hover:cursor-pointer hover:text-black focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800 dark:hover:text-white"
+          class="flex items-center gap-1 justify-start text-left hover:cursor-pointer focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800"
           data-v-fd04734e=""
           data-v-fd04734e=""
           role="button"
           role="button"
-          size="small"
           tabindex="0"
           tabindex="0"
-          tag="span"
-        />
+        >
+          <common-label-stub
+            class="relative block! truncate font-normal text-gray-100! select-none dark:text-neutral-400! hover:text-black! dark:hover:text-white!"
+            data-v-fd04734e=""
+            size="small"
+            tag="span"
+          />
+          <!--v-if-->
+        </div>
         
         
         
         
         
         
@@ -61,21 +75,28 @@
         />
         />
       </th>
       </th>
       <th
       <th
-        class="relative h-10 p-2.5 text-xs ltr:text-left rtl:text-right"
+        class="relative h-10 p-2.5 text-xs justify-start text-left"
         data-v-fd04734e=""
         data-v-fd04734e=""
         id="state_id-header"
         id="state_id-header"
       >
       >
         <!-- TODO: Implement with bulk edit -->
         <!-- TODO: Implement with bulk edit -->
         
         
-        <common-label-stub
+        <!-- eslint-disable vuejs-accessibility/no-static-element-interactions,vuejs-accessibility/mouse-events-have-key-events-->
+        <div
           aria-label="Sorted descending"
           aria-label="Sorted descending"
-          class="block truncate font-normal text-gray-100 select-none dark:text-neutral-400 ltr:text-left rtl:text-right hover:cursor-pointer hover:text-black focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800 dark:hover:text-white"
+          class="flex items-center gap-1 justify-start text-left hover:cursor-pointer focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800"
           data-v-fd04734e=""
           data-v-fd04734e=""
           role="button"
           role="button"
-          size="small"
           tabindex="0"
           tabindex="0"
-          tag="span"
-        />
+        >
+          <common-label-stub
+            class="relative block! truncate font-normal text-gray-100! select-none dark:text-neutral-400! hover:text-black! dark:hover:text-white!"
+            data-v-fd04734e=""
+            size="small"
+            tag="span"
+          />
+          <!--v-if-->
+        </div>
         
         
         
         
         
         
@@ -84,21 +105,28 @@
         />
         />
       </th>
       </th>
       <th
       <th
-        class="relative h-10 p-2.5 text-xs ltr:text-left rtl:text-right"
+        class="relative h-10 p-2.5 text-xs justify-start text-left"
         data-v-fd04734e=""
         data-v-fd04734e=""
         id="priority_id-header"
         id="priority_id-header"
       >
       >
         <!-- TODO: Implement with bulk edit -->
         <!-- TODO: Implement with bulk edit -->
         
         
-        <common-label-stub
+        <!-- eslint-disable vuejs-accessibility/no-static-element-interactions,vuejs-accessibility/mouse-events-have-key-events-->
+        <div
           aria-label="Sorted descending"
           aria-label="Sorted descending"
-          class="block truncate font-normal text-gray-100 select-none dark:text-neutral-400 ltr:text-left rtl:text-right hover:cursor-pointer hover:text-black focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800 dark:hover:text-white"
+          class="flex items-center gap-1 justify-start text-left hover:cursor-pointer focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800"
           data-v-fd04734e=""
           data-v-fd04734e=""
           role="button"
           role="button"
-          size="small"
           tabindex="0"
           tabindex="0"
-          tag="span"
-        />
+        >
+          <common-label-stub
+            class="relative block! truncate font-normal text-gray-100! select-none dark:text-neutral-400! hover:text-black! dark:hover:text-white!"
+            data-v-fd04734e=""
+            size="small"
+            tag="span"
+          />
+          <!--v-if-->
+        </div>
         
         
         
         
         
         
@@ -107,21 +135,28 @@
         />
         />
       </th>
       </th>
       <th
       <th
-        class="relative h-10 p-2.5 text-xs ltr:text-right rtl:text-left"
+        class="relative h-10 p-2.5 text-xs justify-end text-end"
         data-v-fd04734e=""
         data-v-fd04734e=""
         id="created_at-header"
         id="created_at-header"
       >
       >
         <!-- TODO: Implement with bulk edit -->
         <!-- TODO: Implement with bulk edit -->
         
         
-        <common-label-stub
+        <!-- eslint-disable vuejs-accessibility/no-static-element-interactions,vuejs-accessibility/mouse-events-have-key-events-->
+        <div
           aria-label="Sorted descending"
           aria-label="Sorted descending"
-          class="block truncate font-normal text-gray-100 select-none dark:text-neutral-400 ltr:text-right rtl:text-left hover:cursor-pointer hover:text-black focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800 dark:hover:text-white"
+          class="flex items-center gap-1 justify-end text-end hover:cursor-pointer focus-visible:rounded-xs focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-blue-800"
           data-v-fd04734e=""
           data-v-fd04734e=""
           role="button"
           role="button"
-          size="small"
           tabindex="0"
           tabindex="0"
-          tag="span"
-        />
+        >
+          <common-label-stub
+            class="relative block! truncate font-normal text-gray-100! select-none dark:text-neutral-400! hover:text-black! dark:hover:text-white!"
+            data-v-fd04734e=""
+            size="small"
+            tag="span"
+          />
+          <!--v-if-->
+        </div>
         
         
         
         
         
         

+ 4 - 1
app/frontend/apps/desktop/components/CommonTable/types.ts

@@ -27,7 +27,10 @@ type TableHeaderPreference = {
 }
 }
 
 
 type TableColumnPreference = {
 type TableColumnPreference = {
-  alignContent?: 'center' | 'right'
+  /**
+   * @default 'left'
+   * */
+  alignContent?: 'center' | 'right' | 'left'
 }
 }
 
 
 export interface TableSimpleHeader<K = string>
 export interface TableSimpleHeader<K = string>

+ 6 - 0
app/frontend/apps/desktop/components/QuickSearch/QuickSearchInput/QuickSearchInput.vue

@@ -2,6 +2,7 @@
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 import { onBeforeUnmount, useTemplateRef, watch } from 'vue'
 import { onBeforeUnmount, useTemplateRef, watch } from 'vue'
+import { useRouter } from 'vue-router'
 
 
 import emitter from '#shared/utils/emitter.ts'
 import emitter from '#shared/utils/emitter.ts'
 
 
@@ -14,6 +15,8 @@ const isSearchActive = defineModel<boolean>('search-active', {
   default: false,
   default: false,
 })
 })
 
 
+const router = useRouter()
+
 const inputSearchInstance = useTemplateRef('input-search')
 const inputSearchInstance = useTemplateRef('input-search')
 
 
 const resetInput = () => {
 const resetInput = () => {
@@ -48,6 +51,9 @@ emitter.on('reset-quick-search-field', () => resetInput())
       v-model="searchValue"
       v-model="searchValue"
       wrapper-class="rounded-lg bg-blue-200 px-2.5 py-2 outline-offset-1 outline-blue-800 focus-within:outline dark:bg-gray-700"
       wrapper-class="rounded-lg bg-blue-200 px-2.5 py-2 outline-offset-1 outline-blue-800 focus-within:outline dark:bg-gray-700"
       @focus-input="isSearchActive = true"
       @focus-input="isSearchActive = true"
+      @keydown.enter="
+        router.push({ name: 'search', params: { searchTerm: searchValue } })
+      "
     />
     />
     <CommonButton
     <CommonButton
       v-if="isSearchActive"
       v-if="isSearchActive"

+ 1 - 0
app/frontend/apps/desktop/components/QuickSearch/QuickSearchInput/__tests__/QuickSearchInput.spec.ts

@@ -15,6 +15,7 @@ const renderQuickSearchInput = () => {
       modelValue,
       modelValue,
       searchActive,
       searchActive,
     },
     },
+    router: true,
   })
   })
 
 
   return { wrapper, modelValue, searchActive }
   return { wrapper, modelValue, searchActive }

+ 4 - 3
app/frontend/apps/desktop/components/QuickSearch/QuickSearchResultList/QuickSearchResultList.vue

@@ -119,15 +119,16 @@ const { resetQuickSearchInputField } = useQuickSearchInput()
     <CommonLink
     <CommonLink
       v-if="!isLoadingSearchResults"
       v-if="!isLoadingSearchResults"
       class="group/link mb-4 block"
       class="group/link mb-4 block"
-      link="#"
+      :link="{ name: 'search', params: { searchTerm: props.search } }"
     >
     >
-      <CommonLabel
+      <CommonLink
+        link="#"
         class="text-blue-800! group-hover/link:underline"
         class="text-blue-800! group-hover/link:underline"
         prefix-icon="search-detail"
         prefix-icon="search-detail"
         size="small"
         size="small"
       >
       >
         {{ $t('detailed search') }}
         {{ $t('detailed search') }}
-      </CommonLabel>
+      </CommonLink>
     </CommonLink>
     </CommonLink>
 
 
     <div v-if="hasResults" class="space-y-1">
     <div v-if="hasResults" class="space-y-1">

+ 31 - 1
app/frontend/apps/desktop/components/QuickSearch/__tests__/QuickSearch.spec.ts

@@ -26,9 +26,39 @@ const renderQuickSearch = async (search: string = '') => {
       collapsed: false,
       collapsed: false,
       search,
       search,
     },
     },
-    router: true,
     store: true,
     store: true,
     dialog: true,
     dialog: true,
+    router: true,
+    routerRoutes: [
+      {
+        name: 'Dashboard',
+        path: '/',
+        component: {
+          template: 'Welcome to zammad.',
+        },
+      },
+      {
+        name: 'Example',
+        path: '/example',
+        component: {
+          template: 'This is a example page.',
+        },
+      },
+      {
+        name: 'Error',
+        path: '/:pathMatch(.*)*',
+        component: {
+          template: 'Error page',
+        },
+      },
+      {
+        name: 'search',
+        path: '/search/:searchTerm',
+        component: {
+          template: 'search',
+        },
+      },
+    ],
   })
   })
 
 
   await waitForNextTick()
   await waitForNextTick()

+ 1 - 1
app/frontend/apps/desktop/components/UserTaskbarTabs/Ticket/Ticket.vue

@@ -146,7 +146,7 @@ const currentViewTitle = computed(
     <CommonLabel
     <CommonLabel
       class="block! truncate text-gray-300 group-focus-visible/link:text-white dark:text-neutral-400 group-hover/tab:dark:text-white"
       class="block! truncate text-gray-300 group-focus-visible/link:text-white dark:text-neutral-400 group-hover/tab:dark:text-white"
       :class="{
       :class="{
-        '!text-white': taskbarTabActive,
+        'text-white!': taskbarTabActive,
       }"
       }"
     >
     >
       {{ currentTitle }}
       {{ currentTitle }}

Некоторые файлы не были показаны из-за большого количества измененных файлов