diff --git a/packages/demo/src/App.tsx b/packages/demo/src/App.tsx index e3b1995cd03a832514e0a52ceb621b68a3f224a8_cGFja2FnZXMvZGVtby9zcmMvQXBwLnRzeA==..3f96e0b0f87b46c7ce7e791b2060cd664fe65c1e_cGFja2FnZXMvZGVtby9zcmMvQXBwLnRzeA== 100644 --- a/packages/demo/src/App.tsx +++ b/packages/demo/src/App.tsx @@ -7,4 +7,5 @@ TextField, DateField, NumberField, + ReferenceField, ShowGuesser, @@ -10,7 +11,8 @@ ShowGuesser, + ListGuesser, Edit, SimpleForm, TextInput, NumberInput, DateInput, EditProps, @@ -11,7 +13,8 @@ Edit, SimpleForm, TextInput, NumberInput, DateInput, EditProps, + ShowProps, ListProps, @@ -17,7 +20,9 @@ ListProps, + Show, + SimpleShowLayout, DataProvider, } from "react-admin"; import { createDataProvider } from "ra-cubicweb/dist"; import { schema } from "./schema"; @@ -18,9 +23,24 @@ DataProvider, } from "react-admin"; import { createDataProvider } from "ra-cubicweb/dist"; import { schema } from "./schema"; +export const MuseumShow = (props: ShowProps) => ( + <Show {...props}> + <SimpleShowLayout> + <TextField source="postal_address" /> + <NumberField source="longitude" /> + <NumberField source="latitude" /> + <TextField source="name" /> + <TextField source="id" /> + <ReferenceField label="City" link="show" reference="City" source="is_in"> + <TextField source="name" /> + </ReferenceField> + </SimpleShowLayout> + </Show> +); + const MuseumEdit = (props: EditProps) => ( <Edit {...props}> <SimpleForm> @@ -45,6 +65,26 @@ </List> ); +export const CityList = (props: ListProps) => ( + <List {...props}> + <Datagrid rowClick="show"> + <NumberField source="zip_code" /> + <TextField source="name" /> + <TextField source="id" /> + </Datagrid> + </List> +); + +export const CityShow = (props: ShowProps) => ( + <Show {...props}> + <SimpleShowLayout> + <NumberField source="zip_code" /> + <TextField source="name" /> + <TextField source="id" /> + </SimpleShowLayout> + </Show> +); + const dataProvider = createDataProvider("http://localhost:8080", schema); dataProvider.getList("toto", { pagination: { page: 1, perPage: 10 }, @@ -62,6 +102,6 @@ <Resource name="Museum" list={MuseumList} - show={ShowGuesser} + show={MuseumShow} edit={MuseumEdit} /> @@ -66,5 +106,6 @@ edit={MuseumEdit} /> + <Resource name="City" list={CityList} show={CityShow} /> </Admin> ); diff --git a/packages/ra-cubicweb/src/index.ts b/packages/ra-cubicweb/src/index.ts index e3b1995cd03a832514e0a52ceb621b68a3f224a8_cGFja2FnZXMvcmEtY3ViaWN3ZWIvc3JjL2luZGV4LnRz..3f96e0b0f87b46c7ce7e791b2060cd664fe65c1e_cGFja2FnZXMvcmEtY3ViaWN3ZWIvc3JjL2luZGV4LnRz 100644 --- a/packages/ra-cubicweb/src/index.ts +++ b/packages/ra-cubicweb/src/index.ts @@ -1,6 +1,6 @@ import { client } from "@logilab/cwclientlibjs"; import { AuthProvider, DataProvider } from "ra-core"; -import { Schema, ETypesNames } from "./Schema"; +import { Schema, ETypesNames, Relationships } from "./Schema"; // import authProvider from './authProvider'; // see https://marmelab.com/react-admin/Authentication.html @@ -60,8 +60,10 @@ }; }); }, - getOne: async (resource: ETypesNames<S>, _params) => { - const attributesNames = ["eid", ...Object.keys(schema.etypes[resource])]; + getOne: async (resource: ETypesNames<S>, params) => { + // FIXME Retrieve object relation + // Getting attributes + const attributesNames = [...Object.keys(schema.etypes[resource])]; const selection: string[] = []; const restrictions: string[] = []; attributesNames.forEach((key, idx) => { @@ -69,4 +71,5 @@ selection.push(variable); restrictions.push(`X ${key} ${variable}`); }); + const result = await rqlClient.queryRows( @@ -72,4 +75,6 @@ const result = await rqlClient.queryRows( - `Any ${selection.join(",")} Where ${restrictions.join(",")}` + `Any ${selection.join(",")} Where ${restrictions.join(",")}, X eid ${ + params.id + }` ); const row = result[0]; @@ -74,12 +79,30 @@ ); const row = result[0]; - return { - data: row.reduce( - (agg, attributeValue, idx) => ({ - [attributesNames[idx]]: attributeValue, - ...agg, - }), - { id: row[0] } - ), - }; + const entity = row.reduce( + (agg, attributeValue, idx) => ({ + [attributesNames[idx]]: attributeValue, + ...agg, + }), + { id: params.id } + ); + + // Getting relations + const subjectRelations = Object.fromEntries( + Object.entries(schema.relationships).filter( + ([_relationName, definition]: [string, S["relationships"][string]]) => + definition.subject === resource + ) + ); + for (const relationName in subjectRelations) { + const definition: S["relationships"][string] = + subjectRelations[relationName]; + + const result = await rqlClient.queryRows( + `Any TARGET Where TARGET is ${definition.object},X ${relationName} TARGET, X eid ${params.id}` + ); + if (result.length !== 0) { + entity[relationName] = result.map((row) => row[0]); + } + } + return { data: entity }; }, @@ -85,5 +108,32 @@ }, - getMany: (_resource, _params) => Promise.reject("Not implemented"), + getMany: async (resource, params) => { + // FIXME handle several params id and refactor code to use GetOne + // Getting attributes + const attributesNames = [...Object.keys(schema.etypes[resource])]; + const selection: string[] = []; + const restrictions: string[] = []; + attributesNames.forEach((key, idx) => { + const variable = `X${idx}`; + selection.push(variable); + restrictions.push(`X ${key} ${variable}`); + }); + + const result = await rqlClient.queryRows( + `Any ${selection.join(",")} Where ${restrictions.join(",")}, X eid ${ + params.ids[0] + }` + ); + const row = result[0]; + const entity = row.reduce( + (agg, attributeValue, idx) => ({ + [attributesNames[idx]]: attributeValue, + ...agg, + }), + { id: params.ids[0] } + ); + + return { data: [entity] }; + }, getManyReference: (_resource, _params) => Promise.reject("Not implemented"), update: (_resource, _params) => Promise.reject("Not implemented"), updateMany: (_resource, _params) => Promise.reject("Not implemented"),