关于 d2-03-main-menu
此开发技能根据必填的实体名称和所选能力,为 Angular 应用构建首页菜单,并规定共用路由表及响应式 Tailwind 卡片网格设计。
主要功能
- 01根据所选能力生成菜单项
- 02将菜单设为默认首页路由
- 03配置共用的搜索与表单路由
- 04使用响应式 Tailwind 卡片网格
适用场景
- 01为实体型应用创建首页菜单
- 02仅显示受支持的搜索与记录操作
- 03协调菜单、搜索和表单页面的路由
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ softinter-chiangrai/ up-ai-skill-training --skill d2-03-main-menu安装后在 Claude Code 中输入/d2-03-main-menu确认已加载。
详细介绍
第 2 天 · 步骤 3 — 根据功能动态生成菜单项的主菜单
开始前: 请提供:
- 实体名称(PascalCase,例如:
Product、Order、Employee)——必填 - 可用功能(选择一个或多个:
search、create、save、delete)——必填search:浏览/列出所有记录create:创建新记录save:保存到数据库(用于创建/编辑)delete:删除记录
请严格按指定内容使用。菜单按钮将根据所选功能生成。
路由设置(app.routes.ts)——所有页面的完整路由表:
- 导入 MenuComponent、所有 SearchComponents 和所有 FormComponents
- 将菜单设为默认/着陆页路由(路径:'')
- 为每个程序定义实体路由:搜索、创建、编辑
- 此路由表由 d2-03(菜单)、d2-04(搜索)和 d2-05(表单)共用
import { Routes } from '@angular/router';
import { MenuComponent } from './pages/menu/menu.component';
import { <Entity>SearchComponent } from './pages/<entity>-search/<entity>-search.component';
import { <Entity>FormComponent } from './pages/<entity>-form/<entity>-form.component';
// Add more imports for additional entities as needed
export const routes: Routes = [
// Landing page (menu comes first!)
{ path: '', component: MenuComponent },
// <Entity> CRUD routes
{ path: '<entity>', component: <Entity>SearchComponent }, // Search/list page
{ path: '<entity>/new', component: <Entity>FormComponent }, // Create new record
{ path: '<entity>/:id/edit', component: <Entity>FormComponent }, // Edit existing record
// Add more entity routes here for additional programs:
// { path: 'customer', component: CustomerSearchComponent },
// { path: 'customer/new', component: CustomerFormComponent },
// { path: 'customer/:id/edit', component: CustomerFormComponent },
];
路由用法:
- d2-03-main-menu 使用
{ path: '', component: MenuComponent }——着陆页 - d2-04-search-delete-page 使用
/<entity>路由,并通过router.navigate(['/<entity>/new'])、router.navigate(['/<entity>', id, 'edit'])进行导航 - d2-05-form-page 使用
/<entity>/new和/<entity>/:id/edit路由
组件 TypeScript(根据功能动态生成):
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { CommonModule } from '@angular/common';
interface MenuItem {
name: string;
icon: string;
path: string;
}
interface Program {
name: string;
entity: string;
icon: string;
description: string;
capabilities: string[];
menuItems: MenuItem[];
}
@Component({
selector: 'app-menu',
standalone: true,
imports: [CommonModule],
templateUrl: './menu.component.html',
styleUrls: ['./menu.component.css']
})
export class MenuComponent {
appTitle = 'CRUD Dashboard';
appSubtitle = 'Manage your data with ease';
programs: Program[] = [];
constructor(private router: Router) {
this.programs = [
{
name: '<Entity>',
entity: '<entity>',
icon: '📦',
description: 'Manage <entity> records',
capabilities: ['search', 'create', 'save', 'delete'],
menuItems: this.generateMenuItems('<entity>', ['search', 'create', 'save', 'delete'])
},
// Add more programs here:
// { name: 'Customer', entity: 'customer', icon: '👥', description: 'Manage customer data', capabilities: [...], menuItems: ... }
];
}
generateMenuItems(entity: string, capabilities: string[]): MenuItem[] {
const items: MenuItem[] = [];
if (capabilities.includes('search')) {
items.push({ name: 'Browse', icon: '📋', path: `/${entity}` });
}
if (capabilities.includes('create')) {
items.push({ name: 'Create', icon: '✚', path: `/${entity}/new` });
}
return items;
}
navigate(path: string) {
this.router.navigate([path]);
}
}
模板(根据功能动态生成的菜单,包含响应式卡片网格和标准 Tailwind 类):
<div class="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 p-6">
<div class="max-w-6xl mx-auto mb-12">
<div class="text-center mb-8">
<h1 class="text-5xl font-bold text-gray-900">{{ appTitle }}</h1>
<p class="text-gray-600 text-xl mt-4">{{ appSubtitle }}</p>
</div>
</div>
<div class="max-w-6xl mx-auto">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
@for (program of programs; track program.entity) {
<div class="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow p-6">
<div class="flex items-center mb-4">
<span class="text-5xl mr-4">{{ program.icon }}</span>
<div>
<h3 class="text-2xl font-bold text-gray-900">{{ program.name }}</h3>
<p class="text-gray-600 text-sm">{{ program.description }}</p>
</div>
</div>
<div class="flex flex-wrap gap-2 mb-4">
@for (cap of program.capabilities; track cap) {
<span class="bg-gray-100 text-gray-700 text-xs font-semibold px-3 py-1 rounded-full">
{{ cap }}
</span>
}
</div>
<div class="border-b border-gray-200 my-4"></div>
<div class="flex flex-col gap-4">
@for (item of program.menuItems; track item.name) {
<button
(click)="navigate(item.path)"
[class]="item.name === 'Browse' ? 'w-full text-white font-semibold px-6 py-3 rounded-lg transition bg-blue-500 hover:bg-blue-600' : 'w-full text-white font-semibold px-6 py-3 rounded-lg transition bg-green-500 hover:bg-green-600'"
>
{{ item.icon }} {{ item.name }}
</button>
}
</div>
@if (program.menuItems.length === 0) {
<p class="text-gray-600 text-sm text-center">No actions available for this program.</p>
}
</div>
}
</div>
</div>
<div class="max-w-6xl mx-auto mt-12 text-center">
<p class="text-gray-600 text-sm">Built with Angular + Tailwind CSS</p>
</div>
</div>
设计系统(标准 Tailwind):
- 间距: p-6(内边距)、mb-4/8/12、gap-2/4/8
- 颜色: bg-blue-500/600、bg-green-500/600、text-gray-600、bg-gray-100
- 阴影: shadow-md、hover:shadow-xl(卡片层级)
- 字体排版: text-5xl/2xl、font-bold/semibold
- 布局: 响应式网格(1-2-3 列)、flex flex-col
- 交互: rounded-lg、transition、悬停状态
评论
支持 Markdown