Browse Source

feat: add import and export packae

Ahmad Kholid 2 years ago
parent
commit
4194969124
2 changed files with 64 additions and 8 deletions
  1. 1 0
      src/locales/en/newtab.json
  2. 63 8
      src/newtab/pages/Packages.vue

+ 1 - 0
src/locales/en/newtab.json

@@ -14,6 +14,7 @@
     "icon": "Package icon",
     "icon": "Package icon",
     "open": "Open packages",
     "open": "Open packages",
     "new": "New package",
     "new": "New package",
+    "import": "Import package",
     "set": "Set as a package",
     "set": "Set as a package",
     "settings": {
     "settings": {
       "asBlock": "Set package as block"
       "asBlock": "Set package as block"

+ 63 - 8
src/newtab/pages/Packages.vue

@@ -5,13 +5,32 @@
     </h1>
     </h1>
     <div class="mt-8 flex items-start">
     <div class="mt-8 flex items-start">
       <div class="w-60 mr-8 hidden lg:block">
       <div class="w-60 mr-8 hidden lg:block">
-        <ui-button
-          class="w-full"
-          variant="accent"
-          @click="addState.show = true"
-        >
-          <p>{{ t('packages.new') }}</p>
-        </ui-button>
+        <div class="flex items-center">
+          <ui-button
+            class="w-full rounded-r-none border-r"
+            variant="accent"
+            @click="addState.show = true"
+          >
+            <p>{{ t('packages.new') }}</p>
+          </ui-button>
+          <hr />
+          <ui-popover>
+            <template #trigger>
+              <ui-button icon variant="accent" class="rounded-l-none">
+                <v-remixicon name="riArrowDropDownLine" />
+              </ui-button>
+            </template>
+            <ui-list>
+              <ui-list-item
+                v-close-popover
+                class="cursor-pointer"
+                @click="importPackage"
+              >
+                {{ t('packages.import') }}
+              </ui-list-item>
+            </ui-list>
+          </ui-popover>
+        </div>
         <ui-list class="text-gray-600 dark:text-gray-200 mt-4 space-y-1">
         <ui-list class="text-gray-600 dark:text-gray-200 mt-4 space-y-1">
           <ui-list-item
           <ui-list-item
             v-for="cat in categories"
             v-for="cat in categories"
@@ -102,6 +121,15 @@
                     <v-remixicon name="riExternalLinkLine" class="mr-2 -ml-1" />
                     <v-remixicon name="riExternalLinkLine" class="mr-2 -ml-1" />
                     <span>Open package page</span>
                     <span>Open package page</span>
                   </ui-list-item>
                   </ui-list-item>
+                  <ui-list-item
+                    v-else
+                    v-close-popover
+                    class="cursor-pointer"
+                    @click="exportPackage(pkg)"
+                  >
+                    <v-remixicon name="riDownloadLine" class="mr-2 -ml-1" />
+                    <span>{{ t('common.export') }}</span>
+                  </ui-list-item>
                   <ui-list-item
                   <ui-list-item
                     v-close-popover
                     v-close-popover
                     class="cursor-pointer text-red-500 dark:text-red-400"
                     class="cursor-pointer text-red-500 dark:text-red-400"
@@ -172,8 +200,9 @@ import { reactive, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useI18n } from 'vue-i18n';
 import { useDialog } from '@/composable/dialog';
 import { useDialog } from '@/composable/dialog';
 import { usePackageStore } from '@/stores/package';
 import { usePackageStore } from '@/stores/package';
-import { arraySorter } from '@/utils/helper';
+import { arraySorter, openFilePicker, parseJSON } from '@/utils/helper';
 import dayjs from '@/lib/dayjs';
 import dayjs from '@/lib/dayjs';
+import dataExporter from '@/utils/dataExporter';
 
 
 const { t } = useI18n();
 const { t } = useI18n();
 const dialog = useDialog();
 const dialog = useDialog();
@@ -222,6 +251,32 @@ const packages = computed(() => {
   });
   });
 });
 });
 
 
+function importPackage() {
+  openFilePicker(['application/json']).then(([file]) => {
+    if (file.type !== 'application/json') return;
+
+    const fileReader = new FileReader();
+    fileReader.onload = () => {
+      const pkgJson = parseJSON(fileReader.result, null);
+      if (!pkgJson) return;
+      if (!pkgJson.name || !pkgJson.data) return;
+
+      packageStore.insert(pkgJson);
+    };
+    fileReader.readAsText(file);
+  });
+}
+function exportPackage(pkg) {
+  const copyPkg = JSON.parse(JSON.stringify(pkg));
+  delete copyPkg.id;
+
+  const blobUrl = dataExporter(
+    copyPkg,
+    { type: 'json', name: `${pkg.name}.automa-pkg` },
+    true
+  );
+  URL.revokeObjectURL(blobUrl);
+}
 function deletePackage({ id, name }) {
 function deletePackage({ id, name }) {
   dialog.confirm({
   dialog.confirm({
     title: 'Delete package',
     title: 'Delete package',