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

Feat/menu #156

Merged
merged 18 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion src/app/components/SearchMenu/MenuItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import { SearchSource } from '../../../util/DefaultEntities';
import RoundedButton from '../../RoundedButton';

Expand All @@ -17,6 +17,7 @@ const MenuItem: React.FC<MenuItemProps> = ({
item,
index,
}) => {

return (
<>
<li
Expand Down
40 changes: 30 additions & 10 deletions src/app/components/SearchMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Modal from '../Modal';
import MenuItem from './MenuItem';
import { FiSearch } from 'react-icons/fi';
import { on, off } from '../../util/EventHandler';
import BehaviourFactory from '../../factory/BehaviourFactory';
import { AdapterBaseProps } from '../../../electron/database/adapter/AdapterBase';

interface SearchMenuProps {
setOpen(): void;
Expand All @@ -24,9 +26,12 @@ const SearchMenu: React.FC<SearchMenuProps> = ({ isOpen, setOpen }) => {

useEffect(() => {
setSelectedItem(-1);
setSearchResult(searchSourceMemo);
setSearchResult(sortMenu(searchSourceMemo));

setMaxItems(searchSourceMemo.length * 2);
if (!isOpen) {
setInputSearch('');
}
}, [isOpen, searchSourceMemo]);

useEffect(() => {
Expand Down Expand Up @@ -82,14 +87,30 @@ const SearchMenu: React.FC<SearchMenuProps> = ({ isOpen, setOpen }) => {
[searchResult, selectedItem]
);

const globalSearchHandler = useCallback((search) => {
const retorno: any = window.api.sendSync('globalSearch', {
entity: 'Any',
value: search,
const factorySearchHandler = useCallback((ret) => {
const processed = ret.map((item: AdapterBaseProps) => {
console.log(item);
return BehaviourFactory.make(item);
});
return retorno;
return processed;
}, []);

const globalSearchHandler = useCallback(
(search) => {
const ret: any = window.api.sendSync('globalSearch', {
entity: 'Any',
value: search,
});

return factorySearchHandler(ret);
},
[factorySearchHandler]
);

const sortMenu = (results: any) => {
return results.sort((a: any, b: any) => (a.label < b.label ? -1 : 1));
};

const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
Expand All @@ -103,9 +124,8 @@ const SearchMenu: React.FC<SearchMenuProps> = ({ isOpen, setOpen }) => {
results.push(...resultsDb);
}

const finalResult: SearchSource[] = results.sort((a, b) =>
a.label < b.label ? -1 : 1
);
const finalResult: SearchSource[] = sortMenu(results);

setSearchResult(finalResult);
setMaxItems(finalResult.length * 2);
setSelectedItem(-1);
Expand Down Expand Up @@ -150,7 +170,7 @@ const SearchMenu: React.FC<SearchMenuProps> = ({ isOpen, setOpen }) => {
return (
isOpen && (
<>
<Modal isOpen={isOpen} setIsOpen={setOpen} customClass='quick-search'>
<Modal isOpen={isOpen} setIsOpen={setOpen} customClass="quick-search">
<div>
<Input
name="search-menu"
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Tabs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const Tabs: React.FC = () => {
type: type,
title: `${type}.label`,
action: action,
item: undefined,
item: item ? item : undefined,
};

addTab(tab);
Expand Down Expand Up @@ -194,7 +194,7 @@ const Tabs: React.FC = () => {
[tabItems]
);

useEffect(()=>{
useEffect(() => {
setActiveTab(selectedTab);
}, [selectedTab]);

Expand Down
1 change: 0 additions & 1 deletion src/app/components/Title/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import TitleUpdate from './Update';

const Title: React.FC<{ action: string, item?: unknown }> = ({ action, item }) => {
const title = item as Title;

return (
<>
{action === 'create' && <TitleCreate />}
Expand Down
22 changes: 22 additions & 0 deletions src/app/factory/BehaviourFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Person from './Person';
import Title from './Title';
import {AdapterBaseProps} from '../../electron/database/adapter/AdapterBase';
import { SearchSource } from '../util/DefaultEntities';

interface Product {
[key: string]: Person | Title;
}

class BehaviourFactory {
static readonly factories: Product = {
Person: new Person(),
Title: new Title(),
};

static make(item: AdapterBaseProps): SearchSource {
const classElement = this.factories[item.handler];
return classElement.execute(item);
}
}

export default BehaviourFactory;
23 changes: 23 additions & 0 deletions src/app/factory/IconFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FaPlus, FaUser, FaBook, FaHandshake } from 'react-icons/fa';
import { FiBook } from 'react-icons/fi';
import { IconBaseProps } from 'react-icons';

interface Product {
[key: string]: React.ComponentType<IconBaseProps>;
}

class IconFactory {
static readonly icons: Product = {
FiBook: FiBook,
FaPlus: FaPlus,
FaUser: FaUser,
FaBook: FaBook,
FaHandshake: FaHandshake,
};

static icon(param: string): React.ComponentType<IconBaseProps> {
return this.icons[param];
}
}

export default IconFactory;
57 changes: 57 additions & 0 deletions src/app/factory/Person.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { trigger } from '../util/EventHandler';
import { AppEvent } from '../../common/AppEvent';
import { Actions } from '../../common/Actions';
import IconFactory from './IconFactory';
import {AdapterBaseProps} from '../../electron/database/adapter/AdapterBase';
import { SearchSource } from '../util/DefaultEntities';

class Person {
execute(item: AdapterBaseProps): SearchSource {
const icon = IconFactory.icon(item.icon);
const iconAction = IconFactory.icon(item.iconAction);

const newItem = {
name: item.name,
label: item.label,
complement: item.complement,
icon: icon,
iconColor: item.iconColor,
iconAction: iconAction,
handler: {
onClick: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.personTab, {
action: Actions.read,
value: item.item,
});
},
onPress: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.personTab, {
action: Actions.read,
value: item.item,
});
},
},
action: {
onClick: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.borrowTab, {
action: Actions.create,
value: item.item,
});
},
onPress: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.borrowTab, {
action: Actions.create,
value: item.item,
});
},
},
};
return newItem;
}
}

export default Person;
56 changes: 56 additions & 0 deletions src/app/factory/Title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { trigger } from '../util/EventHandler';
import { AppEvent } from '../../common/AppEvent';
import { Actions } from '../../common/Actions';
import IconFactory from './IconFactory';
import {AdapterBaseProps} from '../../electron/database/adapter/AdapterBase';
import { SearchSource } from '../util/DefaultEntities';

class Title {
execute(item: AdapterBaseProps): SearchSource {
const icon = IconFactory.icon(item.icon);
const iconAction = IconFactory.icon(item.iconAction);
const newItem = {
name: item.name,
label: item.label,
complement: item.complement,
icon: icon,
iconColor: item.iconColor,
iconAction: iconAction,
handler: {
onClick: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.titleTab, {
action: Actions.read,
value: item.item,
});
},
onPress: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.titleTab, {
action: Actions.read,
value: item.item,
});
},
},
action: {
onClick: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.borrowTab, {
action: Actions.create,
value: item.item,
});
},
onPress: (): void => {
trigger(AppEvent.quickSearch);
trigger(AppEvent.borrowTab, {
action: Actions.create,
value: item.item,
});
},
},
};
return newItem;
}
}

export default Title;
2 changes: 1 addition & 1 deletion src/app/util/DefaultEntities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { FiBook, FiSettings, FiUser } from 'react-icons/fi';
import i18n from '../i18n';
import { trigger } from './EventHandler';
import { AppEvent } from '../../common/AppEvent';
import Borrow from '../components/Borrow';
import { Actions } from '../../common/Actions';

export interface SearchSource {
name: string;
label: string;
complement?: string,
icon: React.ComponentType<IconBaseProps>;
iconColor: string;
iconAction?: React.ComponentType<IconBaseProps>;
Expand Down
20 changes: 19 additions & 1 deletion src/electron/Main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import BorrowRepository from './database/repository/BorrowRepository';
import TitlePublisherRepository from './database/repository/TitlePublisherRepository';
import UserRepository from './database/repository/UserRepository';
import PersonRepository from './database/repository/PersonRepository';
import TitleAdapter from '../electron/database/adapter/TitleAdapter';
import PersonAdapter from '../electron/database/adapter/PersonAdapter';

declare const MAIN_WINDOW_WEBPACK_ENTRY: string;
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string;
Expand Down Expand Up @@ -352,7 +354,23 @@ export default class Main {

ipcMain.on('globalSearch', async (event, content: Event[]) => {
try {
event.returnValue = [];
const { value, entity } = content[0];
const titleAdapter = new TitleAdapter();
const personAdapter = new PersonAdapter();

const titles = await titleAdapter.defineData(
await this.getCustomRepository('Title', TitleRepository).globalSearch(
value
)
);

const people = await personAdapter.defineData(
await this.getCustomRepository('User', PersonRepository).globalSearch(
value
)
);

event.returnValue = [...titles, ...people];
} catch (err) {
log.error(err);
}
Expand Down
26 changes: 26 additions & 0 deletions src/electron/database/adapter/AdapterBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Title } from '../models/Title.schema';
import { User } from '../models/User.schema';

export type AdapterBaseProps = {
name: string;
label: string;
complement?: string;
icon: string;
iconColor: string;
iconAction: string;
handler: string;
action: string;
item: Title | User;
};

interface BaseAdapterContract {
defineData(dataFromRepository: Title[] | User[]): Promise<AdapterBaseProps[]>;
}

export default class AdapterBase implements BaseAdapterContract {
defineData(
dataFromRepository: Title[] | User[]
): Promise<AdapterBaseProps[]> {
throw new Error('Method not implemented.');
}
}
31 changes: 31 additions & 0 deletions src/electron/database/adapter/PersonAdapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Title } from '../models/Title.schema';
import { User } from '../models/User.schema';
import AdapterBase, { AdapterBaseProps } from './AdapterBase';

export default class PersonAdapter implements AdapterBase {
public async defineData(
dataFromRepository: Title[] | User[]
): Promise<AdapterBaseProps[]> {
try {
const data = dataFromRepository.map((item: Title | User) => {
const processedItem = {
name: item.name,
label: item.name,
complement: item.name,
icon: 'FaUser',
iconColor: '#ff78f7',
iconAction: 'FaHandshake',
handler: 'Person',
action: 'Person',
item: item,
};

return processedItem;
});
return data;
} catch (err) {
console.log(err);
throw err;
}
}
}
Loading