支持了虚拟组件的创建,增强了创建流程

This commit is contained in:
Pan Qiancheng 2024-11-16 16:20:36 +08:00
parent 76746f668c
commit 804061618e
6 changed files with 83 additions and 33 deletions

View File

@ -8,6 +8,7 @@ import { join } from 'path';
import { ComponentsItem } from './oakTreePanel';
type ConfigStep = {
skip?: (config: CreateComponentConfig) => boolean;
name: keyof CreateComponentConfig;
description: string;
inputType: 'input' | 'select' | 'confirm';
@ -19,7 +20,7 @@ type ConfigStep = {
validate?: (value: string) => boolean;
};
const withSelectEntity: ConfigStep[] = [
const defaultSteps: ConfigStep[] = [
{
name: 'folderName',
description: '请输入组件名称',
@ -27,7 +28,7 @@ const withSelectEntity: ConfigStep[] = [
validate: (value) => {
// 合法正则表达式
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(value);
}
},
},
{
name: 'renderFile',
@ -45,28 +46,29 @@ const withSelectEntity: ConfigStep[] = [
many: true,
},
{
// 如果已经选择了实体,则跳过
skip: (config) => !!config.entityName,
name: 'entityName',
description: '请选择关联实体',
inputType: 'select',
options: () => entityConfig.entityNameList,
options: () => ['虚拟组件', ...entityConfig.entityNameList],
},
{
// 如果选择了虚拟组件,则跳过
skip: (config) => config.entityName === '虚拟组件',
name: 'isList',
description: '是否为列表',
inputType: 'confirm',
},
{
// 如果选择了虚拟组件,则跳过
skip: (config) => config.entityName === '虚拟组件',
name: 'autoProjection',
description: '是否注入Projection',
inputType: 'confirm',
},
];
// 从withSelectEntity中排除第二步骤
const createComponentSteps: ConfigStep[] = withSelectEntity
.slice(0, 2)
.concat(withSelectEntity.slice(3));
const afterCreateComponent = async (folderPath: string) => {
console.log('执行创建后操作folderPath:', folderPath);
// updateEntityComponent(normalizePath(join(folderPath, "index.ts")));
@ -78,6 +80,7 @@ const goCreate = async (
config?: Partial<CreateComponentConfig>
) => {
const createComponentConfig: CreateComponentConfig = {
isVirtual: false,
folderName: '',
entityName: '',
isList: false,
@ -86,6 +89,9 @@ const goCreate = async (
...config,
};
for (const step of steps) {
if (step.skip && step.skip(createComponentConfig)) {
continue;
}
if (step.inputType === 'input') {
const result = await vscode.window.showInputBox({
prompt: step.description,
@ -155,7 +161,7 @@ const plugin = vscode.commands.registerCommand(
if (uri instanceof ComponentsItem) {
const entityName = uri.getEntityName();
const componentsPath = join(pathConfig.componentsHome, entityName);
goCreate(componentsPath, createComponentSteps, {
goCreate(componentsPath, defaultSteps, {
entityName,
});
return;
@ -179,7 +185,7 @@ const plugin = vscode.commands.registerCommand(
);
}
goCreate(folderPath, withSelectEntity);
goCreate(folderPath, defaultSteps);
}
);

View File

@ -1,5 +1,9 @@
export default OakComponent({
{{#if isVirtual}}
// Virtual Component
{{else}}
entity: '{{entityName}}',
{{/if}}
isList: {{isList}},
{{#if autoProjection}}
projection: {

View File

@ -9,16 +9,27 @@ const {{componentName}} = (
'{{entityName}}',
{{isList}},
{
{{#if isList}}
list: RowWithActions<EntityDict, '{{entityName}}'>[];
{{#if isVirtual}}
// virtual
{{else}}
{{#if isList}}
list: RowWithActions<EntityDict, '{{entityName}}'>[];
{{else}}
item: RowWithActions<EntityDict, '{{entityName}}'>;
{{/if}}
{{/if}}
}
>
) => {
{{#if isVirtual}}
const { oakFullpath } = props.data;
{{else}}
const { {{#if isList}}list{{else}}item{{/if}} } = props.data;
{{/if}}
{{#if isVirtual}}
return (<> 虚拟组件 </>);
{{else}}
return (
<>
{{#if isList}}
@ -34,6 +45,7 @@ const {{componentName}} = (
{{/if}}
</>
);
{{/if}}
};
export default {{componentName}};

View File

@ -9,16 +9,27 @@ const {{componentName}} = (
'{{entityName}}',
{{isList}},
{
{{#if isList}}
list: RowWithActions<EntityDict, '{{entityName}}'>[];
{{#if isVirtual}}
// virtual
{{else}}
{{#if isList}}
list: RowWithActions<EntityDict, '{{entityName}}'>[];
{{else}}
item: RowWithActions<EntityDict, '{{entityName}}'>;
{{/if}}
{{/if}}
}
>
) => {
{{#if isVirtual}}
const { oakFullpath } = props.data;
{{else}}
const { {{#if isList}}list{{else}}item{{/if}} } = props.data;
{{/if}}
{{#if isVirtual}}
return (<> 虚拟组件 </>);
{{else}}
return (
<>
{{#if isList}}
@ -34,6 +45,7 @@ const {{componentName}} = (
{{/if}}
</>
);
{{/if}}
};
export default {{componentName}};

View File

@ -7,6 +7,7 @@ import {
} from 'oak-domain/lib/types';
export type CreateComponentConfig = {
isVirtual: boolean;
folderName: string;
entityName: string;
isList: boolean;
@ -15,6 +16,7 @@ export type CreateComponentConfig = {
};
export type IndexTsTemplate = {
isVirtual: boolean;
entityName: string;
isList: boolean;
autoProjection: boolean;
@ -22,6 +24,7 @@ export type IndexTsTemplate = {
};
export type ComponentTemplate = {
isVirtual: boolean;
componentName: string;
entityName: string;
isList: boolean;

View File

@ -77,24 +77,37 @@ export const generateTemplate = (
outPath: string,
config: CreateComponentConfig
) => {
const componentName = toUpperFirst(config.folderName);
const realConfig = { ...config };
// 判断是否为Virtual
if (realConfig.entityName === '虚拟组件') {
realConfig.isVirtual = true;
realConfig.entityName = 'user';
realConfig.isList = false;
realConfig.autoProjection = false;
}
const componentName = toUpperFirst(realConfig.folderName);
const data: CreateOakComponent = {
index: {
entityName: config.entityName,
isList: config.isList,
autoProjection: config.autoProjection,
projectionFields: genProjections(config.entityName),
isVirtual: realConfig.isVirtual,
entityName: realConfig.entityName,
isList: realConfig.isList,
autoProjection: realConfig.autoProjection,
projectionFields: genProjections(realConfig.entityName),
},
webPcTsx: {
isVirtual: realConfig.isVirtual,
componentName,
entityName: config.entityName,
isList: config.isList,
entityName: realConfig.entityName,
isList: realConfig.isList,
},
webTsx: {
isVirtual: realConfig.isVirtual,
componentName,
entityName: config.entityName,
isList: config.isList,
entityName: realConfig.entityName,
isList: realConfig.isList,
},
localeZhCN: {},
styleLess: {},
@ -103,28 +116,28 @@ export const generateTemplate = (
},
};
// render文件
config.renderFile.includes('web.pc.tsx') &&
realConfig.renderFile.includes('web.pc.tsx') &&
outputTemplate('webPcTsx', data.webPcTsx, outPath);
config.renderFile.includes('web.tsx') &&
realConfig.renderFile.includes('web.tsx') &&
outputTemplate('webTsx', data.webTsx, outPath);
config.renderFile.includes('index.xml') &&
realConfig.renderFile.includes('index.xml') &&
outputTemplate('indexXml', {}, outPath);
config.renderFile.includes('index.xml') &&
realConfig.renderFile.includes('index.xml') &&
outputTemplate('indexLess', {}, outPath);
config.renderFile.includes('render.native.tsx') &&
realConfig.renderFile.includes('render.native.tsx') &&
outputTemplate('renderNativeTsx', {}, outPath);
config.renderFile.includes('render.ios.tsx') &&
realConfig.renderFile.includes('render.ios.tsx') &&
outputTemplate('renderIosTsx', {}, outPath);
config.renderFile.includes('render.android.tsx') &&
realConfig.renderFile.includes('render.android.tsx') &&
outputTemplate('renderAndroidTsx', {}, outPath);
// index.json
config.renderFile.includes('index.xml') &&
realConfig.renderFile.includes('index.xml') &&
outputTemplate('indexJson', {}, outPath);
// 其他文件
outputTemplate('localeZhCN', data.localeZhCN, outPath);
(config.renderFile.includes('web.pc.tsx') ||
config.renderFile.includes('web.tsx')) &&
(realConfig.renderFile.includes('web.pc.tsx') ||
realConfig.renderFile.includes('web.tsx')) &&
outputTemplate('styleLess', data.styleLess, outPath);
// 因为这里涉及到组件的扫描index.ts 文件需要在最后生成
outputTemplate('index', data.index, outPath);