Parcourir la source

feat(newtab): add sidebar

Ahmad Kholid il y a 3 ans
Parent
commit
70ee0c5fdc

+ 8 - 1
.babelrc

@@ -1,6 +1,13 @@
 {
   "plugins": [],
   "presets": [
-    "@babel/preset-env"
+    ["@babel/preset-env", {
+      "useBuiltIns": "usage",
+      "corejs": 3,
+      "targets": {
+        // https://jamie.build/last-2-versions
+        "browsers": ["> 0.25%", "not ie 11", "not op_mini all"]
+      }
+    }]
   ]
 }

+ 2 - 0
package.json

@@ -38,6 +38,7 @@
     "babel-loader": "^8.2.2",
     "clean-webpack-plugin": "^3.0.0",
     "copy-webpack-plugin": "^7.0.0",
+    "core-js": "3",
     "css-loader": "^5.0.2",
     "eslint": "^7.20.0",
     "eslint-config-airbnb-base": "^14.2.1",
@@ -52,6 +53,7 @@
     "fs-extra": "^9.1.0",
     "html-loader": "^2.1.0",
     "html-webpack-plugin": "^5.2.0",
+    "mini-css-extract-plugin": "^2.3.0",
     "postcss": "^8.3.6",
     "postcss-loader": "^6.1.1",
     "prettier": "^2.4.1",

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

@@ -4,6 +4,8 @@
 
 body {
 	font-family: 'Inter', sans-serif;
+  font-size: 16px;
+  @apply bg-gray-100 dark:bg-gray-900;
 }
 
 input:focus,

+ 91 - 0
src/components/newtab/app/AppSidebar.vue

@@ -0,0 +1,91 @@
+<template>
+  <aside class="fixed h-screen left-0 top-0 w-16 py-5 bg-white">
+    <div
+      class="space-y-2 relative text-center"
+      @mouseleave="showHoverIndicator = false"
+    >
+      <div
+        v-show="showHoverIndicator"
+        ref="hoverIndicator"
+        class="
+          rounded-lg
+          h-10
+          w-10
+          absolute
+          left-1/2
+          bg-box-transparent
+          transition-transform
+          duration-200
+        "
+        style="transform: translate(-50%, 0)"
+      ></div>
+      <router-link
+        v-for="tab in tabs"
+        v-slot="{ href, navigate, isActive }"
+        :key="tab.name"
+        custom
+        :to="tab.path"
+      >
+        <a
+          :class="{ 'is-active': isActive }"
+          :href="href"
+          class="
+            z-10
+            relative
+            w-full
+            flex
+            items-center
+            justify-center
+            tab
+            relative
+          "
+          @click="navigate"
+          @mouseenter="hoverHandler"
+        >
+          <div class="p-2 rounded-lg transition-colors inline-block">
+            <v-remixicon :name="tab.icon" />
+          </div>
+        </a>
+      </router-link>
+    </div>
+  </aside>
+</template>
+<script setup>
+import { ref } from 'vue';
+
+const tabs = [
+  {
+    name: 'Dashboard',
+    icon: 'riHome5Line',
+    path: '/',
+  },
+  {
+    name: 'Worfklows',
+    icon: 'riFlowChart',
+    path: '/workflows',
+  },
+  {
+    name: 'Logs',
+    icon: 'riHistoryLine',
+    path: '/logs',
+  },
+];
+const hoverIndicator = ref(null);
+const showHoverIndicator = ref(false);
+
+function hoverHandler({ target }) {
+  showHoverIndicator.value = true;
+  hoverIndicator.value.style.transform = `translate(-50%, ${target.offsetTop}px)`;
+}
+</script>
+<style scoped>
+.tab.is-active:after {
+  content: '';
+  position: absolute;
+  right: 0;
+  top: 0;
+  height: 100%;
+  width: 4px;
+  @apply bg-accent;
+}
+</style>

+ 2 - 2
src/components/popup/home/HomeWorkflowCard.vue

@@ -2,10 +2,10 @@
   <ui-card
     class="w-full flex items-center space-x-2 hover:ring-2 hover:ring-gray-900"
   >
-    <div class="flex-1">
+    <router-link to="/workflow/anu/edit" class="flex-1">
       <p class="leading-tight">halo {{ 1 }}</p>
       <p class="leading-none text-gray-500">3 days ago</p>
-    </div>
+    </router-link>
     <router-link to="/workflow/anu" icon title="Execute">
       <v-remixicon name="riPlayLine" />
     </router-link>

+ 4 - 0
src/lib/v-remixicon.js

@@ -13,6 +13,8 @@ import {
   riEditBoxLine,
   riStopLine,
   riCheckboxCircleLine,
+  riFlowChart,
+  riHistoryLine,
 } from 'v-remixicon/icons';
 
 vRemixicon.add({
@@ -29,6 +31,8 @@ vRemixicon.add({
   riEditBoxLine,
   riStopLine,
   riCheckboxCircleLine,
+  riFlowChart,
+  riHistoryLine,
   mdiDrag:
     'M7,19V17H9V19H7M11,19V17H13V19H11M15,19V17H17V19H15M7,15V13H9V15H7M11,15V13H13V15H11M15,15V13H17V15H15M7,11V9H9V11H7M11,11V9H13V11H11M15,11V9H17V11H15M7,7V5H9V7H7M11,7V5H13V7H11M15,7V5H17V7H15Z',
 });

+ 7 - 1
src/newtab/App.vue

@@ -1,3 +1,9 @@
 <template>
-  <p>hola?</p>
+  <app-sidebar />
+  <main class="pl-20">
+    <router-view />
+  </main>
 </template>
+<script setup>
+import AppSidebar from '@/components/newtab/app/AppSidebar.vue';
+</script>

+ 12 - 1
src/newtab/index.js

@@ -1,6 +1,17 @@
 import { createApp } from 'vue';
 import App from './App.vue';
+import router from './router';
+import store from '../store';
+import compsUi from '../lib/comps-ui';
+import vRemixicon from '../lib/v-remixicon';
+import '../assets/css/tailwind.css';
+import '../assets/css/fonts.css';
 
-createApp(App).mount('#app');
+createApp(App)
+  .use(router)
+  .use(store)
+  .use(compsUi)
+  .use(vRemixicon)
+  .mount('#app');
 
 if (module.hot) module.hot.accept();

+ 3 - 0
src/newtab/pages/Home.vue

@@ -0,0 +1,3 @@
+<template>
+  <p>from home</p>
+</template>

+ 3 - 0
src/newtab/pages/Workflows.vue

@@ -0,0 +1,3 @@
+<template>
+  <p>lll</p>
+</template>

+ 3 - 0
src/newtab/pages/logs.vue

@@ -0,0 +1,3 @@
+<template>
+  <p>logs.......</p>
+</template>

+ 27 - 0
src/newtab/router.js

@@ -0,0 +1,27 @@
+import { createRouter, createWebHashHistory } from 'vue-router';
+import Home from './pages/Home.vue';
+import Workflows from './pages/Workflows.vue';
+import Logs from './pages/Logs.vue';
+
+const routes = [
+  {
+    name: 'home',
+    path: '/',
+    component: Home,
+  },
+  {
+    name: 'workflows',
+    path: '/workflows',
+    component: Workflows,
+  },
+  {
+    name: 'logs',
+    path: '/logs',
+    component: Logs,
+  },
+];
+
+export default createRouter({
+  routes,
+  history: createWebHashHistory(),
+});

+ 0 - 1
src/popup/App.vue

@@ -6,6 +6,5 @@ body {
   height: 500px;
   width: 330px;
   font-size: 16px;
-  @apply bg-gray-100 dark:bg-gray-900;
 }
 </style>

+ 7 - 1
src/popup/index.js

@@ -1,11 +1,17 @@
 import { createApp } from 'vue';
 import App from './App.vue';
 import router from './router';
+import store from '../store';
 import compsUi from '../lib/comps-ui';
 import vRemixicon from '../lib/v-remixicon';
 import '../assets/css/tailwind.css';
 import '../assets/css/fonts.css';
 
-createApp(App).use(router).use(compsUi).use(vRemixicon).mount('#app');
+createApp(App)
+  .use(router)
+  .use(store)
+  .use(compsUi)
+  .use(vRemixicon)
+  .mount('#app');
 
 if (module.hot) module.hot.accept();

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

@@ -9,7 +9,7 @@
       class="flex-1 search-input"
       placeholder="Search..."
     ></ui-input>
-    <ui-button icon title="dashboard" class="ml-3">
+    <ui-button icon title="dashboard" class="ml-3" @click="openDashboard">
       <v-remixicon name="riHome5Line" />
     </ui-button>
   </div>
@@ -19,4 +19,8 @@
 </template>
 <script setup>
 import HomeWorkflowCard from '@/components/popup/home/HomeWorkflowCard.vue';
+
+function openDashboard() {
+  window.open(chrome.runtime.getURL('/newtab.html'), '_blank');
+}
 </script>

+ 2 - 2
src/popup/pages/Workflow.vue

@@ -4,9 +4,9 @@
       <router-link to="/" class="-ml-2">
         <v-remixicon name="riArrowLeftSLine" size="28" />
       </router-link>
-      <a href="/" target="_blank" title="Edit">
+      <router-link :to="`/workflow/${$route.params.id}/edit`" title="Edit">
         <v-remixicon name="riEditBoxLine" />
-      </a>
+      </router-link>
     </div>
     <h1 class="text-xl font-semibold">Workflow name</h1>
   </div>

+ 3 - 0
src/popup/pages/workflow/Edit.vue

@@ -0,0 +1,3 @@
+<template>
+  <p>edit workflow</p>
+</template>

+ 6 - 0
src/popup/router.js

@@ -1,6 +1,7 @@
 import { createRouter, createWebHashHistory } from 'vue-router';
 import Home from './pages/Home.vue';
 import Workflow from './pages/Workflow.vue';
+import WorkflowEdit from './pages/workflow/Edit.vue';
 
 const routes = [
   {
@@ -13,6 +14,11 @@ const routes = [
     name: 'workflow',
     component: Workflow,
   },
+  {
+    path: '/workflow/:id/edit',
+    name: 'workflow-edit',
+    component: WorkflowEdit,
+  },
 ];
 
 export default createRouter({

+ 17 - 5
webpack.config.js

@@ -5,6 +5,7 @@ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
 const { VueLoaderPlugin } = require('vue-loader');
 const CopyWebpackPlugin = require('copy-webpack-plugin');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 const TerserPlugin = require('terser-webpack-plugin');
 const env = require('./utils/env');
 
@@ -61,9 +62,7 @@ const options = {
         test: /\.css$/,
         // in the `src` directory
         use: [
-          {
-            loader: 'style-loader',
-          },
+          MiniCssExtractPlugin.loader,
           {
             loader: 'css-loader',
           },
@@ -101,6 +100,7 @@ const options = {
       .concat(['.js', '.vue', '.css']),
   },
   plugins: [
+    new MiniCssExtractPlugin(),
     new VueLoaderPlugin(),
     new webpack.ProgressPlugin(),
     // clean the build folder
@@ -140,13 +140,13 @@ const options = {
       ],
     }),
     new HtmlWebpackPlugin({
-      template: path.join(__dirname, 'src', 'Newtab', 'index.html'),
+      template: path.join(__dirname, 'src', 'newtab', 'index.html'),
       filename: 'newtab.html',
       chunks: ['newtab'],
       cache: false,
     }),
     new HtmlWebpackPlugin({
-      template: path.join(__dirname, 'src', 'Popup', 'index.html'),
+      template: path.join(__dirname, 'src', 'popup', 'index.html'),
       filename: 'popup.html',
       chunks: ['popup'],
       cache: false,
@@ -167,6 +167,18 @@ if (env.NODE_ENV === 'development') {
         extractComments: false,
       }),
     ],
+    runtimeChunk: 'single',
+    splitChunks: {
+      chunks: 'all',
+      maxInitialRequests: Infinity,
+      minSize: 0,
+      cacheGroups: {
+        vendor: {
+          test: /[\\/]node_modules[\\/]/,
+          name: 'vendor',
+        },
+      },
+    },
   };
 }
 

+ 12 - 0
yarn.lock

@@ -2116,6 +2116,11 @@ core-js-compat@^3.14.0, core-js-compat@^3.16.0:
     browserslist "^4.17.0"
     semver "7.0.0"
 
+core-js@3:
+  version "3.17.3"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.17.3.tgz#8e8bd20e91df9951e903cabe91f9af4a0895bc1e"
+  integrity sha512-lyvajs+wd8N1hXfzob1LdOCCHFU4bGMbqqmLn1Q4QlCpDqWPpGf+p0nj+LNrvDDG33j0hZXw2nsvvVpHysxyNw==
+
 core-util-is@~1.0.0:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@@ -4332,6 +4337,13 @@ mimic-fn@^2.1.0:
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
 
+mini-css-extract-plugin@^2.3.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.3.0.tgz#87515f185533752944d753ac7216fc876779dafe"
+  integrity sha512-uzWaOwC+gJrnKbr23J1ZRWx/Wd9W9Ce1mKPlsBGBV/r8zG7/G7oKMxGmxbI65pVGbae2cR7CUx9Ulk0HQt8BfQ==
+  dependencies:
+    schema-utils "^3.1.0"
+
 minimalistic-assert@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"