Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: build.yml
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v7
- name: Use Node.js
uses: actions/setup-node@v7
with:
node-version: "24.x"
cache: "npm"
- name: Install
run: npm ci --ignore-scripts
- name: Prettier Check
run: npm run prettier:check
- name: Build
run: npm run-script build
env:
CI: ""
21 changes: 21 additions & 0 deletions src/api/TermAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { useQuery } from "react-query";
import {
getPropertyRelationsQuery,
getTermRelationsQuery,
getTermSkosRelationsQuery,
getTermTypeQuery,
TermBaseInterface,
TermInterface,
TermRelationsInterface,
Terms,
TermSkosRelationsInterface,
TermsRelationsResource,
TermsSkosRelationsResource,
TermsTypes,
} from "./data/terms";
import { HIDDEN_VOCABULARY } from "./data/vocabularies";
Expand Down Expand Up @@ -56,6 +59,17 @@ export const getRelations = async (
}
};

export const getSkosRelations = async (
term: TermInterface | undefined
): Promise<TermSkosRelationsInterface[]> => {
if (typeof term === "undefined") {
return Promise.reject("Invalid term");
}
return await TermsSkosRelationsResource.query(
getTermSkosRelationsQuery(term.$id)
);
};

export type RelationResult = ReturnType<typeof getRelations> extends Promise<
(infer U)[]
>
Expand All @@ -79,3 +93,10 @@ export const useRelations = (term: TermInterface | undefined) => {
notifyOnChangeProps: ["data", "isError"],
});
};

export const useSkosRelations = (term: TermInterface | undefined) => {
return useQuery(["skos-relations", term?.$id], () => getSkosRelations(term), {
enabled: !!term,
notifyOnChangeProps: ["data", "isError"],
});
};
42 changes: 42 additions & 0 deletions src/api/data/terms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ export const TermBaseSchema = {
"@id": skos.definition,
"@optional": true,
},
notation: {
"@id": skos.notation,
"@optional": true,
"@array": true,
},
} as const;

const TermSchema = {
Expand Down Expand Up @@ -91,10 +96,23 @@ const TermTypesSchema = {
},
} as const;

const TermSkosRelationsSchema = {
"@type": skos.Concept,
related: {
"@id": skos.related,
"@array": true,
"@context": RelationItemSchema,
},
} as const;

export type TermRelationsInterface = SchemaInterface<
typeof TermRelationsSchema
>;

export type TermSkosRelationsInterface = SchemaInterface<
typeof TermSkosRelationsSchema
>;

export type TermInterface = SchemaInterface<typeof TermSchema>;

export type TermBaseInterface = SchemaInterface<typeof TermBaseSchema>;
Expand All @@ -107,6 +125,11 @@ export const TermsRelationsResource = createResource(
context
);

export const TermsSkosRelationsResource = createResource(
TermSkosRelationsSchema,
context
);

export const getTermRelationsQuery = (termIri: string) => {
const query = $`
CONSTRUCT{
Expand Down Expand Up @@ -266,3 +289,22 @@ WHERE {

return query;
};

export const getTermSkosRelationsQuery = (termIri: string) => {
return $`
CONSTRUCT {
?term a ${n(skos.Concept)} ; a ${n(ldkit.Resource)} .
?term ${n(skos.related)} ?related .
?related ${n(skos.prefLabel)} ?relatedLabel .
?related ${n(popisDat["je-pojmem-ze-slovníku"])} ?relatedVocabulary .
?relatedVocabulary ${n(dcterms.title)} ?relatedVocabularyTitle .
} WHERE {
BIND(${n(termIri)} as ?term)
?term (${n(skos.related)}|${n(skos.relatedMatch)}) ?related .
?related ${n(skos.prefLabel)} ?relatedLabel .
?related ${n(popisDat["je-pojmem-ze-slovníku"])} ?relatedVocabulary .
?relatedVocabulary ${n(dcterms.title)} ?relatedVocabularyTitle .
FILTER (?relatedVocabulary != ${n(HIDDEN_VOCABULARY)})
}
`.toString();
};
4 changes: 2 additions & 2 deletions src/components/detail_common/DetailPageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { ReactElement } from "react";
import React, { ReactElement, ReactNode } from "react";
import { Box, Container, Grid, Typography } from "@mui/material";
import IRI from "./IRI";

interface DetailPageHeaderProps {
aboveLabel: ReactElement;
label: string;
label: ReactNode;
belowLabel?: ReactElement;
iri: string;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/terms/Hierarchy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const Hierarchy: React.FC<HierarchyProps> = ({ term }) => {
<Box py={2} mb={2} px={2} mt={4}>
<Box borderLeft={4} pr={6} borderColor="primary.main">
<Box pl={4}>
<Typography variant="h5">Související pojmy</Typography>
<Typography variant="h5">Hierarchie</Typography>
</Box>
<Box pl={2}>
<HierarchyParents
Expand Down
12 changes: 12 additions & 0 deletions src/components/terms/Notations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import { Chip } from "@mui/material";

export const Notations: React.FC<{ notation: string[] }> = ({ notation }) => {
return (
<>
{notation.map((n) => (
<Chip label={n} variant="outlined" color="secondary" />
))}
</>
);
};
6 changes: 5 additions & 1 deletion src/components/terms/Relations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ const Relations: React.FC<RelationsProperty> = ({ term }) => {
);
}

return <DetailItemWrapper title="Vztahy">{content}</DetailItemWrapper>;
return (
<DetailItemWrapper title="Vymodelované vztahy">
{content}
</DetailItemWrapper>
);
}
return null;
};
Expand Down
37 changes: 37 additions & 0 deletions src/components/terms/SkosRelations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";
import { TermInterface } from "../../api/data/terms";
import { useSkosRelations } from "../../api/TermAPI";
import Loader from "../Loader";
import { isTermEmpty } from "../../utils/TermUtils";
import EmptyTerm from "./EmptyTerm";
import { RelationItem } from "./RelationItem";
import { DetailItemWrapper } from "./Hierarchy";
import { TermBox } from "./TermRelations";

export const SkosRelations: React.FC<{ term: TermInterface }> = ({ term }) => {
const { data, isLoading, isSuccess } = useSkosRelations(term);

if (isLoading) {
return <Loader />;
}
if (isTermEmpty(term) && data?.length === 0) {
return <EmptyTerm />;
}
if (data?.length === 0 || data === undefined || !isSuccess) {
return null;
}

return (
<DetailItemWrapper title="Související pojmy">
{data[0].related.map((item) => (
<TermBox>
<RelationItem
data={item}
key={item.$id}
showVocabulary={term.vocabulary.$id !== item.vocabulary.$id}
/>
</TermBox>
))}
</DetailItemWrapper>
);
};
18 changes: 16 additions & 2 deletions src/components/terms/TermHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React from "react";
import { Box } from "@mui/material";
import AltLabel from "../detail_common/AltLabel";
import DetailPageHeader from "../detail_common/DetailPageHeader";
import RouteLink from "../RouteLink";
import { generateVocabularyRoute } from "../../utils/Utils";
import { TermInterface } from "../../api/data/terms";
import { Notations } from "./Notations";

export interface DetailHeaderProps {
term: TermInterface;
}

const TermHeader: React.FC<DetailHeaderProps> = ({ term }) => {
const { $id, label, altLabels, vocabulary } = term;
const { $id, label, altLabels, notation, vocabulary } = term;

const vocabularyRoute = generateVocabularyRoute(vocabulary.$id);
const above = (
Expand All @@ -20,10 +22,22 @@ const TermHeader: React.FC<DetailHeaderProps> = ({ term }) => {
);
const below = <AltLabel altLabels={altLabels} />;

const title =
notation.length > 0 ? (
<>
{label}
<Box component="span" sx={{ marginLeft: "0.25rem" }}>
<Notations notation={notation} />
</Box>
</>
) : (
label
);

return (
<DetailPageHeader
aboveLabel={above}
label={label}
label={title}
belowLabel={below}
iri={$id}
/>
Expand Down
2 changes: 2 additions & 0 deletions src/components/terms/TermPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ErrorPage from "../ErrorPage";
import Relations from "./Relations";
import useRouteQuery from "../../hooks/useRouteQuery";
import { generateTermBase } from "../../utils/Utils";
import { SkosRelations } from "./SkosRelations";

const TermPage: React.FC = () => {
const routeQuery = useRouteQuery();
Expand All @@ -36,6 +37,7 @@ const TermPage: React.FC = () => {
<Hierarchy term={data} />
{/**Relations component checks if the term is empty, because it is the last one**/}
<Relations term={data} />
<SkosRelations term={data} />
</Box>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/terms/TermRelations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface RelationsItemProps {
ranges: ReactElement[];
}

const TermBox = styled(Box)(({ theme }) => ({
export const TermBox = styled(Box)(({ theme }) => ({
flex: 3,
minWidth: 165,
display: "flex",
Expand Down