added more fields to a bazaar project
Signed-off-by: Lykke Axlin <lykkeaxlin@hotmail.com> Co-authored-by: klaraab <klarabroman@live.se>
This commit is contained in:
@@ -16,11 +16,11 @@
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { SubmitHandler } from 'react-hook-form';
|
||||
import { UseFormReset, UseFormGetValues } from 'react-hook-form';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { ProjectDialog } from '../ProjectDialog';
|
||||
import { ProjectSelector } from '../ProjectSelector';
|
||||
import { BazaarProject, FormValues, Status } from '../../types';
|
||||
import { BazaarProject, FormValues, Size, Status } from '../../types';
|
||||
import { bazaarApiRef } from '../../api';
|
||||
|
||||
type Props = {
|
||||
@@ -52,6 +52,10 @@ export const AddProjectDialog = ({
|
||||
community: '',
|
||||
announcement: '',
|
||||
status: 'proposed' as Status,
|
||||
size: 'medium' as Size,
|
||||
responsible: '',
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
};
|
||||
|
||||
const handleListItemClick = (entity: Entity) => {
|
||||
@@ -63,9 +67,9 @@ export const AddProjectDialog = ({
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const handleSave: SubmitHandler<FormValues> = async (
|
||||
getValues: any,
|
||||
reset: any,
|
||||
const handleSave: any = async (
|
||||
getValues: UseFormGetValues<FormValues>,
|
||||
reset: UseFormReset<FormValues>,
|
||||
) => {
|
||||
const formValues = getValues();
|
||||
|
||||
@@ -77,6 +81,10 @@ export const AddProjectDialog = ({
|
||||
status: formValues.status,
|
||||
community: formValues.community,
|
||||
membersCount: 0,
|
||||
size: formValues.size,
|
||||
startDate: formValues.startDate ?? null,
|
||||
endDate: formValues.endDate ?? null,
|
||||
responsible: formValues.responsible,
|
||||
} as BazaarProject);
|
||||
|
||||
fetchBazaarProjects();
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import { Controller, Control, UseFormSetValue } from 'react-hook-form';
|
||||
import { FormValues } from '../../types';
|
||||
import {
|
||||
KeyboardDatePicker,
|
||||
MuiPickersUtilsProvider,
|
||||
} from '@material-ui/pickers';
|
||||
import LuxonUtils from '@date-io/luxon';
|
||||
import { IconButton } from '@material-ui/core';
|
||||
import ClearIcon from '@material-ui/icons/Clear';
|
||||
|
||||
type Props = {
|
||||
name: 'startDate' | 'endDate';
|
||||
control: Control<FormValues, object>;
|
||||
setValue: UseFormSetValue<FormValues>;
|
||||
};
|
||||
|
||||
export const DateSelector = ({ name, control, setValue }: Props) => {
|
||||
const label = `${
|
||||
name.charAt(0).toLocaleUpperCase('en-US') + name.slice(1, name.indexOf('D'))
|
||||
} date`;
|
||||
|
||||
return (
|
||||
<Controller
|
||||
name={name}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<FormControl>
|
||||
<MuiPickersUtilsProvider utils={LuxonUtils}>
|
||||
<KeyboardDatePicker
|
||||
disablePast
|
||||
disableToolbar
|
||||
format="dd-MM-yyyy"
|
||||
label={label}
|
||||
value={field.value}
|
||||
onChange={date => {
|
||||
setValue(name, date?.toISO());
|
||||
}}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<IconButton onClick={() => setValue(name, null)}>
|
||||
<ClearIcon />
|
||||
</IconButton>
|
||||
),
|
||||
}}
|
||||
InputAdornmentProps={{
|
||||
position: 'start',
|
||||
}}
|
||||
/>
|
||||
</MuiPickersUtilsProvider>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DateSelector } from './DateSelector';
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Control, UseFormSetValue } from 'react-hook-form';
|
||||
import { FormValues } from '../../types';
|
||||
import { Typography } from '@material-ui/core';
|
||||
import { DateSelector } from '../DateSelector/DateSelector';
|
||||
|
||||
type Props = {
|
||||
control: Control<FormValues, object>;
|
||||
setValue: UseFormSetValue<FormValues>;
|
||||
};
|
||||
|
||||
export const DoubleDateSelector = ({ control, setValue }: Props) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
marginTop: '0.25rem',
|
||||
textAlign: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
float: 'left',
|
||||
}}
|
||||
>
|
||||
<DateSelector name="startDate" control={control} setValue={setValue} />
|
||||
</div>
|
||||
|
||||
<Typography
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
fontSize: '1.5rem',
|
||||
margin: '0 1rem',
|
||||
}}
|
||||
>
|
||||
-
|
||||
</Typography>
|
||||
<div
|
||||
style={{
|
||||
float: 'right',
|
||||
}}
|
||||
>
|
||||
<DateSelector name="endDate" control={control} setValue={setValue} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DoubleDateSelector } from './DoubleDateSelector';
|
||||
@@ -18,8 +18,9 @@ import React, { useState, useEffect } from 'react';
|
||||
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { ProjectDialog } from '../ProjectDialog';
|
||||
import { BazaarProject, FormValues } from '../../types';
|
||||
import { BazaarProject, FormValues, Size, Status } from '../../types';
|
||||
import { bazaarApiRef } from '../../api';
|
||||
import { UseFormGetValues } from 'react-hook-form';
|
||||
|
||||
type Props = {
|
||||
entity: Entity;
|
||||
@@ -41,6 +42,10 @@ export const EditProjectDialog = ({
|
||||
announcement: bazaarProject.announcement,
|
||||
community: bazaarProject.community,
|
||||
status: bazaarProject.status,
|
||||
size: bazaarProject.size,
|
||||
startDate: bazaarProject?.startDate ?? null,
|
||||
endDate: bazaarProject?.endDate ?? null,
|
||||
responsible: bazaarProject.responsible,
|
||||
});
|
||||
|
||||
const bazaarApi = useApi(bazaarApiRef);
|
||||
@@ -50,19 +55,27 @@ export const EditProjectDialog = ({
|
||||
announcement: bazaarProject.announcement,
|
||||
community: bazaarProject.community,
|
||||
status: bazaarProject.status,
|
||||
size: bazaarProject.size,
|
||||
startDate: bazaarProject?.startDate ?? null,
|
||||
endDate: bazaarProject?.endDate ?? null,
|
||||
responsible: bazaarProject.responsible,
|
||||
});
|
||||
}, [bazaarProject]);
|
||||
|
||||
const handleSave: any = async (getValues: any, _: any) => {
|
||||
const handleSave: any = async (getValues: UseFormGetValues<FormValues>) => {
|
||||
const formValues = getValues();
|
||||
|
||||
const updateResponse = await bazaarApi.updateMetadata({
|
||||
name: entity.metadata.name,
|
||||
entityRef: stringifyEntityRef(entity),
|
||||
announcement: formValues.announcement,
|
||||
status: formValues.status,
|
||||
status: formValues.status as Status,
|
||||
community: formValues.community,
|
||||
membersCount: bazaarProject.membersCount,
|
||||
size: formValues.size as Size,
|
||||
startDate: formValues?.startDate ?? null,
|
||||
endDate: formValues?.endDate ?? null,
|
||||
responsible: formValues.responsible,
|
||||
});
|
||||
|
||||
if (updateResponse.status === 'ok') fetchBazaarProject();
|
||||
|
||||
@@ -121,6 +121,10 @@ export const EntityBazaarInfoCard = () => {
|
||||
status: metadata.status,
|
||||
updatedAt: metadata.updated_at,
|
||||
membersCount: metadata.members_count,
|
||||
size: metadata.size,
|
||||
startDate: metadata.start_date,
|
||||
endDate: metadata.end_date,
|
||||
responsible: metadata.responsible,
|
||||
} as BazaarProject;
|
||||
}
|
||||
}
|
||||
@@ -259,7 +263,7 @@ export const EntityBazaarInfoCard = () => {
|
||||
</MenuList>
|
||||
</Popover>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Grid item xs={10}>
|
||||
<AboutField label="Announcement">
|
||||
{bazaarProject?.value?.announcement
|
||||
? bazaarProject?.value?.announcement
|
||||
@@ -278,17 +282,11 @@ export const EntityBazaarInfoCard = () => {
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
<AboutField label="Status">
|
||||
<StatusTag status={bazaarProject?.value?.status || 'proposed'} />
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6}>
|
||||
<Grid style={{ marginRight: '0rem' }}>
|
||||
{' '}
|
||||
<AboutField label="Latest members">
|
||||
{members?.value?.length ? (
|
||||
members.value.slice(0, 3).map((member: Member) => {
|
||||
members.value.slice(0, 7).map((member: Member) => {
|
||||
return (
|
||||
<div key={member.userId}>
|
||||
<Avatar
|
||||
@@ -299,6 +297,7 @@ export const EntityBazaarInfoCard = () => {
|
||||
fontSize: '8px',
|
||||
float: 'left',
|
||||
marginRight: '0.3rem',
|
||||
marginBottom: '0.25rem',
|
||||
}}
|
||||
picture={member.picture}
|
||||
/>
|
||||
@@ -317,6 +316,44 @@ export const EntityBazaarInfoCard = () => {
|
||||
)}
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<AboutField label="Status">
|
||||
<StatusTag status={bazaarProject?.value?.status || 'proposed'} />
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<AboutField label="size">
|
||||
<Typography variant="body2">
|
||||
{bazaarProject?.value?.size}
|
||||
</Typography>
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<AboutField label="Start date">
|
||||
<Typography variant="body2">
|
||||
{bazaarProject?.value?.startDate?.substring(0, 10) || ''}
|
||||
</Typography>
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<AboutField label="End date">
|
||||
<Typography variant="body2">
|
||||
{bazaarProject?.value?.endDate?.substring(0, 10) || ''}
|
||||
</Typography>
|
||||
</AboutField>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<AboutField label="Responsible">
|
||||
<Typography variant="body2">
|
||||
{bazaarProject?.value?.responsible || ''}
|
||||
</Typography>
|
||||
</AboutField>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -19,13 +19,18 @@ import { Controller, Control, FieldError } from 'react-hook-form';
|
||||
import { TextField } from '@material-ui/core';
|
||||
import { FormValues } from '../../types';
|
||||
|
||||
type Rules = {
|
||||
required: boolean;
|
||||
pattern?: any;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
inputType: 'announcement' | 'community';
|
||||
inputType: 'announcement' | 'community' | 'responsible';
|
||||
error?: FieldError | undefined;
|
||||
control: Control<FormValues, object>;
|
||||
helperText?: string;
|
||||
placeholder?: string;
|
||||
rules?: Object;
|
||||
rules?: Rules | undefined;
|
||||
};
|
||||
|
||||
export const InputField = ({
|
||||
@@ -47,6 +52,7 @@ export const InputField = ({
|
||||
render={({ field }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
required={rules?.required}
|
||||
margin="dense"
|
||||
multiline
|
||||
id="title"
|
||||
|
||||
@@ -25,7 +25,7 @@ import { FormValues } from '../../types';
|
||||
type Props = {
|
||||
options: string[];
|
||||
control: Control<FormValues, object>;
|
||||
name: 'announcement' | 'status';
|
||||
name: 'status' | 'size';
|
||||
error?: FieldError | undefined;
|
||||
};
|
||||
|
||||
@@ -42,14 +42,17 @@ export const InputSelector = ({ name, options, control, error }: Props) => {
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth>
|
||||
<InputLabel
|
||||
required
|
||||
htmlFor="demo-simple-select-outlined"
|
||||
id="demo-simple-select-outlined-label"
|
||||
style={{
|
||||
marginTop: '0.25rem',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</InputLabel>
|
||||
<Select
|
||||
{...field}
|
||||
required
|
||||
labelId="demo-simple-select-outlined-label"
|
||||
id="demo-simple-select-outlined"
|
||||
label={label}
|
||||
|
||||
@@ -26,10 +26,16 @@ import MuiDialogContent from '@material-ui/core/DialogContent';
|
||||
import MuiDialogActions from '@material-ui/core/DialogActions';
|
||||
import CloseIcon from '@material-ui/icons/Close';
|
||||
import { Button, Dialog, Typography, IconButton } from '@material-ui/core';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import {
|
||||
useForm,
|
||||
SubmitHandler,
|
||||
UseFormReset,
|
||||
UseFormGetValues,
|
||||
} from 'react-hook-form';
|
||||
import { InputField } from '../InputField/InputField';
|
||||
import { InputSelector } from '../InputSelector/InputSelector';
|
||||
import { FormValues } from '../../types';
|
||||
import { DoubleDateSelector } from '../DoubleDateSelector/DoubleDateSelector';
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -87,7 +93,10 @@ const DialogActions = withStyles((theme: Theme) => ({
|
||||
}))(MuiDialogActions);
|
||||
|
||||
type Props = {
|
||||
handleSave: (getValues: any, reset: any) => SubmitHandler<FormValues>;
|
||||
handleSave: (
|
||||
getValues: UseFormGetValues<FormValues>,
|
||||
reset: UseFormReset<FormValues>,
|
||||
) => SubmitHandler<FormValues>;
|
||||
isAddForm: boolean;
|
||||
title: string;
|
||||
defaultValues: FormValues;
|
||||
@@ -111,6 +120,7 @@ export const ProjectDialog = ({
|
||||
control,
|
||||
getValues,
|
||||
formState: { errors },
|
||||
setValue,
|
||||
} = useForm<FormValues>({
|
||||
mode: 'onChange',
|
||||
defaultValues: defaultValues,
|
||||
@@ -137,7 +147,6 @@ export const ProjectDialog = ({
|
||||
<DialogTitle id="customized-dialog-title" onClose={handleCloseAndClear}>
|
||||
{title}
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent dividers>
|
||||
{isAddForm && projectSelector}
|
||||
|
||||
@@ -152,23 +161,41 @@ export const ProjectDialog = ({
|
||||
placeholder="Describe who you are and what skills you are looking for"
|
||||
/>
|
||||
|
||||
<InputSelector
|
||||
control={control}
|
||||
name="status"
|
||||
options={['proposed', 'ongoing']}
|
||||
/>
|
||||
|
||||
<InputSelector
|
||||
control={control}
|
||||
name="size"
|
||||
options={['small', 'medium', 'large']}
|
||||
/>
|
||||
|
||||
<DoubleDateSelector setValue={setValue} control={control} />
|
||||
|
||||
<InputField
|
||||
error={errors.responsible}
|
||||
control={control}
|
||||
rules={{
|
||||
required: false,
|
||||
}}
|
||||
inputType="responsible"
|
||||
placeholder="Contact person of the project"
|
||||
/>
|
||||
|
||||
<InputField
|
||||
error={errors.community}
|
||||
control={control}
|
||||
rules={{
|
||||
required: false,
|
||||
pattern: RegExp('^(https?)://[^s$.?#].[^s]*$'),
|
||||
pattern: RegExp('^(https?)://'),
|
||||
}}
|
||||
inputType="community"
|
||||
helperText="please enter a link starting with http/https"
|
||||
placeholder="Community link to e.g. Teams or Discord"
|
||||
/>
|
||||
|
||||
<InputSelector
|
||||
control={control}
|
||||
name="status"
|
||||
options={['proposed', 'ongoing']}
|
||||
/>
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions>
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Content } from '@backstage/core-components';
|
||||
import { ProjectCard } from '../ProjectCard/ProjectCard';
|
||||
import { makeStyles, Grid } from '@material-ui/core';
|
||||
import Pagination from '@material-ui/lab/Pagination';
|
||||
import { makeStyles, Grid, TablePagination } from '@material-ui/core';
|
||||
import { BazaarProject } from '../../types';
|
||||
|
||||
type Props = {
|
||||
@@ -42,12 +41,18 @@ const useStyles = makeStyles({
|
||||
|
||||
export const ProjectPreview = ({ bazaarProjects, sortingMethod }: Props) => {
|
||||
const classes = useStyles();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const pageSize = 10;
|
||||
const pageCount = Math.ceil(bazaarProjects.length / pageSize);
|
||||
const [page, setPage] = useState(1);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(10);
|
||||
|
||||
const handlePageClick = (_: any, pageIndex: number) => {
|
||||
setCurrentPage(pageIndex);
|
||||
const handleChangePage = (_: any, newPage: number) => {
|
||||
setPage(newPage + 1);
|
||||
};
|
||||
|
||||
const handleChangeRowsPerPage = (
|
||||
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
setRowsPerPage(parseInt(event.target.value, 10));
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
if (!bazaarProjects.length) {
|
||||
@@ -72,37 +77,31 @@ export const ProjectPreview = ({ bazaarProjects, sortingMethod }: Props) => {
|
||||
<Content className={classes.content} noPadding>
|
||||
<Grid wrap="wrap" container spacing={3}>
|
||||
{bazaarProjects
|
||||
.slice(pageSize * (currentPage - 1), pageSize * currentPage)
|
||||
.map((bazaarProject: BazaarProject) => {
|
||||
const entityRef = bazaarProject.entityRef;
|
||||
|
||||
.slice((page - 1) * rowsPerPage, rowsPerPage * page)
|
||||
.map((bazaarProject: BazaarProject, i: number) => {
|
||||
return (
|
||||
<Grid
|
||||
key={(entityRef as string) || ''}
|
||||
className={classes.item}
|
||||
item
|
||||
xs={3}
|
||||
>
|
||||
<ProjectCard
|
||||
bazaarProject={bazaarProject}
|
||||
key={Math.random()}
|
||||
/>
|
||||
<Grid key={i} className={classes.item} item xs={3}>
|
||||
<ProjectCard bazaarProject={bazaarProject} key={i} />
|
||||
</Grid>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
<Pagination
|
||||
showFirstButton
|
||||
showLastButton
|
||||
siblingCount={2}
|
||||
|
||||
<TablePagination
|
||||
count={bazaarProjects?.length}
|
||||
page={page - 1}
|
||||
onPageChange={handleChangePage}
|
||||
rowsPerPage={rowsPerPage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
backIconButtonProps={{ disabled: page === 1 }}
|
||||
nextIconButtonProps={{
|
||||
disabled: rowsPerPage * page >= bazaarProjects.length,
|
||||
}}
|
||||
style={{
|
||||
marginTop: '1rem',
|
||||
marginLeft: 'auto',
|
||||
marginRight: '0',
|
||||
}}
|
||||
count={pageCount}
|
||||
page={currentPage}
|
||||
onChange={handlePageClick}
|
||||
/>
|
||||
</Content>
|
||||
);
|
||||
|
||||
@@ -45,7 +45,7 @@ export const ProjectSelector = ({
|
||||
isFormInvalid && value === '' ? 'Please select a project' : ''
|
||||
}
|
||||
{...params}
|
||||
label="Select a project"
|
||||
label="Select a project *"
|
||||
/>
|
||||
)}
|
||||
onChange={(_, data) => onChange(data!)}
|
||||
|
||||
@@ -100,6 +100,10 @@ export const SortView = () => {
|
||||
community: project.community,
|
||||
updatedAt: project.updated_at,
|
||||
membersCount: project.members_count,
|
||||
size: project.size,
|
||||
startDate: project.startDate,
|
||||
endDate: project.endDate,
|
||||
responsible: project.responsible,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ export type Member = {
|
||||
|
||||
export type Status = 'ongoing' | 'proposed';
|
||||
|
||||
export type Size = 'small' | 'medium' | 'large';
|
||||
|
||||
export type BazaarProject = {
|
||||
name: string;
|
||||
entityRef: EntityRef;
|
||||
@@ -33,10 +35,18 @@ export type BazaarProject = {
|
||||
announcement: string;
|
||||
updatedAt?: string;
|
||||
membersCount: number;
|
||||
size: Size;
|
||||
startDate?: string | null;
|
||||
endDate?: string | null;
|
||||
responsible: string;
|
||||
};
|
||||
|
||||
export type FormValues = {
|
||||
announcement: string;
|
||||
community: string;
|
||||
status: string;
|
||||
size: Size;
|
||||
startDate?: string | null;
|
||||
endDate?: string | null;
|
||||
responsible: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user