Upgrade prettier and fix files

This commit is contained in:
Przemek Więch
2026-04-28 23:51:29 +02:00
parent 03f118b7fa
commit 51e5d2740d
7 changed files with 286 additions and 256 deletions

58
package-lock.json generated
View File

@@ -77,7 +77,7 @@
"gh-pages": "^6.3.0", "gh-pages": "^6.3.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
"prettier": "^3.4.2", "prettier": "^3.8.3",
"prettier-plugin-organize-imports": "^4.1.0", "prettier-plugin-organize-imports": "^4.1.0",
"run-script-os": "^1.1.6", "run-script-os": "^1.1.6",
"start-server-and-test": "^2.0.9", "start-server-and-test": "^2.0.9",
@@ -10571,10 +10571,11 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.4.2", "version": "3.8.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/prettier/-/prettier-3.8.3.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
"dev": true, "dev": true,
"license": "MIT",
"bin": { "bin": {
"prettier": "bin/prettier.cjs" "prettier": "bin/prettier.cjs"
}, },
@@ -12615,7 +12616,7 @@
"version": "5.7.3", "version": "5.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"devOptional": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@@ -13430,8 +13431,7 @@
"@artsy/fresnel": { "@artsy/fresnel": {
"version": "6.2.1", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/@artsy/fresnel/-/fresnel-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@artsy/fresnel/-/fresnel-6.2.1.tgz",
"integrity": "sha512-UAyHZU64Vie3sLDdL3qD+7pODGzKNu9pSpxGKpDOCaiBvCDZnFXIfJEEfV9v9i+QiJJwzO+lqsFwvw6YiJeXFQ==", "integrity": "sha512-UAyHZU64Vie3sLDdL3qD+7pODGzKNu9pSpxGKpDOCaiBvCDZnFXIfJEEfV9v9i+QiJJwzO+lqsFwvw6YiJeXFQ=="
"requires": {}
}, },
"@asamuzakjp/css-color": { "@asamuzakjp/css-color": {
"version": "2.8.3", "version": "2.8.3",
@@ -13986,8 +13986,7 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz", "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz",
"integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==", "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==",
"dev": true, "dev": true
"requires": {}
}, },
"@csstools/css-color-parser": { "@csstools/css-color-parser": {
"version": "3.0.7", "version": "3.0.7",
@@ -14003,8 +14002,7 @@
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
"integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
"dev": true, "dev": true
"requires": {}
}, },
"@csstools/css-tokenizer": { "@csstools/css-tokenizer": {
"version": "3.0.3", "version": "3.0.3",
@@ -15331,8 +15329,7 @@
"version": "18.3.5", "version": "18.3.5",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz",
"integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==",
"dev": true, "dev": true
"requires": {}
}, },
"@types/semver": { "@types/semver": {
"version": "7.7.1", "version": "7.7.1",
@@ -15561,8 +15558,7 @@
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true, "dev": true
"requires": {}
}, },
"acorn-walk": { "acorn-walk": {
"version": "8.3.4", "version": "8.3.4",
@@ -17116,8 +17112,7 @@
"version": "1.5.3", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
"integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
"dev": true, "dev": true
"requires": {}
}, },
"deep-is": { "deep-is": {
"version": "0.1.4", "version": "0.1.4",
@@ -19527,8 +19522,7 @@
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
"dev": true, "dev": true
"requires": {}
}, },
"jest-regex-util": { "jest-regex-util": {
"version": "29.6.3", "version": "29.6.3",
@@ -20937,17 +20931,16 @@
"dev": true "dev": true
}, },
"prettier": { "prettier": {
"version": "3.4.2", "version": "3.8.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", "resolved": "https://us-npm.pkg.dev/artifact-foundry-prod/ah-3p-staging-npm/prettier/-/prettier-3.8.3.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
"dev": true "dev": true
}, },
"prettier-plugin-organize-imports": { "prettier-plugin-organize-imports": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz", "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz",
"integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==", "integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==",
"dev": true, "dev": true
"requires": {}
}, },
"pretty-bytes": { "pretty-bytes": {
"version": "5.6.0", "version": "5.6.0",
@@ -22059,8 +22052,7 @@
"version": "6.4.6", "version": "6.4.6",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true, "dev": true
"requires": {}
}, },
"picomatch": { "picomatch": {
"version": "4.0.4", "version": "4.0.4",
@@ -22369,7 +22361,7 @@
"version": "5.7.3", "version": "5.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"devOptional": true "dev": true
}, },
"uc.micro": { "uc.micro": {
"version": "1.0.6", "version": "1.0.6",
@@ -22572,8 +22564,7 @@
"version": "6.4.6", "version": "6.4.6",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true, "dev": true
"requires": {}
}, },
"picomatch": { "picomatch": {
"version": "4.0.4", "version": "4.0.4",
@@ -22598,8 +22589,7 @@
"version": "3.1.4", "version": "3.1.4",
"resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.4.tgz", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.4.tgz",
"integrity": "sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==", "integrity": "sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==",
"dev": true, "dev": true
"requires": {}
} }
} }
}, },
@@ -22797,8 +22787,7 @@
"version": "8.18.0", "version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"dev": true, "dev": true
"requires": {}
}, },
"xml-name-validator": { "xml-name-validator": {
"version": "5.0.0", "version": "5.0.0",
@@ -22877,8 +22866,7 @@
"version": "4.0.2", "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", "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==", "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
"dev": true, "dev": true
"requires": {}
}, },
"zwitch": { "zwitch": {
"version": "2.0.4", "version": "2.0.4",

View File

@@ -72,7 +72,7 @@
"gh-pages": "^6.3.0", "gh-pages": "^6.3.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
"prettier": "^3.4.2", "prettier": "^3.8.3",
"prettier-plugin-organize-imports": "^4.1.0", "prettier-plugin-organize-imports": "^4.1.0",
"run-script-os": "^1.1.6", "run-script-os": "^1.1.6",
"start-server-and-test": "^2.0.9", "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: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 }", "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", "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", "lint": "eslint src --ext .ts,.tsx",
"predeploy": "npm run build", "predeploy": "npm run build",
"deploy": "gh-pages -d dist", "deploy": "gh-pages -d dist",

View File

@@ -1,8 +1,8 @@
import {SourceHead} from '../head/head';
import {GedcomData} from '../../util/gedcom_util';
import {ParsedQuery} from 'query-string'; import {ParsedQuery} from 'query-string';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import {Checkbox, Form, Header, Item} from 'semantic-ui-react'; import {Checkbox, Form, Header, Item} from 'semantic-ui-react';
import {GedcomData} from '../../util/gedcom_util';
import {SourceHead} from '../head/head';
export enum ChartColors { export enum ChartColors {
NO_COLOR, NO_COLOR,
@@ -82,158 +82,169 @@ export function ConfigPanel(props: {
}) { }) {
return ( return (
<> <>
{SourceHead(props.gedcom)}<Form className="details"> {SourceHead(props.gedcom)}
<Item.Group> <Form className="details">
<Item> <Item.Group>
<Item.Content> <Item>
<Header sub> <Item.Content>
<FormattedMessage id="config.colors" defaultMessage="Colors" /> <Header sub>
</Header> <FormattedMessage id="config.colors" defaultMessage="Colors" />
<Form.Field className="no-margin"> </Header>
<Checkbox <Form.Field className="no-margin">
radio <Checkbox
label={ radio
<FormattedMessage label={
tagName="label" <FormattedMessage
id="config.colors.NO_COLOR" tagName="label"
defaultMessage="none" id="config.colors.NO_COLOR"
/> defaultMessage="none"
} />
name="checkboxRadioGroup" }
value="none" name="checkboxRadioGroup"
checked={props.config.color === ChartColors.NO_COLOR} value="none"
onClick={() => checked={props.config.color === ChartColors.NO_COLOR}
props.onChange({ onClick={() =>
...props.config, props.onChange({
color: ChartColors.NO_COLOR, ...props.config,
}) color: ChartColors.NO_COLOR,
} })
/> }
</Form.Field> />
<Form.Field className="no-margin"> </Form.Field>
<Checkbox <Form.Field className="no-margin">
radio <Checkbox
label={ radio
<FormattedMessage label={
tagName="label" <FormattedMessage
id="config.colors.COLOR_BY_GENERATION" tagName="label"
defaultMessage="by generation" id="config.colors.COLOR_BY_GENERATION"
/> defaultMessage="by generation"
} />
name="checkboxRadioGroup" }
value="generation" name="checkboxRadioGroup"
checked={props.config.color === ChartColors.COLOR_BY_GENERATION} value="generation"
onClick={() => checked={
props.onChange({ props.config.color === ChartColors.COLOR_BY_GENERATION
...props.config, }
color: ChartColors.COLOR_BY_GENERATION, onClick={() =>
}) props.onChange({
} ...props.config,
/> color: ChartColors.COLOR_BY_GENERATION,
</Form.Field> })
<Form.Field className="no-margin"> }
<Checkbox />
radio </Form.Field>
label={ <Form.Field className="no-margin">
<FormattedMessage <Checkbox
tagName="label" radio
id="config.colors.COLOR_BY_SEX" label={
defaultMessage="by sex" <FormattedMessage
/> tagName="label"
} id="config.colors.COLOR_BY_SEX"
name="checkboxRadioGroup" defaultMessage="by sex"
value="gender" />
checked={props.config.color === ChartColors.COLOR_BY_SEX} }
onClick={() => name="checkboxRadioGroup"
props.onChange({ value="gender"
...props.config, checked={props.config.color === ChartColors.COLOR_BY_SEX}
color: ChartColors.COLOR_BY_SEX, onClick={() =>
}) props.onChange({
} ...props.config,
/> color: ChartColors.COLOR_BY_SEX,
</Form.Field> })
</Item.Content> }
</Item> />
<Item> </Form.Field>
<Item.Content> </Item.Content>
<Header sub> </Item>
<FormattedMessage id="config.ids" defaultMessage="IDs" /> <Item>
</Header> <Item.Content>
<Form.Field className="no-margin"> <Header sub>
<Checkbox <FormattedMessage id="config.ids" defaultMessage="IDs" />
radio </Header>
label={ <Form.Field className="no-margin">
<FormattedMessage <Checkbox
tagName="label" radio
id="config.ids.HIDE" label={
defaultMessage="hide" <FormattedMessage
/> tagName="label"
} id="config.ids.HIDE"
name="checkboxRadioGroup" defaultMessage="hide"
value="hide" />
checked={props.config.id === Ids.HIDE} }
onClick={() => props.onChange({...props.config, id: Ids.HIDE})} name="checkboxRadioGroup"
/> value="hide"
</Form.Field> checked={props.config.id === Ids.HIDE}
<Form.Field className="no-margin"> onClick={() =>
<Checkbox props.onChange({...props.config, id: Ids.HIDE})
radio }
label={ />
<FormattedMessage </Form.Field>
tagName="label" <Form.Field className="no-margin">
id="config.ids.SHOW" <Checkbox
defaultMessage="show" radio
/> label={
} <FormattedMessage
name="checkboxRadioGroup" tagName="label"
value="show" id="config.ids.SHOW"
checked={props.config.id === Ids.SHOW} defaultMessage="show"
onClick={() => props.onChange({...props.config, id: Ids.SHOW})} />
/> }
</Form.Field> name="checkboxRadioGroup"
</Item.Content> value="show"
</Item> checked={props.config.id === Ids.SHOW}
<Item> onClick={() =>
<Item.Content> props.onChange({...props.config, id: Ids.SHOW})
<Header sub> }
<FormattedMessage id="config.sex" defaultMessage="Sex" /> />
</Header> </Form.Field>
<Form.Field className="no-margin"> </Item.Content>
<Checkbox </Item>
radio <Item>
label={ <Item.Content>
<FormattedMessage <Header sub>
tagName="label" <FormattedMessage id="config.sex" defaultMessage="Sex" />
id="config.sex.HIDE" </Header>
defaultMessage="hide" <Form.Field className="no-margin">
/> <Checkbox
} radio
name="checkboxRadioGroup" label={
value="hide" <FormattedMessage
checked={props.config.sex === Sex.HIDE} tagName="label"
onClick={() => props.onChange({...props.config, sex: Sex.HIDE})} id="config.sex.HIDE"
/> defaultMessage="hide"
</Form.Field> />
<Form.Field className="no-margin"> }
<Checkbox name="checkboxRadioGroup"
radio value="hide"
label={ checked={props.config.sex === Sex.HIDE}
<FormattedMessage onClick={() =>
tagName="label" props.onChange({...props.config, sex: Sex.HIDE})
id="config.sex.SHOW" }
defaultMessage="show" />
/> </Form.Field>
} <Form.Field className="no-margin">
name="checkboxRadioGroup" <Checkbox
value="show" radio
checked={props.config.sex === Sex.SHOW} label={
onClick={() => props.onChange({...props.config, sex: Sex.SHOW})} <FormattedMessage
/> tagName="label"
</Form.Field> id="config.sex.SHOW"
</Item.Content> defaultMessage="show"
</Item> />
</Item.Group> }
</Form> name="checkboxRadioGroup"
value="show"
checked={props.config.sex === Sex.SHOW}
onClick={() =>
props.onChange({...props.config, sex: Sex.SHOW})
}
/>
</Form.Field>
</Item.Content>
</Item>
</Item.Group>
</Form>
</> </>
); );
} }

View File

@@ -25,7 +25,7 @@ export function AdditionalFiles({files}: Props) {
</a> </a>
</List.Header> </List.Header>
<List.Description> <List.Description>
{file.titl && <div>{file.titl}</div>} {file.titl && <div>{file.titl}</div>}
</List.Description> </List.Description>
</List.Content> </List.Content>
</List.Item> </List.Item>

View File

@@ -11,13 +11,13 @@ import {
getNonImageFileEntry, getNonImageFileEntry,
mapToSource, mapToSource,
} from '../../util/gedcom_util'; } 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 {ALL_SUPPORTED_EVENT_TYPES, Events} from './events';
import {MultilineText} from './multiline-text'; import {MultilineText} from './multiline-text';
import {Sources} from './sources'; import {Sources} from './sources';
import {TranslatedTag} from './translated-tag'; import {TranslatedTag} from './translated-tag';
import {WrappedImage} from './wrapped-image'; import {WrappedImage} from './wrapped-image';
import {Config, Ids} from '../config/config';
const EXCLUDED_TAGS = [ const EXCLUDED_TAGS = [
...ALL_SUPPORTED_EVENT_TYPES, ...ALL_SUPPORTED_EVENT_TYPES,
@@ -61,32 +61,30 @@ function attributeDetails(entry: GedcomEntry) {
} }
const attributeName = entry.tree const attributeName = entry.tree
.filter((subentry) => subentry.tag === 'TYPE') .filter((subentry) => subentry.tag === 'TYPE')
.flatMap((type) => getData(type)) .flatMap((type) => getData(type))
.join() .join()
.trim(); .trim();
const attributeValue = getData(entry).join(' ').trim(); const attributeValue = getData(entry).join(' ').trim();
if(attributeName) { if (attributeName) {
return ( return (
<> <>
<Header sub> <Header sub>
<TranslatedTag tag={entry.tag}/> <TranslatedTag tag={entry.tag} />
</Header> </Header>
<div> <div>
<b>{attributeName}</b>: {attributeValue} <b>{attributeName}</b>: {attributeValue}
</div> </div>
</> </>
); );
} else { } else {
return ( return (
<> <>
<Header sub> <Header sub>
<TranslatedTag tag={entry.tag}/> <TranslatedTag tag={entry.tag} />
</Header> </Header>
<div> <div>{attributeValue}</div>
{attributeValue}
</div>
</> </>
); );
} }
@@ -142,7 +140,9 @@ function sourceDetails(
function fileDetails(objectEntries: GedcomEntry[], gedcom: GedcomData) { function fileDetails(objectEntries: GedcomEntry[], gedcom: GedcomData) {
const files: FileEntry[] = []; const files: FileEntry[] = [];
objectEntries objectEntries
.map((objectEntry) => dereference(objectEntry, gedcom, (gedcom) => gedcom.other)) .map((objectEntry) =>
dereference(objectEntry, gedcom, (gedcom) => gedcom.other),
)
.forEach((objectEntry) => { .forEach((objectEntry) => {
const fileEntry = getNonImageFileEntry(objectEntry); const fileEntry = getNonImageFileEntry(objectEntry);
if (fileEntry) { if (fileEntry) {
@@ -150,7 +150,7 @@ function fileDetails(objectEntries: GedcomEntry[], gedcom: GedcomData) {
url: fileEntry.data, url: fileEntry.data,
filename: getFileName(fileEntry), filename: getFileName(fileEntry),
titl: objectEntry.tree.find((entry) => entry.tag === 'TITL')?.data, 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 ( return (
<Item> <Item>
<Item.Content> <Item.Content>
<Header sub> <Header sub>
<FormattedMessage id="config.ids" defaultMessage="Identification" /> <FormattedMessage id="config.ids" defaultMessage="Identification" />
</Header> </Header>
<div><i>{indi}</i></div> <div>
<i>{indi}</i>
</div>
</Item.Content> </Item.Content>
</Item> </Item>
); );
@@ -354,10 +356,10 @@ export function Details(props: Props) {
<Events gedcom={props.gedcom} entries={entries} indi={props.indi} /> <Events gedcom={props.gedcom} entries={entries} indi={props.indi} />
{props.config.id === Ids.SHOW ? getSectionForId(props.indi) : null} {props.config.id === Ids.SHOW ? getSectionForId(props.indi) : null}
{getSectionForEachMatchingEntry( {getSectionForEachMatchingEntry(
entries, entries,
props.gedcom, props.gedcom,
['FACT'], ['FACT'],
attributeDetails, attributeDetails,
)} )}
{getOtherSections(entries, props.gedcom)} {getOtherSections(entries, props.gedcom)}
{getSectionForEachMatchingEntry( {getSectionForEachMatchingEntry(

View File

@@ -11,8 +11,17 @@ interface Props {
export function LinkifyNewTab({children}: Props) { export function LinkifyNewTab({children}: Props) {
return ( return (
<Linkify <Linkify
componentDecorator={(decoratedHref: string, decoratedText: string, key: number) => ( componentDecorator={(
<a href={decoratedHref} key={key} target="_blank" rel="noopener noreferrer"> decoratedHref: string,
decoratedText: string,
key: number,
) => (
<a
href={decoratedHref}
key={key}
target="_blank"
rel="noopener noreferrer"
>
{decoratedText} {decoratedText}
</a> </a>
)} )}

View File

@@ -1,108 +1,128 @@
import {
dereference,
GedcomData,
} from '../../util/gedcom_util';
import {FormattedMessage, useIntl} from 'react-intl'; 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 {getDate} from 'topola';
import {formatDateOrRange} from '../../util/date_util'; 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; const head = gedcom.head;
/* Don't show the section if there is no relevant information */ /* Don't show the section if there is no relevant information */
if (!head || !head.tree) { if (!head || !head.tree) {
return null; return null;
} }
const sour = head.tree.find((entry) => entry.tag === 'SOUR'); 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 date = head.tree.find((entry) => entry.tag === 'DATE'); // Creation date
const intl = useIntl(); 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 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 const copr = head.tree.find((entry) => entry.tag === 'COPR')?.data; // Copyright
// Reference to submitter // Reference to submitter
const submReference = head.tree.find((entry) => entry.tag === 'SUBM'); 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 name =
const phon = subm && subm.tree && subm.tree.find((entry) => entry.tag === 'PHON')?.data; // Phone number subm && subm.tree && subm.tree.find((entry) => entry.tag === 'NAME')?.data; // Submitter name
const email = subm && subm.tree && subm.tree.find((entry) => entry.tag === 'EMAIL')?.data; // Email 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 addr =
const adr1 = addr && addr.tree && addr.tree.find((entry) => entry.tag === 'ADR1')?.data; // Street address subm && subm.tree && subm.tree.find((entry) => entry.tag === 'ADDR'); // Address
const city = addr && addr.tree && addr.tree.find((entry) => entry.tag === 'CITY')?.data; // City const adr1 =
const post = addr && addr.tree && addr.tree.find((entry) => entry.tag === 'POST')?.data; // Postal code 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 const location = [adr1, post, city].filter(Boolean).join(', '); // Combined location
/* Don't show the section if there is no relevant information */ /* 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; return null;
} }
// Icons: https://react.semantic-ui.com/elements/icon/ // Icons: https://react.semantic-ui.com/elements/icon/
return ( return (
<> <>
<Header sub> <Header sub>
<FormattedMessage id="head.source" defaultMessage="Data source" /> <FormattedMessage id="head.source" defaultMessage="Data source" />
</Header> </Header>
<List> <List>
{sour_name && ( {sour_name && (
<List.Item> <List.Item>
<List.Icon name='edit' /> <List.Icon name="edit" />
<List.Content>{sour_name}</List.Content> <List.Content>{sour_name}</List.Content>
</List.Item> </List.Item>
)} )}
{date && ( {date && (
<List.Item> <List.Item>
<List.Icon name='calendar' /> <List.Icon name="calendar" />
<List.Content>{dateFormatted}</List.Content> <List.Content>{dateFormatted}</List.Content>
</List.Item> </List.Item>
)} )}
{file && ( {file && (
<List.Item> <List.Item>
<List.Icon name='file' /> <List.Icon name="file" />
<List.Content>{filename}</List.Content> <List.Content>{filename}</List.Content>
</List.Item> </List.Item>
)} )}
{name && ( {name && (
<List.Item> <List.Item>
<List.Icon name='user' /> <List.Icon name="user" />
<List.Content>{name}</List.Content> <List.Content>{name}</List.Content>
</List.Item> </List.Item>
)} )}
{adr1 && ( {adr1 && (
<List.Item> <List.Item>
<List.Icon name='marker' /> <List.Icon name="marker" />
<List.Content>{location}</List.Content> <List.Content>{location}</List.Content>
</List.Item> </List.Item>
)} )}
{phon && ( {phon && (
<List.Item> <List.Item>
<List.Icon name='phone' /> <List.Icon name="phone" />
<List.Content>{phon}</List.Content> <List.Content>{phon}</List.Content>
</List.Item> </List.Item>
)} )}
{email && ( {email && (
<List.Item> <List.Item>
<List.Icon name='mail' /> <List.Icon name="mail" />
<List.Content>{email}</List.Content> <List.Content>{email}</List.Content>
</List.Item> </List.Item>
)} )}
{copr && ( {copr && (
<List.Item> <List.Item>
<List.Icon name='copyright' /> <List.Icon name="copyright" />
<List.Content>{copr}</List.Content> <List.Content>{copr}</List.Content>
</List.Item> </List.Item>
)} )}
</List> </List>
<Divider /> <Divider />
</> </>
); );
} }