From 30b4ec33b5b68e65d9307ecabdf7f4cabcab57b9 Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Thu, 28 Nov 2024 13:44:48 +0100 Subject: [PATCH 01/60] chore: import css files to use default TIDO and tailwind css --- src/main.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index d70ec748..62fd4568 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,9 +1,13 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import App from './App.tsx' +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import App from "./App.tsx"; -createRoot(document.getElementById('app')!).render( +import "./css/preflight.scss"; +import "./css/style.css"; +import "./css/style.scss"; + +createRoot(document.getElementById("app")!).render( - , -) + +); From bbf544b73554a166c1f478799dcf2521e65bf7e7 Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Thu, 28 Nov 2024 13:46:07 +0100 Subject: [PATCH 02/60] chore: define a basic default config --- src/config.tsx | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/config.tsx diff --git a/src/config.tsx b/src/config.tsx new file mode 100644 index 00000000..0477e128 --- /dev/null +++ b/src/config.tsx @@ -0,0 +1,31 @@ +const defaultConfig = { + globalTree: true, + urlConfig: {}, + labels: { + item: "Sheet", + manifest: "Manuscript", + }, + colors: { + forceMode: "light", + primary: "#1a3771", + }, + panels: [ + { + index: 0, + collection: + "https://api.ahiqar.sub.uni-goettingen.de/textapi/ahiqar/syriac/collection.json", + }, + { + index: 1, + manifest: + "https://goethes-farbenlehre-berlin.sub.uni-goettingen.de/textapi/Z_1822-02-20_k/manifest.json", + }, + { + index: 2, + manifest: + "https://goethes-farbenlehre-berlin.sub.uni-goettingen.de/textapi/ Z_1829-06-28_k/manifest.json", + }, + ], +}; + +export default defaultConfig; From 1015aa9f8ba3ee0ed1e6f54b67b44d93a478354c Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Thu, 28 Nov 2024 14:04:53 +0100 Subject: [PATCH 03/60] feat: add ConfigContext in the App --- src/App.tsx | 24 +++++++++++++++++++----- src/contexts/ConfigContext.tsx | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/contexts/ConfigContext.tsx diff --git a/src/App.tsx b/src/App.tsx index 5a638c35..6052807d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,23 @@ +import { FC, useEffect, useState } from "react"; +import defaultConfig from "./config"; +import "primeicons/primeicons.css"; +import { ConfigContext } from "./contexts/ConfigContext"; + function App() { + const [config, setConfig] = useState(defaultConfig); + + useEffect(() => {}, []); + return ( - <> -

Hi!

- - ) +
+ +
+ ); } -export default App +export default App; diff --git a/src/contexts/ConfigContext.tsx b/src/contexts/ConfigContext.tsx new file mode 100644 index 00000000..8b02f457 --- /dev/null +++ b/src/contexts/ConfigContext.tsx @@ -0,0 +1,3 @@ +import { createContext } from "react"; + +export const ConfigContext = createContext({}); From 9fad0de1e9643eaab01b259981042317bc8d7067 Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Thu, 28 Nov 2024 14:16:01 +0100 Subject: [PATCH 04/60] chore: use absolute path in the project --- tsconfig.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index f867de0d..6d69320b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,9 @@ "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, + "paths": { + "@/*": ["./*"] + }, /* Bundler mode */ "moduleResolution": "Bundler", @@ -22,5 +25,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["src"] + "include": ["**/*.tsx", "**/*.ts"] } From 6b1ad4a1b7b7210c10870116560c04680735f3f9 Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Thu, 28 Nov 2024 14:54:15 +0100 Subject: [PATCH 05/60] chore: movethe configuration of absolute path to tsconfig.json --- jsconfig.json | 7 +------ tsconfig.json | 11 ++++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/jsconfig.json b/jsconfig.json index 2c8ee2bb..875cb600 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,8 +1,3 @@ { - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["src/*"] - } - } + "compilerOptions": {} } diff --git a/tsconfig.json b/tsconfig.json index 6d69320b..869938ea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,10 +6,6 @@ "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, - "paths": { - "@/*": ["./*"] - }, - /* Bundler mode */ "moduleResolution": "Bundler", "allowImportingTsExtensions": true, @@ -18,6 +14,11 @@ "noEmit": true, "jsx": "react-jsx", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + }, + /* Linting */ "strict": true, "noUnusedLocals": true, @@ -25,5 +26,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["**/*.tsx", "**/*.ts"] + "include": ["./"] } From 72001c8fe3280a9a0ca348fc58542130b39ab930 Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Fri, 29 Nov 2024 10:54:23 +0100 Subject: [PATCH 06/60] feat: add text on each panel for each pre-configured panel --- src/App.tsx | 18 ++++++++- src/components/CustomHTML.tsx | 9 +++++ src/components/PanelsWrapper.tsx | 22 ++++++++++ src/components/panel/Panel.tsx | 69 ++++++++++++++++++++++++++++++++ src/main.tsx | 6 +-- src/utils/http.tsx | 6 +++ src/utils/panel.tsx | 7 ++++ 7 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 src/components/CustomHTML.tsx create mode 100644 src/components/PanelsWrapper.tsx create mode 100644 src/components/panel/Panel.tsx create mode 100644 src/utils/http.tsx create mode 100644 src/utils/panel.tsx diff --git a/src/App.tsx b/src/App.tsx index 6052807d..2dedc211 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,11 +2,21 @@ import { FC, useEffect, useState } from "react"; import defaultConfig from "./config"; import "primeicons/primeicons.css"; import { ConfigContext } from "./contexts/ConfigContext"; +import Panel from "@/components/panel/Panel"; + +import { readApi } from "@/utils/http"; +import PanelsWrapper from "./components/PanelsWrapper"; function App() { const [config, setConfig] = useState(defaultConfig); + const [openedPanels, setOpenedPanels] = useState(defaultConfig.panels); - useEffect(() => {}, []); + function initOpenedPanels(panels) { + setOpenedPanels((prevValue) => panels); + } + useEffect(() => { + initOpenedPanels(config.panels); + }, []); return (
@@ -14,8 +24,12 @@ function App() { value={{ config, setConfig, + openedPanels, }} - > + > + Welcome to TIDO + +
); } diff --git a/src/components/CustomHTML.tsx b/src/components/CustomHTML.tsx new file mode 100644 index 00000000..829976d3 --- /dev/null +++ b/src/components/CustomHTML.tsx @@ -0,0 +1,9 @@ +import React, { useEffect } from "react"; +const CustomHTML = ({ textHtml }) => { + const ref = React.useRef(); + + useEffect(() => (ref.current.outerHTML = textHtml), []); + + return
; +}; +export default CustomHTML; diff --git a/src/components/PanelsWrapper.tsx b/src/components/PanelsWrapper.tsx new file mode 100644 index 00000000..a847af85 --- /dev/null +++ b/src/components/PanelsWrapper.tsx @@ -0,0 +1,22 @@ +import { FC, useState, useEffect, useContext } from "react"; +import { ConfigContext } from "@/contexts/ConfigContext"; +import Panel from "@/components/panel/Panel"; + +import { getPanelUrl } from "@/utils/panel"; + +const PanelsWrapper: FC = ({}) => { + const { config, setConfig, openedPanels } = useContext(ConfigContext); + + const panels = + openedPanels.length > 0 && + openedPanels.map((panel, i) => ( +
+ +
+ )); + useEffect(() => {}, []); + + return
{panels}
; +}; + +export default PanelsWrapper; diff --git a/src/components/panel/Panel.tsx b/src/components/panel/Panel.tsx new file mode 100644 index 00000000..7b8f8396 --- /dev/null +++ b/src/components/panel/Panel.tsx @@ -0,0 +1,69 @@ +import { + FC, + useState, + useEffect, + useContext, + createElement, + Fragment, +} from "react"; +import { ConfigContext } from "@/contexts/ConfigContext"; +import CustomHTML from "@/components/CustomHTML"; + +import { readApi } from "@/utils/http"; + +// TODO: add a Typescript interface for the props types +// prop: url - should be the url of collection or manifest +const Panel: FC = ({ url }) => { + const { config, setConfig } = useContext(ConfigContext); + const [data, setData] = useState(); + const [itemUrl, setItemUrl] = useState(""); + const [text, setText] = useState(); + const [numberTexts, setNumberTexts] = useState(0); + + async function getItemUrl(documentData): string { + // if collection - then we should read the api data from the manifest and get its first sequence item id + // if manifest - we retrieve the first sequence item id + if ("title" in documentData) { + // 'title' in document -> document is collection + const manifestData = await readApi(documentData.sequence[0].id); + return manifestData.sequence[0].id; + } + + if ("label" in documentData) { + return documentData.sequence[0].id; + } + } + + async function readData(url: string) { + const documentData = await readApi(url); + const itemUrl = await getItemUrl(documentData); + const itemData = await readApi(itemUrl); + const itemHtmlUrl = itemData["content"][0]["url"]; + + const textInHtml = await readHtml(itemHtmlUrl); + setText(); + //setText(textInHtml); + // if ("content" in jsonData) setNumberTexts(jsonData["content"].length); + //setData(documentData); + } + + async function readHtml(url: string): Promise { + // url: the url of html file of the item + const data = await fetch(url); + const text = await data.text(); + + return text; + } + useEffect(() => { + // read Api data from url + readData(url); + }, [url]); + + return ( +
+ {text} +
+ ); +}; + +export default Panel; diff --git a/src/main.tsx b/src/main.tsx index 62fd4568..516d7163 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,8 +6,4 @@ import "./css/preflight.scss"; import "./css/style.css"; import "./css/style.scss"; -createRoot(document.getElementById("app")!).render( - - - -); +createRoot(document.getElementById("app")!).render(); diff --git a/src/utils/http.tsx b/src/utils/http.tsx new file mode 100644 index 00000000..ffbb1a30 --- /dev/null +++ b/src/utils/http.tsx @@ -0,0 +1,6 @@ +export async function readApi(url) { + const apiData = await fetch(url); + const data = await apiData.json(); + + return data; +} diff --git a/src/utils/panel.tsx b/src/utils/panel.tsx new file mode 100644 index 00000000..2a700a43 --- /dev/null +++ b/src/utils/panel.tsx @@ -0,0 +1,7 @@ +// get the url of the document (collection or manifest) which will be shown in the panel +export function getPanelUrl(panel) { + if (!("collection" in panel) && !("manifest" in panel)) + console.error("manifest or collection not defined in panel"); + if ("collection" in panel) return panel.collection; + if ("manifest" in panel) return panel.manifest; +} From dca9e888a3e45ce7435d4c08245c6d9b53a65e3e Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Fri, 29 Nov 2024 15:17:48 +0100 Subject: [PATCH 07/60] feat: switch the text tab using buttons toggle --- src/components/CustomHTML.tsx | 4 +- src/components/panel/Panel.tsx | 67 ++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/components/CustomHTML.tsx b/src/components/CustomHTML.tsx index 829976d3..935e49f9 100644 --- a/src/components/CustomHTML.tsx +++ b/src/components/CustomHTML.tsx @@ -2,7 +2,9 @@ import React, { useEffect } from "react"; const CustomHTML = ({ textHtml }) => { const ref = React.useRef(); - useEffect(() => (ref.current.outerHTML = textHtml), []); + useEffect(() => { + ref.current.innerHTML = textHtml; + }, [textHtml]); return
; }; diff --git a/src/components/panel/Panel.tsx b/src/components/panel/Panel.tsx index 7b8f8396..17dc4a83 100644 --- a/src/components/panel/Panel.tsx +++ b/src/components/panel/Panel.tsx @@ -1,11 +1,6 @@ -import { - FC, - useState, - useEffect, - useContext, - createElement, - Fragment, -} from "react"; +import { FC, useState, useEffect, useContext } from "react"; +import { Button } from "primereact/button"; + import { ConfigContext } from "@/contexts/ConfigContext"; import CustomHTML from "@/components/CustomHTML"; @@ -18,6 +13,8 @@ const Panel: FC = ({ url }) => { const [data, setData] = useState(); const [itemUrl, setItemUrl] = useState(""); const [text, setText] = useState(); + const [textTypes, setTextTypes] = useState([]); + const [activeText, setActiveText] = useState(""); const [numberTexts, setNumberTexts] = useState(0); async function getItemUrl(documentData): string { @@ -34,11 +31,29 @@ const Panel: FC = ({ url }) => { } } + function assignTextTypes(itemData: Item) { + let types: string[] = []; + if (!itemData.hasOwnProperty("content")) return; + if (itemData["content"].length === 0) return; + + const content = itemData["content"]; + for (let i = 0; i < content.length; i++) { + types.push(getContentType(content[i].type)); + } + setTextTypes(() => types); + } + + function getContentType(value): string { + if (!value) return ""; + return value.split("type=")[1]; + } + async function readData(url: string) { const documentData = await readApi(url); const itemUrl = await getItemUrl(documentData); const itemData = await readApi(itemUrl); - const itemHtmlUrl = itemData["content"][0]["url"]; + assignTextTypes(itemData); + const itemHtmlUrl = getUrlActiveText(itemData["content"]); //[0]["url"]; const textInHtml = await readHtml(itemHtmlUrl); setText(); @@ -54,13 +69,43 @@ const Panel: FC = ({ url }) => { return text; } + + function handleTextTabClick(e) { + e.preventDefault(); + setActiveText(() => e.target.innerHTML); + } + + function getUrlActiveText(content) { + const activeItemUrl = content.find((item) => + item.type.includes(activeText) + ).url; + return activeItemUrl; + } + + const textTypesButtons = + textTypes.length > 0 && + textTypes.map((type, i) => ( +
{text}
From faf367d4ee73edf56f61be25dfcc8c1726a753ed Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Mon, 2 Dec 2024 10:55:07 +0100 Subject: [PATCH 10/60] chore: add primereact as dev dependency --- package-lock.json | 94 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 ++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c263d26..5eb4e32c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "ncp": "^2.0.0", "openseadragon": "^5.0.0", "postcss-html": "^1.7.0", + "primereact": "^10.8.5", "react": "^18.3.1", "react-dom": "^18.3.1", "sass": "^1.80.6", @@ -274,6 +275,18 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", @@ -1902,6 +1915,15 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", @@ -3582,6 +3604,16 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "dev": true }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -6834,6 +6866,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/primereact": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/primereact/-/primereact-10.8.5.tgz", + "integrity": "sha512-B1LeJdNGGAB8P1VRJE0TDYz6rZSDwxE7Ft8PLFjRYLO44+mIJNDsLYSB56LRJOoqUNRhQrRIe/5ctS5eyQAzwQ==", + "dev": true, + "dependencies": { + "@types/react-transition-group": "^4.4.1", + "react-transition-group": "^4.4.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -6849,6 +6904,17 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", @@ -6969,6 +7035,12 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -6978,6 +7050,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -7148,6 +7236,12 @@ "node": ">=8" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "node_modules/request-progress": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", diff --git a/package.json b/package.json index cfa44260..aff2c4aa 100644 --- a/package.json +++ b/package.json @@ -39,16 +39,17 @@ "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react": "^4.3.3", + "autoprefixer": "^10.4.17", + "cypress": "^13.15.2", "eslint": "^9.14.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", - "autoprefixer": "^10.4.17", - "cypress": "^13.15.2", "globals": "^15.11.0", "http-server": "^14.1.1", "ncp": "^2.0.0", "openseadragon": "^5.0.0", "postcss-html": "^1.7.0", + "primereact": "^10.8.5", "react": "^18.3.1", "react-dom": "^18.3.1", "sass": "^1.80.6", From 8463aae172e596d963a26558edeec4c9a000100a Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Mon, 2 Dec 2024 10:55:25 +0100 Subject: [PATCH 11/60] chore: remove the import of primeicons --- src/App.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 2dedc211..c2dc9869 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,5 @@ import { FC, useEffect, useState } from "react"; import defaultConfig from "./config"; -import "primeicons/primeicons.css"; import { ConfigContext } from "./contexts/ConfigContext"; import Panel from "@/components/panel/Panel"; From a7490635970068022616078daaa040dc68317e23 Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Mon, 2 Dec 2024 15:47:00 +0100 Subject: [PATCH 12/60] chore: configure 'single' quotes in eslint config file --- eslint.config.js | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 092408a9..5edcfdde 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,28 +1,36 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; export default tseslint.config( - { ignores: ['dist'] }, + { ignores: ["dist"] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], + files: ["**/*.{ts,tsx}"], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, + "react-hooks": reactHooks, + "react-refresh": reactRefresh, }, rules: { ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', + "react-refresh/only-export-components": [ + "warn", { allowConstantExport: true }, ], + "@/quotes": [ + "error", + "single", + { + avoidEscape: true, + allowTemplateLiterals: true, + }, + ], }, - }, -) + } +); From 3321f4ec0ea2350dd372f74be7cb2220cd10f79b Mon Sep 17 00:00:00 2001 From: orlinmalkja Date: Mon, 2 Dec 2024 15:47:55 +0100 Subject: [PATCH 13/60] style: convert the 'double' to 'single' quotes --- src/App.tsx | 12 +++++------ src/components/CustomHTML.tsx | 2 +- src/components/PanelsWrapper.tsx | 3 +-- src/components/panel/Panel.tsx | 34 ++++++++++++++---------------- src/components/panel/TextTypes.tsx | 8 +++---- src/config.tsx | 14 ++++++------ src/contexts/ConfigContext.tsx | 2 +- src/main.tsx | 14 ++++++------ src/utils/panel.tsx | 8 +++---- 9 files changed, 47 insertions(+), 50 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c2dc9869..861f8baa 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,10 @@ -import { FC, useEffect, useState } from "react"; -import defaultConfig from "./config"; -import { ConfigContext } from "./contexts/ConfigContext"; -import Panel from "@/components/panel/Panel"; +import { FC, useEffect, useState } from 'react'; +import defaultConfig from './config'; +import { ConfigContext } from './contexts/ConfigContext'; +import Panel from '@/components/panel/Panel'; -import { readApi } from "@/utils/http"; -import PanelsWrapper from "./components/PanelsWrapper"; +import { readApi } from '@/utils/http'; +import PanelsWrapper from './components/PanelsWrapper'; function App() { const [config, setConfig] = useState(defaultConfig); diff --git a/src/components/CustomHTML.tsx b/src/components/CustomHTML.tsx index 935e49f9..2767ee61 100644 --- a/src/components/CustomHTML.tsx +++ b/src/components/CustomHTML.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect } from 'react'; const CustomHTML = ({ textHtml }) => { const ref = React.useRef(); diff --git a/src/components/PanelsWrapper.tsx b/src/components/PanelsWrapper.tsx index a847af85..2dda5dc8 100644 --- a/src/components/PanelsWrapper.tsx +++ b/src/components/PanelsWrapper.tsx @@ -5,7 +5,7 @@ import Panel from "@/components/panel/Panel"; import { getPanelUrl } from "@/utils/panel"; const PanelsWrapper: FC = ({}) => { - const { config, setConfig, openedPanels } = useContext(ConfigContext); + const { openedPanels } = useContext(ConfigContext); const panels = openedPanels.length > 0 && @@ -14,7 +14,6 @@ const PanelsWrapper: FC = ({}) => { )); - useEffect(() => {}, []); return
{panels}
; }; diff --git a/src/components/panel/Panel.tsx b/src/components/panel/Panel.tsx index 16fe2681..cc83d332 100644 --- a/src/components/panel/Panel.tsx +++ b/src/components/panel/Panel.tsx @@ -1,42 +1,40 @@ -import { FC, useState, useEffect, useContext } from "react"; -import { Button } from "primereact/button"; +import { FC, useState, useEffect, useContext } from 'react'; +import { Button } from 'primereact/button'; -import { ConfigContext } from "@/contexts/ConfigContext"; -import CustomHTML from "@/components/CustomHTML"; -import TextTypes from "@/components/panel/TextTypes"; +import { ConfigContext } from '@/contexts/ConfigContext'; +import CustomHTML from '@/components/CustomHTML'; +import TextTypes from '@/components/panel/TextTypes'; -import { readApi } from "@/utils/http"; +import { readApi } from '@/utils/http'; // TODO: add a Typescript interface for the props types // prop: url - should be the url of collection or manifest const Panel: FC = ({ url }) => { const { config, setConfig } = useContext(ConfigContext); - const [data, setData] = useState(); - const [itemUrl, setItemUrl] = useState(""); const [text, setText] = useState(); const [textTypes, setTextTypes] = useState([]); - const [activeText, setActiveText] = useState(""); + const [activeText, setActiveText] = useState(''); async function getItemUrl(documentData): string { // if collection - then we should read the api data from the manifest and get its first sequence item id // if manifest - we retrieve the first sequence item id - if ("title" in documentData) { + if ('title' in documentData) { // 'title' in document -> document is collection const manifestData = await readApi(documentData.sequence[0].id); return manifestData.sequence[0].id; } - if ("label" in documentData) { + if ('label' in documentData) { return documentData.sequence[0].id; } } function assignTextTypes(itemData: Item) { - let types: string[] = []; - if (!itemData.hasOwnProperty("content")) return; - if (itemData["content"].length === 0) return; + const types: string[] = []; + if (!itemData.hasOwnProperty('content')) return; + if (itemData['content'].length === 0) return; - const content = itemData["content"]; + const content = itemData['content']; for (let i = 0; i < content.length; i++) { types.push(getContentType(content[i].type)); } @@ -44,8 +42,8 @@ const Panel: FC = ({ url }) => { } function getContentType(value): string { - if (!value) return ""; - return value.split("type=")[1]; + if (!value) return ''; + return value.split('type=')[1]; } async function readData(url: string) { @@ -53,7 +51,7 @@ const Panel: FC = ({ url }) => { const itemUrl = await getItemUrl(documentData); const itemData = await readApi(itemUrl); assignTextTypes(itemData); - const itemHtmlUrl = getUrlActiveText(itemData["content"]); + const itemHtmlUrl = getUrlActiveText(itemData['content']); const textInHtml = await readHtml(itemHtmlUrl); setText(); diff --git a/src/components/panel/TextTypes.tsx b/src/components/panel/TextTypes.tsx index cbc72a0f..8d31a9a5 100644 --- a/src/components/panel/TextTypes.tsx +++ b/src/components/panel/TextTypes.tsx @@ -1,6 +1,6 @@ -import { FC, useState, useEffect, useContext } from "react"; -import { ConfigContext } from "@/contexts/ConfigContext"; -import { Button } from "primereact/button"; +import { FC, useState, useEffect, useContext } from 'react'; +import { ConfigContext } from '@/contexts/ConfigContext'; +import { Button } from 'primereact/button'; const TextTypes: FC = ({ textTypes, activeText, setActiveText }) => { const { config, setConfig, openedPanels } = useContext(ConfigContext); @@ -15,7 +15,7 @@ const TextTypes: FC = ({ textTypes, activeText, setActiveText }) => { textTypes.map((type, i) => (