mcpField
D
d2-04-search-delete-page

d2-04-search-delete-page

github.com/softinter-chiangrai開発040 回インストール9 週間前に更新
リポジトリ

d2-04-search-delete-page について

CRUD機能の選択に応じて操作を切り替える検索リストページを作るためのAngular開発スキルです。signalによる状態管理、データ取得、ルーティング、削除確認を扱います。

主な機能

  1. 01機能に応じた追加・削除ボタン
  2. 02signalによるリスト状態管理
  3. 03エンティティレコードの取得と表示
  4. 04編集・戻る・新規作成の画面遷移
  5. 05削除確認とリスト更新

活用シーン

  1. 01編集機能付きのエンティティ検索ページ作成
  2. 02プロジェクトで無効な操作の非表示
  3. 03削除確認後のリスト更新実装

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/softinter-chiangrai/up-ai-skill-training --skill d2-04-search-delete-page

インストール後、Claude Code で/d2-04-search-delete-pageを入力して読み込まれたか確認します。

詳細

2 日目 · ステップ 4 — 機能に基づいた機能を備えた検索ページ

**注記:**このスキルは、d2-03-main-menu で選択した機能に応じて変わります。

  • search が選択されている場合:編集ボタン付きの一覧を表示します
  • delete も選択されている場合:インライン確認ポップアップ付きの削除ボタンを追加します
  • search のみの場合:削除ボタンは表示されません

up-app/src/app/pages/<entity>-search/<entity>-search.component.ts(スタンドアロンコンポーネント):

  • signal<Entity[]>([]) を使用して項目一覧を保存します。データを取得したら、.set() を呼び出して更新します。
  • 初期化時に <entity>Service.getAll() を呼び出し、this.items.set(data) でシグナルを更新します。
  • create 機能が有効な場合:追加ボタンを含むヘッダーバーを表示し、router.navigate(['/<entity>/new']) に移動します。
  • ホーム/メニューに移動する 戻る ボタンを追加し、router.navigate(['/']) に移動します。
  • 行ごと(@for と track item.id を使用):
    • 編集ボタン → router.navigate(['/<entity>', item.id, 'edit'])(常に含めます)
    • 削除ボタン(delete 機能が選択されている場合のみ)→ 確認ポップアップを表示します。確認されたら、<entity>Service.delete(id) を呼び出し、成功時に .set() でシグナルを更新します。

**ルート:**すでに d2-03-main-menu で定義済みです(完全な app.routes.ts)。このスキルでは、ナビゲーションにこれらのルートを使用します。

コンポーネントの TypeScript:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { CommonModule } from '@angular/common';
import { signal } from '@angular/core';
import { <Entity>Service, <Entity> } from '../../services/<entity>.service';

@Component({
  selector: 'app-<entity>-search',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './<entity>-search.component.html',
  styleUrls: ['./<entity>-search.component.css']
})
export class <Entity>SearchComponent implements OnInit {
  items = signal<<Entity>[]>([]);
  
  // Capability flags (set based on selections from d2-03)
  hasCreateCapability = true;   // Set to false if 'create' not selected
  hasDeleteCapability = true;   // Set to false if 'delete' not selected

  constructor(
    private router: Router,
    private <entity>Service: <Entity>Service
  ) {}

  ngOnInit() {
    this.<entity>Service.getAll().subscribe(data => {
      this.items.set(data);
    });
  }

  onBack() {
    this.router.navigate(['/']);  // Navigate back to menu/home
  }

  onAdd() {
    this.router.navigate([`/<entity>/new`]);
  }

  onEdit(id: number | undefined) {
    if (id) {
      this.router.navigate(['/<entity>', id, 'edit']);
    }
  }

  onDelete(item: <Entity>) {
    if (confirm(`Delete "<property name from item>"?`)) {
      if (item.id) {
        this.<entity>Service.delete(item.id).subscribe(() => {
          const current = this.items();
          this.items.set(current.filter(i => i.id !== item.id));
        });
      }
    }
  }
}

テンプレート(柔軟な列、戻るボタン、機能に基づいた削除機能を含む):

<div class="min-h-screen bg-gray-50">
  <div class="max-w-4xl mx-auto p-6">
    
    <div class="flex justify-between items-center mb-6">
      <div class="flex items-center gap-4">
        <button
          (click)="onBack()"
          class="bg-gray-500 hover:bg-gray-600 text-white font-semibold px-4 py-2 rounded-lg transition"
        >
          ← Back
        </button>
        <h1 class="text-4xl font-bold text-gray-900"><Entity> List</h1>
      </div>
      @if (hasCreateCapability) {
        <button
          (click)="onAdd()"
          class="bg-green-500 hover:bg-green-600 text-white font-semibold px-6 py-3 rounded-lg transition shadow-md"
        >
          + Add New
        </button>
      }
    </div>

    
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
      <div class="overflow-x-auto">
        <table class="min-w-full">
          <thead>
            <tr class="bg-gray-100 border-b border-gray-200">
              
              <th class="px-6 py-3 text-left font-semibold text-gray-700">Code</th>
              <th class="px-6 py-3 text-left font-semibold text-gray-700">Name</th>
              <th class="px-6 py-3 text-left font-semibold text-gray-700">Address</th>
              <th class="px-6 py-3 text-left font-semibold text-gray-700">Phone</th>
              <th class="px-6 py-3 text-center font-semibold text-gray-700">Actions</th>
            </tr>
          </thead>
          <tbody>
            @for (item of items(); track item.id) {
              <tr class="border-b border-gray-100 hover:bg-gray-50 transition">
                
                <td class="px-6 py-3 text-gray-900 font-medium">{{ item.empCode }}</td>
                <td class="px-6 py-3 text-gray-900">{{ item.empName }}</td>
                <td class="px-6 py-3 text-gray-700">{{ item.address || "-" }}</td>
                <td class="px-6 py-3 text-gray-700">{{ item.phoneNo || "-" }}</td>
                <td class="px-6 py-3 text-center">
                  <button
                    (click)="onEdit(item.id)"
                    class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg mr-2 transition text-sm font-semibold"
                  >
                    Edit
                  </button>
                  @if (hasDeleteCapability) {
                    <button
                      (click)="onDelete(item)"
                      class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition text-sm font-semibold"
                    >
                      Delete
                    </button>
                  }
                </td>
              </tr>
            }
          </tbody>
        </table>
      </div>

      @if (items().length === 0) {
        <div class="text-center py-8 text-gray-600">
          <p class="text-lg">No <entity> found. 
            @if (hasCreateCapability) {
              <a href="javascript:" (click)="onAdd()" class="text-blue-500 hover:underline">Create one</a>.
            } @else {
              Contact your administrator to create records.
            }
          </p>
        </div>
      }
    </div>
  </div>
</div>

列のカスタマイズ:

  • empCode、empName、address、phoneNo を、エンティティの実際のプロパティ名に置き換えます
  • テーブルのヘッダー <th> とデータ <td> の列を追加/削除して、エンティティの構成に合わせます
  • 空または null のオプション項目には || "-" を使用してダッシュを表示します

機能フラグ:

  • d2-03 での選択内容に基づいて hasCreateCapability と hasDeleteCapability を設定します
  • false の場合、追加ボタンと削除ボタンは表示されません
  • CRUD 要件に応じてボタンを動的に調整します

コメント