@abpjs/language-management 0.7.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/dist/index.mjs ADDED
@@ -0,0 +1,1175 @@
1
+ // src/constants/routes.ts
2
+ var LANGUAGE_MANAGEMENT_ROUTES = {
3
+ routes: [
4
+ {
5
+ name: "Languages",
6
+ path: "language-management",
7
+ layout: "application",
8
+ order: 101,
9
+ children: [
10
+ {
11
+ name: "Languages",
12
+ path: "languages",
13
+ order: 1
14
+ },
15
+ {
16
+ name: "Language Texts",
17
+ path: "texts",
18
+ order: 2
19
+ }
20
+ ]
21
+ }
22
+ ]
23
+ };
24
+
25
+ // src/services/language-management.service.ts
26
+ var LanguageManagementService = class {
27
+ constructor(rest) {
28
+ this.rest = rest;
29
+ }
30
+ // ========================
31
+ // Language Operations
32
+ // ========================
33
+ /**
34
+ * Get all languages with optional pagination
35
+ * @param params - Optional query parameters for pagination and filtering
36
+ * @returns Promise with paginated language response
37
+ */
38
+ getLanguages(params = {}) {
39
+ return this.rest.request({
40
+ method: "GET",
41
+ url: "/api/language-management/languages",
42
+ params
43
+ });
44
+ }
45
+ /**
46
+ * Get a language by ID
47
+ * @param id - The language ID
48
+ * @returns Promise with the language
49
+ */
50
+ getLanguageById(id) {
51
+ return this.rest.request({
52
+ method: "GET",
53
+ url: `/api/language-management/languages/${id}`
54
+ });
55
+ }
56
+ /**
57
+ * Create a new language
58
+ * @param body - The language data to create
59
+ * @returns Promise with the created language
60
+ */
61
+ createLanguage(body) {
62
+ return this.rest.request({
63
+ method: "POST",
64
+ url: "/api/language-management/languages",
65
+ body
66
+ });
67
+ }
68
+ /**
69
+ * Update an existing language
70
+ * @param id - The language ID to update
71
+ * @param body - The updated language data
72
+ * @returns Promise with the updated language
73
+ */
74
+ updateLanguage(id, body) {
75
+ return this.rest.request({
76
+ method: "PUT",
77
+ url: `/api/language-management/languages/${id}`,
78
+ body
79
+ });
80
+ }
81
+ /**
82
+ * Delete a language
83
+ * @param id - The language ID to delete
84
+ * @returns Promise resolving when complete
85
+ */
86
+ deleteLanguage(id) {
87
+ return this.rest.request({
88
+ method: "DELETE",
89
+ url: `/api/language-management/languages/${id}`
90
+ });
91
+ }
92
+ /**
93
+ * Set a language as the default language
94
+ * @param id - The language ID to set as default
95
+ * @returns Promise resolving when complete
96
+ */
97
+ setAsDefaultLanguage(id) {
98
+ return this.rest.request({
99
+ method: "PUT",
100
+ url: `/api/language-management/languages/${id}/set-as-default`
101
+ });
102
+ }
103
+ // ========================
104
+ // Culture Operations
105
+ // ========================
106
+ /**
107
+ * Get all available cultures
108
+ * @returns Promise with list of cultures
109
+ */
110
+ getCultures() {
111
+ return this.rest.request({
112
+ method: "GET",
113
+ url: "/api/language-management/languages/culture-list"
114
+ });
115
+ }
116
+ // ========================
117
+ // Resource Operations
118
+ // ========================
119
+ /**
120
+ * Get all available localization resources
121
+ * @returns Promise with list of resources
122
+ */
123
+ getResources() {
124
+ return this.rest.request({
125
+ method: "GET",
126
+ url: "/api/language-management/languages/resources"
127
+ });
128
+ }
129
+ // ========================
130
+ // Language Text Operations
131
+ // ========================
132
+ /**
133
+ * Get language texts with pagination and filtering
134
+ * @param params - Query parameters including resource name, cultures, and filter options
135
+ * @returns Promise with paginated language text response
136
+ */
137
+ getLanguageTexts(params) {
138
+ return this.rest.request({
139
+ method: "GET",
140
+ url: "/api/language-management/language-texts",
141
+ params
142
+ });
143
+ }
144
+ /**
145
+ * Get a language text by name
146
+ * @param params - Parameters identifying the language text
147
+ * @returns Promise with the language text
148
+ */
149
+ getLanguageTextByName(params) {
150
+ return this.rest.request({
151
+ method: "GET",
152
+ url: "/api/language-management/language-texts",
153
+ params
154
+ });
155
+ }
156
+ /**
157
+ * Update a language text by name
158
+ * @param params - Parameters including the new value
159
+ * @returns Promise with the updated language text
160
+ */
161
+ updateLanguageTextByName(params) {
162
+ const { resourceName, cultureName, name, value } = params;
163
+ return this.rest.request({
164
+ method: "PUT",
165
+ url: `/api/language-management/language-texts/${resourceName}/${cultureName}/${name}`,
166
+ body: { value }
167
+ });
168
+ }
169
+ /**
170
+ * Restore a language text to its default value
171
+ * @param params - Parameters identifying the language text
172
+ * @returns Promise resolving when complete
173
+ */
174
+ restoreLanguageTextByName(params) {
175
+ const { resourceName, cultureName, name } = params;
176
+ return this.rest.request({
177
+ method: "PUT",
178
+ url: `/api/language-management/language-texts/${resourceName}/${cultureName}/${name}/restore`
179
+ });
180
+ }
181
+ };
182
+
183
+ // src/hooks/useLanguages.ts
184
+ import { useState, useCallback, useMemo } from "react";
185
+ import { useRestService } from "@abpjs/core";
186
+ function useLanguages() {
187
+ const restService = useRestService();
188
+ const service = useMemo(() => new LanguageManagementService(restService), [restService]);
189
+ const [languages, setLanguages] = useState([]);
190
+ const [totalCount, setTotalCount] = useState(0);
191
+ const [cultures, setCultures] = useState([]);
192
+ const [selectedLanguage, setSelectedLanguage] = useState(
193
+ null
194
+ );
195
+ const [isLoading, setIsLoading] = useState(false);
196
+ const [error, setError] = useState(null);
197
+ const [sortKey, setSortKey] = useState("displayName");
198
+ const [sortOrder, setSortOrder] = useState("");
199
+ const fetchLanguages = useCallback(
200
+ async (params) => {
201
+ setIsLoading(true);
202
+ setError(null);
203
+ try {
204
+ const response = await service.getLanguages(params);
205
+ setLanguages(response.items || []);
206
+ setTotalCount(response.totalCount || 0);
207
+ setIsLoading(false);
208
+ return { success: true };
209
+ } catch (err) {
210
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch languages";
211
+ setError(errorMessage);
212
+ setIsLoading(false);
213
+ return { success: false, error: errorMessage };
214
+ }
215
+ },
216
+ [service]
217
+ );
218
+ const fetchCultures = useCallback(async () => {
219
+ setIsLoading(true);
220
+ setError(null);
221
+ try {
222
+ const response = await service.getCultures();
223
+ setCultures(response || []);
224
+ setIsLoading(false);
225
+ return { success: true };
226
+ } catch (err) {
227
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch cultures";
228
+ setError(errorMessage);
229
+ setIsLoading(false);
230
+ return { success: false, error: errorMessage };
231
+ }
232
+ }, [service]);
233
+ const getLanguageById = useCallback(
234
+ async (id) => {
235
+ setIsLoading(true);
236
+ setError(null);
237
+ try {
238
+ const language = await service.getLanguageById(id);
239
+ setSelectedLanguage(language);
240
+ setIsLoading(false);
241
+ return { success: true };
242
+ } catch (err) {
243
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch language";
244
+ setError(errorMessage);
245
+ setIsLoading(false);
246
+ return { success: false, error: errorMessage };
247
+ }
248
+ },
249
+ [service]
250
+ );
251
+ const createLanguage = useCallback(
252
+ async (language) => {
253
+ setIsLoading(true);
254
+ setError(null);
255
+ try {
256
+ await service.createLanguage(language);
257
+ await fetchLanguages();
258
+ return { success: true };
259
+ } catch (err) {
260
+ const errorMessage = err instanceof Error ? err.message : "Failed to create language";
261
+ setError(errorMessage);
262
+ setIsLoading(false);
263
+ return { success: false, error: errorMessage };
264
+ }
265
+ },
266
+ [service, fetchLanguages]
267
+ );
268
+ const updateLanguage = useCallback(
269
+ async (id, language) => {
270
+ setIsLoading(true);
271
+ setError(null);
272
+ try {
273
+ await service.updateLanguage(id, language);
274
+ await fetchLanguages();
275
+ return { success: true };
276
+ } catch (err) {
277
+ const errorMessage = err instanceof Error ? err.message : "Failed to update language";
278
+ setError(errorMessage);
279
+ setIsLoading(false);
280
+ return { success: false, error: errorMessage };
281
+ }
282
+ },
283
+ [service, fetchLanguages]
284
+ );
285
+ const deleteLanguage = useCallback(
286
+ async (id) => {
287
+ setIsLoading(true);
288
+ setError(null);
289
+ try {
290
+ await service.deleteLanguage(id);
291
+ await fetchLanguages();
292
+ return { success: true };
293
+ } catch (err) {
294
+ const errorMessage = err instanceof Error ? err.message : "Failed to delete language";
295
+ setError(errorMessage);
296
+ setIsLoading(false);
297
+ return { success: false, error: errorMessage };
298
+ }
299
+ },
300
+ [service, fetchLanguages]
301
+ );
302
+ const setAsDefaultLanguage = useCallback(
303
+ async (id) => {
304
+ setIsLoading(true);
305
+ setError(null);
306
+ try {
307
+ await service.setAsDefaultLanguage(id);
308
+ await fetchLanguages();
309
+ return { success: true };
310
+ } catch (err) {
311
+ const errorMessage = err instanceof Error ? err.message : "Failed to set language as default";
312
+ setError(errorMessage);
313
+ setIsLoading(false);
314
+ return { success: false, error: errorMessage };
315
+ }
316
+ },
317
+ [service, fetchLanguages]
318
+ );
319
+ const reset = useCallback(() => {
320
+ setLanguages([]);
321
+ setTotalCount(0);
322
+ setCultures([]);
323
+ setSelectedLanguage(null);
324
+ setIsLoading(false);
325
+ setError(null);
326
+ }, []);
327
+ return {
328
+ languages,
329
+ totalCount,
330
+ cultures,
331
+ selectedLanguage,
332
+ isLoading,
333
+ error,
334
+ sortKey,
335
+ sortOrder,
336
+ fetchLanguages,
337
+ fetchCultures,
338
+ getLanguageById,
339
+ createLanguage,
340
+ updateLanguage,
341
+ deleteLanguage,
342
+ setAsDefaultLanguage,
343
+ setSelectedLanguage,
344
+ setSortKey,
345
+ setSortOrder,
346
+ reset
347
+ };
348
+ }
349
+
350
+ // src/hooks/useLanguageTexts.ts
351
+ import { useState as useState2, useCallback as useCallback2, useMemo as useMemo2 } from "react";
352
+ import { useRestService as useRestService2 } from "@abpjs/core";
353
+ function useLanguageTexts() {
354
+ const restService = useRestService2();
355
+ const service = useMemo2(() => new LanguageManagementService(restService), [restService]);
356
+ const [languageTexts, setLanguageTexts] = useState2([]);
357
+ const [totalCount, setTotalCount] = useState2(0);
358
+ const [resources, setResources] = useState2([]);
359
+ const [selectedLanguageText, setSelectedLanguageText] = useState2(null);
360
+ const [isLoading, setIsLoading] = useState2(false);
361
+ const [error, setError] = useState2(null);
362
+ const [sortKey, setSortKey] = useState2("name");
363
+ const [sortOrder, setSortOrder] = useState2("");
364
+ const [lastQueryParams, setLastQueryParams] = useState2(null);
365
+ const fetchLanguageTexts = useCallback2(
366
+ async (params) => {
367
+ setIsLoading(true);
368
+ setError(null);
369
+ setLastQueryParams(params);
370
+ try {
371
+ const response = await service.getLanguageTexts(params);
372
+ setLanguageTexts(response.items || []);
373
+ setTotalCount(response.totalCount || 0);
374
+ setIsLoading(false);
375
+ return { success: true };
376
+ } catch (err) {
377
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch language texts";
378
+ setError(errorMessage);
379
+ setIsLoading(false);
380
+ return { success: false, error: errorMessage };
381
+ }
382
+ },
383
+ [service]
384
+ );
385
+ const fetchResources = useCallback2(async () => {
386
+ setIsLoading(true);
387
+ setError(null);
388
+ try {
389
+ const response = await service.getResources();
390
+ setResources(response || []);
391
+ setIsLoading(false);
392
+ return { success: true };
393
+ } catch (err) {
394
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch resources";
395
+ setError(errorMessage);
396
+ setIsLoading(false);
397
+ return { success: false, error: errorMessage };
398
+ }
399
+ }, [service]);
400
+ const getLanguageTextByName = useCallback2(
401
+ async (params) => {
402
+ setIsLoading(true);
403
+ setError(null);
404
+ try {
405
+ const languageText = await service.getLanguageTextByName(params);
406
+ setSelectedLanguageText(languageText);
407
+ setIsLoading(false);
408
+ return { success: true };
409
+ } catch (err) {
410
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch language text";
411
+ setError(errorMessage);
412
+ setIsLoading(false);
413
+ return { success: false, error: errorMessage };
414
+ }
415
+ },
416
+ [service]
417
+ );
418
+ const updateLanguageTextByName = useCallback2(
419
+ async (params) => {
420
+ setIsLoading(true);
421
+ setError(null);
422
+ try {
423
+ await service.updateLanguageTextByName(params);
424
+ if (lastQueryParams) {
425
+ await fetchLanguageTexts(lastQueryParams);
426
+ } else {
427
+ setIsLoading(false);
428
+ }
429
+ return { success: true };
430
+ } catch (err) {
431
+ const errorMessage = err instanceof Error ? err.message : "Failed to update language text";
432
+ setError(errorMessage);
433
+ setIsLoading(false);
434
+ return { success: false, error: errorMessage };
435
+ }
436
+ },
437
+ [service, lastQueryParams, fetchLanguageTexts]
438
+ );
439
+ const restoreLanguageTextByName = useCallback2(
440
+ async (params) => {
441
+ setIsLoading(true);
442
+ setError(null);
443
+ try {
444
+ await service.restoreLanguageTextByName(params);
445
+ if (lastQueryParams) {
446
+ await fetchLanguageTexts(lastQueryParams);
447
+ } else {
448
+ setIsLoading(false);
449
+ }
450
+ return { success: true };
451
+ } catch (err) {
452
+ const errorMessage = err instanceof Error ? err.message : "Failed to restore language text";
453
+ setError(errorMessage);
454
+ setIsLoading(false);
455
+ return { success: false, error: errorMessage };
456
+ }
457
+ },
458
+ [service, lastQueryParams, fetchLanguageTexts]
459
+ );
460
+ const reset = useCallback2(() => {
461
+ setLanguageTexts([]);
462
+ setTotalCount(0);
463
+ setResources([]);
464
+ setSelectedLanguageText(null);
465
+ setIsLoading(false);
466
+ setError(null);
467
+ setLastQueryParams(null);
468
+ }, []);
469
+ return {
470
+ languageTexts,
471
+ totalCount,
472
+ resources,
473
+ selectedLanguageText,
474
+ isLoading,
475
+ error,
476
+ sortKey,
477
+ sortOrder,
478
+ fetchLanguageTexts,
479
+ fetchResources,
480
+ getLanguageTextByName,
481
+ updateLanguageTextByName,
482
+ restoreLanguageTextByName,
483
+ setSelectedLanguageText,
484
+ setSortKey,
485
+ setSortOrder,
486
+ reset
487
+ };
488
+ }
489
+
490
+ // src/components/Languages/LanguagesComponent.tsx
491
+ import { useEffect, useState as useState3, useCallback as useCallback3 } from "react";
492
+ import { useLocalization } from "@abpjs/core";
493
+ import { Modal, useConfirmation, Toaster, Alert, Button, FormField } from "@abpjs/theme-shared";
494
+ import {
495
+ Box,
496
+ Flex,
497
+ Input,
498
+ Table,
499
+ Spinner,
500
+ VStack,
501
+ Menu,
502
+ Text,
503
+ Badge
504
+ } from "@chakra-ui/react";
505
+ import { NativeSelectRoot, NativeSelectField } from "@chakra-ui/react";
506
+ import { Checkbox } from "@chakra-ui/react";
507
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
508
+ var DEFAULT_FORM_STATE = {
509
+ cultureName: "",
510
+ uiCultureName: "",
511
+ displayName: "",
512
+ flagIcon: "",
513
+ isEnabled: true
514
+ };
515
+ function LanguagesComponent({
516
+ onLanguageCreated,
517
+ onLanguageUpdated,
518
+ onLanguageDeleted
519
+ }) {
520
+ const { t } = useLocalization();
521
+ const confirmation = useConfirmation();
522
+ const {
523
+ languages,
524
+ cultures,
525
+ selectedLanguage,
526
+ isLoading,
527
+ error,
528
+ fetchLanguages,
529
+ fetchCultures,
530
+ getLanguageById,
531
+ createLanguage,
532
+ updateLanguage,
533
+ deleteLanguage,
534
+ setAsDefaultLanguage,
535
+ setSelectedLanguage
536
+ } = useLanguages();
537
+ const [isModalOpen, setIsModalOpen] = useState3(false);
538
+ const [formState, setFormState] = useState3(DEFAULT_FORM_STATE);
539
+ const [isSubmitting, setIsSubmitting] = useState3(false);
540
+ const [isEditing, setIsEditing] = useState3(false);
541
+ const [searchTerm, setSearchTerm] = useState3("");
542
+ useEffect(() => {
543
+ fetchLanguages();
544
+ fetchCultures();
545
+ }, [fetchLanguages, fetchCultures]);
546
+ const filteredLanguages = languages.filter(
547
+ (lang) => !searchTerm || lang.displayName.toLowerCase().includes(searchTerm.toLowerCase()) || lang.cultureName.toLowerCase().includes(searchTerm.toLowerCase())
548
+ );
549
+ const handleAdd = useCallback3(() => {
550
+ setSelectedLanguage(null);
551
+ setFormState(DEFAULT_FORM_STATE);
552
+ setIsEditing(false);
553
+ setIsModalOpen(true);
554
+ }, [setSelectedLanguage]);
555
+ const handleEdit = useCallback3(
556
+ async (id) => {
557
+ const result = await getLanguageById(id);
558
+ if (result.success) {
559
+ setIsEditing(true);
560
+ setIsModalOpen(true);
561
+ }
562
+ },
563
+ [getLanguageById]
564
+ );
565
+ useEffect(() => {
566
+ if (selectedLanguage && isEditing) {
567
+ setFormState({
568
+ cultureName: selectedLanguage.cultureName || "",
569
+ uiCultureName: selectedLanguage.uiCultureName || "",
570
+ displayName: selectedLanguage.displayName || "",
571
+ flagIcon: selectedLanguage.flagIcon || "",
572
+ isEnabled: selectedLanguage.isEnabled ?? true
573
+ });
574
+ }
575
+ }, [selectedLanguage, isEditing]);
576
+ const handleDelete = useCallback3(
577
+ async (id, displayName) => {
578
+ const status = await confirmation.warn(
579
+ t("AbpLanguageManagement::LanguageDeletionConfirmationMessage", displayName) || `Are you sure you want to delete the language '${displayName}'?`,
580
+ t("AbpLanguageManagement::AreYouSure") || "Are you sure?"
581
+ );
582
+ if (status === Toaster.Status.confirm) {
583
+ const result = await deleteLanguage(id);
584
+ if (result.success) {
585
+ onLanguageDeleted?.(id);
586
+ }
587
+ }
588
+ },
589
+ [confirmation, t, deleteLanguage, onLanguageDeleted]
590
+ );
591
+ const handleSetAsDefault = useCallback3(
592
+ async (id) => {
593
+ const status = await confirmation.info(
594
+ t("AbpLanguageManagement::SetAsDefaultLanguageConfirmationMessage") || "Are you sure you want to set this language as the default?",
595
+ t("AbpLanguageManagement::AreYouSure") || "Are you sure?"
596
+ );
597
+ if (status === Toaster.Status.confirm) {
598
+ await setAsDefaultLanguage(id);
599
+ }
600
+ },
601
+ [confirmation, t, setAsDefaultLanguage]
602
+ );
603
+ const handleSubmit = useCallback3(async () => {
604
+ if (!isEditing && !formState.cultureName) return;
605
+ if (!formState.displayName.trim()) return;
606
+ setIsSubmitting(true);
607
+ let result;
608
+ if (isEditing && selectedLanguage?.id) {
609
+ const updateData = {
610
+ displayName: formState.displayName.trim(),
611
+ flagIcon: formState.flagIcon,
612
+ isEnabled: formState.isEnabled
613
+ };
614
+ result = await updateLanguage(selectedLanguage.id, updateData);
615
+ if (result.success) {
616
+ onLanguageUpdated?.({
617
+ ...selectedLanguage,
618
+ ...updateData
619
+ });
620
+ }
621
+ } else {
622
+ const createData = {
623
+ cultureName: formState.cultureName,
624
+ uiCultureName: formState.uiCultureName || formState.cultureName,
625
+ displayName: formState.displayName.trim(),
626
+ flagIcon: formState.flagIcon,
627
+ isEnabled: formState.isEnabled
628
+ };
629
+ result = await createLanguage(createData);
630
+ if (result.success) {
631
+ onLanguageCreated?.({
632
+ id: "",
633
+ creationTime: (/* @__PURE__ */ new Date()).toISOString(),
634
+ creatorId: "",
635
+ isDefaultLanguage: false,
636
+ ...createData
637
+ });
638
+ }
639
+ }
640
+ setIsSubmitting(false);
641
+ if (result.success) {
642
+ setIsModalOpen(false);
643
+ setFormState(DEFAULT_FORM_STATE);
644
+ setSelectedLanguage(null);
645
+ setIsEditing(false);
646
+ }
647
+ }, [
648
+ formState,
649
+ isEditing,
650
+ selectedLanguage,
651
+ updateLanguage,
652
+ createLanguage,
653
+ onLanguageCreated,
654
+ onLanguageUpdated,
655
+ setSelectedLanguage
656
+ ]);
657
+ const handleModalClose = useCallback3(() => {
658
+ setIsModalOpen(false);
659
+ setFormState(DEFAULT_FORM_STATE);
660
+ setSelectedLanguage(null);
661
+ setIsEditing(false);
662
+ }, [setSelectedLanguage]);
663
+ const handleInputChange = useCallback3(
664
+ (field, value) => {
665
+ setFormState((prev) => ({ ...prev, [field]: value }));
666
+ },
667
+ []
668
+ );
669
+ const handleCultureChange = useCallback3(
670
+ (cultureName) => {
671
+ setFormState((prev) => ({
672
+ ...prev,
673
+ cultureName,
674
+ uiCultureName: cultureName
675
+ }));
676
+ const culture = cultures.find((c) => c.name === cultureName);
677
+ if (culture) {
678
+ setFormState((prev) => ({
679
+ ...prev,
680
+ displayName: culture.displayName
681
+ }));
682
+ }
683
+ },
684
+ [cultures]
685
+ );
686
+ return /* @__PURE__ */ jsxs(Box, { id: "language-management-languages-wrapper", className: "card", p: 4, children: [
687
+ /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", mb: 4, children: [
688
+ /* @__PURE__ */ jsx(Text, { fontSize: "xl", fontWeight: "bold", children: t("AbpLanguageManagement::Languages") || "Languages" }),
689
+ /* @__PURE__ */ jsx(Button, { colorPalette: "blue", onClick: handleAdd, children: t("AbpLanguageManagement::NewLanguage") || "New Language" })
690
+ ] }),
691
+ /* @__PURE__ */ jsx(Box, { mb: 4, children: /* @__PURE__ */ jsx(
692
+ Input,
693
+ {
694
+ placeholder: t("AbpLanguageManagement::Search") || "Search...",
695
+ value: searchTerm,
696
+ onChange: (e) => setSearchTerm(e.target.value),
697
+ maxW: "300px"
698
+ }
699
+ ) }),
700
+ error && /* @__PURE__ */ jsx(Alert, { status: "error", mb: 4, children: error }),
701
+ isLoading && languages.length === 0 && /* @__PURE__ */ jsx(Flex, { justify: "center", py: 8, children: /* @__PURE__ */ jsx(Spinner, { size: "lg" }) }),
702
+ languages.length > 0 && /* @__PURE__ */ jsxs(Table.Root, { variant: "outline", children: [
703
+ /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
704
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpLanguageManagement::Actions") || "Actions" }),
705
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpLanguageManagement::DisplayName") || "Display Name" }),
706
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpLanguageManagement::CultureName") || "Culture Name" }),
707
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpLanguageManagement::UiCultureName") || "UI Culture Name" }),
708
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpLanguageManagement::IsEnabled") || "Enabled" }),
709
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpLanguageManagement::IsDefaultLanguage") || "Default" })
710
+ ] }) }),
711
+ /* @__PURE__ */ jsx(Table.Body, { children: filteredLanguages.map((language) => /* @__PURE__ */ jsxs(Table.Row, { children: [
712
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Menu.Root, { children: [
713
+ /* @__PURE__ */ jsx(Menu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "sm", colorPalette: "blue", children: t("AbpLanguageManagement::Actions") || "Actions" }) }),
714
+ /* @__PURE__ */ jsx(Menu.Positioner, { children: /* @__PURE__ */ jsxs(Menu.Content, { children: [
715
+ /* @__PURE__ */ jsx(Menu.Item, { value: "edit", onClick: () => handleEdit(language.id), children: t("AbpLanguageManagement::Edit") || "Edit" }),
716
+ !language.isDefaultLanguage && /* @__PURE__ */ jsxs(Fragment, { children: [
717
+ /* @__PURE__ */ jsx(
718
+ Menu.Item,
719
+ {
720
+ value: "setDefault",
721
+ onClick: () => handleSetAsDefault(language.id),
722
+ children: t("AbpLanguageManagement::SetAsDefaultLanguage") || "Set as Default"
723
+ }
724
+ ),
725
+ /* @__PURE__ */ jsx(
726
+ Menu.Item,
727
+ {
728
+ value: "delete",
729
+ color: "red.500",
730
+ onClick: () => handleDelete(language.id, language.displayName),
731
+ children: t("AbpLanguageManagement::Delete") || "Delete"
732
+ }
733
+ )
734
+ ] })
735
+ ] }) })
736
+ ] }) }),
737
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
738
+ language.flagIcon && /* @__PURE__ */ jsx(Text, { children: language.flagIcon }),
739
+ language.displayName
740
+ ] }) }),
741
+ /* @__PURE__ */ jsx(Table.Cell, { children: language.cultureName }),
742
+ /* @__PURE__ */ jsx(Table.Cell, { children: language.uiCultureName }),
743
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Badge, { colorPalette: language.isEnabled ? "green" : "red", children: language.isEnabled ? t("AbpLanguageManagement::Yes") || "Yes" : t("AbpLanguageManagement::No") || "No" }) }),
744
+ /* @__PURE__ */ jsx(Table.Cell, { children: language.isDefaultLanguage && /* @__PURE__ */ jsx(Badge, { colorPalette: "blue", children: t("AbpLanguageManagement::Default") || "Default" }) })
745
+ ] }, language.id)) })
746
+ ] }),
747
+ !isLoading && languages.length === 0 && /* @__PURE__ */ jsx(Text, { textAlign: "center", color: "gray.500", py: 8, children: t("AbpLanguageManagement::NoLanguagesFound") || "No languages found" }),
748
+ /* @__PURE__ */ jsx(
749
+ Modal,
750
+ {
751
+ visible: isModalOpen,
752
+ onVisibleChange: setIsModalOpen,
753
+ header: isEditing ? t("AbpLanguageManagement::Edit") || "Edit" : t("AbpLanguageManagement::NewLanguage") || "New Language",
754
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
755
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleModalClose, disabled: isSubmitting, children: t("AbpLanguageManagement::Cancel") || "Cancel" }),
756
+ /* @__PURE__ */ jsx(
757
+ Button,
758
+ {
759
+ colorPalette: "blue",
760
+ onClick: handleSubmit,
761
+ loading: isSubmitting,
762
+ disabled: !formState.displayName.trim() || !isEditing && !formState.cultureName,
763
+ children: t("AbpLanguageManagement::Save") || "Save"
764
+ }
765
+ )
766
+ ] }),
767
+ children: /* @__PURE__ */ jsxs(VStack, { gap: 4, align: "stretch", children: [
768
+ !isEditing && /* @__PURE__ */ jsx(FormField, { label: t("AbpLanguageManagement::CultureName") || "Culture", required: true, children: /* @__PURE__ */ jsx(NativeSelectRoot, { children: /* @__PURE__ */ jsxs(
769
+ NativeSelectField,
770
+ {
771
+ value: formState.cultureName,
772
+ onChange: (e) => handleCultureChange(e.target.value),
773
+ children: [
774
+ /* @__PURE__ */ jsx("option", { value: "", children: t("AbpLanguageManagement::SelectCulture") || "Select a culture..." }),
775
+ cultures.map((culture) => /* @__PURE__ */ jsxs("option", { value: culture.name, children: [
776
+ culture.displayName,
777
+ " (",
778
+ culture.name,
779
+ ")"
780
+ ] }, culture.name))
781
+ ]
782
+ }
783
+ ) }) }),
784
+ !isEditing && /* @__PURE__ */ jsx(FormField, { label: t("AbpLanguageManagement::UiCultureName") || "UI Culture", children: /* @__PURE__ */ jsx(NativeSelectRoot, { children: /* @__PURE__ */ jsxs(
785
+ NativeSelectField,
786
+ {
787
+ value: formState.uiCultureName,
788
+ onChange: (e) => handleInputChange("uiCultureName", e.target.value),
789
+ children: [
790
+ /* @__PURE__ */ jsx("option", { value: "", children: t("AbpLanguageManagement::SameAsCulture") || "Same as culture" }),
791
+ cultures.map((culture) => /* @__PURE__ */ jsxs("option", { value: culture.name, children: [
792
+ culture.displayName,
793
+ " (",
794
+ culture.name,
795
+ ")"
796
+ ] }, culture.name))
797
+ ]
798
+ }
799
+ ) }) }),
800
+ /* @__PURE__ */ jsx(FormField, { label: t("AbpLanguageManagement::DisplayName") || "Display Name", required: true, children: /* @__PURE__ */ jsx(
801
+ Input,
802
+ {
803
+ value: formState.displayName,
804
+ onChange: (e) => handleInputChange("displayName", e.target.value),
805
+ maxLength: 128,
806
+ placeholder: t("AbpLanguageManagement::DisplayName") || "Display Name"
807
+ }
808
+ ) }),
809
+ /* @__PURE__ */ jsx(FormField, { label: t("AbpLanguageManagement::FlagIcon") || "Flag Icon", children: /* @__PURE__ */ jsx(
810
+ Input,
811
+ {
812
+ value: formState.flagIcon,
813
+ onChange: (e) => handleInputChange("flagIcon", e.target.value),
814
+ maxLength: 48,
815
+ placeholder: t("AbpLanguageManagement::FlagIcon") || "Flag icon (e.g., emoji)"
816
+ }
817
+ ) }),
818
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(
819
+ Checkbox.Root,
820
+ {
821
+ checked: formState.isEnabled,
822
+ onCheckedChange: (e) => handleInputChange("isEnabled", !!e.checked),
823
+ children: [
824
+ /* @__PURE__ */ jsx(Checkbox.HiddenInput, {}),
825
+ /* @__PURE__ */ jsx(Checkbox.Control, {}),
826
+ /* @__PURE__ */ jsx(Checkbox.Label, { children: t("AbpLanguageManagement::IsEnabled") || "Enabled" })
827
+ ]
828
+ }
829
+ ) })
830
+ ] })
831
+ }
832
+ )
833
+ ] });
834
+ }
835
+
836
+ // src/components/LanguageTexts/LanguageTextsComponent.tsx
837
+ import { useEffect as useEffect2, useState as useState4, useCallback as useCallback4 } from "react";
838
+ import { useLocalization as useLocalization2 } from "@abpjs/core";
839
+ import { Modal as Modal2, useConfirmation as useConfirmation2, Toaster as Toaster2, Alert as Alert2, Button as Button2, FormField as FormField2 } from "@abpjs/theme-shared";
840
+ import {
841
+ Box as Box2,
842
+ Flex as Flex2,
843
+ Input as Input2,
844
+ Table as Table2,
845
+ Spinner as Spinner2,
846
+ VStack as VStack2,
847
+ Menu as Menu2,
848
+ Text as Text2,
849
+ Textarea,
850
+ HStack
851
+ } from "@chakra-ui/react";
852
+ import { NativeSelectRoot as NativeSelectRoot2, NativeSelectField as NativeSelectField2 } from "@chakra-ui/react";
853
+ import { Checkbox as Checkbox2 } from "@chakra-ui/react";
854
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
855
+ var DEFAULT_FILTER_STATE = {
856
+ resourceName: "",
857
+ baseCultureName: "",
858
+ targetCultureName: "",
859
+ filter: "",
860
+ getOnlyEmptyValues: false
861
+ };
862
+ function LanguageTextsComponent({
863
+ onLanguageTextUpdated,
864
+ onLanguageTextRestored
865
+ }) {
866
+ const { t } = useLocalization2();
867
+ const confirmation = useConfirmation2();
868
+ const { languages, fetchLanguages } = useLanguages();
869
+ const {
870
+ languageTexts,
871
+ totalCount,
872
+ resources,
873
+ selectedLanguageText,
874
+ isLoading,
875
+ error,
876
+ fetchLanguageTexts,
877
+ fetchResources,
878
+ updateLanguageTextByName,
879
+ restoreLanguageTextByName,
880
+ setSelectedLanguageText
881
+ } = useLanguageTexts();
882
+ const [filterState, setFilterState] = useState4(DEFAULT_FILTER_STATE);
883
+ const [isModalOpen, setIsModalOpen] = useState4(false);
884
+ const [editValue, setEditValue] = useState4("");
885
+ const [isSubmitting, setIsSubmitting] = useState4(false);
886
+ const [currentPage, setCurrentPage] = useState4(0);
887
+ const [pageSize] = useState4(10);
888
+ useEffect2(() => {
889
+ fetchLanguages();
890
+ fetchResources();
891
+ }, [fetchLanguages, fetchResources]);
892
+ useEffect2(() => {
893
+ if (languages.length > 0 && !filterState.baseCultureName) {
894
+ const defaultLanguage = languages.find((l) => l.isDefaultLanguage);
895
+ const baseCulture = defaultLanguage?.cultureName || languages[0]?.cultureName || "en";
896
+ const targetCulture = languages.find((l) => !l.isDefaultLanguage)?.cultureName || baseCulture;
897
+ setFilterState((prev) => ({
898
+ ...prev,
899
+ baseCultureName: baseCulture,
900
+ targetCultureName: targetCulture
901
+ }));
902
+ }
903
+ }, [languages, filterState.baseCultureName]);
904
+ const loadLanguageTexts = useCallback4(
905
+ async (page = currentPage) => {
906
+ if (!filterState.baseCultureName || !filterState.targetCultureName) return;
907
+ await fetchLanguageTexts({
908
+ resourceName: filterState.resourceName || void 0,
909
+ baseCultureName: filterState.baseCultureName,
910
+ targetCultureName: filterState.targetCultureName,
911
+ getOnlyEmptyValues: filterState.getOnlyEmptyValues,
912
+ filter: filterState.filter || void 0,
913
+ skipCount: page * pageSize,
914
+ maxResultCount: pageSize
915
+ });
916
+ },
917
+ [filterState, currentPage, pageSize, fetchLanguageTexts]
918
+ );
919
+ useEffect2(() => {
920
+ if (filterState.baseCultureName && filterState.targetCultureName) {
921
+ setCurrentPage(0);
922
+ loadLanguageTexts(0);
923
+ }
924
+ }, [
925
+ filterState.baseCultureName,
926
+ filterState.targetCultureName,
927
+ filterState.resourceName,
928
+ filterState.getOnlyEmptyValues
929
+ ]);
930
+ const handleSearch = useCallback4(() => {
931
+ setCurrentPage(0);
932
+ loadLanguageTexts(0);
933
+ }, [loadLanguageTexts]);
934
+ const handleEdit = useCallback4(
935
+ (languageText) => {
936
+ setSelectedLanguageText(languageText);
937
+ setEditValue(languageText.value || "");
938
+ setIsModalOpen(true);
939
+ },
940
+ [setSelectedLanguageText]
941
+ );
942
+ const handleRestore = useCallback4(
943
+ async (languageText) => {
944
+ const status = await confirmation.warn(
945
+ t("AbpLanguageManagement::RestoreToDefaultConfirmationMessage") || "Are you sure you want to restore this text to its default value?",
946
+ t("AbpLanguageManagement::AreYouSure") || "Are you sure?"
947
+ );
948
+ if (status === Toaster2.Status.confirm) {
949
+ const params = {
950
+ resourceName: languageText.resourceName,
951
+ cultureName: languageText.cultureName,
952
+ name: languageText.name
953
+ };
954
+ const result = await restoreLanguageTextByName(params);
955
+ if (result.success) {
956
+ onLanguageTextRestored?.(params);
957
+ }
958
+ }
959
+ },
960
+ [confirmation, t, restoreLanguageTextByName, onLanguageTextRestored]
961
+ );
962
+ const handleSubmit = useCallback4(async () => {
963
+ if (!selectedLanguageText) return;
964
+ setIsSubmitting(true);
965
+ const params = {
966
+ resourceName: selectedLanguageText.resourceName,
967
+ cultureName: selectedLanguageText.cultureName,
968
+ name: selectedLanguageText.name,
969
+ value: editValue
970
+ };
971
+ const result = await updateLanguageTextByName(params);
972
+ setIsSubmitting(false);
973
+ if (result.success) {
974
+ onLanguageTextUpdated?.(params);
975
+ setIsModalOpen(false);
976
+ setSelectedLanguageText(null);
977
+ setEditValue("");
978
+ }
979
+ }, [selectedLanguageText, editValue, updateLanguageTextByName, onLanguageTextUpdated, setSelectedLanguageText]);
980
+ const handleModalClose = useCallback4(() => {
981
+ setIsModalOpen(false);
982
+ setSelectedLanguageText(null);
983
+ setEditValue("");
984
+ }, [setSelectedLanguageText]);
985
+ const handleFilterChange = useCallback4(
986
+ (field, value) => {
987
+ setFilterState((prev) => ({ ...prev, [field]: value }));
988
+ },
989
+ []
990
+ );
991
+ const handlePageChange = useCallback4(
992
+ (newPage) => {
993
+ setCurrentPage(newPage);
994
+ loadLanguageTexts(newPage);
995
+ },
996
+ [loadLanguageTexts]
997
+ );
998
+ const totalPages = Math.ceil(totalCount / pageSize);
999
+ return /* @__PURE__ */ jsxs2(Box2, { id: "language-management-texts-wrapper", className: "card", p: 4, children: [
1000
+ /* @__PURE__ */ jsx2(Flex2, { justify: "space-between", align: "center", mb: 4, children: /* @__PURE__ */ jsx2(Text2, { fontSize: "xl", fontWeight: "bold", children: t("AbpLanguageManagement::LanguageTexts") || "Language Texts" }) }),
1001
+ /* @__PURE__ */ jsxs2(VStack2, { gap: 4, align: "stretch", mb: 4, children: [
1002
+ /* @__PURE__ */ jsxs2(HStack, { gap: 4, flexWrap: "wrap", children: [
1003
+ /* @__PURE__ */ jsx2(Box2, { flex: "1", minW: "200px", children: /* @__PURE__ */ jsx2(FormField2, { label: t("AbpLanguageManagement::Resource") || "Resource", children: /* @__PURE__ */ jsx2(NativeSelectRoot2, { children: /* @__PURE__ */ jsxs2(
1004
+ NativeSelectField2,
1005
+ {
1006
+ value: filterState.resourceName,
1007
+ onChange: (e) => handleFilterChange("resourceName", e.target.value),
1008
+ children: [
1009
+ /* @__PURE__ */ jsx2("option", { value: "", children: t("AbpLanguageManagement::AllResources") || "All Resources" }),
1010
+ resources.map((resource) => /* @__PURE__ */ jsx2("option", { value: resource.name, children: resource.name }, resource.name))
1011
+ ]
1012
+ }
1013
+ ) }) }) }),
1014
+ /* @__PURE__ */ jsx2(Box2, { flex: "1", minW: "200px", children: /* @__PURE__ */ jsx2(FormField2, { label: t("AbpLanguageManagement::BaseCulture") || "Base Culture", children: /* @__PURE__ */ jsx2(NativeSelectRoot2, { children: /* @__PURE__ */ jsx2(
1015
+ NativeSelectField2,
1016
+ {
1017
+ value: filterState.baseCultureName,
1018
+ onChange: (e) => handleFilterChange("baseCultureName", e.target.value),
1019
+ children: languages.map((lang) => /* @__PURE__ */ jsxs2("option", { value: lang.cultureName, children: [
1020
+ lang.displayName,
1021
+ " (",
1022
+ lang.cultureName,
1023
+ ")"
1024
+ ] }, lang.cultureName))
1025
+ }
1026
+ ) }) }) }),
1027
+ /* @__PURE__ */ jsx2(Box2, { flex: "1", minW: "200px", children: /* @__PURE__ */ jsx2(FormField2, { label: t("AbpLanguageManagement::TargetCulture") || "Target Culture", children: /* @__PURE__ */ jsx2(NativeSelectRoot2, { children: /* @__PURE__ */ jsx2(
1028
+ NativeSelectField2,
1029
+ {
1030
+ value: filterState.targetCultureName,
1031
+ onChange: (e) => handleFilterChange("targetCultureName", e.target.value),
1032
+ children: languages.map((lang) => /* @__PURE__ */ jsxs2("option", { value: lang.cultureName, children: [
1033
+ lang.displayName,
1034
+ " (",
1035
+ lang.cultureName,
1036
+ ")"
1037
+ ] }, lang.cultureName))
1038
+ }
1039
+ ) }) }) })
1040
+ ] }),
1041
+ /* @__PURE__ */ jsxs2(HStack, { gap: 4, children: [
1042
+ /* @__PURE__ */ jsx2(
1043
+ Input2,
1044
+ {
1045
+ placeholder: t("AbpLanguageManagement::Filter") || "Filter by key or value...",
1046
+ value: filterState.filter,
1047
+ onChange: (e) => handleFilterChange("filter", e.target.value),
1048
+ onKeyDown: (e) => e.key === "Enter" && handleSearch(),
1049
+ flex: "1"
1050
+ }
1051
+ ),
1052
+ /* @__PURE__ */ jsxs2(
1053
+ Checkbox2.Root,
1054
+ {
1055
+ checked: filterState.getOnlyEmptyValues,
1056
+ onCheckedChange: (e) => handleFilterChange("getOnlyEmptyValues", !!e.checked),
1057
+ children: [
1058
+ /* @__PURE__ */ jsx2(Checkbox2.HiddenInput, {}),
1059
+ /* @__PURE__ */ jsx2(Checkbox2.Control, {}),
1060
+ /* @__PURE__ */ jsx2(Checkbox2.Label, { children: t("AbpLanguageManagement::OnlyEmptyValues") || "Only empty values" })
1061
+ ]
1062
+ }
1063
+ ),
1064
+ /* @__PURE__ */ jsx2(Button2, { colorPalette: "blue", onClick: handleSearch, children: t("AbpLanguageManagement::Search") || "Search" })
1065
+ ] })
1066
+ ] }),
1067
+ error && /* @__PURE__ */ jsx2(Alert2, { status: "error", mb: 4, children: error }),
1068
+ isLoading && languageTexts.length === 0 && /* @__PURE__ */ jsx2(Flex2, { justify: "center", py: 8, children: /* @__PURE__ */ jsx2(Spinner2, { size: "lg" }) }),
1069
+ languageTexts.length > 0 && /* @__PURE__ */ jsxs2(Fragment2, { children: [
1070
+ /* @__PURE__ */ jsxs2(Table2.Root, { variant: "outline", children: [
1071
+ /* @__PURE__ */ jsx2(Table2.Header, { children: /* @__PURE__ */ jsxs2(Table2.Row, { children: [
1072
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpLanguageManagement::Actions") || "Actions" }),
1073
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpLanguageManagement::Key") || "Key" }),
1074
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpLanguageManagement::BaseValue") || "Base Value" }),
1075
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpLanguageManagement::TargetValue") || "Target Value" }),
1076
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpLanguageManagement::Resource") || "Resource" })
1077
+ ] }) }),
1078
+ /* @__PURE__ */ jsx2(Table2.Body, { children: languageTexts.map((text, index) => /* @__PURE__ */ jsxs2(Table2.Row, { children: [
1079
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: /* @__PURE__ */ jsxs2(Menu2.Root, { children: [
1080
+ /* @__PURE__ */ jsx2(Menu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx2(Button2, { size: "sm", colorPalette: "blue", children: t("AbpLanguageManagement::Actions") || "Actions" }) }),
1081
+ /* @__PURE__ */ jsx2(Menu2.Positioner, { children: /* @__PURE__ */ jsxs2(Menu2.Content, { children: [
1082
+ /* @__PURE__ */ jsx2(Menu2.Item, { value: "edit", onClick: () => handleEdit(text), children: t("AbpLanguageManagement::Edit") || "Edit" }),
1083
+ text.value !== text.baseValue && /* @__PURE__ */ jsx2(
1084
+ Menu2.Item,
1085
+ {
1086
+ value: "restore",
1087
+ color: "orange.500",
1088
+ onClick: () => handleRestore(text),
1089
+ children: t("AbpLanguageManagement::RestoreToDefault") || "Restore to Default"
1090
+ }
1091
+ )
1092
+ ] }) })
1093
+ ] }) }),
1094
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: /* @__PURE__ */ jsx2(Text2, { fontSize: "sm", fontFamily: "mono", children: text.name }) }),
1095
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: /* @__PURE__ */ jsx2(Text2, { fontSize: "sm", color: "gray.600", children: text.baseValue }) }),
1096
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: /* @__PURE__ */ jsx2(
1097
+ Text2,
1098
+ {
1099
+ fontSize: "sm",
1100
+ color: text.value ? "inherit" : "red.500",
1101
+ fontStyle: text.value ? "normal" : "italic",
1102
+ children: text.value || t("AbpLanguageManagement::NotTranslated") || "(Not translated)"
1103
+ }
1104
+ ) }),
1105
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: /* @__PURE__ */ jsx2(Text2, { fontSize: "sm", color: "gray.500", children: text.resourceName }) })
1106
+ ] }, `${text.resourceName}-${text.name}-${index}`)) })
1107
+ ] }),
1108
+ totalPages > 1 && /* @__PURE__ */ jsxs2(Flex2, { justify: "space-between", align: "center", mt: 4, children: [
1109
+ /* @__PURE__ */ jsx2(Text2, { fontSize: "sm", color: "gray.500", children: t("AbpLanguageManagement::ShowingXofY", (currentPage * pageSize + 1).toString(), Math.min((currentPage + 1) * pageSize, totalCount).toString(), totalCount.toString()) || `Showing ${currentPage * pageSize + 1}-${Math.min((currentPage + 1) * pageSize, totalCount)} of ${totalCount}` }),
1110
+ /* @__PURE__ */ jsxs2(HStack, { gap: 2, children: [
1111
+ /* @__PURE__ */ jsx2(
1112
+ Button2,
1113
+ {
1114
+ size: "sm",
1115
+ variant: "outline",
1116
+ onClick: () => handlePageChange(currentPage - 1),
1117
+ disabled: currentPage === 0,
1118
+ children: t("AbpLanguageManagement::Previous") || "Previous"
1119
+ }
1120
+ ),
1121
+ /* @__PURE__ */ jsxs2(Text2, { fontSize: "sm", children: [
1122
+ currentPage + 1,
1123
+ " / ",
1124
+ totalPages
1125
+ ] }),
1126
+ /* @__PURE__ */ jsx2(
1127
+ Button2,
1128
+ {
1129
+ size: "sm",
1130
+ variant: "outline",
1131
+ onClick: () => handlePageChange(currentPage + 1),
1132
+ disabled: currentPage >= totalPages - 1,
1133
+ children: t("AbpLanguageManagement::Next") || "Next"
1134
+ }
1135
+ )
1136
+ ] })
1137
+ ] })
1138
+ ] }),
1139
+ !isLoading && languageTexts.length === 0 && filterState.baseCultureName && filterState.targetCultureName && /* @__PURE__ */ jsx2(Text2, { textAlign: "center", color: "gray.500", py: 8, children: t("AbpLanguageManagement::NoLanguageTextsFound") || "No language texts found" }),
1140
+ !filterState.baseCultureName || !filterState.targetCultureName ? /* @__PURE__ */ jsx2(Text2, { textAlign: "center", color: "gray.500", py: 8, children: t("AbpLanguageManagement::SelectCulturesToViewTexts") || "Select base and target cultures to view language texts" }) : null,
1141
+ /* @__PURE__ */ jsx2(
1142
+ Modal2,
1143
+ {
1144
+ visible: isModalOpen,
1145
+ onVisibleChange: setIsModalOpen,
1146
+ header: t("AbpLanguageManagement::EditLanguageText") || "Edit Language Text",
1147
+ footer: /* @__PURE__ */ jsxs2(Fragment2, { children: [
1148
+ /* @__PURE__ */ jsx2(Button2, { variant: "outline", onClick: handleModalClose, disabled: isSubmitting, children: t("AbpLanguageManagement::Cancel") || "Cancel" }),
1149
+ /* @__PURE__ */ jsx2(Button2, { colorPalette: "blue", onClick: handleSubmit, loading: isSubmitting, children: t("AbpLanguageManagement::Save") || "Save" })
1150
+ ] }),
1151
+ children: /* @__PURE__ */ jsx2(VStack2, { gap: 4, align: "stretch", children: selectedLanguageText && /* @__PURE__ */ jsxs2(Fragment2, { children: [
1152
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpLanguageManagement::Key") || "Key", children: /* @__PURE__ */ jsx2(Text2, { fontFamily: "mono", p: 2, bg: "gray.100", borderRadius: "md", children: selectedLanguageText.name }) }),
1153
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpLanguageManagement::BaseValue") || "Base Value", children: /* @__PURE__ */ jsx2(Text2, { p: 2, bg: "gray.100", borderRadius: "md", color: "gray.600", children: selectedLanguageText.baseValue }) }),
1154
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpLanguageManagement::TargetValue") || "Target Value", children: /* @__PURE__ */ jsx2(
1155
+ Textarea,
1156
+ {
1157
+ value: editValue,
1158
+ onChange: (e) => setEditValue(e.target.value),
1159
+ placeholder: t("AbpLanguageManagement::EnterTranslation") || "Enter translation...",
1160
+ rows: 4
1161
+ }
1162
+ ) })
1163
+ ] }) })
1164
+ }
1165
+ )
1166
+ ] });
1167
+ }
1168
+ export {
1169
+ LANGUAGE_MANAGEMENT_ROUTES,
1170
+ LanguageManagementService,
1171
+ LanguageTextsComponent,
1172
+ LanguagesComponent,
1173
+ useLanguageTexts,
1174
+ useLanguages
1175
+ };