Реализация генерации шаблонов страниц клиента
All checks were successful
continuous-integration/drone/tag Build is passing

This commit is contained in:
Ymnuk 2023-08-11 12:28:30 +03:00
parent 37524245b8
commit 87fa4bfd29
11 changed files with 265 additions and 7 deletions

View File

@ -11,15 +11,15 @@ import (
func generateBackendRest() {
type RestStruct struct {
/*type RestStruct struct {
Path string
Project *structs.Project
Rest *structs.Rest
}
}*/
if len(Project.Backend.Rest) > 0 {
for i := range Project.Backend.Rest {
restStruct := &RestStruct{
restStruct := &structs.RestStruct{
Project: Project,
Path: i,
Rest: Project.Backend.Rest[i],

View File

@ -1,6 +1,7 @@
package lib
import (
"fmt"
"log"
"os"
"path/filepath"
@ -113,10 +114,6 @@ func generateFrontendAngularTmpl() {
FileIn: "tmpl/frontend/angular/src/app/page/user/user.component.ts.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", "user", "user.component.ts"),
},
{
FileIn: "tmpl/frontend/angular/src/app/app-routing.module.ts.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "app-routing.module.ts"),
},
{
FileIn: "tmpl/frontend/angular/src/app/app.component.html.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "app.component.html"),
@ -213,4 +210,73 @@ func generateFrontendAngularTmpl() {
}
}
templs := []structs.TmplInOut{
{
FileIn: "tmpl/frontend/angular/src/app/app-routing.module.ts.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "app-routing.module.ts"),
},
}
for _, staticTmpls := range templs {
err := templ.PrepareTmplFile(staticTmpls.FileIn, Project, staticTmpls.FileOut)
if err != nil {
log.Fatal(err)
}
}
/*templs = []structs.TmplInOut{
{
FileIn: "tmpl/frontend/angular/src/app/page/page.component.ts.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "app-routing.module.ts"),
},
}*/
for i, rest := range Project.Backend.Rest {
restStruct := structs.RestStruct{
Path: i,
Project: Project,
Rest: rest,
}
templs := []structs.TmplInOut{
{
FileIn: "tmpl/frontend/angular/src/app/page/page/page.component.ts.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", templ.RemoveFirstChar(i), fmt.Sprintf("%s.component.ts", templ.AngularFilename(i))),
},
{
FileIn: "tmpl/frontend/angular/src/app/page/page/page.component.scss.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", templ.RemoveFirstChar(i), fmt.Sprintf("%s.component.scss", templ.AngularFilename(i))),
},
{
FileIn: "tmpl/frontend/angular/src/app/page/page/page.component.html.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", templ.RemoveFirstChar(i), fmt.Sprintf("%s.component.html", templ.AngularFilename(i))),
},
}
for _, item := range templs {
if err := templ.PrepareTmplIsNotExists(item.FileIn, restStruct, item.FileOut); err != nil {
log.Fatal(err)
}
}
if rest.Editable {
templs := []structs.TmplInOut{
{
FileIn: "tmpl/frontend/angular/src/app/page/page/form/form.component.ts.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", templ.RemoveFirstChar(i), "form", fmt.Sprintf("%s-form.component.ts", templ.AngularFilename(i))),
},
{
FileIn: "tmpl/frontend/angular/src/app/page/page/form/form.component.scss.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", templ.RemoveFirstChar(i), "form", fmt.Sprintf("%s-form.component.scss", templ.AngularFilename(i))),
},
{
FileIn: "tmpl/frontend/angular/src/app/page/page/form/form.component.html.tmpl",
FileOut: filepath.Join(AppConfig.OutdirFrontend, "src", "app", "page", templ.RemoveFirstChar(i), "form", fmt.Sprintf("%s-form.component.html", templ.AngularFilename(i))),
},
}
for _, item := range templs {
if err := templ.PrepareTmplIsNotExists(item.FileIn, restStruct, item.FileOut); err != nil {
log.Fatal(err)
}
}
}
}
}

View File

@ -43,6 +43,11 @@ var funcMap = template.FuncMap{
"isMethod": IsMethod,
"roles": Roles,
"removeFirstChar": RemoveFirstChar,
"angularRestName": AngularRestName,
"angularFilename": AngularFilename,
}
func IsMethod(arr map[string][]string, method string) bool {
@ -340,3 +345,44 @@ func MkdirIsNotExists(pathdir string) (err error) {
err = nil
return
}
func AngularRestName(tmp string) string {
value := tmp
value = strings.Trim(value, " ")
if value == "" {
return "Unknow"
}
value = strings.ReplaceAll(value, "/", "_")
value = FieldNamePrepare(value)
/*var regexpForReplace = regexp.MustCompile(`_([a-z])`)
value = strings.ToUpper(regexpForReplace.ReplaceAllString(value, `$1`))
asRunes := []rune(value)
asRunes[0] = []rune(strings.ToUpper(string([]rune(value)[0])))[0]
value = string(asRunes)*/
return value
}
func AngularFilename(value string) string {
value = strings.Trim(value, " ")
if value == "" {
return "unknow"
}
value = strings.ReplaceAll(value, "/", "-")
if []rune(value)[0] == '-' {
value = string([]rune(value)[1:])
}
return value
}
func RemoveFirstChar(value string) string {
value = strings.Trim(value, " ")
if value == "" {
return ""
}
value = string([]rune(value)[1:])
return value
}

View File

@ -6,6 +6,13 @@ import { LoginComponent } from './page/login/login.component';
import { UsersComponent } from './page/user/user.component';
import { UserFormComponent } from './page/user/user-form/user-form.component';
{{ range $index, $rest := .Backend.Rest }}
import { {{ angularRestName $index }}Component } from './page/{{ removeFirstChar $index }}/{{ angularFilename $index }}.component';
{{ if $rest.Editable }}
import { {{ angularRestName $index }}FormComponent } from './page/{{ removeFirstChar $index }}/form/{{ angularFilename $index }}-form.component';
{{ end }}
{{ end }}
const routes: Routes = [
{
@ -20,6 +27,14 @@ const routes: Routes = [
{ path: 'users/new', component: UserFormComponent },
{ path: 'users/:id', component: UserFormComponent },
{{ range $index, $rest := .Backend.Rest }}
{ path: '{{ removeFirstChar $index }}', component: {{ angularRestName $index }}Component },
{{ if $rest.Editable }}
{ path: '{{ removeFirstChar $index }}/new', component: {{ angularRestName $index }}FormComponent },
{ path: '{{ removeFirstChar $index }}/:id', component: {{ angularRestName $index }}FormComponent },
{{ end }}
{{ end }}
]
}
];

View File

@ -0,0 +1,13 @@
<div class="center">
<p-card header="Пользователь">
<form [formGroup]="form">
<div class="button">
<button pButton pRipple (click)="onSave()"label="Сохранить" class="p-button-raised"
[disabled]="form.invalid || form.disabled"></button>
<button pButton pRipple (click)="onCancel()"label="Отмена" class="p-button-raised"
[disabled]="form.invalid || form.disabled"></button>
</div>
</form>
</p-card>
</div>

View File

@ -0,0 +1 @@
// Empty styles

View File

@ -0,0 +1,54 @@
import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms';
import { Subscription, Observable, firstValueFrom } from 'rxjs';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { MessageService } from 'primeng/api';
@Component({
selector: 'app-{{ angularFilename .Path }}-form',
templateUrl: './{{ angularFilename .Path }}-form.component.html',
styleUrls: ['./{{ angularFilename .Path }}-form.component.scss']
})
export class {{ angularRestName .Path }}FormComponent implements OnInit, AfterViewInit, OnDestroy {
private id?: string; // Идентификатор
public form: UntypedFormGroup = new UntypedFormGroup({
// TODO
});
constructor(
private router: Router,
private route: ActivatedRoute,
private toast: MessageService
) {
}
ngAfterViewInit(): void {
// Получим переданные параметры (id)
this.route.params.subscribe((params: Params) => {
if (params['id'] != null) {
this.id = params['id'];
// Получаем данные с сервера о выбранном пользователе
} else {
this.id = undefined;
}
});
}
ngOnDestroy(): void {
// TODO
}
ngOnInit(): void {
// TODO
}
onSave(): void {
// TODO
}
onCancel(): void {
this.router.navigate(['/{{ removeFirstChar .Path }}']);
}
}

View File

@ -0,0 +1,12 @@
<p-button type="button" (click)="OnNewItem()">Добавить</p-button>
<p-table [value]="users" responsiveLayout="scroll" [rows]="10" [showCurrentPageReport]="true"
[rowsPerPageOptions]="[10,25,50]" [paginator]="true"
currentPageReportTemplate="Отображено с {first} по {last} из {totalRecords} записей">
<ng-template pTemplate="header">
</ng-template>
<ng-template pTemplate="body" let-element>
</ng-template>
</p-table>

View File

@ -0,0 +1,3 @@
table {
width: 100%;
}

View File

@ -0,0 +1,41 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { firstValueFrom, Observable, Subscription } from 'rxjs';
import { Router } from '@angular/router';
import { UntypedFormControl } from '@angular/forms';
import { MessageService } from 'primeng/api';
@Component({
selector: 'app-{{ angularFilename .Path }}',
templateUrl: './{{ angularFilename .Path }}.component.html',
styleUrls: ['./{{ angularFilename .Path }}.component.scss']
})
export class {{ angularRestName .Path }}Component implements OnInit, OnDestroy {
constructor(
private toast: MessageService,
private router: Router
) { }
ngOnDestroy(): void { }
private refreshData(): void {
// TODO
}
ngOnInit(): void {
this.refreshData();
}
onEdit(id:any): void {
this.router.navigate(['/{{ removeFirstChar .Path }}', id]);
}
onDelete(id:any): void {
// TODO
}
OnNewItem(): void {
this.router.navigate(['/{{ removeFirstChar .Path }}/new']);
}
}

7
structs/rest-struct.go Normal file
View File

@ -0,0 +1,7 @@
package structs
type RestStruct struct {
Path string
Project *Project
Rest *Rest
}