@wordrhyme/auto-crud 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -7
- package/dist/index.cjs +590 -94
- package/dist/index.d.cts +153 -15
- package/dist/index.d.ts +169 -31
- package/dist/index.js +582 -94
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -4014,8 +4014,7 @@ function createSelectColumn() {
|
|
|
4014
4014
|
/**
|
|
4015
4015
|
* 创建操作列
|
|
4016
4016
|
*/
|
|
4017
|
-
function createActionsColumn(
|
|
4018
|
-
const { onEdit, onDelete, onView, onCopy } = config;
|
|
4017
|
+
function createActionsColumn(items) {
|
|
4019
4018
|
return {
|
|
4020
4019
|
id: "actions",
|
|
4021
4020
|
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuTrigger, {
|
|
@@ -4026,29 +4025,14 @@ function createActionsColumn(config) {
|
|
|
4026
4025
|
className: "flex size-8 p-0 data-[state=open]:bg-muted",
|
|
4027
4026
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Ellipsis, { className: "size-4" })
|
|
4028
4027
|
})
|
|
4029
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
4028
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuContent, {
|
|
4030
4029
|
align: "end",
|
|
4031
4030
|
className: "w-40",
|
|
4032
|
-
children: [
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
onEdit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuItem, {
|
|
4038
|
-
onClick: () => onEdit(row.original),
|
|
4039
|
-
children: "编辑"
|
|
4040
|
-
}),
|
|
4041
|
-
onCopy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuItem, {
|
|
4042
|
-
onClick: () => onCopy(row.original),
|
|
4043
|
-
children: "复制"
|
|
4044
|
-
}),
|
|
4045
|
-
(onView || onEdit || onCopy) && onDelete && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuSeparator, {}),
|
|
4046
|
-
onDelete && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuItem, {
|
|
4047
|
-
className: "text-destructive",
|
|
4048
|
-
onClick: () => onDelete(row.original),
|
|
4049
|
-
children: "删除"
|
|
4050
|
-
})
|
|
4051
|
-
]
|
|
4031
|
+
children: items.map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [item.separator && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuSeparator, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuItem, {
|
|
4032
|
+
className: item.variant === "destructive" ? "text-destructive" : "",
|
|
4033
|
+
onClick: () => item.onClick(row.original),
|
|
4034
|
+
children: item.label
|
|
4035
|
+
})] }, i))
|
|
4052
4036
|
})] }),
|
|
4053
4037
|
size: 40
|
|
4054
4038
|
};
|
|
@@ -4936,10 +4920,462 @@ function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides,
|
|
|
4936
4920
|
}
|
|
4937
4921
|
const AutoForm = (0, react.forwardRef)(AutoFormInner);
|
|
4938
4922
|
|
|
4923
|
+
//#endregion
|
|
4924
|
+
//#region src/i18n/locale.ts
|
|
4925
|
+
const zhCN = {
|
|
4926
|
+
toolbar: {
|
|
4927
|
+
create: "新建",
|
|
4928
|
+
import: "导入",
|
|
4929
|
+
export: "导出",
|
|
4930
|
+
exportSelected: (count) => `导出(${count})`
|
|
4931
|
+
},
|
|
4932
|
+
rowActions: {
|
|
4933
|
+
view: "查看",
|
|
4934
|
+
edit: "编辑",
|
|
4935
|
+
copy: "复制",
|
|
4936
|
+
delete: "删除"
|
|
4937
|
+
},
|
|
4938
|
+
viewModal: { title: "详情" },
|
|
4939
|
+
boolean: {
|
|
4940
|
+
true: "是",
|
|
4941
|
+
false: "否"
|
|
4942
|
+
},
|
|
4943
|
+
formModal: {
|
|
4944
|
+
createTitle: "新建",
|
|
4945
|
+
editTitle: "编辑",
|
|
4946
|
+
cancel: "取消",
|
|
4947
|
+
create: "创建",
|
|
4948
|
+
save: "保存",
|
|
4949
|
+
submitting: "处理中..."
|
|
4950
|
+
},
|
|
4951
|
+
deleteModal: {
|
|
4952
|
+
title: "确认删除",
|
|
4953
|
+
description: "此操作无法撤销。确定要删除这条记录吗?",
|
|
4954
|
+
cancel: "取消",
|
|
4955
|
+
confirm: "确认删除",
|
|
4956
|
+
confirming: "删除中..."
|
|
4957
|
+
},
|
|
4958
|
+
importDialog: {
|
|
4959
|
+
title: "导入数据",
|
|
4960
|
+
uploadDescription: "上传 CSV 或 JSON 文件以批量导入数据",
|
|
4961
|
+
previewDescription: (count) => `已解析 ${count} 条数据,确认后开始导入`,
|
|
4962
|
+
importingDescription: "正在导入数据...",
|
|
4963
|
+
doneDescription: "导入完成",
|
|
4964
|
+
dragHint: "拖拽文件到此处,或点击选择文件",
|
|
4965
|
+
formatHint: "支持 CSV、JSON 格式",
|
|
4966
|
+
downloadTemplate: "下载 CSV 模板",
|
|
4967
|
+
moreColumns: (count) => `+${count} 列`,
|
|
4968
|
+
previewSummary: (rows, fields, format, previewLimit) => `共 ${rows} 条数据${previewLimit ? `(预览前 ${previewLimit} 条)` : ""},${fields} 个字段,格式: ${format.toUpperCase()}`,
|
|
4969
|
+
reselect: "重新选择",
|
|
4970
|
+
confirmImport: "确认导入",
|
|
4971
|
+
importingRows: (count) => `正在导入 ${count} 条数据...`,
|
|
4972
|
+
resultCreated: "新建",
|
|
4973
|
+
resultUpdated: "更新",
|
|
4974
|
+
resultSkipped: "跳过",
|
|
4975
|
+
resultFailed: "验证失败",
|
|
4976
|
+
failedRowHeader: "行号",
|
|
4977
|
+
failedErrorHeader: "错误",
|
|
4978
|
+
close: "关闭",
|
|
4979
|
+
continueImport: "继续导入",
|
|
4980
|
+
errorNoData: "文件中没有数据行",
|
|
4981
|
+
errorParseFailed: "文件解析失败",
|
|
4982
|
+
errorImportFailed: "导入失败"
|
|
4983
|
+
}
|
|
4984
|
+
};
|
|
4985
|
+
const enUS = {
|
|
4986
|
+
toolbar: {
|
|
4987
|
+
create: "New",
|
|
4988
|
+
import: "Import",
|
|
4989
|
+
export: "Export",
|
|
4990
|
+
exportSelected: (count) => `Export (${count})`
|
|
4991
|
+
},
|
|
4992
|
+
rowActions: {
|
|
4993
|
+
view: "View",
|
|
4994
|
+
edit: "Edit",
|
|
4995
|
+
copy: "Copy",
|
|
4996
|
+
delete: "Delete"
|
|
4997
|
+
},
|
|
4998
|
+
viewModal: { title: "Details" },
|
|
4999
|
+
boolean: {
|
|
5000
|
+
true: "Yes",
|
|
5001
|
+
false: "No"
|
|
5002
|
+
},
|
|
5003
|
+
formModal: {
|
|
5004
|
+
createTitle: "New",
|
|
5005
|
+
editTitle: "Edit",
|
|
5006
|
+
cancel: "Cancel",
|
|
5007
|
+
create: "Create",
|
|
5008
|
+
save: "Save",
|
|
5009
|
+
submitting: "Processing..."
|
|
5010
|
+
},
|
|
5011
|
+
deleteModal: {
|
|
5012
|
+
title: "Confirm Delete",
|
|
5013
|
+
description: "This action cannot be undone. Are you sure you want to delete this record?",
|
|
5014
|
+
cancel: "Cancel",
|
|
5015
|
+
confirm: "Delete",
|
|
5016
|
+
confirming: "Deleting..."
|
|
5017
|
+
},
|
|
5018
|
+
importDialog: {
|
|
5019
|
+
title: "Import Data",
|
|
5020
|
+
uploadDescription: "Upload a CSV or JSON file to bulk import data",
|
|
5021
|
+
previewDescription: (count) => `Parsed ${count} records, confirm to start importing`,
|
|
5022
|
+
importingDescription: "Importing data...",
|
|
5023
|
+
doneDescription: "Import complete",
|
|
5024
|
+
dragHint: "Drag file here, or click to select",
|
|
5025
|
+
formatHint: "Supports CSV, JSON formats",
|
|
5026
|
+
downloadTemplate: "Download CSV Template",
|
|
5027
|
+
moreColumns: (count) => `+${count} more`,
|
|
5028
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} records${previewLimit ? ` (preview first ${previewLimit})` : ""}, ${fields} fields, format: ${format.toUpperCase()}`,
|
|
5029
|
+
reselect: "Reselect",
|
|
5030
|
+
confirmImport: "Confirm Import",
|
|
5031
|
+
importingRows: (count) => `Importing ${count} records...`,
|
|
5032
|
+
resultCreated: "Created",
|
|
5033
|
+
resultUpdated: "Updated",
|
|
5034
|
+
resultSkipped: "Skipped",
|
|
5035
|
+
resultFailed: "Failed",
|
|
5036
|
+
failedRowHeader: "Row",
|
|
5037
|
+
failedErrorHeader: "Error",
|
|
5038
|
+
close: "Close",
|
|
5039
|
+
continueImport: "Import More",
|
|
5040
|
+
errorNoData: "No data rows found in file",
|
|
5041
|
+
errorParseFailed: "Failed to parse file",
|
|
5042
|
+
errorImportFailed: "Import failed"
|
|
5043
|
+
}
|
|
5044
|
+
};
|
|
5045
|
+
const jaJP = {
|
|
5046
|
+
toolbar: {
|
|
5047
|
+
create: "新規作成",
|
|
5048
|
+
import: "インポート",
|
|
5049
|
+
export: "エクスポート",
|
|
5050
|
+
exportSelected: (count) => `エクスポート(${count})`
|
|
5051
|
+
},
|
|
5052
|
+
rowActions: {
|
|
5053
|
+
view: "詳細",
|
|
5054
|
+
edit: "編集",
|
|
5055
|
+
copy: "コピー",
|
|
5056
|
+
delete: "削除"
|
|
5057
|
+
},
|
|
5058
|
+
viewModal: { title: "詳細" },
|
|
5059
|
+
boolean: {
|
|
5060
|
+
true: "はい",
|
|
5061
|
+
false: "いいえ"
|
|
5062
|
+
},
|
|
5063
|
+
formModal: {
|
|
5064
|
+
createTitle: "新規作成",
|
|
5065
|
+
editTitle: "編集",
|
|
5066
|
+
cancel: "キャンセル",
|
|
5067
|
+
create: "作成",
|
|
5068
|
+
save: "保存",
|
|
5069
|
+
submitting: "処理中..."
|
|
5070
|
+
},
|
|
5071
|
+
deleteModal: {
|
|
5072
|
+
title: "削除の確認",
|
|
5073
|
+
description: "この操作は元に戻せません。このレコードを削除してもよろしいですか?",
|
|
5074
|
+
cancel: "キャンセル",
|
|
5075
|
+
confirm: "削除する",
|
|
5076
|
+
confirming: "削除中..."
|
|
5077
|
+
},
|
|
5078
|
+
importDialog: {
|
|
5079
|
+
title: "データのインポート",
|
|
5080
|
+
uploadDescription: "CSVまたはJSONファイルをアップロードして一括インポート",
|
|
5081
|
+
previewDescription: (count) => `${count}件のデータを解析しました。確認してインポートを開始します`,
|
|
5082
|
+
importingDescription: "データをインポート中...",
|
|
5083
|
+
doneDescription: "インポート完了",
|
|
5084
|
+
dragHint: "ファイルをここにドラッグするか、クリックして選択",
|
|
5085
|
+
formatHint: "CSV・JSON形式に対応",
|
|
5086
|
+
downloadTemplate: "CSVテンプレートをダウンロード",
|
|
5087
|
+
moreColumns: (count) => `+${count}列`,
|
|
5088
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows}件${previewLimit ? `(上位${previewLimit}件プレビュー)` : ""}、${fields}フィールド、形式: ${format.toUpperCase()}`,
|
|
5089
|
+
reselect: "再選択",
|
|
5090
|
+
confirmImport: "インポートを確認",
|
|
5091
|
+
importingRows: (count) => `${count}件をインポート中...`,
|
|
5092
|
+
resultCreated: "新規作成",
|
|
5093
|
+
resultUpdated: "更新",
|
|
5094
|
+
resultSkipped: "スキップ",
|
|
5095
|
+
resultFailed: "失敗",
|
|
5096
|
+
failedRowHeader: "行番号",
|
|
5097
|
+
failedErrorHeader: "エラー",
|
|
5098
|
+
close: "閉じる",
|
|
5099
|
+
continueImport: "続けてインポート",
|
|
5100
|
+
errorNoData: "ファイルにデータ行がありません",
|
|
5101
|
+
errorParseFailed: "ファイルの解析に失敗しました",
|
|
5102
|
+
errorImportFailed: "インポートに失敗しました"
|
|
5103
|
+
}
|
|
5104
|
+
};
|
|
5105
|
+
const koKR = {
|
|
5106
|
+
toolbar: {
|
|
5107
|
+
create: "새로 만들기",
|
|
5108
|
+
import: "가져오기",
|
|
5109
|
+
export: "내보내기",
|
|
5110
|
+
exportSelected: (count) => `내보내기(${count})`
|
|
5111
|
+
},
|
|
5112
|
+
rowActions: {
|
|
5113
|
+
view: "보기",
|
|
5114
|
+
edit: "편집",
|
|
5115
|
+
copy: "복사",
|
|
5116
|
+
delete: "삭제"
|
|
5117
|
+
},
|
|
5118
|
+
viewModal: { title: "상세 정보" },
|
|
5119
|
+
boolean: {
|
|
5120
|
+
true: "예",
|
|
5121
|
+
false: "아니요"
|
|
5122
|
+
},
|
|
5123
|
+
formModal: {
|
|
5124
|
+
createTitle: "새로 만들기",
|
|
5125
|
+
editTitle: "편집",
|
|
5126
|
+
cancel: "취소",
|
|
5127
|
+
create: "만들기",
|
|
5128
|
+
save: "저장",
|
|
5129
|
+
submitting: "처리 중..."
|
|
5130
|
+
},
|
|
5131
|
+
deleteModal: {
|
|
5132
|
+
title: "삭제 확인",
|
|
5133
|
+
description: "이 작업은 취소할 수 없습니다. 이 레코드를 삭제하시겠습니까?",
|
|
5134
|
+
cancel: "취소",
|
|
5135
|
+
confirm: "삭제",
|
|
5136
|
+
confirming: "삭제 중..."
|
|
5137
|
+
},
|
|
5138
|
+
importDialog: {
|
|
5139
|
+
title: "데이터 가져오기",
|
|
5140
|
+
uploadDescription: "CSV 또는 JSON 파일을 업로드하여 일괄 가져오기",
|
|
5141
|
+
previewDescription: (count) => `${count}개의 데이터를 분석했습니다. 확인 후 가져오기를 시작합니다`,
|
|
5142
|
+
importingDescription: "데이터를 가져오는 중...",
|
|
5143
|
+
doneDescription: "가져오기 완료",
|
|
5144
|
+
dragHint: "파일을 여기에 드래그하거나 클릭하여 선택",
|
|
5145
|
+
formatHint: "CSV, JSON 형식 지원",
|
|
5146
|
+
downloadTemplate: "CSV 템플릿 다운로드",
|
|
5147
|
+
moreColumns: (count) => `+${count}열 더`,
|
|
5148
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows}개 레코드${previewLimit ? ` (상위 ${previewLimit}개 미리보기)` : ""}, ${fields}개 필드, 형식: ${format.toUpperCase()}`,
|
|
5149
|
+
reselect: "다시 선택",
|
|
5150
|
+
confirmImport: "가져오기 확인",
|
|
5151
|
+
importingRows: (count) => `${count}개의 레코드를 가져오는 중...`,
|
|
5152
|
+
resultCreated: "생성됨",
|
|
5153
|
+
resultUpdated: "업데이트됨",
|
|
5154
|
+
resultSkipped: "건너뜀",
|
|
5155
|
+
resultFailed: "실패",
|
|
5156
|
+
failedRowHeader: "행 번호",
|
|
5157
|
+
failedErrorHeader: "오류",
|
|
5158
|
+
close: "닫기",
|
|
5159
|
+
continueImport: "계속 가져오기",
|
|
5160
|
+
errorNoData: "파일에 데이터 행이 없습니다",
|
|
5161
|
+
errorParseFailed: "파일 파싱에 실패했습니다",
|
|
5162
|
+
errorImportFailed: "가져오기에 실패했습니다"
|
|
5163
|
+
}
|
|
5164
|
+
};
|
|
5165
|
+
const frFR = {
|
|
5166
|
+
toolbar: {
|
|
5167
|
+
create: "Nouveau",
|
|
5168
|
+
import: "Importer",
|
|
5169
|
+
export: "Exporter",
|
|
5170
|
+
exportSelected: (count) => `Exporter (${count})`
|
|
5171
|
+
},
|
|
5172
|
+
rowActions: {
|
|
5173
|
+
view: "Voir",
|
|
5174
|
+
edit: "Modifier",
|
|
5175
|
+
copy: "Copier",
|
|
5176
|
+
delete: "Supprimer"
|
|
5177
|
+
},
|
|
5178
|
+
viewModal: { title: "Détails" },
|
|
5179
|
+
boolean: {
|
|
5180
|
+
true: "Oui",
|
|
5181
|
+
false: "Non"
|
|
5182
|
+
},
|
|
5183
|
+
formModal: {
|
|
5184
|
+
createTitle: "Nouveau",
|
|
5185
|
+
editTitle: "Modifier",
|
|
5186
|
+
cancel: "Annuler",
|
|
5187
|
+
create: "Créer",
|
|
5188
|
+
save: "Enregistrer",
|
|
5189
|
+
submitting: "En cours..."
|
|
5190
|
+
},
|
|
5191
|
+
deleteModal: {
|
|
5192
|
+
title: "Confirmer la suppression",
|
|
5193
|
+
description: "Cette action est irréversible. Voulez-vous vraiment supprimer cet enregistrement ?",
|
|
5194
|
+
cancel: "Annuler",
|
|
5195
|
+
confirm: "Supprimer",
|
|
5196
|
+
confirming: "Suppression..."
|
|
5197
|
+
},
|
|
5198
|
+
importDialog: {
|
|
5199
|
+
title: "Importer des données",
|
|
5200
|
+
uploadDescription: "Téléchargez un fichier CSV ou JSON pour importer en masse",
|
|
5201
|
+
previewDescription: (count) => `${count} enregistrements analysés, confirmez pour démarrer l'import`,
|
|
5202
|
+
importingDescription: "Importation en cours...",
|
|
5203
|
+
doneDescription: "Import terminé",
|
|
5204
|
+
dragHint: "Glissez un fichier ici ou cliquez pour sélectionner",
|
|
5205
|
+
formatHint: "Formats CSV et JSON acceptés",
|
|
5206
|
+
downloadTemplate: "Télécharger le modèle CSV",
|
|
5207
|
+
moreColumns: (count) => `+${count} colonnes`,
|
|
5208
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} enregistrements${previewLimit ? ` (aperçu des ${previewLimit} premiers)` : ""}, ${fields} champs, format : ${format.toUpperCase()}`,
|
|
5209
|
+
reselect: "Resélectionner",
|
|
5210
|
+
confirmImport: "Confirmer l'import",
|
|
5211
|
+
importingRows: (count) => `Importation de ${count} enregistrements...`,
|
|
5212
|
+
resultCreated: "Créés",
|
|
5213
|
+
resultUpdated: "Mis à jour",
|
|
5214
|
+
resultSkipped: "Ignorés",
|
|
5215
|
+
resultFailed: "Échoués",
|
|
5216
|
+
failedRowHeader: "Ligne",
|
|
5217
|
+
failedErrorHeader: "Erreur",
|
|
5218
|
+
close: "Fermer",
|
|
5219
|
+
continueImport: "Continuer l'import",
|
|
5220
|
+
errorNoData: "Aucune ligne de données dans le fichier",
|
|
5221
|
+
errorParseFailed: "Échec de l'analyse du fichier",
|
|
5222
|
+
errorImportFailed: "Échec de l'importation"
|
|
5223
|
+
}
|
|
5224
|
+
};
|
|
5225
|
+
const deDE = {
|
|
5226
|
+
toolbar: {
|
|
5227
|
+
create: "Neu",
|
|
5228
|
+
import: "Importieren",
|
|
5229
|
+
export: "Exportieren",
|
|
5230
|
+
exportSelected: (count) => `Exportieren (${count})`
|
|
5231
|
+
},
|
|
5232
|
+
rowActions: {
|
|
5233
|
+
view: "Anzeigen",
|
|
5234
|
+
edit: "Bearbeiten",
|
|
5235
|
+
copy: "Kopieren",
|
|
5236
|
+
delete: "Löschen"
|
|
5237
|
+
},
|
|
5238
|
+
viewModal: { title: "Details" },
|
|
5239
|
+
boolean: {
|
|
5240
|
+
true: "Ja",
|
|
5241
|
+
false: "Nein"
|
|
5242
|
+
},
|
|
5243
|
+
formModal: {
|
|
5244
|
+
createTitle: "Neu",
|
|
5245
|
+
editTitle: "Bearbeiten",
|
|
5246
|
+
cancel: "Abbrechen",
|
|
5247
|
+
create: "Erstellen",
|
|
5248
|
+
save: "Speichern",
|
|
5249
|
+
submitting: "Wird verarbeitet..."
|
|
5250
|
+
},
|
|
5251
|
+
deleteModal: {
|
|
5252
|
+
title: "Löschen bestätigen",
|
|
5253
|
+
description: "Diese Aktion kann nicht rückgängig gemacht werden. Möchten Sie diesen Datensatz wirklich löschen?",
|
|
5254
|
+
cancel: "Abbrechen",
|
|
5255
|
+
confirm: "Löschen",
|
|
5256
|
+
confirming: "Wird gelöscht..."
|
|
5257
|
+
},
|
|
5258
|
+
importDialog: {
|
|
5259
|
+
title: "Daten importieren",
|
|
5260
|
+
uploadDescription: "CSV- oder JSON-Datei hochladen, um Daten massenweise zu importieren",
|
|
5261
|
+
previewDescription: (count) => `${count} Datensätze analysiert, bestätigen Sie den Import`,
|
|
5262
|
+
importingDescription: "Daten werden importiert...",
|
|
5263
|
+
doneDescription: "Import abgeschlossen",
|
|
5264
|
+
dragHint: "Datei hierher ziehen oder klicken zum Auswählen",
|
|
5265
|
+
formatHint: "CSV- und JSON-Formate werden unterstützt",
|
|
5266
|
+
downloadTemplate: "CSV-Vorlage herunterladen",
|
|
5267
|
+
moreColumns: (count) => `+${count} Spalten`,
|
|
5268
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} Datensätze${previewLimit ? ` (Vorschau der ersten ${previewLimit})` : ""}, ${fields} Felder, Format: ${format.toUpperCase()}`,
|
|
5269
|
+
reselect: "Neu auswählen",
|
|
5270
|
+
confirmImport: "Import bestätigen",
|
|
5271
|
+
importingRows: (count) => `${count} Datensätze werden importiert...`,
|
|
5272
|
+
resultCreated: "Erstellt",
|
|
5273
|
+
resultUpdated: "Aktualisiert",
|
|
5274
|
+
resultSkipped: "Übersprungen",
|
|
5275
|
+
resultFailed: "Fehlgeschlagen",
|
|
5276
|
+
failedRowHeader: "Zeile",
|
|
5277
|
+
failedErrorHeader: "Fehler",
|
|
5278
|
+
close: "Schließen",
|
|
5279
|
+
continueImport: "Weiteren Import starten",
|
|
5280
|
+
errorNoData: "Keine Datenzeilen in der Datei",
|
|
5281
|
+
errorParseFailed: "Datei konnte nicht analysiert werden",
|
|
5282
|
+
errorImportFailed: "Import fehlgeschlagen"
|
|
5283
|
+
}
|
|
5284
|
+
};
|
|
5285
|
+
const esES = {
|
|
5286
|
+
toolbar: {
|
|
5287
|
+
create: "Nuevo",
|
|
5288
|
+
import: "Importar",
|
|
5289
|
+
export: "Exportar",
|
|
5290
|
+
exportSelected: (count) => `Exportar (${count})`
|
|
5291
|
+
},
|
|
5292
|
+
rowActions: {
|
|
5293
|
+
view: "Ver",
|
|
5294
|
+
edit: "Editar",
|
|
5295
|
+
copy: "Copiar",
|
|
5296
|
+
delete: "Eliminar"
|
|
5297
|
+
},
|
|
5298
|
+
viewModal: { title: "Detalles" },
|
|
5299
|
+
boolean: {
|
|
5300
|
+
true: "Sí",
|
|
5301
|
+
false: "No"
|
|
5302
|
+
},
|
|
5303
|
+
formModal: {
|
|
5304
|
+
createTitle: "Nuevo",
|
|
5305
|
+
editTitle: "Editar",
|
|
5306
|
+
cancel: "Cancelar",
|
|
5307
|
+
create: "Crear",
|
|
5308
|
+
save: "Guardar",
|
|
5309
|
+
submitting: "Procesando..."
|
|
5310
|
+
},
|
|
5311
|
+
deleteModal: {
|
|
5312
|
+
title: "Confirmar eliminación",
|
|
5313
|
+
description: "Esta acción no se puede deshacer. ¿Está seguro de que desea eliminar este registro?",
|
|
5314
|
+
cancel: "Cancelar",
|
|
5315
|
+
confirm: "Eliminar",
|
|
5316
|
+
confirming: "Eliminando..."
|
|
5317
|
+
},
|
|
5318
|
+
importDialog: {
|
|
5319
|
+
title: "Importar datos",
|
|
5320
|
+
uploadDescription: "Suba un archivo CSV o JSON para importar datos de forma masiva",
|
|
5321
|
+
previewDescription: (count) => `Se analizaron ${count} registros, confirme para iniciar la importación`,
|
|
5322
|
+
importingDescription: "Importando datos...",
|
|
5323
|
+
doneDescription: "Importación completada",
|
|
5324
|
+
dragHint: "Arrastre el archivo aquí o haga clic para seleccionar",
|
|
5325
|
+
formatHint: "Formatos CSV y JSON compatibles",
|
|
5326
|
+
downloadTemplate: "Descargar plantilla CSV",
|
|
5327
|
+
moreColumns: (count) => `+${count} columnas`,
|
|
5328
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} registros${previewLimit ? ` (vista previa de los primeros ${previewLimit})` : ""}, ${fields} campos, formato: ${format.toUpperCase()}`,
|
|
5329
|
+
reselect: "Volver a seleccionar",
|
|
5330
|
+
confirmImport: "Confirmar importación",
|
|
5331
|
+
importingRows: (count) => `Importando ${count} registros...`,
|
|
5332
|
+
resultCreated: "Creados",
|
|
5333
|
+
resultUpdated: "Actualizados",
|
|
5334
|
+
resultSkipped: "Omitidos",
|
|
5335
|
+
resultFailed: "Fallidos",
|
|
5336
|
+
failedRowHeader: "Fila",
|
|
5337
|
+
failedErrorHeader: "Error",
|
|
5338
|
+
close: "Cerrar",
|
|
5339
|
+
continueImport: "Continuar importando",
|
|
5340
|
+
errorNoData: "No se encontraron filas de datos en el archivo",
|
|
5341
|
+
errorParseFailed: "Error al analizar el archivo",
|
|
5342
|
+
errorImportFailed: "Error en la importación"
|
|
5343
|
+
}
|
|
5344
|
+
};
|
|
5345
|
+
const BUILTIN_LOCALES = {
|
|
5346
|
+
"zh-CN": zhCN,
|
|
5347
|
+
"en-US": enUS,
|
|
5348
|
+
"ja-JP": jaJP,
|
|
5349
|
+
"ko-KR": koKR,
|
|
5350
|
+
"fr-FR": frFR,
|
|
5351
|
+
"de-DE": deDE,
|
|
5352
|
+
"es-ES": esES
|
|
5353
|
+
};
|
|
5354
|
+
function deepMerge(target, source) {
|
|
5355
|
+
const result = { ...target };
|
|
5356
|
+
for (const key of Object.keys(source)) {
|
|
5357
|
+
const sv = source[key];
|
|
5358
|
+
const tv = target[key];
|
|
5359
|
+
if (sv !== void 0 && sv !== null && typeof sv === "object" && !Array.isArray(sv) && typeof tv === "object" && tv !== null && !Array.isArray(tv)) result[key] = deepMerge(tv, sv);
|
|
5360
|
+
else if (sv !== void 0) result[key] = sv;
|
|
5361
|
+
}
|
|
5362
|
+
return result;
|
|
5363
|
+
}
|
|
5364
|
+
/**
|
|
5365
|
+
* 解析 locale prop 为完整的 AutoCrudLocale
|
|
5366
|
+
* - string → 内置语言(fallback: zh-CN)
|
|
5367
|
+
* - object → 以 zh-CN 为基础深合并
|
|
5368
|
+
*/
|
|
5369
|
+
function resolveLocale(localeProp) {
|
|
5370
|
+
if (!localeProp) return zhCN;
|
|
5371
|
+
if (typeof localeProp === "string") return BUILTIN_LOCALES[localeProp] ?? zhCN;
|
|
5372
|
+
return deepMerge(zhCN, localeProp);
|
|
5373
|
+
}
|
|
5374
|
+
|
|
4939
5375
|
//#endregion
|
|
4940
5376
|
//#region src/components/auto-crud/crud-form-modal.tsx
|
|
4941
|
-
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, title, labelAlign, labelWidth }) {
|
|
4942
|
-
const defaultTitle = mode === "create" ?
|
|
5377
|
+
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, title, locale = zhCN.formModal, labelAlign, labelWidth }) {
|
|
5378
|
+
const defaultTitle = mode === "create" ? locale.createTitle : locale.editTitle;
|
|
4943
5379
|
const formRef = (0, react.useRef)(null);
|
|
4944
5380
|
const handleSubmit = async () => {
|
|
4945
5381
|
await formRef.current?.submit();
|
|
@@ -4955,12 +5391,12 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
4955
5391
|
type: "button",
|
|
4956
5392
|
variant: "outline",
|
|
4957
5393
|
onClick: () => onOpenChange(false),
|
|
4958
|
-
children:
|
|
5394
|
+
children: locale.cancel
|
|
4959
5395
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
4960
5396
|
type: "button",
|
|
4961
5397
|
onClick: handleSubmit,
|
|
4962
5398
|
disabled: loading,
|
|
4963
|
-
children: loading ?
|
|
5399
|
+
children: loading ? locale.submitting : mode === "create" ? locale.create : locale.save
|
|
4964
5400
|
})]
|
|
4965
5401
|
}),
|
|
4966
5402
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoForm, {
|
|
@@ -4980,7 +5416,7 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
4980
5416
|
|
|
4981
5417
|
//#endregion
|
|
4982
5418
|
//#region src/components/auto-crud/import-dialog.tsx
|
|
4983
|
-
function ImportDialog({ open, onOpenChange, onImport, columns = [], title =
|
|
5419
|
+
function ImportDialog({ open, onOpenChange, onImport, columns = [], title, locale = zhCN.importDialog }) {
|
|
4984
5420
|
const [step, setStep] = react.useState("upload");
|
|
4985
5421
|
const [parsedData, setParsedData] = react.useState(null);
|
|
4986
5422
|
const [error, setError] = react.useState(null);
|
|
@@ -5003,13 +5439,13 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5003
5439
|
try {
|
|
5004
5440
|
const data = await parseImportFile(file);
|
|
5005
5441
|
if (data.rows.length === 0) {
|
|
5006
|
-
setError(
|
|
5442
|
+
setError(locale.errorNoData);
|
|
5007
5443
|
return;
|
|
5008
5444
|
}
|
|
5009
5445
|
setParsedData(data);
|
|
5010
5446
|
setStep("preview");
|
|
5011
5447
|
} catch (e) {
|
|
5012
|
-
setError(e instanceof Error ? e.message :
|
|
5448
|
+
setError(e instanceof Error ? e.message : locale.errorParseFailed);
|
|
5013
5449
|
}
|
|
5014
5450
|
}, []);
|
|
5015
5451
|
const handleDrop = react.useCallback((e) => {
|
|
@@ -5029,7 +5465,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5029
5465
|
setResult(await onImport(parsedData.rows));
|
|
5030
5466
|
setStep("result");
|
|
5031
5467
|
} catch (e) {
|
|
5032
|
-
setError(e instanceof Error ? e.message :
|
|
5468
|
+
setError(e instanceof Error ? e.message : locale.errorImportFailed);
|
|
5033
5469
|
setStep("preview");
|
|
5034
5470
|
}
|
|
5035
5471
|
}, [parsedData, onImport]);
|
|
@@ -5049,11 +5485,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5049
5485
|
onOpenChange: handleOpenChange,
|
|
5050
5486
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogContent, {
|
|
5051
5487
|
className: "sm:max-w-[600px]",
|
|
5052
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DialogTitle, { children: title }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogDescription, { children: [
|
|
5053
|
-
step === "upload" &&
|
|
5054
|
-
step === "preview" &&
|
|
5055
|
-
step === "importing" &&
|
|
5056
|
-
step === "result" &&
|
|
5488
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DialogTitle, { children: title ?? locale.title }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogDescription, { children: [
|
|
5489
|
+
step === "upload" && locale.uploadDescription,
|
|
5490
|
+
step === "preview" && locale.previewDescription(parsedData?.rows.length ?? 0),
|
|
5491
|
+
step === "importing" && locale.importingDescription,
|
|
5492
|
+
step === "result" && locale.doneDescription
|
|
5057
5493
|
] })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5058
5494
|
className: "space-y-4",
|
|
5059
5495
|
children: [
|
|
@@ -5084,11 +5520,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5084
5520
|
}),
|
|
5085
5521
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5086
5522
|
className: "text-sm text-muted-foreground",
|
|
5087
|
-
children:
|
|
5523
|
+
children: locale.dragHint
|
|
5088
5524
|
}),
|
|
5089
5525
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5090
5526
|
className: "text-xs text-muted-foreground/60",
|
|
5091
|
-
children:
|
|
5527
|
+
children: locale.formatHint
|
|
5092
5528
|
})
|
|
5093
5529
|
]
|
|
5094
5530
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -5103,7 +5539,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5103
5539
|
size: "sm",
|
|
5104
5540
|
className: "w-full",
|
|
5105
5541
|
onClick: handleDownloadTemplate,
|
|
5106
|
-
children:
|
|
5542
|
+
children: locale.downloadTemplate
|
|
5107
5543
|
})] }),
|
|
5108
5544
|
step === "preview" && parsedData && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
5109
5545
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -5123,13 +5559,9 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5123
5559
|
className: "px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5124
5560
|
children: h
|
|
5125
5561
|
}, h)),
|
|
5126
|
-
parsedData.headers.length > 6 && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
5562
|
+
parsedData.headers.length > 6 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5127
5563
|
className: "px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5128
|
-
children:
|
|
5129
|
-
"+",
|
|
5130
|
-
parsedData.headers.length - 6,
|
|
5131
|
-
" 列"
|
|
5132
|
-
]
|
|
5564
|
+
children: locale.moreColumns(parsedData.headers.length - 6)
|
|
5133
5565
|
})
|
|
5134
5566
|
] })
|
|
5135
5567
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: parsedData.rows.slice(0, 10).map((row, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
@@ -5152,40 +5584,27 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5152
5584
|
})
|
|
5153
5585
|
})
|
|
5154
5586
|
}),
|
|
5155
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
5587
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5156
5588
|
className: "text-sm text-muted-foreground",
|
|
5157
|
-
children:
|
|
5158
|
-
"共 ",
|
|
5159
|
-
parsedData.rows.length,
|
|
5160
|
-
" 条数据",
|
|
5161
|
-
parsedData.rows.length > 10 && "(预览前 10 条)",
|
|
5162
|
-
",",
|
|
5163
|
-
parsedData.headers.length,
|
|
5164
|
-
" 个字段 ,格式: ",
|
|
5165
|
-
parsedData.format.toUpperCase()
|
|
5166
|
-
]
|
|
5589
|
+
children: locale.previewSummary(parsedData.rows.length, parsedData.headers.length, parsedData.format, parsedData.rows.length > 10 ? 10 : void 0)
|
|
5167
5590
|
}),
|
|
5168
5591
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5169
5592
|
className: "flex gap-2 justify-end",
|
|
5170
5593
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
5171
5594
|
variant: "outline",
|
|
5172
5595
|
onClick: reset,
|
|
5173
|
-
children:
|
|
5596
|
+
children: locale.reselect
|
|
5174
5597
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
5175
5598
|
onClick: handleImport,
|
|
5176
|
-
children:
|
|
5599
|
+
children: locale.confirmImport
|
|
5177
5600
|
})]
|
|
5178
5601
|
})
|
|
5179
5602
|
] }),
|
|
5180
5603
|
step === "importing" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5181
5604
|
className: "flex flex-col items-center gap-4 py-8",
|
|
5182
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
5605
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5183
5606
|
className: "text-sm text-muted-foreground",
|
|
5184
|
-
children:
|
|
5185
|
-
"正在导入 ",
|
|
5186
|
-
parsedData?.rows.length ?? 0,
|
|
5187
|
-
" 条数据..."
|
|
5188
|
-
]
|
|
5607
|
+
children: locale.importingRows(parsedData?.rows.length ?? 0)
|
|
5189
5608
|
})]
|
|
5190
5609
|
}),
|
|
5191
5610
|
step === "result" && result && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -5200,7 +5619,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5200
5619
|
children: result.success
|
|
5201
5620
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5202
5621
|
className: "text-xs text-green-600/80",
|
|
5203
|
-
children:
|
|
5622
|
+
children: locale.resultCreated
|
|
5204
5623
|
})]
|
|
5205
5624
|
}),
|
|
5206
5625
|
(result.updated ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -5210,7 +5629,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5210
5629
|
children: result.updated
|
|
5211
5630
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5212
5631
|
className: "text-xs text-blue-600/80",
|
|
5213
|
-
children:
|
|
5632
|
+
children: locale.resultUpdated
|
|
5214
5633
|
})]
|
|
5215
5634
|
}),
|
|
5216
5635
|
result.skipped > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -5220,7 +5639,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5220
5639
|
children: result.skipped
|
|
5221
5640
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5222
5641
|
className: "text-xs text-yellow-600/80",
|
|
5223
|
-
children:
|
|
5642
|
+
children: locale.resultSkipped
|
|
5224
5643
|
})]
|
|
5225
5644
|
}),
|
|
5226
5645
|
result.failed.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -5230,7 +5649,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5230
5649
|
children: result.failed.length
|
|
5231
5650
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5232
5651
|
className: "text-xs text-red-600/80",
|
|
5233
|
-
children:
|
|
5652
|
+
children: locale.resultFailed
|
|
5234
5653
|
})]
|
|
5235
5654
|
})
|
|
5236
5655
|
]
|
|
@@ -5244,10 +5663,10 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5244
5663
|
className: "sticky top-0 bg-red-50 dark:bg-red-950/30",
|
|
5245
5664
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5246
5665
|
className: "px-3 py-2 text-left font-medium text-red-600",
|
|
5247
|
-
children:
|
|
5666
|
+
children: locale.failedRowHeader
|
|
5248
5667
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5249
5668
|
className: "px-3 py-2 text-left font-medium text-red-600",
|
|
5250
|
-
children:
|
|
5669
|
+
children: locale.failedErrorHeader
|
|
5251
5670
|
})] })
|
|
5252
5671
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: result.failed.map((f) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
5253
5672
|
className: "border-t border-red-100 dark:border-red-900",
|
|
@@ -5267,11 +5686,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5267
5686
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
5268
5687
|
variant: "outline",
|
|
5269
5688
|
onClick: () => handleOpenChange(false),
|
|
5270
|
-
children:
|
|
5689
|
+
children: locale.close
|
|
5271
5690
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
5272
5691
|
variant: "outline",
|
|
5273
5692
|
onClick: reset,
|
|
5274
|
-
children:
|
|
5693
|
+
children: locale.continueImport
|
|
5275
5694
|
})]
|
|
5276
5695
|
})] }),
|
|
5277
5696
|
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -5421,13 +5840,13 @@ function buildBatchUpdateFields(schema, batchFields, fields) {
|
|
|
5421
5840
|
/**
|
|
5422
5841
|
* 渲染字段值
|
|
5423
5842
|
*/
|
|
5424
|
-
function renderFieldValue(value, type) {
|
|
5843
|
+
function renderFieldValue(value, type, booleanLocale) {
|
|
5425
5844
|
if (value === null || value === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5426
5845
|
className: "text-muted-foreground",
|
|
5427
5846
|
children: "-"
|
|
5428
5847
|
});
|
|
5429
5848
|
switch (type) {
|
|
5430
|
-
case "boolean": return value ?
|
|
5849
|
+
case "boolean": return value ? booleanLocale.true : booleanLocale.false;
|
|
5431
5850
|
case "date": return formatDate(value);
|
|
5432
5851
|
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Badge, {
|
|
5433
5852
|
variant: "outline",
|
|
@@ -5450,7 +5869,7 @@ function renderFieldValue(value, type) {
|
|
|
5450
5869
|
/**
|
|
5451
5870
|
* ViewModal 组件 - 详情查看弹窗
|
|
5452
5871
|
*/
|
|
5453
|
-
function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldConfig, denyFields }) {
|
|
5872
|
+
function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldConfig, denyFields, locale }) {
|
|
5454
5873
|
if (!data) return null;
|
|
5455
5874
|
const shape = schema.shape;
|
|
5456
5875
|
const denySet = new Set(denyFields ?? []);
|
|
@@ -5470,7 +5889,7 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
|
|
|
5470
5889
|
children: label
|
|
5471
5890
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", {
|
|
5472
5891
|
className: "col-span-2 text-sm",
|
|
5473
|
-
children: renderFieldValue(value, parsed.type)
|
|
5892
|
+
children: renderFieldValue(value, parsed.type, locale.boolean)
|
|
5474
5893
|
})]
|
|
5475
5894
|
}, key);
|
|
5476
5895
|
})
|
|
@@ -5478,23 +5897,89 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
|
|
|
5478
5897
|
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Sheet, {
|
|
5479
5898
|
open,
|
|
5480
5899
|
onOpenChange,
|
|
5481
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.SheetContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.SheetHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.SheetTitle, { children:
|
|
5900
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.SheetContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.SheetHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.SheetTitle, { children: locale.viewModal.title }) }), content] })
|
|
5482
5901
|
});
|
|
5483
5902
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Dialog, {
|
|
5484
5903
|
open,
|
|
5485
5904
|
onOpenChange,
|
|
5486
5905
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogContent, {
|
|
5487
5906
|
className: "max-w-2xl max-h-[80vh] overflow-y-auto",
|
|
5488
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DialogTitle, { children:
|
|
5907
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DialogTitle, { children: locale.viewModal.title }) }), content]
|
|
5489
5908
|
})
|
|
5490
5909
|
});
|
|
5491
5910
|
}
|
|
5911
|
+
function resolveActions(items, defaults, rowActionsLocale) {
|
|
5912
|
+
const defaultItems = [
|
|
5913
|
+
{
|
|
5914
|
+
label: rowActionsLocale.view,
|
|
5915
|
+
onClick: defaults.openView
|
|
5916
|
+
},
|
|
5917
|
+
...defaults.openEdit ? [{
|
|
5918
|
+
label: rowActionsLocale.edit,
|
|
5919
|
+
onClick: defaults.openEdit
|
|
5920
|
+
}] : [],
|
|
5921
|
+
...defaults.copyRow ? [{
|
|
5922
|
+
label: rowActionsLocale.copy,
|
|
5923
|
+
onClick: defaults.copyRow
|
|
5924
|
+
}] : [],
|
|
5925
|
+
...defaults.openDelete ? [{
|
|
5926
|
+
label: rowActionsLocale.delete,
|
|
5927
|
+
onClick: defaults.openDelete,
|
|
5928
|
+
separator: true,
|
|
5929
|
+
variant: "destructive"
|
|
5930
|
+
}] : []
|
|
5931
|
+
];
|
|
5932
|
+
if (!items || items.length === 0) return defaultItems;
|
|
5933
|
+
if (!items.some((i) => i.type !== "custom")) {
|
|
5934
|
+
const startItems = items.filter((i) => i.type === "custom" && i.position === "start").map(({ label, onClick, separator, variant }) => ({
|
|
5935
|
+
label,
|
|
5936
|
+
onClick,
|
|
5937
|
+
separator,
|
|
5938
|
+
variant
|
|
5939
|
+
}));
|
|
5940
|
+
const endItems = items.filter((i) => i.type === "custom" && i.position !== "start").map(({ label, onClick, separator, variant }) => ({
|
|
5941
|
+
label,
|
|
5942
|
+
onClick,
|
|
5943
|
+
separator,
|
|
5944
|
+
variant
|
|
5945
|
+
}));
|
|
5946
|
+
return [
|
|
5947
|
+
...startItems,
|
|
5948
|
+
...defaultItems,
|
|
5949
|
+
...endItems
|
|
5950
|
+
];
|
|
5951
|
+
}
|
|
5952
|
+
const handlerMap = {
|
|
5953
|
+
view: defaults.openView,
|
|
5954
|
+
edit: defaults.openEdit,
|
|
5955
|
+
copy: defaults.copyRow,
|
|
5956
|
+
delete: defaults.openDelete
|
|
5957
|
+
};
|
|
5958
|
+
const variantMap = { delete: "destructive" };
|
|
5959
|
+
return items.flatMap((item) => {
|
|
5960
|
+
if (item.type === "custom") return [{
|
|
5961
|
+
label: item.label,
|
|
5962
|
+
onClick: item.onClick,
|
|
5963
|
+
separator: item.separator,
|
|
5964
|
+
variant: item.variant
|
|
5965
|
+
}];
|
|
5966
|
+
const handler = item.onClick ?? handlerMap[item.type];
|
|
5967
|
+
if (!handler) return [];
|
|
5968
|
+
return [{
|
|
5969
|
+
label: item.label ?? rowActionsLocale[item.type],
|
|
5970
|
+
onClick: handler,
|
|
5971
|
+
separator: item.separator,
|
|
5972
|
+
variant: variantMap[item.type]
|
|
5973
|
+
}];
|
|
5974
|
+
});
|
|
5975
|
+
}
|
|
5492
5976
|
/**
|
|
5493
5977
|
* AutoCrudTable 组件
|
|
5494
5978
|
*
|
|
5495
5979
|
* 高级 CRUD 表格组件,封装了完整的增删改查流程
|
|
5496
5980
|
*/
|
|
5497
|
-
function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions }) {
|
|
5981
|
+
function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions, actions: actionItems, locale: localeProp }) {
|
|
5982
|
+
const locale = resolveLocale(localeProp);
|
|
5498
5983
|
const can = {
|
|
5499
5984
|
create: permissions?.can?.create ?? true,
|
|
5500
5985
|
update: permissions?.can?.update ?? true,
|
|
@@ -5587,18 +6072,18 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5587
6072
|
variant: "outline",
|
|
5588
6073
|
size: "sm",
|
|
5589
6074
|
onClick: () => setImportOpen(true),
|
|
5590
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }),
|
|
6075
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), locale.toolbar.import]
|
|
5591
6076
|
}),
|
|
5592
6077
|
canExport && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Button, {
|
|
5593
6078
|
variant: "outline",
|
|
5594
6079
|
size: "sm",
|
|
5595
6080
|
onClick: handleExportClick,
|
|
5596
6081
|
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
5597
|
-
children: [exporting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "mr-2 h-4 w-4" }), selectedCount > 0 ?
|
|
6082
|
+
children: [exporting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "mr-2 h-4 w-4" }), selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export]
|
|
5598
6083
|
}),
|
|
5599
6084
|
can.create && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
5600
6085
|
onClick: resource.handlers.openCreate,
|
|
5601
|
-
children:
|
|
6086
|
+
children: locale.toolbar.create
|
|
5602
6087
|
})
|
|
5603
6088
|
]
|
|
5604
6089
|
})]
|
|
@@ -5610,12 +6095,12 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5610
6095
|
overrides: tableOverrides,
|
|
5611
6096
|
exclude: hiddenColumns,
|
|
5612
6097
|
filterMode: tableConfig?.filterModes,
|
|
5613
|
-
actions: {
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
},
|
|
6098
|
+
actions: resolveActions(actionItems, {
|
|
6099
|
+
openView: resource.handlers.openView,
|
|
6100
|
+
openEdit: can.update ? resource.handlers.openEdit : void 0,
|
|
6101
|
+
copyRow: can.create ? resource.handlers.copyRow : void 0,
|
|
6102
|
+
openDelete: can.delete ? resource.handlers.openDelete : void 0
|
|
6103
|
+
}, locale.rowActions),
|
|
5619
6104
|
onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
|
|
5620
6105
|
onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
|
|
5621
6106
|
batchUpdateFields: can.update ? batchFields : void 0,
|
|
@@ -5636,7 +6121,8 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5636
6121
|
},
|
|
5637
6122
|
loading: resource.mutations.isCreating || resource.mutations.isUpdating,
|
|
5638
6123
|
variant: resource.modal.variant,
|
|
5639
|
-
overrides: formOverrides
|
|
6124
|
+
overrides: formOverrides,
|
|
6125
|
+
locale: locale.formModal
|
|
5640
6126
|
}),
|
|
5641
6127
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ViewModal, {
|
|
5642
6128
|
open: resource.modal.viewOpen,
|
|
@@ -5645,22 +6131,24 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5645
6131
|
data: resource.modal.selected,
|
|
5646
6132
|
schema,
|
|
5647
6133
|
fields,
|
|
5648
|
-
denyFields
|
|
6134
|
+
denyFields,
|
|
6135
|
+
locale
|
|
5649
6136
|
}),
|
|
5650
6137
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialog, {
|
|
5651
6138
|
open: resource.modal.deleteOpen,
|
|
5652
6139
|
onOpenChange: (open) => !open && resource.handlers.closeModals(),
|
|
5653
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogTitle, { children:
|
|
6140
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogTitle, { children: locale.deleteModal.title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogDescription, { children: locale.deleteModal.description })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogCancel, { children: locale.deleteModal.cancel }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogAction, {
|
|
5654
6141
|
onClick: resource.handlers.confirmDelete,
|
|
5655
6142
|
disabled: resource.mutations.isDeleting,
|
|
5656
|
-
children: resource.mutations.isDeleting ?
|
|
6143
|
+
children: resource.mutations.isDeleting ? locale.deleteModal.confirming : locale.deleteModal.confirm
|
|
5657
6144
|
})] })] })
|
|
5658
6145
|
}),
|
|
5659
6146
|
canImport && resource.handlers.import && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImportDialog, {
|
|
5660
6147
|
open: importOpen,
|
|
5661
6148
|
onOpenChange: setImportOpen,
|
|
5662
6149
|
onImport: resource.handlers.import,
|
|
5663
|
-
columns: importColumns
|
|
6150
|
+
columns: importColumns,
|
|
6151
|
+
locale: locale.importDialog
|
|
5664
6152
|
})
|
|
5665
6153
|
]
|
|
5666
6154
|
});
|
|
@@ -7056,13 +7544,19 @@ exports.createSelectColumn = createSelectColumn;
|
|
|
7056
7544
|
exports.createTRPCDataSource = createTRPCDataSource;
|
|
7057
7545
|
exports.createTableSchema = createTableSchema;
|
|
7058
7546
|
exports.dataToCSV = dataToCSV;
|
|
7547
|
+
exports.deDE = deDE;
|
|
7059
7548
|
exports.downloadCSVTemplate = downloadCSVTemplate;
|
|
7549
|
+
exports.enUS = enUS;
|
|
7550
|
+
exports.esES = esES;
|
|
7060
7551
|
exports.exportAllToCSV = exportAllToCSV;
|
|
7061
7552
|
exports.exportTableToCSV = exportTableToCSV;
|
|
7062
7553
|
exports.formatDate = formatDate;
|
|
7554
|
+
exports.frFR = frFR;
|
|
7063
7555
|
exports.generateCSVTemplate = generateCSVTemplate;
|
|
7064
7556
|
exports.getUrlParams = getUrlParams;
|
|
7065
7557
|
exports.humanize = humanize;
|
|
7558
|
+
exports.jaJP = jaJP;
|
|
7559
|
+
exports.koKR = koKR;
|
|
7066
7560
|
exports.noopToastAdapter = noopToastAdapter;
|
|
7067
7561
|
exports.parseAsArrayOf = parseAsArrayOf;
|
|
7068
7562
|
exports.parseAsInteger = parseAsInteger;
|
|
@@ -7072,6 +7566,7 @@ exports.parseCSV = parseCSV;
|
|
|
7072
7566
|
exports.parseImportFile = parseImportFile;
|
|
7073
7567
|
exports.parseJSON = parseJSON;
|
|
7074
7568
|
exports.parseZodField = parseZodField;
|
|
7569
|
+
exports.resolveLocale = resolveLocale;
|
|
7075
7570
|
exports.setSearchParams = setSearchParams;
|
|
7076
7571
|
exports.useAutoCrudResource = useAutoCrudResource;
|
|
7077
7572
|
exports.useDataTable = useDataTable;
|
|
@@ -7079,4 +7574,5 @@ exports.useQueryState = useQueryState;
|
|
|
7079
7574
|
exports.useQueryStates = useQueryStates;
|
|
7080
7575
|
exports.useReadableFilters = useReadableFilters;
|
|
7081
7576
|
exports.useUrlState = useUrlState;
|
|
7082
|
-
exports.useUrlStates = useUrlStates;
|
|
7577
|
+
exports.useUrlStates = useUrlStates;
|
|
7578
|
+
exports.zhCN = zhCN;
|