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

Family member search #160

Open
wants to merge 4 commits into
base: dev-version-2
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion src/main/webapp/app/entities/cc-member/member.indexer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IUserCCInfo } from 'app/shared/model/user-cc-info.model';

export const genereateIndex = (userCCInfo: IUserCCInfo) => {
export const generateIndex = (userCCInfo: IUserCCInfo) => {
const searchIndex = (userCCInfo.user?.firstName?.trim() || '') + (userCCInfo.user?.lastName?.trim() || '');
return searchIndex.replace(/\s+/g, '').toLowerCase();
};
4 changes: 2 additions & 2 deletions src/main/webapp/app/entities/cc-member/member.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap
import CustomTab from 'app/shared/components/customTab/custom-tab';
import { SearchEngine } from 'app/shared/util/native-search-utils';
import { IUserCCInfo } from 'app/shared/model/user-cc-info.model';
import { genereateIndex } from './member.indexer';
import { generateIndex } from './member.indexer';

function useQuery() {
return new URLSearchParams(useLocation().search);
}

const member: React.FC<RouteComponentProps> = (props: RouteComponentProps) => {
const searchEngine: SearchEngine<IUserCCInfo> = new SearchEngine([], genereateIndex);
const searchEngine: SearchEngine<IUserCCInfo> = new SearchEngine([], generateIndex);
const query = useQuery();
const [viewModel, setViewModel] = useState({
isLoading: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class FamilyMemberCreate extends React.Component<IFamilyMemberCreateProps
if (user) {
return (
<option key={user.id} value={user.id}>
{concatFullName(user.firstName, user.lastName)}
{concatFullName(user.firstName ?? '', user.lastName ?? '')}
</option>
);
}
Expand Down Expand Up @@ -137,7 +137,7 @@ export class FamilyMemberCreate extends React.Component<IFamilyMemberCreateProps
this.renderNames(users)
) : (
<option key={userEntity.id} value={userEntity.id}>
{concatFullName(userEntity?.user?.firstName, userEntity?.user?.lastName)}
{concatFullName(userEntity?.user?.firstName ?? '', userEntity?.user?.lastName ?? '')}
</option>
)}
</AvField>
Expand Down
50 changes: 35 additions & 15 deletions src/main/webapp/app/entities/club-family/family-member.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,41 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Translate, translate } from 'react-jhipster';
import { connect } from 'react-redux';
import { IRootState } from 'app/shared/reducers';

import { generateIndex } from '../cc-member/member.indexer';
import AuthorizationChecker from 'app/shared/components/authorization-checker/authorization-checker';
import CCRole from 'app/shared/model/enum/cc-role.enum';
import EventRole from 'app/shared/model/enum/event-role.enum';
import MemberCard from './member-card';
import FilterSearchBar from 'app/shared/components/advancedSearchModal/advancedSearchModal';
import EventModal from 'app/shared/components/eventModal/event-modal';

import AdvancedSearchBar from 'app/shared/components/advancedSearchModal/advancedSearchModal';
import { getUsersWithFilter, reset as resetUsers } from 'app/entities/user-cc-info/user-cc-info.reducer';
import { getClubFamilyDetails } from 'app/shared/services/club-family-info.service';
import { reset as resetFilter } from 'app/shared/components/advancedSearchModal/advancedSearchModal.reducer';
import { SearchEngine } from 'app/shared/util/native-search-utils';
import { IUserCCInfo } from 'app/shared/model/user-cc-info.model';

export interface IFamilyMemberProps extends StateProps, DispatchProps, RouteComponentProps<{ familyCode: string }> {}

export interface IFamilyMemberState {
searchModalIsOpen: boolean;
memberName: string;
filteredUsers: IUserCCInfo[];
}
class FamilyMember extends React.Component<IFamilyMemberProps, IFamilyMemberState> {
searchEngine: SearchEngine<IUserCCInfo> = new SearchEngine([], generateIndex);

constructor(props: IFamilyMemberProps) {
super(props);
this.state = {
searchModalIsOpen: false,
memberName: '',
filteredUsers: [],
};
}

async componentDidMount() {
this.props.getUsersWithFilter(this.props.match.params.familyCode);
await this.props.getUsersWithFilter(this.props.match.params.familyCode);
this.setState({
filteredUsers: this.props.users,
});
}

componentWillUnmount() {
Expand All @@ -52,19 +60,32 @@ class FamilyMember extends React.Component<IFamilyMemberProps, IFamilyMemberStat
});
};

onEditButtonClick = (userCCInfoId?: number): void => {};
updateMemberName = (event: { target: HTMLInputElement }): void => {
this.setState({ memberName: event.target.value });
};

searchMembers = (): void => {
const filteredUsers = this.searchEngine.updateEngine(this.props.users).search(this.state.memberName);
this.setState({ filteredUsers });
};

advanceSearch = async (familyCode: string, filters: any): Promise<void> => {
await this.props.getUsersWithFilter(familyCode, filters);
const filteredUsers = this.searchEngine.updateEngine(this.props.users).search(this.state.memberName);
this.setState({ filteredUsers });
};

render() {
const { users, match } = this.props;
const { searchModalIsOpen } = this.state;
const { searchModalIsOpen, memberName, filteredUsers } = this.state;
const familyName = getClubFamilyDetails(match.params.familyCode).name;
return (
<div>
<FilterSearchBar
<AdvancedSearchBar
isOpen={searchModalIsOpen}
toggleModal={this.toggleSearchModal}
familyCode={this.props.match.params.familyCode}
searchUsers={this.props.getUsersWithFilter}
searchUsers={this.advanceSearch}
/>
<h2 id="event-activity-heading" className="event-module-heading">
{familyName ? translate(familyName) : null}
Expand All @@ -80,21 +101,20 @@ class FamilyMember extends React.Component<IFamilyMemberProps, IFamilyMemberStat
</AuthorizationChecker>
<InputGroup>
<InputGroupAddon className="search-bar-prepend" addonType="prepend" color="white">
{/* ADD IN SEARCH ONCLICK TO THE BUTTON BELOW*/}
<Button color="primary">
<Button color="primary" onClick={this.searchMembers}>
<FontAwesomeIcon icon="search" />
</Button>
</InputGroupAddon>
<Input placeholder="Type a name to filter" className="search-bar-input" />
<Input placeholder="Type a name to filter" className="search-bar-input" value={memberName} onChange={this.updateMemberName} />
<InputGroupAddon addonType="append">
<Button className="search-bar-append" onClick={this.toggleSearchModal}>
<FontAwesomeIcon icon="filter" color="#07ADE1" />
</Button>
</InputGroupAddon>
</InputGroup>
{users && users.length > 0 ? (
{filteredUsers && filteredUsers.length > 0 ? (
<div>
{users.map(user => (
{filteredUsers.map(user => (
<MemberCard
key={user.id}
userCCInfo={user}
Expand Down
2 changes: 0 additions & 2 deletions src/main/webapp/app/entities/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ const Routes: React.FC<RouteComponentProps> = ({ match }) => (
<ErrorBoundaryRoute path={`${match.url}/transaction`} component={Transaction} />
<ErrorBoundaryRoute path={`${match.url}/claim`} component={Claim} />
<ErrorBoundaryRoute path={`${match.url}/debt`} component={Debt} />
<ErrorBoundaryRoute path={`${match.url}/administrator`} component={Administrator} />
<ErrorBoundaryRoute path={`${match.url}/members/club-family`} component={ClubFamily} />
<ErrorBoundaryRoute path={`${match.url}/members/cc-member`} component={Member} />
<ErrorBoundaryRoute path={`${match.url}/members/administrator`} component={Administrator} />
<ErrorBoundaryRoute path={`${match.url}/members/cc-family`} component={ClubFamily} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const ACTION_TYPES = {
const initialState: IUserCCInfoState = {
loading: false,
errResponse: null,
entities: [] as ReadonlyArray<IUserCCInfo>,
entities: [],
entity: defaultValue,
updating: false,
updateSuccess: false,
Expand All @@ -33,7 +33,7 @@ const initialState: IUserCCInfoState = {
export interface IUserCCInfoState {
loading: boolean;
errResponse: null | AxiosError;
entities: ReadonlyArray<IUserCCInfo>;
entities: IUserCCInfo[];
entity: Readonly<IUserCCInfo>;
updating: boolean;
updateSuccess: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export interface IAdvancedSearchModalState {
}

export interface IFilter {
userFirstName?: string;
userLastName?: string;
memberName?: string;
courseProgramId?: number;
yearSession?: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IFilter, setEntity } from './advancedSearchModal.reducer';

import './advancedSearchModal.scss';

interface IFilterSearchBarProps extends StateProps, DispatchProps {
interface IAdvancedSearchModalProps extends StateProps, DispatchProps {
isOpen: boolean;
toggleModal: () => void;
familyCode: string;
Expand All @@ -21,20 +21,19 @@ interface IAdvancedSearchModalState {
filters: IFilter;
}

class AdvancedSearchModal extends React.Component<IFilterSearchBarProps, IAdvancedSearchModalState> {
constructor(props: IFilterSearchBarProps) {
class AdvancedSearchModal extends React.Component<IAdvancedSearchModalProps, IAdvancedSearchModalState> {
constructor(props: IAdvancedSearchModalProps) {
super(props);
this.state = {
filters: {
userFirstName: '',
userLastName: '',
memberName: '',
courseProgramId: undefined,
yearSession: '',
},
};
}

componentDidUpdate(prevProps: IFilterSearchBarProps) {
componentDidUpdate(prevProps: IAdvancedSearchModalProps) {
if (this.props.isOpen !== prevProps.isOpen) {
this.props.getYearSessionOptions(0, 12, 'value,desc');
this.props.getCourseProgramOptions(0, 12, 'value,desc');
Expand Down Expand Up @@ -77,10 +76,7 @@ class AdvancedSearchModal extends React.Component<IFilterSearchBarProps, IAdvanc
<h2 className="text-center mb-4">Advanced Search</h2>
<AvForm model={filters ?? {}} onSubmit={this.searchEntities}>
<AvGroup>
<AvInput id="first-name" type="text" placeholder="First Name" className="form-control" name="userFirstName" autoFocus />
</AvGroup>
<AvGroup>
<AvInput id="last-name" type="text" placeholder="Last Name" className="form-control" name="userLastName" autoFocus />
<AvInput id="member-name" type="text" placeholder="Member Name" className="form-control" name="memberName" autoFocus />
</AvGroup>
<AvGroup>
<AvInput id="course-program" type="select" placeholder="Course Program" className="form-control" name="courseProgramId">
Expand Down