stackpress
Version:
Incept is a content management framework.
183 lines (182 loc) • 5.92 kB
JavaScript
import { VariableDeclarationKind } from 'ts-morph';
export default function createView(directory, _registry, model) {
const file = `${model.name}/admin/views/create.tsx`;
const source = directory.createSourceFile(file, '', { overwrite: true });
source.addImportDeclaration({
isTypeOnly: true,
moduleSpecifier: 'stackpress/view/client',
namedImports: ['NestedObject', 'ServerPageProps']
});
source.addImportDeclaration({
isTypeOnly: true,
moduleSpecifier: 'stackpress/admin/types',
namedImports: ['AdminConfigProps']
});
source.addImportDeclaration({
isTypeOnly: true,
moduleSpecifier: '../../types.js',
namedImports: [`${model.title}Input`, model.title]
});
source.addImportDeclaration({
moduleSpecifier: 'r22n',
namedImports: ['useLanguage']
});
source.addImportDeclaration({
moduleSpecifier: 'frui/form/Button',
defaultImport: 'Button'
});
source.addImportDeclaration({
moduleSpecifier: 'stackpress/view/client',
namedImports: ['useServer', 'Crumbs', 'LayoutAdmin']
});
model.fields.forEach(column => {
if (typeof column.field.component !== 'string')
return;
if (column.field.method === 'fieldset') {
source.addImportDeclaration({
moduleSpecifier: `../../components/fields/${column.title}Field.js`,
namedImports: [`${column.title}FieldsetControl`]
});
return;
}
source.addImportDeclaration({
moduleSpecifier: `../../components/fields/${column.title}Field.js`,
namedImports: [`${column.title}FieldControl`]
});
});
source.addFunction({
isExported: true,
name: `Admin${model.title}CreateCrumbs`,
statements: (`
//hooks
const { _ } = useLanguage();
//variables
const crumbs = [
{
label: (<span className="admin-crumb">{_('${model.plural}')}</span>),
icon: 'user',
href: 'search'
},
{
label: _('Create'),
icon: 'plus'
}
];
return (<Crumbs crumbs={crumbs} />);
`)
});
source.addFunction({
isExported: true,
name: `Admin${model.title}CreateForm`,
parameters: [{
name: 'props',
type: `{
input: Partial<${model.title}Input>,
errors: NestedObject<string | string[]>
}`
}],
statements: (`
const { input, errors } = props;
const { _ } = useLanguage();
return (
<form method="post">
${model.fields.map(column => column.field.method === 'fieldset' ? (`
<${column.title}FieldsetControl
className="control"
name="${column.name}"
value={input['${column.name}']}
errors={errors['${column.name}']}
/>
`) : (`
<${column.title}FieldControl
className="control"
name="${column.name}${column.multiple ? '[]' : ''}"
value={input['${column.name}']}
error={errors.${column.name}?.toString()}
/>
`)).join('\n')}
<Button className="submit" type="submit">
<i className="icon fas fa-fw fa-save"></i>
{_('Save')}
</Button>
</form>
);
`)
});
source.addFunction({
isExported: true,
name: `Admin${model.title}CreateBody`,
statements: (`
const { request, response } = useServer<${[
'AdminConfigProps',
`Partial<${model.title}Input>`,
model.title
].join(', ')}>();
const input = { ...response.results, ...request.data() };
const errors = response.errors();
//render
return (
<main className="admin-page admin-form-page">
<div className="admin-crumbs">
<Admin${model.title}CreateCrumbs />
</div>
<div className="admin-form">
<Admin${model.title}CreateForm errors={errors} input={input} />
</div>
</main>
);
`)
});
source.addFunction({
isExported: true,
name: `Admin${model.title}CreateHead`,
parameters: [{
name: 'props',
type: 'ServerPageProps<AdminConfigProps>'
}],
statements: (`
const { data, styles = [] } = props;
const { favicon = '/favicon.ico' } = data?.brand || {};
const { _ } = useLanguage();
const mimetype = favicon.endsWith('.png')
? 'image/png'
: favicon.endsWith('.svg')
? 'image/svg+xml'
: 'image/x-icon';
return (
<>
<title>{_('Create ${model.singular}')}</title>
{favicon && <link rel="icon" type={mimetype} href={favicon} />}
<link rel="stylesheet" type="text/css" href="/styles/global.css" />
{styles.map((href, index) => (
<link key={index} rel="stylesheet" type="text/css" href={href} />
))}
</>
);
`)
});
source.addFunction({
isExported: true,
name: `Admin${model.title}CreatePage`,
parameters: [{
name: 'props',
type: 'ServerPageProps<AdminConfigProps>'
}],
statements: (`
return (
<LayoutAdmin {...props}>
<Admin${model.title}CreateBody />
</LayoutAdmin>
);
`)
});
source.addVariableStatement({
isExported: true,
declarationKind: VariableDeclarationKind.Const,
declarations: [{
name: 'Head',
initializer: `Admin${model.title}CreateHead`
}]
});
source.addStatements(`export default Admin${model.title}CreatePage;`);
}