Skip to content

Commit

Permalink
feat: Membership management - frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
mguihal committed Jul 9, 2024
1 parent 6bb82a4 commit 5a48a31
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 167 deletions.
35 changes: 0 additions & 35 deletions frontend/src/common/GroupedReferenceHandler.jsx

This file was deleted.

51 changes: 51 additions & 0 deletions frontend/src/common/field/MembershipAssociationField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from "react";
import {
RecordContextProvider,
ReferenceField,
useGetMany,
useRecordContext,
} from "react-admin";
import RightLabel from "../list/SideList/RightLabel";
import { Box, Grid } from "@mui/material";
import { AvatarWithLabelField } from "@semapps/field-components";

const MembershipAssociationField = (props) => {
const { source, referenceFieldProps } = props;
const record = useRecordContext();

const { data: membershipData } = useGetMany("MembershipAssociation", {
ids: record?.[source] || [],
});
const { data: roleData } = useGetMany("MembershipRole", {
ids: [...new Set(membershipData?.map((d) => d["pair:membershipRole"]))],
});

return (
<div>
{roleData?.map((role) => {
const memberships = membershipData?.filter(m => m['pair:membershipRole'] === role.id);

return (
<Box key={role.id}>
<RightLabel label={role['pair:label']} source={source} />
<Box mb={4}>
<Grid container spacing={3}>
{memberships?.map((membership) => (
<Grid item key={membership.id} xs={6}>
<RecordContextProvider value={membership}>
<ReferenceField {...referenceFieldProps}>
<AvatarWithLabelField label="pair:label" image="image" />
</ReferenceField>
</RecordContextProvider>
</Grid>
))}
</Grid>
</Box>
</Box>
);
})}
</div>
);
};

export default MembershipAssociationField;
72 changes: 72 additions & 0 deletions frontend/src/common/input/MembershipAssociationInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from "react";
import {
TextInput,
ArrayInput,
SimpleFormIterator,
AutocompleteInput,
useRecordContext,
useGetMany,
ReferenceInput,
FormDataConsumer,
RecordContextProvider,
SelectInput,
} from "react-admin";

const MembershipAssociationInput = (props) => {
const { source, referenceInputProps, label } = props;
const record = useRecordContext();

const { data } = useGetMany("MembershipAssociation", {
ids: record?.[source] || [],
});

if (!data) return null;

return (
<ArrayInput source={source}>
<SimpleFormIterator inline>
<FormDataConsumer>
{({ scopedFormData, getSource }) => {
const relationRecord = data?.find((r) => r.id === scopedFormData);

return (
<RecordContextProvider value={relationRecord}>
<ReferenceInput {...referenceInputProps}>
<AutocompleteInput
name={getSource(referenceInputProps.source)}
label={label}
size="small"
sx={{
mt: 1,
mb: "4px",
minWidth: 300,
}}
shouldRenderSuggestions={(value) =>
value && value.length > 1
}
/>
</ReferenceInput>
<ReferenceInput
reference="MembershipRole"
source="pair:membershipRole"
>
<SelectInput
name={getSource("pair:membershipRole")}
label="Rôle"
/>
</ReferenceInput>
<TextInput
source={getSource("type")}
defaultValue={"pair:MembershipAssociation"}
sx={{ display: "none" }}
/>
</RecordContextProvider>
);
}}
</FormDataConsumer>
</SimpleFormIterator>
</ArrayInput>
);
};

export default MembershipAssociationInput;
29 changes: 0 additions & 29 deletions frontend/src/common/input/ReificationArrayInput.jsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import {
SelectInput,
TabbedForm,
ImageField,
AutocompleteInput,
} from 'react-admin';
import { ReferenceInput, ImageInput } from '@semapps/input-components';
import { MarkdownInput } from '@semapps/markdown-components';
import { MultiLinesInput } from '@semapps/input-components';
import { OrganizationsInput, EventsInput, DocumentsInput, LocationInput } from '../../../../common/input';
import Edit from "../../../../layout/edit/Edit";
import CustomTreeSelectArrayInput from '../../../../common/input/TreeComponent/CustomTreeSelectArrayInput';
import ReificationArrayInput from '../../../../common/input/ReificationArrayInput';
import MembershipAssociationInput from '../../../../common/input/MembershipAssociationInput';

export const OrganizationEdit = props => (
<Edit redirect="show" {...props}>
Expand All @@ -35,22 +34,14 @@ export const OrganizationEdit = props => (
</ImageInput>
</TabbedForm.Tab>
<TabbedForm.Tab label="Membres">
<ReificationArrayInput source="pair:organizationOfMembership" reificationClass="pair:MembershipAssociation" >
<ReferenceInput reference="Person" source="pair:membershipActor">
<AutocompleteInput label="Membre" optionText={record => record && `${record['pair:firstName']} ${record['pair:lastName']}`}
size='small'
sx={{
mt: 1,
mb: '4px',
minWidth: 300,
}}
shouldRenderSuggestions={value => value && value.length > 1}
/>
</ReferenceInput>
<ReferenceInput reference="MembershipRole" source="pair:membershipRole">
<SelectInput label="Rôle" optionText="pair:label" />
</ReferenceInput>
</ReificationArrayInput>
<MembershipAssociationInput
source="pair:organizationOfMembership"
referenceInputProps={{
reference: "Person",
source: "pair:membershipActor"
}}
label="Membre"
/>
</TabbedForm.Tab>
<TabbedForm.Tab label="Relations">
<OrganizationsInput source="pair:partnerOf" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import {
QuickAppendReferenceArrayField,
MultiUrlField,
AvatarWithLabelField,
SeparatedListField,
ReferenceField
SeparatedListField
} from '@semapps/field-components';
import { ChipList, GridList } from '@semapps/list-components';
import DescriptionIcon from '@mui/icons-material/Description';
Expand All @@ -18,18 +17,7 @@ import VideocamOutlinedIcon from '@mui/icons-material/VideocamOutlined';
import { MarkdownField } from '../../../../common/field';
import { Hero, MainList, SideList } from '../../../../common/list';
import Show from "../../../../layout/show/Show";
import RightLabel from '../../../../common/list/SideList/RightLabel';
import GroupedReferenceHandler from '../../../../common/GroupedReferenceHandler';

const ConditionalSourceDefinedHandler = ({ record, source, children, ...otherProps }) => {
if (record?.[source] && (!Array.isArray(record[source]) || record[source].length > 0)) {
return React.Children.map(children, (child) => {
return React.cloneElement(child, { ...otherProps, record, source });
});
} else {
return <></>;
}
};
import MembershipAssociationField from "../../../../common/field/MembershipAssociationField";

const domainMapping = {
'forums.assemblee-virtuelle.org': {
Expand Down Expand Up @@ -90,26 +78,17 @@ const OrganizationShow = props => (
</Grid>
<Grid item xs={12} sm={3}>
<SideList>
<GroupedReferenceHandler
<MembershipAssociationField
source="pair:organizationOfMembership"
groupReference="MembershipRole"
groupLabel="pair:label"
filterProperty="pair:membershipRole"
label={false}
>
<ConditionalSourceDefinedHandler>
<RightLabel mb={0} />
<ArrayField source="pair:organizationOfMembership">
<Box mb={4}>
<GridList xs={6} linkType={false} externalLinks>
<ReferenceField reference="Person" source="pair:membershipActor" link="show" basePath="/Person">
<AvatarWithLabelField label="pair:label" image="image" />
</ReferenceField>
</GridList>
</Box>
</ArrayField>
</ConditionalSourceDefinedHandler>
</GroupedReferenceHandler>
referenceFieldProps={{
reference: "Person",
source: "pair:membershipActor",
basePath: "/Person",
link: "show"
}}
/>

<ReferenceArrayField reference="Organization" source="pair:partnerOf">
<GridList xs={6} linkType="show" externalLinks>
<AvatarWithLabelField label="pair:label" image="image">
Expand Down
29 changes: 10 additions & 19 deletions frontend/src/resources/Agent/Actor/Person/PersonEdit.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import { ImageField, TabbedForm, TextInput, FormTab, AutocompleteInput, SelectInput } from 'react-admin';
import { ReferenceInput } from '@semapps/input-components';
import { ImageField, TabbedForm, TextInput, FormTab } from 'react-admin';
import { ImageInput } from '@semapps/input-components';
import { ActivitiesInput, LocationInput, SkillsInput, ThemesInput } from '../../../../common/input';
import Edit from "../../../../layout/edit/Edit";
import ReificationArrayInput from '../../../../common/input/ReificationArrayInput';
import MembershipAssociationInput from '../../../../common/input/MembershipAssociationInput';

export const PersonEdit = props => (
<Edit
Expand All @@ -23,22 +22,14 @@ export const PersonEdit = props => (
</ImageInput>
</FormTab>
<FormTab label="Rôles">
<ReificationArrayInput source="pair:actorOfMembership" reificationClass="pair:MembershipAssociation" >
<ReferenceInput reference="Organization" source="pair:membershipOrganization">
<AutocompleteInput label="Organization" optionText="pair:label"
size='small'
sx={{
mt: 1,
mb: '4px',
minWidth: 300,
}}
shouldRenderSuggestions={value => value && value.length > 1}
/>
</ReferenceInput>
<ReferenceInput reference="MembershipRole" source="pair:membershipRole">
<SelectInput label="Rôle" optionText="pair:label" />
</ReferenceInput>
</ReificationArrayInput>
<MembershipAssociationInput
source="pair:actorOfMembership"
referenceInputProps={{
reference: "Organization",
source: "pair:membershipOrganization"
}}
label="Organisation"
/>
</FormTab>
<FormTab label="Relations">
<ActivitiesInput source="pair:involvedIn" />
Expand Down
Loading

0 comments on commit 5a48a31

Please sign in to comment.