Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1096 arborescence des thématiques + multi sélection de thématique #1097

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion src/frontend/packages/list-components/dist/index.cjs.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/frontend/packages/list-components/dist/index.es.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/frontend/packages/list-components/dist/index.es.js.map

Large diffs are not rendered by default.

198 changes: 198 additions & 0 deletions src/frontend/packages/list-components/src/ReferenceFilterTree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import React from 'react';
import { useGetList } from 'react-admin';
import {TreeItem, TreeView, useTreeItem} from '@mui/lab';
import { useListFilterContext } from 'ra-core';
import CancelIcon from '@mui/icons-material/Cancel';
import LabelIcon from '@mui/icons-material/Label';
import { IconButton } from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import clsx from 'clsx';
import Typography from '@mui/material/Typography';

/**
* @example
* const FilterAside = () => (
* <Card>
* <CardContent>
* <FilterLiveSearch source="pair:label" />
* <ReferenceFilter reference="Theme" source="pair:broader" label="pair:label" />
* </CardContent>
* </Card>
* );
*/
BastienSig marked this conversation as resolved.
Show resolved Hide resolved


function GenerateTreeItemFromNarrower( source, label, themeList, narrower) {
let narrowerChild = {};
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
let isLastNarrower = false;
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
return (
themeList.map(function(theme) {
if (theme != undefined) {
if (theme[source] == narrower["id"]) {
themeList.map(function(t) {
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
if (t[source] != undefined && t[source] == theme["id"]) {
isLastNarrower = true;
narrowerChild = t;
}
})
return (
<CustomTreeItem key={theme["id"]} nodeId={theme["id"]} label={theme[label]} >
{isLastNarrower ? GenerateTreeItemFromNarrower(source, label, themeList, theme) : null }
</CustomTreeItem>
)
}
}
})
)
}

const CustomContent = React.forwardRef(function CustomContent(props, ref) {
const {
classes,
className,
label,
nodeId,
icon: iconProp,
expansionIcon,
displayIcon,
} = props;

const {
disabled,
expanded,
selected,
focused,
handleExpansion,
handleSelection,
preventSelection,
} = useTreeItem(nodeId);

const icon = iconProp || expansionIcon || displayIcon;

const handleMouseDown = (event) => {
preventSelection(event);
};

const handleExpansionClick = (event) => {
handleExpansion(event);
};

const handleSelectionClick = (event) => {
handleSelection(event);
};

return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div
className={clsx(className, classes.root, {
[classes.expanded]: expanded,
[classes.selected]: selected,
[classes.focused]: focused,
[classes.disabled]: disabled,
})}
onMouseDown={handleMouseDown}
ref={ref}
>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<div onClick={handleExpansionClick} className={classes.iconContainer}>
{icon}
</div>
<Typography
onClick={handleSelectionClick}
component="div"
className={classes.label}
>
{label}
</Typography>
</div>
);
});


function CustomTreeItem(props) {
return <TreeItem ContentComponent={CustomContent} {...props} />;
}

const ReferenceFilterTree = ({ reference, source, label, limit, sort, filter }) => {
const { data } = useGetList(reference, { page: 1, perPage: limit }, sort, filter);
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
const { filterValues, setFilters } = useListFilterContext();
let routeTree = [], listTheme = [], isThemeSelected = false;
BastienSig marked this conversation as resolved.
Show resolved Hide resolved

for (const theme in data) {
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
if (data[theme]['pair:broader'] == undefined ) {
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
routeTree.push(data[theme]);
}
listTheme = listTheme.concat(data[theme]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

je ne voie pas l'interet de recalculer. pas dicponible dans data?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BastienSig non resolu?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne le recalcule pas je le convertie en tableau d'objet. Mais il éxiste peut ¨être plus simple.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listRoot=data.filter(i=>i[predicate]===undefined)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok pour le for in par contre il reste des reference à theme et broader

}

function deleteFilterTheme() {
const newFilterValues = Object.assign({}, filterValues);
delete newFilterValues.sparqlWhere;
setFilters(newFilterValues, null, false);
isThemeSelected = false
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
}

const handleSelect = (event, nodes) => {
const sparqlWhere = {
"type": "bgp",
"triples": nodes.map((node) => {
return {
subject: {
termType: 'Variable',
value: 's1',
},
predicate: {
termType: 'NamedNode',
value: "http://virtual-assembly.org/ontologies/pair#hasTopic",
},
object: {
termType: 'NamedNode',
value: node,
},
};
}),
}

const query = JSON.stringify(sparqlWhere);
const encodedQuery = encodeURIComponent(query);
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
setFilters({...filterValues, "sparqlWhere": encodedQuery })

}
console.log(filterValues)
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
if (filterValues.sparqlWhere != undefined)
isThemeSelected = true
BastienSig marked this conversation as resolved.
Show resolved Hide resolved

return (
<div >
<IconButton size="small" edge="start">
<LabelIcon style={{ color: 'black', }} />
</IconButton>
Thèmes
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
{isThemeSelected ? <IconButton onClick={deleteFilterTheme} size="small">
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
<CancelIcon />
</IconButton> : null}
<TreeView
multiSelect
onNodeSelect={handleSelect}
aria-label="icon expansion"
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
>
{routeTree.map((route) =>
<CustomTreeItem nodeId={route["id"]} label={route[label]} key={route["id"]}>
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
{GenerateTreeItemFromNarrower(source, label, listTheme, route)}
</CustomTreeItem>
)}
</TreeView>
</div>
)
};

ReferenceFilterTree.defaultProps = {
limit: 25,
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
showCounters: true
};

export default ReferenceFilterTree;

1 change: 1 addition & 0 deletions src/frontend/packages/list-components/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { default as ChipList } from './ChipList';
export { default as GridList } from './GridList';
export { default as MasonryList } from './MasonryList';
export { default as ReferenceFilter } from './ReferenceFilter';
export { default as ReferenceFilterTree } from './ReferenceFilterTree';

export { default as MultiViewsList } from './MultiViewsList/MultiViewsList';
export { default as ListActionsWithViews } from './MultiViewsList/ListActionsWithViews';
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ const fetchSparqlEndpoints = async (containers, resourceId, params, config) => {
getBlankNodesFromDataServers(containers[serverKey], dataServers);

const predicates = params.filter?._predicates || dataModel.list?.predicates;

//When the sparql request come from URI, it's a string who must must be decode.
if (params.filter.sparqlWhere && typeof params.filter.sparqlWhere === 'string' || params.filter.sparqlWhere instanceof String) {
BastienSig marked this conversation as resolved.
Show resolved Hide resolved
params.filter.sparqlWhere = JSON.parse(decodeURIComponent(params.filter.sparqlWhere));
}
const sparqlQuery = buildSparqlQuery({
containers: containers[serverKey],
params: { ...params, filter: { ...dataModel.list?.filter, ...params.filter } },
Expand Down