Skip to content

Commit

Permalink
Merge pull request #181 from canyener/add-loading-indicator-for-submi…
Browse files Browse the repository at this point in the history
…tting

Add loading indicator for submitting
  • Loading branch information
canyener authored Dec 13, 2020
2 parents 7733216 + 52a0845 commit 34af957
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 17 deletions.
17 changes: 14 additions & 3 deletions src/app/layout/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, Fragment } from 'react'
import React, { useState, useEffect, Fragment, SyntheticEvent } from 'react'
import { Container } from 'semantic-ui-react'

import { IActivity } from '../models/activity'
Expand All @@ -14,6 +14,8 @@ const App = () => {
const [selectedActivity, setSelectedActivity] = useState<IActivity | null>(null)
const [editMode, setEditMode] = useState(false)
const [loading, setLoading] = useState(true)
const [submitting, setSubmitting] = useState(false)
const [target, setTarget] = useState('')

const handleSelectActivity = (id: string) => {
setSelectedActivity(activities.filter(activity => activity.id === id)[0])
Expand All @@ -26,25 +28,32 @@ const App = () => {
}

const handleCreateActivity = (activity: IActivity) => {
setSubmitting(true)
agent.Activities.create(activity).then(() => {
setActivities([...activities, activity])
setSelectedActivity(activity)
setEditMode(false)
})
.then(() => setSubmitting(false))
}

const handleEditActivity = (activity: IActivity) => {
setSubmitting(true)
agent.Activities.update(activity).then(() => {
setActivities([...activities.filter(item => item.id !== activity.id), activity])
setSelectedActivity(activity)
setEditMode(false)
})
.then(() => setSubmitting(false))
}

const handleDeleteActivity = (id: string) => {
const handleDeleteActivity = (event: SyntheticEvent<HTMLButtonElement>, id: string) => {
setSubmitting(true)
setTarget(event.currentTarget.name)
agent.Activities.delete(id).then(() => {
setActivities([...activities.filter(activity => activity.id !== id)])
})
.then(() => setSubmitting(false))
}

useEffect(() => {
Expand All @@ -62,7 +71,7 @@ const App = () => {
.then(() => setLoading(false))
}, [])

if(loading) return <LoadingComponent content="Loading Activities..."/>
if (loading) return <LoadingComponent content="Loading Activities..." />

return (
<Fragment>
Expand All @@ -78,6 +87,8 @@ const App = () => {
createActivity={handleCreateActivity}
editActivity={handleEditActivity}
deleteActivity={handleDeleteActivity}
submitting={submitting}
target={target}
/>
</Container>
</Fragment>
Expand Down
13 changes: 10 additions & 3 deletions src/features/activities/dashboard/ActivityDashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { SyntheticEvent } from 'react'
import { Grid } from 'semantic-ui-react'

import { IActivity } from '../../../app/models/activity'
Expand All @@ -15,7 +15,9 @@ interface IProps {
setSelectedActivity: (activity: IActivity | null) => void
createActivity: (activity: IActivity) => void
editActivity: (activity: IActivity) => void
deleteActivity: (id: string) => void
deleteActivity: (event: SyntheticEvent<HTMLButtonElement>,id: string) => void
submitting: boolean,
target: string
}

const ActivityDashboard: React.FC<IProps> = ({
Expand All @@ -27,14 +29,18 @@ const ActivityDashboard: React.FC<IProps> = ({
setSelectedActivity,
createActivity,
editActivity,
deleteActivity
deleteActivity,
submitting,
target
}) => (
<Grid>
<Grid.Column width={10}>
<ActivityList
activities={activities}
selectActivity={selectActivity}
deleteActivity={deleteActivity}
submitting={submitting}
target={target}
/>
</Grid.Column>
<Grid.Column width={6}>
Expand All @@ -56,6 +62,7 @@ const ActivityDashboard: React.FC<IProps> = ({
activity={selectedActivity}
createActivity={createActivity}
editActivity={editActivity}
submitting={submitting}
/>
)}
</Grid.Column>
Expand Down
18 changes: 14 additions & 4 deletions src/features/activities/dashboard/ActivityList.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import React from 'react'
import React, { SyntheticEvent } from 'react'
import { Item, Button, Label, Segment } from 'semantic-ui-react'

import { IActivity } from '../../../app/models/activity'

interface IProps {
activities: IActivity[]
selectActivity: (id: string) => void
deleteActivity: (id: string) => void
deleteActivity: (event: SyntheticEvent<HTMLButtonElement>,id: string) => void
submitting: boolean
target: string
}

const ActivityList: React.FC<IProps> = ({ activities, selectActivity, deleteActivity }) => (
const ActivityList: React.FC<IProps> = ({
activities,
selectActivity,
deleteActivity,
submitting,
target
}) => (
<Segment clearing>
<Item.Group divided>
{
Expand All @@ -30,7 +38,9 @@ const ActivityList: React.FC<IProps> = ({ activities, selectActivity, deleteActi
color='blue'
/>
<Button
onClick={() => deleteActivity(activity.id)}
name={activity.id}
loading={target === activity.id && submitting}
onClick={(e) => deleteActivity(e, activity.id)}
floated='right'
content='Delete'
color='red'
Expand Down
6 changes: 4 additions & 2 deletions src/features/activities/form/ActivityForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ interface IProps {
activity: IActivity | null,
createActivity: (activity: IActivity) => void
editActivity: (activity: IActivity) => void
submitting: boolean
}

const ActivityForm: React.FC<IProps> = ({
setEditMode,
activity: initialFormState,
createActivity,
editActivity
editActivity,
submitting
}) => {
const initializeForm = () => {
if (initialFormState) {
Expand Down Expand Up @@ -91,7 +93,7 @@ const ActivityForm: React.FC<IProps> = ({
name='venue'
placeholder='Venue'
value={activity.venue} />
<Button floated='right' positive type='submit' content='Submit' />
<Button loading={submitting} floated='right' positive type='submit' content='Submit' />
<Button onClick={() => setEditMode(false)} floated='right' type='button' content='Cancel' />
</Form>
</Segment>
Expand Down
6 changes: 6 additions & 0 deletions src/tests/components/ActivityDashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ test('Should render ActivityDashboard correctly with editMode equals to false',
createActivity={() => { }}
editActivity={() => { }}
deleteActivity={() => { }}
submitting={false}
target=''
/>
)

Expand All @@ -34,6 +36,8 @@ test('Should render ActivityDashboard correctly with editMode equals to true', (
createActivity={() => { }}
editActivity={() => { }}
deleteActivity={() => { }}
submitting={false}
target=''
/>
)

Expand All @@ -52,6 +56,8 @@ test('Should render ActivityDashboard correctly with edit mode false and selecte
createActivity={() => { }}
editActivity={() => { }}
deleteActivity={() => { }}
submitting={false}
target=''
/>
)

Expand Down
3 changes: 3 additions & 0 deletions src/tests/components/ActivityForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ test('Should render ActivityForm correctly when activity prop is null', () => {
activity={null}
createActivity={() => { }}
editActivity={() => { }}
submitting={false}
/>
)

Expand All @@ -25,6 +26,7 @@ test('Should render ActivityForm correctly with given activity', () => {
activity={fakeActivities[0]}
createActivity={() => { }}
editActivity={() => { }}
submitting={false}
/>
)

Expand All @@ -40,6 +42,7 @@ test('Should call setEditMode with false when Cancel button is clicked ', () =>
activity={fakeActivities[0]}
createActivity={() => { }}
editActivity={() => { }}
submitting={false}
/>
)

Expand Down
20 changes: 15 additions & 5 deletions src/tests/components/ActivityList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ test('Should render ActivityList correctly', () => {
activities={fakeActivities}
selectActivity={() => { }}
deleteActivity={() => { }}
/>)
submitting={false}
target=''
/>
)

expect(wrapper).toMatchSnapshot()
})
Expand All @@ -23,7 +26,11 @@ test('Should call selectActivity once when button is clicked', () => {
activities={fakeActivities}
selectActivity={selectActivitySpy}
deleteActivity={() => { }}
/>)
submitting={false}
target=''
/>
)

wrapper.find('Button').first().simulate('click')
expect(selectActivitySpy).toHaveBeenCalledTimes(1)
})
Expand All @@ -35,8 +42,11 @@ test('Should call deleteActivity once when delete button is clicked', () => {
activities={fakeActivities}
selectActivity={() => { }}
deleteActivity={deleteActivitySpy}
/>)
submitting={false}
target=''
/>
)

wrapper.find('Button').at(1).simulate('click')
expect(deleteActivitySpy).toHaveBeenCalledTimes(1)
wrapper.find('Button').at(1).simulate('click')
expect(deleteActivitySpy).toHaveBeenCalledTimes(1)
})
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ exports[`Should render ActivityDashboard correctly with edit mode false and sele
}
deleteActivity={[Function]}
selectActivity={[Function]}
submitting={false}
target=""
/>
</GridColumn>
<GridColumn
Expand Down Expand Up @@ -68,6 +70,8 @@ exports[`Should render ActivityDashboard correctly with editMode equals to false
}
deleteActivity={[Function]}
selectActivity={[Function]}
submitting={false}
target=""
/>
</GridColumn>
<GridColumn
Expand Down Expand Up @@ -122,6 +126,8 @@ exports[`Should render ActivityDashboard correctly with editMode equals to true
}
deleteActivity={[Function]}
selectActivity={[Function]}
submitting={false}
target=""
/>
</GridColumn>
<GridColumn
Expand All @@ -143,6 +149,7 @@ exports[`Should render ActivityDashboard correctly with editMode equals to true
editActivity={[Function]}
key="1"
setEditMode={[Function]}
submitting={false}
/>
</GridColumn>
</Grid>
Expand Down
2 changes: 2 additions & 0 deletions src/tests/components/__snapshots__/ActivityForm.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ exports[`Should render ActivityForm correctly when activity prop is null 1`] = `
as="button"
content="Submit"
floated="right"
loading={false}
positive={true}
type="submit"
/>
Expand Down Expand Up @@ -138,6 +139,7 @@ exports[`Should render ActivityForm correctly with given activity 1`] = `
as="button"
content="Submit"
floated="right"
loading={false}
positive={true}
type="submit"
/>
Expand Down
4 changes: 4 additions & 0 deletions src/tests/components/__snapshots__/ActivityList.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ exports[`Should render ActivityList correctly 1`] = `
color="red"
content="Delete"
floated="right"
loading={false}
name="1"
onClick={[Function]}
/>
<Label
Expand Down Expand Up @@ -86,6 +88,8 @@ exports[`Should render ActivityList correctly 1`] = `
color="red"
content="Delete"
floated="right"
loading={false}
name="2"
onClick={[Function]}
/>
<Label
Expand Down
Loading

0 comments on commit 34af957

Please sign in to comment.