Custom Detail Task
Membuat komponen Micro Frontend (MFE) yang tampil sebagai custom Detail View di tab Detail task melalui slot custom_views.DETAILS pada Addon.
Secara default, tab Detail sebuah task menampilkan tampilan bawaan AlurKerja. Bila perlu tampilan kustom — kartu ringkasan, layout multi-kolom, integrasi data eksternal, atau visualisasi — Anda bisa menggantinya dengan komponen React Anda sendiri yang dibungkus sebagai Addon dengan slot custom_views.DETAILS.
Hasil Akhir
Jika Addon Anda mendaftarkan komponen di slot custom_views.DETAILS, AlurKerja akan me-load komponen tersebut di tab Detail seperti berikut.
Tampilan di atas menunjukkan komponen MFE kustom sudah ter-render dan menampilkan data sesuai konteks task.
Konsep
Yang menentukan sebuah view tampil di tab Input atau tab Detail adalah slot tempat ia dideklarasikan di custom_views pada index.json Addon:
| Slot | Tab yang dirender |
|---|---|
custom_views.FORMS | Tab Input (writable form) |
custom_views.DETAILS | Tab Detail (umumnya read-only) |
Klasifikasi ini tidak di-hardcode di Studio — Studio mengiterasi custom_views.DETAILS, lalu mengambil label tampilan dari section details di index.json.
views/src/TaskSummaryView.tsx ← 1. Komponen React (AlurkerjaMfeProps)
│
▼
views/webpack.config.js exposes ← 2. Expose lewat Module Federation
│ './task_summary_view'
▼
index.json custom_views.DETAILS ← 3. Daftarkan: "ticket_summary": "task_summary_view"
index.json details ← 4. Beri label tampilan
│
▼
yarn build → alurkerja addon publish ← 5. Build + publish via CLI
│
▼
Studio → tab Detail ← 6. VerifikasiDetail View bersifat read-only. Komponen di slot DETAILS umumnya hanya membaca data (mis. via form.getValues() atau fetch ke API) lalu menampilkannya — bukan menerima input. Tombol submit/aksi ditangani oleh platform.
Prasyarat
- Node.js & yarn/npm untuk membangun bundle MFE.
- AlurKerja CLI sudah terpasang dan login ke environment target — lihat AlurKerja CLI.
- Project Addon sudah disiapkan (struktur folder Addon +
index.json) — lihat Pembuatan Addon pada AlurKerja.
Step 1 — Buat Komponen Detail View
Buat file komponen di views/src/. Pakai tipe prop AlurkerjaMfeProps (didefinisikan di views/src/type/AlurkerjaType.ts), yang menyediakan:
form— helper React Hook Form:getValues,watch,register,setValue,control.alurkerjaParams— konteks runtime:apiBaseUrl,token,activeTenant,probis,taskId, dst.
Karena ini Detail View, komponen umumnya membaca data lalu menampilkannya (read-only).
File: views/src/TaskSummaryView.tsx
import React, { useEffect, useState } from "react";
import { AlurkerjaMfeProps } from "./type/AlurkerjaType";
export default function TaskSummaryView({ form, alurkerjaParams }: AlurkerjaMfeProps) {
// Baca data yang sudah ada di form (mis. hasil action sebelumnya).
const values = form.getValues?.() ?? {};
const ticket = values?.ticket_summary ?? values?.value ?? {};
const { apiBaseUrl, token, activeTenant, taskId } = alurkerjaParams ?? {};
// (Opsional) ambil detail tambahan dari API.
const [detail, setDetail] = useState<any>(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (!apiBaseUrl || !ticket?.id) return;
setLoading(true);
fetch(`${apiBaseUrl}/api/tickets/${ticket.id}`, {
headers: {
Authorization: `Bearer ${token}`,
"X-Tenant": activeTenant ?? "",
},
})
.then((r) => r.json())
.then(setDetail)
.catch(() => setDetail(null))
.finally(() => setLoading(false));
}, [apiBaseUrl, token, activeTenant, ticket?.id]);
const priority = detail?.priority ?? ticket?.priority ?? "Normal";
const priorityColor =
priority === "High" ? "bg-red-100 text-red-700" :
priority === "Medium" ? "bg-yellow-100 text-yellow-700" :
"bg-gray-100 text-gray-700";
const row = (label: string, value?: React.ReactNode) => (
<div className="grid grid-cols-[180px_1fr] gap-3 py-2 border-b border-gray-100">
<span className="text-sm text-gray-500">{label}</span>
<span className="text-sm text-gray-900">{value ?? "-"}</span>
</div>
);
return (
<div className="card max-w-4xl mx-auto p-4">
<h2 className="text-2xl font-bold text-gray-900 mb-6">Ringkasan Tiket</h2>
{loading && <p className="text-sm text-gray-500">Memuat detail…</p>}
<div className="bg-white rounded-lg">
{row("Nomor Tiket", detail?.nomor ?? ticket?.nomor)}
{row("Pelapor", detail?.reporter ?? ticket?.reporter)}
{row("Prioritas", (
<span className={`inline-block rounded px-2 py-0.5 text-xs ${priorityColor}`}>
{priority}
</span>
))}
{row("Dibuat", detail?.created_at ?? ticket?.created_at)}
{row("Task ID", taskId)}
</div>
</div>
);
}Pola data: Detail/Action views membaca field langsung (ticket_summary, nomor, dst.). Config views (CREATE/EDIT) memakai prefix value. (mis. value.fileName). Komponen view tidak berisi tombol submit — aksi ditangani oleh platform.
Step 2 — Expose Komponen di Webpack
Tambahkan komponen baru ke exposes pada ModuleFederationPlugin di views/webpack.config.js:
new ModuleFederationPlugin({
name: 'task_summary_view', // ← samakan dengan component_scope di index.json
filename: 'remoteEntry.js',
exposes: {
'./task_summary_view': './src/TaskSummaryView.tsx', // ← samakan dengan custom_views
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
'react-hook-form': { singleton: true },
},
}),Aturan penamaan: key di exposes ('./task_summary_view') harus sama persis dengan nilai yang dipakai di custom_views.DETAILS ("task_summary_view", tanpa ./). Gunakan snake_case, tanpa spasi/karakter khusus.
Step 3 — Daftarkan di custom_views.DETAILS
Edit index.json. Tambahkan entri pada slot DETAILS (key = identifier detail, value = nama komponen yang di-expose):
"custom_views": {
"DETAILS": {
"ticket_summary": "task_summary_view"
}
}Step 4 — Beri Nama Tampilan di Section details
Label yang tampil di tab Detail Studio diambil dari section details (paralel dengan forms / views):
"details": {
"ticket_summary": {
"name": "Ringkasan Tiket",
"description": "Detail view yang menampilkan ringkasan tiket."
}
}Perbedaan Input vs Detail:
- Input — sebuah form wajib ada di
formsdancustom_views.FORMS. - Detail — cukup ada di
custom_views.DETAILS; label diambil daridetails. Sectiondetailsmembuat label lebih rapi, mekanisme tab Detail-nya berpusat padacustom_views.DETAILS.
Potongan index.json yang sudah lengkap untuk bagian ini:
{
"component_scope": "task_summary_view",
"custom_views": {
"DETAILS": {
"ticket_summary": "task_summary_view"
}
},
"details": {
"ticket_summary": {
"name": "Ringkasan Tiket",
"description": "Detail view yang menampilkan ringkasan tiket."
}
}
}Validasi JSON sebelum lanjut:
python3 -c "import json; d=json.load(open('index.json')); print('OK'); print(d['custom_views']['DETAILS']); print(d['details'])"Step 5 — Build & Publish
Karena ada perubahan kode di views/src, wajib rebuild bundle MFE:
cd views
yarn build # atau: npm run build → output ke views/dist
cd ..Lalu publish via AlurKerja CLI (jalankan di terminal interaktif — CLI akan meminta tenant id):
alurkerja addon publishBila perubahan hanya di index.json (Step 3 & 4) tanpa menyentuh kode view, rebuild tidak diperlukan — cukup publish ulang. Karena di sini kita menambah komponen baru (Step 1), build tetap wajib.
Step 6 — Verifikasi
- Buka Addon di Studio, masuk ke task/elemen yang relevan.
- Pindah ke tab Detail (FormTabSwitcher: Input ↔ Detail).
- Komponen
task_summary_viewdi-load via Module Federation dan tampil dengan label "Ringkasan Tiket".
Cek konsistensi cepat
Pastikan setiap komponen yang dirujuk di custom_views benar-benar di-expose:
python3 - <<'PY'
import json, re
d = json.load(open('index.json'))
exposed = set(re.findall(r"\./([A-Za-z0-9_]+)':", open('views/webpack.config.js').read()))
refs = set()
for v in d.get('custom_views', {}).values():
refs.update(v.values() if isinstance(v, dict) else [v])
missing = refs - exposed
print("Exposed:", sorted(exposed))
print("Direferensikan:", sorted(refs))
print("BELUM di-expose:", missing or "tidak ada — semua valid")
PYTroubleshooting
| Gejala | Penyebab & Solusi |
|---|---|
| View tidak muncul di tab Detail | Pastikan entri ada di custom_views.DETAILS (bukan FORMS / VIEWS / CONFIGS). |
| Komponen gagal load / blank | Nilai di custom_views.DETAILS tidak cocok dengan key exposes di webpack. Samakan (tanpa ./). |
| Build gagal | Ada komponen dirujuk di custom_views tapi file/expose-nya belum ada. Lengkapi Step 1 & 2. |
| Perubahan tidak terlihat | Lupa yarn build atau lupa publish ulang via CLI. |
| Label salah/kosong di tab Detail | Tambahkan/rapikan entri di section details. |
Ringkasan Checklist
- Step 1 —
views/src/TaskSummaryView.tsxdibuat (pakaiAlurkerjaMfeProps). - Step 2 — di-expose di
views/webpack.config.jssebagai'./task_summary_view'. - Step 3 — terdaftar di
index.json→custom_views.DETAILS. - Step 4 — label tampilan di
index.json→details. - Step 5 —
yarn buildlalualurkerja addon publish. - Step 6 — komponen muncul di tab Detail Studio.
Lihat Juga
- AlurKerja CLI — setup CLI & publish addon.
- Pembuatan Addon pada AlurKerja — anatomi
index.jsondan slotcustom_viewslain (FORMS / VIEWS / DETAILS / CONFIGS / ACTIONS). - BPMN Adding Form — sisi konfigurasi form di User Task.
BPMN Adding Form
Panduan ini berisi langkah-langkah mengelola Form dan menggunakan berbagai mode tampilan di BPMN Editor.
BPMN Generate Test Suite
Panduan untuk menggunakan fitur Generate Test Suite pada Diagram BPMN di AlurKerja untuk membuat skenario pengujian otomatis berdasarkan proses bisnis yang telah dibuat.
