diff --git a/frontend/desktop/builds/webpack.dev.config.js b/frontend/desktop/builds/webpack.dev.config.js index 6f8292fcca..6e4bbed305 100644 --- a/frontend/desktop/builds/webpack.dev.config.js +++ b/frontend/desktop/builds/webpack.dev.config.js @@ -39,7 +39,8 @@ const proxyPath = [ 'iam/*', 'plugin_service/*', 'mako_operations/*', - 'collection/*' + 'collection/*', + 'template_market/*' ] const proxyRule = {} proxyPath.forEach((item) => { diff --git a/frontend/desktop/package.json b/frontend/desktop/package.json index b5f9d7c997..3fb6cb1ebe 100644 --- a/frontend/desktop/package.json +++ b/frontend/desktop/package.json @@ -17,6 +17,7 @@ "@blueking/notice-component-vue2": "^2.0.1", "@blueking/platform-config": "^1.0.2", "@blueking/user-selector": "^1.0.5-beta.2", + "@toast-ui/editor": "^3.2.2", "@vue/babel-preset-jsx": "^1.3.0", "ajv": "^6.10.2", "art-template": "^4.13.0", diff --git a/frontend/desktop/src/assets/html/index.html b/frontend/desktop/src/assets/html/index.html index 8975278ddc..99de8b7b7d 100644 --- a/frontend/desktop/src/assets/html/index.html +++ b/frontend/desktop/src/assets/html/index.html @@ -56,6 +56,9 @@ var BK_PAAS_SHARED_RES_URL = '{{BK_PAAS_SHARED_RES_URL}}' var APP_NAME = '{{APP_NAME}}' var RUN_VER_NAME = '{{RUN_VER_NAME}}' + var ENABLE_TEMPLATE_MARKET = {{ENABLE_TEMPLATE_MARKET}} + var TEMPLATE_MARKET_HOST = '{{TEMPLATE_MARKET_HOST}}' + var TEMPLATE_MARKET_DOC_URL = '{{TEMPLATE_MARKET_DOC_URL}}' // 是否开启通知中心 var ENABLE_NOTICE_CENTER = {{ENABLE_NOTICE_CENTER}} function getCookie(name) { diff --git a/frontend/desktop/src/config/i18n/cn.js b/frontend/desktop/src/config/i18n/cn.js index 626bf09c77..24b1009f42 100644 --- a/frontend/desktop/src/config/i18n/cn.js +++ b/frontend/desktop/src/config/i18n/cn.js @@ -1800,7 +1800,31 @@ const cn = { '产品官网': '产品官网', '联系bk助手': '联系bk助手', '蓝鲸桌面': '蓝鲸桌面', - '蓝鲸': '蓝鲸' + '蓝鲸': '蓝鲸', + '共享到商店': '共享到商店', + '共享到SRE商店': '共享到SRE商店', + '帮助文档': '帮助文档', + 'SRE商店': 'SRE商店', + 'templateSharedTips': '注意事项:共享的流程不包含敏感信息,支持在 {0} 预览', + 'templateSharedSuccessTips': '共享成功,请前往 {0} 查看', + '更新': '更新', + '共享类型': '共享类型', + '场景名称': '场景名称', + '场景标识': '场景标识', + '场景分类': '场景分类', + '风险级别': '风险级别', + '使用说明': '使用说明', + '高': '高', + '低': '低', + '请输入场景名称': '请输入场景名称', + '请选择场景名称': '请选择场景名称', + '请输入场景标识': '请输入场景标识', + '请选择场景分类': '请选择场景分类', + '场景使用者通过标签可以快速找到同一类场景': '场景使用者通过标签可以快速找到同一类场景', + '申明该场景的运维操作风险级别,以便场景使用者决策场景的使用方式': '申明该场景的运维操作风险级别,以便场景使用者决策场景的使用方式', + '请输入标签,enter保存': '请输入标签,enter保存', + '将清空输入信息': '将清空输入信息', + '【n】标签已存在': '【{n}】标签已存在' } export default cn diff --git a/frontend/desktop/src/config/i18n/en.js b/frontend/desktop/src/config/i18n/en.js index 1d4b8410f2..31713a6823 100644 --- a/frontend/desktop/src/config/i18n/en.js +++ b/frontend/desktop/src/config/i18n/en.js @@ -1834,7 +1834,31 @@ const en = { '产品官网': 'Product Website', '联系bk助手': 'Contact BK Assistant', '蓝鲸桌面': 'BlueWhale Desktop', - '蓝鲸': 'BlueKing' + '蓝鲸': 'BlueKing', + '共享到商店': 'Shared to the store', + '共享到SRE商店': 'Shared to the SRE Store', + '帮助文档': 'Help Doc', + 'SRE商店': 'SRE Store', + 'templateSharedTips': 'Note: The shared process does not contain sensitive information and can be previewed at {0}', + 'templateSharedSuccessTips': 'Shared successfully, please go to {0} to view', + '更新': 'Updated', + '共享类型': 'Sharing Type', + '场景名称': 'Scene Name', + '场景标识': 'Scene Identifier', + '场景分类': 'Scene Category', + '风险级别': 'Risk Level', + '使用说明': 'Instructions', + '高': 'High', + '低': 'Low', + '请输入场景名称': 'Please enter the scene name', + '请选择场景名称': 'Please select the scene name', + '请输入场景标识': 'Please enter the scene identifier', + '请选择场景分类': 'Please select the scene category', + '场景使用者通过标签可以快速找到同一类场景': 'Scene users can quickly find scenes of the same category through tags', + '申明该场景的运维操作风险级别,以便场景使用者决策场景的使用方式': 'Declare the operational risk level of the scene to aid users in deciding how to use the scene', + '请输入标签,enter保存': 'Please enter a tag and press Enter to save', + '将清空输入信息': 'This will clear the input information', + '【n】标签已存在': 'The tag [{n}] already exists' } export default en diff --git a/frontend/desktop/src/main.js b/frontend/desktop/src/main.js index fc66dbd8fa..5bd2d39e07 100644 --- a/frontend/desktop/src/main.js +++ b/frontend/desktop/src/main.js @@ -29,6 +29,7 @@ import { Input, InputNumber, Select, Radio, RadioGroup, RadioButton, Checkbox, import enLocale from 'element-ui/lib/locale/lang/en' import zhLocale from 'element-ui/lib/locale/lang/zh-CN' import locales from 'element-ui/lib/locale' +import '@toast-ui/editor/dist/toastui-editor.css' import { STRING_LENGTH } from '@/constants/index.js' import cron from '@/assets/js/node-cron-valid/node-cron-vaild.js' import tools from './utils/tools' diff --git a/frontend/desktop/src/pages/task/TaskCreate/TaskParamFill.vue b/frontend/desktop/src/pages/task/TaskCreate/TaskParamFill.vue index 66b78a7e1e..953c6b54a6 100644 --- a/frontend/desktop/src/pages/task/TaskCreate/TaskParamFill.vue +++ b/frontend/desktop/src/pages/task/TaskCreate/TaskParamFill.vue @@ -184,7 +184,8 @@ 'viewMode': state => state.view_mode, 'app_id': state => state.app_id, 'functionClaimMsg': state => state.functionClaimMsg, - 'permissionMeta': state => state.permissionMeta + 'permissionMeta': state => state.permissionMeta, + 'bizId': state => state.project.bizId }), ...mapState('project', { 'timeZone': state => state.timezone, @@ -575,7 +576,15 @@ this.$router.push(url) // 如果被嵌入了,则像父页面发送事件 if (this.hideHeader) { - window.parent.postMessage({ eventName: 'createTaskEvent' }, '*') + window.parent.postMessage({ + eventName: 'createTaskEvent', + data: { + cc_id: this.bizId, + project_id: this.project_id, + task_id: taskData.id, + task_name: taskData.name + } + }, '*') } } catch (e) { console.log(e) diff --git a/frontend/desktop/src/pages/task/TaskExecute/TaskOperationHeader.vue b/frontend/desktop/src/pages/task/TaskExecute/TaskOperationHeader.vue index 9fc63ea700..125cb0444f 100644 --- a/frontend/desktop/src/pages/task/TaskExecute/TaskOperationHeader.vue +++ b/frontend/desktop/src/pages/task/TaskExecute/TaskOperationHeader.vue @@ -220,6 +220,11 @@ if (!isFromCreate && this.$route.name === 'taskExecute' && window.history.length > 2) { return this.$router.back() } + // 如果被嵌入了,则像父页面发送事件 + if (this.hideHeader) { + window.parent.postMessage({ eventName: 'goBackEvent' }, '*') + return + } this.$router.push({ name: 'taskList', params: { project_id: this.project_id } diff --git a/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/SharedTagSelect.vue b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/SharedTagSelect.vue new file mode 100644 index 0000000000..d33813e183 --- /dev/null +++ b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/SharedTagSelect.vue @@ -0,0 +1,118 @@ + + + diff --git a/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/SharedTplSlider.vue b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/SharedTplSlider.vue new file mode 100644 index 0000000000..1b09dba3c6 --- /dev/null +++ b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/SharedTplSlider.vue @@ -0,0 +1,424 @@ + + + diff --git a/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/index.vue b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/index.vue new file mode 100644 index 0000000000..152f793e2d --- /dev/null +++ b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/index.vue @@ -0,0 +1,41 @@ + + + diff --git a/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/markdownEditor/editor.vue b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/markdownEditor/editor.vue new file mode 100644 index 0000000000..1c62759a04 --- /dev/null +++ b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/markdownEditor/editor.vue @@ -0,0 +1,95 @@ + + diff --git a/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/markdownEditor/previewEditor.vue b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/markdownEditor/previewEditor.vue new file mode 100644 index 0000000000..4dc493fae5 --- /dev/null +++ b/frontend/desktop/src/pages/template/TemplateList/SharedTemplate/markdownEditor/previewEditor.vue @@ -0,0 +1,31 @@ + + diff --git a/frontend/desktop/src/pages/template/TemplateList/projectTplList.vue b/frontend/desktop/src/pages/template/TemplateList/projectTplList.vue index e795538f05..2a29e76dbf 100644 --- a/frontend/desktop/src/pages/template/TemplateList/projectTplList.vue +++ b/frontend/desktop/src/pages/template/TemplateList/projectTplList.vue @@ -29,7 +29,7 @@ @click="checkCreatePermission"> {{$t('新建')}} - +
{{ $t('导入') }} @@ -40,7 +40,6 @@
@@ -52,6 +51,11 @@
  • {{ $t('导出为') }} DAT {{ $t('文件') }}
  • + + * { + margin-right: 14px; + } } .my-create-btn { position: absolute; diff --git a/frontend/desktop/src/pages/template/TemplatePreview/index.vue b/frontend/desktop/src/pages/template/TemplatePreview/index.vue index 54f764d1b2..17ba751969 100644 --- a/frontend/desktop/src/pages/template/TemplatePreview/index.vue +++ b/frontend/desktop/src/pages/template/TemplatePreview/index.vue @@ -15,8 +15,7 @@ }, props: { project_id: [Number, String], - template_id: [Number, String], - common: [Number, String] + template_id: [Number, String] }, data () { return { @@ -33,17 +32,17 @@ this.getTemplateData() }, methods: { - ...mapActions('template/', [ - 'loadTemplateData' + ...mapActions('templateMarket/', [ + 'loadTemplatePreviewData' ]), async getTemplateData () { try { this.templateLoading = true - const resp = await this.loadTemplateData({ - templateId: this.template_id, - common: this.common + const resp = await this.loadTemplatePreviewData({ + template_id: this.template_id, + project_id: this.project_id }) - const pipelineTree = JSON.parse(resp.pipeline_tree) + const pipelineTree = JSON.parse(resp.data.pipeline_tree) this.templateData = formatCanvasData('perview', pipelineTree) } catch (e) { console.log(e) diff --git a/frontend/desktop/src/store/modules/index.js b/frontend/desktop/src/store/modules/index.js index 1178ed301c..08b395a75c 100644 --- a/frontend/desktop/src/store/modules/index.js +++ b/frontend/desktop/src/store/modules/index.js @@ -23,6 +23,7 @@ import periodic from './periodic.js' import clocked from './clocked.js' import manage from './manage.js' import admin from './admin.js' +import templateMarket from './templateMarket.js' const modules = { template, @@ -38,7 +39,8 @@ const modules = { clocked, manage, project, - admin + admin, + templateMarket } export default modules diff --git a/frontend/desktop/src/store/modules/templateMarket.js b/frontend/desktop/src/store/modules/templateMarket.js new file mode 100644 index 0000000000..2809adcb9a --- /dev/null +++ b/frontend/desktop/src/store/modules/templateMarket.js @@ -0,0 +1,38 @@ + +import axios from 'axios' + +const templateMarket = { + namespaced: true, + actions: { + loadMarkedServiceCategory ({ commit }) { + return axios.get('/template_market/api/templates_scene/get_service_category/').then(response => response.data) + }, + loadMarkedSceneLabel ({ commit }) { + return axios.get('/template_market/api/templates_scene/get_scene_label/').then(response => response.data) + }, + loadMarkedRiskLevel ({ commit }) { + return axios.get('/template_market/api/templates_scene/get_risk_level/').then(response => response.data) + }, + getFileUploadAddr ({ commit }, params) { + return axios.get('/template_market/api/templates_scene/get_file_upload_addr/', { params }).then(response => response.data.data) + }, + createLabel ({ commit }, params) { + return axios.post('/template_market/api/templates_scene/create_scene_label/', params).then(response => response.data) + }, + loadSharedTemplateRecord ({ commit }) { + return axios.get('/template_market/api/templates_scene/').then(response => response.data) + }, + sharedTemplateRecord ({ commit }, params) { + const { id } = params + const baseUrl = '/template_market/api/templates_scene/' + const url = id ? `${baseUrl}${id}/` : baseUrl + const method = id ? 'patch' : 'post' + return axios[method](url, params).then(response => response.data) + }, + loadTemplatePreviewData ({ commit }, params) { + return axios.get('/template_market/api/template_preview/', { params }).then(response => response.data) + } + } +} + +export default templateMarket