# HG changeset patch # User François FERRY <francois.ferry@logilab.fr> # Date 1614095799 -3600 # Tue Feb 23 16:56:39 2021 +0100 # Node ID 70c03510bc065bf65711916c16d4fa87b5683af9 # Parent 8e3e1997aa98813f263153c0258243e157bfe444 feat: allow to list object relations diff --git a/packages/demo/src/App.tsx b/packages/demo/src/App.tsx --- a/packages/demo/src/App.tsx +++ b/packages/demo/src/App.tsx @@ -17,6 +17,7 @@ Show, SimpleShowLayout, DataProvider, + ReferenceArrayField, } from "react-admin"; import { client } from "@logilab/cwclientlibjs"; import { createDataProvider } from "ra-cubicweb/dist"; @@ -65,9 +66,9 @@ export const CityList = (props: ListProps) => ( <List {...props}> <Datagrid rowClick="show"> - <NumberField source="zip_code" /> + <TextField source="id" /> <TextField source="name" /> - <TextField source="id" /> + <NumberField source="zip_code" /> </Datagrid> </List> ); @@ -75,9 +76,14 @@ export const CityShow = (props: ShowProps) => ( <Show {...props}> <SimpleShowLayout> - <NumberField source="zip_code" /> + <TextField source="id" /> <TextField source="name" /> - <TextField source="id" /> + <NumberField source="zip_code" /> + <ReferenceArrayField label="Museum" reference="Museum" source="reverse_is_in"> + <Datagrid rowClick="show"> + <TextField source="name"/> + </Datagrid> + </ReferenceArrayField> </SimpleShowLayout> </Show> ); diff --git a/packages/ra-cubicweb/src/index.ts b/packages/ra-cubicweb/src/index.ts --- a/packages/ra-cubicweb/src/index.ts +++ b/packages/ra-cubicweb/src/index.ts @@ -87,7 +87,7 @@ { eid: params.id, id: params.id } ); - // Getting relations + // Getting subject relations const subjectRelations = Object.fromEntries( Object.entries(schema.relationships).filter( ([_relationName, definition]: [string, S["relationships"][string]]) => @@ -102,6 +102,22 @@ entity[relationName] = result.map((row) => row[0]); } } + + // Getting object relations + const objectRelations = Object.fromEntries( + Object.entries(schema.relationships).filter( + ([_relationName, definition]: [string, S["relationships"][string]]) => + definition.object.includes(resource) + ) + ); + for (const relationName in objectRelations) { + const result = await rqlClient.queryRows( + `Any TARGET Where TARGET ${relationName} X, X eid ${params.id}` + ); + if (result.length !== 0) { + entity[`reverse_${relationName}`] = result.map((row) => row[0]); + } + } return { data: entity }; }, getMany: async (resource, params) => { @@ -115,22 +131,20 @@ selection.push(variable); restrictions.push(`X ${key} ${variable}`); }); - const result = await rqlClient.queryRows( - `Any ${selection.join(",")} Where ${restrictions.join(",")}, X eid ${ - params.ids[0] - }` + `Any ${selection.join(",")} Where ${restrictions.join(",")}, X eid IN (${ + params.ids.join(",") + })` ); - const row = result[0]; - const entity = row.reduce( + const entities = result.map((row, rowIdx) => row.reduce( (agg, attributeValue, idx) => ({ [attributesNames[idx]]: attributeValue, ...agg, }), - { id: params.ids[0] } - ); + { id: params.ids[rowIdx] } + )); - return { data: [entity] }; + return { data: entities }; }, getManyReference: (_resource, _params) => Promise.reject("Not implemented"), update: async (resource, { data, id }) => {