├── .gitignore ├── README.md ├── babel.config.js ├── dist ├── css │ ├── appconfig.27e6c97f.css │ ├── appconfig~common~dashboard~groups~help~images~instance~instances~login~networks~profiles~projects~se~d63bb708.8993a2e0.css │ ├── appconfig~common~dashboard~groups~help~images~instance~instances~networks~profiles~projects~settings~users.5c6ada20.css │ ├── appconfig~dashboard~groups~help~images~instance~instances~login~networks~profiles~projects~settings~users.a2378f9f.css │ ├── appconfig~dashboard~groups~help~images~instance~instances~networks~profiles~projects~settings~users.6a2713a9.css │ ├── chunk-vendors.329858b2.css │ ├── common.62726b2d.css │ ├── dashboard.67cac3d6.css │ ├── groups.715f8e51.css │ ├── help.1d812d59.css │ ├── images.6a10af55.css │ ├── instance.d4c2dbf2.css │ ├── instances.9f2bc43b.css │ ├── login.c5369e4f.css │ ├── networks.fd924073.css │ ├── profiles.fd924073.css │ ├── projects.fd924073.css │ ├── settings.89345e09.css │ └── users.41933215.css ├── favicon.ico ├── index.html ├── js │ ├── app.f7e81680.js │ ├── app.f7e81680.js.map │ ├── appconfig.b3686073.js │ ├── appconfig.b3686073.js.map │ ├── appconfig~common~dashboard~groups~help~images~instance~instances~login~networks~profiles~projects~se~d63bb708.41ea6473.js │ ├── appconfig~common~dashboard~groups~help~images~instance~instances~login~networks~profiles~projects~se~d63bb708.41ea6473.js.map │ ├── appconfig~common~dashboard~groups~help~images~instance~instances~networks~profiles~projects~settings~users.e03c7a85.js │ ├── appconfig~common~dashboard~groups~help~images~instance~instances~networks~profiles~projects~settings~users.e03c7a85.js.map │ ├── appconfig~dashboard~groups~help~images~instance~instances~login~networks~profiles~projects~settings~users.8bf742e3.js │ ├── appconfig~dashboard~groups~help~images~instance~instances~login~networks~profiles~projects~settings~users.8bf742e3.js.map │ ├── appconfig~dashboard~groups~help~images~instance~instances~networks~profiles~projects~settings~users.b3eb35ca.js │ ├── appconfig~dashboard~groups~help~images~instance~instances~networks~profiles~projects~settings~users.b3eb35ca.js.map │ ├── chunk-vendors.86457050.js │ ├── chunk-vendors.86457050.js.map │ ├── common.1da52282.js │ ├── common.1da52282.js.map │ ├── dashboard.599df7d6.js │ ├── dashboard.599df7d6.js.map │ ├── groups.aeee21c6.js │ ├── groups.aeee21c6.js.map │ ├── help.37d3939e.js │ ├── help.37d3939e.js.map │ ├── images.c72210ce.js │ ├── images.c72210ce.js.map │ ├── instance.63f0b1ea.js │ ├── instance.63f0b1ea.js.map │ ├── instances.ab1666aa.js │ ├── instances.ab1666aa.js.map │ ├── login.ccffa843.js │ ├── login.ccffa843.js.map │ ├── networks.1a1595be.js │ ├── networks.1a1595be.js.map │ ├── profiles.7fdf17b0.js │ ├── profiles.7fdf17b0.js.map │ ├── projects.e02339f8.js │ ├── projects.e02339f8.js.map │ ├── settings.820d8edf.js │ ├── settings.820d8edf.js.map │ ├── users.6042eb17.js │ └── users.6042eb17.js.map └── static │ └── config.json ├── install_dashboard.sh ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── static │ └── config.json ├── src ├── App.vue ├── assets │ ├── locales │ │ ├── en.json │ │ └── sk.json │ ├── logo_lxd-manager.png │ └── styles │ │ ├── _variables.scss │ │ └── main.scss ├── components │ ├── AdminStats │ │ ├── AdminStats.vue │ │ ├── AdminStatsCard.vue │ │ └── HostStatsCard.vue │ ├── AppConfig │ │ ├── AppConfig.vue │ │ ├── EmailConfig.vue │ │ ├── OtherConfig.vue │ │ ├── PriceConfig.vue │ │ └── Tabs.vue │ ├── Groups │ │ ├── Groups.vue │ │ └── GroupsEdit.vue │ ├── Help │ │ └── Help.vue │ ├── Images │ │ ├── Images.vue │ │ ├── ImagesCard.vue │ │ └── RemoteImages.vue │ ├── Instance │ │ ├── Console.vue │ │ ├── Info.vue │ │ ├── Settings.vue │ │ ├── Snapshots.vue │ │ ├── Stats.vue │ │ └── Tabs.vue │ ├── Instances │ │ ├── DashboardInstances.vue │ │ └── Instances.vue │ ├── Loader.vue │ ├── Networks │ │ ├── Networks.vue │ │ └── NetworksCard.vue │ ├── Notifications.vue │ ├── Order │ │ ├── Order.vue │ │ ├── OrderCreate.vue │ │ └── OrderUpgrade.vue │ ├── Profiles │ │ ├── Profiles.vue │ │ └── ProfilesCard.vue │ ├── Projects │ │ ├── Projects.vue │ │ └── ProjectsCard.vue │ ├── Relogin.vue │ ├── Requests │ │ └── Requests.vue │ ├── Settings │ │ ├── Settings.vue │ │ ├── SettingsChangePassword.vue │ │ ├── SettingsProfile.vue │ │ └── SettingsSettings.vue │ ├── Stats │ │ ├── Stats.vue │ │ └── StatsCard.vue │ └── Users │ │ └── Users.vue ├── libraries │ ├── i18n │ │ └── index.js │ ├── plugins │ │ ├── auth.js │ │ ├── index.js │ │ └── title.js │ ├── router │ │ ├── index.js │ │ ├── main-routes.js │ │ └── routes.js │ ├── services │ │ ├── abilities.js │ │ ├── appconfig.js │ │ ├── auth.js │ │ ├── checkconfig.js │ │ ├── groups.js │ │ ├── host.js │ │ ├── images.js │ │ ├── index.js │ │ ├── instances.js │ │ ├── me.js │ │ ├── networks.js │ │ ├── operations.js │ │ ├── profiles.js │ │ ├── projects.js │ │ ├── requests.js │ │ ├── resource.js │ │ ├── serverResource.js │ │ ├── servers.js │ │ ├── stats.js │ │ └── users.js │ ├── store │ │ ├── actions.js │ │ ├── getters.js │ │ ├── index.js │ │ ├── modules │ │ │ ├── abilities.js │ │ │ ├── appconfig.js │ │ │ ├── auth.js │ │ │ ├── checkconfig.js │ │ │ ├── groups.js │ │ │ ├── host.js │ │ │ ├── images.js │ │ │ ├── index.js │ │ │ ├── instances.js │ │ │ ├── networks.js │ │ │ ├── notifications.js │ │ │ ├── operations.js │ │ │ ├── profiles.js │ │ │ ├── projects.js │ │ │ ├── requests.js │ │ │ ├── servers.js │ │ │ ├── stats.js │ │ │ └── users.js │ │ ├── mutations.js │ │ └── state.js │ └── utils │ │ ├── auth │ │ ├── abilities.js │ │ ├── groups.js │ │ └── index.js │ │ ├── axios.js │ │ ├── constants.js │ │ ├── format │ │ ├── images.js │ │ ├── instance.js │ │ ├── memoryLimit.js │ │ ├── request.js │ │ ├── stats.js │ │ ├── user.js │ │ └── userActions.js │ │ ├── helpers.js │ │ ├── index.js │ │ ├── states.js │ │ └── storage.js ├── main.js ├── plugins │ └── vuetify.js └── views │ ├── layouts │ ├── Error.vue │ ├── Layout.vue │ └── Login.vue │ └── pages │ ├── AppConfig.vue │ ├── Dashboard.vue │ ├── Groups.vue │ ├── Help.vue │ ├── Images.vue │ ├── Instance.vue │ ├── Instances.vue │ ├── Networks.vue │ ├── Profiles.vue │ ├── Projects.vue │ ├── Requests.vue │ ├── Settings.vue │ └── Users.vue └── vue.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | #/dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## LXDmanager-vue-dashboard 2 | 3 | This application provide frontend for lxdmanager. 4 | You can read more details and try **demo** on https://lxdmanager.com 5 | 6 | **1.0.0** — *Possible run it in production* 7 | 8 | ![dashboard](https://user-images.githubusercontent.com/45683353/61130070-1f70cc80-a4b6-11e9-9bd8-2166abad5988.png) 9 | ![dashboard2](https://user-images.githubusercontent.com/45683353/61130071-1f70cc80-a4b6-11e9-928d-696e86bb8469.png) 10 | ![servers](https://user-images.githubusercontent.com/45683353/61130072-20096300-a4b6-11e9-81b1-9a8a367dc89d.png) 11 | ![users](https://user-images.githubusercontent.com/45683353/61130074-20096300-a4b6-11e9-9f7e-456d6fe33069.png) 12 | ![groups](https://user-images.githubusercontent.com/45683353/61130075-20096300-a4b6-11e9-95da-e69deb3ccdc0.png) 13 | 14 | ## Why ? 15 | 16 | The purpose of this application is to provide web gui manager for LXD with additional features and user based management. 17 | It can be used for restrict access to containers for developers or as web management for container hosting clients. 18 | 19 | ## Credits 20 | 21 | This project is based on [vue-cli](https://github.com/lxc-webpanel/dashboard-vue) 22 | 23 | ## Running requirement 24 | 25 | This project require running backend for API from (https://github.com/Miso-K/lxd-api-gateway) 26 | 27 | It is recomended to use *Nginx* as webserver and proxy for websocket. 28 | 29 | ## Install 30 | For installation actual version of *lxdmanager-vue-dashboard* you can use *install_dashboard.sh* script. 31 | 32 | ``` bash 33 | # Download the script 34 | curl https://raw.githubusercontent.com/Miso-K/lxdmanager-vue-dashboard/master/install_dashboard.sh > install_dashboard.sh 35 | # Set execution permissions 36 | chmod +x install_dashboard.sh 37 | # Run script to install program 38 | ./install_dashboard.sh 39 | ``` 40 | 41 | The script download github repository and copy content of directory *dist* into */var/www/lxdmanager-vue-dashboard/* 42 | 43 | You can manualy download repository from github and copy content of directory *dist* where you need. 44 | 45 | *Nginx* config templates are stored in *nginx* directory. 46 | 47 | 48 | ## Development and build using vue ui 49 | 50 | ``` bash 51 | # install vue-cli and dependencies 52 | npm install @vue/cli 53 | 54 | # run vue ui at localhost:8080 55 | vue ui 56 | 57 | ``` 58 | 59 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Miso-K/lxdmanager-vue-dashboard/de00c56f1c209f6d9fc9f2f4afce3193c3073304/dist/favicon.ico -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | vue-dashboard-2
-------------------------------------------------------------------------------- /dist/static/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "API_BASE_URL":"http://127.0.0.1:5000" 3 | } 4 | -------------------------------------------------------------------------------- /install_dashboard.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | setupEnvironment () { 4 | printf '=============Setup the environment=============== \n'. 5 | apt-get update 6 | apt-get install nginx 7 | } 8 | 9 | setupApp () { 10 | printf '===============Setup the Application ================== \n' 11 | git clone https://github.com/Miso-K/lxdmanager-vue-dashboard lxdmanager-vue-dashboard 12 | 13 | echo -e "\nPlease install \"lxd-api-gateway\" with nginx proxy before \"lxdmanager-vue-dashboard\"" 14 | 15 | cd lxdmanager-vue-dashboard 16 | 17 | mkdir -p /var/www/lxdmanager-vue-dashboard 18 | cp -r lxdmanager-vue-dashboard/dist/* /var/www/lxdmanager-vue-dashboard 19 | } 20 | 21 | configureNginx () { 22 | printf '==================== Configure nginx =================== \n' 23 | 24 | # certbot-auto certonly -d ${NAME} --authenticator webroot --webroot-path /var/www/acme 25 | 26 | # Create nginx config file 27 | bash -c "cat > /etc/nginx/sites-enabled/${NAME}.conf < 1%", 70 | "last 2 versions" 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Miso-K/lxdmanager-vue-dashboard/de00c56f1c209f6d9fc9f2f4afce3193c3073304/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-dashboard-2 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /public/static/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "API_BASE_URL":"http://127.0.0.1:5000" 3 | } 4 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/logo_lxd-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Miso-K/lxdmanager-vue-dashboard/de00c56f1c209f6d9fc9f2f4afce3193c3073304/src/assets/logo_lxd-manager.png -------------------------------------------------------------------------------- /src/assets/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | $lwp_primary: #004159; 2 | $lwp_secondary: #23accf; -------------------------------------------------------------------------------- /src/assets/styles/main.scss: -------------------------------------------------------------------------------- 1 | @import './variables'; 2 | 3 | html { 4 | box-sizing: border-box; 5 | } 6 | 7 | *, 8 | *:before, 9 | *:after { 10 | box-sizing: inherit; 11 | } 12 | 13 | .valign-wrapper { 14 | display: flex; 15 | align-items: center; 16 | 17 | .valign { 18 | display: block; 19 | } 20 | } 21 | 22 | .secondary--text { 23 | color: $lwp_secondary !important; 24 | } 25 | 26 | .v-sheet--offset { 27 | top: -24px; 28 | position: relative; 29 | } 30 | -------------------------------------------------------------------------------- /src/components/AdminStats/AdminStats.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | 169 | -------------------------------------------------------------------------------- /src/components/AdminStats/AdminStatsCard.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/AdminStats/HostStatsCard.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 40 | 41 | -------------------------------------------------------------------------------- /src/components/AppConfig/PriceConfig.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 173 | 174 | -------------------------------------------------------------------------------- /src/components/AppConfig/Tabs.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 64 | -------------------------------------------------------------------------------- /src/components/Groups/Groups.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 203 | -------------------------------------------------------------------------------- /src/components/Help/Help.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 76 | -------------------------------------------------------------------------------- /src/components/Images/Images.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 44 | 45 | -------------------------------------------------------------------------------- /src/components/Images/RemoteImages.vue: -------------------------------------------------------------------------------- 1 | 81 | 82 | 143 | -------------------------------------------------------------------------------- /src/components/Instance/Console.vue: -------------------------------------------------------------------------------- 1 | 36 | 177 | -------------------------------------------------------------------------------- /src/components/Instance/Tabs.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 84 | -------------------------------------------------------------------------------- /src/components/Instances/DashboardInstances.vue: -------------------------------------------------------------------------------- 1 | 89 | 90 | 191 | -------------------------------------------------------------------------------- /src/components/Loader.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 19 | -------------------------------------------------------------------------------- /src/components/Networks/Networks.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 44 | -------------------------------------------------------------------------------- /src/components/Networks/NetworksCard.vue: -------------------------------------------------------------------------------- 1 | 84 | 85 | 208 | 209 | -------------------------------------------------------------------------------- /src/components/Notifications.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 38 | -------------------------------------------------------------------------------- /src/components/Order/Order.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 54 | -------------------------------------------------------------------------------- /src/components/Profiles/Profiles.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 44 | -------------------------------------------------------------------------------- /src/components/Projects/Projects.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 43 | 44 | -------------------------------------------------------------------------------- /src/components/Projects/ProjectsCard.vue: -------------------------------------------------------------------------------- 1 | 84 | 85 | 200 | 201 | -------------------------------------------------------------------------------- /src/components/Relogin.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 90 | -------------------------------------------------------------------------------- /src/components/Settings/Settings.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 36 | 75 | -------------------------------------------------------------------------------- /src/components/Settings/SettingsChangePassword.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 123 | -------------------------------------------------------------------------------- /src/components/Settings/SettingsProfile.vue: -------------------------------------------------------------------------------- 1 | 117 | 118 | 177 | -------------------------------------------------------------------------------- /src/components/Settings/SettingsSettings.vue: -------------------------------------------------------------------------------- 1 | 89 | 90 | 205 | 206 | -------------------------------------------------------------------------------- /src/components/Stats/Stats.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 106 | -------------------------------------------------------------------------------- /src/components/Stats/StatsCard.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 35 | -------------------------------------------------------------------------------- /src/libraries/i18n/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import I18n from 'vue-i18n'; 3 | 4 | Vue.use(I18n); 5 | 6 | // https://kazupon.github.io/vue-i18n/dynamic.html 7 | export default new I18n({ 8 | locale: 'en', 9 | fallbackLocale: 'en', 10 | messages: { 11 | en: require('../../assets/locales/en'), 12 | sk: require('../../assets/locales/sk') 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /src/libraries/plugins/auth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Auth middleware 3 | */ 4 | import _intersection from 'lodash/intersection'; 5 | import store from '../store'; 6 | import router from '../router'; 7 | 8 | export const checkAbilities = (required, abilities) => { 9 | if (required.length > 0) { 10 | if (typeof required === 'string') { 11 | return abilities.indexOf(required) !== -1; 12 | } 13 | 14 | if (required instanceof Array) { 15 | return _intersection(abilities, required).length === required.length; 16 | } 17 | } 18 | 19 | return false; 20 | }; 21 | 22 | export const loadAndCheckAuth = auth => store.dispatch('load') 23 | .then(() => { 24 | if (auth !== false && auth !== true && !checkAbilities(auth, store.getters['auth/me'].abilities)) { 25 | return Promise.reject(); 26 | } 27 | 28 | return Promise.resolve(); 29 | }); 30 | 31 | export default (Vue) => { 32 | // Authorize 33 | // Make sure that is the first hook. 34 | router.beforeHooks.unshift((to, from, next) => { // eslint-disable-line consistent-return 35 | // don't need authorize 36 | if (!to.meta.auth) return next(); 37 | 38 | // check login state 39 | store.dispatch('auth/checkToken') 40 | .then((valid) => { // eslint-disable-line consistent-return 41 | // authorized 42 | if (valid) return next(); 43 | 44 | // unauthorized 45 | console.log('⛔️ Unauthorized'); 46 | next({ name: 'login', query: { redirect: to.fullPath } }); 47 | }); 48 | }); 49 | 50 | // Redirect to dashboard if accessing '/login' when authenticated 51 | router.beforeEach((to, from, next) => { // eslint-disable-line consistent-return 52 | if (to.name !== 'login') return next(); 53 | 54 | store.dispatch('auth/checkToken') 55 | .then((valid) => { // eslint-disable-line consistent-return 56 | if (!valid) return next(); 57 | 58 | // when logged in 59 | next({ path: to.query.redirect || '/' }); 60 | }); 61 | }); 62 | 63 | // mount the authorize to Vue component instance 64 | Object.defineProperties(Vue.prototype, { 65 | $auth: { 66 | get: () => ({ 67 | me() { 68 | return store.getters['auth/me']; 69 | }, 70 | admin() { 71 | return this.me().admin || false; 72 | }, 73 | can(abilities) { 74 | return checkAbilities(abilities, this.me().abilities); 75 | } 76 | }) 77 | } 78 | }); 79 | }; 80 | -------------------------------------------------------------------------------- /src/libraries/plugins/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * My plugins 3 | */ 4 | 5 | import title from './title'; 6 | import auth from './auth'; 7 | 8 | export default { 9 | install(Vue) { 10 | title(Vue, { property: 'title', separator: ' — ' }); 11 | auth(Vue); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/libraries/plugins/title.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Change title when route updates 3 | */ 4 | import router from '../router'; 5 | import store from '../store'; 6 | 7 | export default (Vue, options) => { 8 | let items; 9 | 10 | // change title 11 | router.afterEach((route) => { 12 | items = route.matched 13 | .map(item => (item.components.default[options.property] || item.components.default.name)) // eslint-disable-line max-len 14 | .reverse(); 15 | items[items.length - 1] = store.getters.appconfig.app ? 16 | store.getters.appconfig.app.production_name : items[items.length - 1]; 17 | document.title = items.join(options.separator); 18 | }); 19 | 20 | Object.defineProperties(Vue.prototype, { 21 | $title: { 22 | get: () => (title, fullname) => { 23 | if (fullname) { 24 | document.title = title; 25 | } else { 26 | // partial 27 | items[0] = title; 28 | document.title = items.join(options.separator); 29 | } 30 | } 31 | } 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /src/libraries/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | import routes from './routes'; 4 | 5 | Vue.use(VueRouter); 6 | 7 | const Router = new VueRouter({ 8 | //mode: 'history', 9 | mode: process.env.PUBLIC_URL ? 'history' : 'hash', 10 | base: process.env.PUBLIC_URL, 11 | routes 12 | }); 13 | 14 | export default Router; 15 | // https://router.vuejs.org/zh-cn/advanced/scroll-behavior.html 16 | // https://github.com/vuejs/vue-router/blob/next/examples/scroll-behavior/app.js 17 | -------------------------------------------------------------------------------- /src/libraries/router/main-routes.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | // - Dashboard 3 | { 4 | name: 'dashboard', 5 | path: '/dashboard', 6 | meta: { auth: true }, 7 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Dashboard')), 'dashboard') 8 | }, 9 | // - Instances 10 | { 11 | name: 'instances', 12 | path: '/instances', 13 | meta: { auth: true }, 14 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Instances')), 'instances') 15 | }, 16 | // - Images 17 | { 18 | name: 'images', 19 | path: '/images', 20 | meta: { auth: true }, 21 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Images')), 'images') 22 | }, 23 | // - Networks 24 | { 25 | name: 'networks', 26 | path: '/networks', 27 | meta: { auth: true }, 28 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Networks')), 'networks') 29 | }, 30 | // - Profiles 31 | { 32 | name: 'profiles', 33 | path: '/profiles', 34 | meta: { auth: true }, 35 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Profiles')), 'profiles') 36 | }, 37 | // - Projects 38 | { 39 | name: 'projects', 40 | path: '/projects', 41 | meta: { auth: true }, 42 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Projects')), 'projects') 43 | }, 44 | // - Users 45 | { 46 | name: 'users', 47 | path: '/users', 48 | meta: { auth: 'users_create' }, 49 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Users')), 'users') 50 | }, 51 | // - Groups 52 | { 53 | name: 'groups', 54 | path: '/groups', 55 | meta: { auth: 'groups_create' }, 56 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Groups')), 'groups') 57 | }, 58 | // - Settings 59 | { 60 | name: 'settings', 61 | path: '/settings', 62 | meta: { auth: 'me_update' }, 63 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Settings')), 'settings') 64 | }, 65 | // - Instance 66 | { 67 | name: 'instance', 68 | path: '/instance/:id', 69 | meta: { auth: true }, 70 | props: true, 71 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Instance')), 'instance') 72 | }, 73 | // - Help 74 | { 75 | name: 'help', 76 | path: '/help', 77 | meta: { auth: true }, 78 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Help')), 'help') 79 | }, 80 | // - Appconfig 81 | { 82 | name: 'appconfig', 83 | path: '/appconfig', 84 | meta: { auth: 'config_infos' }, 85 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/AppConfig')), 'appconfig') 86 | }, 87 | // - Requests 88 | { 89 | name: 'requests', 90 | path: '/requests', 91 | meta: { auth: true }, 92 | component: resolve => require.ensure([], () => resolve(require('../../views/pages/Requests')), 'help') 93 | } 94 | ]; 95 | -------------------------------------------------------------------------------- /src/libraries/router/routes.js: -------------------------------------------------------------------------------- 1 | import mainRoutes from './main-routes'; 2 | import store from '../store'; 3 | 4 | export default [ 5 | // ## login page 6 | { 7 | name: 'login', 8 | path: '/login', 9 | meta: { auth: false }, 10 | component: resolve => require.ensure([], () => resolve(require('../../views/layouts/Login')), 'login') 11 | }, 12 | // ## logout page 13 | { 14 | name: 'logout', 15 | path: '/logout', 16 | meta: { auth: false }, 17 | beforeEnter(to, from, next) { 18 | store.dispatch('auth/logout'); 19 | next({ name: 'login', query: { logout: 1 } }); 20 | } 21 | }, 22 | // ## main page 23 | { 24 | path: '/', 25 | meta: { auth: true }, 26 | redirect: '/dashboard', 27 | component: resolve => require.ensure([], () => resolve(require('../../views/layouts/Layout')), 'common'), 28 | children: mainRoutes 29 | }, 30 | // ## not found page 31 | { 32 | name: 'not-found', 33 | path: '*', 34 | meta: { auth: false }, 35 | component: resolve => require.ensure([], () => resolve(require('../../views/layouts/Error')), 'common') 36 | } 37 | ]; 38 | -------------------------------------------------------------------------------- /src/libraries/services/abilities.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Users service 3 | */ 4 | 5 | import Resource from './resource'; 6 | 7 | export default new Resource('lgw/abilities'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/appconfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AppConfig service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class AppConfig { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get() { // eslint-disable-line class-methods-use-this 13 | return axios.get(`/${this.base}/lxdconfig`); 14 | } 15 | 16 | post(options) { 17 | const url = `/${this.base}/lxdconfig`; 18 | return axios.post(url, options); 19 | } 20 | 21 | postcerts(options) { 22 | return axios.post(`/${this.base}/lxdcerts`, options); 23 | } 24 | } 25 | 26 | export default new AppConfig('lgw'); 27 | -------------------------------------------------------------------------------- /src/libraries/services/auth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Auth service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class Auth { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | token(options) { 13 | return axios.post(this.url(), options); 14 | } 15 | 16 | check() { 17 | return axios.get(this.url('check')); 18 | } 19 | 20 | otpToken(options) { 21 | return axios.post(this.url('otp'), options); 22 | } 23 | 24 | refresh() { 25 | return axios.post(this.url('refresh')); 26 | } 27 | 28 | logout() { 29 | return axios.delete(this.url('logout')); 30 | } 31 | 32 | url(path) { 33 | const p = path ? `/${path}` : ''; 34 | return `/${this.base}${p}`; 35 | } 36 | } 37 | 38 | export default new Auth('auth'); 39 | -------------------------------------------------------------------------------- /src/libraries/services/checkconfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * LXD service 3 | */ 4 | 5 | import Resource from './resource'; 6 | 7 | export default new Resource('lgw/config'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/groups.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Users service 3 | */ 4 | 5 | import Resource from './resource'; 6 | 7 | export default new Resource('lgw/groups'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/host.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Host service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class Host { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get() { // eslint-disable-line class-methods-use-this 13 | return axios.get(`/${this.base}`); 14 | } 15 | } 16 | 17 | export default new Host('lxc/resources'); 18 | -------------------------------------------------------------------------------- /src/libraries/services/images.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Images service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | import Resource from './resource'; 7 | 8 | class Images extends Resource { 9 | // constructor(base) { 10 | // this.base = base; 11 | // } 12 | 13 | get() { // eslint-disable-line class-methods-use-this 14 | return axios.get(`/${this.base}`); 15 | } 16 | 17 | getRemote() { // eslint-disable-line class-methods-use-this 18 | // return axios.get('https://uk.images.linuxcontainers.org/1.0/images/aliases?recursion=1'); 19 | return axios.get('/lgw/images/remote'); 20 | } 21 | 22 | post(server, options) { 23 | const url = `/${this.base}/${server}`; 24 | return axios.post(url, options); 25 | } 26 | 27 | put(server, id, options) { 28 | const url = `/${this.base}/${server}/${id}`; 29 | return axios.put(url, options); 30 | } 31 | 32 | patch(server, id, options) { 33 | const url = `/${this.base}/${server}/${id}`; 34 | return axios.patch(url, options); 35 | } 36 | 37 | delete(server, fingerprint) { 38 | return axios.delete(`/${this.base}/${server}/${fingerprint}`); 39 | } 40 | 41 | aliasCreate(server, options) { 42 | return axios.post(`/${this.base}/aliases/${server}`, options); 43 | } 44 | 45 | aliasRename(server, alias, options) { 46 | return axios.post(`/${this.base}/aliases/${server}/${alias}`, options); 47 | } 48 | 49 | aliasPatch(server, alias, options) { 50 | return axios.patch(`/${this.base}/aliases/${server}/${alias}`, options); 51 | } 52 | } 53 | 54 | export default new Images('lxc/images'); 55 | -------------------------------------------------------------------------------- /src/libraries/services/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Services 3 | * http://www.ruanyifeng.com/blog/2014/05/restful_api.html 4 | */ 5 | import AbilitiesService from './abilities'; 6 | import AuthService from './auth'; 7 | import InstancesService from './instances'; 8 | import MeService from './me'; 9 | import UsersService from './users'; 10 | import RequestsService from './requests'; 11 | import GroupsService from './groups'; 12 | import StatsService from './stats'; 13 | import HostService from './host'; 14 | import AppConfigService from './appconfig'; 15 | import CheckconfigService from './checkconfig'; 16 | import ImagesService from './images'; 17 | import OperationsService from './operations'; 18 | import NetworksService from './networks'; 19 | import ProfilesService from './profiles'; 20 | import ProjectsService from './projects'; 21 | import ServersService from './servers'; 22 | 23 | export { 24 | AbilitiesService, 25 | AuthService, 26 | InstancesService, 27 | GroupsService, 28 | RequestsService, 29 | MeService, 30 | UsersService, 31 | StatsService, 32 | HostService, 33 | AppConfigService, 34 | CheckconfigService, 35 | OperationsService, 36 | ImagesService, 37 | NetworksService, 38 | ProfilesService, 39 | ProjectsService, 40 | ServersService 41 | }; 42 | -------------------------------------------------------------------------------- /src/libraries/services/instances.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Instances service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | import Resource from './resource'; 7 | 8 | class InstanceResource extends Resource { 9 | start(id) { 10 | return axios.post(`/${this.base}/${id}/start`); 11 | } 12 | 13 | stop(id) { 14 | return axios.post(`/${this.base}/${id}/stop`); 15 | } 16 | 17 | freeze(id) { 18 | return axios.post(`/${this.base}/${id}/freeze`); 19 | } 20 | 21 | unfreeze(id) { 22 | return axios.post(`/${this.base}/${id}/unfreeze`); 23 | } 24 | 25 | stopforce(id) { 26 | return axios.post(`/${this.base}/${id}/stop`); 27 | } 28 | 29 | restart(id) { 30 | return axios.post(`/${this.base}/${id}/restart`); 31 | } 32 | 33 | terminal(id) { 34 | return axios.post(`/${this.base}/${id}/exec`); 35 | } 36 | 37 | fetch(id) { // eslint-disable-line class-methods-use-this 38 | return axios.get(`/${this.base}/${id}`); 39 | } 40 | 41 | snapshots(id) { // eslint-disable-line class-methods-use-this 42 | return axios.get(`/${this.base}/${id}/snapshots`); 43 | } 44 | 45 | snapshot(id, name) { // eslint-disable-line class-methods-use-this 46 | return axios.get(`/${this.base}/${id}/snapshots/${name}`); 47 | } 48 | 49 | snapshotDelete(id, name) { // eslint-disable-line class-methods-use-this 50 | return axios.delete(`/${this.base}/${id}/snapshots/${name}`); 51 | } 52 | 53 | snapshotRestore(id, name) { // eslint-disable-line class-methods-use-this 54 | return axios.post(`/${this.base}/${id}/snapshots/${name}/restore`); 55 | } 56 | 57 | snapshotCreate(id, options) { // eslint-disable-line class-methods-use-this 58 | return axios.post(`/${this.base}/${id}/snapshots`, options); 59 | } 60 | 61 | operation(id) { 62 | console.log(this.base); 63 | return axios.get(`/lxc/operations/${id}`); 64 | } 65 | 66 | updateState(id, options) { 67 | return axios.put(`/${this.base}/${id}/state`, options); 68 | } 69 | } 70 | 71 | export default new InstanceResource('lxc/instances'); 72 | -------------------------------------------------------------------------------- /src/libraries/services/me.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Me service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class Me { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get() { // eslint-disable-line class-methods-use-this 13 | return axios.get(`/${this.base}`); 14 | } 15 | 16 | put(options) { 17 | const url = `/${this.base}`; 18 | return axios.put(url, options); 19 | } 20 | 21 | otp() { 22 | return axios.post(`/${this.base}/otp`); 23 | } 24 | } 25 | 26 | export default new Me('lgw/me'); 27 | -------------------------------------------------------------------------------- /src/libraries/services/networks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Networks service 3 | */ 4 | 5 | import ServerResource from './serverResource'; 6 | 7 | export default new ServerResource('lxc/networks'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/operations.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Operations service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | import Resource from './resource'; 7 | 8 | class Images extends Resource { 9 | // constructor(base) { 10 | // this.base = base; 11 | // } 12 | get(server, id) { 13 | const url = `/${this.base}/${server}/${id}`; 14 | return axios.get(url); 15 | } 16 | } 17 | 18 | export default new Images('lxc/operations'); 19 | -------------------------------------------------------------------------------- /src/libraries/services/profiles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Profiles service 3 | */ 4 | 5 | import ServerResource from './serverResource'; 6 | 7 | export default new ServerResource('lxc/profiles'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/projects.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Projects service 3 | */ 4 | 5 | import ServerResource from './serverResource'; 6 | 7 | export default new ServerResource('lxc/projects'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/requests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Requests service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class Requests { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get() { // eslint-disable-line class-methods-use-this 13 | return axios.get(`/${this.base}`); 14 | } 15 | 16 | request(options) { 17 | // console.log(this.base); 18 | return axios.post(`/${this.base}`, options); 19 | } 20 | 21 | put(id, options) { 22 | const url = `/${this.base}/${id}`; 23 | return axios.put(url, options); 24 | } 25 | 26 | delete(id) { 27 | const url = `/${this.base}/${id}`; 28 | return axios.delete(url); 29 | } 30 | } 31 | 32 | export default new Requests('lgw/requests'); 33 | -------------------------------------------------------------------------------- /src/libraries/services/resource.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Resource class 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class Resource { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get(id, options) { 13 | let url = `/${this.base}`; 14 | let opts = options; 15 | 16 | if (typeof id === 'object') { 17 | opts = id; 18 | } else if (id !== undefined) { 19 | url += `/${id}`; 20 | } 21 | return axios.get(url, opts); 22 | } 23 | 24 | delete(id, options) { 25 | const url = `/${this.base}/${id}`; 26 | return axios.delete(url, options); 27 | } 28 | 29 | post(options) { 30 | const url = `/${this.base}`; 31 | return axios.post(url, options); 32 | } 33 | 34 | put(id, options) { 35 | const url = `/${this.base}/${id}`; 36 | return axios.put(url, options); 37 | } 38 | 39 | patch(id, options) { 40 | const url = `/${this.base}/${id}`; 41 | return axios.patch(url, options); 42 | } 43 | } 44 | 45 | export default Resource; 46 | -------------------------------------------------------------------------------- /src/libraries/services/serverResource.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Resource class 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class ServerResource { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get(id, options) { 13 | let url = `/${this.base}`; 14 | let opts = options; 15 | 16 | if (typeof id === 'object') { 17 | opts = id; 18 | } else if (id !== undefined) { 19 | url += `/${id}`; 20 | } 21 | return axios.get(url, opts); 22 | } 23 | 24 | delete(server, id, options) { 25 | const url = `/${this.base}/${server}/${id}`; 26 | return axios.delete(url, options); 27 | } 28 | 29 | post(server, options) { 30 | const url = `/${this.base}/${server}`; 31 | return axios.post(url, options); 32 | } 33 | 34 | put(server, id, options) { 35 | const url = `/${this.base}/${server}/${id}`; 36 | return axios.put(url, options); 37 | } 38 | 39 | patch(server, id, options) { 40 | const url = `/${this.base}/${server}/${id}`; 41 | return axios.patch(url, options); 42 | } 43 | } 44 | 45 | export default ServerResource; 46 | -------------------------------------------------------------------------------- /src/libraries/services/servers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Servers service 3 | */ 4 | 5 | import Resource from './resource'; 6 | 7 | export default new Resource('lgw/servers'); 8 | -------------------------------------------------------------------------------- /src/libraries/services/stats.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Stats service 3 | */ 4 | 5 | import { axios } from '../utils'; 6 | 7 | class Stats { 8 | constructor(base) { 9 | this.base = base; 10 | } 11 | 12 | get() { // eslint-disable-line class-methods-use-this 13 | return axios.get(`/${this.base}`); 14 | } 15 | } 16 | 17 | export default new Stats('lgw/stats'); 18 | -------------------------------------------------------------------------------- /src/libraries/services/users.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Users service 3 | */ 4 | 5 | import Resource from './resource'; 6 | 7 | export default new Resource('lgw/users'); 8 | -------------------------------------------------------------------------------- /src/libraries/store/actions.js: -------------------------------------------------------------------------------- 1 | import store from './index'; 2 | 3 | export const changeTitle = ({ commit }, title) => { 4 | commit('CHANGE_SESSION', { title }); 5 | }; 6 | 7 | export const load = ({ commit }) => { 8 | // eslint-disable-next-line max-len 9 | // const actions = ['fetchMe', 'fetchGroups', 'fetchAbilities'].map(action => store.dispatch(action)); 10 | // eslint-disable-next-line max-len 11 | const actions = ['fetchMe', 'fetchUsers', 'fetchGroups', 'fetchAbilities', 'fetchInstances', 'fetchImages', 'fetchAppConfig'].map(action => store.dispatch(action)); 12 | 13 | return Promise.all(actions).then(() => { 14 | commit('APP_LOAD'); 15 | }).catch((err) => { 16 | // console.log('Failed to init app...', err); 17 | }); 18 | }; 19 | 20 | export const openDialog = ({ commit }, id) => { 21 | commit('OPEN_DIALOG', id); 22 | }; 23 | 24 | export const closeDialog = ({ commit }, id) => { 25 | commit('CLOSE_DIALOG', id); 26 | }; 27 | -------------------------------------------------------------------------------- /src/libraries/store/getters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取页面标题 3 | * @param {Object} state Vuex状态对象 4 | * @return {String} 页面标题 5 | */ 6 | export const title = state => state.title; 7 | 8 | /** 9 | * 获取客户端会话信息 10 | * @param {Object} state Vuex状态对象 11 | * @return {Object} 客户端会话信息 12 | */ 13 | export const session = state => state.session; 14 | 15 | /** 16 | * 获取顶部工具栏 17 | * @param {Object} state Vuex状态对象 18 | * @return {Object} 顶部工具栏 19 | */ 20 | export const header = state => state.header; 21 | 22 | /** 23 | * 获取侧边导航栏 24 | * @param {Object} state Vuex状态对象 25 | * @return {Object} 侧边导航栏 26 | */ 27 | export const sidebar = state => state.sidebar; 28 | -------------------------------------------------------------------------------- /src/libraries/store/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Vuex docs 3 | * https://vuex.vuejs.org/zh-cn 4 | * https://github.com/vuejs/vue-hackernews-2.0 5 | */ 6 | 7 | import Vue from 'vue'; 8 | import Vuex from 'vuex'; 9 | 10 | // // Make sure state writeable 11 | // import * as state from './state' // prop readonly 12 | import state from './state'; 13 | import * as getters from './getters'; 14 | import * as mutations from './mutations'; 15 | import * as actions from './actions'; 16 | import * as modules from './modules'; 17 | 18 | Vue.use(Vuex); 19 | 20 | const strict = process.env.NODE_ENV !== 'production'; 21 | 22 | const plugins = []; 23 | 24 | const store = new Vuex.Store({ 25 | state, 26 | getters, 27 | mutations, 28 | modules: modules.default, 29 | actions, 30 | strict, 31 | plugins 32 | }); 33 | 34 | // ## Initial 35 | // store.dispatch('initToken') 36 | // // change axios authorization header 37 | // axios.defaults.headers.Authorization = `Bearer ${storage.get('wedn_net_access_token')}` 38 | 39 | // ## Hot module replacement 40 | if (module.hot) { 41 | module.hot.accept([ 42 | './getters', 43 | './mutations', 44 | './actions', 45 | './modules/abilities', 46 | './modules/auth', 47 | './modules/instances', 48 | './modules/groups', 49 | './modules/notifications', 50 | './modules/users', 51 | './modules/stats', 52 | './modules/host', 53 | './modules/requests', 54 | './modules/appconfig', 55 | './modules/checkconfig', 56 | './modules/images', 57 | './modules/operations', 58 | './modules/networks', 59 | './modules/profiles', 60 | './modules/projects' 61 | ], () => { 62 | store.hotUpdate({ 63 | getters: require('./getters'), 64 | mutations: require('./mutations'), 65 | actions: require('./actions'), 66 | modules: { 67 | abilities: require('./modules/abilities'), 68 | auth: require('./modules/auth'), 69 | instances: require('./modules/instances'), 70 | groups: require('./modules/groups'), 71 | notifications: require('./modules/notifications'), 72 | users: require('./modules/users'), 73 | requests: require('./modules/requests'), 74 | host: require('./modules/host'), 75 | appconfig: require('./modules/appconfig'), 76 | checkconfig: require('./modules/checkconfig'), 77 | images: require('./modules/images'), 78 | operations: require('./modules/operations'), 79 | networks: require('./modules/networks'), 80 | profiles: require('./modules/profiles'), 81 | projects: require('./modules/projects'), 82 | stats: require('./modules/stats').default 83 | } 84 | }); 85 | }); 86 | } 87 | 88 | // store.registerModule('instances', modules.instances); 89 | 90 | export default store; 91 | -------------------------------------------------------------------------------- /src/libraries/store/modules/abilities.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { AbilitiesService } from '../../services'; 3 | 4 | export const ABILITIES_REQUEST = 'ABILITIES_REQUEST'; 5 | export const ABILITIES_SUCCESS = 'ABILITIES_SUCCESS'; 6 | export const ABILITIES_FAILURE = 'ABILITIES_FAILURE'; 7 | 8 | /** 9 | * Initial state 10 | * @type {Object} 11 | */ 12 | const abilitiesState = { 13 | abilities: {}, 14 | loading: false 15 | }; 16 | 17 | /** 18 | * Getters 19 | * @type {Object} 20 | */ 21 | const abilitiesGetters = { 22 | abilities: state => state.abilities, 23 | ability: state => id => state.abilities[id], 24 | abilitiessTableData(state, getters) { 25 | if (Object.keys(getters.abilities).length === 0) return false; 26 | return _map(getters.abilities, ability => ability); // eslint-disable-line max-len 27 | } 28 | }; 29 | 30 | /** 31 | * Mutations 32 | * @type {Object} 33 | */ 34 | const abilitiesMutations = { 35 | [ABILITIES_REQUEST]: (state) => { 36 | Object.assign(state, { loading: true }); 37 | }, 38 | [ABILITIES_SUCCESS]: (state, abilities) => { 39 | Object.assign(state, { ...abilities, loading: false }); 40 | }, 41 | [ABILITIES_FAILURE]: (state, err) => { 42 | console.log(ABILITIES_FAILURE, err); 43 | Object.assign(state, { loading: false }); 44 | } 45 | }; 46 | 47 | /** 48 | * Actions 49 | * @type {Object} 50 | */ 51 | const abilitiesActions = { 52 | fetchAbilities({ commit }) { 53 | commit(ABILITIES_REQUEST); 54 | 55 | return AbilitiesService.get().then((res) => { 56 | res.abilities = res.data.data; 57 | commit(ABILITIES_SUCCESS, res); 58 | }).catch((err) => { 59 | commit(ABILITIES_FAILURE, err); 60 | }); 61 | } 62 | }; 63 | 64 | // Export module 65 | export default { 66 | state: abilitiesState, 67 | getters: abilitiesGetters, 68 | mutations: abilitiesMutations, 69 | actions: abilitiesActions 70 | }; 71 | -------------------------------------------------------------------------------- /src/libraries/store/modules/appconfig.js: -------------------------------------------------------------------------------- 1 | import { AppConfigService } from '../../services'; 2 | import storage from '../../utils/storage'; 3 | 4 | export const APPCONFIG_REQUEST = 'APPCONFIG_REQUEST'; 5 | export const APPCONFIG_SUCCESS = 'APPCONFIG_SUCCESS'; 6 | export const APPCONFIG_FAILURE = 'APPCONFIG_FAILURE'; 7 | 8 | export const APPCONFIG_KEY = 'APPCONFIG'; 9 | const storedAppConfig = storage.get(APPCONFIG_KEY); 10 | 11 | /** 12 | * Initial state 13 | * @type {Object} 14 | */ 15 | const appconfigState = { 16 | loading: false, 17 | appconfig: storedAppConfig || {} 18 | }; 19 | 20 | /** 21 | * Getters 22 | * @type {Object} 23 | */ 24 | const appconfigGetters = { 25 | appconfig: state => state.appconfig // eslint-disable-line no-confusing-arrow, max-len 26 | }; 27 | 28 | /** 29 | * Mutations 30 | * @type {Object} 31 | */ 32 | const mutations = { 33 | [APPCONFIG_REQUEST]: (state) => { 34 | Object.assign(state, { loading: true }); 35 | }, 36 | [APPCONFIG_SUCCESS]: (state, appconfig) => { 37 | Object.assign(state, { ...appconfig, loading: false }); 38 | storage.set(APPCONFIG_KEY, appconfig.appconfig); 39 | }, 40 | [APPCONFIG_FAILURE]: (state, err) => { 41 | console.log(APPCONFIG_FAILURE, err); 42 | Object.assign(state, { loading: false }); 43 | storage.remove(APPCONFIG_KEY); 44 | } 45 | }; 46 | 47 | /** 48 | * Actions 49 | * @type {Object} 50 | */ 51 | const actions = { 52 | fetchAppConfig({ commit }) { 53 | commit(APPCONFIG_REQUEST); 54 | 55 | return AppConfigService.get() 56 | .then((res) => { 57 | commit(APPCONFIG_SUCCESS, { appconfig: res.data.data }); // it is named lxdconfig in backend 58 | }).catch((err) => { 59 | commit(APPCONFIG_FAILURE, err); 60 | }); 61 | }, 62 | 63 | saveAppConfig({ commit }, data) { 64 | commit(APPCONFIG_REQUEST); 65 | console.log(data); 66 | // const obj = { 67 | // data: { 68 | // type: 'users', 69 | // attributes: data 70 | // } 71 | // }; 72 | return AppConfigService.post(data).then((res) => { 73 | console.log(res); 74 | commit(APPCONFIG_SUCCESS, res.data); 75 | }).catch((err) => { 76 | commit(APPCONFIG_FAILURE, err); 77 | }); 78 | }, 79 | 80 | saveCerts({ commit }, data) { 81 | commit(APPCONFIG_REQUEST); 82 | console.log(data); 83 | // const obj = { 84 | // data: { 85 | // type: 'users', 86 | // attributes: data 87 | // } 88 | // }; 89 | return AppConfigService.postcerts(data).then((res) => { 90 | console.log(res); 91 | commit(APPCONFIG_SUCCESS, res.data); 92 | }).catch((err) => { 93 | commit(APPCONFIG_FAILURE, err); 94 | }); 95 | } 96 | }; 97 | 98 | // Export module 99 | export default { 100 | state: appconfigState, 101 | getters: appconfigGetters, 102 | mutations, 103 | actions 104 | }; 105 | -------------------------------------------------------------------------------- /src/libraries/store/modules/auth.js: -------------------------------------------------------------------------------- 1 | import jwtDecode from 'jwt-decode'; 2 | import { AuthService } from '../../services'; 3 | import { getUserAbilities } from '../../utils/auth'; 4 | import storage from '../../utils/storage'; 5 | 6 | export const STORAGE_TOKEN_KEY = 'lwp_token'; 7 | export const STORAGE_REFRESH_TOKEN_KEY = 'lwp_token2'; 8 | export const STORAGE_ME_KEY = 'lwp_me'; 9 | 10 | export const TOKEN_REQUEST = 'TOKEN_REQUEST'; 11 | export const TOKEN_SUCCESS = 'TOKEN_SUCCESS'; 12 | export const TOKEN_FAILURE = 'TOKEN_FAILURE'; 13 | 14 | export const CHECK_TOKEN_REQUEST = 'CHECK_TOKEN_REQUEST'; 15 | export const CHECK_TOKEN_SUCCESS = 'CHECK_TOKEN_SUCCESS'; 16 | export const CHECK_TOKEN_FAILURE = 'CHECK_TOKEN_FAILURE'; 17 | 18 | export const LOGOUT = 'LOGOUT'; 19 | 20 | export const APPCONFIG_KEY = 'APPCONFIG'; 21 | export const STORAGE_INSTANCES_KEY = 'STORAGE_INSTANCES'; 22 | 23 | const storedToken = storage.get(STORAGE_TOKEN_KEY); 24 | const storedRefreshToken = storage.get(STORAGE_REFRESH_TOKEN_KEY); 25 | 26 | /** 27 | * Initial state 28 | * @type {Object} 29 | */ 30 | const authState = { 31 | token: storedToken || null, 32 | refresh_token: storedRefreshToken || null, 33 | otp_token: null, 34 | otp_confirmed: null 35 | }; 36 | 37 | /** 38 | * Getters 39 | * @type {Object} 40 | */ 41 | const authGetters = { 42 | token: state => state.token, 43 | refresh_token: state => state.refresh_token, 44 | otp_token: state => state.otp_token, 45 | otpConfirmed: state => state.otp_confirmed, 46 | identity: ({ token }) => token ? jwtDecode(token).identity : null, // eslint-disable-line no-confusing-arrow,max-len 47 | me(state, getters, rootState, { myself, groups, abilities }) { 48 | // const index = users.findIndex(e => e.id === getters.identity); 49 | return { 50 | ...myself, 51 | abilities: getUserAbilities({ myself, groups, abilities }, getters.identity) 52 | // groups: getUserGroups({ myself, groups }, getters.identity) 53 | }; 54 | } 55 | }; 56 | 57 | /** 58 | * Mutations 59 | * @type {Object} 60 | */ 61 | const authMutations = { 62 | [TOKEN_REQUEST]: () => { 63 | console.log('fetching token...'); 64 | }, 65 | [TOKEN_SUCCESS]: (state, data) => { 66 | Object.assign(state, { 67 | token: data.access_token, 68 | // eslint-disable-next-line max-len 69 | refresh_token: data.refresh_token ? data.refresh_token : storage.get(STORAGE_REFRESH_TOKEN_KEY), 70 | otp_confirmed: jwtDecode(data.access_token).user_claims.otp_confirmed, 71 | me: jwtDecode(data.access_token).identity 72 | }); 73 | // eslint-disable-next-line max-len 74 | storage.set(STORAGE_TOKEN_KEY, data.access_token); 75 | // eslint-disable-next-line max-len 76 | storage.set(STORAGE_REFRESH_TOKEN_KEY, data.refresh_token ? data.refresh_token : storage.get(STORAGE_REFRESH_TOKEN_KEY)); 77 | }, 78 | [TOKEN_FAILURE]: (state, err) => { 79 | console.log(TOKEN_FAILURE, err); 80 | Object.assign(state, { token: null, me: null }); 81 | storage.remove(STORAGE_TOKEN_KEY); 82 | storage.remove(STORAGE_REFRESH_TOKEN_KEY); 83 | storage.remove(APPCONFIG_KEY); 84 | storage.remove(STORAGE_INSTANCES_KEY); 85 | location.reload(); 86 | }, 87 | [LOGOUT]: (state) => { 88 | Object.assign(state, { token: null, me: null }); 89 | storage.remove(STORAGE_TOKEN_KEY); 90 | storage.remove(STORAGE_REFRESH_TOKEN_KEY); 91 | storage.remove(APPCONFIG_KEY); 92 | storage.remove(STORAGE_INSTANCES_KEY); 93 | location.reload(); 94 | } 95 | }; 96 | 97 | /** 98 | * Actions 99 | * @type {Object} 100 | */ 101 | const authActions = { 102 | token({ commit }, { username, password }) { 103 | commit(TOKEN_REQUEST); 104 | 105 | return AuthService.token({ 106 | username: username.trim(), 107 | password: password.trim() 108 | }).then((res) => { 109 | // console.log(res.data); 110 | commit(TOKEN_SUCCESS, res.data); 111 | }).catch((err) => { 112 | commit(TOKEN_FAILURE, err); 113 | }); 114 | }, 115 | 116 | checkToken({ commit, getters }) { 117 | return new Promise((resolve) => { 118 | // validate local store 119 | if (!getters.token) { 120 | return resolve(false); 121 | } 122 | 123 | // remote 124 | AuthService.check() 125 | .then(() => resolve(true)) 126 | .catch((err) => { 127 | commit(TOKEN_FAILURE, err); 128 | return resolve(false); 129 | }); 130 | 131 | return undefined; 132 | }); 133 | }, 134 | 135 | otpToken({ commit }, { secret }) { 136 | commit(TOKEN_REQUEST); 137 | return AuthService.otpToken({ 138 | secret: secret.trim() 139 | }).then((res) => { 140 | // console.log(res.data); 141 | commit(TOKEN_SUCCESS, res.data); 142 | }).catch((err) => { 143 | // console.log(err); 144 | commit(TOKEN_FAILURE, err); 145 | }); 146 | }, 147 | 148 | refreshToken({ commit }) { 149 | commit(TOKEN_REQUEST); 150 | // send refresh token as token 151 | storage.set(STORAGE_TOKEN_KEY, storage.get(STORAGE_REFRESH_TOKEN_KEY)); 152 | return AuthService.refresh({}).then((res) => { 153 | // console.log(res); 154 | commit(TOKEN_SUCCESS, res.data); 155 | }).catch((err) => { 156 | commit(TOKEN_FAILURE, err); 157 | }); 158 | }, 159 | 160 | // logout({ commit }) { 161 | // commit(LOGOUT); 162 | // } 163 | 164 | logout({ commit }) { 165 | // commit(LOGOUT); 166 | AuthService.logout({}).then(() => { 167 | commit(LOGOUT); 168 | }).catch((err) => { 169 | commit(TOKEN_FAILURE, err); 170 | }); 171 | } 172 | }; 173 | 174 | // Export module 175 | export default { 176 | namespaced: true, 177 | state: authState, 178 | getters: authGetters, 179 | mutations: authMutations, 180 | actions: authActions 181 | }; 182 | -------------------------------------------------------------------------------- /src/libraries/store/modules/checkconfig.js: -------------------------------------------------------------------------------- 1 | import { CheckconfigService } from '../../services'; 2 | 3 | export const CHECKCONFIG_REQUEST = 'CHECKCONFIG_REQUEST'; 4 | export const CHECKCONFIG_SUCCESS = 'CHECKCONFIG_SUCCESS'; 5 | export const CHECKCONFIG_FAILURE = 'CHECKCONFIG_FAILURE'; 6 | 7 | /** 8 | * Initial state 9 | * @type {Object} 10 | */ 11 | const checkconfigState = { 12 | checkconfig: {}, 13 | loading: false 14 | }; 15 | 16 | /** 17 | * Getters 18 | * @type {Object} 19 | */ 20 | const checkconfigGetters = { 21 | checkconfig: state => state.checkconfig 22 | }; 23 | 24 | /** 25 | * Mutations 26 | * @type {Object} 27 | */ 28 | const mutations = { 29 | [CHECKCONFIG_REQUEST]: (state) => { 30 | Object.assign(state, { loading: true }); 31 | }, 32 | [CHECKCONFIG_SUCCESS]: (state, host) => { 33 | Object.assign(state, { ...host, loading: false }); 34 | }, 35 | [CHECKCONFIG_FAILURE]: (state, err) => { 36 | // console.log(CHECKCONFIG_FAILURE, err); 37 | Object.assign(state, { checkconfig: err, loading: false }); 38 | } 39 | }; 40 | 41 | /** 42 | * Actions 43 | * @type {Object} 44 | */ 45 | const actions = { 46 | fetchCheckconfig({ commit }, data) { 47 | commit(CHECKCONFIG_REQUEST); 48 | // console.log(data); 49 | return CheckconfigService.get(data) 50 | .then((res) => { 51 | // console.log(res); 52 | commit(CHECKCONFIG_SUCCESS, { checkconfig: res.data.data }); 53 | }).catch((err) => { 54 | commit(CHECKCONFIG_FAILURE, err); 55 | }); 56 | } 57 | }; 58 | 59 | // Export module 60 | export default { 61 | state: checkconfigState, 62 | getters: checkconfigGetters, 63 | mutations, 64 | actions 65 | }; 66 | -------------------------------------------------------------------------------- /src/libraries/store/modules/groups.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { GroupsService } from '../../services'; 3 | 4 | export const GROUPS_REQUEST = 'GROUPS_REQUEST'; 5 | export const GROUPS_SUCCESS = 'GROUPS_SUCCESS'; 6 | export const GROUPS_FAILURE = 'GROUPS_FAILURE'; 7 | 8 | /** 9 | * Initial state 10 | * @type {Object} 11 | */ 12 | const groupsState = { 13 | groups: {}, 14 | loading: false 15 | }; 16 | 17 | /** 18 | * Getters 19 | * @type {Object} 20 | */ 21 | const groupsGetters = { 22 | groups: state => state.groups, 23 | group: state => id => state.groups[id], 24 | groupsTableData(state, getters) { 25 | if (Object.keys(getters.groups).length === 0) return false; 26 | return _map(getters.groups, group => group); // eslint-disable-line max-len 27 | }, 28 | groupsList(state, getters) { 29 | if (Object.keys(getters.groups).length === 0) return false; 30 | return _map(getters.groups, group => ({ 31 | name: group.name, 32 | id: group.id 33 | })); 34 | } 35 | }; 36 | 37 | /** 38 | * Mutations 39 | * @type {Object} 40 | */ 41 | const groupsMutations = { 42 | [GROUPS_REQUEST]: (state) => { 43 | Object.assign(state, { loading: true }); 44 | }, 45 | [GROUPS_SUCCESS]: (state, groups) => { 46 | Object.assign(state, { ...groups, loading: false }); 47 | }, 48 | [GROUPS_FAILURE]: (state, err) => { 49 | console.log(GROUPS_FAILURE, err); 50 | Object.assign(state, { loading: false }); 51 | } 52 | }; 53 | 54 | /** 55 | * Actions 56 | * @type {Object} 57 | */ 58 | const groupsActions = { 59 | fetchGroups({ commit }) { 60 | commit(GROUPS_REQUEST); 61 | 62 | return GroupsService.get().then((res) => { 63 | res.groups = res.data.data; 64 | commit(GROUPS_SUCCESS, res); 65 | }).catch((err) => { 66 | commit(GROUPS_FAILURE, err); 67 | }); 68 | }, 69 | 70 | createGroup({ commit }, data) { 71 | commit(GROUPS_REQUEST); 72 | // console.log('create log:'); 73 | // console.log(data); 74 | 75 | const obj = { 76 | data: { 77 | type: 'groups', 78 | name: data.name, 79 | relationships: { 80 | abilities: data.abilities ? data.abilities.map(a => ({ 81 | type: 'ability', 82 | id: a.id ? a.id : a 83 | })) : [] 84 | } 85 | } 86 | }; 87 | // console.log(obj); 88 | return GroupsService.post(obj).then((res) => { 89 | // console.log(res); 90 | commit(GROUPS_SUCCESS, res.data.data); 91 | }).catch((err) => { 92 | commit(GROUPS_FAILURE, err); 93 | }); 94 | }, 95 | 96 | updateGroup({ commit }, data) { 97 | commit(GROUPS_REQUEST); 98 | // console.log('update log:'); 99 | // console.log(data); 100 | 101 | const obj = { 102 | data: { 103 | type: 'groups', 104 | id: data.id, 105 | name: data.name, 106 | relationships: { 107 | abilities: data.abilities ? data.abilities.map(a => ({ 108 | type: 'ability', 109 | id: a.id ? a.id : a 110 | })) : [] 111 | } 112 | } 113 | }; 114 | // console.log(obj); 115 | return GroupsService.put(data.id, obj).then((res) => { 116 | // console.log(res); 117 | commit(GROUPS_SUCCESS, res.data.data); 118 | }).catch((err) => { 119 | commit(GROUPS_FAILURE, err); 120 | }); 121 | }, 122 | 123 | deleteGroup({ commit }, id) { 124 | commit(GROUPS_REQUEST); 125 | GroupsService.delete(id).then((res) => { 126 | commit(GROUPS_SUCCESS, res); 127 | }).catch((err) => { 128 | commit(GROUPS_FAILURE, err); 129 | }); 130 | } 131 | }; 132 | 133 | // Export module 134 | export default { 135 | state: groupsState, 136 | getters: groupsGetters, 137 | mutations: groupsMutations, 138 | actions: groupsActions 139 | }; 140 | -------------------------------------------------------------------------------- /src/libraries/store/modules/host.js: -------------------------------------------------------------------------------- 1 | import { HostService } from '../../services'; 2 | 3 | export const HOST_REQUEST = 'HOST_REQUEST'; 4 | export const HOST_SUCCESS = 'HOST_SUCCESS'; 5 | export const HOST_FAILURE = 'HOST_FAILURE'; 6 | 7 | /** 8 | * Initial state 9 | * @type {Object} 10 | */ 11 | const hostState = { 12 | loading: false, 13 | host: {} 14 | }; 15 | 16 | /** 17 | * Getters 18 | * @type {Object} 19 | */ 20 | const hostGetters = { 21 | host: state => state.host // eslint-disable-line no-confusing-arrow, max-len 22 | }; 23 | 24 | /** 25 | * Mutations 26 | * @type {Object} 27 | */ 28 | const mutations = { 29 | [HOST_REQUEST]: (state) => { 30 | Object.assign(state, { loading: true }); 31 | }, 32 | [HOST_SUCCESS]: (state, host) => { 33 | Object.assign(state, { ...host, loading: false }); 34 | }, 35 | [HOST_FAILURE]: (state, err) => { 36 | console.log(HOST_FAILURE, err); 37 | Object.assign(state, { loading: false }); 38 | } 39 | }; 40 | 41 | /** 42 | * Actions 43 | * @type {Object} 44 | */ 45 | const actions = { 46 | fetchHost({ commit }) { 47 | commit(HOST_REQUEST); 48 | 49 | return HostService.get() 50 | .then((res) => { 51 | // console.log(res); 52 | commit(HOST_SUCCESS, { host: res.data.data }); 53 | }).catch((err) => { 54 | commit(HOST_FAILURE, err); 55 | }); 56 | } 57 | }; 58 | 59 | // Export module 60 | export default { 61 | state: hostState, 62 | getters: hostGetters, 63 | mutations, 64 | actions 65 | }; 66 | -------------------------------------------------------------------------------- /src/libraries/store/modules/images.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { ImagesService } from '../../services'; 3 | import formatImage from '../../utils/format/images'; 4 | 5 | export const IMAGES_REQUEST = 'IMAGES_REQUEST'; 6 | export const IMAGES_SUCCESS = 'IMAGES_SUCCESS'; 7 | export const IMAGES_FAILURE = 'IMAGES_FAILURE'; 8 | export const REMOTE_IMAGES_SUCCESS = 'REMOTE_IMAGES_SUCCESS'; 9 | export const IMAGE_SUCCESS = 'IMAGE_SUCCESS'; 10 | 11 | /** 12 | * Initial state 13 | * @type {Object} 14 | */ 15 | const imagesState = { 16 | images: {}, 17 | remoteImages: {}, 18 | loading: false 19 | }; 20 | 21 | /** 22 | * Getters 23 | * @type {Object} 24 | */ 25 | const imagesGetters = { 26 | images: state => state.images, 27 | image: state => id => state.images[id], 28 | imagesTableData(state, getters) { 29 | if (Object.keys(getters.images).length === 0) return false; 30 | return _map(getters.images, image => formatImage(image)); // eslint-disable-line max-len 31 | }, 32 | remoteImages: state => state.remoteImages 33 | }; 34 | 35 | /** 36 | * Mutations 37 | * @type {Object} 38 | */ 39 | const imagesMutations = { 40 | [IMAGES_REQUEST]: (state) => { 41 | Object.assign(state, { loading: true }); 42 | }, 43 | [IMAGES_SUCCESS]: (state, images) => { 44 | Object.assign(state, { images, loading: false }); 45 | }, 46 | [REMOTE_IMAGES_SUCCESS]: (state, remoteImages) => { 47 | Object.assign(state, { remoteImages, loading: false }); 48 | }, 49 | [IMAGE_SUCCESS]: (state) => { 50 | Object.assign(state, { loading: false }); 51 | }, 52 | [IMAGES_FAILURE]: (state, err) => { 53 | console.log(IMAGES_FAILURE, err); 54 | Object.assign(state, { loading: false }); 55 | } 56 | }; 57 | 58 | /** 59 | * Actions 60 | * @type {Object} 61 | */ 62 | const imagesActions = { 63 | fetchImages({ commit }) { 64 | commit(IMAGES_REQUEST); 65 | 66 | return ImagesService.get().then((res) => { 67 | // console.log(res); 68 | commit(IMAGES_SUCCESS, res.data.data); 69 | }).catch((err) => { 70 | commit(IMAGES_FAILURE, err); 71 | }); 72 | }, 73 | 74 | fetchRemoteImages({ commit }) { 75 | commit(IMAGES_REQUEST); 76 | 77 | return ImagesService.getRemote().then((res) => { 78 | // console.log(res); 79 | commit(REMOTE_IMAGES_SUCCESS, res.data.data); 80 | }).catch((err) => { 81 | commit(IMAGES_FAILURE, err); 82 | }); 83 | }, 84 | 85 | createImage({ dispatch, commit }, data) { 86 | commit(IMAGES_REQUEST); 87 | // console.log('create log:'); 88 | console.log(data); 89 | 90 | const obj = { 91 | data: { 92 | public: false, 93 | aliases: [ 94 | { 95 | name: data.aliasName, 96 | description: data.aliasDescription 97 | } 98 | ], 99 | source: { 100 | type: 'image', 101 | mode: 'pull', 102 | server: 'https://uk.images.linuxcontainers.org', 103 | fingerprint: data.fingerprint 104 | } 105 | } 106 | }; 107 | console.log(obj); 108 | return ImagesService.post(data.server, obj).then((res) => { 109 | // console.log(res.data); 110 | // dispatch('notify', { id: 0, message: 'Image was downloaded', color: '' }); 111 | dispatch('fetchOperation', { server: data.server, id: res.data.metadata.id }); 112 | dispatch('fetchImages'); 113 | commit(IMAGE_SUCCESS, res); 114 | }).catch((err) => { 115 | commit(IMAGES_FAILURE, err); 116 | }); 117 | }, 118 | 119 | createImageAlias({ commit }, data) { 120 | commit(IMAGES_REQUEST); 121 | const obj = { 122 | data: { 123 | name: data.new_name, 124 | description: data.alias_description, 125 | target: data.fingerprint 126 | } 127 | }; 128 | // console.log(obj); 129 | return ImagesService.aliasCreate(data.server, obj).then((res) => { 130 | console.log(res); 131 | commit(IMAGE_SUCCESS, res.data); 132 | }).catch((err) => { 133 | commit(IMAGES_FAILURE, err); 134 | }); 135 | }, 136 | 137 | updateImageName({ commit }, data) { 138 | commit(IMAGES_REQUEST); 139 | const obj = { 140 | data: { 141 | name: data.new_name 142 | } 143 | }; 144 | console.log(obj); 145 | return ImagesService.aliasRename(data.server, data.name, obj).then((res) => { 146 | console.log(res); 147 | commit(IMAGE_SUCCESS, res.data); 148 | }).catch((err) => { 149 | commit(IMAGES_FAILURE, err); 150 | }); 151 | }, 152 | 153 | updateImageDescription({ commit }, data) { 154 | commit(IMAGES_REQUEST); 155 | // console.log('update log:'); 156 | // console.log(data); 157 | const obj = { 158 | data: { 159 | description: data.alias_description 160 | } 161 | }; 162 | return ImagesService.aliasPatch(data.server, data.name, obj).then((res) => { 163 | // console.log(res); 164 | commit(IMAGE_SUCCESS, res.data); 165 | }).catch((err) => { 166 | commit(IMAGES_FAILURE, err); 167 | }); 168 | }, 169 | 170 | deleteImage({ commit }, data) { 171 | commit(IMAGES_REQUEST); 172 | ImagesService.delete(data.server, data.fingerprint).then((res) => { 173 | commit(IMAGE_SUCCESS, res); 174 | }).catch((err) => { 175 | commit(IMAGES_FAILURE, err); 176 | }); 177 | } 178 | }; 179 | 180 | // Export module 181 | export default { 182 | state: imagesState, 183 | getters: imagesGetters, 184 | mutations: imagesMutations, 185 | actions: imagesActions 186 | }; 187 | -------------------------------------------------------------------------------- /src/libraries/store/modules/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-len */ 2 | import abilities from './abilities'; 3 | import auth from './auth'; 4 | import instances from './instances'; 5 | import groups from './groups'; 6 | import notifications from './notifications'; 7 | import users from './users'; 8 | import stats from './stats'; 9 | import host from './host'; 10 | import requests from './requests'; 11 | import appconfig from './appconfig'; 12 | import checkconfig from './checkconfig'; 13 | import images from './images'; 14 | import operations from './operations'; 15 | import networks from './networks'; 16 | import profiles from './profiles'; 17 | import projects from './projects'; 18 | import servers from './servers'; 19 | 20 | export default { 21 | abilities, 22 | auth, 23 | instances, 24 | groups, 25 | notifications, 26 | users, 27 | stats, 28 | host, 29 | requests, 30 | checkconfig, 31 | appconfig, 32 | images, 33 | operations, 34 | networks, 35 | profiles, 36 | projects, 37 | servers 38 | }; 39 | -------------------------------------------------------------------------------- /src/libraries/store/modules/networks.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { NetworksService } from '../../services'; 3 | 4 | export const NETWORKS_REQUEST = 'NETWORKS_REQUEST'; 5 | export const NETWORKS_SUCCESS = 'NETWORKS_SUCCESS'; 6 | export const NETWORKS_FAILURE = 'NETWORKS_FAILURE'; 7 | 8 | /** 9 | * Initial state 10 | * @type {Object} 11 | */ 12 | const networksState = { 13 | loading: false, 14 | networks: [] 15 | }; 16 | 17 | /** 18 | * Getters 19 | * @type {Object} 20 | */ 21 | const networksGetters = { 22 | networks: state => state.networks, // eslint-disable-line no-confusing-arrow, max-len 23 | networksTableData(state, getters) { 24 | if (Object.keys(getters.networks).length === 0) return false; 25 | return _map(getters.networks, network => network); // eslint-disable-line max-len 26 | } 27 | }; 28 | 29 | /** 30 | * Mutations 31 | * @type {Object} 32 | */ 33 | const mutations = { 34 | [NETWORKS_REQUEST]: (state) => { 35 | Object.assign(state, { loading: true }); 36 | }, 37 | [NETWORKS_SUCCESS]: (state, networks) => { 38 | Object.assign(state, { ...networks, loading: false }); 39 | }, 40 | [NETWORKS_FAILURE]: (state, err) => { 41 | console.log(NETWORKS_FAILURE, err); 42 | Object.assign(state, { loading: false }); 43 | } 44 | }; 45 | 46 | /** 47 | * Actions 48 | * @type {Object} 49 | */ 50 | const actions = { 51 | fetchNetworks({ commit }) { 52 | commit(NETWORKS_REQUEST); 53 | 54 | return NetworksService.get() 55 | .then((res) => { 56 | // console.log(res); 57 | commit(NETWORKS_SUCCESS, { networks: res.data.data }); 58 | }).catch((err) => { 59 | commit(NETWORKS_FAILURE, err); 60 | }); 61 | }, 62 | 63 | createNetwork({ commit }, data) { 64 | commit(NETWORKS_REQUEST); 65 | const obj = data; 66 | return NetworksService.post(data.server, obj).then((res) => { 67 | // console.log(res); 68 | commit(NETWORKS_SUCCESS, res.data); 69 | }).catch((err) => { 70 | commit(NETWORKS_FAILURE, err); 71 | }); 72 | }, 73 | 74 | updateNetwork({ commit }, data) { 75 | commit(NETWORKS_REQUEST); 76 | const obj = data; 77 | const name = data.data.name; 78 | return NetworksService.put(data.server, name, obj).then((res) => { 79 | // console.log(res); 80 | commit(NETWORKS_SUCCESS, res.data); 81 | }).catch((err) => { 82 | commit(NETWORKS_FAILURE, err); 83 | }); 84 | }, 85 | 86 | deleteNetwork({ commit }, data) { 87 | commit(NETWORKS_REQUEST); 88 | return NetworksService.delete(data.server, data.name).then((res) => { 89 | commit(NETWORKS_SUCCESS, res.data); 90 | }).catch((err) => { 91 | commit(NETWORKS_FAILURE, err); 92 | }); 93 | } 94 | }; 95 | 96 | // Export module 97 | export default { 98 | state: networksState, 99 | getters: networksGetters, 100 | mutations, 101 | actions 102 | }; 103 | -------------------------------------------------------------------------------- /src/libraries/store/modules/notifications.js: -------------------------------------------------------------------------------- 1 | export const ADD_NOTIFICATION = 'ADD_NOTIFICATION'; 2 | export const OPEN_SNACKBAR = 'OPEN_SNACKBAR'; 3 | export const CLOSE_SNACKBAR = 'CLOSE_SNACKBAR'; 4 | 5 | let timer; 6 | 7 | /** 8 | * Initial state 9 | * @type {Object} 10 | */ 11 | const notificationsState = { 12 | active: false, 13 | messages: [] 14 | }; 15 | 16 | /** 17 | * Getters 18 | * @type {Object} 19 | */ 20 | const notificationsGetters = { 21 | notifications: state => state.notifications 22 | }; 23 | 24 | /* eslint-disable no-param-reassign */ 25 | /** 26 | * Mutations 27 | * @type {Object} 28 | */ 29 | const notificationsMutations = { 30 | [ADD_NOTIFICATION]: (state, n) => { 31 | state.messages.push({ message: n.message, id: n.id, color: n.color ? n.color : '' }); 32 | }, 33 | [OPEN_SNACKBAR]: (state) => { 34 | state.active = true; 35 | // console.log(state, id); 36 | // state.messages 37 | }, 38 | [CLOSE_SNACKBAR]: (state) => { 39 | state.active = false; 40 | state.messages.splice(0, 1); 41 | // console.log(state); 42 | } 43 | }; 44 | /* eslint-enable no-param-reassign */ 45 | 46 | /** 47 | * Actions 48 | * @type {Object} 49 | */ 50 | const notificationsActions = { 51 | notify({ state, commit }, msg) { 52 | // console.log('NOTIFY'); 53 | commit(ADD_NOTIFICATION, msg); 54 | 55 | commit(OPEN_SNACKBAR); 56 | 57 | timer = setInterval(() => { 58 | // console.log('setInterval'); 59 | 60 | commit(CLOSE_SNACKBAR); 61 | 62 | if (state.messages.length > 1) { 63 | commit(OPEN_SNACKBAR); 64 | } else { 65 | clearInterval(timer); 66 | } 67 | }, 5000); 68 | }, 69 | closeNotif() { 70 | // console.log('closeNotif'); 71 | } 72 | }; 73 | 74 | // Export module 75 | export default { 76 | state: notificationsState, 77 | getters: notificationsGetters, 78 | mutations: notificationsMutations, 79 | actions: notificationsActions 80 | }; 81 | -------------------------------------------------------------------------------- /src/libraries/store/modules/operations.js: -------------------------------------------------------------------------------- 1 | import { OperationsService } from '../../services'; 2 | 3 | export const OPERATIONS_REQUEST = 'STATS_REQUEST'; 4 | export const OPERATIONS_SUCCESS = 'STATS_SUCCESS'; 5 | export const OPERATIONS_FAILURE = 'STATS_FAILURE'; 6 | 7 | /** 8 | * Initial state 9 | * @type {Object} 10 | */ 11 | const operationsState = { 12 | loading: false, 13 | operations: {} 14 | }; 15 | 16 | /** 17 | * Getters 18 | * @type {Object} 19 | */ 20 | const operationsGetters = { 21 | operations: state => state.operations 22 | }; 23 | 24 | /** 25 | * Mutations 26 | * @type {Object} 27 | */ 28 | const mutations = { 29 | [OPERATIONS_REQUEST]: (state) => { 30 | Object.assign(state, { loading: true }); 31 | }, 32 | [OPERATIONS_SUCCESS]: (state, stats) => { 33 | Object.assign(state, { ...stats, loading: false }); 34 | }, 35 | [OPERATIONS_FAILURE]: (state, err) => { 36 | // console.log(OPERATIONS_FAILURE, err); 37 | Object.assign(state, { status: err, loading: false }); 38 | } 39 | }; 40 | 41 | /** 42 | * Actions 43 | * @type {Object} 44 | */ 45 | const actions = { 46 | fetchOperation({ dispatch, commit }, data) { 47 | // commit(SNAPSHOTS_REQUEST); 48 | // console.log('operation'); 49 | OperationsService.get(data.server, data.id).then((res) => { 50 | // console.log(res); 51 | const meta = res.data.metadata; 52 | setTimeout(() => { 53 | // commit(SNAPSHOT_SUCCESS, { id, attributes: res.snapshots[id].attributes }); 54 | dispatch('notify', { id: 0, message: `${meta.description}-${meta.status}`, color: '' }); 55 | }, 1000); 56 | }).catch((err) => { 57 | commit(OPERATIONS_FAILURE, err, data.id); 58 | }); 59 | } 60 | }; 61 | 62 | // Export module 63 | export default { 64 | state: operationsState, 65 | getters: operationsGetters, 66 | mutations, 67 | actions 68 | }; 69 | -------------------------------------------------------------------------------- /src/libraries/store/modules/profiles.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { ProfilesService } from '../../services'; 3 | 4 | export const PROFILES_REQUEST = 'PROFILES_REQUEST'; 5 | export const PROFILES_SUCCESS = 'PROFILES_SUCCESS'; 6 | export const PROFILES_FAILURE = 'PROFILES_FAILURE'; 7 | 8 | /** 9 | * Initial state 10 | * @type {Object} 11 | */ 12 | const profilesState = { 13 | loading: false, 14 | profiles: {} 15 | }; 16 | 17 | /** 18 | * Getters 19 | * @type {Object} 20 | */ 21 | const profilesGetters = { 22 | profiles: state => state.profiles, // eslint-disable-line no-confusing-arrow, max-len 23 | profilesTableData(state, getters) { 24 | if (Object.keys(getters.profiles).length === 0) return false; 25 | return _map(getters.profiles, profile => profile); // eslint-disable-line max-len 26 | } 27 | }; 28 | 29 | /** 30 | * Mutations 31 | * @type {Object} 32 | */ 33 | const mutations = { 34 | [PROFILES_REQUEST]: (state) => { 35 | Object.assign(state, { loading: true }); 36 | }, 37 | [PROFILES_SUCCESS]: (state, profiles) => { 38 | Object.assign(state, { ...profiles, loading: false }); 39 | }, 40 | [PROFILES_FAILURE]: (state, err) => { 41 | console.log(PROFILES_FAILURE, err); 42 | Object.assign(state, { loading: false }); 43 | } 44 | }; 45 | 46 | /** 47 | * Actions 48 | * @type {Object} 49 | */ 50 | const actions = { 51 | fetchProfiles({ commit }) { 52 | commit(PROFILES_REQUEST); 53 | 54 | return ProfilesService.get() 55 | .then((res) => { 56 | // console.log(res); 57 | commit(PROFILES_SUCCESS, { profiles: res.data.data }); 58 | }).catch((err) => { 59 | commit(PROFILES_FAILURE, err); 60 | }); 61 | }, 62 | 63 | createProfile({ commit }, data) { 64 | commit(PROFILES_REQUEST); 65 | const obj = data; 66 | // console.log(obj); 67 | return ProfilesService.post(data.server, obj).then((res) => { 68 | // console.log(res); 69 | commit(PROFILES_SUCCESS, res.data); 70 | }).catch((err) => { 71 | commit(PROFILES_FAILURE, err); 72 | }); 73 | }, 74 | 75 | updateProfile({ commit }, data) { 76 | commit(PROFILES_REQUEST); 77 | const obj = data; 78 | const name = data.data.name; 79 | return ProfilesService.put(data.server, name, obj).then((res) => { 80 | // console.log(res); 81 | commit(PROFILES_SUCCESS, res.data); 82 | }).catch((err) => { 83 | commit(PROFILES_FAILURE, err); 84 | }); 85 | }, 86 | 87 | deleteProfile({ commit }, data) { 88 | commit(PROFILES_REQUEST); 89 | return ProfilesService.delete(data.server, data.name).then((res) => { 90 | commit(PROFILES_SUCCESS, res.data); 91 | }).catch((err) => { 92 | commit(PROFILES_FAILURE, err); 93 | }); 94 | } 95 | }; 96 | 97 | // Export module 98 | export default { 99 | state: profilesState, 100 | getters: profilesGetters, 101 | mutations, 102 | actions 103 | }; 104 | -------------------------------------------------------------------------------- /src/libraries/store/modules/projects.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { ProjectsService } from '../../services'; 3 | 4 | export const PROJECTS_REQUEST = 'PROJECTS_REQUEST'; 5 | export const PROJECTS_SUCCESS = 'PROJECTS_SUCCESS'; 6 | export const PROJECTS_FAILURE = 'PROJECTS_FAILURE'; 7 | 8 | /** 9 | * Initial state 10 | * @type {Object} 11 | */ 12 | const projectsState = { 13 | loading: false, 14 | projects: {} 15 | }; 16 | 17 | /** 18 | * Getters 19 | * @type {Object} 20 | */ 21 | const projectsGetters = { 22 | projects: state => state.projects, // eslint-disable-line no-confusing-arrow, max-len 23 | projectsTableData(state, getters) { 24 | if (Object.keys(getters.projects).length === 0) return false; 25 | return _map(getters.projects, project => project); // eslint-disable-line max-len 26 | } 27 | }; 28 | 29 | /** 30 | * Mutations 31 | * @type {Object} 32 | */ 33 | const mutations = { 34 | [PROJECTS_REQUEST]: (state) => { 35 | Object.assign(state, { loading: true }); 36 | }, 37 | [PROJECTS_SUCCESS]: (state, projects) => { 38 | Object.assign(state, { ...projects, loading: false }); 39 | }, 40 | [PROJECTS_FAILURE]: (state, err) => { 41 | console.log(PROJECTS_FAILURE, err); 42 | Object.assign(state, { loading: false }); 43 | } 44 | }; 45 | 46 | /** 47 | * Actions 48 | * @type {Object} 49 | */ 50 | const actions = { 51 | fetchProjects({ commit }) { 52 | commit(PROJECTS_REQUEST); 53 | 54 | return ProjectsService.get() 55 | .then((res) => { 56 | // console.log(res); 57 | commit(PROJECTS_SUCCESS, { projects: res.data.data }); 58 | }).catch((err) => { 59 | commit(PROJECTS_FAILURE, err); 60 | }); 61 | }, 62 | 63 | createProject({ commit }, data) { 64 | commit(PROJECTS_REQUEST); 65 | const obj = data; 66 | return ProjectsService.post(data.server, obj).then((res) => { 67 | // console.log(res); 68 | commit(PROJECTS_SUCCESS, res.data); 69 | }).catch((err) => { 70 | commit(PROJECTS_FAILURE, err); 71 | }); 72 | }, 73 | 74 | updateProject({ commit }, data) { 75 | commit(PROJECTS_REQUEST); 76 | const obj = data; 77 | const name = data.data.name; 78 | return ProjectsService.put(data.server, name, obj).then((res) => { 79 | // console.log(res); 80 | commit(PROJECTS_SUCCESS, res.data); 81 | }).catch((err) => { 82 | commit(PROJECTS_FAILURE, err); 83 | }); 84 | }, 85 | 86 | deleteProject({ commit }, data) { 87 | commit(PROJECTS_REQUEST); 88 | return ProjectsService.delete(data.server, data.name).then((res) => { 89 | commit(PROJECTS_SUCCESS, res.data); 90 | }).catch((err) => { 91 | commit(PROJECTS_FAILURE, err); 92 | }); 93 | } 94 | }; 95 | 96 | // Export module 97 | export default { 98 | state: projectsState, 99 | getters: projectsGetters, 100 | mutations, 101 | actions 102 | }; 103 | -------------------------------------------------------------------------------- /src/libraries/store/modules/requests.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { RequestsService } from '../../services'; 3 | import formatRequest from '../../utils/format/request'; 4 | 5 | export const REQUESTS_REQUEST = 'REQUESTS_REQUEST'; 6 | export const REQUESTS_SUCCESS = 'REQUESTS_SUCCESS'; 7 | export const REQUESTS_FAILURE = 'REQUESTS_FAILURE'; 8 | 9 | /** 10 | * Initial state 11 | * @type {Object} 12 | */ 13 | const requestsState = { 14 | requests: {}, 15 | loading: false 16 | }; 17 | 18 | /** 19 | * Getters 20 | * @type {Object} 21 | */ 22 | const requestsGetters = { 23 | requests: state => state.requests, 24 | request: state => id => state.requests[id], 25 | requestsTableData(state, getters) { 26 | // if (Object.keys(getters.requests).length === 0) return false; 27 | return _map(getters.requests, request => formatRequest(request)); // eslint-disable-line max-len 28 | } 29 | }; 30 | 31 | /** 32 | * Mutations 33 | * @type {Object} 34 | */ 35 | const mutations = { 36 | [REQUESTS_REQUEST]: (state) => { 37 | Object.assign(state, { loading: true }); 38 | }, 39 | [REQUESTS_SUCCESS]: (state, host) => { 40 | Object.assign(state, { ...host, loading: false }); 41 | }, 42 | [REQUESTS_FAILURE]: (state, err) => { 43 | console.log(REQUESTS_FAILURE, err); 44 | Object.assign(state, { loading: false }); 45 | } 46 | }; 47 | 48 | /** 49 | * Actions 50 | * @type {Object} 51 | */ 52 | const actions = { 53 | fetchRequests({ commit }) { 54 | commit(REQUESTS_REQUEST); 55 | 56 | return RequestsService.get() 57 | .then((res) => { 58 | res.requests = res.data.data; 59 | commit(REQUESTS_SUCCESS, res); 60 | }).catch((err) => { 61 | commit(REQUESTS_FAILURE, err); 62 | }); 63 | }, 64 | 65 | createRequests({ commit }, { action, message, status, meta_data, mail_message }) { 66 | commit(REQUESTS_REQUEST); 67 | // console.log(action + message + status); 68 | const obj = { 69 | data: { 70 | type: 'requests', 71 | action, 72 | message, 73 | status, 74 | meta_data, 75 | mail_message 76 | } 77 | }; 78 | console.log(obj); 79 | return RequestsService.request(obj).then((res) => { 80 | // console.log(res); 81 | commit(REQUESTS_SUCCESS, res.data); 82 | }).catch((err) => { 83 | commit(REQUESTS_FAILURE, err); 84 | }); 85 | }, 86 | 87 | changeRequests({ commit }, { id, message, status, mail_message }) { 88 | commit(REQUESTS_REQUEST); 89 | console.log(message + status); 90 | const obj = { 91 | data: { 92 | type: 'requests', 93 | message, 94 | status, 95 | mail_message 96 | } 97 | }; 98 | console.log(obj); 99 | return RequestsService.put(id, obj).then((res) => { 100 | console.log(res); 101 | commit(REQUESTS_SUCCESS, res.data); 102 | }).catch((err) => { 103 | commit(REQUESTS_FAILURE, err); 104 | }); 105 | }, 106 | 107 | deleteRequests({ commit }, id) { 108 | commit(REQUESTS_REQUEST); 109 | RequestsService.delete(id).then((res) => { 110 | commit(REQUESTS_SUCCESS, res); 111 | }).catch((err) => { 112 | commit(REQUESTS_FAILURE, err); 113 | }); 114 | } 115 | }; 116 | 117 | // Export module 118 | export default { 119 | state: requestsState, 120 | getters: requestsGetters, 121 | mutations, 122 | actions 123 | }; 124 | -------------------------------------------------------------------------------- /src/libraries/store/modules/servers.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { ServersService } from '../../services'; 3 | 4 | export const SERVERS_REQUEST = 'SERVERS_REQUEST'; 5 | export const SERVERS_SUCCESS = 'SERVERS_SUCCESS'; 6 | export const SERVERS_FAILURE = 'SERVERS_FAILURE'; 7 | 8 | /** 9 | * Initial state 10 | * @type {Object} 11 | */ 12 | const serversState = { 13 | loading: false, 14 | servers: {} 15 | }; 16 | 17 | /** 18 | * Getters 19 | * @type {Object} 20 | */ 21 | const serversGetters = { 22 | servers: state => state.servers, // eslint-disable-line no-confusing-arrow, max-len 23 | serversTableData(state, getters) { 24 | if (Object.keys(getters.servers).length === 0) return false; 25 | return _map(getters.servers, server => server); // eslint-disable-line max-len 26 | } 27 | }; 28 | 29 | /** 30 | * Mutations 31 | * @type {Object} 32 | */ 33 | const mutations = { 34 | [SERVERS_REQUEST]: (state) => { 35 | Object.assign(state, { loading: true }); 36 | }, 37 | [SERVERS_SUCCESS]: (state, servers) => { 38 | Object.assign(state, { ...servers, loading: false }); 39 | }, 40 | [SERVERS_FAILURE]: (state, err) => { 41 | console.log(SERVERS_FAILURE, err); 42 | Object.assign(state, { loading: false }); 43 | } 44 | }; 45 | 46 | /** 47 | * Actions 48 | * @type {Object} 49 | */ 50 | const actions = { 51 | fetchServers({ commit }) { 52 | commit(SERVERS_REQUEST); 53 | 54 | return ServersService.get() 55 | .then((res) => { 56 | // console.log(res); 57 | commit(SERVERS_SUCCESS, { servers: res.data.data }); 58 | }).catch((err) => { 59 | commit(SERVERS_FAILURE, err); 60 | }); 61 | }, 62 | 63 | createServer({ commit }, data) { 64 | commit(SERVERS_REQUEST); 65 | const obj = data; 66 | // console.log(obj); 67 | return ServersService.post(obj).then((res) => { 68 | // console.log(res); 69 | commit(SERVERS_SUCCESS, res.data); 70 | }).catch((err) => { 71 | commit(SERVERS_FAILURE, err); 72 | }); 73 | }, 74 | 75 | updateServer({ commit }, data) { 76 | commit(SERVERS_REQUEST); 77 | const obj = data; 78 | const name = data.data.name; 79 | return ServersService.put(name, obj).then((res) => { 80 | // console.log(res); 81 | commit(SERVERS_SUCCESS, res.data); 82 | }).catch((err) => { 83 | commit(SERVERS_FAILURE, err); 84 | }); 85 | }, 86 | 87 | deleteServer({ commit }, name) { 88 | commit(SERVERS_REQUEST); 89 | return ServersService.delete(name).then((res) => { 90 | commit(SERVERS_SUCCESS, res.data); 91 | }).catch((err) => { 92 | commit(SERVERS_FAILURE, err); 93 | }); 94 | } 95 | }; 96 | 97 | // Export module 98 | export default { 99 | state: serversState, 100 | getters: serversGetters, 101 | mutations, 102 | actions 103 | }; 104 | -------------------------------------------------------------------------------- /src/libraries/store/modules/stats.js: -------------------------------------------------------------------------------- 1 | import { StatsService } from '../../services'; 2 | 3 | const statsId = 1; 4 | 5 | export const STATS_REQUEST = 'STATS_REQUEST'; 6 | export const STATS_SUCCESS = 'STATS_SUCCESS'; 7 | export const STATS_FAILURE = 'STATS_FAILURE'; 8 | 9 | /** 10 | * Initial state 11 | * @type {Object} 12 | */ 13 | const statsState = { 14 | loading: false, 15 | stats: {} 16 | }; 17 | 18 | /** 19 | * Getters 20 | * @type {Object} 21 | */ 22 | const statsGetters = { 23 | stats: state => state.stats[statsId] ? state.stats[statsId].attributes : state.stats, // eslint-disable-line no-confusing-arrow, max-len 24 | statsTotalMemory: (state, getters) => (getters.stats.memory && getters.stats.memory) || 0, // eslint-disable-line max-len 25 | statsTotalDisk: (state, getters) => (getters.stats.disk && getters.stats.disk[0]) || 0, 26 | statsCPUs: (state, getters) => (getters.stats.cpu && getters.stats.cpu.physical) || 0 27 | }; 28 | 29 | /** 30 | * Mutations 31 | * @type {Object} 32 | */ 33 | const mutations = { 34 | [STATS_REQUEST]: (state) => { 35 | Object.assign(state, { loading: true }); 36 | }, 37 | [STATS_SUCCESS]: (state, stats) => { 38 | Object.assign(state, { ...stats, loading: false }); 39 | }, 40 | [STATS_FAILURE]: (state, err) => { 41 | console.log(STATS_FAILURE, err); 42 | Object.assign(state, { loading: false }); 43 | } 44 | }; 45 | 46 | /** 47 | * Actions 48 | * @type {Object} 49 | */ 50 | const actions = { 51 | fetchStats({ commit }) { 52 | commit(STATS_REQUEST); 53 | 54 | return StatsService.get() 55 | .then((res) => { 56 | // console.log(res); 57 | commit(STATS_SUCCESS, { stats: res.data.data }); 58 | }).catch((err) => { 59 | commit(STATS_FAILURE, err); 60 | }); 61 | } 62 | }; 63 | 64 | // Export module 65 | export default { 66 | state: statsState, 67 | getters: statsGetters, 68 | mutations, 69 | actions 70 | }; 71 | -------------------------------------------------------------------------------- /src/libraries/store/modules/users.js: -------------------------------------------------------------------------------- 1 | import _map from 'lodash/map'; 2 | import { MeService, UsersService } from '../../services'; 3 | import formatUser from '../../utils/format/user'; 4 | import { formatCreateUser, formatUpdateUser } from '../../utils/format/userActions'; 5 | import storage from '../../utils/storage'; 6 | import i18n from '../../i18n'; 7 | 8 | export const USERS_REQUEST = 'USERS_REQUEST'; 9 | export const USERS_SUCCESS = 'USERS_SUCCESS'; 10 | export const USERS_FAILURE = 'USERS_FAILURE'; 11 | export const ME_SUCCESS = 'ME_SUCCESS'; 12 | export const SET_OTP_SECRET = 'SET_OTP_SECRET'; 13 | 14 | export const STORAGE_USERS_KEY = 'STORAGE_USERS'; 15 | export const STORAGE_LANGUAGE_KEY = 'STORAGE_LANGUAGE'; 16 | 17 | const storedUsers = storage.get(STORAGE_USERS_KEY); 18 | const storedLanguage = storage.get(STORAGE_LANGUAGE_KEY); 19 | /** 20 | * Initial state 21 | * @type {Object} 22 | */ 23 | const usersState = { 24 | // instances: storedInstances || [], 25 | users: storedUsers || [], 26 | myself: {}, 27 | language: storedLanguage || 'en', 28 | otp: {}, 29 | loading: false 30 | }; 31 | 32 | /** 33 | * Getters 34 | * @type {Object} 35 | */ 36 | const usersGetters = { 37 | myself: state => state.myself, 38 | language: state => state.language, 39 | users: state => state.users, 40 | user: state => id => state.users[id], 41 | usersTableData(state, getters) { 42 | if (Object.keys(getters.users).length === 0) return false; 43 | return _map(getters.users, user => formatUser(user)); // eslint-disable-line max-len 44 | } 45 | }; 46 | 47 | /** 48 | * Mutations 49 | * @type {Object} 50 | */ 51 | const usersMutations = { 52 | [USERS_REQUEST]: (state) => { 53 | Object.assign(state, { loading: true }); 54 | }, 55 | [USERS_SUCCESS]: (state, users) => { 56 | Object.assign(state, { ...users, loading: false }); 57 | storage.set(STORAGE_USERS_KEY, users.users); 58 | }, 59 | [USERS_FAILURE]: (state, err) => { 60 | // console.log(USERS_FAILURE, err); 61 | Object.assign(state, { loading: false, status: err }); 62 | storage.remove(STORAGE_USERS_KEY); 63 | }, 64 | [ME_SUCCESS]: (state, myself) => { 65 | Object.assign(state, { myself, loading: false }); 66 | // console.log(myself); 67 | storage.set(STORAGE_LANGUAGE_KEY, myself.language); 68 | }, 69 | [SET_OTP_SECRET]: (state, otp) => { 70 | Object.assign(state, { otp, loading: false }); 71 | } 72 | }; 73 | 74 | /** 75 | * Actions 76 | * @type {Object} 77 | */ 78 | const usersActions = { 79 | fetchMe({ commit }) { 80 | commit(USERS_REQUEST); 81 | 82 | MeService.get().then((res) => { 83 | i18n.locale = res.data.data.language; 84 | commit(ME_SUCCESS, res.data.data); 85 | }).catch((err) => { 86 | commit(USERS_FAILURE, err); 87 | }); 88 | }, 89 | 90 | fetchUsers({ commit }) { 91 | commit(USERS_REQUEST); 92 | 93 | UsersService.get().then((res) => { 94 | // console.log(res); 95 | res.users = res.data.data; 96 | commit(USERS_SUCCESS, res); 97 | }).catch((err) => { 98 | commit(USERS_FAILURE, err); 99 | }); 100 | }, 101 | 102 | createUser({ commit }, data) { 103 | commit(USERS_REQUEST); 104 | // console.log(data); 105 | const obj = formatCreateUser(data); 106 | // console.log(obj); 107 | return UsersService.post(obj).then((res) => { 108 | // console.log(res); 109 | commit(USERS_SUCCESS, res.data.data); 110 | }).catch((err) => { 111 | commit(USERS_FAILURE, err); 112 | }); 113 | }, 114 | 115 | updateUser({ commit }, data) { 116 | commit(USERS_REQUEST); 117 | // console.log('update log:'); 118 | // console.log(data); 119 | 120 | const obj = formatUpdateUser(data); 121 | // console.log(obj); 122 | return UsersService.put(data.id, obj).then((res) => { 123 | // console.log(res); 124 | commit(USERS_SUCCESS, res.data); 125 | }).catch((err) => { 126 | commit(USERS_FAILURE, err); 127 | }); 128 | }, 129 | 130 | updateMe({ commit }, data) { 131 | commit(USERS_REQUEST); 132 | 133 | const obj = { data }; 134 | obj.data.type = 'users'; 135 | obj.data.postal_code = data.postal_code; 136 | 137 | return MeService.put(obj).then((res) => { 138 | // console.log(res); 139 | commit(USERS_SUCCESS, res.data); 140 | }).catch((err) => { 141 | commit(USERS_FAILURE, err); 142 | }); 143 | }, 144 | 145 | otpMe({ commit }) { 146 | commit(USERS_REQUEST); 147 | MeService.otp().then((res) => { 148 | // console.log(res.otp[0].attributes); 149 | res.otp = res.data.data; 150 | commit(SET_OTP_SECRET, res.otp); 151 | }).catch((err) => { 152 | commit(USERS_FAILURE, err); 153 | }); 154 | }, 155 | 156 | deleteUser({ commit }, id) { 157 | commit(USERS_REQUEST); 158 | UsersService.delete(id).then((res) => { 159 | commit(USERS_SUCCESS, res); 160 | }).catch((err) => { 161 | commit(USERS_FAILURE, err); 162 | }); 163 | } 164 | }; 165 | 166 | // Export module 167 | export default { 168 | state: usersState, 169 | getters: usersGetters, 170 | mutations: usersMutations, 171 | actions: usersActions 172 | }; 173 | -------------------------------------------------------------------------------- /src/libraries/store/mutations.js: -------------------------------------------------------------------------------- 1 | import { axios, storage } from '../utils'; 2 | 3 | /** 4 | * 5 | * @param {Object} state Vuex 6 | * @param {Object} session 7 | */ 8 | export const CHANGE_SESSION = (state, session) => { 9 | if (session && session.token) { 10 | // change axios authorization header 11 | axios.defaults.headers.Authorization = `Bearer ${session.token}`; 12 | } 13 | // TODO: new session mixin 14 | Object.assign(state.session, session); 15 | storage.set('SESSION_TOKEN_KEY', state.session); 16 | }; 17 | 18 | /** 19 | * 20 | * @param {Object} state Vuex 21 | */ 22 | export const TOGGLE_SIDEBAR_COLLAPSE = (state) => { 23 | state.sidebar.collapse = !state.sidebar.collapse; // eslint-disable-line no-param-reassign 24 | storage.set('wedn_net_sidebar_collapse', state.sidebar.collapse); 25 | }; 26 | 27 | export const CLOSE_DIALOG = (state) => { 28 | state.dialog = { // eslint-disable-line no-param-reassign 29 | active: false, 30 | containerId: null, 31 | instanceId: null 32 | }; 33 | }; 34 | 35 | export const OPEN_DIALOG = (state, id) => { 36 | state.dialog = { // eslint-disable-line no-param-reassign 37 | active: true, 38 | instanceId: id 39 | }; 40 | }; 41 | 42 | /** 43 | * 44 | * @param {Object} state Vuex 45 | */ 46 | export const APP_LOAD = (state) => { 47 | state.initialized = true; // eslint-disable-line no-param-reassign 48 | }; 49 | -------------------------------------------------------------------------------- /src/libraries/store/state.js: -------------------------------------------------------------------------------- 1 | // import { axios } from '../utils'; 2 | 3 | const state = { 4 | initiliazed: false, 5 | dialog: { 6 | active: false, 7 | instanceId: null 8 | } 9 | }; 10 | 11 | export default state; 12 | -------------------------------------------------------------------------------- /src/libraries/utils/auth/abilities.js: -------------------------------------------------------------------------------- 1 | // import _reduce from 'lodash/reduce'; 2 | // import build from 'redux-object'; 3 | 4 | const getUserAbilities = (state) => { 5 | const user = state.myself; 6 | const abilities = []; 7 | // console.log(user); 8 | if (Object.keys(user).length !== 0 && user.relationships.groups) { 9 | const abbs = state.groups[0].relationships.abilities; 10 | abbs.forEach((ability) => { 11 | if (ability && ability.name) { 12 | if (abilities.indexOf(ability.name) === -1) { 13 | abilities.push(ability.name); 14 | } 15 | } 16 | }); 17 | return abilities; 18 | } 19 | return []; 20 | }; 21 | 22 | export default getUserAbilities; 23 | -------------------------------------------------------------------------------- /src/libraries/utils/auth/groups.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | // import build from 'redux-object'; 3 | 4 | const getUserGroups = (state, identity) => { 5 | // const user = build(state, 'users', identity); 6 | // console.log(user); 7 | // let groups = []; 8 | 9 | // if (user && user.groups && user.groups[0]) { 10 | // groups = _map(user.groups, group => group.name); 11 | // } 12 | 13 | // return groups; 14 | return []; 15 | }; 16 | 17 | export default getUserGroups; 18 | -------------------------------------------------------------------------------- /src/libraries/utils/auth/index.js: -------------------------------------------------------------------------------- 1 | import getUserAbilities from './abilities'; 2 | import getUserGroups from './groups'; 3 | 4 | export { 5 | getUserAbilities, 6 | getUserGroups 7 | }; 8 | -------------------------------------------------------------------------------- /src/libraries/utils/axios.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-len */ 2 | import axios from 'axios'; 3 | // import normalize from 'json-api-normalizer'; 4 | import storage from './storage'; 5 | import { STORAGE_TOKEN_KEY, STORAGE_REFRESH_TOKEN_KEY } from '../store/modules/auth'; 6 | // import { STORAGE_REQUEST_TOKEN_KEY } from '../store/modules/auth'; 7 | import router from '../router'; 8 | 9 | // Vue.prototype.$URL 10 | axios.get('static/config.json').then((response) => { 11 | const API_BASE_URL = `${response.data.API_BASE_URL}/api/v1`; 12 | const API_BASE_WS_URL = `${response.data.API_BASE_WS_URL}`; 13 | storage.set('API_BASE_URL', API_BASE_URL); 14 | storage.set('API_BASE_WS_URL', API_BASE_WS_URL); 15 | }); 16 | 17 | 18 | const instance = axios.create({ 19 | // baseURL: process.env.API_BASE_URL || '', 20 | baseURL: storage.get('API_BASE_URL') || process.env.API_BASE_URL, 21 | timeout: 50000, 22 | headers: { 23 | 'Content-Type': 'application/json', 24 | 'X-Requested-With': 'XMLHttpRequest' 25 | } 26 | }); 27 | 28 | // Redirect to '/login' if API returns 401 29 | instance.interceptors.response.use((response) => { 30 | // console.log(response); 31 | // const res = response.config.url.includes('auth') || response.config.url.includes('users') || response.config.url.includes('me') || response.config.url.includes('abilities') || response.config.url.includes('groups') || response.config.url.includes('containers') || response.config.url.includes('requests') || response.config.url.includes('operations') || response.config.url.includes('resources') || response.config.url.includes('stats') || response.config.url.includes('lxdconfig') || response.config.url.includes('images') ? response : normalize(response.data, { camelizeKeys: false }); 32 | // const res = response.config.url.includes('auth') ? response : normalize(response.data, { camelizeKeys: false }); 33 | // const res = response.config.url.includes('auth') ? response : response.data; 34 | // console.log(res); 35 | const res = response; 36 | return res; 37 | }, (err) => { 38 | console.log('[AXIOS:response:error]', err, err.response); 39 | 40 | if (err.response.status && err.response.status === 401) { 41 | console.log('⛔️ Unauthorized'); 42 | 43 | storage.remove(STORAGE_TOKEN_KEY); 44 | storage.remove(STORAGE_REFRESH_TOKEN_KEY); 45 | 46 | // router.replace({ name: 'login', query: { redirect: router.currentRoute.fullPath } }); 47 | router.replace({ name: 'login' }); 48 | } 49 | 50 | return Promise.reject(err); 51 | }); 52 | 53 | // Set 'Authorization' header 54 | instance.interceptors.request.use((requestConfig) => { 55 | const token = storage.get(STORAGE_TOKEN_KEY); 56 | 57 | const config = requestConfig; 58 | const headers = requestConfig.headers || {}; 59 | config.headers = headers; 60 | 61 | if (token !== null && token !== 'undefined' && typeof token !== 'undefined') { 62 | headers.Authorization = `Bearer ${token}`; 63 | } 64 | 65 | return config; 66 | }); 67 | 68 | export default instance; 69 | -------------------------------------------------------------------------------- /src/libraries/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const UNLIMITED = 'unlimited'; 2 | 3 | export default {}; 4 | -------------------------------------------------------------------------------- /src/libraries/utils/format/images.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | 3 | export default function images(data) { 4 | // return first non empty alias name 5 | const alias = data.aliases.find(el => el.name !== ''); 6 | return { 7 | // id: data.id, 8 | name: alias ? alias.name : '', 9 | alias_description: alias ? alias.description : '', 10 | fingerprint: data.fingerprint.substring(0, 12), 11 | public: data.public, 12 | description: data.properties.description, 13 | architecture: data.architecture, 14 | type: data.type, 15 | size: data.size, 16 | uploaded_at: data.uploaded_at, 17 | relationships: data.relationships 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /src/libraries/utils/format/instance.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | // import formatMemoryLimit from './memoryLimit'; 3 | // import formatCPUs from './cpus'; 4 | import { KMGBToB, BToGB, BToGiB, BToMB, BToMiB } from '../helpers'; 5 | 6 | export default function instance(ct) { 7 | // console.log(ct); 8 | const status = ct.status.toUpperCase(); 9 | 10 | let limitsMemoryRaw = null; 11 | if (ct.expanded_config['limits.memory']) { 12 | const value = ct.expanded_config['limits.memory'].match(/\d+/g)[0]; 13 | const size = ct.expanded_config['limits.memory'].match(/[a-zA-Z]+/g)[0]; 14 | limitsMemoryRaw = KMGBToB(value, size); 15 | } 16 | 17 | let limitsDiskRaw = null; 18 | if (ct.expanded_devices.root.size) { 19 | const value = ct.expanded_devices.root.size.match(/\d+/g)[0]; 20 | const size = ct.expanded_devices.root.size.match(/[a-zA-Z]+/g)[0]; 21 | limitsDiskRaw = KMGBToB(value, size); 22 | } 23 | let diskSize = null; 24 | if (ct.expanded_devices.root.size) { 25 | diskSize = ct.expanded_devices.root.size; 26 | } 27 | // console.log(ct.attributes.config['limits.memory'].match(/\d+/g)[0]); 28 | // console.log(ct.attributes.config['limits.memory'].match(/[a-zA-Z]+/g)[0]); 29 | // limitsMemoryRaw = ct.attributes.config['limits.memory'] 30 | // ? ct.attributes.config['limits.memory'].match(/\d+/g)[0] : null; 31 | // const limitsDiskRaw = ct.attributes.config.limits_memory.match(/\d+/g); 32 | 33 | let ips = ''; 34 | if (ct.state.network) { 35 | ips = !ct.state.network.eth0 || status === 'STOPPED' ? '' : ct.state.network.eth0.addresses; 36 | } 37 | 38 | // const regex = new RegExp('/b?vethb?', 'g'); 39 | // if (ct.state.network) { 40 | // const filtered = Object.entries(ct.state.network) 41 | // .filter(network => network[0].match('eth0')) 42 | // .map(net => { net[0]: net[1] }); 43 | // const filtered = ct.state.network; // .filter(network => network.match(regex)); 44 | // console.log(Object.fromEntries(filtered)); 45 | // } 46 | 47 | return { 48 | state: ct.state, 49 | status, 50 | id: ct.id, 51 | name: ct.name, 52 | type: ct.type, 53 | created_at: ct.created_at, 54 | servers: ct.relationships.servers, 55 | ips, 56 | config: { 57 | image_description: ct.expanded_config['image.description'], 58 | image_architecture: ct.expanded_config['image.architecture'], 59 | image_release: ct.expanded_config['image.release'], 60 | image_os: ct.expanded_config['image.os'], 61 | image_version: ct.expanded_config['image.version'], 62 | limits_cpu: ct.expanded_config['limits.cpu'], 63 | limits_memory: ct.expanded_config['limits.memory'], 64 | limits_memory_raw: limitsMemoryRaw, 65 | limits_memory_mb: BToMB(limitsMemoryRaw), 66 | limits_memory_mib: BToMiB(limitsMemoryRaw), 67 | // eslint-disable-next-line max-len,no-nested-ternary 68 | limits_disk: diskSize, 69 | limits_disk_raw: limitsDiskRaw, 70 | limits_disk_gb: BToGB(limitsDiskRaw), 71 | limits_disk_gib: BToGiB(limitsDiskRaw), 72 | user_price: ct.config['user.price'], 73 | user_terminal: ct.expanded_config['user.terminal'] 74 | } 75 | }; 76 | } 77 | -------------------------------------------------------------------------------- /src/libraries/utils/format/memoryLimit.js: -------------------------------------------------------------------------------- 1 | import { humanFileSize } from '../helpers'; 2 | import I18n from '../../i18n'; 3 | 4 | export default function memoryLimit(value, hostValue) { 5 | if (!value || !isNaN(value)) return I18n.t('unlimited'); 6 | 7 | return value > hostValue ? I18n.t('unlimited') : humanFileSize(value); 8 | } 9 | -------------------------------------------------------------------------------- /src/libraries/utils/format/request.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | 3 | export default function request(data) { 4 | // console.log(data); 5 | return { 6 | id: data.id, 7 | action: data.action, 8 | message: data.message, 9 | status: data.status, 10 | meta_data: data.meta_data, 11 | created_on: data.created_on, 12 | changed_on: data.changed_on, 13 | // eslint-disable-next-line max-len 14 | last_change: data.changed_on ? data.changed_on : data.created_on, 15 | users: data.relationships.users 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /src/libraries/utils/format/stats.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | // import formatMemoryLimit from './memoryLimit'; 3 | // import formatCPUs from './cpus'; 4 | // import { KMGBToB, BToGB, BToGiB, BToMB, BToMiB } from '../helpers'; 5 | 6 | export default function stats(instances) { 7 | // console.log(instances); 8 | const instancesTotal = (instances.length); 9 | 10 | const instancesRunning = instances.filter(word => word.status === 'RUNNING').length; 11 | // console.log(instancesRunning); 12 | 13 | function stringToFloat(x) { 14 | const parsed = parseFloat(x, 10); 15 | if (isNaN(parsed)) { return 0; } 16 | return parsed; 17 | } 18 | 19 | const cpuTotal = instances.reduce((prev, cur) => prev + stringToFloat(cur.config.limits_cpu), 0); 20 | // console.log(cpuTotal); 21 | 22 | const memoryTotalRaw = instances.reduce( 23 | (prev, cur) => prev + stringToFloat(cur.config.limits_memory_raw), 0); 24 | // console.log(memoryTotalRaw); 25 | 26 | const diskTotalRaw = instances.reduce( 27 | (prev, cur) => prev + stringToFloat(cur.config.limits_disk_raw), 0); 28 | // console.log(diskTotalRaw); 29 | 30 | const priceTotal = instances.reduce( 31 | (prev, cur) => prev + stringToFloat(cur.config.user_price), 0); 32 | // console.log(priceTotal); 33 | 34 | return { 35 | instancesTotal, 36 | instancesRunning, 37 | cpuTotal, 38 | memoryTotalRaw, 39 | diskTotalRaw, 40 | priceTotal 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /src/libraries/utils/format/user.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | 3 | export default function user(us) { 4 | // console.log(us); 5 | return { 6 | id: us.id, 7 | username: us.username, 8 | email: us.email, 9 | name: us.name, 10 | phone: us.phone, 11 | address: us.address, 12 | city: us.city, 13 | country: us.country, 14 | postal_code: us.postal_code, 15 | ico: us.ico, 16 | ic_dph: us.ic_dph, 17 | dic: us.dic, 18 | language: us.language, 19 | registered_on: us.registered_on, 20 | otp_enabled: us.otp_enabled, 21 | otp_type: us.otp_type, 22 | admin: us.admin, 23 | instances: us.relationships.instances.map(instance => instance), 24 | groups: us.relationships.groups.map(group => group) 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/libraries/utils/format/userActions.js: -------------------------------------------------------------------------------- 1 | // import _map from 'lodash/map'; 2 | 3 | const formatCreateUser = (data) => { 4 | const obj = { 5 | data: { 6 | type: 'users', 7 | id: data.id, 8 | username: data.username, 9 | name: data.name, 10 | email: data.email, 11 | relationships: { 12 | groups: data.groups ? data.groups.map(g => ({ 13 | type: 'groups', 14 | id: g.id ? g.id : g 15 | })) : [ 16 | { 17 | type: 'groups', 18 | id: 2 19 | } 20 | ], 21 | instances: data.instances ? data.instances.map(c => ({ 22 | type: 'instances', 23 | id: c.id ? c.id : c 24 | })) : [] 25 | } 26 | } 27 | }; 28 | if (data.password !== '' && data.password) { 29 | obj.data.password = data.password; 30 | } 31 | if (data.phone !== '' && data.phone) { 32 | obj.data.phone = data.phone; 33 | } 34 | if (data.address !== '' && data.address) { 35 | obj.data.address = data.address; 36 | } 37 | if (data.city !== '' && data.city) { 38 | obj.data.city = data.city; 39 | } 40 | if (data.country !== '' && data.country) { 41 | obj.data.country = data.country; 42 | } 43 | if (data.postal_code !== '' && data.postal_code) { 44 | obj.data.postal_code = data.postal_code; 45 | } 46 | if (data.ico !== '' && data.ico) { 47 | obj.data.ico = data.ico; 48 | } 49 | if (data.ic_dph !== '' && data.ic_dph) { 50 | obj.data.ic_dph = data.ic_dph; 51 | } 52 | if (data.dic !== '' && data.dic) { 53 | obj.data.dic = data.dic; 54 | } 55 | if (data.language !== '' && data.language) { 56 | obj.data.language = data.language; 57 | } 58 | if (data.otp_type !== '' && data.otp_type) { 59 | obj.data.otp_type = data.otp_type; 60 | } 61 | return obj; 62 | }; 63 | 64 | const formatUpdateUser = (data) => { 65 | const obj = { 66 | data: { 67 | type: 'users', 68 | id: data.id, 69 | username: data.username, 70 | name: data.name, 71 | email: data.email, 72 | relationships: { 73 | groups: data.groups ? data.groups.map(g => ({ 74 | id: g.id ? g.id : g 75 | })) : [ 76 | { 77 | id: 2, 78 | name: 'user' 79 | } 80 | ], 81 | instances: data.instances ? data.instances.map(c => ({ 82 | id: c.id ? c.id : c 83 | })) : [] 84 | } 85 | } 86 | }; 87 | if (data.password !== '' && data.password) { 88 | obj.data.password = data.password; 89 | } 90 | if (data.phone !== '' && data.phone) { 91 | obj.data.phone = data.phone; 92 | } 93 | if (data.address !== '' && data.address) { 94 | obj.data.address = data.address; 95 | } 96 | if (data.city !== '' && data.city) { 97 | obj.data.city = data.city; 98 | } 99 | if (data.country !== '' && data.country) { 100 | obj.data.country = data.country; 101 | } 102 | if (data.postal_code !== '' && data.postal_code) { 103 | obj.data.postal_code = data.postal_code; 104 | } 105 | if (data.ico !== '' && data.ico) { 106 | obj.data.ico = data.ico; 107 | } 108 | if (data.ic_dph !== '' && data.ic_dph) { 109 | obj.data.ic_dph = data.ic_dph; 110 | } 111 | if (data.dic !== '' && data.dic) { 112 | obj.data.dic = data.dic; 113 | } 114 | if (data.language !== '' && data.language) { 115 | obj.data.language = data.language; 116 | } 117 | if (data.otp_type !== '' && data.otp_type) { 118 | obj.data.otp_type = data.otp_type; 119 | } 120 | return obj; 121 | }; 122 | 123 | export { 124 | formatCreateUser, 125 | formatUpdateUser 126 | }; 127 | -------------------------------------------------------------------------------- /src/libraries/utils/helpers.js: -------------------------------------------------------------------------------- 1 | const humanFileSize = (bytes) => { 2 | if (!bytes) return 0; 3 | 4 | const i = Math.floor(Math.log(bytes) / Math.log(1000)); 5 | return `${((bytes / (1000 ** i)).toFixed(2) * 1)} ${['B', 'kB', 'MB', 'GB', 'TB', 'PB'][i]}`; 6 | }; 7 | 8 | const hBinaryPrefix = (bytes, unit, show) => { 9 | if (!bytes) return 0; 10 | let i = 0; 11 | let value = 0; 12 | 13 | if (unit === 'MiB' || unit === 'GiB') { 14 | i = Math.floor(Math.log(bytes) / Math.log(1024)); 15 | value = ((bytes / (1024 ** i)).toFixed(2) * 1); 16 | } else { 17 | i = Math.floor(Math.log(bytes) / Math.log(1000)); 18 | value = ((bytes / (1000 ** i)).toFixed(2) * 1); 19 | } 20 | 21 | if (show === 'MiB' || show === 'GiB') { 22 | return [value, ['B', 'kiB', 'MiB', 'GiB', 'TiB', 'PiB'][i]]; 23 | } 24 | return [value, ['B', 'kB', 'MB', 'GB', 'TB', 'PB'][i]]; 25 | }; 26 | 27 | const BToMB = (bytes) => { 28 | if (!bytes) return null; 29 | 30 | return `${(bytes / 1000 / 1000).toFixed(0)}`; 31 | }; 32 | 33 | const BToMiB = (bytes) => { 34 | if (!bytes) return null; 35 | 36 | return `${(bytes / 1024 / 1024).toFixed(0)}`; 37 | }; 38 | 39 | const BToGB = (bytes) => { 40 | if (!bytes) return null; 41 | 42 | return `${(bytes / 1000 / 1000 / 1000).toFixed(2)}`; 43 | }; 44 | 45 | const BToGiB = (bytes) => { 46 | if (!bytes) return null; 47 | 48 | return `${(bytes / 1024 / 1024 / 1024).toFixed(2)}`; 49 | }; 50 | 51 | 52 | const KMGBToB = (value, size) => { 53 | if (!value) return null; 54 | 55 | if (size === 'KB') { 56 | return value * 1000; 57 | } 58 | if (size === 'MB') { 59 | return value * 1000 * 1000; 60 | } 61 | if (size === 'GB') { 62 | return value * 1000 * 1000 * 1000; 63 | } 64 | if (size === 'KiB') { 65 | return value * 1024; 66 | } 67 | if (size === 'MiB') { 68 | return value * 1024 * 1024; 69 | } 70 | if (size === 'GiB') { 71 | return value * 1024 * 1024 * 1024; 72 | } 73 | return null; 74 | }; 75 | 76 | const updateInstanceState = (action) => { 77 | const data = { 78 | data: { 79 | action, 80 | timeout: 30, 81 | force: false 82 | } 83 | }; 84 | return data; 85 | }; 86 | 87 | export { 88 | BToMB, 89 | BToMiB, 90 | BToGB, 91 | BToGiB, 92 | KMGBToB, 93 | humanFileSize, 94 | hBinaryPrefix, 95 | updateInstanceState 96 | }; 97 | -------------------------------------------------------------------------------- /src/libraries/utils/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Utils 3 | */ 4 | 5 | import axios from './axios'; 6 | import storage from './storage'; 7 | 8 | export { 9 | axios, 10 | storage 11 | }; 12 | -------------------------------------------------------------------------------- /src/libraries/utils/states.js: -------------------------------------------------------------------------------- 1 | export const ALL = 'ALL'; 2 | export const FROZEN = 'FROZEN'; 3 | export const FREEZING = 'FREEZING'; 4 | export const RESTARTING = 'RESTARTING'; 5 | export const RUNNING = 'RUNNING'; 6 | export const SHUTTING_DOWN = 'SHUTTING_DOWN'; 7 | export const STARTING = 'STARTING'; 8 | export const STOPPED = 'STOPPED'; 9 | export const STOPPING = 'STOPPING'; 10 | export const UNFREEZING = 'UNFREEZING'; 11 | 12 | const transitioning = (state) => { // eslint-disable-line arrow-body-style 13 | return state === FREEZING 14 | || state === RESTARTING 15 | || state === SHUTTING_DOWN 16 | || state === STOPPING 17 | || state === STARTING 18 | || state === UNFREEZING; 19 | }; 20 | 21 | export { 22 | transitioning 23 | }; 24 | -------------------------------------------------------------------------------- /src/libraries/utils/storage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Storage 3 | * > - https://github.com/marcuswestin/store.js 4 | * > - https://github.com/marcuswestin/store.js#make-your-own-build 5 | * @example 6 | * import storage from './storage' 7 | * storage.get( ... ) 8 | * storage.set( ... ) 9 | * storage.remove( ... ) 10 | * storage.clearAll() 11 | * storage.each( ... ) 12 | */ 13 | 14 | import store from 'store'; 15 | 16 | export default store; 17 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import './libraries/utils/axios' 3 | import plugins from './libraries/plugins/index' 4 | import App from './App.vue' 5 | import vuetify from './plugins/vuetify' 6 | import router from './libraries/router' 7 | import store from './libraries/store/index' 8 | import i18n from './libraries/i18n/index' 9 | // import Vuex from './libraries/store/index' 10 | // import Layout from './layouts/Layout.vue' 11 | 12 | // Vue.component('Layout', Layout) 13 | 14 | Vue.config.productionTip = false 15 | 16 | Vue.use(plugins); 17 | 18 | new Vue({ 19 | vuetify, 20 | i18n, 21 | store, 22 | router, 23 | render: h => h(App) 24 | }).$mount('#app') 25 | -------------------------------------------------------------------------------- /src/plugins/vuetify.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuetify from 'vuetify/lib/framework'; 3 | // import 'vuetify/dist/vuetify.min.css'; 4 | // import '@mdi/font/css/materialdesignicons.css' 5 | 6 | Vue.use(Vuetify); 7 | 8 | export default new Vuetify({ 9 | icons: { 10 | iconfont: 'mdi', // default - only for display purposes 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/views/layouts/Error.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /src/views/layouts/Layout.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 140 | 141 | -------------------------------------------------------------------------------- /src/views/pages/AppConfig.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Dashboard.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 41 | -------------------------------------------------------------------------------- /src/views/pages/Groups.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Help.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Images.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Instance.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 23 | -------------------------------------------------------------------------------- /src/views/pages/Instances.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 23 | -------------------------------------------------------------------------------- /src/views/pages/Networks.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Profiles.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Projects.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Requests.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Settings.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /src/views/pages/Users.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transpileDependencies: [ 3 | 'vuetify' 4 | ], 5 | 6 | lintOnSave: false 7 | } 8 | --------------------------------------------------------------------------------