fix project invitation list

This commit is contained in:
Simon Larsen
2022-08-13 23:01:50 +01:00
parent b056b16f12
commit 0696fb7d29
15 changed files with 128 additions and 46 deletions

View File

View File

@@ -20,6 +20,7 @@
"Common": "file:../Common",
"formik": "^2.2.9",
"history": "^5.3.0",
"lodash": "^4.17.21",
"Model": "file:../Model",
"prop-types": "^15.8.1",
"react": "^18.1.0",

View File

@@ -20,9 +20,10 @@
"@types/react-toggle": "^4.0.3",
"bootstrap": "^5.2.0-beta1",
"Common": "file:../Common",
"Model": "file:../Model",
"formik": "^2.2.9",
"history": "^5.3.0",
"lodash": "^4.17.21",
"Model": "file:../Model",
"prop-types": "^15.8.1",
"react": "^18.1.0",
"react-color": "^2.19.3",

View File

@@ -6,6 +6,7 @@ import OneUptimeDate from 'Common/Types/Date';
import FieldType from '../Types/FieldType';
import HiddenText from '../HiddenText/HiddenText';
import { JSONObject } from 'Common/Types/JSON';
import _ from 'lodash';
export interface ComponentProps {
item: JSONObject;
@@ -28,8 +29,8 @@ const Detail: Function = (
let data: string | ReactElement = '';
if ((props.item as any)[fieldKey]) {
data = (props.item as any)[fieldKey]?.toString() || '';
if (_.get(props.item, fieldKey)) {
data = _.get(props.item, fieldKey, '')?.toString() || '';
}
if (field.fieldType === FieldType.Date) {

View File

@@ -13,6 +13,7 @@ export interface ActionButton {
export default interface Columns<TEntity> {
field?: SelectEntityField<TEntity>;
selectedProperty?: string;
title: string;
disableSort?: boolean;
type: FieldType;

View File

@@ -65,7 +65,9 @@ export interface ComponentProps<TBaseModel extends BaseModel> {
query?: Query<TBaseModel>;
onBeforeCreate?: ((item: TBaseModel) => Promise<TBaseModel>) | undefined;
createVerb?: string;
showAsList?: boolean | undefined
showAsList?: boolean | undefined;
singularName?: string | undefined;
pluralName?: string | undefined;
}
enum ModalType {
@@ -234,7 +236,7 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
if (props.isCreateable && hasPermissionToCreate) {
headerbuttons.push({
title: `${props.createVerb || 'Create'} ${model.singularName}`,
title: `${props.createVerb || 'Create'} ${props.singularName || model.singularName}`,
buttonStyle: ButtonStyleType.OUTLINE,
onClick: () => {
setModalType(ModalType.Create);
@@ -372,7 +374,7 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
columns.push({
...column,
disableSort: column.disableSort || shouldDisableSort(key),
key,
key: column.selectedProperty ? key+"."+column.selectedProperty: key,
});
if (key) {
@@ -511,8 +513,8 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
setSortBy(sortBy);
setSortOrder(sortOrder);
}}
singularLabel={model.singularName || 'Item'}
pluralLabel={model.pluralName || 'Items'}
singularLabel={props.singularName || model.singularName || 'Item'}
pluralLabel={props.pluralName || model.pluralName || 'Items'}
error={error}
currentPageNumber={currentPageNumber}
isLoading={isLoading}
@@ -603,8 +605,8 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
setSortBy(sortBy);
setSortOrder(sortOrder);
}}
singularLabel={model.singularName || 'Item'}
pluralLabel={model.pluralName || 'Items'}
singularLabel={props.singularName || model.singularName || 'Item'}
pluralLabel={props.pluralName || model.pluralName || 'Items'}
error={error}
currentPageNumber={currentPageNumber}
isLoading={isLoading}
@@ -696,9 +698,9 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
title={
modalType === ModalType.Create
? `${props.createVerb || 'Create'} New ${
model.singularName
props.singularName || model.singularName
}`
: `Edit ${model.singularName}`
: `Edit ${props.singularName || model.singularName}`
}
onClose={() => {
setShowModal(false);
@@ -706,7 +708,7 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
submitButtonText={
modalType === ModalType.Create
? `${props.createVerb || 'Create'} ${
model.singularName
props.singularName || model.singularName
}`
: `Save Changes`
}
@@ -739,9 +741,9 @@ const ModelTable: Function = <TBaseModel extends BaseModel>(
{showDeleteConfirmModal && (
<ConfirmModal
title={`Delete ${model.singularName}`}
title={`Delete ${props.singularName || model.singularName}`}
description={`Are you sure you want to delete this ${(
model.singularName || 'item'
props.singularName || model.singularName || 'item'
)?.toLowerCase()}?`}
onClose={() => {
setShowDeleteConfirmModal(false);

View File

@@ -54,15 +54,10 @@ const List: FunctionComponent<ComponentProps> = (
if (props.data.length === 0) {
return (
<tbody>
<tr>
<td colSpan={props.columns.length}>
<ErrorMessage error={props.noItemsMessage
? props.noItemsMessage
: `No ${props.singularLabel.toLocaleLowerCase()}`} onRefreshClick={props.onRefreshClick} />
</td>
</tr>
</tbody>
<ErrorMessage error={props.noItemsMessage
? props.noItemsMessage
: `No ${props.singularLabel.toLocaleLowerCase()}`} onRefreshClick={props.onRefreshClick} />
);
}

View File

@@ -18,7 +18,7 @@ const ListBody: FunctionComponent<ComponentProps> = (
props: ComponentProps
): ReactElement => {
return (
<div id={props.id}>
<div id={props.id} >
{props.data &&
props.data.map((item: JSONObject, i: number) => {
return (

View File

@@ -1,5 +1,6 @@
import { JSONObject } from 'Common/Types/JSON';
import React, { FunctionComponent, ReactElement, useEffect, useState } from 'react';
import Button, { ButtonSize } from '../Button/Button';
import Detail from '../Detail/Detail';
import Field from '../Detail/Field';
import ActionButtonSchema, { ActionType } from './Types/ActionButtonSchema';
@@ -9,8 +10,8 @@ export interface ComponentProps {
item: JSONObject;
columns: Columns;
onActionEvent?:
| ((actionType: ActionType, item: JSONObject) => void)
| undefined;
| ((actionType: ActionType, item: JSONObject) => void)
| undefined;
actionButtons?: Array<ActionButtonSchema> | undefined;
}
@@ -18,15 +19,15 @@ const ListRow: FunctionComponent<ComponentProps> = (
props: ComponentProps
): ReactElement => {
// convert column to field
const [fields, setFields] = useState<Array<Field>>([]);
useEffect(() => {
const detailFields:Array<Field> = [];
const detailFields: Array<Field> = [];
for (const column of props.columns) {
if (!column.key) {
// if its an action column, ignore.
continue;
@@ -44,8 +45,52 @@ const ListRow: FunctionComponent<ComponentProps> = (
}, [props.columns])
return (
<div>
<div className="padding-15 list-item">
<Detail item={props.item} fields={fields} />
<div>
{props.actionButtons?.map(
(
button: ActionButtonSchema,
i: number
) => {
return (
<span
style={
i > 0
? {
marginLeft:
'10px',
}
: {}
}
key={i}
>
<Button
buttonSize={
ButtonSize.Small
}
title={button.title}
icon={button.icon}
buttonStyle={
button.buttonStyleType
}
onClick={() => {
if (
props.onActionEvent
) {
props.onActionEvent(
button.actionType,
props.item
);
}
}}
/>
</span>
);
}
)}
</div>
</div>
);
};

View File

@@ -7,6 +7,7 @@ import ActionButtonSchema, { ActionType } from './Types/ActionButtonSchema';
import Column from './Types/Column';
import Columns from './Types/Columns';
import FieldType from '../Types/FieldType';
import _ from 'lodash';
export interface ComponentProps {
item: JSONObject;
@@ -58,9 +59,7 @@ const TableRow: FunctionComponent<ComponentProps> = (
/>
)
) : (
(props.item[
column.key
]?.toString() as string)
_.get(props.item, column.key, '')?.toString() || ''
)
) : (
<></>

View File

@@ -14,7 +14,8 @@ enum FieldType {
Port,
HiddenText,
Actions,
Boolean
Boolean,
Entity
}
export default FieldType;

View File

@@ -210,4 +210,26 @@
.vertical-center{
margin-top: 20%;
}
.padding-15{
padding: 15px;
}
// Lists
.list-item{
border-style: solid;
border-width: 2px;
border-color: $color-very-light-grey;
border-top: 0px;
border-right: 0px;
border-left: 0px;
}
.modal-dialog{
opacity: 1;
}

View File

@@ -14,7 +14,6 @@ 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';
@@ -78,9 +77,9 @@ const DashboardHeader: FunctionComponent<ComponentProps> = (
{showProjectInvitationModal && <FullPageModal onClose={() => {
setShowProjectInvitationModal(false);
}}>
<ModelTable<TeamPermission>
modelType={TeamPermission}
id="team-permission-table"
<ModelTable<TeamMember>
modelType={TeamMember}
id="team-member-table"
isDeleteable={true}
query={{
userId: User.getUserId(),
@@ -91,29 +90,32 @@ const DashboardHeader: FunctionComponent<ComponentProps> = (
isViewable={false}
cardProps={{
icon: IconProp.User,
title: 'Project Invitations',
title: 'Pending 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.'
'No project or team invitations for you so far.'
}
showAsList={true}
singularName="Project Invitation"
pluralName="Project Invitations"
columns={[
{
field: {
projectId: true,
project: true,
},
title: 'Project',
title: 'Project Invited to',
type: FieldType.Text,
isFilterable: true,
selectedProperty: "name"
},
{
field: {
teamId: true,
team: true,
},
title: 'Team',
title: 'Team Invited to',
type: FieldType.Text,
selectedProperty: "name"
},
]}
/>

11
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "3.0.2",
"license": "MIT",
"dependencies": {
"@types/lodash": "^4.14.182",
"eslint-plugin-progress": "^0.0.1"
},
"devDependencies": {
@@ -617,6 +618,11 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"node_modules/@types/lodash": {
"version": "4.14.182",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",
"integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz",
@@ -5020,6 +5026,11 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"@types/lodash": {
"version": "4.14.182",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",
"integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q=="
},
"@typescript-eslint/eslint-plugin": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz",

View File

@@ -5,6 +5,7 @@
"main": "index.ts",
"type": "module",
"dependencies": {
"@types/lodash": "^4.14.182",
"eslint-plugin-progress": "^0.0.1"
},
"devDependencies": {