@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.js
CHANGED
|
@@ -3972,8 +3972,7 @@ function createSelectColumn() {
|
|
|
3972
3972
|
/**
|
|
3973
3973
|
* 创建操作列
|
|
3974
3974
|
*/
|
|
3975
|
-
function createActionsColumn(
|
|
3976
|
-
const { onEdit, onDelete, onView, onCopy } = config;
|
|
3975
|
+
function createActionsColumn(items) {
|
|
3977
3976
|
return {
|
|
3978
3977
|
id: "actions",
|
|
3979
3978
|
cell: ({ row }) => /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
@@ -3984,29 +3983,14 @@ function createActionsColumn(config) {
|
|
|
3984
3983
|
className: "flex size-8 p-0 data-[state=open]:bg-muted",
|
|
3985
3984
|
children: /* @__PURE__ */ jsx(Ellipsis, { className: "size-4" })
|
|
3986
3985
|
})
|
|
3987
|
-
}), /* @__PURE__ */
|
|
3986
|
+
}), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
3988
3987
|
align: "end",
|
|
3989
3988
|
className: "w-40",
|
|
3990
|
-
children: [
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
onEdit && /* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
3996
|
-
onClick: () => onEdit(row.original),
|
|
3997
|
-
children: "编辑"
|
|
3998
|
-
}),
|
|
3999
|
-
onCopy && /* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
4000
|
-
onClick: () => onCopy(row.original),
|
|
4001
|
-
children: "复制"
|
|
4002
|
-
}),
|
|
4003
|
-
(onView || onEdit || onCopy) && onDelete && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
4004
|
-
onDelete && /* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
4005
|
-
className: "text-destructive",
|
|
4006
|
-
onClick: () => onDelete(row.original),
|
|
4007
|
-
children: "删除"
|
|
4008
|
-
})
|
|
4009
|
-
]
|
|
3989
|
+
children: items.map((item, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [item.separator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
3990
|
+
className: item.variant === "destructive" ? "text-destructive" : "",
|
|
3991
|
+
onClick: () => item.onClick(row.original),
|
|
3992
|
+
children: item.label
|
|
3993
|
+
})] }, i))
|
|
4010
3994
|
})] }),
|
|
4011
3995
|
size: 40
|
|
4012
3996
|
};
|
|
@@ -4894,10 +4878,462 @@ function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides,
|
|
|
4894
4878
|
}
|
|
4895
4879
|
const AutoForm = forwardRef(AutoFormInner);
|
|
4896
4880
|
|
|
4881
|
+
//#endregion
|
|
4882
|
+
//#region src/i18n/locale.ts
|
|
4883
|
+
const zhCN = {
|
|
4884
|
+
toolbar: {
|
|
4885
|
+
create: "新建",
|
|
4886
|
+
import: "导入",
|
|
4887
|
+
export: "导出",
|
|
4888
|
+
exportSelected: (count) => `导出(${count})`
|
|
4889
|
+
},
|
|
4890
|
+
rowActions: {
|
|
4891
|
+
view: "查看",
|
|
4892
|
+
edit: "编辑",
|
|
4893
|
+
copy: "复制",
|
|
4894
|
+
delete: "删除"
|
|
4895
|
+
},
|
|
4896
|
+
viewModal: { title: "详情" },
|
|
4897
|
+
boolean: {
|
|
4898
|
+
true: "是",
|
|
4899
|
+
false: "否"
|
|
4900
|
+
},
|
|
4901
|
+
formModal: {
|
|
4902
|
+
createTitle: "新建",
|
|
4903
|
+
editTitle: "编辑",
|
|
4904
|
+
cancel: "取消",
|
|
4905
|
+
create: "创建",
|
|
4906
|
+
save: "保存",
|
|
4907
|
+
submitting: "处理中..."
|
|
4908
|
+
},
|
|
4909
|
+
deleteModal: {
|
|
4910
|
+
title: "确认删除",
|
|
4911
|
+
description: "此操作无法撤销。确定要删除这条记录吗?",
|
|
4912
|
+
cancel: "取消",
|
|
4913
|
+
confirm: "确认删除",
|
|
4914
|
+
confirming: "删除中..."
|
|
4915
|
+
},
|
|
4916
|
+
importDialog: {
|
|
4917
|
+
title: "导入数据",
|
|
4918
|
+
uploadDescription: "上传 CSV 或 JSON 文件以批量导入数据",
|
|
4919
|
+
previewDescription: (count) => `已解析 ${count} 条数据,确认后开始导入`,
|
|
4920
|
+
importingDescription: "正在导入数据...",
|
|
4921
|
+
doneDescription: "导入完成",
|
|
4922
|
+
dragHint: "拖拽文件到此处,或点击选择文件",
|
|
4923
|
+
formatHint: "支持 CSV、JSON 格式",
|
|
4924
|
+
downloadTemplate: "下载 CSV 模板",
|
|
4925
|
+
moreColumns: (count) => `+${count} 列`,
|
|
4926
|
+
previewSummary: (rows, fields, format, previewLimit) => `共 ${rows} 条数据${previewLimit ? `(预览前 ${previewLimit} 条)` : ""},${fields} 个字段,格式: ${format.toUpperCase()}`,
|
|
4927
|
+
reselect: "重新选择",
|
|
4928
|
+
confirmImport: "确认导入",
|
|
4929
|
+
importingRows: (count) => `正在导入 ${count} 条数据...`,
|
|
4930
|
+
resultCreated: "新建",
|
|
4931
|
+
resultUpdated: "更新",
|
|
4932
|
+
resultSkipped: "跳过",
|
|
4933
|
+
resultFailed: "验证失败",
|
|
4934
|
+
failedRowHeader: "行号",
|
|
4935
|
+
failedErrorHeader: "错误",
|
|
4936
|
+
close: "关闭",
|
|
4937
|
+
continueImport: "继续导入",
|
|
4938
|
+
errorNoData: "文件中没有数据行",
|
|
4939
|
+
errorParseFailed: "文件解析失败",
|
|
4940
|
+
errorImportFailed: "导入失败"
|
|
4941
|
+
}
|
|
4942
|
+
};
|
|
4943
|
+
const enUS = {
|
|
4944
|
+
toolbar: {
|
|
4945
|
+
create: "New",
|
|
4946
|
+
import: "Import",
|
|
4947
|
+
export: "Export",
|
|
4948
|
+
exportSelected: (count) => `Export (${count})`
|
|
4949
|
+
},
|
|
4950
|
+
rowActions: {
|
|
4951
|
+
view: "View",
|
|
4952
|
+
edit: "Edit",
|
|
4953
|
+
copy: "Copy",
|
|
4954
|
+
delete: "Delete"
|
|
4955
|
+
},
|
|
4956
|
+
viewModal: { title: "Details" },
|
|
4957
|
+
boolean: {
|
|
4958
|
+
true: "Yes",
|
|
4959
|
+
false: "No"
|
|
4960
|
+
},
|
|
4961
|
+
formModal: {
|
|
4962
|
+
createTitle: "New",
|
|
4963
|
+
editTitle: "Edit",
|
|
4964
|
+
cancel: "Cancel",
|
|
4965
|
+
create: "Create",
|
|
4966
|
+
save: "Save",
|
|
4967
|
+
submitting: "Processing..."
|
|
4968
|
+
},
|
|
4969
|
+
deleteModal: {
|
|
4970
|
+
title: "Confirm Delete",
|
|
4971
|
+
description: "This action cannot be undone. Are you sure you want to delete this record?",
|
|
4972
|
+
cancel: "Cancel",
|
|
4973
|
+
confirm: "Delete",
|
|
4974
|
+
confirming: "Deleting..."
|
|
4975
|
+
},
|
|
4976
|
+
importDialog: {
|
|
4977
|
+
title: "Import Data",
|
|
4978
|
+
uploadDescription: "Upload a CSV or JSON file to bulk import data",
|
|
4979
|
+
previewDescription: (count) => `Parsed ${count} records, confirm to start importing`,
|
|
4980
|
+
importingDescription: "Importing data...",
|
|
4981
|
+
doneDescription: "Import complete",
|
|
4982
|
+
dragHint: "Drag file here, or click to select",
|
|
4983
|
+
formatHint: "Supports CSV, JSON formats",
|
|
4984
|
+
downloadTemplate: "Download CSV Template",
|
|
4985
|
+
moreColumns: (count) => `+${count} more`,
|
|
4986
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} records${previewLimit ? ` (preview first ${previewLimit})` : ""}, ${fields} fields, format: ${format.toUpperCase()}`,
|
|
4987
|
+
reselect: "Reselect",
|
|
4988
|
+
confirmImport: "Confirm Import",
|
|
4989
|
+
importingRows: (count) => `Importing ${count} records...`,
|
|
4990
|
+
resultCreated: "Created",
|
|
4991
|
+
resultUpdated: "Updated",
|
|
4992
|
+
resultSkipped: "Skipped",
|
|
4993
|
+
resultFailed: "Failed",
|
|
4994
|
+
failedRowHeader: "Row",
|
|
4995
|
+
failedErrorHeader: "Error",
|
|
4996
|
+
close: "Close",
|
|
4997
|
+
continueImport: "Import More",
|
|
4998
|
+
errorNoData: "No data rows found in file",
|
|
4999
|
+
errorParseFailed: "Failed to parse file",
|
|
5000
|
+
errorImportFailed: "Import failed"
|
|
5001
|
+
}
|
|
5002
|
+
};
|
|
5003
|
+
const jaJP = {
|
|
5004
|
+
toolbar: {
|
|
5005
|
+
create: "新規作成",
|
|
5006
|
+
import: "インポート",
|
|
5007
|
+
export: "エクスポート",
|
|
5008
|
+
exportSelected: (count) => `エクスポート(${count})`
|
|
5009
|
+
},
|
|
5010
|
+
rowActions: {
|
|
5011
|
+
view: "詳細",
|
|
5012
|
+
edit: "編集",
|
|
5013
|
+
copy: "コピー",
|
|
5014
|
+
delete: "削除"
|
|
5015
|
+
},
|
|
5016
|
+
viewModal: { title: "詳細" },
|
|
5017
|
+
boolean: {
|
|
5018
|
+
true: "はい",
|
|
5019
|
+
false: "いいえ"
|
|
5020
|
+
},
|
|
5021
|
+
formModal: {
|
|
5022
|
+
createTitle: "新規作成",
|
|
5023
|
+
editTitle: "編集",
|
|
5024
|
+
cancel: "キャンセル",
|
|
5025
|
+
create: "作成",
|
|
5026
|
+
save: "保存",
|
|
5027
|
+
submitting: "処理中..."
|
|
5028
|
+
},
|
|
5029
|
+
deleteModal: {
|
|
5030
|
+
title: "削除の確認",
|
|
5031
|
+
description: "この操作は元に戻せません。このレコードを削除してもよろしいですか?",
|
|
5032
|
+
cancel: "キャンセル",
|
|
5033
|
+
confirm: "削除する",
|
|
5034
|
+
confirming: "削除中..."
|
|
5035
|
+
},
|
|
5036
|
+
importDialog: {
|
|
5037
|
+
title: "データのインポート",
|
|
5038
|
+
uploadDescription: "CSVまたはJSONファイルをアップロードして一括インポート",
|
|
5039
|
+
previewDescription: (count) => `${count}件のデータを解析しました。確認してインポートを開始します`,
|
|
5040
|
+
importingDescription: "データをインポート中...",
|
|
5041
|
+
doneDescription: "インポート完了",
|
|
5042
|
+
dragHint: "ファイルをここにドラッグするか、クリックして選択",
|
|
5043
|
+
formatHint: "CSV・JSON形式に対応",
|
|
5044
|
+
downloadTemplate: "CSVテンプレートをダウンロード",
|
|
5045
|
+
moreColumns: (count) => `+${count}列`,
|
|
5046
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows}件${previewLimit ? `(上位${previewLimit}件プレビュー)` : ""}、${fields}フィールド、形式: ${format.toUpperCase()}`,
|
|
5047
|
+
reselect: "再選択",
|
|
5048
|
+
confirmImport: "インポートを確認",
|
|
5049
|
+
importingRows: (count) => `${count}件をインポート中...`,
|
|
5050
|
+
resultCreated: "新規作成",
|
|
5051
|
+
resultUpdated: "更新",
|
|
5052
|
+
resultSkipped: "スキップ",
|
|
5053
|
+
resultFailed: "失敗",
|
|
5054
|
+
failedRowHeader: "行番号",
|
|
5055
|
+
failedErrorHeader: "エラー",
|
|
5056
|
+
close: "閉じる",
|
|
5057
|
+
continueImport: "続けてインポート",
|
|
5058
|
+
errorNoData: "ファイルにデータ行がありません",
|
|
5059
|
+
errorParseFailed: "ファイルの解析に失敗しました",
|
|
5060
|
+
errorImportFailed: "インポートに失敗しました"
|
|
5061
|
+
}
|
|
5062
|
+
};
|
|
5063
|
+
const koKR = {
|
|
5064
|
+
toolbar: {
|
|
5065
|
+
create: "새로 만들기",
|
|
5066
|
+
import: "가져오기",
|
|
5067
|
+
export: "내보내기",
|
|
5068
|
+
exportSelected: (count) => `내보내기(${count})`
|
|
5069
|
+
},
|
|
5070
|
+
rowActions: {
|
|
5071
|
+
view: "보기",
|
|
5072
|
+
edit: "편집",
|
|
5073
|
+
copy: "복사",
|
|
5074
|
+
delete: "삭제"
|
|
5075
|
+
},
|
|
5076
|
+
viewModal: { title: "상세 정보" },
|
|
5077
|
+
boolean: {
|
|
5078
|
+
true: "예",
|
|
5079
|
+
false: "아니요"
|
|
5080
|
+
},
|
|
5081
|
+
formModal: {
|
|
5082
|
+
createTitle: "새로 만들기",
|
|
5083
|
+
editTitle: "편집",
|
|
5084
|
+
cancel: "취소",
|
|
5085
|
+
create: "만들기",
|
|
5086
|
+
save: "저장",
|
|
5087
|
+
submitting: "처리 중..."
|
|
5088
|
+
},
|
|
5089
|
+
deleteModal: {
|
|
5090
|
+
title: "삭제 확인",
|
|
5091
|
+
description: "이 작업은 취소할 수 없습니다. 이 레코드를 삭제하시겠습니까?",
|
|
5092
|
+
cancel: "취소",
|
|
5093
|
+
confirm: "삭제",
|
|
5094
|
+
confirming: "삭제 중..."
|
|
5095
|
+
},
|
|
5096
|
+
importDialog: {
|
|
5097
|
+
title: "데이터 가져오기",
|
|
5098
|
+
uploadDescription: "CSV 또는 JSON 파일을 업로드하여 일괄 가져오기",
|
|
5099
|
+
previewDescription: (count) => `${count}개의 데이터를 분석했습니다. 확인 후 가져오기를 시작합니다`,
|
|
5100
|
+
importingDescription: "데이터를 가져오는 중...",
|
|
5101
|
+
doneDescription: "가져오기 완료",
|
|
5102
|
+
dragHint: "파일을 여기에 드래그하거나 클릭하여 선택",
|
|
5103
|
+
formatHint: "CSV, JSON 형식 지원",
|
|
5104
|
+
downloadTemplate: "CSV 템플릿 다운로드",
|
|
5105
|
+
moreColumns: (count) => `+${count}열 더`,
|
|
5106
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows}개 레코드${previewLimit ? ` (상위 ${previewLimit}개 미리보기)` : ""}, ${fields}개 필드, 형식: ${format.toUpperCase()}`,
|
|
5107
|
+
reselect: "다시 선택",
|
|
5108
|
+
confirmImport: "가져오기 확인",
|
|
5109
|
+
importingRows: (count) => `${count}개의 레코드를 가져오는 중...`,
|
|
5110
|
+
resultCreated: "생성됨",
|
|
5111
|
+
resultUpdated: "업데이트됨",
|
|
5112
|
+
resultSkipped: "건너뜀",
|
|
5113
|
+
resultFailed: "실패",
|
|
5114
|
+
failedRowHeader: "행 번호",
|
|
5115
|
+
failedErrorHeader: "오류",
|
|
5116
|
+
close: "닫기",
|
|
5117
|
+
continueImport: "계속 가져오기",
|
|
5118
|
+
errorNoData: "파일에 데이터 행이 없습니다",
|
|
5119
|
+
errorParseFailed: "파일 파싱에 실패했습니다",
|
|
5120
|
+
errorImportFailed: "가져오기에 실패했습니다"
|
|
5121
|
+
}
|
|
5122
|
+
};
|
|
5123
|
+
const frFR = {
|
|
5124
|
+
toolbar: {
|
|
5125
|
+
create: "Nouveau",
|
|
5126
|
+
import: "Importer",
|
|
5127
|
+
export: "Exporter",
|
|
5128
|
+
exportSelected: (count) => `Exporter (${count})`
|
|
5129
|
+
},
|
|
5130
|
+
rowActions: {
|
|
5131
|
+
view: "Voir",
|
|
5132
|
+
edit: "Modifier",
|
|
5133
|
+
copy: "Copier",
|
|
5134
|
+
delete: "Supprimer"
|
|
5135
|
+
},
|
|
5136
|
+
viewModal: { title: "Détails" },
|
|
5137
|
+
boolean: {
|
|
5138
|
+
true: "Oui",
|
|
5139
|
+
false: "Non"
|
|
5140
|
+
},
|
|
5141
|
+
formModal: {
|
|
5142
|
+
createTitle: "Nouveau",
|
|
5143
|
+
editTitle: "Modifier",
|
|
5144
|
+
cancel: "Annuler",
|
|
5145
|
+
create: "Créer",
|
|
5146
|
+
save: "Enregistrer",
|
|
5147
|
+
submitting: "En cours..."
|
|
5148
|
+
},
|
|
5149
|
+
deleteModal: {
|
|
5150
|
+
title: "Confirmer la suppression",
|
|
5151
|
+
description: "Cette action est irréversible. Voulez-vous vraiment supprimer cet enregistrement ?",
|
|
5152
|
+
cancel: "Annuler",
|
|
5153
|
+
confirm: "Supprimer",
|
|
5154
|
+
confirming: "Suppression..."
|
|
5155
|
+
},
|
|
5156
|
+
importDialog: {
|
|
5157
|
+
title: "Importer des données",
|
|
5158
|
+
uploadDescription: "Téléchargez un fichier CSV ou JSON pour importer en masse",
|
|
5159
|
+
previewDescription: (count) => `${count} enregistrements analysés, confirmez pour démarrer l'import`,
|
|
5160
|
+
importingDescription: "Importation en cours...",
|
|
5161
|
+
doneDescription: "Import terminé",
|
|
5162
|
+
dragHint: "Glissez un fichier ici ou cliquez pour sélectionner",
|
|
5163
|
+
formatHint: "Formats CSV et JSON acceptés",
|
|
5164
|
+
downloadTemplate: "Télécharger le modèle CSV",
|
|
5165
|
+
moreColumns: (count) => `+${count} colonnes`,
|
|
5166
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} enregistrements${previewLimit ? ` (aperçu des ${previewLimit} premiers)` : ""}, ${fields} champs, format : ${format.toUpperCase()}`,
|
|
5167
|
+
reselect: "Resélectionner",
|
|
5168
|
+
confirmImport: "Confirmer l'import",
|
|
5169
|
+
importingRows: (count) => `Importation de ${count} enregistrements...`,
|
|
5170
|
+
resultCreated: "Créés",
|
|
5171
|
+
resultUpdated: "Mis à jour",
|
|
5172
|
+
resultSkipped: "Ignorés",
|
|
5173
|
+
resultFailed: "Échoués",
|
|
5174
|
+
failedRowHeader: "Ligne",
|
|
5175
|
+
failedErrorHeader: "Erreur",
|
|
5176
|
+
close: "Fermer",
|
|
5177
|
+
continueImport: "Continuer l'import",
|
|
5178
|
+
errorNoData: "Aucune ligne de données dans le fichier",
|
|
5179
|
+
errorParseFailed: "Échec de l'analyse du fichier",
|
|
5180
|
+
errorImportFailed: "Échec de l'importation"
|
|
5181
|
+
}
|
|
5182
|
+
};
|
|
5183
|
+
const deDE = {
|
|
5184
|
+
toolbar: {
|
|
5185
|
+
create: "Neu",
|
|
5186
|
+
import: "Importieren",
|
|
5187
|
+
export: "Exportieren",
|
|
5188
|
+
exportSelected: (count) => `Exportieren (${count})`
|
|
5189
|
+
},
|
|
5190
|
+
rowActions: {
|
|
5191
|
+
view: "Anzeigen",
|
|
5192
|
+
edit: "Bearbeiten",
|
|
5193
|
+
copy: "Kopieren",
|
|
5194
|
+
delete: "Löschen"
|
|
5195
|
+
},
|
|
5196
|
+
viewModal: { title: "Details" },
|
|
5197
|
+
boolean: {
|
|
5198
|
+
true: "Ja",
|
|
5199
|
+
false: "Nein"
|
|
5200
|
+
},
|
|
5201
|
+
formModal: {
|
|
5202
|
+
createTitle: "Neu",
|
|
5203
|
+
editTitle: "Bearbeiten",
|
|
5204
|
+
cancel: "Abbrechen",
|
|
5205
|
+
create: "Erstellen",
|
|
5206
|
+
save: "Speichern",
|
|
5207
|
+
submitting: "Wird verarbeitet..."
|
|
5208
|
+
},
|
|
5209
|
+
deleteModal: {
|
|
5210
|
+
title: "Löschen bestätigen",
|
|
5211
|
+
description: "Diese Aktion kann nicht rückgängig gemacht werden. Möchten Sie diesen Datensatz wirklich löschen?",
|
|
5212
|
+
cancel: "Abbrechen",
|
|
5213
|
+
confirm: "Löschen",
|
|
5214
|
+
confirming: "Wird gelöscht..."
|
|
5215
|
+
},
|
|
5216
|
+
importDialog: {
|
|
5217
|
+
title: "Daten importieren",
|
|
5218
|
+
uploadDescription: "CSV- oder JSON-Datei hochladen, um Daten massenweise zu importieren",
|
|
5219
|
+
previewDescription: (count) => `${count} Datensätze analysiert, bestätigen Sie den Import`,
|
|
5220
|
+
importingDescription: "Daten werden importiert...",
|
|
5221
|
+
doneDescription: "Import abgeschlossen",
|
|
5222
|
+
dragHint: "Datei hierher ziehen oder klicken zum Auswählen",
|
|
5223
|
+
formatHint: "CSV- und JSON-Formate werden unterstützt",
|
|
5224
|
+
downloadTemplate: "CSV-Vorlage herunterladen",
|
|
5225
|
+
moreColumns: (count) => `+${count} Spalten`,
|
|
5226
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} Datensätze${previewLimit ? ` (Vorschau der ersten ${previewLimit})` : ""}, ${fields} Felder, Format: ${format.toUpperCase()}`,
|
|
5227
|
+
reselect: "Neu auswählen",
|
|
5228
|
+
confirmImport: "Import bestätigen",
|
|
5229
|
+
importingRows: (count) => `${count} Datensätze werden importiert...`,
|
|
5230
|
+
resultCreated: "Erstellt",
|
|
5231
|
+
resultUpdated: "Aktualisiert",
|
|
5232
|
+
resultSkipped: "Übersprungen",
|
|
5233
|
+
resultFailed: "Fehlgeschlagen",
|
|
5234
|
+
failedRowHeader: "Zeile",
|
|
5235
|
+
failedErrorHeader: "Fehler",
|
|
5236
|
+
close: "Schließen",
|
|
5237
|
+
continueImport: "Weiteren Import starten",
|
|
5238
|
+
errorNoData: "Keine Datenzeilen in der Datei",
|
|
5239
|
+
errorParseFailed: "Datei konnte nicht analysiert werden",
|
|
5240
|
+
errorImportFailed: "Import fehlgeschlagen"
|
|
5241
|
+
}
|
|
5242
|
+
};
|
|
5243
|
+
const esES = {
|
|
5244
|
+
toolbar: {
|
|
5245
|
+
create: "Nuevo",
|
|
5246
|
+
import: "Importar",
|
|
5247
|
+
export: "Exportar",
|
|
5248
|
+
exportSelected: (count) => `Exportar (${count})`
|
|
5249
|
+
},
|
|
5250
|
+
rowActions: {
|
|
5251
|
+
view: "Ver",
|
|
5252
|
+
edit: "Editar",
|
|
5253
|
+
copy: "Copiar",
|
|
5254
|
+
delete: "Eliminar"
|
|
5255
|
+
},
|
|
5256
|
+
viewModal: { title: "Detalles" },
|
|
5257
|
+
boolean: {
|
|
5258
|
+
true: "Sí",
|
|
5259
|
+
false: "No"
|
|
5260
|
+
},
|
|
5261
|
+
formModal: {
|
|
5262
|
+
createTitle: "Nuevo",
|
|
5263
|
+
editTitle: "Editar",
|
|
5264
|
+
cancel: "Cancelar",
|
|
5265
|
+
create: "Crear",
|
|
5266
|
+
save: "Guardar",
|
|
5267
|
+
submitting: "Procesando..."
|
|
5268
|
+
},
|
|
5269
|
+
deleteModal: {
|
|
5270
|
+
title: "Confirmar eliminación",
|
|
5271
|
+
description: "Esta acción no se puede deshacer. ¿Está seguro de que desea eliminar este registro?",
|
|
5272
|
+
cancel: "Cancelar",
|
|
5273
|
+
confirm: "Eliminar",
|
|
5274
|
+
confirming: "Eliminando..."
|
|
5275
|
+
},
|
|
5276
|
+
importDialog: {
|
|
5277
|
+
title: "Importar datos",
|
|
5278
|
+
uploadDescription: "Suba un archivo CSV o JSON para importar datos de forma masiva",
|
|
5279
|
+
previewDescription: (count) => `Se analizaron ${count} registros, confirme para iniciar la importación`,
|
|
5280
|
+
importingDescription: "Importando datos...",
|
|
5281
|
+
doneDescription: "Importación completada",
|
|
5282
|
+
dragHint: "Arrastre el archivo aquí o haga clic para seleccionar",
|
|
5283
|
+
formatHint: "Formatos CSV y JSON compatibles",
|
|
5284
|
+
downloadTemplate: "Descargar plantilla CSV",
|
|
5285
|
+
moreColumns: (count) => `+${count} columnas`,
|
|
5286
|
+
previewSummary: (rows, fields, format, previewLimit) => `${rows} registros${previewLimit ? ` (vista previa de los primeros ${previewLimit})` : ""}, ${fields} campos, formato: ${format.toUpperCase()}`,
|
|
5287
|
+
reselect: "Volver a seleccionar",
|
|
5288
|
+
confirmImport: "Confirmar importación",
|
|
5289
|
+
importingRows: (count) => `Importando ${count} registros...`,
|
|
5290
|
+
resultCreated: "Creados",
|
|
5291
|
+
resultUpdated: "Actualizados",
|
|
5292
|
+
resultSkipped: "Omitidos",
|
|
5293
|
+
resultFailed: "Fallidos",
|
|
5294
|
+
failedRowHeader: "Fila",
|
|
5295
|
+
failedErrorHeader: "Error",
|
|
5296
|
+
close: "Cerrar",
|
|
5297
|
+
continueImport: "Continuar importando",
|
|
5298
|
+
errorNoData: "No se encontraron filas de datos en el archivo",
|
|
5299
|
+
errorParseFailed: "Error al analizar el archivo",
|
|
5300
|
+
errorImportFailed: "Error en la importación"
|
|
5301
|
+
}
|
|
5302
|
+
};
|
|
5303
|
+
const BUILTIN_LOCALES = {
|
|
5304
|
+
"zh-CN": zhCN,
|
|
5305
|
+
"en-US": enUS,
|
|
5306
|
+
"ja-JP": jaJP,
|
|
5307
|
+
"ko-KR": koKR,
|
|
5308
|
+
"fr-FR": frFR,
|
|
5309
|
+
"de-DE": deDE,
|
|
5310
|
+
"es-ES": esES
|
|
5311
|
+
};
|
|
5312
|
+
function deepMerge(target, source) {
|
|
5313
|
+
const result = { ...target };
|
|
5314
|
+
for (const key of Object.keys(source)) {
|
|
5315
|
+
const sv = source[key];
|
|
5316
|
+
const tv = target[key];
|
|
5317
|
+
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);
|
|
5318
|
+
else if (sv !== void 0) result[key] = sv;
|
|
5319
|
+
}
|
|
5320
|
+
return result;
|
|
5321
|
+
}
|
|
5322
|
+
/**
|
|
5323
|
+
* 解析 locale prop 为完整的 AutoCrudLocale
|
|
5324
|
+
* - string → 内置语言(fallback: zh-CN)
|
|
5325
|
+
* - object → 以 zh-CN 为基础深合并
|
|
5326
|
+
*/
|
|
5327
|
+
function resolveLocale(localeProp) {
|
|
5328
|
+
if (!localeProp) return zhCN;
|
|
5329
|
+
if (typeof localeProp === "string") return BUILTIN_LOCALES[localeProp] ?? zhCN;
|
|
5330
|
+
return deepMerge(zhCN, localeProp);
|
|
5331
|
+
}
|
|
5332
|
+
|
|
4897
5333
|
//#endregion
|
|
4898
5334
|
//#region src/components/auto-crud/crud-form-modal.tsx
|
|
4899
|
-
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, title, labelAlign, labelWidth }) {
|
|
4900
|
-
const defaultTitle = mode === "create" ?
|
|
5335
|
+
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, title, locale = zhCN.formModal, labelAlign, labelWidth }) {
|
|
5336
|
+
const defaultTitle = mode === "create" ? locale.createTitle : locale.editTitle;
|
|
4901
5337
|
const formRef = useRef(null);
|
|
4902
5338
|
const handleSubmit = async () => {
|
|
4903
5339
|
await formRef.current?.submit();
|
|
@@ -4913,12 +5349,12 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
4913
5349
|
type: "button",
|
|
4914
5350
|
variant: "outline",
|
|
4915
5351
|
onClick: () => onOpenChange(false),
|
|
4916
|
-
children:
|
|
5352
|
+
children: locale.cancel
|
|
4917
5353
|
}), /* @__PURE__ */ jsx(Button, {
|
|
4918
5354
|
type: "button",
|
|
4919
5355
|
onClick: handleSubmit,
|
|
4920
5356
|
disabled: loading,
|
|
4921
|
-
children: loading ?
|
|
5357
|
+
children: loading ? locale.submitting : mode === "create" ? locale.create : locale.save
|
|
4922
5358
|
})]
|
|
4923
5359
|
}),
|
|
4924
5360
|
children: /* @__PURE__ */ jsx(AutoForm, {
|
|
@@ -4938,7 +5374,7 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
4938
5374
|
|
|
4939
5375
|
//#endregion
|
|
4940
5376
|
//#region src/components/auto-crud/import-dialog.tsx
|
|
4941
|
-
function ImportDialog({ open, onOpenChange, onImport, columns = [], title =
|
|
5377
|
+
function ImportDialog({ open, onOpenChange, onImport, columns = [], title, locale = zhCN.importDialog }) {
|
|
4942
5378
|
const [step, setStep] = React.useState("upload");
|
|
4943
5379
|
const [parsedData, setParsedData] = React.useState(null);
|
|
4944
5380
|
const [error, setError] = React.useState(null);
|
|
@@ -4961,13 +5397,13 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
4961
5397
|
try {
|
|
4962
5398
|
const data = await parseImportFile(file);
|
|
4963
5399
|
if (data.rows.length === 0) {
|
|
4964
|
-
setError(
|
|
5400
|
+
setError(locale.errorNoData);
|
|
4965
5401
|
return;
|
|
4966
5402
|
}
|
|
4967
5403
|
setParsedData(data);
|
|
4968
5404
|
setStep("preview");
|
|
4969
5405
|
} catch (e) {
|
|
4970
|
-
setError(e instanceof Error ? e.message :
|
|
5406
|
+
setError(e instanceof Error ? e.message : locale.errorParseFailed);
|
|
4971
5407
|
}
|
|
4972
5408
|
}, []);
|
|
4973
5409
|
const handleDrop = React.useCallback((e) => {
|
|
@@ -4987,7 +5423,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
4987
5423
|
setResult(await onImport(parsedData.rows));
|
|
4988
5424
|
setStep("result");
|
|
4989
5425
|
} catch (e) {
|
|
4990
|
-
setError(e instanceof Error ? e.message :
|
|
5426
|
+
setError(e instanceof Error ? e.message : locale.errorImportFailed);
|
|
4991
5427
|
setStep("preview");
|
|
4992
5428
|
}
|
|
4993
5429
|
}, [parsedData, onImport]);
|
|
@@ -5007,11 +5443,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5007
5443
|
onOpenChange: handleOpenChange,
|
|
5008
5444
|
children: /* @__PURE__ */ jsxs(DialogContent, {
|
|
5009
5445
|
className: "sm:max-w-[600px]",
|
|
5010
|
-
children: [/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
5011
|
-
step === "upload" &&
|
|
5012
|
-
step === "preview" &&
|
|
5013
|
-
step === "importing" &&
|
|
5014
|
-
step === "result" &&
|
|
5446
|
+
children: [/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: title ?? locale.title }), /* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
5447
|
+
step === "upload" && locale.uploadDescription,
|
|
5448
|
+
step === "preview" && locale.previewDescription(parsedData?.rows.length ?? 0),
|
|
5449
|
+
step === "importing" && locale.importingDescription,
|
|
5450
|
+
step === "result" && locale.doneDescription
|
|
5015
5451
|
] })] }), /* @__PURE__ */ jsxs("div", {
|
|
5016
5452
|
className: "space-y-4",
|
|
5017
5453
|
children: [
|
|
@@ -5042,11 +5478,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5042
5478
|
}),
|
|
5043
5479
|
/* @__PURE__ */ jsx("p", {
|
|
5044
5480
|
className: "text-sm text-muted-foreground",
|
|
5045
|
-
children:
|
|
5481
|
+
children: locale.dragHint
|
|
5046
5482
|
}),
|
|
5047
5483
|
/* @__PURE__ */ jsx("p", {
|
|
5048
5484
|
className: "text-xs text-muted-foreground/60",
|
|
5049
|
-
children:
|
|
5485
|
+
children: locale.formatHint
|
|
5050
5486
|
})
|
|
5051
5487
|
]
|
|
5052
5488
|
}), /* @__PURE__ */ jsx("input", {
|
|
@@ -5061,7 +5497,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5061
5497
|
size: "sm",
|
|
5062
5498
|
className: "w-full",
|
|
5063
5499
|
onClick: handleDownloadTemplate,
|
|
5064
|
-
children:
|
|
5500
|
+
children: locale.downloadTemplate
|
|
5065
5501
|
})] }),
|
|
5066
5502
|
step === "preview" && parsedData && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5067
5503
|
/* @__PURE__ */ jsx("div", {
|
|
@@ -5081,13 +5517,9 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5081
5517
|
className: "px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5082
5518
|
children: h
|
|
5083
5519
|
}, h)),
|
|
5084
|
-
parsedData.headers.length > 6 && /* @__PURE__ */
|
|
5520
|
+
parsedData.headers.length > 6 && /* @__PURE__ */ jsx("th", {
|
|
5085
5521
|
className: "px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5086
|
-
children:
|
|
5087
|
-
"+",
|
|
5088
|
-
parsedData.headers.length - 6,
|
|
5089
|
-
" 列"
|
|
5090
|
-
]
|
|
5522
|
+
children: locale.moreColumns(parsedData.headers.length - 6)
|
|
5091
5523
|
})
|
|
5092
5524
|
] })
|
|
5093
5525
|
}), /* @__PURE__ */ jsx("tbody", { children: parsedData.rows.slice(0, 10).map((row, i) => /* @__PURE__ */ jsxs("tr", {
|
|
@@ -5110,40 +5542,27 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5110
5542
|
})
|
|
5111
5543
|
})
|
|
5112
5544
|
}),
|
|
5113
|
-
/* @__PURE__ */
|
|
5545
|
+
/* @__PURE__ */ jsx("p", {
|
|
5114
5546
|
className: "text-sm text-muted-foreground",
|
|
5115
|
-
children:
|
|
5116
|
-
"共 ",
|
|
5117
|
-
parsedData.rows.length,
|
|
5118
|
-
" 条数据",
|
|
5119
|
-
parsedData.rows.length > 10 && "(预览前 10 条)",
|
|
5120
|
-
",",
|
|
5121
|
-
parsedData.headers.length,
|
|
5122
|
-
" 个字段 ,格式: ",
|
|
5123
|
-
parsedData.format.toUpperCase()
|
|
5124
|
-
]
|
|
5547
|
+
children: locale.previewSummary(parsedData.rows.length, parsedData.headers.length, parsedData.format, parsedData.rows.length > 10 ? 10 : void 0)
|
|
5125
5548
|
}),
|
|
5126
5549
|
/* @__PURE__ */ jsxs("div", {
|
|
5127
5550
|
className: "flex gap-2 justify-end",
|
|
5128
5551
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
5129
5552
|
variant: "outline",
|
|
5130
5553
|
onClick: reset,
|
|
5131
|
-
children:
|
|
5554
|
+
children: locale.reselect
|
|
5132
5555
|
}), /* @__PURE__ */ jsx(Button, {
|
|
5133
5556
|
onClick: handleImport,
|
|
5134
|
-
children:
|
|
5557
|
+
children: locale.confirmImport
|
|
5135
5558
|
})]
|
|
5136
5559
|
})
|
|
5137
5560
|
] }),
|
|
5138
5561
|
step === "importing" && /* @__PURE__ */ jsxs("div", {
|
|
5139
5562
|
className: "flex flex-col items-center gap-4 py-8",
|
|
5140
|
-
children: [/* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }), /* @__PURE__ */
|
|
5563
|
+
children: [/* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }), /* @__PURE__ */ jsx("p", {
|
|
5141
5564
|
className: "text-sm text-muted-foreground",
|
|
5142
|
-
children:
|
|
5143
|
-
"正在导入 ",
|
|
5144
|
-
parsedData?.rows.length ?? 0,
|
|
5145
|
-
" 条数据..."
|
|
5146
|
-
]
|
|
5565
|
+
children: locale.importingRows(parsedData?.rows.length ?? 0)
|
|
5147
5566
|
})]
|
|
5148
5567
|
}),
|
|
5149
5568
|
step === "result" && result && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -5158,7 +5577,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5158
5577
|
children: result.success
|
|
5159
5578
|
}), /* @__PURE__ */ jsx("p", {
|
|
5160
5579
|
className: "text-xs text-green-600/80",
|
|
5161
|
-
children:
|
|
5580
|
+
children: locale.resultCreated
|
|
5162
5581
|
})]
|
|
5163
5582
|
}),
|
|
5164
5583
|
(result.updated ?? 0) > 0 && /* @__PURE__ */ jsxs("div", {
|
|
@@ -5168,7 +5587,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5168
5587
|
children: result.updated
|
|
5169
5588
|
}), /* @__PURE__ */ jsx("p", {
|
|
5170
5589
|
className: "text-xs text-blue-600/80",
|
|
5171
|
-
children:
|
|
5590
|
+
children: locale.resultUpdated
|
|
5172
5591
|
})]
|
|
5173
5592
|
}),
|
|
5174
5593
|
result.skipped > 0 && /* @__PURE__ */ jsxs("div", {
|
|
@@ -5178,7 +5597,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5178
5597
|
children: result.skipped
|
|
5179
5598
|
}), /* @__PURE__ */ jsx("p", {
|
|
5180
5599
|
className: "text-xs text-yellow-600/80",
|
|
5181
|
-
children:
|
|
5600
|
+
children: locale.resultSkipped
|
|
5182
5601
|
})]
|
|
5183
5602
|
}),
|
|
5184
5603
|
result.failed.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
@@ -5188,7 +5607,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5188
5607
|
children: result.failed.length
|
|
5189
5608
|
}), /* @__PURE__ */ jsx("p", {
|
|
5190
5609
|
className: "text-xs text-red-600/80",
|
|
5191
|
-
children:
|
|
5610
|
+
children: locale.resultFailed
|
|
5192
5611
|
})]
|
|
5193
5612
|
})
|
|
5194
5613
|
]
|
|
@@ -5202,10 +5621,10 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5202
5621
|
className: "sticky top-0 bg-red-50 dark:bg-red-950/30",
|
|
5203
5622
|
children: /* @__PURE__ */ jsxs("tr", { children: [/* @__PURE__ */ jsx("th", {
|
|
5204
5623
|
className: "px-3 py-2 text-left font-medium text-red-600",
|
|
5205
|
-
children:
|
|
5624
|
+
children: locale.failedRowHeader
|
|
5206
5625
|
}), /* @__PURE__ */ jsx("th", {
|
|
5207
5626
|
className: "px-3 py-2 text-left font-medium text-red-600",
|
|
5208
|
-
children:
|
|
5627
|
+
children: locale.failedErrorHeader
|
|
5209
5628
|
})] })
|
|
5210
5629
|
}), /* @__PURE__ */ jsx("tbody", { children: result.failed.map((f) => /* @__PURE__ */ jsxs("tr", {
|
|
5211
5630
|
className: "border-t border-red-100 dark:border-red-900",
|
|
@@ -5225,11 +5644,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title = "导
|
|
|
5225
5644
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
5226
5645
|
variant: "outline",
|
|
5227
5646
|
onClick: () => handleOpenChange(false),
|
|
5228
|
-
children:
|
|
5647
|
+
children: locale.close
|
|
5229
5648
|
}), /* @__PURE__ */ jsx(Button, {
|
|
5230
5649
|
variant: "outline",
|
|
5231
5650
|
onClick: reset,
|
|
5232
|
-
children:
|
|
5651
|
+
children: locale.continueImport
|
|
5233
5652
|
})]
|
|
5234
5653
|
})] }),
|
|
5235
5654
|
error && /* @__PURE__ */ jsx("div", {
|
|
@@ -5379,13 +5798,13 @@ function buildBatchUpdateFields(schema, batchFields, fields) {
|
|
|
5379
5798
|
/**
|
|
5380
5799
|
* 渲染字段值
|
|
5381
5800
|
*/
|
|
5382
|
-
function renderFieldValue(value, type) {
|
|
5801
|
+
function renderFieldValue(value, type, booleanLocale) {
|
|
5383
5802
|
if (value === null || value === void 0) return /* @__PURE__ */ jsx("span", {
|
|
5384
5803
|
className: "text-muted-foreground",
|
|
5385
5804
|
children: "-"
|
|
5386
5805
|
});
|
|
5387
5806
|
switch (type) {
|
|
5388
|
-
case "boolean": return value ?
|
|
5807
|
+
case "boolean": return value ? booleanLocale.true : booleanLocale.false;
|
|
5389
5808
|
case "date": return formatDate(value);
|
|
5390
5809
|
case "enum": return /* @__PURE__ */ jsx(Badge, {
|
|
5391
5810
|
variant: "outline",
|
|
@@ -5408,7 +5827,7 @@ function renderFieldValue(value, type) {
|
|
|
5408
5827
|
/**
|
|
5409
5828
|
* ViewModal 组件 - 详情查看弹窗
|
|
5410
5829
|
*/
|
|
5411
|
-
function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldConfig, denyFields }) {
|
|
5830
|
+
function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldConfig, denyFields, locale }) {
|
|
5412
5831
|
if (!data) return null;
|
|
5413
5832
|
const shape = schema.shape;
|
|
5414
5833
|
const denySet = new Set(denyFields ?? []);
|
|
@@ -5428,7 +5847,7 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
|
|
|
5428
5847
|
children: label
|
|
5429
5848
|
}), /* @__PURE__ */ jsx("dd", {
|
|
5430
5849
|
className: "col-span-2 text-sm",
|
|
5431
|
-
children: renderFieldValue(value, parsed.type)
|
|
5850
|
+
children: renderFieldValue(value, parsed.type, locale.boolean)
|
|
5432
5851
|
})]
|
|
5433
5852
|
}, key);
|
|
5434
5853
|
})
|
|
@@ -5436,23 +5855,89 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
|
|
|
5436
5855
|
if (variant === "sheet") return /* @__PURE__ */ jsx(Sheet, {
|
|
5437
5856
|
open,
|
|
5438
5857
|
onOpenChange,
|
|
5439
|
-
children: /* @__PURE__ */ jsxs(SheetContent, { children: [/* @__PURE__ */ jsx(SheetHeader, { children: /* @__PURE__ */ jsx(SheetTitle, { children:
|
|
5858
|
+
children: /* @__PURE__ */ jsxs(SheetContent, { children: [/* @__PURE__ */ jsx(SheetHeader, { children: /* @__PURE__ */ jsx(SheetTitle, { children: locale.viewModal.title }) }), content] })
|
|
5440
5859
|
});
|
|
5441
5860
|
return /* @__PURE__ */ jsx(Dialog, {
|
|
5442
5861
|
open,
|
|
5443
5862
|
onOpenChange,
|
|
5444
5863
|
children: /* @__PURE__ */ jsxs(DialogContent, {
|
|
5445
5864
|
className: "max-w-2xl max-h-[80vh] overflow-y-auto",
|
|
5446
|
-
children: [/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children:
|
|
5865
|
+
children: [/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: locale.viewModal.title }) }), content]
|
|
5447
5866
|
})
|
|
5448
5867
|
});
|
|
5449
5868
|
}
|
|
5869
|
+
function resolveActions(items, defaults, rowActionsLocale) {
|
|
5870
|
+
const defaultItems = [
|
|
5871
|
+
{
|
|
5872
|
+
label: rowActionsLocale.view,
|
|
5873
|
+
onClick: defaults.openView
|
|
5874
|
+
},
|
|
5875
|
+
...defaults.openEdit ? [{
|
|
5876
|
+
label: rowActionsLocale.edit,
|
|
5877
|
+
onClick: defaults.openEdit
|
|
5878
|
+
}] : [],
|
|
5879
|
+
...defaults.copyRow ? [{
|
|
5880
|
+
label: rowActionsLocale.copy,
|
|
5881
|
+
onClick: defaults.copyRow
|
|
5882
|
+
}] : [],
|
|
5883
|
+
...defaults.openDelete ? [{
|
|
5884
|
+
label: rowActionsLocale.delete,
|
|
5885
|
+
onClick: defaults.openDelete,
|
|
5886
|
+
separator: true,
|
|
5887
|
+
variant: "destructive"
|
|
5888
|
+
}] : []
|
|
5889
|
+
];
|
|
5890
|
+
if (!items || items.length === 0) return defaultItems;
|
|
5891
|
+
if (!items.some((i) => i.type !== "custom")) {
|
|
5892
|
+
const startItems = items.filter((i) => i.type === "custom" && i.position === "start").map(({ label, onClick, separator, variant }) => ({
|
|
5893
|
+
label,
|
|
5894
|
+
onClick,
|
|
5895
|
+
separator,
|
|
5896
|
+
variant
|
|
5897
|
+
}));
|
|
5898
|
+
const endItems = items.filter((i) => i.type === "custom" && i.position !== "start").map(({ label, onClick, separator, variant }) => ({
|
|
5899
|
+
label,
|
|
5900
|
+
onClick,
|
|
5901
|
+
separator,
|
|
5902
|
+
variant
|
|
5903
|
+
}));
|
|
5904
|
+
return [
|
|
5905
|
+
...startItems,
|
|
5906
|
+
...defaultItems,
|
|
5907
|
+
...endItems
|
|
5908
|
+
];
|
|
5909
|
+
}
|
|
5910
|
+
const handlerMap = {
|
|
5911
|
+
view: defaults.openView,
|
|
5912
|
+
edit: defaults.openEdit,
|
|
5913
|
+
copy: defaults.copyRow,
|
|
5914
|
+
delete: defaults.openDelete
|
|
5915
|
+
};
|
|
5916
|
+
const variantMap = { delete: "destructive" };
|
|
5917
|
+
return items.flatMap((item) => {
|
|
5918
|
+
if (item.type === "custom") return [{
|
|
5919
|
+
label: item.label,
|
|
5920
|
+
onClick: item.onClick,
|
|
5921
|
+
separator: item.separator,
|
|
5922
|
+
variant: item.variant
|
|
5923
|
+
}];
|
|
5924
|
+
const handler = item.onClick ?? handlerMap[item.type];
|
|
5925
|
+
if (!handler) return [];
|
|
5926
|
+
return [{
|
|
5927
|
+
label: item.label ?? rowActionsLocale[item.type],
|
|
5928
|
+
onClick: handler,
|
|
5929
|
+
separator: item.separator,
|
|
5930
|
+
variant: variantMap[item.type]
|
|
5931
|
+
}];
|
|
5932
|
+
});
|
|
5933
|
+
}
|
|
5450
5934
|
/**
|
|
5451
5935
|
* AutoCrudTable 组件
|
|
5452
5936
|
*
|
|
5453
5937
|
* 高级 CRUD 表格组件,封装了完整的增删改查流程
|
|
5454
5938
|
*/
|
|
5455
|
-
function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions }) {
|
|
5939
|
+
function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, slots, permissions, actions: actionItems, locale: localeProp }) {
|
|
5940
|
+
const locale = resolveLocale(localeProp);
|
|
5456
5941
|
const can = {
|
|
5457
5942
|
create: permissions?.can?.create ?? true,
|
|
5458
5943
|
update: permissions?.can?.update ?? true,
|
|
@@ -5545,18 +6030,18 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5545
6030
|
variant: "outline",
|
|
5546
6031
|
size: "sm",
|
|
5547
6032
|
onClick: () => setImportOpen(true),
|
|
5548
|
-
children: [/* @__PURE__ */ jsx(Download, { className: "mr-2 h-4 w-4" }),
|
|
6033
|
+
children: [/* @__PURE__ */ jsx(Download, { className: "mr-2 h-4 w-4" }), locale.toolbar.import]
|
|
5549
6034
|
}),
|
|
5550
6035
|
canExport && /* @__PURE__ */ jsxs(Button, {
|
|
5551
6036
|
variant: "outline",
|
|
5552
6037
|
size: "sm",
|
|
5553
6038
|
onClick: handleExportClick,
|
|
5554
6039
|
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
5555
|
-
children: [exporting ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Upload, { className: "mr-2 h-4 w-4" }), selectedCount > 0 ?
|
|
6040
|
+
children: [exporting ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Upload, { className: "mr-2 h-4 w-4" }), selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export]
|
|
5556
6041
|
}),
|
|
5557
6042
|
can.create && /* @__PURE__ */ jsx(Button, {
|
|
5558
6043
|
onClick: resource.handlers.openCreate,
|
|
5559
|
-
children:
|
|
6044
|
+
children: locale.toolbar.create
|
|
5560
6045
|
})
|
|
5561
6046
|
]
|
|
5562
6047
|
})]
|
|
@@ -5568,12 +6053,12 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5568
6053
|
overrides: tableOverrides,
|
|
5569
6054
|
exclude: hiddenColumns,
|
|
5570
6055
|
filterMode: tableConfig?.filterModes,
|
|
5571
|
-
actions: {
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
},
|
|
6056
|
+
actions: resolveActions(actionItems, {
|
|
6057
|
+
openView: resource.handlers.openView,
|
|
6058
|
+
openEdit: can.update ? resource.handlers.openEdit : void 0,
|
|
6059
|
+
copyRow: can.create ? resource.handlers.copyRow : void 0,
|
|
6060
|
+
openDelete: can.delete ? resource.handlers.openDelete : void 0
|
|
6061
|
+
}, locale.rowActions),
|
|
5577
6062
|
onDeleteSelected: can.delete ? resource.handlers.deleteMany : void 0,
|
|
5578
6063
|
onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
|
|
5579
6064
|
batchUpdateFields: can.update ? batchFields : void 0,
|
|
@@ -5594,7 +6079,8 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5594
6079
|
},
|
|
5595
6080
|
loading: resource.mutations.isCreating || resource.mutations.isUpdating,
|
|
5596
6081
|
variant: resource.modal.variant,
|
|
5597
|
-
overrides: formOverrides
|
|
6082
|
+
overrides: formOverrides,
|
|
6083
|
+
locale: locale.formModal
|
|
5598
6084
|
}),
|
|
5599
6085
|
/* @__PURE__ */ jsx(ViewModal, {
|
|
5600
6086
|
open: resource.modal.viewOpen,
|
|
@@ -5603,22 +6089,24 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
|
|
|
5603
6089
|
data: resource.modal.selected,
|
|
5604
6090
|
schema,
|
|
5605
6091
|
fields,
|
|
5606
|
-
denyFields
|
|
6092
|
+
denyFields,
|
|
6093
|
+
locale
|
|
5607
6094
|
}),
|
|
5608
6095
|
/* @__PURE__ */ jsx(AlertDialog, {
|
|
5609
6096
|
open: resource.modal.deleteOpen,
|
|
5610
6097
|
onOpenChange: (open) => !open && resource.handlers.closeModals(),
|
|
5611
|
-
children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [/* @__PURE__ */ jsx(AlertDialogTitle, { children:
|
|
6098
|
+
children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [/* @__PURE__ */ jsx(AlertDialogTitle, { children: locale.deleteModal.title }), /* @__PURE__ */ jsx(AlertDialogDescription, { children: locale.deleteModal.description })] }), /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [/* @__PURE__ */ jsx(AlertDialogCancel, { children: locale.deleteModal.cancel }), /* @__PURE__ */ jsx(AlertDialogAction, {
|
|
5612
6099
|
onClick: resource.handlers.confirmDelete,
|
|
5613
6100
|
disabled: resource.mutations.isDeleting,
|
|
5614
|
-
children: resource.mutations.isDeleting ?
|
|
6101
|
+
children: resource.mutations.isDeleting ? locale.deleteModal.confirming : locale.deleteModal.confirm
|
|
5615
6102
|
})] })] })
|
|
5616
6103
|
}),
|
|
5617
6104
|
canImport && resource.handlers.import && /* @__PURE__ */ jsx(ImportDialog, {
|
|
5618
6105
|
open: importOpen,
|
|
5619
6106
|
onOpenChange: setImportOpen,
|
|
5620
6107
|
onImport: resource.handlers.import,
|
|
5621
|
-
columns: importColumns
|
|
6108
|
+
columns: importColumns,
|
|
6109
|
+
locale: locale.importDialog
|
|
5622
6110
|
})
|
|
5623
6111
|
]
|
|
5624
6112
|
});
|
|
@@ -6988,4 +7476,4 @@ function createMemoryDataSource(initialData = []) {
|
|
|
6988
7476
|
}
|
|
6989
7477
|
|
|
6990
7478
|
//#endregion
|
|
6991
|
-
export { AutoCrudTable, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, CrudFormModal, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions, ExportDialog, ImportDialog, SchemaAdapter, cn, coerceRowValues, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataToCSV, downloadCSVTemplate, exportAllToCSV, exportTableToCSV, formatDate, generateCSVTemplate, getUrlParams, humanize, noopToastAdapter, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates };
|
|
7479
|
+
export { AutoCrudTable, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, CrudFormModal, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions, ExportDialog, ImportDialog, SchemaAdapter, cn, coerceRowValues, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
|