29 lines
7 KiB
JSON
29 lines
7 KiB
JSON
{
|
||
"ListFormCode": "Sas.DeveloperKit.CustomComponents",
|
||
"KeyFieldName": "Id",
|
||
"GeneratedAt": "2026-10-04T13:55:55Z",
|
||
"Order": 0,
|
||
"Rows": [
|
||
{
|
||
"Id": "b2d9fa60-b052-5039-a0fc-146f4e5b2e8c",
|
||
"Name": "MyPerformanceWidget",
|
||
"RoutePath": null,
|
||
"Description": "Intranet panosu: çalışanın aktif değerlendirmesi, puanları ve gelişim aksiyonları",
|
||
"IsActive": true,
|
||
"Dependencies": [],
|
||
"Code": "// Calisanin kendi performans ozeti. Veri ekranlarin kendi sorgusundan okunur: satir suzmesi\n// (EmployeeId = oturum acan kullanici) ve yetki ListForm'da kalir, bilesen yalnizca sayar.\nconst REVIEWS = 'Hr.MyPerformanceReview'\nconst PLANS = 'Hr.MyDevelopmentPlan'\n\nconst loadRows = async (listFormCode) => {\n const response = await apiService.fetchData({\n method: 'GET',\n url: '/api/app/list-form-select/select',\n params: { listFormCode, take: 500 },\n })\n return response.data?.data ?? []\n}\n\nconst formatScore = (value) =>\n value === null || value === undefined || value === '' ? '-' : Number(value).toFixed(1)\n\nconst Stat = ({ label, value, children }) => (\n <div className=\"flex items-center gap-3 rounded-lg border border-gray-200 bg-gray-50 p-3 dark:border-gray-700 dark:bg-gray-900/40\">\n {children}\n <div className=\"min-w-0\">\n <div className=\"text-lg font-semibold text-gray-900 dark:text-white\">{value}</div>\n <div className=\"truncate text-xs text-gray-500 dark:text-gray-400\">{label}</div>\n </div>\n </div>\n)\n\nconst MyPerformanceWidget = () => {\n const [reviews, setReviews] = useState([])\n const [plans, setPlans] = useState([])\n const [loading, setLoading] = useState(true)\n const canSeePlans = checkPermission(PLANS)\n\n useEffect(() => {\n let active = true\n Promise.all([loadRows(REVIEWS), canSeePlans ? loadRows(PLANS) : Promise.resolve([])])\n .then(([reviewRows, planRows]) => {\n if (!active) return\n setReviews(reviewRows)\n setPlans(planRows)\n })\n .catch(() => {})\n .finally(() => active && setLoading(false))\n return () => {\n active = false\n }\n }, [canSeePlans])\n\n const completed = reviews.filter((r) => r.Status === 'Completed')\n const current = reviews.find((r) => r.Status !== 'Completed')\n const scored = completed.filter((r) => r.OverallScore !== null && r.OverallScore !== undefined)\n const average = scored.length\n ? scored.reduce((sum, r) => sum + Number(r.OverallScore), 0) / scored.length\n : null\n const today = new Date().toISOString().slice(0, 10)\n const openPlans = plans.filter((p) => p.Status === 'Planned' || p.Status === 'InProgress')\n const overduePlans = openPlans.filter((p) => p.DueDate && String(p.DueDate).slice(0, 10) < today)\n\n return (\n <div className=\"overflow-hidden rounded-xl border border-gray-200/50 bg-white shadow-lg dark:border-gray-700/50 dark:bg-gray-800\">\n <div className=\"flex items-center gap-2 border-b border-gray-200 p-4 dark:border-gray-700\">\n <PlatformIcon name=\"FaChartLine\" className=\"h-5 w-5 text-indigo-500\" />\n <h2 className=\"text-base font-semibold text-gray-900 dark:text-white\">\n {translate('::Sas.DashboardWidget.MyPerformance')}\n </h2>\n </div>\n <div className=\"space-y-3 p-3\">\n {loading ? (\n <div className=\"p-4 text-center text-sm text-gray-500\">...</div>\n ) : reviews.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-gray-500 dark:text-gray-400\">\n {translate('::Sas.DashboardWidget.Performance.NoReview')}\n </div>\n ) : (\n <>\n {current && (\n <div className=\"rounded-lg border border-indigo-200 bg-indigo-50 p-3 dark:border-indigo-800 dark:bg-indigo-900/30\">\n <div className=\"text-xs text-indigo-600 dark:text-indigo-300\">\n {translate('::Sas.DashboardWidget.Performance.ActiveReview')}\n </div>\n <div className=\"text-sm font-semibold text-gray-900 dark:text-white\">\n {translate('::Hr.PerformanceReview.Status.' + current.Status)}\n </div>\n <div className=\"mt-2 grid grid-cols-3 gap-2 text-xs text-gray-600 dark:text-gray-300\">\n <div>\n {translate('::Sas.Listform.ListformField.GoalScore')}\n <div className=\"font-semibold\">{formatScore(current.GoalScore)}</div>\n </div>\n <div>\n {translate('::Sas.Listform.ListformField.CompetencyScore')}\n <div className=\"font-semibold\">{formatScore(current.CompetencyScore)}</div>\n </div>\n <div>\n {translate('::Sas.Listform.ListformField.OverallScore')}\n <div className=\"font-semibold\">{formatScore(current.OverallScore)}</div>\n </div>\n </div>\n </div>\n )}\n <div className=\"grid grid-cols-2 gap-2\">\n <Stat label={translate('::Hr.Performance.Widget.Completed')} value={completed.length}>\n <PlatformIcon name=\"FaCheckCircle\" className=\"h-5 w-5 text-green-500\" />\n </Stat>\n <Stat label={translate('::Hr.Performance.Widget.AverageScore')} value={formatScore(average)}>\n <PlatformIcon name=\"FaStar\" className=\"h-5 w-5 text-purple-500\" />\n </Stat>\n {canSeePlans && (\n <Stat label={translate('::Hr.Performance.Widget.Open')} value={openPlans.length}>\n <PlatformIcon name=\"FaTasks\" className=\"h-5 w-5 text-blue-500\" />\n </Stat>\n )}\n {canSeePlans && (\n <Stat label={translate('::Hr.Performance.Widget.Overdue')} value={overduePlans.length}>\n <PlatformIcon name=\"FaExclamationTriangle\" className=\"h-5 w-5 text-red-500\" />\n </Stat>\n )}\n </div>\n </>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1 pt-1\">\n <a href={'/admin/list/' + REVIEWS} className=\"text-sm font-medium text-indigo-600 hover:underline dark:text-indigo-400\">\n {translate('::Hr.MyPerformanceReview')} →\n </a>\n {canSeePlans && (\n <a href={'/admin/list/' + PLANS} className=\"text-sm font-medium text-indigo-600 hover:underline dark:text-indigo-400\">\n {translate('::Hr.MyDevelopmentPlan')} →\n </a>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default MyPerformanceWidget",
|
||
"Props": null,
|
||
"DataSources": [],
|
||
"SeoTitle": null,
|
||
"SeoDescription": null,
|
||
"SeoKeywords": null,
|
||
"SeoOgImage": null,
|
||
"SeoCanonicalUrl": null,
|
||
"SeoNoIndex": true,
|
||
"SeoIncludeInSitemap": false,
|
||
"SeoChangeFrequency": null,
|
||
"SeoPriority": null,
|
||
"SeoStructuredData": null
|
||
}
|
||
]
|
||
}
|