Ver Fonte

feat: add tooltip

Ahmad Kholid há 3 anos atrás
pai
commit
0dbf36d124

+ 1 - 0
.eslintrc.js

@@ -30,6 +30,7 @@ module.exports = {
   // add your custom rules here
   rules: {
     'no-undef': 'off',
+    'no-underscore-dangle': 'off',
     'func-names': 'off',
     'import/extensions': [
       'error',

+ 4 - 2
src/assets/css/tailwind.css

@@ -9,7 +9,7 @@ body {
 }
 table th,
 table td {
-  @apply p-2;
+  @apply py-2 px-4;
 }
 input:focus,
 button:focus,
@@ -44,7 +44,9 @@ select:focus,
 .scroll::-webkit-scrollbar-track {
   background: transparent;
 }
-
+.tippy-box[data-theme~='tooltip-theme'] {
+  @apply px-2 py-1 bg-gray-900 text-sm text-gray-200 rounded-md;
+}
 
 @layer utilities {
   .hoverable {

+ 5 - 1
src/components/newtab/app/AppSidebar.vue

@@ -23,10 +23,11 @@
         v-for="tab in tabs"
         v-slot="{ href, navigate, isActive }"
         :key="tab.name"
-        custom
         :to="tab.path"
+        custom
       >
         <a
+          v-tooltip:right.group="tab.name"
           :class="{ 'is-active': isActive }"
           :href="href"
           class="
@@ -52,6 +53,9 @@
 </template>
 <script setup>
 import { ref } from 'vue';
+import { useGroupTooltip } from '@/composable/groupTooltip';
+
+useGroupTooltip();
 
 const tabs = [
   {

+ 6 - 3
src/components/newtab/shared/SharedLogsTable.vue

@@ -3,8 +3,11 @@
     <tbody class="divide-y">
       <tr v-for="log in logs" :key="log.id" class="hoverable">
         <slot name="item-prepend" :log="log" />
-        <td class="p-2 w-6/12 text-overflow">
-          <router-link :to="`/logs/${log.id}`" class="block w-full h-full">
+        <td class="text-overflow" style="min-width: 140px; max-width: 330px">
+          <router-link
+            :to="`/logs/${log.id}`"
+            class="inline-block text-overflow w-full align-middle"
+          >
             {{ log.name }}
           </router-link>
         </td>
@@ -22,7 +25,7 @@
           <v-remixicon name="riTimerLine"></v-remixicon>
           <span>{{ countDuration(log.startedAt, log.endedAt) }}</span>
         </td>
-        <td class="p-2 text-right">
+        <td class="text-right">
           <span
             :class="statusColors[log.status]"
             class="inline-block py-1 w-16 text-center text-sm rounded-lg"

+ 1 - 1
src/components/newtab/workflow/WorkflowCard.vue

@@ -14,7 +14,7 @@
             <v-remixicon name="riMoreLine" />
           </button>
         </template>
-        <ui-list class="w-44 space-y-1">
+        <ui-list class="w-40 space-y-1">
           <ui-list-item
             v-close-popover
             class="cursor-pointer"

+ 5 - 5
src/components/newtab/workflow/edit/EditTrigger.vue

@@ -43,7 +43,7 @@
     </div>
     <div v-else-if="data.type === 'date'" class="mt-2">
       <ui-input
-        :model-value="data.date || minDate"
+        :model-value="data.date"
         :max="maxDate"
         :min="minDate"
         class="w-full"
@@ -52,7 +52,7 @@
         @change="updateDate({ date: $event })"
       />
       <ui-input
-        :model-value="data.time || '00:00'"
+        :model-value="data.time"
         type="time"
         class="w-full mt-2"
         placeholder="Time"
@@ -110,10 +110,10 @@ function updateIntervalInput(value, { key, min, max }) {
 function updateDate(value) {
   if (!value) return;
 
-  let date = value;
+  let date = value?.date ?? minDate;
 
-  if (dayjs(minDate).isAfter(value)) date = minDate;
-  else if (dayjs(maxDate).isBefore(value)) date = maxDate;
+  if (dayjs(minDate).isAfter(date)) date = minDate;
+  else if (dayjs(maxDate).isBefore(date)) date = maxDate;
 
   updateData({ date });
 }

+ 31 - 0
src/composable/groupTooltip.js

@@ -0,0 +1,31 @@
+import { getCurrentInstance, onMounted, shallowRef } from 'vue';
+import { createSingleton } from 'tippy.js';
+import createTippy, { defaultOptions } from '@/lib/tippy';
+
+export function useGroupTooltip(elements, options = {}) {
+  const singleton = shallowRef(null);
+
+  onMounted(() => {
+    let tippyInstances = [];
+
+    if (Array.isArray(elements)) {
+      tippyInstances = elements.map((el) => el._tippy || createTippy(el));
+    } else {
+      const instance = getCurrentInstance();
+      const ctx = instance && instance.ctx;
+
+      tippyInstances = ctx._tooltipGroup || [];
+    }
+
+    singleton.value = createSingleton(tippyInstances, {
+      ...defaultOptions,
+      ...options,
+      theme: 'tooltip-theme',
+      placement: 'right',
+      moveTransition: 'transform 0.2s ease-out',
+      overrides: ['placement', 'theme'],
+    });
+  });
+
+  return singleton;
+}

+ 39 - 0
src/directives/VTooltip.js

@@ -0,0 +1,39 @@
+import createTippy from '@/lib/tippy';
+
+function getContent(content) {
+  if (typeof content === 'string') {
+    return { content };
+  }
+
+  if (typeof content === 'object' && content !== null) {
+    return content;
+  }
+
+  return {};
+}
+
+export default {
+  mounted(el, { value, arg = 'top', instance, modifiers }) {
+    const content = getContent(value);
+
+    const tooltip = createTippy(el, {
+      ...content,
+      theme: 'tooltip-theme',
+      placement: arg,
+    });
+
+    if (modifiers.group) {
+      if (!Array.isArray(instance._tooltipGroup)) instance._tooltipGroup = [];
+
+      instance._tooltipGroup.push(tooltip);
+    }
+  },
+  updated(el, { value, arg = 'top' }) {
+    const content = getContent(value);
+
+    el._tippy.setProps({
+      placement: arg,
+      ...content,
+    });
+  },
+};

+ 2 - 0
src/lib/comps-ui.js

@@ -1,3 +1,4 @@
+import VTooltip from '../directives/VTooltip';
 import VAutofocus from '../directives/VAutofocus';
 import VClosePopover from '../directives/VClosePopover';
 
@@ -18,6 +19,7 @@ function componentsExtractor(app, components) {
 }
 
 export default function (app) {
+  app.directive('tooltip', VTooltip);
   app.directive('autofocus', VAutofocus);
   app.directive('close-popover', VClosePopover);
 

+ 1 - 0
src/newtab/App.vue

@@ -6,6 +6,7 @@
   <ui-dialog />
 </template>
 <script setup>
+/* to-do add tooltip */
 import { ref } from 'vue';
 import { useStore } from 'vuex';
 import browser from 'webextension-polyfill';

+ 16 - 1
src/newtab/pages/workflows/[id].vue

@@ -60,7 +60,17 @@
           v-if="activeTab === 'logs'"
           :logs="logs"
           class="w-full"
-        />
+        >
+          <template #item-append="{ log: itemLog }">
+            <td class="text-right">
+              <v-remixicon
+                name="riDeleteBin7Line"
+                class="inline-block text-red-500 cursor-pointer"
+                @click="deleteLog(itemLog.id)"
+              />
+            </td>
+          </template>
+        </shared-logs-table>
         <div v-else-if="activeTab === 'running'" class="grid grid-cols-2 gap-4">
           <shared-workflow-state
             v-for="item in workflowState"
@@ -148,6 +158,11 @@ const updateBlockData = debounce((data) => {
 
   if (inputEl) inputEl.dispatchEvent(new Event('change'));
 }, 250);
+function deleteLog(logId) {
+  Log.delete(logId).then(() => {
+    store.dispatch('saveToStorage', 'logs');
+  });
+}
 function deleteBlock(id) {
   if (state.isEditBlock && state.blockData.blockId === id) {
     state.isEditBlock = false;

+ 5 - 1
src/popup/pages/Home.vue

@@ -26,7 +26,11 @@
     <ui-card v-if="Workflow.all().length === 0" class="text-center">
       <img src="@/assets/svg/alien.svg" />
       <p class="font-semibold">It looks like you don't have any workflows</p>
-      <ui-button variant="accent" class="mt-6" @click="openDashboard">
+      <ui-button
+        variant="accent"
+        class="mt-6"
+        @click="openDashboard('/workflows')"
+      >
         New workflow
       </ui-button>
     </ui-card>

+ 5 - 2
src/store/index.js

@@ -15,7 +15,7 @@ const store = createStore({
   },
   getters: {
     getWorkflowState: (state) => (id) =>
-      state.workflowState.filter(({ workflowId }) => workflowId === id),
+      (state.workflowState || []).filter(({ workflowId }) => workflowId === id),
   },
   actions: {
     async retrieve({ dispatch, getters }, keys = 'workflows') {
@@ -44,7 +44,10 @@ const store = createStore({
           'workflowState'
         );
 
-        commit('updateState', { key: 'workflowState', value: workflowState });
+        commit('updateState', {
+          key: 'workflowState',
+          value: workflowState || [],
+        });
       } catch (error) {
         console.error(error);
       }