Skip to content

Commit

Permalink
feat(vue-dsl): add app generate code (#178)
Browse files Browse the repository at this point in the history
* feat(vue-dsl): add app generate code

* feat(vue-dsl): add app generate code

* feat(vue-dsl): add generate global store code

* feat(vue-dsl): delete parse config and parse schema hook

* feat(tempalte): refra generateTemplate logic

* feat(vue-generator): add generate script frame code

* feat(vue-generator): add hook flow for sfc file generate

* feat(vue-generator): support generate sfc script

* feat(vue-generator): support jsx generate

* fix(vue-generator): fix double quotes issue

* feat(vue-generator): handle app generate code

* feat(toolbar-generate-vue): toolbar-generate-vue use new codegen function

* feat(vue-generator): add requiredBlock parser

* feat(docs): add readme doc

* feat(docs): add more docs

* fix(vue-generator): adapt for more scenario

* feat(vue-generator): support tiny-grid editor use tiny component

* fix(vue-generator): complete unit test

* fix(vue-generator): add unit test

* feat(vue-generator): add sfc generator unit test

* feat(vue-generator[docs]): add contributing docs

* feat(vue-generator): add test coverage script and app generate test case

* fix(generate-vue): optimize desc and file list

* fix(vue-generate): [template] fix viteConfig process.env is processed

* fix(vue-generator): escape process.env string

* feat(vue-generator): support builtin components

* fix(vue-generator): add builtin componentsMap

* fix(vue-generator): fix bind utils props

* fix(vue-generator): support utils expression

* fix(vue-generator): support children expression add utils

* fix(vue-generator): support nested folder page

* fix(vue-generator): support get datasource with name

* fix(vue-generator): only write necessary dependencies into package.json

* feat(vue-generator): simplified genTemplate hooks

* fix(vue-generator): update vue-generator  docs

* feat(vue-generator): detect jsx on custom  method

* feat(vue-generator): add d.ts types declaration
  • Loading branch information
chilingling authored May 13, 2024
1 parent aa8d361 commit 3a66996
Show file tree
Hide file tree
Showing 128 changed files with 10,771 additions and 139 deletions.
2 changes: 1 addition & 1 deletion mockServer/src/mock/get/app-center/v1/apps/schema/918.json
Original file line number Diff line number Diff line change
Expand Up @@ -1787,7 +1787,7 @@
},
{
"componentName": "TinyPlusFrozenPage",
"package": "@opentiny/vuee",
"package": "@opentiny/vue",
"exportName": "FrozenPage",
"destructuring": true,
"version": "3.4.1"
Expand Down
1 change: 1 addition & 0 deletions packages/design-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@opentiny/tiny-engine-canvas": "workspace:*",
"@opentiny/tiny-engine-common": "workspace:*",
"@opentiny/tiny-engine-controller": "workspace:*",
"@opentiny/tiny-engine-dsl-vue": "workspace:*",
"@opentiny/tiny-engine-http": "workspace:*",
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-plugin-block": "workspace:*",
Expand Down
83 changes: 60 additions & 23 deletions packages/design-core/src/preview/src/preview/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ import { defineComponent, computed, defineAsyncComponent } from 'vue'
import { Repl, ReplStore } from '@vue/repl'
import vueJsx from '@vue/babel-plugin-jsx'
import { transformSync } from '@babel/core'
import { Notify } from '@opentiny/vue'
import { genSFCWithDefaultPlugin, parseRequiredBlocks } from '@opentiny/tiny-engine-dsl-vue'
import importMap from './importMap'
import srcFiles from './srcFiles'
import generateMetaFiles, { processAppJsCode } from './generate'
import { getSearchParams, fetchCode, fetchMetaData } from './http'
import { getSearchParams, fetchMetaData, fetchAppSchema, fetchBlockSchema } from './http'
import { PanelType, PreviewTips } from '../constant'
import { injectDebugSwitch } from './debugSwitch'
import '@vue/repl/style.css'
Expand Down Expand Up @@ -71,31 +71,68 @@ export default {
const newImportMap = { imports: { ...importMap.imports, ...utilsImportMaps } }
store.setImportMap(newImportMap)
}
const getBlocksSchema = async (pageSchema, blockSet = new Set()) => {
let res = []
const blockNames = parseRequiredBlocks(pageSchema)
const promiseList = blockNames
.filter((name) => {
if (blockSet.has(name)) {
return false
}
blockSet.add(name)
return true
})
.map((name) => fetchBlockSchema(name))
const schemaList = await Promise.allSettled(promiseList)
schemaList.forEach((item) => {
if (item.status === 'fulfilled' && item.value?.[0]?.content) {
res.push(item.value[0].content)
res.push(...getBlocksSchema(item.value[0].content, blockSet))
}
})
return res
}
const queryParams = getSearchParams()
const promiseList = [fetchCode(queryParams), fetchMetaData(queryParams), setFiles(srcFiles, 'src/Main.vue')]
Promise.all(promiseList).then(([codeList, metaData]) => {
const promiseList = [
fetchAppSchema(queryParams?.app),
fetchMetaData(queryParams),
setFiles(srcFiles, 'src/Main.vue')
]
Promise.all(promiseList).then(async ([appData, metaData]) => {
addUtilsImportMap(metaData.utils || [])
const codeErrorMsgs = codeList
.filter(({ errors }) => errors?.length)
.map(({ errors }) => errors)
.flat()
.map(({ message }) => message)
if (codeErrorMsgs.length) {
const title = PreviewTips.ERROR_WHEN_COMPILE
Notify({
type: 'error',
title,
message: codeErrorMsgs.join('\n'),
// 不自动关闭
duration: 0,
position: 'top-right'
})
return title
}
const blocks = await getBlocksSchema(queryParams.pageInfo?.schema)
// TODO: 需要验证级联生成 block schema
// TODO: 物料内置 block 需要如何处理?
const pageCode = [
{
panelName: 'Main.vue',
panelValue:
genSFCWithDefaultPlugin(queryParams.pageInfo?.schema, appData?.componentsMap || [], {
blockRelativePath: './'
}) || '',
panelType: 'vue',
index: true
},
...(blocks || []).map((blockSchema) => {
return {
panelName: blockSchema.fileName,
panelValue:
genSFCWithDefaultPlugin(blockSchema, appData?.componentsMap || [], { blockRelativePath: './' }) || '',
panelType: 'vue',
index: true
}
})
]
// [@vue/repl] `Only lang="ts" is supported for <script> blocks.`
const langReg = /lang="jsx"/
Expand Down Expand Up @@ -143,7 +180,7 @@ export default {
newFiles['app.js'] = appJsCode
codeList.map(fixScriptLang).forEach(assignFiles)
pageCode.map(fixScriptLang).forEach(assignFiles)
const metaFiles = generateMetaFiles(metaData)
Object.assign(newFiles, metaFiles)
Expand Down
3 changes: 3 additions & 0 deletions packages/design-core/src/preview/src/preview/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ export const fetchMetaData = async ({ platform, app, type, id, history, tenant }
params: { platform, app, type, id, history }
})
: {}

export const fetchAppSchema = async (id) => http.get(`/app-center/v1/api/apps/schema/${id}`)
export const fetchBlockSchema = async (blockName) => http.get(`/material-center/api/block?label=${blockName}`)
65 changes: 65 additions & 0 deletions packages/design-core/src/preview/src/preview/srcFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,69 @@ srcFiles['locales.js'] = localesJS
srcFiles['stores.js'] = storesJS
srcFiles['storesHelper.js'] = storesHelperJS

export const genPreviewTemplate = () => {
return [
{
fileName: 'App.vue',
path: '',
fileContent: appVue
},
{
fileName: 'constant.js',
path: '',
fileContent: constantJS
},
{
fileName: 'app.js',
path: '',
fileContent: appJS.replace(/VITE_CDN_DOMAIN/g, import.meta.env.VITE_CDN_DOMAIN)
},
{
fileName: 'injectGlobal.js',
path: '',
fileContent: injectGlobalJS
},
{
fileName: 'lowcode.js',
path: '',
fileContent: lowcodeJS
},
{
fileName: 'dataSourceMap.js',
path: '',
fileContent: dataSourceMapJS
},
{
fileName: 'dataSource.js',
path: '',
fileContent: dataSourceJS
},
{
fileName: 'utils.js',
path: '',
fileContent: utilsJS
},
{
fileName: 'bridge.js',
path: '',
fileContent: bridgeJS
},
{
fileName: 'locales.js',
path: '',
fileContent: localesJS
},
{
fileName: 'stores.js',
path: '',
fileContent: storesJS
},
{
fileName: 'storesHelper.js',
path: '',
fileContent: storesHelperJS
}
]
}

export default srcFiles
1 change: 1 addition & 0 deletions packages/toolbars/generate-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"@opentiny/tiny-engine-canvas": "workspace:*",
"@opentiny/tiny-engine-controller": "workspace:*",
"@opentiny/tiny-engine-dsl-vue": "workspace:*",
"@opentiny/tiny-engine-http": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"prettier": "2.7.1"
Expand Down
25 changes: 20 additions & 5 deletions packages/toolbars/generate-vue/src/FileSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,30 @@ export default {
emits: ['cancel', 'confirm'],
setup(props, { emit }) {
const getTableTreeData = (data) => {
const dataMap = {}
const res = []
data.forEach((item) => {
if (!dataMap[item.fileType]) {
dataMap[item.fileType] = { fileType: item.fileType, children: [] }
const folder = item.filePath.split('/').slice(0, -1)
if (!folder.length) {
res.push(item)
return
}
dataMap[item.fileType].children.push(item)
const parentFolder = folder.reduce((parent, curPath) => {
let curItem = parent.find((parItem) => parItem.path === curPath)
if (!curItem) {
curItem = { path: curPath, filePath: curPath, children: [] }
parent.push(curItem)
}
return curItem.children
}, res)
parentFolder.push(item)
})
return Object.values(dataMap)
return res
}
const tableData = computed(() => getTableTreeData(props.data))
Expand Down
Loading

0 comments on commit 3a66996

Please sign in to comment.