sozsoft-platform/configs/seeds/data/Sas.DeveloperKit.CustomComponents/1bca19aa-e144-5e4c-b23b-9eddd4dafd19.json

30 lines
8.1 KiB
JSON
Raw Permalink Normal View History

2026-10-19 14:35:08 +00:00
{
"ListFormCode": "Sas.DeveloperKit.CustomComponents",
"KeyFieldName": "Id",
"GeneratedAt": "2026-10-05T06:00:00Z",
"Order": 0,
"Rows": [
{
"Id": "1bca19aa-e144-5e4c-b23b-9eddd4dafd19",
"Name": "MyTimesheetWidget",
"RoutePath": null,
"Description": "Intranet panosu: çalışanın aylık puantajı (seçilen ay) ve yıllık toplamı, fazla mesai sınırı; Puantajım bağlantısı",
"IsActive": true,
"Dependencies": [],
"Code": "// Calisanin kendi puantaj ozeti. Veri Puantajim ekraninin sorgusundan okunur: satir suzmesi\n// (EmployeeId = oturum acan kullanici) ve yetki ListForm'da kalir, bilesen yalnizca toplar.\nconst MONTHLY = 'Hr.MyTimesheet'\n\nconst loadMonths = async () => {\n const response = await apiService.fetchData({\n method: 'GET',\n url: '/api/app/list-form-select/select',\n params: { listFormCode: MONTHLY, take: 500 },\n })\n return response.data?.data ?? []\n}\n\nconst num = (value) => Number(value ?? 0)\nconst format = (value) => {\n const number = num(value)\n return Number.isInteger(number) ? String(number) : number.toFixed(1)\n}\nconst sum = (rows, field) => rows.reduce((total, row) => total + num(row[field]), 0)\nconst periodOf = (row) => num(row.PeriodYear) * 100 + num(row.PeriodMonth)\nconst periodLabel = (period) => `${String(period % 100).padStart(2, '0')}.${Math.floor(period / 100)}`\n\nconst Stat = ({ label, value, className }) => (\n <div className=\"rounded-lg border border-gray-200 bg-gray-50 p-2 text-center dark:border-gray-700 dark:bg-gray-900/40\">\n <div className={'text-lg font-semibold ' + className}>{value}</div>\n <div className=\"truncate text-xs text-gray-500 dark:text-gray-400\">{label}</div>\n </div>\n)\n\nconst MyTimesheetWidget = () => {\n const [rows, setRows] = useState([])\n const [period, setPeriod] = useState(0)\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n let active = true\n loadMonths()\n .then((data) => {\n if (!active) return\n const now = new Date()\n const current = now.getFullYear() * 100 + now.getMonth() + 1\n const periods = data.map(periodOf)\n setRows(data)\n setPeriod(periods.includes(current) ? current : Math.max(current, ...periods))\n })\n .catch(() => {})\n .finally(() => active && setLoading(false))\n return () => {\n active = false\n }\n }, [])\n\n const t = (key, params) => translate(`::Sas.DashboardWidget.Timesheet.${key}`, params)\n const periods = [...new Set(rows.map(periodOf))].sort((a, b) => b - a)\n const month = rows.find((row) => periodOf(row) === period) ?? {}\n const yearRows = rows.filter((row) => num(row.PeriodYear) === Math.floor(period / 100))\n const yearOvertime = sum(yearRows, 'OvertimeHours')\n const limit = num(yearRows[0]?.AnnualOvertimeLimit) || 270\n const ratio = Math.min(100, Math.round((yearOvertime / limit) * 100))\n const barColor = ratio >= 100 ? 'bg-red-500' : ratio >= 80 ? 'bg-orange-500' : 'bg-indigo-500'\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 justify-between gap-2 border-b border-gray-200 p-4 dark:border-gray-700\">\n <div className=\"flex items-center gap-2\">\n <PlatformIcon name=\"FaBusinessTime\" 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.MyTimesheet')}\n </h2>\n </div>\n {periods.length > 0 && (\n <select\n value={period}\n onChange={(event) => setPeriod(Number(event.target.value))}\n className=\"rounded-md border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-200\"\n >\n {periods.map((value) => (\n <option key={value} value={value}>\n {periodLabel(value)}\n </option>\n ))}\n </select>\n )}\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 ) : rows.length === 0 ? (\n <div className=\"text-sm text-gray-500 dark:text-gray-400\">{t('NoData')}</div>\n ) : (\n <>\n <div className=\"grid grid-cols-3 gap-2\">\n <Stat label={t('Ne
"Props": null,
"DataSources": [],
"SeoTitle": null,
"SeoDescription": null,
"SeoKeywords": null,
"SeoOgImage": null,
"SeoCanonicalUrl": null,
"SeoNoIndex": true,
"SeoIncludeInSitemap": false,
"SeoChangeFrequency": null,
"SeoPriority": null,
"SeoStructuredData": null
}
]
}