|
| 1 | +import { EntryNode } from "@/client"; |
| 2 | +import { |
| 3 | + Chip, |
| 4 | + Stack, |
| 5 | + TableBody, |
| 6 | + TableCell, |
| 7 | + TableRow, |
| 8 | + Tooltip, |
| 9 | + Typography, |
| 10 | +} from "@mui/material"; |
| 11 | +import { Link } from "react-router-dom"; |
| 12 | +import ISO6391 from "iso-639-1"; |
| 13 | +import { useEffect, useState } from "react"; |
| 14 | +import { SHOWN_LANGUAGES_KEY } from "@/pages/project/editentry/ListTranslations"; |
| 15 | + |
| 16 | +type Props = { |
| 17 | + entryNodes: EntryNode[]; |
| 18 | + taxonomyName: string; |
| 19 | + branchName: string; |
| 20 | +}; |
| 21 | + |
| 22 | +const EntryTitle = ({ id }: { id: string }) => { |
| 23 | + const languageCode = id.split(":", 1)[0]; |
| 24 | + const languageName = ISO6391.getName(languageCode); |
| 25 | + return ( |
| 26 | + <Typography variant="subtitle1"> |
| 27 | + {id.slice(languageCode.length + 1)} |
| 28 | + <Tooltip title="Main language of the entry" placement="right" arrow> |
| 29 | + <Chip label={languageName} size="small" sx={{ ml: 1, mb: 0.5 }} /> |
| 30 | + </Tooltip> |
| 31 | + </Typography> |
| 32 | + ); |
| 33 | +}; |
| 34 | + |
| 35 | +const getTranslations = ( |
| 36 | + tags: Record<string, string[]>, |
| 37 | + shownLanguageCodes: string[] |
| 38 | +) => { |
| 39 | + const result: string[] = []; |
| 40 | + |
| 41 | + shownLanguageCodes.forEach((languageCode) => { |
| 42 | + const languageName = |
| 43 | + languageCode === "xx" |
| 44 | + ? "Fallback translations" |
| 45 | + : ISO6391.getName(languageCode); |
| 46 | + const translations = tags[`tags_${languageCode}`]; |
| 47 | + if (translations) { |
| 48 | + result.push(`${languageName}: ${translations.join(", ")}`); |
| 49 | + } |
| 50 | + }); |
| 51 | + |
| 52 | + return result; |
| 53 | +}; |
| 54 | + |
| 55 | +export const EntryNodesTableBody = ({ |
| 56 | + entryNodes, |
| 57 | + taxonomyName, |
| 58 | + branchName, |
| 59 | +}: Props) => { |
| 60 | + const [shownLanguageCodes, setShownLanguageCodes] = useState<string[]>([]); |
| 61 | + |
| 62 | + useEffect(() => { |
| 63 | + // get shown languages from local storage if it exists else use main language |
| 64 | + try { |
| 65 | + const rawLocalStorageShownLanguages = |
| 66 | + localStorage.getItem(SHOWN_LANGUAGES_KEY); |
| 67 | + let localStorageShownLanguages: string[] | null = |
| 68 | + rawLocalStorageShownLanguages |
| 69 | + ? JSON.parse(rawLocalStorageShownLanguages) |
| 70 | + : null; |
| 71 | + // validate that shown languages is an array of strings and filter all items that are valid language codes |
| 72 | + if ( |
| 73 | + Array.isArray(localStorageShownLanguages) && |
| 74 | + localStorageShownLanguages.every((item) => typeof item === "string") |
| 75 | + ) { |
| 76 | + localStorageShownLanguages = localStorageShownLanguages.filter( |
| 77 | + (item) => { |
| 78 | + return item === "xx" || ISO6391.validate(item); |
| 79 | + } |
| 80 | + ); |
| 81 | + } else { |
| 82 | + localStorageShownLanguages = []; |
| 83 | + } |
| 84 | + setShownLanguageCodes(localStorageShownLanguages); |
| 85 | + } catch (e) { |
| 86 | + // shown languages is an empty list, when we can't parse the local storage |
| 87 | + console.log(e); |
| 88 | + } |
| 89 | + }, []); |
| 90 | + |
| 91 | + return ( |
| 92 | + <> |
| 93 | + <TableBody> |
| 94 | + {entryNodes.map(({ id, isExternal, tags }) => ( |
| 95 | + <TableRow |
| 96 | + key={id} |
| 97 | + hover |
| 98 | + component={Link} |
| 99 | + to={`/${taxonomyName}/${branchName}/entry/${id}`} |
| 100 | + sx={{ textDecoration: "none" }} |
| 101 | + > |
| 102 | + <TableCell align="left" component="td" scope="row"> |
| 103 | + <Stack gap={0.5}> |
| 104 | + <EntryTitle id={id} /> |
| 105 | + {isExternal && ( |
| 106 | + <Typography variant="subtitle2" color="secondary"> |
| 107 | + External Node |
| 108 | + </Typography> |
| 109 | + )} |
| 110 | + {getTranslations(tags, shownLanguageCodes).map((line, i) => ( |
| 111 | + <Typography key={i} variant="body2" color="inherit"> |
| 112 | + {line} |
| 113 | + </Typography> |
| 114 | + ))} |
| 115 | + </Stack> |
| 116 | + </TableCell> |
| 117 | + </TableRow> |
| 118 | + ))} |
| 119 | + </TableBody> |
| 120 | + </> |
| 121 | + ); |
| 122 | +}; |
0 commit comments