@wordrhyme/auto-crud 1.0.1 → 1.0.3

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/dist/index.cjs CHANGED
@@ -4014,8 +4014,7 @@ function createSelectColumn() {
4014
4014
  /**
4015
4015
  * 创建操作列
4016
4016
  */
4017
- function createActionsColumn(config) {
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.jsxs)(__pixpilot_shadcn.DropdownMenuContent, {
4028
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuContent, {
4030
4029
  align: "end",
4031
4030
  className: "w-40",
4032
- children: [
4033
- onView && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuItem, {
4034
- onClick: () => onView(row.original),
4035
- children: "查看"
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
  };
@@ -4830,7 +4814,7 @@ function getComponentProps(type, parsed) {
4830
4814
  function createFormSchema(schema, options) {
4831
4815
  const shape = schema.shape;
4832
4816
  const properties = {};
4833
- const { overrides, exclude = [], layout = "vertical", gridColumns = 2, labelAlign = "top", labelWidth, labelCol, wrapperCol } = options ?? {};
4817
+ const { overrides, exclude = [], layout = "vertical", gridColumns = 1, labelAlign = "top", labelWidth, labelCol, wrapperCol } = options ?? {};
4834
4818
  const decoratorProps = { className: "space-y-2" };
4835
4819
  if (labelAlign) decoratorProps.labelAlign = labelAlign;
4836
4820
  if (labelWidth) decoratorProps.labelWidth = labelWidth;
@@ -4895,7 +4879,7 @@ const FormilySwitch = (0, __formily_react.connect)(__pixpilot_shadcn.Switch, (0,
4895
4879
  value: "checked",
4896
4880
  onInput: "onCheckedChange"
4897
4881
  }));
4898
- function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides, mode = "create", loading = false, gridColumns = 2, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
4882
+ function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides, mode = "create", loading = false, gridColumns = 1, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
4899
4883
  const form = (0, react.useMemo)(() => (0, __formily_core.createForm)({ initialValues }), [JSON.stringify(initialValues)]);
4900
4884
  const formSchema = (0, react.useMemo)(() => createEditFormSchema(zodSchema, {
4901
4885
  overrides,
@@ -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, gridColumns, 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 ? "处理中..." : mode === "create" ? "创建" : "保存"
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, {
@@ -4971,6 +5407,7 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
4971
5407
  loading,
4972
5408
  onSubmit,
4973
5409
  overrides,
5410
+ gridColumns,
4974
5411
  labelAlign,
4975
5412
  labelWidth,
4976
5413
  showSubmitButton: false
@@ -4980,7 +5417,7 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
4980
5417
 
4981
5418
  //#endregion
4982
5419
  //#region src/components/auto-crud/import-dialog.tsx
4983
- function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导入数据" }) {
5420
+ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, locale = zhCN.importDialog }) {
4984
5421
  const [step, setStep] = react.useState("upload");
4985
5422
  const [parsedData, setParsedData] = react.useState(null);
4986
5423
  const [error, setError] = react.useState(null);
@@ -5003,13 +5440,13 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5003
5440
  try {
5004
5441
  const data = await parseImportFile(file);
5005
5442
  if (data.rows.length === 0) {
5006
- setError("文件中没有数据行");
5443
+ setError(locale.errorNoData);
5007
5444
  return;
5008
5445
  }
5009
5446
  setParsedData(data);
5010
5447
  setStep("preview");
5011
5448
  } catch (e) {
5012
- setError(e instanceof Error ? e.message : "文件解析失败");
5449
+ setError(e instanceof Error ? e.message : locale.errorParseFailed);
5013
5450
  }
5014
5451
  }, []);
5015
5452
  const handleDrop = react.useCallback((e) => {
@@ -5029,7 +5466,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5029
5466
  setResult(await onImport(parsedData.rows));
5030
5467
  setStep("result");
5031
5468
  } catch (e) {
5032
- setError(e instanceof Error ? e.message : "导入失败");
5469
+ setError(e instanceof Error ? e.message : locale.errorImportFailed);
5033
5470
  setStep("preview");
5034
5471
  }
5035
5472
  }, [parsedData, onImport]);
@@ -5049,11 +5486,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5049
5486
  onOpenChange: handleOpenChange,
5050
5487
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogContent, {
5051
5488
  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" && "上传 CSV 或 JSON 文件以批量导入数据",
5054
- step === "preview" && `已解析 ${parsedData?.rows.length ?? 0} 条数据,确认后开始导入`,
5055
- step === "importing" && "正在导入数据...",
5056
- step === "result" && "导入完成"
5489
+ 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: [
5490
+ step === "upload" && locale.uploadDescription,
5491
+ step === "preview" && locale.previewDescription(parsedData?.rows.length ?? 0),
5492
+ step === "importing" && locale.importingDescription,
5493
+ step === "result" && locale.doneDescription
5057
5494
  ] })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5058
5495
  className: "space-y-4",
5059
5496
  children: [
@@ -5084,11 +5521,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5084
5521
  }),
5085
5522
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5086
5523
  className: "text-sm text-muted-foreground",
5087
- children: "拖拽文件到此处,或点击选择文件"
5524
+ children: locale.dragHint
5088
5525
  }),
5089
5526
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5090
5527
  className: "text-xs text-muted-foreground/60",
5091
- children: "支持 CSV、JSON 格式"
5528
+ children: locale.formatHint
5092
5529
  })
5093
5530
  ]
5094
5531
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -5103,7 +5540,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5103
5540
  size: "sm",
5104
5541
  className: "w-full",
5105
5542
  onClick: handleDownloadTemplate,
5106
- children: "下载 CSV 模板"
5543
+ children: locale.downloadTemplate
5107
5544
  })] }),
5108
5545
  step === "preview" && parsedData && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
5109
5546
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -5123,13 +5560,9 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5123
5560
  className: "px-3 py-2 text-left font-medium text-muted-foreground",
5124
5561
  children: h
5125
5562
  }, h)),
5126
- parsedData.headers.length > 6 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("th", {
5563
+ parsedData.headers.length > 6 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5127
5564
  className: "px-3 py-2 text-left font-medium text-muted-foreground",
5128
- children: [
5129
- "+",
5130
- parsedData.headers.length - 6,
5131
- " 列"
5132
- ]
5565
+ children: locale.moreColumns(parsedData.headers.length - 6)
5133
5566
  })
5134
5567
  ] })
5135
5568
  }), /* @__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 +5585,27 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5152
5585
  })
5153
5586
  })
5154
5587
  }),
5155
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
5588
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5156
5589
  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
- ]
5590
+ children: locale.previewSummary(parsedData.rows.length, parsedData.headers.length, parsedData.format, parsedData.rows.length > 10 ? 10 : void 0)
5167
5591
  }),
5168
5592
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5169
5593
  className: "flex gap-2 justify-end",
5170
5594
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
5171
5595
  variant: "outline",
5172
5596
  onClick: reset,
5173
- children: "重新选择"
5597
+ children: locale.reselect
5174
5598
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
5175
5599
  onClick: handleImport,
5176
- children: "确认导入"
5600
+ children: locale.confirmImport
5177
5601
  })]
5178
5602
  })
5179
5603
  ] }),
5180
5604
  step === "importing" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5181
5605
  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.jsxs)("p", {
5606
+ 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
5607
  className: "text-sm text-muted-foreground",
5184
- children: [
5185
- "正在导入 ",
5186
- parsedData?.rows.length ?? 0,
5187
- " 条数据..."
5188
- ]
5608
+ children: locale.importingRows(parsedData?.rows.length ?? 0)
5189
5609
  })]
5190
5610
  }),
5191
5611
  step === "result" && result && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5200,7 +5620,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5200
5620
  children: result.success
5201
5621
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5202
5622
  className: "text-xs text-green-600/80",
5203
- children: "新建"
5623
+ children: locale.resultCreated
5204
5624
  })]
5205
5625
  }),
5206
5626
  (result.updated ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5210,7 +5630,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5210
5630
  children: result.updated
5211
5631
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5212
5632
  className: "text-xs text-blue-600/80",
5213
- children: "更新"
5633
+ children: locale.resultUpdated
5214
5634
  })]
5215
5635
  }),
5216
5636
  result.skipped > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5220,7 +5640,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5220
5640
  children: result.skipped
5221
5641
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5222
5642
  className: "text-xs text-yellow-600/80",
5223
- children: "跳过"
5643
+ children: locale.resultSkipped
5224
5644
  })]
5225
5645
  }),
5226
5646
  result.failed.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5230,7 +5650,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5230
5650
  children: result.failed.length
5231
5651
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5232
5652
  className: "text-xs text-red-600/80",
5233
- children: "验证失败"
5653
+ children: locale.resultFailed
5234
5654
  })]
5235
5655
  })
5236
5656
  ]
@@ -5244,10 +5664,10 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5244
5664
  className: "sticky top-0 bg-red-50 dark:bg-red-950/30",
5245
5665
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5246
5666
  className: "px-3 py-2 text-left font-medium text-red-600",
5247
- children: "行号"
5667
+ children: locale.failedRowHeader
5248
5668
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5249
5669
  className: "px-3 py-2 text-left font-medium text-red-600",
5250
- children: "错误"
5670
+ children: locale.failedErrorHeader
5251
5671
  })] })
5252
5672
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: result.failed.map((f) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
5253
5673
  className: "border-t border-red-100 dark:border-red-900",
@@ -5267,11 +5687,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
5267
5687
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
5268
5688
  variant: "outline",
5269
5689
  onClick: () => handleOpenChange(false),
5270
- children: "关闭"
5690
+ children: locale.close
5271
5691
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
5272
5692
  variant: "outline",
5273
5693
  onClick: reset,
5274
- children: "继续导入"
5694
+ children: locale.continueImport
5275
5695
  })]
5276
5696
  })] }),
5277
5697
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -5421,13 +5841,13 @@ function buildBatchUpdateFields(schema, batchFields, fields) {
5421
5841
  /**
5422
5842
  * 渲染字段值
5423
5843
  */
5424
- function renderFieldValue(value, type) {
5844
+ function renderFieldValue(value, type, booleanLocale) {
5425
5845
  if (value === null || value === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5426
5846
  className: "text-muted-foreground",
5427
5847
  children: "-"
5428
5848
  });
5429
5849
  switch (type) {
5430
- case "boolean": return value ? "是" : "否";
5850
+ case "boolean": return value ? booleanLocale.true : booleanLocale.false;
5431
5851
  case "date": return formatDate(value);
5432
5852
  case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Badge, {
5433
5853
  variant: "outline",
@@ -5450,7 +5870,7 @@ function renderFieldValue(value, type) {
5450
5870
  /**
5451
5871
  * ViewModal 组件 - 详情查看弹窗
5452
5872
  */
5453
- function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldConfig, denyFields }) {
5873
+ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldConfig, denyFields, locale }) {
5454
5874
  if (!data) return null;
5455
5875
  const shape = schema.shape;
5456
5876
  const denySet = new Set(denyFields ?? []);
@@ -5470,7 +5890,7 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
5470
5890
  children: label
5471
5891
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", {
5472
5892
  className: "col-span-2 text-sm",
5473
- children: renderFieldValue(value, parsed.type)
5893
+ children: renderFieldValue(value, parsed.type, locale.boolean)
5474
5894
  })]
5475
5895
  }, key);
5476
5896
  })
@@ -5478,23 +5898,89 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
5478
5898
  if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Sheet, {
5479
5899
  open,
5480
5900
  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: "详情" }) }), content] })
5901
+ 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
5902
  });
5483
5903
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Dialog, {
5484
5904
  open,
5485
5905
  onOpenChange,
5486
5906
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DialogContent, {
5487
5907
  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: "详情" }) }), content]
5908
+ 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
5909
  })
5490
5910
  });
5491
5911
  }
5912
+ function resolveActions(items, defaults, rowActionsLocale) {
5913
+ const defaultItems = [
5914
+ {
5915
+ label: rowActionsLocale.view,
5916
+ onClick: defaults.openView
5917
+ },
5918
+ ...defaults.openEdit ? [{
5919
+ label: rowActionsLocale.edit,
5920
+ onClick: defaults.openEdit
5921
+ }] : [],
5922
+ ...defaults.copyRow ? [{
5923
+ label: rowActionsLocale.copy,
5924
+ onClick: defaults.copyRow
5925
+ }] : [],
5926
+ ...defaults.openDelete ? [{
5927
+ label: rowActionsLocale.delete,
5928
+ onClick: defaults.openDelete,
5929
+ separator: true,
5930
+ variant: "destructive"
5931
+ }] : []
5932
+ ];
5933
+ if (!items || items.length === 0) return defaultItems;
5934
+ if (!items.some((i) => i.type !== "custom")) {
5935
+ const startItems = items.filter((i) => i.type === "custom" && i.position === "start").map(({ label, onClick, separator, variant }) => ({
5936
+ label,
5937
+ onClick,
5938
+ separator,
5939
+ variant
5940
+ }));
5941
+ const endItems = items.filter((i) => i.type === "custom" && i.position !== "start").map(({ label, onClick, separator, variant }) => ({
5942
+ label,
5943
+ onClick,
5944
+ separator,
5945
+ variant
5946
+ }));
5947
+ return [
5948
+ ...startItems,
5949
+ ...defaultItems,
5950
+ ...endItems
5951
+ ];
5952
+ }
5953
+ const handlerMap = {
5954
+ view: defaults.openView,
5955
+ edit: defaults.openEdit,
5956
+ copy: defaults.copyRow,
5957
+ delete: defaults.openDelete
5958
+ };
5959
+ const variantMap = { delete: "destructive" };
5960
+ return items.flatMap((item) => {
5961
+ if (item.type === "custom") return [{
5962
+ label: item.label,
5963
+ onClick: item.onClick,
5964
+ separator: item.separator,
5965
+ variant: item.variant
5966
+ }];
5967
+ const handler = item.onClick ?? handlerMap[item.type];
5968
+ if (!handler) return [];
5969
+ return [{
5970
+ label: item.label ?? rowActionsLocale[item.type],
5971
+ onClick: handler,
5972
+ separator: item.separator,
5973
+ variant: variantMap[item.type]
5974
+ }];
5975
+ });
5976
+ }
5492
5977
  /**
5493
5978
  * AutoCrudTable 组件
5494
5979
  *
5495
5980
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
5496
5981
  */
5497
- function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions }) {
5982
+ function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions, actions: actionItems, locale: localeProp }) {
5983
+ const locale = resolveLocale(localeProp);
5498
5984
  const can = {
5499
5985
  create: permissions?.can?.create ?? true,
5500
5986
  update: permissions?.can?.update ?? true,
@@ -5587,18 +6073,18 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
5587
6073
  variant: "outline",
5588
6074
  size: "sm",
5589
6075
  onClick: () => setImportOpen(true),
5590
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), "导入"]
6076
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), locale.toolbar.import]
5591
6077
  }),
5592
6078
  canExport && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Button, {
5593
6079
  variant: "outline",
5594
6080
  size: "sm",
5595
6081
  onClick: handleExportClick,
5596
6082
  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 ? `导出(${selectedCount})` : "导出"]
6083
+ 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
6084
  }),
5599
6085
  can.create && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
5600
6086
  onClick: resource.handlers.openCreate,
5601
- children: "新建"
6087
+ children: locale.toolbar.create
5602
6088
  })
5603
6089
  ]
5604
6090
  })]
@@ -5610,12 +6096,12 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
5610
6096
  overrides: tableOverrides,
5611
6097
  exclude: hiddenColumns,
5612
6098
  filterMode: tableConfig?.filterModes,
5613
- actions: {
5614
- onView: resource.handlers.openView,
5615
- onEdit: can.update ? resource.handlers.openEdit : void 0,
5616
- onCopy: can.create ? resource.handlers.copyRow : void 0,
5617
- onDelete: can.delete ? resource.handlers.openDelete : void 0
5618
- },
6099
+ actions: resolveActions(actionItems, {
6100
+ openView: resource.handlers.openView,
6101
+ openEdit: can.update ? resource.handlers.openEdit : void 0,
6102
+ copyRow: can.create ? resource.handlers.copyRow : void 0,
6103
+ openDelete: can.delete ? resource.handlers.openDelete : void 0
6104
+ }, locale.rowActions),
5619
6105
  onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
5620
6106
  onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
5621
6107
  batchUpdateFields: can.update ? batchFields : void 0,
@@ -5636,7 +6122,9 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
5636
6122
  },
5637
6123
  loading: resource.mutations.isCreating || resource.mutations.isUpdating,
5638
6124
  variant: resource.modal.variant,
5639
- overrides: formOverrides
6125
+ overrides: formOverrides,
6126
+ locale: locale.formModal,
6127
+ gridColumns: formConfig?.columns
5640
6128
  }),
5641
6129
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ViewModal, {
5642
6130
  open: resource.modal.viewOpen,
@@ -5645,22 +6133,24 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
5645
6133
  data: resource.modal.selected,
5646
6134
  schema,
5647
6135
  fields,
5648
- denyFields
6136
+ denyFields,
6137
+ locale
5649
6138
  }),
5650
6139
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialog, {
5651
6140
  open: resource.modal.deleteOpen,
5652
6141
  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: "确认删除" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogDescription, { children: "此操作无法撤销。确定要删除这条记录吗?" })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogCancel, { children: "取消" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.AlertDialogAction, {
6142
+ 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
6143
  onClick: resource.handlers.confirmDelete,
5655
6144
  disabled: resource.mutations.isDeleting,
5656
- children: resource.mutations.isDeleting ? "删除中..." : "确认删除"
6145
+ children: resource.mutations.isDeleting ? locale.deleteModal.confirming : locale.deleteModal.confirm
5657
6146
  })] })] })
5658
6147
  }),
5659
6148
  canImport && resource.handlers.import && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImportDialog, {
5660
6149
  open: importOpen,
5661
6150
  onOpenChange: setImportOpen,
5662
6151
  onImport: resource.handlers.import,
5663
- columns: importColumns
6152
+ columns: importColumns,
6153
+ locale: locale.importDialog
5664
6154
  })
5665
6155
  ]
5666
6156
  });
@@ -7056,13 +7546,19 @@ exports.createSelectColumn = createSelectColumn;
7056
7546
  exports.createTRPCDataSource = createTRPCDataSource;
7057
7547
  exports.createTableSchema = createTableSchema;
7058
7548
  exports.dataToCSV = dataToCSV;
7549
+ exports.deDE = deDE;
7059
7550
  exports.downloadCSVTemplate = downloadCSVTemplate;
7551
+ exports.enUS = enUS;
7552
+ exports.esES = esES;
7060
7553
  exports.exportAllToCSV = exportAllToCSV;
7061
7554
  exports.exportTableToCSV = exportTableToCSV;
7062
7555
  exports.formatDate = formatDate;
7556
+ exports.frFR = frFR;
7063
7557
  exports.generateCSVTemplate = generateCSVTemplate;
7064
7558
  exports.getUrlParams = getUrlParams;
7065
7559
  exports.humanize = humanize;
7560
+ exports.jaJP = jaJP;
7561
+ exports.koKR = koKR;
7066
7562
  exports.noopToastAdapter = noopToastAdapter;
7067
7563
  exports.parseAsArrayOf = parseAsArrayOf;
7068
7564
  exports.parseAsInteger = parseAsInteger;
@@ -7072,6 +7568,7 @@ exports.parseCSV = parseCSV;
7072
7568
  exports.parseImportFile = parseImportFile;
7073
7569
  exports.parseJSON = parseJSON;
7074
7570
  exports.parseZodField = parseZodField;
7571
+ exports.resolveLocale = resolveLocale;
7075
7572
  exports.setSearchParams = setSearchParams;
7076
7573
  exports.useAutoCrudResource = useAutoCrudResource;
7077
7574
  exports.useDataTable = useDataTable;
@@ -7079,4 +7576,5 @@ exports.useQueryState = useQueryState;
7079
7576
  exports.useQueryStates = useQueryStates;
7080
7577
  exports.useReadableFilters = useReadableFilters;
7081
7578
  exports.useUrlState = useUrlState;
7082
- exports.useUrlStates = useUrlStates;
7579
+ exports.useUrlStates = useUrlStates;
7580
+ exports.zhCN = zhCN;