Browse Source

feat: add folder and sort in popup

Ahmad Kholid 2 years ago
parent
commit
dffbe6ffde
1 changed files with 87 additions and 7 deletions
  1. 87 7
      src/popup/pages/Home.vue

+ 87 - 7
src/popup/pages/Home.vue

@@ -104,6 +104,45 @@
         @toggle-pin="togglePinWorkflow(workflow)"
       />
     </div>
+    <div
+      :class="{ 'p-2 rounded-lg bg-white': pinnedWorkflows.length === 0 }"
+      class="flex items-center"
+    >
+      <ui-select v-model="state.activeFolder" class="flex-1">
+        <option value="">Folder (all)</option>
+        <option
+          v-for="folder in folderStore.items"
+          :key="folder.id"
+          :value="folder.id"
+        >
+          {{ folder.name }}
+        </option>
+      </ui-select>
+      <ui-popover class="ml-2">
+        <template #trigger>
+          <ui-button>
+            <v-remixicon name="riSortDesc" class="mr-2 -ml-1" />
+            <span>Sort</span>
+          </ui-button>
+        </template>
+        <div class="w-48">
+          <ui-select v-model="sortState.order" block placeholder="Sort order">
+            <option value="asc">Ascending</option>
+            <option value="desc">Descending</option>
+          </ui-select>
+          <ui-select
+            v-model="sortState.by"
+            :placeholder="t('sort.sortBy')"
+            block
+            class="flex-1 mt-2"
+          >
+            <option v-for="sort in sorts" :key="sort" :value="sort">
+              {{ t(`sort.${sort}`) }}
+            </option>
+          </ui-select>
+        </div>
+      </ui-popover>
+    </div>
     <home-workflow-card
       v-for="workflow in workflows"
       :key="workflow.id"
@@ -142,17 +181,18 @@
   </div>
 </template>
 <script setup>
-import { computed, onMounted, shallowReactive } from 'vue';
+import { computed, onMounted, shallowReactive, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import browser from 'webextension-polyfill';
 import { useUserStore } from '@/stores/user';
+import { useFolderStore } from '@/stores/folder';
 import { useDialog } from '@/composable/dialog';
 import { sendMessage } from '@/utils/message';
 import { useWorkflowStore } from '@/stores/workflow';
 import { useGroupTooltip } from '@/composable/groupTooltip';
 import { useTeamWorkflowStore } from '@/stores/teamWorkflow';
 import { useHostedWorkflowStore } from '@/stores/hostedWorkflow';
-import { parseJSON } from '@/utils/helper';
+import { parseJSON, arraySorter } from '@/utils/helper';
 import { initElementSelector as initElementSelectorFunc } from '@/newtab/utils/elementSelector';
 import automa from '@business';
 import HomeWorkflowCard from '@/components/popup/home/HomeWorkflowCard.vue';
@@ -164,12 +204,21 @@ const isMV2 = browser.runtime.getManifest().manifest_version === 2;
 const { t } = useI18n();
 const dialog = useDialog();
 const userStore = useUserStore();
+const folderStore = useFolderStore();
 const workflowStore = useWorkflowStore();
 const teamWorkflowStore = useTeamWorkflowStore();
 const hostedWorkflowStore = useHostedWorkflowStore();
 
 useGroupTooltip();
 
+const sorts = ['name', 'createdAt', 'mostUsed'];
+const savedSorts =
+  parseJSON(localStorage.getItem('popup-workflow-sort'), {}) || {};
+
+const sortState = shallowReactive({
+  by: savedSorts.sortBy || 'createdAt',
+  order: savedSorts.sortOrder || 'desc',
+});
 const state = shallowReactive({
   query: '',
   teams: [],
@@ -178,6 +227,7 @@ const state = shallowReactive({
   haveAccess: true,
   activeTab: 'local',
   pinnedWorkflows: [],
+  activeFolder: savedSorts.activeFolder,
   showSettingsPopup: isMV2
     ? false
     : parseJSON(localStorage.getItem('settingsPopup'), true) ?? true,
@@ -212,11 +262,23 @@ const hostedWorkflows = computed(() => {
 const localWorkflows = computed(() => {
   if (state.activeTab !== 'local') return [];
 
-  return workflowStore.getWorkflows
-    .filter(({ name }) =>
-      name.toLocaleLowerCase().includes(state.query.toLocaleLowerCase())
-    )
-    .sort((a, b) => (a.createdAt > b.createdAt ? -1 : 1));
+  const filteredLocalWorkflows = workflowStore.getWorkflows.filter(
+    ({ name, folderId }) => {
+      const isInFoloder =
+        !state.activeFolder || state.activeFolder === folderId;
+      const nameMatch = name
+        .toLocaleLowerCase()
+        .includes(state.query.toLocaleLowerCase());
+
+      return isInFoloder && nameMatch;
+    }
+  );
+
+  return arraySorter({
+    key: sortState.by,
+    order: sortState.order,
+    data: filteredLocalWorkflows,
+  });
 });
 const workflows = computed(() =>
   state.activeTab === 'local' ? localWorkflows.value : hostedWorkflows.value
@@ -331,6 +393,16 @@ function onTabChange(value) {
   localStorage.setItem('popup-tab', value);
 }
 
+watch(
+  () => [sortState.by, sortState.order, state.activeFolder],
+  ([sortBy, sortOrder, activeFolder]) => {
+    localStorage.setItem(
+      'popup-workflow-sort',
+      JSON.stringify({ sortOrder, sortBy, activeFolder })
+    );
+  }
+);
+
 onMounted(async () => {
   const [tab] = await browser.tabs.query({ active: true, currentWindow: true });
   state.haveAccess = /^(https?)/.test(tab.url);
@@ -338,6 +410,7 @@ onMounted(async () => {
   const storage = await browser.storage.local.get('pinnedWorkflows');
   state.pinnedWorkflows = storage.pinnedWorkflows || [];
 
+  await folderStore.load();
   await userStore.loadUser({ storage: localStorage, ttl: 1000 * 60 * 5 });
   await teamWorkflowStore.loadData();
 
@@ -351,6 +424,13 @@ onMounted(async () => {
 
   state.retrieved = true;
   state.activeTab = activeTab;
+
+  if (state.activeFolder) {
+    const folderExist = folderStore.items.some(
+      (folder) => folder.id === state.activeFolder
+    );
+    if (!folderExist) state.activeFolder = '';
+  }
 });
 </script>
 <style>