├── theme ├── submenu.css ├── tab-pane.css ├── button-group.css ├── collapse-item.css ├── dropdown-item.css ├── dropdown-menu.css ├── form-item.css ├── menu-item.css ├── breadcrumb-item.css ├── checkbox-button.css ├── checkbox-group.css ├── infinite-scroll.css ├── infiniteScroll.css ├── menu-item-group.css ├── fonts │ ├── element-icons.ttf │ └── element-icons.woff ├── element-variables.css └── aside.css ├── src ├── .eslintignore ├── assets │ ├── css │ │ ├── index.scss │ │ ├── variable.scss │ │ └── element-ui_reset.scss │ ├── iconfont │ │ ├── iconfont.eot │ │ ├── iconfont.ttf │ │ └── iconfont.woff │ └── images │ │ └── dot.svg ├── service │ ├── module │ │ ├── global.js │ │ ├── jobs.js │ │ ├── datacatelog.js │ │ ├── user.js │ │ ├── settings.js │ │ ├── schedules.js │ │ ├── workflow.js │ │ └── notebook.js │ ├── index.js │ └── handleService.js ├── icons │ ├── svg │ │ ├── node_train_24.svg │ │ ├── node_save_24.svg │ │ ├── node_register_24.svg │ │ ├── node_predict_24.svg │ │ ├── node_linearregression_24.svg │ │ ├── node_jsonexpandext_24.svg │ │ ├── node_logisticregression_24.svg │ │ ├── node_naivebayes_24.svg │ │ ├── nav_monitor_24.svg │ │ ├── node_syntaxanalyzeext_24.svg │ │ ├── node_select_24.svg │ │ ├── nav_homepage_24.svg │ │ ├── node_runscript_24.svg │ │ ├── schedule_update.svg │ │ ├── node_vecmapinplace_24.svg │ │ ├── nav_workspace_24.svg │ │ ├── node_tablerepartition_24.svg │ │ ├── file_notebook_16.svg │ │ ├── node_kmeans_24.svg │ │ ├── node_alsinplace_24.svg │ │ ├── nav_process_24.svg │ │ ├── node_randomforest_24.svg │ │ ├── node_normalizeinplace_24.svg │ │ ├── file_workflow_16.svg │ │ ├── node_ratesampler_24.svg │ │ ├── node_discretizer_24.svg │ │ ├── node_scriptudf_24.svg │ │ ├── node_load_24.svg │ │ ├── node_pythoncommand_24.svg │ │ ├── node_word2vecinplace_24.svg │ │ ├── node_scalerinplace_24.svg │ │ ├── node_ray_24.svg │ │ ├── node_tfidfinplace_24.svg │ │ └── node_treebuildext_24.svg │ └── index.js ├── router │ ├── index.js │ ├── beforeEach.js │ └── routes.js ├── page │ ├── Schedules │ │ └── index.vue │ ├── Workspace │ │ ├── Workflow │ │ │ ├── components │ │ │ │ ├── ETNode │ │ │ │ │ ├── config.js │ │ │ │ │ └── FormItem.vue │ │ │ │ ├── NodeItem │ │ │ │ │ └── index.vue │ │ │ │ ├── TrainNode │ │ │ │ │ └── handler.js │ │ │ │ └── WorkflowPreview │ │ │ │ │ └── index.vue │ │ │ └── config │ │ │ │ └── commonConfig.js │ │ ├── Notebook │ │ │ ├── CollapseCode │ │ │ │ ├── index.vue │ │ │ │ └── Editor.vue │ │ │ ├── ShortcutPrompt │ │ │ │ └── index.vue │ │ │ ├── ActionButton │ │ │ │ └── index.vue │ │ │ ├── ShortcutDetail │ │ │ │ └── index.vue │ │ │ ├── CellList │ │ │ │ └── util.js │ │ │ ├── ShortcutItem │ │ │ │ └── index.vue │ │ │ └── LogMessage │ │ │ │ └── index.vue │ │ └── index.vue │ ├── Jobs │ │ └── index.vue │ ├── Dialogs │ │ └── Dialogs.vue │ └── IframeImage │ │ └── index.vue ├── store │ ├── module │ │ ├── modals.js │ │ ├── jobs.js │ │ ├── datacatalog.js │ │ ├── user.js │ │ ├── global.js │ │ ├── schedules.js │ │ ├── settings.js │ │ └── workflow.js │ └── index.js ├── App.vue ├── locale │ └── index.js ├── util │ └── __test__ │ │ └── index.spec.js ├── components │ ├── Layout │ │ └── index.vue │ ├── SvgIcon │ │ └── index.vue │ ├── CheckSubmit │ │ ├── store.js │ │ └── index.vue │ ├── Markdown │ │ ├── index.vue │ │ └── CodeCopy.vue │ ├── DAGView │ │ └── store.js │ ├── CheckAction │ │ └── store.js │ ├── FailureDetail │ │ ├── store.js │ │ └── index.vue │ ├── GraphNode │ │ └── index.vue │ ├── IconBtn │ │ └── index.vue │ ├── EditTask │ │ └── store.js │ ├── Header │ │ ├── GlobalHelp.vue │ │ ├── ChangeLang.vue │ │ ├── index.vue │ │ ├── UserInfo.vue │ │ └── HeaderMenu.vue │ ├── CodeDialog │ │ ├── store.js │ │ └── index.vue │ ├── UploadSystemFile │ │ └── store.js │ ├── CreateFolder │ │ └── store.js │ ├── ImportNotebook │ │ └── store.js │ ├── RenameNoteBook │ │ └── store.js │ ├── CreateNoteBook │ │ └── store.js │ ├── CreateSelect │ │ ├── store.js │ │ └── index.vue │ ├── CloneNoteBook │ │ └── store.js │ ├── MoveNotebook │ │ └── store.js │ ├── AddSchedule │ │ └── store.js │ ├── SetSchedule │ │ └── store.js │ ├── CreateConnection │ │ ├── store.js │ │ └── index.vue │ ├── CreateNode │ │ └── store.js │ ├── InputTag │ │ └── index.vue │ └── SetDemo │ │ └── index.vue ├── config │ ├── lang.json │ ├── lang.js │ └── index.js └── main.js ├── .env ├── jsconfig.json ├── public ├── static │ └── favicon.png └── index.html ├── dev └── fetchPR.sh ├── .gitignore ├── babel.config.js ├── prettier.config.js ├── .eslintrc.js ├── test └── jest.conf.js ├── README.md ├── package.json ├── vue.config.js └── .github └── workflows └── opened_issue_triage.yml /theme/submenu.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/tab-pane.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/button-group.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/collapse-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/dropdown-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/dropdown-menu.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/form-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/menu-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/breadcrumb-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/checkbox-button.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/checkbox-group.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/infinite-scroll.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/infiniteScroll.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/menu-item-group.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/.eslintignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /config/ 3 | /dist/ 4 | /*.js 5 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | BASE_URL=./ 2 | VUE_APP_API_URL=/ 3 | PROXY_SERVER=http://127.0.0.1:9006 4 | -------------------------------------------------------------------------------- /src/assets/css/index.scss: -------------------------------------------------------------------------------- 1 | 2 | @import './config.scss'; 3 | @import './element-ui_reset.scss'; -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true 4 | } 5 | } -------------------------------------------------------------------------------- /public/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byzer-org/byzer-notebook-vue/HEAD/public/static/favicon.png -------------------------------------------------------------------------------- /theme/fonts/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byzer-org/byzer-notebook-vue/HEAD/theme/fonts/element-icons.ttf -------------------------------------------------------------------------------- /src/assets/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byzer-org/byzer-notebook-vue/HEAD/src/assets/iconfont/iconfont.eot -------------------------------------------------------------------------------- /src/assets/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byzer-org/byzer-notebook-vue/HEAD/src/assets/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /theme/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byzer-org/byzer-notebook-vue/HEAD/theme/fonts/element-icons.woff -------------------------------------------------------------------------------- /src/assets/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byzer-org/byzer-notebook-vue/HEAD/src/assets/iconfont/iconfont.woff -------------------------------------------------------------------------------- /src/service/module/global.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import axios from '../handleService' 4 | 5 | export default { 6 | getEnv: () => axios.get('/api/settings/env') 7 | } -------------------------------------------------------------------------------- /src/assets/images/dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/icons/svg/node_train_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/icons/index.js: -------------------------------------------------------------------------------- 1 | 2 | import Vue from 'vue'; 3 | import SvgIcon from '@/components/SvgIcon'; 4 | 5 | // icons图标自动加载 6 | const req = require.context('./svg', false, /\.svg$/); 7 | req.keys().map(req); 8 | 9 | Vue.component('svg-icon', SvgIcon); -------------------------------------------------------------------------------- /dev/fetchPR.sh: -------------------------------------------------------------------------------- 1 | pr="${1}" 2 | if [ -z "${pr}" ] 3 | then 4 | echo "PR Number is required" 5 | exit 1 6 | fi 7 | git co main 8 | git rev-parse --verify pr${pr} 9 | if [ $? -eq 0 ] 10 | then 11 | git branch -D pr${1} 12 | fi 13 | git fetch origin pull/${pr}/head:pr${pr} 14 | git co pr${1} 15 | -------------------------------------------------------------------------------- /src/icons/svg/node_save_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/svg/node_register_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import VueRouter from 'vue-router' 2 | import Vue from 'vue' 3 | import routes from './routes' 4 | import beforEach from './beforeEach' 5 | 6 | Vue.use(VueRouter) 7 | 8 | const router = new VueRouter({ 9 | routes 10 | }) 11 | 12 | router.beforeEach(beforEach) 13 | export default router 14 | -------------------------------------------------------------------------------- /src/icons/svg/node_predict_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/page/Schedules/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/icons/svg/node_linearregression_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/store/module/modals.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import * as types from '../type' 4 | 5 | export default { 6 | state: { 7 | }, 8 | mutations: { 9 | [types.HIDE_ALL_MODALS]: state => { 10 | for (const [, modalState] of Object.entries(state)) { 11 | if (modalState.isShow) { 12 | modalState.isShow = false 13 | } 14 | } 15 | } 16 | }, 17 | actions: { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | /build/*.tar.gz 5 | /test/coverage/ 6 | package-lock.json 7 | yarn.lock 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | pnpm-debug.log* 18 | 19 | # Editor directories and files 20 | .idea 21 | .vscode 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /src/service/module/jobs.js: -------------------------------------------------------------------------------- 1 | 2 | import axios from '../handleService' 3 | 4 | export default { 5 | getJobList: ({ params, dataTypeSubUrl }) => axios.get(`/api/jobs${dataTypeSubUrl}?${params}`), 6 | getCodeById: job_id => axios.get(`/api/job/${job_id}/content`), 7 | deleteJobs: ids => axios.delete(`/api/jobs/${ids}`), 8 | getJobLogs: ({ job_id, offset = -1 }) => axios.get(`/api/job/${job_id}/log?offset=${offset}`) 9 | } -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | presets: [ 4 | '@vue/cli-plugin-babel/preset', 5 | ['@babel/preset-env', { 'modules': false }] 6 | ], 7 | env: { 8 | test: { 9 | presets: [['env', { targets: { node: 'current' } }]] 10 | } 11 | }, 12 | 'plugins': [ 13 | ['@babel/plugin-proposal-decorators', { 'legacy': true }], 14 | ['@babel/plugin-proposal-class-properties', { 'loose': false }], 15 | ['@babel/plugin-transform-runtime'] 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/icons/svg/node_jsonexpandext_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | tabWidth: 2, 4 | useTabs: false, 5 | semi: false, // 末尾不加尾号 6 | singleQuote: true, // 默认单引号 7 | quoteProps: 'as-needed', 8 | jsxSingleQuote: false, 9 | trailingComma: 'none', // es5对象属性最后加逗号。none不加 10 | bracketSpacing: true, 11 | jsxBracketSameLine: false, 12 | arrowParens: 'always', 13 | htmlWhitespaceSensitivity: 'ignore', 14 | vueIndentScriptAndStyle: false, // script、style标签不缩进 15 | endOfLine: 'lf' 16 | } 17 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 23 | 24 | 26 | -------------------------------------------------------------------------------- /src/icons/svg/node_logisticregression_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/service/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import global from './module/global' 4 | import notebook from './module/notebook' 5 | import user from './module/user' 6 | import datacatalog from './module/datacatelog' 7 | import jobs from './module/jobs' 8 | import schedules from './module/schedules' 9 | import settings from './module/settings' 10 | import workflow from './module/workflow' 11 | export { 12 | global, 13 | notebook, 14 | workflow, 15 | user, 16 | datacatalog, 17 | jobs, 18 | schedules, 19 | settings 20 | } 21 | -------------------------------------------------------------------------------- /src/icons/svg/node_naivebayes_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/icons/svg/nav_monitor_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/svg/node_syntaxanalyzeext_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/service/module/datacatelog.js: -------------------------------------------------------------------------------- 1 | 2 | import axios from '../handleService' 3 | 4 | export default { 5 | getDBList: db_type => axios.get(`/api/catalog/${db_type}/databases`), 6 | getTableList: ({ db_type, database }) => axios.get(`/api/catalog/${db_type}/${database}/tables`), 7 | getFileList: path => axios.get(`/api/catalog/hdfs/file_list?path=${encodeURIComponent(path)}`), 8 | uploadFile: data => axios.post('/api/upload_file', data, { headers: { 9 | 'Content-Type': 'multipart/form-data' 10 | }}), 11 | deleteUploadFile: file_name => axios.delete(`/api/upload_file?file_name=${encodeURIComponent(file_name)}`) 12 | } -------------------------------------------------------------------------------- /src/icons/svg/node_select_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/service/module/user.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import axios from '../handleService' 5 | import { encode } from 'js-base64' 6 | export default { 7 | submitLogin: ({ username, password }) => { 8 | return axios.post('/api/user/authentication', {}, { 9 | headers: { 10 | Authorization: 'Basic ' + encode(username + ':' + password), 11 | 'Accept-Language': localStorage.getItem('kynotebook_lang') || 'en' 12 | } 13 | }) 14 | }, 15 | submitSignUp: params => axios.post('/api/user/join', params), 16 | submitLogout: () => axios.delete('/api/user/authentication'), 17 | getUserInfo: () => axios.get('/api/user/me') 18 | } -------------------------------------------------------------------------------- /src/locale/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import enLocale from 'element-ui/lib/locale/lang/en' 4 | import zhLocale from 'element-ui/lib/locale/lang/zh-CN' 5 | import zh from './zh.json' 6 | import en from './en.json' 7 | import { getGlobalLang } from '@/util' 8 | 9 | Vue.use(VueI18n) 10 | 11 | const messages = { 12 | en: { 13 | ...en, 14 | ...enLocale 15 | }, 16 | zh: { 17 | ...zh, 18 | ...zhLocale 19 | } 20 | } 21 | 22 | const i18n = new VueI18n({ 23 | locale: getGlobalLang(), 24 | messages, 25 | silentFallbackWarn: true 26 | }) 27 | 28 | Vue.mixin({i18n}) 29 | 30 | export default i18n 31 | -------------------------------------------------------------------------------- /src/util/__test__/index.spec.js: -------------------------------------------------------------------------------- 1 | import * as util from '../index' 2 | 3 | describe('util-index', () => { 4 | it('timeToStr', () => { 5 | const dateTime = '1000' 6 | const expectedResult = { 7 | 'day': 0, 8 | 'hour': 0, 9 | 'minutes': 0, 10 | 'ms': 0, 11 | 'seconds': 1 12 | } 13 | expect(util.timeToStr(dateTime)).toEqual(expectedResult) 14 | }) 15 | it('formatGetParams', () => { 16 | const params = { 17 | keyword: '123', 18 | page: 0, 19 | size: 10 20 | } 21 | const expectedResult = '&keyword=123&page=0&size=10' 22 | expect(util.formatGetParams(params)).toBe(expectedResult) 23 | }) 24 | }) -------------------------------------------------------------------------------- /src/page/Workspace/Workflow/components/ETNode/config.js: -------------------------------------------------------------------------------- 1 | 2 | export const outputValueTypeList = ['OUTPUT/MODEL_NAME', 'OUTPUT/MODEL_PATH', 'OUTPUT/TABLE'] 3 | export const paramType = { 4 | KEY: 'Key', 5 | NORMAL: 'Normal', 6 | GROUP_A: 'Group/A', 7 | GROUP_B: 'Group/B', 8 | GROUP_C: 'Group/C', 9 | GROUP: 'Group' 10 | } 11 | 12 | export const valueBindType = { 13 | 'NONE': 'NONE', 14 | 'STATIC': 'STATIC', 15 | 'DYNAMIC': 'DYNAMIC' 16 | } 17 | 18 | export const changeTriggerValueType = ['INPUT/MODEL', 'INPUT/TABLE', 'MULTI_ENUM', 'ENUM', 'ARRAY'] // change 触发校验的参数类型 19 | 20 | export const basicNodeType = ['select', 'load', 'save', 'train', 'predict', 'register'] -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/store/module/jobs.js: -------------------------------------------------------------------------------- 1 | 2 | import * as types from '../type' 3 | import { jobs } from '../../service' 4 | export default { 5 | state: {}, 6 | mutations: {}, 7 | actions: { 8 | [types.GET_JOB_LIST]: (_, { params, dataType }) => { 9 | const dataTypeSubUrl = dataType === 'archived' ? '/archive' : '' 10 | return jobs.getJobList({ params, dataTypeSubUrl }) 11 | }, 12 | [types.GET_CODE_BY_ID]: (_, payload) => { 13 | return jobs.getCodeById(payload) 14 | }, 15 | [types.DELETE_JOBS]: (_, payload) => { 16 | return jobs.deleteJobs(payload) 17 | }, 18 | [types.GET_JOB_LOGS]: (_, payload) => { 19 | return jobs.getJobLogs(payload) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/components/Layout/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 25 | -------------------------------------------------------------------------------- /src/icons/svg/nav_homepage_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/icons/svg/node_runscript_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/store/module/datacatalog.js: -------------------------------------------------------------------------------- 1 | 2 | import * as types from '../type' 3 | import { datacatalog } from '../../service' 4 | export default { 5 | state: {}, 6 | mutations: {}, 7 | actions: { 8 | [types.GET_DB_LIST]: (_, payload) => { 9 | return datacatalog.getDBList(payload) 10 | }, 11 | [types.GET_TABLE_LIST]: (_, payload) => { 12 | return datacatalog.getTableList(payload) 13 | }, 14 | [types.UPLOAD_SYSTEM_FILE]: (_, payload) => { 15 | return datacatalog.uploadFile(payload) 16 | }, 17 | [types.GET_FILE_LIST]: (_, payload) => { 18 | return datacatalog.getFileList(payload) 19 | }, 20 | [types.DELETE_UPLOAD_FILE]: (_, payload) => { 21 | return datacatalog.deleteUploadFile(payload) 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | Vue.use(Vuex) 4 | import * as actionsTypes from './type' 5 | import modals from './module/modals' 6 | import notebook from './module/notebook' 7 | import user from './module/user' 8 | import datacatalog from './module/datacatalog' 9 | import jobs from './module/jobs' 10 | import schedules from './module/schedules' 11 | import settings from './module/settings' 12 | import workflow from './module/workflow' 13 | import global from './module/global' 14 | export default new Vuex.Store({ 15 | modules: { 16 | notebook, 17 | user, 18 | datacatalog, 19 | jobs, 20 | schedules, 21 | settings, 22 | modals, 23 | workflow, 24 | global 25 | } 26 | }) 27 | export { actionsTypes } 28 | -------------------------------------------------------------------------------- /src/icons/svg/schedule_update.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | jest: true 6 | }, 7 | extends: [ 8 | 'plugin:vue/essential', 9 | 'eslint:recommended' 10 | ], 11 | parserOptions: { 12 | parser: 'babel-eslint', 13 | ecmaFeatures: { 14 | 'legacyDecorators': true 15 | } 16 | }, 17 | rules: { 18 | 'generator-star-spacing': 'off', 19 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 20 | 'semi': ['off', 'always'], 21 | 'eqeqeq': 2, 22 | 'spaced-comment': 2, 23 | 'keyword-spacing': 2, 24 | 'space-before-function-paren': 2, 25 | 'quotes': [2, 'single'], 26 | 'comma-dangle': 2, 27 | 'no-useless-escape': 'off', 28 | 'arrow-spacing': 0, 29 | 'arrow-parens': ['error', 'as-needed'] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/router/beforeEach.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import store, { actionsTypes } from '../store' 5 | 6 | export default async function beforeEach (to, from, next) { 7 | try { 8 | const res = await store.dispatch(actionsTypes.GET_ENV) 9 | store.commit('SET_CURRENT_ENV', res.data.is_trial) 10 | store.commit('SET_SCHEDULE_ENABLE', res.data.is_scheduler_enabled) 11 | store.commit('SET_LOGO', res.data.logo) 12 | document.title = res.data.logo || 'Byzer Notebook' 13 | } catch (e) { 14 | console.log(e) 15 | } 16 | if (store.state.user.userInfo) { 17 | next() 18 | } else if (to.meta.needLogin) { 19 | store.dispatch(actionsTypes.GET_USER_INFO).then(res => { 20 | let data = res.data 21 | store.commit('SET_USER_INFO', data) 22 | next({ ...to }) 23 | }) 24 | } else { 25 | next() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/store/module/user.js: -------------------------------------------------------------------------------- 1 | import * as types from '../type' 2 | import { user } from '../../service' 3 | export default { 4 | state: { 5 | userInfo: null 6 | }, 7 | mutations: { 8 | [types.SET_USER_INFO]: (state, payload) => { 9 | state.userInfo = payload 10 | }, 11 | [types.CLEAR_USER_INFO]: state => { 12 | state.userInfo = null 13 | localStorage.clear() 14 | } 15 | }, 16 | actions: { 17 | [types.HANDLE_LOGIN]: (_, payload) => { 18 | return user.submitLogin(payload) 19 | }, 20 | [types.HANDLE_SIGN_UP]: (_, payload) => { // 注册完成之后的动作与登录保持一致 21 | return user.submitSignUp(payload) 22 | }, 23 | [types.HANDLE_LOGOUT]: () => { 24 | return user.submitLogout() 25 | }, 26 | [types.GET_USER_INFO]: () => { 27 | return user.getUserInfo() 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 33 | 34 | -------------------------------------------------------------------------------- /src/store/module/global.js: -------------------------------------------------------------------------------- 1 | 2 | import * as types from '../type' 3 | import { global } from '../../service' 4 | import { getGlobalLang } from '../../util' 5 | export default { 6 | state: { 7 | is_trial: true, 8 | is_scheduler_enabled: false, 9 | logo: 'Byzer Notebook', 10 | lang: getGlobalLang() 11 | }, 12 | mutations: { 13 | [types.SET_CURRENT_ENV]: (state, data) => { 14 | state.is_trial = data 15 | }, 16 | [types.SET_SCHEDULE_ENABLE]: (state, data) => { 17 | state.is_scheduler_enabled = data 18 | }, 19 | [types.CHANGE_LANG]: (state, data) => { 20 | state.lang = data 21 | localStorage.setItem('lang', data) 22 | }, 23 | [types.SET_LOGO]: (state, data) => { 24 | state.logo = data 25 | } 26 | }, 27 | actions: { 28 | [types.GET_ENV]: () => { 29 | return global.getEnv() 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/icons/svg/node_vecmapinplace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/icons/svg/nav_workspace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/CheckSubmit/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | callback: () => { } 9 | } 10 | } 11 | 12 | export default { 13 | namespaced: true, 14 | state: getInitState(), 15 | mutations: { 16 | [actionsTypes.SET_DATA]: (state, payload) => { 17 | for (const [key, value] of Object.entries(payload || {})) { 18 | state[key] = value 19 | } 20 | }, 21 | [actionsTypes.SHOW_MODAL]: state => { 22 | state.isShow = true 23 | }, 24 | [actionsTypes.HIDE_MODAL]: state => { 25 | state.isShow = false 26 | } 27 | }, 28 | actions: { 29 | [actionsTypes.CALL_MODAL] ({ commit }) { 30 | return new Promise(resolve => { 31 | commit(actionsTypes.SET_DATA, { callback: resolve }) 32 | commit(actionsTypes.SHOW_MODAL) 33 | }) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/components/Markdown/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 30 | 31 | -------------------------------------------------------------------------------- /src/icons/svg/node_tablerepartition_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/icons/svg/file_notebook_16.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/node_kmeans_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/DAGView/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | taskInfo: {}, 9 | callback: () => { } 10 | } 11 | } 12 | 13 | export default { 14 | namespaced: true, 15 | state: getInitState(), 16 | mutations: { 17 | [actionsTypes.SET_TASK_INFO]: (state, payload) => { 18 | for (const [key, value] of Object.entries(payload || {})) { 19 | state[key] = value 20 | } 21 | }, 22 | [actionsTypes.SHOW_MODAL]: state => { 23 | state.isShow = true 24 | }, 25 | [actionsTypes.HIDE_MODAL]: state => { 26 | state.isShow = false 27 | } 28 | }, 29 | actions: { 30 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 31 | return new Promise(resolve => { 32 | commit(actionsTypes.SET_TASK_INFO, { callback: resolve, taskInfo: payload }) 33 | commit(actionsTypes.SHOW_MODAL) 34 | }) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/icons/svg/node_alsinplace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/page/Jobs/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 28 | 36 | -------------------------------------------------------------------------------- /src/components/CheckAction/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | formatParams: {}, 9 | callback: () => { } 10 | } 11 | } 12 | 13 | export default { 14 | namespaced: true, 15 | state: getInitState(), 16 | mutations: { 17 | [actionsTypes.SET_DATA]: (state, payload) => { 18 | for (const [key, value] of Object.entries(payload || {})) { 19 | state[key] = value 20 | } 21 | }, 22 | [actionsTypes.SHOW_MODAL]: state => { 23 | state.isShow = true 24 | }, 25 | [actionsTypes.HIDE_MODAL]: state => { 26 | state.isShow = false 27 | } 28 | }, 29 | actions: { 30 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 31 | return new Promise(resolve => { 32 | commit(actionsTypes.SET_DATA, { callback: resolve, formatParams: payload }) 33 | commit(actionsTypes.SHOW_MODAL) 34 | }) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/icons/svg/nav_process_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/icons/svg/node_randomforest_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /test/jest.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | verbose: false, 5 | rootDir: path.resolve(__dirname, '../'), 6 | // 支持源代码中相同的 `@` -> `src` 别名 7 | moduleNameMapper: { 8 | '^@/(.*)$': '/src/$1' 9 | }, 10 | moduleFileExtensions: [ 11 | 'js', 12 | 'json', 13 | 'vue' 14 | ], 15 | transform: { 16 | '.*\\.(vue)$': 'vue-jest', 17 | '^.+\\.js$': '/node_modules/babel-jest' 18 | }, 19 | collectCoverage: true, 20 | collectCoverageFrom: [ 21 | 'src/util/*.js', 22 | 'src/components/**/*.{vue, js}', 23 | 'src/page/**/*.{vue, js}', 24 | 'src/router/**', 25 | '!src/store/**', 26 | '!src/service/**', 27 | '!src/locael/**', 28 | '!src/assets/**', 29 | '!src/config/**', 30 | '!**/node_modules/**' 31 | ], 32 | coverageReporters: ['html', 'text-summary'], 33 | testMatch: [ 34 | '/src/**/__test__/**/*.spec.js', 35 | '/src/**/__test__/*.spec.js' 36 | ], 37 | coverageDirectory: './test/coverage' 38 | } -------------------------------------------------------------------------------- /src/icons/svg/node_normalizeinplace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/components/FailureDetail/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | failureDetail: {} 9 | } 10 | } 11 | 12 | export default { 13 | namespaced: true, 14 | state: getInitState(), 15 | mutations: { 16 | [actionsTypes.SET_FAILURE_DETAIL]: (state, payload = {}) => { 17 | state.failureDetail = payload 18 | }, 19 | [actionsTypes.SHOW_MODAL]: state => { 20 | state.isShow = true 21 | }, 22 | [actionsTypes.HIDE_MODAL]: state => { 23 | state.isShow = false 24 | }, 25 | [actionsTypes.RESET_MODAL]: state => { 26 | for (const [key, value] of Object.entries(getInitState())) { 27 | state[key] = value 28 | } 29 | } 30 | }, 31 | actions: { 32 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 33 | return new Promise(() => { 34 | commit(actionsTypes.SET_FAILURE_DETAIL, payload) 35 | commit(actionsTypes.SHOW_MODAL) 36 | }) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/icons/svg/file_workflow_16.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/node_ratesampler_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/service/module/settings.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import axios from '../handleService' 5 | 6 | export default { 7 | getDefaultConfig: () => axios.get('/api/settings/configuration'), 8 | getEngineList: () => axios.get('/api/settings/engines'), 9 | saveConfig: params => axios.put('/api/settings/configuration', params), 10 | resetTimout: () => axios.post('/api/settings/configuration/reset'), 11 | checkConnection: payload => axios.post('/api/settings/connection/test', payload), 12 | createConnect: payload => axios.post('/api/settings/connection', payload), 13 | getConnectionList: payload => axios.get(`/api/settings/connection${payload}`), 14 | getExistingTableList: connectionId => axios.get(`/api/settings/connection/${connectionId}/table`), 15 | updateConnection: (connectionId, data) => axios.put(`/api/settings/connection/${connectionId}`, data), 16 | deleteConnection: connectionId => axios.delete(`/api/settings/connection/${connectionId}`), 17 | getAlgorithmList: () => axios.get('/api/settings/node/def?node_type=train'), 18 | getParamsByAlgorithmId: id => axios.get(`/api/settings/node/def/${id}`), 19 | getEngineInfo: payload => axios.get(`/api/engine/status${payload}`) 20 | } -------------------------------------------------------------------------------- /src/icons/svg/node_discretizer_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/css/variable.scss: -------------------------------------------------------------------------------- 1 | 2 | @import '../../../element-variables.scss'; 3 | $-size-base: 14px; 4 | $page-header-height: 48px; 5 | 6 | $findAndReplaceItem: #ffff02; 7 | $findAndReplaceSelectedItem: #f59632; 8 | $findAndReplaceTitleColor: #252525; 9 | $cellTextColor: #39414D; 10 | $cellCommentColor: #66A0A4; 11 | $cellStringColor: #1021D5; 12 | $cellKeywordColor: #CF2F72; 13 | $pattern-grey-100: #A5B2C5; 14 | $pattern-blue-100: #CEE6FD; 15 | $pattern-blue-200: #e6f1fb; 16 | $pattern-blue-300: #3991e1; 17 | $pattern-blue-400: #2492F7; 18 | $pattern-blue-500: #0875DA; 19 | $pattern-blue-600: #0867BF; 20 | $pattern-blue-700: #0659A7; 21 | $pattern-purple-400: #A261E3; 22 | $pattern-purple-500: #8B3ADC; 23 | $pattern-purple-600: #6F22BD; 24 | $pattern-orange-500: #FE9412; 25 | $pattern-orange-600: #FE9412; 26 | $pattern-orange-700: #EC8600; 27 | $pattern-green-100: #EFF9EB; 28 | $pattern-green-500: #66C942; 29 | $pattern-green-600: #4DBA2F; 30 | $pattern-green-700: #49A82B; 31 | $pattern-pink-500: #DC3A72; 32 | $pattern-pink-600: #BD2257; 33 | $pattern-pink-700: #8E1941; 34 | $--background-color-secondary: #F8F9FB; 35 | $--background-color-hover: #ECF0F8; 36 | $--color-nav: #08457D !default; 37 | $--border-update-schedule: #E6EBF4; 38 | -------------------------------------------------------------------------------- /src/components/GraphNode/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webapp 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | 26 | ### Change global color 27 | 28 | add some change in element.variables.scss 29 | then 30 | 1. switch node to v11 31 | 2. npm rebuild node-sass 32 | 3. node_modules/.bin/et 33 | 34 | ### use icon in project 35 | - single color svg 36 | 1. upload svg(s) to iconfont(https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3053543) 37 | 2. download to local 38 | 3. replace files in /src/assets/iconfont 39 | 4. replace the class `.iconfont` with `[class^="el-ksd-icon-"], [class*=" el-ksd-icon-"]` 40 | - multi color svg 41 | 1. add .svg file to /src/icons 42 | 2. use svg-icon component in project 43 | 44 | 45 | 46 | 47 | ### Notes 48 | [![Node](https://img.shields.io/badge/Node-14-green.svg?style=plastic)](https://nodejs.org/en/) 49 | [![npm](https://img.shields.io/badge/npm-6-blue.svg?style=plastic)]() 50 | -------------------------------------------------------------------------------- /src/icons/svg/node_scriptudf_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/service/handleService.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import axios from 'axios' 5 | import router from '../router' 6 | import store from '../store' 7 | import { actionsTypes } from '../store' 8 | const { VUE_APP_API_URL } = process.env 9 | 10 | var instance = axios.create({ 11 | baseURL: window.location.origin + VUE_APP_API_URL, 12 | withCrendentials: true 13 | }) 14 | 15 | instance.interceptors.request.use(function (config) { 16 | config.headers.common['Accept-Language'] = localStorage.getItem('kycloud_lang') || 'en' 17 | return config 18 | }) 19 | instance.interceptors.response.use( 20 | response => { 21 | if (response.headers['content-disposition']) { 22 | return response 23 | } else { 24 | return response.data 25 | } 26 | }, 27 | error => { 28 | if (error.response) { 29 | switch (error.response.status) { 30 | case 401: 31 | store.commit(actionsTypes.HIDE_ALL_MODALS) 32 | store.commit(actionsTypes.CLEAR_USER_INFO) 33 | router.push({name: 'login'}) 34 | } 35 | } 36 | const result = error.response.data 37 | const message = result && result.msg || 'Unknow Error' 38 | window.NotebookVue.$message.error(message) 39 | return Promise.reject(error.response) 40 | } 41 | ) 42 | 43 | export default instance 44 | -------------------------------------------------------------------------------- /src/components/IconBtn/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 43 | 58 | -------------------------------------------------------------------------------- /src/service/module/schedules.js: -------------------------------------------------------------------------------- 1 | import axios from '../handleService' 2 | 3 | export default { 4 | // search schedules 5 | getSchedulesList: () => axios.get('/api/schedule/task/list'), 6 | // search by id 7 | getInstanceById: id => axios.get(`/api/schedule/task/instance/${id}`), 8 | // search file type when open notebook 9 | getNotebookInfo: params => axios.get(`/api/schedule/task?${params}`), 10 | // all instance 11 | getInstanceList: id => axios.get(`/api/schedule/task/instance?task_id=${id}`), 12 | // instance 13 | getInstance: id => axios.get(`/api/schedule/task/instance/${id}/status`), 14 | // set schedule 15 | setSchedule: params => axios.post('/api/schedule/task', params), 16 | // update/remove schedule 17 | updateSchedule: ({ id, params }) => axios.put(`/api/schedule/task/${id}`, params), 18 | // run schedule 19 | runSchedule: id => axios.post(`/api/schedule/task/${id}/execution`), 20 | // delete schedule 21 | deleteSchedule: id => axios.delete(`/api/schedule/task/${id}`), 22 | // toogle schedule release_state to online/offline 23 | toggleSchedule: ({ id, release_state }) => axios.post(`/api/schedule/task/${id}/${release_state}`), 24 | // set state of instance 25 | setInstanceState: ({ id, status }) => axios.post(`/api/schedule/task/instance/${id}/status?set_status=${status}`) 26 | } 27 | -------------------------------------------------------------------------------- /src/icons/svg/node_load_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/EditTask/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | taskInfo: {}, 9 | form: { 10 | taskName: '', 11 | taskDescription: '', 12 | scheduleName: '', 13 | previousTask: null, 14 | userParams: {} 15 | }, 16 | callback: () => { } 17 | } 18 | } 19 | 20 | export default { 21 | namespaced: true, 22 | state: getInitState(), 23 | mutations: { 24 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 25 | for (const key of Object.keys(state.form)) { 26 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 27 | } 28 | }, 29 | [actionsTypes.SET_TASK_INFO]: (state, payload) => { 30 | for (const [key, value] of Object.entries(payload || {})) { 31 | state[key] = value 32 | } 33 | }, 34 | [actionsTypes.SHOW_MODAL]: state => { 35 | state.isShow = true 36 | }, 37 | [actionsTypes.HIDE_MODAL]: state => { 38 | state.isShow = false 39 | } 40 | }, 41 | actions: { 42 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 43 | return new Promise(resolve => { 44 | commit(actionsTypes.SET_TASK_INFO, { callback: resolve, ...payload }) 45 | commit(actionsTypes.SHOW_MODAL) 46 | }) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/components/Header/GlobalHelp.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 32 | 53 | -------------------------------------------------------------------------------- /src/components/Markdown/CodeCopy.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 39 | 40 | -------------------------------------------------------------------------------- /src/components/Header/ChangeLang.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 39 | 53 | -------------------------------------------------------------------------------- /src/icons/svg/node_pythoncommand_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/config/lang.json: -------------------------------------------------------------------------------- 1 | { 2 | "python": { 3 | "input": { 4 | "required": true, 5 | "default": "" 6 | }, 7 | "output": { 8 | "required": false, 9 | "default": "" 10 | }, 11 | "schema": { 12 | "required": true, 13 | "default": "" 14 | }, 15 | "runIn": { 16 | "required": false, 17 | "default": "driver", 18 | "options": ["driver", "executor"] 19 | }, 20 | "dataMode": { 21 | "required": false, 22 | "default": "data", 23 | "options": ["data", "model"] 24 | } , 25 | "cache": { 26 | "required": false, 27 | "default": true, 28 | "options": [true, false] 29 | }, 30 | "env": { 31 | "required": true, 32 | "default": "" 33 | } 34 | }, 35 | "openmldb": { 36 | "url": { 37 | "required": true, 38 | "default": "" 39 | }, 40 | "db": { 41 | "required": true, 42 | "default": "" 43 | }, 44 | "execute_mode": { 45 | "required": true, 46 | "default": "offline", 47 | "options": ["offline", "online"] 48 | }, 49 | "output": { 50 | "required": true, 51 | "default": "" 52 | } 53 | }, 54 | "kylin": { 55 | "db": { 56 | "required": true, 57 | "default": "" 58 | }, 59 | "output": { 60 | "required": true, 61 | "default": "" 62 | } 63 | }, 64 | 65 | "visualize": { 66 | "input": { 67 | "required": true, 68 | "default": "" 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/store/module/schedules.js: -------------------------------------------------------------------------------- 1 | 2 | import * as types from '../type' 3 | import { schedules } from '../../service' 4 | 5 | export default { 6 | state: { 7 | }, 8 | mutations: { 9 | }, 10 | actions: { 11 | [types.GET_SCHEDULE_LIST]: (_, payload) => { 12 | return schedules.getSchedulesList(payload) 13 | }, 14 | [types.GET_INSTANCE_BY_ID]: (_, payload) => { 15 | return schedules.getInstanceById(payload) 16 | }, 17 | [types.GET_NOTEBOOK_INFO]: (_, payload) => { 18 | return schedules.getNotebookInfo(payload) 19 | }, 20 | [types.GET_INSTANCE_LIST]: (_, payload) => { 21 | return schedules.getInstanceList(payload) 22 | }, 23 | [types.GET_INSTANCE]: (_, payload) => { 24 | return schedules.getInstance(payload) 25 | }, 26 | [types.SET_SCHEDULE]: (_, payload) => { 27 | return schedules.setSchedule(payload) 28 | }, 29 | [types.UPDATE_SCHEDULE]: (_, { id, params }) => { 30 | return schedules.updateSchedule({ id, params }) 31 | }, 32 | [types.RUN_SCHEDULE]: (_, payload) => { 33 | return schedules.runSchedule(payload) 34 | }, 35 | [types.DELETE_SCHEDULE]: (_, payload) => { 36 | return schedules.deleteSchedule(payload) 37 | }, 38 | [types.TOGGLE_SCHEDULE]: (_, { id, release_state }) => { 39 | return schedules.toggleSchedule({ id, release_state }) 40 | }, 41 | [types.SET_INSTANCE_STATE]: (_, { id, status }) => { 42 | return schedules.setInstanceState({ id, status }) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/config/lang.js: -------------------------------------------------------------------------------- 1 | export {default} from './lang.json' 2 | export const SpecialCodeSuggestKey = ['.', '/', '`', '\'', '"'] 3 | 4 | export const PYTHON_PREFIX = '#%' 5 | export const OPENMLDB_PREFIX = '--%' 6 | export const KYLIN_PREFIX = '--%' 7 | export const SQL_PREFIX = '--%' 8 | 9 | export const PythonTag = '#%python' 10 | export const MarkdownTag = '--%markdown' 11 | export const OpenMLDBTag = '--%openmldb' 12 | export const KylinTag = '--%kylin' 13 | export const VisualizeTag = '--%visualize' 14 | 15 | export const LANG = { 16 | BYZER: 'byzer', 17 | PYTHON: 'python', 18 | OPENMLDB: 'openmldb', 19 | KYLIN: 'kylin', 20 | MARKDOWN: 'markdown', 21 | VISUALIZE: 'visualize' 22 | } 23 | 24 | export const LANG_PREFIX = { 25 | [LANG.PYTHON]: PYTHON_PREFIX, 26 | [LANG.OPENMLDB]: OPENMLDB_PREFIX, 27 | [LANG.KYLIN]: KYLIN_PREFIX, 28 | [LANG.VISUALIZE]: SQL_PREFIX, 29 | [LANG.MARKDOWN]: null, 30 | [LANG.BYZER]: null 31 | } 32 | 33 | export const LANG_TAG = { 34 | [LANG.PYTHON]: PythonTag, 35 | [LANG.OPENMLDB]: OpenMLDBTag, 36 | [LANG.KYLIN]: KylinTag, 37 | [LANG.MARKDOWN]: MarkdownTag, 38 | [LANG.VISUALIZE]: VisualizeTag, 39 | [LANG.BYZER]: null 40 | } 41 | 42 | export const langList = [ 43 | {label: 'Byzer-lang', value: LANG.BYZER}, 44 | {label: 'Python', value: LANG.PYTHON}, 45 | {label: 'OpenMLDB', value: LANG.OPENMLDB}, 46 | {label: 'Kylin', value: LANG.KYLIN}, 47 | {label: 'Markdown', value: LANG.MARKDOWN}, 48 | {label: 'Visualize', value: LANG.VISUALIZE} 49 | ] 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/components/CodeDialog/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | id: '', 9 | type: '', 10 | form: {}, 11 | callback: () => {} 12 | } 13 | } 14 | 15 | export default { 16 | namespaced: true, 17 | state: getInitState(), 18 | mutations: { 19 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 20 | for (const [key, value] of Object.entries(payload)) { 21 | state[key] = value 22 | } 23 | }, 24 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 25 | for (const key of Object.keys(state.form)) { 26 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 27 | } 28 | }, 29 | [actionsTypes.SHOW_MODAL]: state => { 30 | state.isShow = true 31 | }, 32 | [actionsTypes.HIDE_MODAL]: state => { 33 | state.isShow = false 34 | }, 35 | [actionsTypes.RESET_MODAL]: state => { 36 | for (const [key, value] of Object.entries(getInitState())) { 37 | state[key] = value 38 | } 39 | }, 40 | [actionsTypes.RESET_MODAL_FORM]: state => { 41 | for (const [key, value] of Object.entries(getInitState().form)) { 42 | state.form[key] = value 43 | } 44 | } 45 | }, 46 | actions: { 47 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 48 | return new Promise(resolve => { 49 | commit(actionsTypes.SET_MODAL, { callback: resolve, ...payload }) 50 | commit(actionsTypes.SHOW_MODAL) 51 | }) 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/icons/svg/node_word2vecinplace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/page/Workspace/Notebook/CollapseCode/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 16 | 46 | 57 | 58 | -------------------------------------------------------------------------------- /src/components/UploadSystemFile/store.js: -------------------------------------------------------------------------------- 1 | 2 | import { actionsTypes } from '../../store' 3 | 4 | export function getInitState () { 5 | return { 6 | isShow: false, 7 | form: { 8 | file: '' 9 | }, 10 | type: '', 11 | callback: () => {} 12 | } 13 | } 14 | 15 | export default { 16 | namespaced: true, 17 | state: getInitState(), 18 | mutations: { 19 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 20 | for (const [key, value] of Object.entries(payload)) { 21 | state[key] = value 22 | } 23 | }, 24 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 25 | for (const key of Object.keys(state.form)) { 26 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 27 | } 28 | }, 29 | [actionsTypes.SHOW_MODAL]: state => { 30 | state.isShow = true 31 | }, 32 | [actionsTypes.HIDE_MODAL]: state => { 33 | state.isShow = false 34 | }, 35 | [actionsTypes.RESET_MODAL]: state => { 36 | for (const [key, value] of Object.entries(getInitState())) { 37 | state[key] = value 38 | } 39 | }, 40 | [actionsTypes.RESET_MODAL_FORM]: state => { 41 | for (const [key, value] of Object.entries(getInitState().form)) { 42 | state.form[key] = value 43 | } 44 | } 45 | }, 46 | actions: { 47 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 48 | return new Promise(resolve => { 49 | commit(actionsTypes.SET_MODAL, { callback: resolve, ...payload }) 50 | // 初始化 form 中的数据 51 | commit(actionsTypes.SET_MODAL_FORM) 52 | commit(actionsTypes.SHOW_MODAL) 53 | }) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/components/CreateFolder/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | // id: '', 10 | name: '' 11 | }, 12 | targetfolderId: '', 13 | callback: () => {} 14 | } 15 | } 16 | 17 | export default { 18 | namespaced: true, 19 | state: getInitState(), 20 | mutations: { 21 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 22 | for (const [key, value] of Object.entries(payload)) { 23 | state[key] = value 24 | } 25 | }, 26 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 27 | for (const key of Object.keys(state.form)) { 28 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 29 | } 30 | }, 31 | [actionsTypes.SHOW_MODAL]: state => { 32 | state.isShow = true 33 | }, 34 | [actionsTypes.HIDE_MODAL]: state => { 35 | state.isShow = false 36 | }, 37 | [actionsTypes.RESET_MODAL]: state => { 38 | for (const [key, value] of Object.entries(getInitState())) { 39 | state[key] = value 40 | } 41 | }, 42 | [actionsTypes.RESET_MODAL_FORM]: state => { 43 | for (const [key, value] of Object.entries(getInitState().form)) { 44 | state.form[key] = value 45 | } 46 | } 47 | }, 48 | actions: { 49 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 50 | return new Promise(resolve => { 51 | commit(actionsTypes.SET_MODAL, { callback: resolve }) 52 | commit(actionsTypes.SET_MODAL, { ...payload }) 53 | commit(actionsTypes.SHOW_MODAL) 54 | }) 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/service/module/workflow.js: -------------------------------------------------------------------------------- 1 | 2 | import axios from '../handleService' 3 | export default { 4 | createWorkflow: data => axios.post('/api/workflow', data), 5 | createWorkflowNode: (workflow_id, data) => axios.post(`/api/workflow/${workflow_id}/node`, data), 6 | getNodeList: (workflow_id, commit_id) => axios.get(`/api/workflow/${workflow_id}${commit_id ? '?commit_id=' + commit_id : ''}`), 7 | getWorkflowPreview: (workflow_id, commit_id) => axios.get(`/api/workflow/${workflow_id}/script${commit_id ? '?commit_id=' + commit_id : ''}`), 8 | saveAsNotebook: (workflow_id, data) => axios.post(`/api/workflow/${workflow_id}/notebook`, data), 9 | checkMlsql: data => axios.post('/api/sql/validation', data), 10 | getNodeInfo: (workflow_id, node_id) => axios.get(`/api/workflow/${workflow_id}/node/${node_id}`), 11 | updateFlowNode: (workflow_id, node_id, data) => axios.put(`/api/workflow/${workflow_id}/node/${node_id}`, data), 12 | getExsitingTable: workflow_id => axios.get(`/api/workflow/${workflow_id}/output`), 13 | getExsitingModel: id => axios.get(`/api/workflow${id ? ('/' + id) : ''}/model`), 14 | updateNodePosition: (workflow_id, node_id, data) => axios.put(`/api/workflow/${workflow_id}/node/${node_id}/position`, data), 15 | deleteWorkflowNode: (workflow_id, node_id) => axios.delete(`/api/workflow/${workflow_id}/node/${node_id}`), 16 | getLoadParams: ({node_type, node_name, param_name}) => axios.get(`/api/settings/node/param?node_type=${node_type}&node_name=${node_name}¶m_name=${param_name}`), 17 | getETList: () => axios.get('/api/et'), 18 | getETParams: et_id => axios.get(`/api/et/${et_id}/params`), 19 | getETDependency: data => axios.post('/api/et/dependency', data) 20 | } 21 | -------------------------------------------------------------------------------- /src/components/ImportNotebook/store.js: -------------------------------------------------------------------------------- 1 | 2 | import { actionsTypes } from '../../store' 3 | 4 | export function getInitState () { 5 | return { 6 | isShow: false, 7 | form: { 8 | file: '' 9 | }, 10 | type: '', 11 | folderId: '', 12 | callback: () => {} 13 | } 14 | } 15 | 16 | export default { 17 | namespaced: true, 18 | state: getInitState(), 19 | mutations: { 20 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 21 | for (const [key, value] of Object.entries(payload)) { 22 | state[key] = value 23 | } 24 | }, 25 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 26 | for (const key of Object.keys(state.form)) { 27 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 28 | } 29 | }, 30 | [actionsTypes.SHOW_MODAL]: state => { 31 | state.isShow = true 32 | }, 33 | [actionsTypes.HIDE_MODAL]: state => { 34 | state.isShow = false 35 | }, 36 | [actionsTypes.RESET_MODAL]: state => { 37 | for (const [key, value] of Object.entries(getInitState())) { 38 | state[key] = value 39 | } 40 | }, 41 | [actionsTypes.RESET_MODAL_FORM]: state => { 42 | for (const [key, value] of Object.entries(getInitState().form)) { 43 | state.form[key] = value 44 | } 45 | } 46 | }, 47 | actions: { 48 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 49 | return new Promise(resolve => { 50 | commit(actionsTypes.SET_MODAL, { callback: resolve, ...payload }) 51 | // 初始化 form 中的数据 52 | commit(actionsTypes.SET_MODAL_FORM) 53 | commit(actionsTypes.SHOW_MODAL) 54 | }) 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/components/RenameNoteBook/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | id: '', 10 | name: '', 11 | type: '' 12 | }, 13 | callback: () => {} 14 | } 15 | } 16 | 17 | export default { 18 | namespaced: true, 19 | state: getInitState(), 20 | mutations: { 21 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 22 | for (const [key, value] of Object.entries(payload)) { 23 | state[key] = value 24 | } 25 | }, 26 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 27 | for (const key of Object.keys(state.form)) { 28 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 29 | } 30 | }, 31 | [actionsTypes.SHOW_MODAL]: state => { 32 | state.isShow = true 33 | }, 34 | [actionsTypes.HIDE_MODAL]: state => { 35 | state.isShow = false 36 | }, 37 | [actionsTypes.RESET_MODAL]: state => { 38 | for (const [key, value] of Object.entries(getInitState())) { 39 | state[key] = value 40 | } 41 | }, 42 | [actionsTypes.RESET_MODAL_FORM]: state => { 43 | for (const [key, value] of Object.entries(getInitState().form)) { 44 | state.form[key] = value 45 | } 46 | } 47 | }, 48 | actions: { 49 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 50 | return new Promise(resolve => { 51 | commit(actionsTypes.SET_MODAL, { callback: resolve }) 52 | // 初始化 form 中的数据 53 | commit(actionsTypes.SET_MODAL_FORM, { ...payload }) 54 | commit(actionsTypes.SHOW_MODAL) 55 | }) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/CreateNoteBook/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | folderId: '', 10 | name: '', 11 | type: '' 12 | }, 13 | callback: () => {} 14 | } 15 | } 16 | 17 | export default { 18 | namespaced: true, 19 | state: getInitState(), 20 | mutations: { 21 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 22 | for (const [key, value] of Object.entries(payload)) { 23 | state[key] = value 24 | } 25 | }, 26 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 27 | for (const key of Object.keys(state.form)) { 28 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 29 | } 30 | }, 31 | [actionsTypes.SHOW_MODAL]: state => { 32 | state.isShow = true 33 | }, 34 | [actionsTypes.HIDE_MODAL]: state => { 35 | state.isShow = false 36 | }, 37 | [actionsTypes.RESET_MODAL]: state => { 38 | for (const [key, value] of Object.entries(getInitState())) { 39 | state[key] = value 40 | } 41 | }, 42 | [actionsTypes.RESET_MODAL_FORM]: state => { 43 | for (const [key, value] of Object.entries(getInitState().form)) { 44 | state.form[key] = value 45 | } 46 | } 47 | }, 48 | actions: { 49 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 50 | return new Promise(resolve => { 51 | commit(actionsTypes.SET_MODAL, { callback: resolve }) 52 | // 初始化 form 中的数据 53 | commit(actionsTypes.SET_MODAL_FORM, { ...payload }) 54 | commit(actionsTypes.SHOW_MODAL) 55 | }) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/CreateSelect/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | sql: '' 10 | }, 11 | nodeInfo: null, 12 | callback: () => {} 13 | } 14 | } 15 | 16 | export default { 17 | namespaced: true, 18 | state: getInitState(), 19 | mutations: { 20 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 21 | for (const [key, value] of Object.entries(payload)) { 22 | state[key] = value 23 | } 24 | }, 25 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 26 | for (const key of Object.keys(state.form)) { 27 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 28 | } 29 | }, 30 | [actionsTypes.SHOW_MODAL]: state => { 31 | state.isShow = true 32 | }, 33 | [actionsTypes.HIDE_MODAL]: state => { 34 | state.isShow = false 35 | }, 36 | [actionsTypes.RESET_MODAL]: state => { 37 | for (const [key, value] of Object.entries(getInitState())) { 38 | state[key] = value 39 | } 40 | }, 41 | [actionsTypes.RESET_MODAL_FORM]: state => { 42 | for (const [key, value] of Object.entries(getInitState().form)) { 43 | state.form[key] = value 44 | } 45 | } 46 | }, 47 | actions: { 48 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 49 | return new Promise(resolve => { 50 | commit(actionsTypes.SET_MODAL, { callback: resolve }) 51 | // 初始化 form 中的数据 52 | const { nodeInfo } = payload 53 | commit(actionsTypes.SET_MODAL, { nodeInfo }) 54 | commit(actionsTypes.SHOW_MODAL) 55 | }) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/CloneNoteBook/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | id: '', 10 | name: '', 11 | type: '', 12 | uniq: '', 13 | commit_id: '' 14 | }, 15 | callback: () => {} 16 | } 17 | } 18 | 19 | export default { 20 | namespaced: true, 21 | state: getInitState(), 22 | mutations: { 23 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 24 | for (const [key, value] of Object.entries(payload)) { 25 | state[key] = value 26 | } 27 | }, 28 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 29 | for (const key of Object.keys(state.form)) { 30 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 31 | } 32 | }, 33 | [actionsTypes.SHOW_MODAL]: state => { 34 | state.isShow = true 35 | }, 36 | [actionsTypes.HIDE_MODAL]: state => { 37 | state.isShow = false 38 | }, 39 | [actionsTypes.RESET_MODAL]: state => { 40 | for (const [key, value] of Object.entries(getInitState())) { 41 | state[key] = value 42 | } 43 | }, 44 | [actionsTypes.RESET_MODAL_FORM]: state => { 45 | for (const [key, value] of Object.entries(getInitState().form)) { 46 | state.form[key] = value 47 | } 48 | } 49 | }, 50 | actions: { 51 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 52 | return new Promise(resolve => { 53 | commit(actionsTypes.SET_MODAL, { callback: resolve }) 54 | // 初始化 form 中的数据 55 | commit(actionsTypes.SET_MODAL_FORM, { ...payload }) 56 | commit(actionsTypes.SHOW_MODAL) 57 | }) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/components/MoveNotebook/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | folder: [] 10 | }, 11 | callback: () => {}, 12 | fileInfo: null, 13 | isMoveFolder: false, 14 | currentNodeParentInfo: {} 15 | } 16 | } 17 | 18 | export default { 19 | namespaced: true, 20 | state: getInitState(), 21 | mutations: { 22 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 23 | for (const [key, value] of Object.entries(payload)) { 24 | state[key] = value 25 | } 26 | }, 27 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 28 | for (const key of Object.keys(state.form)) { 29 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 30 | } 31 | }, 32 | [actionsTypes.SHOW_MODAL]: state => { 33 | state.isShow = true 34 | }, 35 | [actionsTypes.HIDE_MODAL]: state => { 36 | state.isShow = false 37 | }, 38 | [actionsTypes.RESET_MODAL]: state => { 39 | for (const [key, value] of Object.entries(getInitState())) { 40 | state[key] = value 41 | } 42 | }, 43 | [actionsTypes.RESET_MODAL_FORM]: state => { 44 | for (const [key, value] of Object.entries(getInitState().form)) { 45 | state.form[key] = value 46 | } 47 | } 48 | }, 49 | actions: { 50 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 51 | return new Promise(resolve => { 52 | commit(actionsTypes.SET_MODAL, { callback: resolve, ...payload }) 53 | // 初始化 form 中的数据 54 | commit(actionsTypes.SET_MODAL_FORM) 55 | commit(actionsTypes.SHOW_MODAL) 56 | }) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/components/AddSchedule/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | task_name: '', 10 | task_desc: '', 11 | user_params: [] 12 | }, 13 | notebookInfo: null, 14 | callback: () => {} 15 | } 16 | } 17 | 18 | export default { 19 | namespaced: true, 20 | state: getInitState(), 21 | mutations: { 22 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 23 | for (const [key, value] of Object.entries(payload)) { 24 | state[key] = value 25 | } 26 | }, 27 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 28 | for (const key of Object.keys(state.form)) { 29 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 30 | } 31 | }, 32 | [actionsTypes.SHOW_MODAL]: state => { 33 | state.isShow = true 34 | }, 35 | [actionsTypes.HIDE_MODAL]: state => { 36 | state.isShow = false 37 | }, 38 | [actionsTypes.RESET_MODAL]: state => { 39 | for (const [key, value] of Object.entries(getInitState())) { 40 | state[key] = value 41 | } 42 | }, 43 | [actionsTypes.RESET_MODAL_FORM]: state => { 44 | for (const [key, value] of Object.entries(getInitState().form)) { 45 | state.form[key] = value 46 | } 47 | } 48 | }, 49 | actions: { 50 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 51 | return new Promise(resolve => { 52 | commit(actionsTypes.SET_MODAL, { callback: resolve, notebookInfo: payload }) 53 | // 初始化 form 中的数据 54 | commit(actionsTypes.SET_MODAL_FORM, { task_name: payload.name }) 55 | commit(actionsTypes.SHOW_MODAL) 56 | }) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/page/Workspace/Notebook/ShortcutPrompt/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 42 | 43 | 71 | -------------------------------------------------------------------------------- /src/components/Header/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 16 | 47 | -------------------------------------------------------------------------------- /src/components/SetSchedule/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | schedule_name: '', 10 | schedule_desc: '', 11 | date: [], 12 | cron: '' 13 | }, 14 | scheduleInfo: null, 15 | callback: () => {} 16 | } 17 | } 18 | 19 | export default { 20 | namespaced: true, 21 | state: getInitState(), 22 | mutations: { 23 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 24 | for (const [key, value] of Object.entries(payload)) { 25 | state[key] = value 26 | } 27 | }, 28 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 29 | for (const key of Object.keys(state.form)) { 30 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 31 | } 32 | }, 33 | [actionsTypes.SHOW_MODAL]: state => { 34 | state.isShow = true 35 | }, 36 | [actionsTypes.HIDE_MODAL]: state => { 37 | state.isShow = false 38 | }, 39 | [actionsTypes.RESET_MODAL]: state => { 40 | for (const [key, value] of Object.entries(getInitState())) { 41 | state[key] = value 42 | } 43 | }, 44 | [actionsTypes.RESET_MODAL_FORM]: state => { 45 | for (const [key, value] of Object.entries(getInitState().form)) { 46 | state.form[key] = value 47 | } 48 | } 49 | }, 50 | actions: { 51 | [actionsTypes.CALL_MODAL] ({ commit }, payload) { 52 | const {name: schedule_name, schedule:{start_time, end_time, crontab: cron}, description: schedule_desc} = payload 53 | return new Promise(resolve => { 54 | commit(actionsTypes.SET_MODAL, { scheduleInfo: payload, callback: resolve }) 55 | commit(actionsTypes.SET_MODAL_FORM, { schedule_name, date: [start_time, end_time], cron, schedule_desc }) 56 | commit(actionsTypes.SHOW_MODAL) 57 | }) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import ElementUI from 'element-ui' 6 | import i18n from './locale' 7 | import 'normalize.css' 8 | import './assets/iconfont/iconfont.css' 9 | import '../theme/index.css' 10 | import './assets/css/index.scss' 11 | import VueClipboard from 'vue-clipboard2' 12 | Vue.use(VueClipboard) 13 | import keymaster from 'keymaster' 14 | import Contextmenu from 'vue-contextmenujs' 15 | Vue.use(Contextmenu); 16 | import './directives' 17 | import { findChildren } from './util' 18 | import '@/icons/index.js' 19 | import IconBtn from './components/IconBtn' 20 | import editor from 'vue2-ace-editor' 21 | import 'brace/theme/chrome' 22 | import 'brace/mode/javascript' 23 | import 'brace/snippets/sql' 24 | import 'brace/snippets/python' 25 | import 'brace/mode/python' 26 | import 'brace/ext/language_tools' 27 | import './config/editor_highlight' 28 | 29 | Vue.component('editor', editor) 30 | Vue.component('icon-btn', IconBtn) 31 | 32 | const bindKeyHandler = fn => { 33 | return () => { 34 | fn() 35 | return false 36 | } 37 | } 38 | keymaster.filter = event => { 39 | var tagName = (event.target || event.srcElement).tagName 40 | 41 | // 所有的FindAndReplace组件 42 | const result = findChildren(window.NotebookVue, 'findAndReplace') 43 | // 是否没有打开的 44 | const workStatus = result && result.every(i => !i.showMsg) 45 | 46 | return !['INPUT', 'SELECT'].includes(tagName) && workStatus && !store.getters.isDemo 47 | } 48 | export const shortcut = { 49 | bind: (seed, func) => keymaster(seed, bindKeyHandler(func)), 50 | ...keymaster 51 | } 52 | 53 | Vue.prototype.$shortcut = shortcut 54 | 55 | Vue.config.productionTip = false 56 | Vue.use(ElementUI, { 57 | i18n: (key, value) => i18n.t(key, value) 58 | }) 59 | 60 | window.NotebookVue = new Vue({ 61 | render: h => h(App), 62 | router, 63 | store, 64 | i18n 65 | }).$mount('#app') 66 | -------------------------------------------------------------------------------- /src/components/CreateConnection/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | form: { 9 | name: '', 10 | datasource: '', 11 | url: '', 12 | driver: '', 13 | username: '', 14 | password: '', 15 | parameter: [ 16 | { name: '', value: '', key: String(Date.now()) } 17 | ] 18 | }, 19 | id: -1, 20 | type: 'add', 21 | callback: () => {} 22 | } 23 | } 24 | 25 | export default { 26 | namespaced: true, 27 | state: getInitState(), 28 | mutations: { 29 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 30 | for (const [key, value] of Object.entries(payload)) { 31 | state[key] = value 32 | } 33 | }, 34 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 35 | for (const key of Object.keys(state.form)) { 36 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 37 | } 38 | }, 39 | [actionsTypes.SHOW_MODAL]: state => { 40 | state.isShow = true 41 | }, 42 | [actionsTypes.HIDE_MODAL]: state => { 43 | state.isShow = false 44 | }, 45 | [actionsTypes.RESET_MODAL]: state => { 46 | for (const [key, value] of Object.entries(getInitState())) { 47 | state[key] = value 48 | } 49 | }, 50 | [actionsTypes.RESET_MODAL_FORM]: state => { 51 | for (const [key, value] of Object.entries(getInitState().form)) { 52 | state.form[key] = value 53 | } 54 | } 55 | }, 56 | actions: { 57 | [actionsTypes.CALL_MODAL] ({ commit }, {type, payload}) { 58 | return new Promise(resolve => { 59 | commit(actionsTypes.SET_MODAL, { callback: resolve, type, id: payload.id }) 60 | // 初始化 form 中的数据 61 | commit(actionsTypes.SET_MODAL_FORM, { ...payload }) 62 | commit(actionsTypes.SHOW_MODAL) 63 | }) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/icons/svg/node_scalerinplace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/store/module/settings.js: -------------------------------------------------------------------------------- 1 | import * as types from '../type' 2 | import { settings } from '../../service' 3 | export default { 4 | state: { 5 | isRunningAll: false, 6 | engineInfo: {} 7 | }, 8 | mutations: { 9 | [types.SET_ENGINE_INFO]: (state, payload) => { 10 | state.engineInfo = payload 11 | } 12 | }, 13 | actions: { 14 | [types.GET_CONFIGS]: () => { 15 | return settings.getDefaultConfig() 16 | }, 17 | [types.GET_ENGINE_LIST]: () => { 18 | return settings.getEngineList() 19 | }, 20 | [types.SAVE_CONFIG]: (_, payload) => { 21 | return settings.saveConfig(payload) 22 | }, 23 | [types.RESET_TIMEOUT]: () => { 24 | return settings.resetTimout() 25 | }, 26 | [types.CHECK_CONNECTION]: (_, payload) => { 27 | return settings.checkConnection(payload) 28 | }, 29 | [types.CREATE_CONNECTION]: (_, payload) => { 30 | return settings.createConnect(payload) 31 | }, 32 | [types.GET_CONNECTION_LIST]: (_, payload = '') => { 33 | return settings.getConnectionList(payload) 34 | }, 35 | [types.GET_CONNECTION_TABLE]: (_, connectionId) => { 36 | return settings.getExistingTableList(connectionId) 37 | }, 38 | [types.UPDATE_CONNECTION]: (_, { connectionId, data }) => { 39 | return settings.updateConnection(connectionId, data) 40 | }, 41 | [types.DELETE_CONNECTION]: (_, connectionId) => { 42 | return settings.deleteConnection(connectionId) 43 | }, 44 | [types.GET_ALGORITHM_LIST]: () => { 45 | return settings.getAlgorithmList() 46 | }, 47 | [types.GET_PARAM_BY_ID]: (_, id) => { 48 | return settings.getParamsByAlgorithmId(id) 49 | }, 50 | [types.GET_ENGINE_INFO]: async ({ commit }, payload = '') => { 51 | let res = {} 52 | try { 53 | res = await settings.getEngineInfo(payload) 54 | commit(types.SET_ENGINE_INFO, res.data) 55 | } catch (err) { 56 | console.log(err) 57 | } 58 | return res 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/page/Workspace/Notebook/ActionButton/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 52 | 53 | 82 | -------------------------------------------------------------------------------- /src/page/Workspace/Workflow/config/commonConfig.js: -------------------------------------------------------------------------------- 1 | const strokeWidth = 1 2 | const color = '#546174' 3 | export const jsplumbSetting = { 4 | grid: [10, 10], 5 | // 动态锚点、位置自适应 6 | Anchors: [ 7 | 'TopCenter', 8 | 'RightMiddle', 9 | 'BottomCenter', 10 | 'LeftMiddle' 11 | ], 12 | // Container: 'flow', 13 | // 连线的样式 StateMachine、Flowchart,有四种默认类型:Bezier(贝塞尔曲线),Straight(直线),Flowchart(流程图),State machine(状态机) 14 | Connector: ['Flowchart', { cornerRadius: 5, alwaysRespectStubs: true, stub: 5 }], 15 | // 鼠标不能拖动删除线 16 | ConnectionsDetachable: false, 17 | // 删除线的时候节点不删除 18 | DeleteEndpointsOnDetach: false, 19 | // 连线的端点 20 | Endpoints: [ [ 'Dot', { radius: 5 } ], ['Rectangle', { width: 5, height: 5 } ]], 21 | // 线端点的样式 22 | EndpointStyle: [{ fill: color }], 23 | // 绘制线 24 | PaintStyle: { 25 | stroke: color, 26 | strokeWidth: strokeWidth 27 | }, 28 | // 绘制箭头 29 | Overlays: [ 30 | [ 31 | 'Arrow', 32 | { 33 | width: 6, 34 | length: 6, 35 | location: 1 36 | } 37 | ], 38 | [ 39 | 'Diamond', 40 | { 41 | width: 6, 42 | length: 6, 43 | location: 0 44 | } 45 | ] 46 | ], 47 | RenderMode: 'svg' 48 | } 49 | 50 | // jsplumb连接参数 51 | export const jsplumbConnectOptions = { 52 | isSource: true, 53 | isTarget: true, 54 | // 动态锚点、提供了4个方向 Continuous、AutoDefault 55 | anchor: [ 56 | 'TopCenter', 57 | 'RightMiddle', 58 | 'BottomCenter', 59 | 'LeftMiddle' 60 | ] 61 | } 62 | 63 | export const jsplumbSourceOptions = { 64 | filter: '.node-anchor', // 触发连线的区域 65 | /* 'span'表示标签,'.className'表示类,'#id'表示元素id*/ 66 | filterExclude: false, 67 | anchor: [ 68 | 'TopCenter', 69 | 'RightMiddle', 70 | 'BottomCenter', 71 | 'LeftMiddle' 72 | ], 73 | allowLoopback: false 74 | } 75 | 76 | export const jsplumbTargetOptions = { 77 | filter: '.node-anchor', 78 | /* 'span'表示标签,'.className'表示类,'#id'表示元素id*/ 79 | filterExclude: false, 80 | anchor: [ 81 | 'TopCenter', 82 | 'RightMiddle', 83 | 'BottomCenter', 84 | 'LeftMiddle' 85 | ], 86 | allowLoopback: false 87 | } -------------------------------------------------------------------------------- /src/components/CheckSubmit/index.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 74 | 82 | -------------------------------------------------------------------------------- /src/components/Header/UserInfo.vue: -------------------------------------------------------------------------------- 1 | 2 | 15 | 57 | -------------------------------------------------------------------------------- /src/icons/svg/node_ray_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/icons/svg/node_tfidfinplace_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/page/Dialogs/Dialogs.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 78 | 79 | 81 | -------------------------------------------------------------------------------- /src/page/Workspace/Notebook/ShortcutDetail/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 77 | 78 | 96 | -------------------------------------------------------------------------------- /src/page/Workspace/Notebook/CellList/util.js: -------------------------------------------------------------------------------- 1 | import langConfig from '@/config/lang.json' 2 | import {LANG_PREFIX, LANG_TAG, LANG} from '@/config/lang' 3 | 4 | export function getDefaultConfig (lang) { 5 | const config = langConfig[lang] 6 | const prefix = LANG_PREFIX[lang] 7 | const tag = LANG_TAG[lang] 8 | let str = '' 9 | let obj = {} 10 | if (tag) { 11 | str = `${tag}` 12 | const keys = Object.keys(config) 13 | keys.forEach(key => { 14 | obj[key] = config[key].default 15 | str += `\n${prefix}${key}=${config[key].default}` 16 | }) 17 | } 18 | return {configStr: tag ? str + '\n' : str, config: obj} 19 | } 20 | 21 | // 获取 cell 的配置, 根据前缀截取 前面几个 22 | export function getCellConfig (cell) { 23 | const {editType} = cell 24 | const prefix = LANG_PREFIX[editType] 25 | if (!prefix) return '' 26 | const tag = LANG_TAG[editType] 27 | const content = cell.content.split('\n') 28 | const newContent = content.filter((item, index) => { 29 | const prevItem = content[index - 1] 30 | return item.startsWith(prefix) && (prevItem?.startsWith(prefix) || prevItem === tag) 31 | }).filter(item => item) 32 | tag && newContent.unshift(tag) 33 | return newContent.join('\n') 34 | } 35 | 36 | export function getConfigObj (config, lang) { 37 | const configList = config.split('\n') 38 | const prefix = LANG_PREFIX[lang] 39 | if (!prefix) return {} 40 | const obj = {} 41 | configList.forEach(item => { 42 | const arr = item.split('=') 43 | if (Object.values(LANG_TAG).includes(arr[0])) return 44 | const key = arr[0].split(prefix)[1] 45 | if (key?.trim()) { 46 | obj[key] = arr[1] 47 | } 48 | }) 49 | return obj 50 | } 51 | 52 | export function getLangByTag (value = '', tag) { 53 | return value.split('\n').map(i => i.trim()).indexOf(tag) > -1 54 | } 55 | 56 | export function getLangByContent (value = '') { 57 | if (value.startsWith(LANG_TAG[LANG.MARKDOWN])) { 58 | return LANG.MARKDOWN 59 | } else if (getLangByTag(value, LANG_TAG[LANG.PYTHON])) { 60 | return LANG.PYTHON 61 | } else if (getLangByTag(value, LANG_TAG[LANG.OPENMLDB])) { 62 | return LANG.OPENMLDB 63 | } else if (getLangByTag(value, LANG_TAG[LANG.KYLIN])) { 64 | return LANG.KYLIN 65 | } else if (getLangByTag(value, LANG_TAG[LANG.VISUALIZE])) { 66 | return LANG.VISUALIZE 67 | } else { 68 | return LANG.BYZER 69 | } 70 | } -------------------------------------------------------------------------------- /src/service/module/notebook.js: -------------------------------------------------------------------------------- 1 | import axios from '../handleService' 2 | 3 | export default { 4 | createNotebook: params => axios.post('/api/file', params), 5 | renameNotebook: params => axios.put('/api/file', params), 6 | cloneNotebook: params => axios.post('/api/file/clone', params), 7 | delNotebook: ({id, type}) => axios.delete(`/api/file/${id}?type=${type}`), 8 | saveOpenedNotebook: list => axios.put('/api/files/opened', list), 9 | getOpenedNotebook: () => axios.get('/api/files/opened'), 10 | importNotebook: data => axios.post('/api/file/import', data, { 11 | headers: { 12 | 'Content-Type': 'multipart/form-data' 13 | } 14 | }), 15 | moveNotebook: data => axios.post('/api/file/move', data), 16 | getNotebookList: () => axios.get('/api/files'), 17 | excuteCode: params => axios.post('/api/script/execution', params), 18 | getJobStatus: id => axios.get(`/api/job/${id}`), 19 | saveNotebookById: ({id, data}) => axios.put(`/api/notebook/${id}`, data), 20 | getNotebookById: (id, commit_id) => axios.get(`/api/notebook/${id}${commit_id ? '?commit_id=' + commit_id : ''}`), 21 | cancelExcuteCell: id => axios.post(`/api/job/${id}/cancel`), 22 | getExcuteProcess: id => axios.get(`/api/job/${id}/progress`), 23 | getCurrentScript: id => axios.get(`/api/job/${id}/current_script`), 24 | createCell: ({id, data}) => axios.post(`/api/notebook/${id}/cell`, data), 25 | deleteCell: ({id, cell_id}) => axios.delete(`/api/notebook/${id}/cell/${cell_id}`), 26 | getDefaultNotebook: () => axios.get('/api/notebook/default'), 27 | clearAllResults: notebookId => axios.delete(`/api/notebook/${notebookId}/result`), 28 | createFolder: data => axios.post('/api/folder', data), 29 | moveFolder: data => axios.post('/api/folder/move', data), 30 | renameFolder: data => axios.put('/api/folder', data), 31 | cloneFolder: data => axios.post('/api/folder/clone', data), 32 | deleteFolder: id => axios.delete(`/api/folder/${id}`), 33 | autoComplete: params => axios.post('/api/notebook/code/suggestion', params), 34 | exportNotebook: ({ 35 | type, 36 | id, 37 | output, 38 | expand_include 39 | }) => axios.get(`/api/file/export/${id}?type=${type}${output ? '&output=' + output : ''}${expand_include ? '&expand_include=' + expand_include : ''}`, {responseType: 'blob'}), 40 | setDemo: params => axios.post('/api/settings/demo', params), 41 | offlineDemo: params => axios.post('/api/settings/demo/remove', params) 42 | } 43 | -------------------------------------------------------------------------------- /src/router/routes.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const routes = [ 5 | { 6 | path: '/', 7 | redirect: { name: 'home' } 8 | }, 9 | { 10 | name: 'login', 11 | path: '/login', 12 | component: () => import('../page/Login'), 13 | meta: { 14 | needLogin: false, 15 | menuIndex: 'login' 16 | } 17 | }, 18 | { 19 | name: 'home', 20 | path: '/home', 21 | component: () => import('../page/Home'), 22 | meta: { 23 | needLogin: true, 24 | menuIndex: 'home' 25 | } 26 | }, 27 | { 28 | name: 'notebook', 29 | path: '/notebook/:uniq?', 30 | component: () => import('../page/Workspace'), 31 | meta: { 32 | needLogin: true, 33 | menuIndex: 'notebook' 34 | } 35 | }, 36 | { 37 | name: 'jobs', 38 | path: '/jobs', 39 | component: () => import('../page/Jobs'), 40 | meta: { 41 | needLogin: true, 42 | menuIndex: 'jobs' 43 | } 44 | }, 45 | { 46 | name: 'schedules', 47 | path: '/schedules', 48 | component: () => import('../page/Schedules'), 49 | redirect: { 50 | name: 'schedulesHome' 51 | }, 52 | meta: { 53 | needLogin: true, 54 | menuIndex: 'schedules' 55 | }, 56 | children: [ 57 | { 58 | name: 'schedulesHome', 59 | path: 'schedules', 60 | component: () => import('../page/Schedules/Schedules'), 61 | meta: { 62 | needLogin: true, 63 | menuIndex: 'schedules' 64 | } 65 | }, 66 | { 67 | name: 'instance', 68 | path: 'instance/:id', 69 | component: () => import('../page/Schedules/Instance'), 70 | meta: { 71 | needLogin: true, 72 | menuIndex: 'schedules' 73 | } 74 | }, 75 | { 76 | name: 'dag', 77 | path: 'dag/:id', 78 | component: () => import('../page/Schedules/Dag'), 79 | meta: { 80 | needLogin: true, 81 | menuIndex: 'schedules' 82 | } 83 | } 84 | ] 85 | }, 86 | { 87 | name: 'settings', 88 | path: '/settings', 89 | component: () => import('../page/Settings'), 90 | meta: { 91 | needLogin: true, 92 | menuIndex: 'settings' 93 | } 94 | }, 95 | { 96 | name: 'result', 97 | path: '/result/:id', 98 | component: () => import('../page/IframeImage'), 99 | meta: { 100 | needLogin: true, 101 | menuIndex: 'result' 102 | } 103 | } 104 | // { 105 | // name: '*', 106 | // redirect: {name: 'result'} 107 | // } 108 | ] 109 | 110 | export default routes 111 | -------------------------------------------------------------------------------- /src/page/Workspace/Notebook/CollapseCode/Editor.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 47 | 48 | 77 | 100 | -------------------------------------------------------------------------------- /src/store/module/workflow.js: -------------------------------------------------------------------------------- 1 | import * as types from '../type' 2 | import { workflow } from '@/service' 3 | export default { 4 | state: { 5 | currentDragNode: null, 6 | nodeList: [] 7 | }, 8 | mutations: { 9 | [types.SET_CURRENT_DRAG_NODE]: (state, payload) => { 10 | state.currentDragNode = payload 11 | }, 12 | [types.SET_NODE_LIST]: (state, payload) => { 13 | state.nodeList = payload 14 | } 15 | }, 16 | actions: { 17 | [types.CREATE_WORKFLOW]: (_, payload) => { 18 | return workflow.createWorkflow(payload) 19 | }, 20 | [types.CREATE_WORKFLOW_NODE]: ({ getters }, payload) => { 21 | return workflow.createWorkflowNode(getters.activeNotebookId, payload) 22 | }, 23 | [types.DELETE_WORKFLOW_NODE]: ({getters}, node_id) => { 24 | return workflow.deleteWorkflowNode(getters.activeNotebookId, node_id) 25 | }, 26 | [types.GET_NODE_LIST]: (_, { workflow_id, commit_id }) => { 27 | return workflow.getNodeList(workflow_id, commit_id) 28 | }, 29 | [types.GET_WORKFLOW_PREVIEW]: (_, { workflow_id, commit_id }) => { 30 | return workflow.getWorkflowPreview(workflow_id, commit_id) 31 | }, 32 | [types.SAVE_WORKFLOW_AS_NOTEBOOK]: ({ getters }, payload) => { 33 | return workflow.saveAsNotebook(getters.activeNotebookId, payload) 34 | }, 35 | [types.CHECK_MLSQL]: (_, payload) => { 36 | return workflow.checkMlsql(payload) 37 | }, 38 | [types.GET_NODE_INFO]: ({ getters }, { node_id }) => { 39 | return workflow.getNodeInfo(getters.activeNotebookId, node_id) 40 | }, 41 | [types.UPDATE_FLOW_NODE]: ({ getters }, { node_id, data }) => { 42 | return workflow.updateFlowNode(getters.activeNotebookId, node_id, data) 43 | }, 44 | [types.GET_EXISTING_TABLE]: ({ getters }) => { 45 | return workflow.getExsitingTable(getters.activeNotebookId) 46 | }, 47 | [types.GET_EXISTING_MODEL]: (_, id) => { 48 | return workflow.getExsitingModel(id) 49 | }, 50 | [types.UPDATE_NODE_POSITION]: (_, { workflow_id, node_id, data }) => { 51 | return workflow.updateNodePosition(workflow_id, node_id, data) 52 | }, 53 | [types.GET_LOAD_PARAMS]: (_, payload) => { 54 | return workflow.getLoadParams(payload) 55 | }, 56 | [types.GET_ET_LIST]: () => { 57 | return workflow.getETList() 58 | }, 59 | [types.GET_ET_PARAMS]: (_, id) => { 60 | return workflow.getETParams(id) 61 | }, 62 | [types.GET_ET_DEPENENCY]: (_, payload) => { 63 | return workflow.getETDependency(payload) 64 | } 65 | }, 66 | getters: { 67 | activeNotebookId: (state, getters, rootState) => { 68 | return rootState.notebook.activeNotebook?.id 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/icons/svg/node_treebuildext_24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "byzer", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "test": "BABEL_ENV=test && jest --config test/jest.conf.js --watchAll" 10 | }, 11 | "dependencies": { 12 | "@antv/layout": "0.1.31", 13 | "@antv/x6": "1.30.1", 14 | "@antv/x6-vue-shape": "1.3.1", 15 | "@kangc/v-md-editor": "1.7.9-beta.1", 16 | "axios": "0.24.0", 17 | "babel-core": "7.0.0-bridge.0", 18 | "brace": "0.10.0", 19 | "clipboard": "^2.0.11", 20 | "core-js": "^3.27.1", 21 | "cron-expression-validator": "1.0.20", 22 | "crypto-js": "4.1.1", 23 | "element-theme": "2.0.1", 24 | "element-ui": "2.15.10", 25 | "file-saver": "2.0.5", 26 | "github-markdown-css": "^5.2.0", 27 | "highlight.js": "^11.8.0", 28 | "html2canvas": "1.0.0-rc.7", 29 | "install": "0.13.0", 30 | "js-base64": "3.6.1", 31 | "jsencrypt": "3.2.1", 32 | "json-bigint": "^1.0.0", 33 | "json2csv": "5.0.6", 34 | "jsplumb": "2.15.6", 35 | "katex": "0.15.1", 36 | "keymaster": "1.6.2", 37 | "lodash": "4.17.21", 38 | "mermaid": "8.13.5", 39 | "moment": "2.29.1", 40 | "node-sass": "6.0.1", 41 | "normalize.css": "8.0.1", 42 | "npm": "7.19.1", 43 | "panzoom": "9.4.2", 44 | "sortablejs": "1.14.0", 45 | "style-resources-loader": "1.5.0", 46 | "vue": "2.6.11", 47 | "vue-class-component": "7.2.3", 48 | "vue-click-outside": "1.1.0", 49 | "vue-clipboard2": "0.3.1", 50 | "vue-contextmenujs": "1.3.13", 51 | "vue-i18n": "8.18.2", 52 | "vue-markdown": "^2.2.4", 53 | "vue-property-decorator": "8.5.0", 54 | "vue-router": "3.2.0", 55 | "vue2-ace-editor": "0.0.15", 56 | "vuedraggable": "2.24.3", 57 | "vuex": "3.4.0" 58 | }, 59 | "devDependencies": { 60 | "@babel/plugin-transform-runtime": "7.16.4", 61 | "@kazupon/vue-i18n-loader": "0.5.0", 62 | "@vue/cli-plugin-babel": "4.5.15", 63 | "@vue/cli-plugin-eslint": "4.5.0", 64 | "@vue/cli-service": "4.5.0", 65 | "@vue/composition-api": "1.4.7", 66 | "@vue/test-utils": "1.3.0", 67 | "babel-eslint": "10.1.0", 68 | "babel-jest": "27.3.1", 69 | "babel-preset-env": "1.7.0", 70 | "element-theme-chalk": "2.15.10", 71 | "eslint": "6.7.2", 72 | "eslint-plugin-vue": "6.2.2", 73 | "filemanager-webpack-plugin": "6.1.7", 74 | "jest": "27.3.1", 75 | "sass": "1.45.0", 76 | "sass-loader": "10.1.1", 77 | "svg-sprite-loader": "6.0.2", 78 | "vue-i18n-locale-message": "0.16.2", 79 | "vue-jest": "3.0.7", 80 | "vue-template-compiler": "2.6.11" 81 | }, 82 | "browserslist": [ 83 | "> 1%", 84 | "last 2 versions", 85 | "not dead" 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs'); 3 | const FileManagerPlugin = require('filemanager-webpack-plugin') 4 | 5 | function resolvePath (dir) { 6 | return path.resolve(__dirname, '.', dir) 7 | } 8 | function getCompressionName () { 9 | try { 10 | const projectName = JSON.parse(fs.readFileSync('package.json')).name; 11 | const projectVersion = JSON.parse(fs.readFileSync('package.json')).version; 12 | return `./build/${projectName}-${projectVersion}.tar.gz`; 13 | } catch (e) { 14 | return './build/dist.tar.gz'; 15 | } 16 | } 17 | const isProd = process.env.NODE_ENV === 'production' 18 | 19 | module.exports = { 20 | lintOnSave: false, 21 | publicPath: process.env.BASE_URL, 22 | assetsDir: 'static', // 配置js、css静态资源二级目录的位置 23 | devServer: { 24 | port: 9090, 25 | proxy: process.env.PROXY_SERVER 26 | }, 27 | configureWebpack: { 28 | devtool: process.env.NODE_ENV === 'dev' ? 'eval-source-map' : undefined, 29 | resolve: { 30 | alias: { 31 | 'vue$': 'vue/dist/vue.common.js' 32 | } 33 | } 34 | }, 35 | chainWebpack: config => { 36 | const oneOfsMap = config.module.rule('scss').oneOfs.store; 37 | oneOfsMap.forEach(item => { 38 | item 39 | .use('style-resources-loader') 40 | .loader('style-resources-loader') 41 | .options({ 42 | patterns: './src/assets/css/variable.scss' 43 | }) 44 | .end() 45 | }) 46 | // 定义组件中文案翻译 47 | config.module 48 | .rule('i18n') 49 | .resourceQuery(/blockType=i18n/) 50 | .type('javascript/auto') 51 | .use('i18n') 52 | .loader('@kazupon/vue-i18n-loader') 53 | .end() 54 | // 配置项目标题 55 | config 56 | .plugin('html') 57 | .tap(args => { 58 | args[0].title = 'Byzer Notebook' 59 | return args 60 | }) 61 | .end() 62 | // 让其他svg loader不要对src/icons进行操作 63 | config.module 64 | .rule('svg') 65 | .exclude.add(resolvePath('src/icons/svg')) 66 | .end() 67 | // 使用svg-sprite-loader 对 src/icons下的svg进行操作 68 | config.module 69 | .rule('icons') 70 | .test(/\.svg$/) 71 | .include.add(resolvePath('src/icons/svg')) 72 | .end() 73 | .use('svg-sprite-loader') 74 | .loader('svg-sprite-loader') 75 | .options({ 76 | symbolId: 'icon-[name]' 77 | }) 78 | .end() 79 | if (isProd) { 80 | config.plugin('filemanager') 81 | .use( 82 | new FileManagerPlugin({ 83 | events: { 84 | onEnd: [{ 85 | delete: [ getCompressionName() ], 86 | archive: [ 87 | { source: './dist', format: 'tar', destination: getCompressionName()} 88 | ] 89 | }] 90 | } 91 | }) 92 | ) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/components/CreateNode/store.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { actionsTypes } from '../../store' 4 | 5 | export function getInitState () { 6 | return { 7 | isShow: false, 8 | selectForm: { 9 | sql: '' 10 | }, 11 | loadForm: { 12 | datasource_type: '', 13 | database: '', 14 | connection: '', 15 | source: '', 16 | target: '', 17 | header: 'true' 18 | }, 19 | saveForm: { 20 | mode: 'overwrite', 21 | datasource_type: '', 22 | data_type: '', 23 | connection: '', 24 | source: '', 25 | target: '' 26 | }, 27 | trainForm: { 28 | source: '', 29 | target: '', 30 | algorithm: '', 31 | save_path: '', 32 | train_param: null 33 | }, 34 | registerForm: { 35 | target: '', 36 | group: '', 37 | deploy_mode_param: { 38 | url: '', 39 | access_token: '' 40 | } 41 | }, 42 | predictForm: { 43 | source: '', 44 | model: '', 45 | predict_param: { 46 | auto: true, 47 | value: '' 48 | }, 49 | target: '' 50 | }, 51 | form: null, 52 | nodeInfo: null, 53 | callback: () => {} 54 | } 55 | } 56 | 57 | export default { 58 | namespaced: true, 59 | state: getInitState(), 60 | mutations: { 61 | [actionsTypes.SET_MODAL]: (state, payload = {}) => { 62 | for (const [key, value] of Object.entries(payload)) { 63 | if (key === 'form') { 64 | state['form'] = state[value] 65 | } else { 66 | state[key] = value 67 | } 68 | } 69 | }, 70 | [actionsTypes.SET_MODAL_FORM]: (state, payload = {}) => { 71 | for (const key of Object.keys(state.form)) { 72 | state.form[key] = payload[key] !== undefined ? payload[key] : state.form[key] 73 | } 74 | }, 75 | [actionsTypes.SHOW_MODAL]: state => { 76 | state.isShow = true 77 | }, 78 | [actionsTypes.HIDE_MODAL]: state => { 79 | state.isShow = false 80 | }, 81 | [actionsTypes.RESET_MODAL]: state => { 82 | for (const [key, value] of Object.entries(getInitState())) { 83 | state[key] = value 84 | } 85 | }, 86 | [actionsTypes.RESET_MODAL_FORM]: state => { 87 | for (const [key, value] of Object.entries(getInitState()[`${state.nodeInfo.type}Form`])) { 88 | state.form[key] = value 89 | } 90 | } 91 | }, 92 | actions: { 93 | [actionsTypes.CALL_MODAL] ({ commit }, { nodeInfo }) { 94 | return new Promise(resolve => { 95 | const { type } = nodeInfo 96 | commit(actionsTypes.SET_MODAL, { callback: resolve, form: `${type}Form` }) 97 | // 初始化 form 中的数据 98 | commit(actionsTypes.SET_MODAL, { nodeInfo }) 99 | 100 | commit(actionsTypes.SHOW_MODAL) 101 | }) 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/page/IframeImage/index.vue: -------------------------------------------------------------------------------- 1 |