diff --git a/package-lock.json b/package-lock.json index 564a265..0d6adce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -77,7 +77,7 @@ "gh-pages": "^6.3.0", "jest": "^29.7.0", "jsdom": "^26.0.0", - "prettier": "^3.4.2", + "prettier": "^3.8.3", "prettier-plugin-organize-imports": "^4.1.0", "run-script-os": "^1.1.6", "start-server-and-test": "^2.0.9", @@ -10571,10 +10571,11 @@ } }, "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "version": "3.8.3", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -12615,7 +12616,7 @@ "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13430,8 +13431,7 @@ "@artsy/fresnel": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@artsy/fresnel/-/fresnel-6.2.1.tgz", - "integrity": "sha512-UAyHZU64Vie3sLDdL3qD+7pODGzKNu9pSpxGKpDOCaiBvCDZnFXIfJEEfV9v9i+QiJJwzO+lqsFwvw6YiJeXFQ==", - "requires": {} + "integrity": "sha512-UAyHZU64Vie3sLDdL3qD+7pODGzKNu9pSpxGKpDOCaiBvCDZnFXIfJEEfV9v9i+QiJJwzO+lqsFwvw6YiJeXFQ==" }, "@asamuzakjp/css-color": { "version": "2.8.3", @@ -13986,8 +13986,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz", "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==", - "dev": true, - "requires": {} + "dev": true }, "@csstools/css-color-parser": { "version": "3.0.7", @@ -14003,8 +14002,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", - "dev": true, - "requires": {} + "dev": true }, "@csstools/css-tokenizer": { "version": "3.0.3", @@ -15331,8 +15329,7 @@ "version": "18.3.5", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", - "dev": true, - "requires": {} + "dev": true }, "@types/semver": { "version": "7.7.1", @@ -15561,8 +15558,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "8.3.4", @@ -17116,8 +17112,7 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "requires": {} + "dev": true }, "deep-is": { "version": "0.1.4", @@ -19527,8 +19522,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "29.6.3", @@ -20937,17 +20931,16 @@ "dev": true }, "prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "version": "3.8.3", + "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true }, "prettier-plugin-organize-imports": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz", "integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==", - "dev": true, - "requires": {} + "dev": true }, "pretty-bytes": { "version": "5.6.0", @@ -22059,8 +22052,7 @@ "version": "6.4.6", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "requires": {} + "dev": true }, "picomatch": { "version": "4.0.4", @@ -22369,7 +22361,7 @@ "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "devOptional": true + "dev": true }, "uc.micro": { "version": "1.0.6", @@ -22572,8 +22564,7 @@ "version": "6.4.6", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "requires": {} + "dev": true }, "picomatch": { "version": "4.0.4", @@ -22598,8 +22589,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.4.tgz", "integrity": "sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -22797,8 +22787,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "requires": {} + "dev": true }, "xml-name-validator": { "version": "5.0.0", @@ -22877,8 +22866,7 @@ "version": "4.0.2", "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/zod-validation-error/-/zod-validation-error-4.0.2.tgz", "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", - "dev": true, - "requires": {} + "dev": true }, "zwitch": { "version": "2.0.4", diff --git a/package.json b/package.json index 32f71ae..cfcbb9b 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "gh-pages": "^6.3.0", "jest": "^29.7.0", "jsdom": "^26.0.0", - "prettier": "^3.4.2", + "prettier": "^3.8.3", "prettier-plugin-organize-imports": "^4.1.0", "run-script-os": "^1.1.6", "start-server-and-test": "^2.0.9", @@ -90,7 +90,7 @@ "build:default": "tsc && GENERATE_SOURCEMAP=false VITE_CHANGELOG=`cat CHANGELOG.md` VITE_GIT_SHA=`git rev-parse --short HEAD` VITE_GIT_TIME=`git log -1 --format=%ci` vite build", "build:windows": "powershell -Command \"Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser; tsc; if ($?) { $env:GENERATE_SOURCEMAP='false'; $env:VITE_CHANGELOG = Get-Content -Path \"CHANGELOG.md\" -Raw; $env:VITE_GIT_SHA=$(git rev-parse --short HEAD); $env:VITE_GIT_TIME=$(git log -1 --format='%ci'); vite build }", "test": "jest", - "prettier": "prettier --write src/**/*.{ts,tsx,json} && prettier --write src/*.{ts,tsx,json}", + "prettier": "prettier --write \"src/**/*.{ts,tsx,json}\"", "lint": "eslint src --ext .ts,.tsx", "predeploy": "npm run build", "deploy": "gh-pages -d dist", diff --git a/src/sidepanel/config/config.tsx b/src/sidepanel/config/config.tsx index 6a26864..3be84ea 100644 --- a/src/sidepanel/config/config.tsx +++ b/src/sidepanel/config/config.tsx @@ -1,8 +1,8 @@ -import {SourceHead} from '../head/head'; -import {GedcomData} from '../../util/gedcom_util'; import {ParsedQuery} from 'query-string'; import {FormattedMessage} from 'react-intl'; import {Checkbox, Form, Header, Item} from 'semantic-ui-react'; +import {GedcomData} from '../../util/gedcom_util'; +import {SourceHead} from '../head/head'; export enum ChartColors { NO_COLOR, @@ -82,158 +82,169 @@ export function ConfigPanel(props: { }) { return ( <> - {SourceHead(props.gedcom)}
- - - -
- -
- - - } - name="checkboxRadioGroup" - value="none" - checked={props.config.color === ChartColors.NO_COLOR} - onClick={() => - props.onChange({ - ...props.config, - color: ChartColors.NO_COLOR, - }) - } - /> - - - - } - name="checkboxRadioGroup" - value="generation" - checked={props.config.color === ChartColors.COLOR_BY_GENERATION} - onClick={() => - props.onChange({ - ...props.config, - color: ChartColors.COLOR_BY_GENERATION, - }) - } - /> - - - - } - name="checkboxRadioGroup" - value="gender" - checked={props.config.color === ChartColors.COLOR_BY_SEX} - onClick={() => - props.onChange({ - ...props.config, - color: ChartColors.COLOR_BY_SEX, - }) - } - /> - -
-
- - -
- -
- - - } - name="checkboxRadioGroup" - value="hide" - checked={props.config.id === Ids.HIDE} - onClick={() => props.onChange({...props.config, id: Ids.HIDE})} - /> - - - - } - name="checkboxRadioGroup" - value="show" - checked={props.config.id === Ids.SHOW} - onClick={() => props.onChange({...props.config, id: Ids.SHOW})} - /> - -
-
- - -
- -
- - - } - name="checkboxRadioGroup" - value="hide" - checked={props.config.sex === Sex.HIDE} - onClick={() => props.onChange({...props.config, sex: Sex.HIDE})} - /> - - - - } - name="checkboxRadioGroup" - value="show" - checked={props.config.sex === Sex.SHOW} - onClick={() => props.onChange({...props.config, sex: Sex.SHOW})} - /> - -
-
-
-
+ {SourceHead(props.gedcom)} +
+ + + +
+ +
+ + + } + name="checkboxRadioGroup" + value="none" + checked={props.config.color === ChartColors.NO_COLOR} + onClick={() => + props.onChange({ + ...props.config, + color: ChartColors.NO_COLOR, + }) + } + /> + + + + } + name="checkboxRadioGroup" + value="generation" + checked={ + props.config.color === ChartColors.COLOR_BY_GENERATION + } + onClick={() => + props.onChange({ + ...props.config, + color: ChartColors.COLOR_BY_GENERATION, + }) + } + /> + + + + } + name="checkboxRadioGroup" + value="gender" + checked={props.config.color === ChartColors.COLOR_BY_SEX} + onClick={() => + props.onChange({ + ...props.config, + color: ChartColors.COLOR_BY_SEX, + }) + } + /> + +
+
+ + +
+ +
+ + + } + name="checkboxRadioGroup" + value="hide" + checked={props.config.id === Ids.HIDE} + onClick={() => + props.onChange({...props.config, id: Ids.HIDE}) + } + /> + + + + } + name="checkboxRadioGroup" + value="show" + checked={props.config.id === Ids.SHOW} + onClick={() => + props.onChange({...props.config, id: Ids.SHOW}) + } + /> + +
+
+ + +
+ +
+ + + } + name="checkboxRadioGroup" + value="hide" + checked={props.config.sex === Sex.HIDE} + onClick={() => + props.onChange({...props.config, sex: Sex.HIDE}) + } + /> + + + + } + name="checkboxRadioGroup" + value="show" + checked={props.config.sex === Sex.SHOW} + onClick={() => + props.onChange({...props.config, sex: Sex.SHOW}) + } + /> + +
+
+
+
); } diff --git a/src/sidepanel/details/additional-files.tsx b/src/sidepanel/details/additional-files.tsx index baee5ca..65c57c9 100644 --- a/src/sidepanel/details/additional-files.tsx +++ b/src/sidepanel/details/additional-files.tsx @@ -25,7 +25,7 @@ export function AdditionalFiles({files}: Props) { - {file.titl &&
{file.titl}
} + {file.titl &&
{file.titl}
}
diff --git a/src/sidepanel/details/details.tsx b/src/sidepanel/details/details.tsx index cd53bb9..b5e20b1 100644 --- a/src/sidepanel/details/details.tsx +++ b/src/sidepanel/details/details.tsx @@ -11,13 +11,13 @@ import { getNonImageFileEntry, mapToSource, } from '../../util/gedcom_util'; -import {FileEntry, AdditionalFiles} from './additional-files'; +import {Config, Ids} from '../config/config'; +import {AdditionalFiles, FileEntry} from './additional-files'; import {ALL_SUPPORTED_EVENT_TYPES, Events} from './events'; import {MultilineText} from './multiline-text'; import {Sources} from './sources'; import {TranslatedTag} from './translated-tag'; import {WrappedImage} from './wrapped-image'; -import {Config, Ids} from '../config/config'; const EXCLUDED_TAGS = [ ...ALL_SUPPORTED_EVENT_TYPES, @@ -61,32 +61,30 @@ function attributeDetails(entry: GedcomEntry) { } const attributeName = entry.tree - .filter((subentry) => subentry.tag === 'TYPE') - .flatMap((type) => getData(type)) - .join() - .trim(); + .filter((subentry) => subentry.tag === 'TYPE') + .flatMap((type) => getData(type)) + .join() + .trim(); const attributeValue = getData(entry).join(' ').trim(); - if(attributeName) { + if (attributeName) { return ( - <> -
- -
-
- {attributeName}: {attributeValue} -
- + <> +
+ +
+
+ {attributeName}: {attributeValue} +
+ ); } else { return ( <>
- +
-
- {attributeValue} -
+
{attributeValue}
); } @@ -142,7 +140,9 @@ function sourceDetails( function fileDetails(objectEntries: GedcomEntry[], gedcom: GedcomData) { const files: FileEntry[] = []; objectEntries - .map((objectEntry) => dereference(objectEntry, gedcom, (gedcom) => gedcom.other)) + .map((objectEntry) => + dereference(objectEntry, gedcom, (gedcom) => gedcom.other), + ) .forEach((objectEntry) => { const fileEntry = getNonImageFileEntry(objectEntry); if (fileEntry) { @@ -150,7 +150,7 @@ function fileDetails(objectEntries: GedcomEntry[], gedcom: GedcomData) { url: fileEntry.data, filename: getFileName(fileEntry), titl: objectEntry.tree.find((entry) => entry.tag === 'TITL')?.data, - }) + }); } }); @@ -314,14 +314,16 @@ function getOtherSections(entries: GedcomEntry[], gedcom: GedcomData) { )); } -function getSectionForId(indi: string) : React.ReactNode { +function getSectionForId(indi: string): React.ReactNode { return (
-
{indi}
+
+ {indi} +
); @@ -354,10 +356,10 @@ export function Details(props: Props) { {props.config.id === Ids.SHOW ? getSectionForId(props.indi) : null} {getSectionForEachMatchingEntry( - entries, - props.gedcom, - ['FACT'], - attributeDetails, + entries, + props.gedcom, + ['FACT'], + attributeDetails, )} {getOtherSections(entries, props.gedcom)} {getSectionForEachMatchingEntry( diff --git a/src/sidepanel/details/linkify-new-tab.tsx b/src/sidepanel/details/linkify-new-tab.tsx index eefc27d..a94c076 100644 --- a/src/sidepanel/details/linkify-new-tab.tsx +++ b/src/sidepanel/details/linkify-new-tab.tsx @@ -11,8 +11,17 @@ interface Props { export function LinkifyNewTab({children}: Props) { return ( ( - + componentDecorator={( + decoratedHref: string, + decoratedText: string, + key: number, + ) => ( + {decoratedText} )} diff --git a/src/sidepanel/head/head.tsx b/src/sidepanel/head/head.tsx index d7d467f..793c6fd 100644 --- a/src/sidepanel/head/head.tsx +++ b/src/sidepanel/head/head.tsx @@ -1,108 +1,128 @@ -import { - dereference, - GedcomData, -} from '../../util/gedcom_util'; import {FormattedMessage, useIntl} from 'react-intl'; -import {Header, Divider, List} from 'semantic-ui-react'; +import {Divider, Header, List} from 'semantic-ui-react'; import {getDate} from 'topola'; import {formatDateOrRange} from '../../util/date_util'; +import {dereference, GedcomData} from '../../util/gedcom_util'; -export function SourceHead(gedcom: GedcomData){ +export function SourceHead(gedcom: GedcomData) { const head = gedcom.head; /* Don't show the section if there is no relevant information */ if (!head || !head.tree) { return null; - } + } const sour = head.tree.find((entry) => entry.tag === 'SOUR'); - const sour_name = sour && sour.tree && sour.tree.find((entry) => entry.tag === 'NAME')?.data; // Software name + const sour_name = + sour && sour.tree && sour.tree.find((entry) => entry.tag === 'NAME')?.data; // Software name const date = head.tree.find((entry) => entry.tag === 'DATE'); // Creation date const intl = useIntl(); - const dateFormatted = date ? formatDateOrRange(getDate(date.data), intl) : null; // Formatted creation date + const dateFormatted = date + ? formatDateOrRange(getDate(date.data), intl) + : null; // Formatted creation date const file = head.tree.find((entry) => entry.tag === 'FILE')?.data; // File path - const filename = file && ( file.split('\\').pop() || file.split('/').pop() ); // Extract file name from path + const filename = file && (file.split('\\').pop() || file.split('/').pop()); // Extract file name from path const copr = head.tree.find((entry) => entry.tag === 'COPR')?.data; // Copyright // Reference to submitter const submReference = head.tree.find((entry) => entry.tag === 'SUBM'); - const subm = submReference && dereference(submReference, gedcom, (gedcom) => gedcom.other); + const subm = + submReference && + dereference(submReference, gedcom, (gedcom) => gedcom.other); - const name = subm && subm.tree && subm.tree.find((entry) => entry.tag === 'NAME')?.data; // Submitter name - const phon = subm && subm.tree && subm.tree.find((entry) => entry.tag === 'PHON')?.data; // Phone number - const email = subm && subm.tree && subm.tree.find((entry) => entry.tag === 'EMAIL')?.data; // Email + const name = + subm && subm.tree && subm.tree.find((entry) => entry.tag === 'NAME')?.data; // Submitter name + const phon = + subm && subm.tree && subm.tree.find((entry) => entry.tag === 'PHON')?.data; // Phone number + const email = + subm && subm.tree && subm.tree.find((entry) => entry.tag === 'EMAIL')?.data; // Email - const addr = subm && subm.tree && subm.tree.find((entry) => entry.tag === 'ADDR'); // Address - const adr1 = addr && addr.tree && addr.tree.find((entry) => entry.tag === 'ADR1')?.data; // Street address - const city = addr && addr.tree && addr.tree.find((entry) => entry.tag === 'CITY')?.data; // City - const post = addr && addr.tree && addr.tree.find((entry) => entry.tag === 'POST')?.data; // Postal code + const addr = + subm && subm.tree && subm.tree.find((entry) => entry.tag === 'ADDR'); // Address + const adr1 = + addr && addr.tree && addr.tree.find((entry) => entry.tag === 'ADR1')?.data; // Street address + const city = + addr && addr.tree && addr.tree.find((entry) => entry.tag === 'CITY')?.data; // City + const post = + addr && addr.tree && addr.tree.find((entry) => entry.tag === 'POST')?.data; // Postal code const location = [adr1, post, city].filter(Boolean).join(', '); // Combined location /* Don't show the section if there is no relevant information */ - if (!(sour_name || dateFormatted || filename || copr || name || phon || email || location)) { + if ( + !( + sour_name || + dateFormatted || + filename || + copr || + name || + phon || + email || + location + ) + ) { return null; } // Icons: https://react.semantic-ui.com/elements/icon/ - return ( - <> + return ( + <>
- {sour_name && ( + {sour_name && ( - + {sour_name} )} - + {date && ( - + {dateFormatted} )} {file && ( - + {filename} )} {name && ( - + {name} )} {adr1 && ( - + {location} )} - {phon && ( + {phon && ( - + {phon} )} {email && ( - + {email} )} {copr && ( - + {copr} )} - - ); -} \ No newline at end of file + + ); +}