Skip to content

Commit

Permalink
Merge pull request BloomBooks#561 from StephenMcConnel/BL-13305-MoreW…
Browse files Browse the repository at this point in the history
…orkOnGrids

Handle irregular language tags for grids (BL-13305) (BloomBooks#561)
  • Loading branch information
andrew-polk authored Jul 24, 2024
2 parents 65c85eb + 3f63e60 commit c687819
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 65 deletions.
113 changes: 72 additions & 41 deletions src/components/AggregateGrid/AggregateGridPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,21 +240,21 @@ export function filterDateStringWithOperator(
}

export function getCountryIdMapFromLangTagData(
langData: ILangTagData[]
langTagData: ILangTagData[]
): Map<string, string> {
const countryIdMap = new Map<string, string>();
langData.forEach((lng) => {
langTagData.forEach((lng) => {
if (lng.region && lng.regionname) {
countryIdMap.set(lng.region, lng.regionname);
}
});
return countryIdMap;
}
export function fixLanguageRegionDataAndGetMap(
rawLangData: ILangTagData[]
export function fixLangTagRegionDataAndGetMap(
rawLangTagData: ILangTagData[]
): Map<string, ILangTagData> {
const map = new Map<string, ILangTagData>();
rawLangData.forEach((lng) => {
rawLangTagData.forEach((lng) => {
map.set(lng.tag, lng);
// Override some primary region settings that seem misguided.
if (lng.tag === "en") {
Expand All @@ -263,42 +263,6 @@ export function fixLanguageRegionDataAndGetMap(
lng.region = "PT"; // Portuguese originated in Portugal, not Brazil.
}
});
// // // Add regions to the original language entries from the -Dupl and -Brai scripts.
// // // I'm not sure what Dupl is, but Brai is Braille. It makes sense that the Braille
// // // script shouldn't be considered a separate language, and that it would used only
// // // where the language is actually spoken.
// // // This ensures that Spanish is known to be spoken in Mexico and the US, for example.
// // // Also, that English is spoken in the UK, Australia, and Canada.
// // // Other languages such as German and French also get additional regions added by this
// // // processing.
// // rawLangData.forEach((lng) => {
// // if (lng.tag.endsWith("-Dupl") || lng.tag.endsWith("-Brai")) {
// // if (lng.regions && lng.regions.length > 0) {
// // const tag = lng.tag.substring(0, lng.tag.length - 5);
// // const origLang = map.get(tag);
// // if (!origLang) {
// // console.warn("No original lang for ", tag);
// // return;
// // }
// // if (!origLang.regions) {
// // origLang.regions = [];
// // }
// // if (!origLang.regions.includes(lng.region)) {
// // console.log(`Adding region ${lng.region} to ${tag}`);
// // origLang.regions.push(lng.region);
// // }
// // lng.regions.forEach((r) => {
// // if (!origLang.regions) {
// // origLang.regions = [];
// // }
// // if (!origLang.regions.includes(r)) {
// // console.log(`Adding region ${r} to ${tag}`);
// // origLang.regions.push(r);
// // }
// // });
// // }
// // }
// // });
// // Restrict the regions for some major languages to the most common ones.
// // REVIEW: are these copilot suggestions good enough?
// const english = map.get("en");
Expand Down Expand Up @@ -326,6 +290,73 @@ export function fixLanguageRegionDataAndGetMap(
return map;
}

export function getLangTagDataForIrregularLangCode(
code: string,
langDataMap: Map<string, ILangTagData>,
countryIdMap: Map<string, string>
): ILangTagData | undefined {
const langTagData = {} as ILangTagData;
const codeSections = code.split("-x-");
const tagPieces = codeSections[0].split("-");
langTagData.tag = code;
if (tagPieces.length > 1) {
const reg = tagPieces.find((piece) => {
return /[A-Z]{2}/.test(piece);
});
if (reg) {
langTagData.region = reg;
langTagData.regionname = countryIdMap.get(reg) || reg;
}
}
if (codeSections.length > 1) {
langTagData.name = codeSections[1];
}
// replace obsolete codes with current ones.
// or possibly specific with generic due to general confusion
let newCode = tagPieces[0];
switch (newCode) {
// swh / Swahili (Tanzania) shares the macrolanguage code sw with swc / Swahili (Congo)
case "swh":
newCode = "sw";
break;
// kmr / Northern Kurdish shares the macrolanguage code ku with ckb / Central Kurdish and sdh / Southern Kurdish
case "kmr":
newCode = "ku";
break;
// obsolete code for Southern Balochi
case "bcc":
newCode = "bal";
break;
// obsolete code for Luyia, sometimes called Bukusu
case "bxk":
newCode = "luy";
break;
// obsolete code for Cusco Quechua
// que / (Cuzco) Quechua shares the macrolanguage code qu with qub, qud, quf, quk, qul, qup, qur, qus, and many more
case "quz":
newCode = "qu";
break;
// obsolete code for Marwari, sometimes called Dhundari
case "dhd":
newCode = "mwr";
break;
// obsolete code for Eastern Yiddish
// yid / (Eastern) Yiddish shares the macrolanguage code yi with yih / Western Yiddish
case "ydd":
newCode = "yi";
break;
}
const tagData = langDataMap.get(newCode);
if (tagData) {
if (!langTagData.name) langTagData.name = tagData.name;
if (!langTagData.region) {
langTagData.region = tagData.region;
langTagData.regionname = tagData.regionname;
}
}
return langTagData;
}

export const ModeratorStatusToolbarPlugin = (
theme: Theme,
user: User | undefined
Expand Down
14 changes: 11 additions & 3 deletions src/components/CountryGrid/CountryGridControlInternal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ import { ICountryGridControlProps } from "./CountryGridControl";
import { CachedTablesContext } from "../../model/CacheProvider";
import {
CachedBookDataContext,
fixLanguageRegionDataAndGetMap,
fixLangTagRegionDataAndGetMap,
getCountryIdMapFromLangTagData,
getLangTagDataForIrregularLangCode,
ModeratorStatusToolbarPlugin,
} from "../AggregateGrid/AggregateGridPage";
import {
Expand Down Expand Up @@ -82,7 +83,7 @@ const CountryGridControlInternal: React.FunctionComponent<ICountryGridControlPro
ICountryGridRowData[]
>([]);
const fullLangDataMap = useMemo(() => {
return fixLanguageRegionDataAndGetMap(rawLangData);
return fixLangTagRegionDataAndGetMap(rawLangData);
}, []);
const countryIdMap = useMemo(() => {
return getCountryIdMapFromLangTagData(rawLangData);
Expand Down Expand Up @@ -173,7 +174,14 @@ const CountryGridControlInternal: React.FunctionComponent<ICountryGridControlPro
) {
return;
}
const lang = fullLangDataMap.get(book.lang1Tag);
let lang = fullLangDataMap.get(book.lang1Tag);
if (!lang) {
lang = getLangTagDataForIrregularLangCode(
book.lang1Tag,
fullLangDataMap,
countryIdMap
);
}
if (lang && lang.region) {
const rowData = countryMap.get(lang.region);
if (rowData) {
Expand Down
22 changes: 10 additions & 12 deletions src/components/LanguageGrid/LanguageGridColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ export function getLanguageGridColumnsDefinitions(): IGridColumn[] {
defaultVisible: true,
sortingEnabled: true,
getCellValue: (lang: ILanguageGridRowData) => {
const hrefValue = `https://bloomlibrary.org/language:${lang.langTag}`;
const hrefValue = `/language:${lang.langTag}`;
return (
<a
href={hrefValue}
target="_blank"
rel="noopener noreferrer"
>
// we don't need rel="noreferrer" because the destination is on the same website,
// and we want to preserve the login status for the new tab
// eslint-disable-next-line react/jsx-no-target-blank
<a href={hrefValue} target="_blank">
{lang.exonym}
</a>
);
Expand Down Expand Up @@ -254,18 +253,17 @@ export function getLanguageGridColumnsDefinitions(): IGridColumn[] {
sortingEnabled: true,
getCellValue: (lang: ILanguageGridRowData) => {
const links = lang.uploaderEmails.map((email, index) => {
const hrefValue = `https://bloomlibrary.org/:search:uploader:${email}`;
const hrefValue = `/:search:uploader:${email}`;
let separator = "";
if (index < lang.uploaderEmails.length - 1) {
separator = ", ";
}
return (
<span>
<a
href={hrefValue}
target="_blank"
rel="noopener noreferrer"
>
{/* we don't need rel="noreferrer" because the destination is on the same website,
and we want to preserve the login status for the new tab */}
{/*eslint-disable-next-line react/jsx-no-target-blank*/}
<a href={hrefValue} target="_blank">
{email}
</a>
{separator}
Expand Down
19 changes: 13 additions & 6 deletions src/components/LanguageGrid/LanguageGridControlInternal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ import { ILanguageGridControlProps } from "./LanguageGridControl";
import { CachedTablesContext } from "../../model/CacheProvider";
import {
CachedBookDataContext,
fixLanguageRegionDataAndGetMap,
fixLangTagRegionDataAndGetMap,
getLangTagDataForIrregularLangCode,
ModeratorStatusToolbarPlugin,
} from "../AggregateGrid/AggregateGridPage";
import { ILangTagData } from "../AggregateGrid/AggregateGridInterfaces";
Expand All @@ -77,7 +78,7 @@ const LanguageGridControlInternal: React.FunctionComponent<ILanguageGridControlP
ILanguageGridRowData[]
>([]);
const fullLangDataMap = useMemo(() => {
return fixLanguageRegionDataAndGetMap(rawLangData);
return fixLangTagRegionDataAndGetMap(rawLangData);
}, []);
const countriesMap = useMemo(() => {
const map = new Map<string, string>();
Expand Down Expand Up @@ -123,10 +124,14 @@ const LanguageGridControlInternal: React.FunctionComponent<ILanguageGridControlP
level3Count: 0,
level4Count: 0,
};
const langData = fullLangDataMap.get(lang.isoCode);
// if (!langData) {
// console.log(`DEBUG: No langData for ${lang.isoCode}`);
// }
let langData = fullLangDataMap.get(lang.isoCode);
if (!langData) {
langData = getLangTagDataForIrregularLangCode(
lang.isoCode,
fullLangDataMap,
countriesMap
);
}
if (langData) {
baseValue.exonym = langData.name;
if (langData.names) {
Expand All @@ -144,6 +149,8 @@ const LanguageGridControlInternal: React.FunctionComponent<ILanguageGridControlP
);
if (regionName) {
baseValue.countryName = regionName;
} else {
baseValue.countryName = `[${langData.region}]`;
}
}
// if we go back to allowing multiple regions per language, this code will be useful
Expand Down
14 changes: 11 additions & 3 deletions src/components/UploaderGrid/UploaderGridControlInternal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ import { CachedTablesContext } from "../../model/CacheProvider";

import {
CachedBookDataContext,
fixLanguageRegionDataAndGetMap,
fixLangTagRegionDataAndGetMap,
getLangTagDataForIrregularLangCode,
ModeratorStatusToolbarPlugin,
} from "../AggregateGrid/AggregateGridPage";
import {
Expand Down Expand Up @@ -85,7 +86,7 @@ const UploaderGridControlInternal: React.FunctionComponent<IUploaderGridControlP
IUploaderGridData[]
>([]);
const fullLangDataMap = useMemo(() => {
return fixLanguageRegionDataAndGetMap(rawLangData);
return fixLangTagRegionDataAndGetMap(rawLangData);
}, []);

// extract a country name map from the language data
Expand Down Expand Up @@ -160,9 +161,16 @@ const UploaderGridControlInternal: React.FunctionComponent<IUploaderGridControlP
if (book.lang1Tag) {
if (!user.languages.includes(book.lang1Tag)) {
user.languages.push(book.lang1Tag);
const langData = fullLangDataMap.get(
let langData = fullLangDataMap.get(
book.lang1Tag
);
if (!langData) {
langData = getLangTagDataForIrregularLangCode(
book.lang1Tag,
fullLangDataMap,
countriesMap
);
}
if (langData && langData.region) {
const countryName = countriesMap.get(
langData.region
Expand Down

0 comments on commit c687819

Please sign in to comment.