diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e42b0345..e15df4d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,14 +21,18 @@ jobs: - name: Check out code uses: actions/checkout@v2 - - - run: npm install + - name: Cache node_modules 📦 + uses: actions/cache@v2.1.4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - run: npm ci --prefer-offline --no-audit working-directory: frontend - run: npm run lint working-directory: frontend - - run: npm run test:unit - working-directory: frontend - - run: npm run build + - run: npm run generate working-directory: frontend - name: Upload a Build Artifact uses: actions/upload-artifact@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4c5a0931..c310f9ee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,18 +10,29 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v1 + - name: Checkout 🛎 + uses: actions/checkout@master + + - name: Setup node env 🏗 + uses: actions/setup-node@v2.1.5 with: - node-version: '12' + node-version: ${{ matrix.node }} + check-latest: true - - name: Check out code - uses: actions/checkout@v2 + - name: Cache node_modules 📦 + uses: actions/cache@v2.1.4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- - - run: npm install - working-directory: frontend - - run: npm run lint + - name: Install dependencies 👨🏻‍💻 + run: npm ci --prefer-offline --no-audit working-directory: frontend - - run: npm run test:unit + + - name: Run linter 👀 + run: npm run lint working-directory: frontend backend: name: Build backend diff --git a/README.md b/README.md index 2231fe1c..506ceec7 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ First make sure you have installed latest [nodejs](https://nodejs.org/en/downloa ``` cd frontend npm install -npm start +npm run dev ``` Follow the link in the console. diff --git a/frontend/.dockerignore b/frontend/.dockerignore index b512c09d..3c3629e6 100644 --- a/frontend/.dockerignore +++ b/frontend/.dockerignore @@ -1 +1 @@ -node_modules \ No newline at end of file +node_modules diff --git a/frontend/.editorconfig b/frontend/.editorconfig new file mode 100644 index 00000000..5d126348 --- /dev/null +++ b/frontend/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js new file mode 100644 index 00000000..fd4ca4f8 --- /dev/null +++ b/frontend/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + root: true, + env: { + browser: true, + node: true + }, + parserOptions: { + parser: '@babel/eslint-parser', + requireConfigFile: false + }, + extends: [ + '@nuxtjs', + 'plugin:nuxt/recommended', + 'prettier' + ], + plugins: [ + ], + // add your custom rules here + rules: {} +} diff --git a/frontend/.gitignore b/frontend/.gitignore index 0ae2ddf7..e8f682ba 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -1,26 +1,90 @@ -.DS_Store -node_modules -/dist - -# local env files -.env.local -.env.*.local - -# Log files +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +/logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* -# Editor directories and files +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# Nuxt generate +dist + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +# IDE / Editor .idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? - -# test reports -/test/unit/coverage/ -/test/e2e/reports/ + +# Service worker +sw.* + +# macOS +.DS_Store + +# Vim swap files +*.swp diff --git a/frontend/.prettierrc b/frontend/.prettierrc new file mode 100644 index 00000000..b2095be8 --- /dev/null +++ b/frontend/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": false, + "singleQuote": true +} diff --git a/frontend/README.md b/frontend/README.md index c932a9c9..43bdbdac 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,24 +1,69 @@ -# helpdesk +# helpdesk-frontend -## Project setup -``` -npm install -``` +## Build Setup -### Compiles and hot-reloads for development -``` -npm run serve -``` +```bash +# install dependencies +$ npm install -### Compiles and minifies for production -``` -npm run build -``` +# serve with hot reload at localhost:3000 +$ npm run dev -### Lints and fixes files -``` -npm run lint +# build for production and launch server +$ npm run build +$ npm run start + +# generate static project +$ npm run generate ``` -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). +For detailed explanation on how things work, check out the [documentation](https://nuxtjs.org). + +## Special Directories + +You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality. + +### `assets` + +The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/assets). + +### `components` + +The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/components). + +### `layouts` + +Layouts are a great help when you want to change the look and feel of your Nuxt app, whether you want to include a sidebar or have distinct layouts for mobile and desktop. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts). + + +### `pages` + +This directory contains your application views and routes. Nuxt will read all the `*.vue` files inside this directory and setup Vue Router automatically. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/get-started/routing). + +### `plugins` + +The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use `Vue.use()`, you should create a file in `plugins/` and add its path to plugins in `nuxt.config.js`. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/plugins). + +### `static` + +This directory contains your static files. Each file inside this directory is mapped to `/`. + +Example: `/static/robots.txt` is mapped as `/robots.txt`. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/static). + +### `store` + +This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex. + +More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/store). diff --git a/frontend/babel.config.js b/frontend/babel.config.js deleted file mode 100644 index e9558405..00000000 --- a/frontend/babel.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - presets: [ - '@vue/cli-plugin-babel/preset' - ] -} diff --git a/frontend/components/DynamicForm.vue b/frontend/components/DynamicForm.vue new file mode 100644 index 00000000..d8b840c5 --- /dev/null +++ b/frontend/components/DynamicForm.vue @@ -0,0 +1,36 @@ + + + diff --git a/frontend/src/components/FormWidgets/CheckBoxInput.vue b/frontend/components/FormWidgets/CheckBoxInput.vue similarity index 100% rename from frontend/src/components/FormWidgets/CheckBoxInput.vue rename to frontend/components/FormWidgets/CheckBoxInput.vue index 3295d2a1..fe460cec 100644 --- a/frontend/src/components/FormWidgets/CheckBoxInput.vue +++ b/frontend/components/FormWidgets/CheckBoxInput.vue @@ -6,9 +6,9 @@ :wrapper-col="{ span: 12 }" > @@ -18,11 +18,6 @@ export default { name: 'CheckBoxInput', props: ['label', 'name', 'value', 'extra'], - methods: { - onCheckBoxChange (event) { - this.$emit('input', event.target.checked) - } - }, computed: { decorator () { return [ @@ -30,6 +25,11 @@ export default { rules: [{required: this.required, message: 'This field is required'}] }] } + }, + methods: { + onCheckBoxChange (event) { + this.$emit('input', event.target.checked) + } } } diff --git a/frontend/src/components/FormWidgets/NumberInput.vue b/frontend/components/FormWidgets/NumberInput.vue similarity index 100% rename from frontend/src/components/FormWidgets/NumberInput.vue rename to frontend/components/FormWidgets/NumberInput.vue index f6a2adc1..ac8460c9 100644 --- a/frontend/src/components/FormWidgets/NumberInput.vue +++ b/frontend/components/FormWidgets/NumberInput.vue @@ -5,10 +5,10 @@ :wrapper-col="{ span: 12 }" > diff --git a/frontend/src/components/FormWidgets/SelectInput.vue b/frontend/components/FormWidgets/SelectInput.vue similarity index 81% rename from frontend/src/components/FormWidgets/SelectInput.vue rename to frontend/components/FormWidgets/SelectInput.vue index d0e547bb..00d8bd32 100644 --- a/frontend/src/components/FormWidgets/SelectInput.vue +++ b/frontend/components/FormWidgets/SelectInput.vue @@ -13,37 +13,33 @@ :searchable="true" :filterable="true" :select-on-tab="true" + :value="selectedValues" @input="handleInput" @keypress.enter.native.prevent="" - :value="selectedValues" > - + diff --git a/frontend/src/components/Hdag.vue b/frontend/components/Hdag.vue similarity index 74% rename from frontend/src/components/Hdag.vue rename to frontend/components/Hdag.vue index 8cdb2159..071a02a3 100644 --- a/frontend/src/components/Hdag.vue +++ b/frontend/components/Hdag.vue @@ -8,11 +8,19 @@ import go from 'gojs' export default { name: "Hdag", - props: ["modelData", "selectedNode"], // accept model data as a parameter - mounted: function() { - var $ = go.GraphObject.make; - var self = this; - var myDiagram = + props: ["modelData", "selectedNode"], + watch: { + modelData(val) { this.updateModel(val); }, + selectedNode(newV) { + const node = this.diagram.findNodeForKey(newV) + this.diagram.select(node) + + }, + }, // accept model data as a parameter + mounted() { + const $ = go.GraphObject.make; + const self = this; + const myDiagram = $(go.Diagram, this.$el, { initialContentAlignment: go.Spot.Center, @@ -20,8 +28,8 @@ export default { "undoManager.isEnabled": false, isReadOnly: true, // Model ChangedEvents get passed up to component users - "ModelChanged": function(e) { self.$emit("model-changed", e); }, - "ChangedSelection": function(e) { self.$emit("changed-selection", e); } + "ModelChanged"(e) { self.$emit("model-changed", e); }, + "ChangedSelection"(e) { self.$emit("changed-selection", e); } }); myDiagram.nodeTemplate = @@ -48,31 +56,23 @@ export default { this.diagram = myDiagram; this.updateModel(this.modelData); }, - watch: { - modelData: function(val) { this.updateModel(val); }, - selectedNode: function(newV) { - var node = this.diagram.findNodeForKey(newV) - this.diagram.select(node) - - }, - }, methods: { - model: function() { return this.diagram.model; }, - updateModel: function(val) { + model() { return this.diagram.model; }, + updateModel(val) { // No GoJS transaction permitted when replacing Diagram.model. if (val instanceof go.Model) { this.diagram.model = val; } else { - var m = new go.GraphLinksModel() + const m = new go.GraphLinksModel() if (val) { - for (var p in val) { + for (const p in val) { m[p] = val[p]; } } this.diagram.model = m; } }, - updateDiagramFromData: function() { + updateDiagramFromData() { this.diagram.startTransaction(); // This is very general but very inefficient. // It would be better to modify the diagramData data by calling diff --git a/frontend/components/NotifyCard.vue b/frontend/components/NotifyCard.vue new file mode 100644 index 00000000..fb867ebb --- /dev/null +++ b/frontend/components/NotifyCard.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/frontend/src/components/ResultHostTable.vue b/frontend/components/ResultHostTable.vue similarity index 88% rename from frontend/src/components/ResultHostTable.vue rename to frontend/components/ResultHostTable.vue index f48b1fe1..e5874dc0 100644 --- a/frontend/src/components/ResultHostTable.vue +++ b/frontend/components/ResultHostTable.vue @@ -4,31 +4,31 @@

{{totalCount}} execution(s) in total , {{successCount}} succeed, {{failedCount}} failed .

+ @expand="handleRowExpand">
Search Reset
@@ -41,7 +41,7 @@

stderr:

-              
+              
                 {{typeof(record.stderr) === 'string' ? record.stderr : ''}}
               
             
@@ -61,12 +61,9 @@ diff --git a/frontend/src/components/SubMenu.vue b/frontend/components/SubMenu.vue similarity index 92% rename from frontend/src/components/SubMenu.vue rename to frontend/components/SubMenu.vue index a8b948cc..0e287f81 100644 --- a/frontend/src/components/SubMenu.vue +++ b/frontend/components/SubMenu.vue @@ -12,7 +12,7 @@ :key="item.key" > {{item.name}} diff --git a/frontend/src/components/SubTab.vue b/frontend/components/SubTab.vue similarity index 66% rename from frontend/src/components/SubTab.vue rename to frontend/components/SubTab.vue index 2cb1769f..1165f316 100644 --- a/frontend/src/components/SubTab.vue +++ b/frontend/components/SubTab.vue @@ -1,16 +1,16 @@ diff --git a/frontend/src/components/SubTabNoRecursive.vue b/frontend/components/SubTabNoRecursive.vue similarity index 64% rename from frontend/src/components/SubTabNoRecursive.vue rename to frontend/components/SubTabNoRecursive.vue index f5f1858d..d1e9ef72 100644 --- a/frontend/src/components/SubTabNoRecursive.vue +++ b/frontend/components/SubTabNoRecursive.vue @@ -1,17 +1,17 @@