add modal to project invitations

This commit is contained in:
Simon Larsen 2022-08-13 22:13:44 +01:00
parent 1097d172b1
commit 105d59103c
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
7 changed files with 179 additions and 15 deletions

View File

@ -14,9 +14,13 @@ const FullPageModal: FunctionComponent<ComponentProps> = (
<div className='margin-50 align-right' onClick={() => {
props.onClose && props.onClose();
}}>
<Icon icon={IconProp.Close} size={SizeProp.ExtraLarge} thick={ThickProp.Thick} />
<Icon
icon={IconProp.Close}
size={SizeProp.ExtraLarge}
thick={ThickProp.Thick}
/>
</div>
{props.children}
<div className='margin-50'>{props.children}</div>
</div>
);
};

View File

@ -38,6 +38,7 @@ import Navigation from '../../Utils/Navigation';
import Route from 'Common/Types/API/Route';
import BadDataException from 'Common/Types/Exception/BadDataException';
import Populate from '../../Utils/ModelAPI/Populate';
import List from '../Table/List';
export interface ComponentProps<TBaseModel extends BaseModel> {
modelType: { new (): TBaseModel };
@ -562,8 +563,116 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
/>)
}
return (
<>
const getList = (): ReactElement => {
return (<List
onFilterChanged={(
filterData: Dictionary<string | boolean | Search | Date>
) => {
const query: Query<TBaseModel> = {};
for (const key in filterData) {
if (
filterData[key] &&
typeof filterData[key] === Typeof.String
) {
query[key as keyof TBaseModel] = (
filterData[key] || ''
).toString();
}
if (typeof filterData[key] === Typeof.Boolean) {
query[key as keyof TBaseModel] = Boolean(
filterData[key]
);
}
if (filterData[key] instanceof Date) {
query[key as keyof TBaseModel] =
filterData[key];
}
if (filterData[key] instanceof Search) {
query[key as keyof TBaseModel] =
filterData[key];
}
}
setQuery(query);
}}
onSortChanged={(sortBy: string, sortOrder: SortOrder) => {
setSortBy(sortBy);
setSortOrder(sortOrder);
}}
singularLabel={model.singularName || 'Item'}
pluralLabel={model.pluralName || 'Items'}
error={error}
currentPageNumber={currentPageNumber}
isLoading={isLoading}
totalItemsCount={totalItemsCount}
data={BaseModel.toJSONObjectArray(data)}
id={props.id}
columns={tableColumns}
itemsOnPage={itemsOnPage}
disablePagination={props.disablePagination || false}
onNavigateToPage={async (
pageNumber: number,
itemsOnPage: number
) => {
setCurrentPageNumber(pageNumber);
setItemsOnPage(itemsOnPage);
}}
showFilter={showTableFilter}
noItemsMessage={props.noItemsMessage || ''}
onRefreshClick={() => {
fetchItems();
}}
actionButtons={actionButtonSchema}
onActionEvent={(key: ActionType, item: JSONObject) => {
if (key === ActionType.Edit) {
setModalType(ModalType.Edit);
setShowModal(true);
setCurrentEditableItem(item);
}
if (key === ActionType.Delete) {
setShowDeleteConfirmModal(true);
setCurrentDeleteableItem(item);
}
if (key === ActionType.View) {
if (!props.currentPageRoute) {
throw new BadDataException(
'Please populate curentPageRoute in ModelTable'
);
}
Navigation.navigate(
new Route(
props.currentPageRoute.toString()
).addRoute('/' + item['_id'])
);
}
}}
/>)
}
const getCardComponent = (): ReactElement => {
if (props.showAsList) {
return <div>
{props.cardProps && <Card
{...props.cardProps}
cardBodyStyle={{ padding: '0px' }}
buttons={cardButtons}
>
{getList()}
</Card>}
{!props.cardProps && getList()}
</div>
}
return <div>
{props.cardProps && <Card
{...props.cardProps}
cardBodyStyle={{ padding: '0px' }}
@ -571,8 +680,16 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
>
{getTable()}
</Card>}
{!props.cardProps && getTable()}
</div>
}
return (
<>
{getCardComponent()}
{showModel ? (
<ModelFormModal<TBaseModel>

View File

@ -1,7 +1,5 @@
import { JSONObject } from 'Common/Types/JSON';
import React, { FunctionComponent, ReactElement } from 'react';
import TableBody from './TableBody';
import TableHeader from './TableHeader';
import Columns from './Types/Columns';
import Pagination from './Pagination';
import SortOrder from 'Common/Types/Database/SortOrder';
@ -10,6 +8,7 @@ import ActionButtonSchema, { ActionType } from './Types/ActionButtonSchema';
import Search from 'Common/Types/Database/Search';
import ErrorMessage from './ErrorMessage';
import TableLoader from './Loader';
import ListBody from './ListBody';
export interface ComponentProps {
data: Array<JSONObject>;
@ -68,7 +67,7 @@ const List: FunctionComponent<ComponentProps> = (
}
return (
<TableBody
<ListBody
id={`${props.id}-body`}
data={props.data}
columns={props.columns}

View File

@ -14,7 +14,7 @@ export interface ComponentProps {
| undefined;
}
const TableBody: FunctionComponent<ComponentProps> = (
const ListBody: FunctionComponent<ComponentProps> = (
props: ComponentProps
): ReactElement => {
return (
@ -35,4 +35,4 @@ const TableBody: FunctionComponent<ComponentProps> = (
);
};
export default TableBody;
export default ListBody;

View File

@ -108,6 +108,7 @@ const App: FunctionComponent = () => {
projects={projects}
error={error}
onProjectSelected={onProjectSelected}
selectedProject={selectedProject}
>
<Routes>
<PageRoute

View File

@ -14,8 +14,13 @@ import TeamMember from 'Model/Models/TeamMember';
import User from 'CommonUI/src/Utils/User';
import FullPageModal from "CommonUI/src/Components/FullPageModal/FullPageModal";
import TeamPermission from 'Model/Models/TeamPermission';
import ModelTable from 'CommonUI/src/Components/ModelTable/ModelTable';
import { IconProp } from 'CommonUI/src/Components/Icon/Icon';
import FieldType from 'CommonUI/src/Components/Types/FieldType';
export interface ComponentProps {
selectedProject: Project | null;
projects: Array<Project>;
onProjectSelected: (project: Project) => void;
}
@ -35,7 +40,7 @@ const DashboardHeader: FunctionComponent<ComponentProps> = (
projects={props.projects}
onProjectSelected={props.onProjectSelected}
/>
<SearchBox key={2} onChange={(_value: string) => {}} />
<SearchBox key={2} onChange={(_value: string) => { }} />
<div
style={{
marginLeft: '15px',
@ -71,11 +76,47 @@ const DashboardHeader: FunctionComponent<ComponentProps> = (
/>
{showProjectInvitationModal && <FullPageModal onClose={() => {
setShowProjectInvitationModal(false);
setShowProjectInvitationModal(false);
}}>
<div>
</div>
<ModelTable<TeamPermission>
modelType={TeamPermission}
id="team-permission-table"
isDeleteable={true}
query={{
userId: User.getUserId(),
hasAcceptedInvitation: false,
}}
isEditable={false}
isCreateable={false}
isViewable={false}
cardProps={{
icon: IconProp.User,
title: 'Project Invitations',
description:
'Here is a list of projects and teams you have been invited to.',
}}
noItemsMessage={
'No proejct or team invitations for you so far.'
}
showAsList={true}
columns={[
{
field: {
projectId: true,
},
title: 'Project',
type: FieldType.Text,
isFilterable: true,
},
{
field: {
teamId: true,
},
title: 'Team',
type: FieldType.Text,
},
]}
/>
</FullPageModal>}
</>
);

View File

@ -9,6 +9,7 @@ export interface ComponentProps {
children: ReactElement | Array<ReactElement>;
isLoading: boolean;
projects: Array<Project>;
selectedProject: Project | null;
error: string;
onProjectSelected: (project: Project) => void;
}
@ -21,6 +22,7 @@ const DashboardMasterPage: FunctionComponent<ComponentProps> = (
footer={<Footer />}
header={
<Header
selectedProject={props.selectedProject}
projects={props.projects}
onProjectSelected={props.onProjectSelected}
/>