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
Add Campaigns card in Multichannel Marketing page #36735
Changes from all commits
30d3168
af4f79a
f5799c8
c444dbd
32cf8d1
cbc616a
c67e479
558ddf2
ee6fa95
8e39098
1d7b663
7610214
d69f7f0
3384ad5
630bd0a
cd7b5f2
c342cbb
2915442
274ea3d
eda6f19
183fc48
743c0e5
0abe368
c17f336
7b068bf
048906a
c9214ab
20ae504
60d815c
cc5345d
61aa3cd
92762ca
a982b7b
f5ba6d9
a4e1192
f7a1ef2
f62b44a
3513ef5
e57181b
8e9f344
b838885
5af90c5
9feaf55
4b87f0a
c0364ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { controls as dataControls } from '@wordpress/data-controls'; | ||
import { AnyAction } from 'redux'; | ||
|
||
export const awaitResponseJson = ( | ||
response: Response | ||
): AnyAction & { response: Response } => { | ||
return { | ||
type: 'AWAIT_RESPONSE_JSON', | ||
response, | ||
}; | ||
}; | ||
|
||
const controls = { | ||
...dataControls, | ||
AWAIT_RESPONSE_JSON( action: AnyAction ) { | ||
return action.response.json(); | ||
}, | ||
}; | ||
|
||
export default controls; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,15 @@ import { | |
receiveRegisteredChannelsError, | ||
receiveRecommendedChannelsSuccess, | ||
receiveRecommendedChannelsError, | ||
receiveCampaigns, | ||
} from './actions'; | ||
import { RegisteredChannel, RecommendedChannel } from './types'; | ||
import { awaitResponseJson } from './controls'; | ||
import { | ||
RegisteredChannel, | ||
RecommendedChannel, | ||
Campaign, | ||
ApiFetchError, | ||
} from './types'; | ||
import { API_NAMESPACE } from './constants'; | ||
import { isApiFetchError } from './guards'; | ||
|
||
|
@@ -47,3 +54,63 @@ export function* getRecommendedChannels() { | |
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Get total number of records from the HTTP response header "x-wp-total". | ||
* | ||
* If the header is not present, then the function will return `undefined`. | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed param response docs |
||
const getTotalFromResponse = ( response: Response ) => { | ||
ecgan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const total = response.headers.get( 'x-wp-total' ); | ||
|
||
if ( total === null ) { | ||
return undefined; | ||
} | ||
|
||
return parseInt( total, 10 ); | ||
}; | ||
|
||
/** | ||
* Get campaigns from API backend. | ||
* | ||
* @param page Page number. First page is `1`. | ||
* @param perPage Page size, i.e. number of records in one page. | ||
*/ | ||
export function* getCampaigns( page: number, perPage: number ) { | ||
puntope marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try { | ||
const response: Response = yield apiFetch( { | ||
path: `${ API_NAMESPACE }/campaigns?page=${ page }&per_page=${ perPage }`, | ||
parse: false, | ||
} ); | ||
|
||
const total = getTotalFromResponse( response ); | ||
const payload: Campaign[] = yield awaitResponseJson( response ); | ||
|
||
yield receiveCampaigns( { | ||
payload, | ||
error: false, | ||
meta: { | ||
page, | ||
perPage, | ||
total, | ||
}, | ||
} ); | ||
} catch ( error ) { | ||
if ( error instanceof Response ) { | ||
const total = getTotalFromResponse( error ); | ||
const payload: ApiFetchError = yield awaitResponseJson( error ); | ||
|
||
yield receiveCampaigns( { | ||
payload, | ||
error: true, | ||
meta: { | ||
page, | ||
perPage, | ||
total, | ||
}, | ||
} ); | ||
} | ||
|
||
throw error; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,10 @@ export const getRegisteredChannels = ( state: State ) => { | |
export const getRecommendedChannels = ( state: State ) => { | ||
return state.recommendedChannels; | ||
}; | ||
|
||
/** | ||
* Get campaigns from state. | ||
*/ | ||
export const getCampaigns = ( state: State ) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💅 Missed JSDOCS There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed |
||
return state.campaigns; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
.woocommerce-marketing-campaigns-card { | ||
&__content { | ||
width: 50%; | ||
margin: auto; | ||
text-align: center; | ||
} | ||
|
||
&__content-icon { | ||
background-color: $studio-gray-0; | ||
border-radius: 28px; | ||
margin-bottom: $gap-smallest; | ||
|
||
&--error { | ||
fill: $alert-red; | ||
} | ||
|
||
&--empty { | ||
fill: $studio-woocommerce-purple-50; | ||
} | ||
} | ||
|
||
&__content-title { | ||
@include font-size( 13 ); | ||
font-weight: 600; | ||
line-height: 16px; | ||
color: $gray-900; | ||
margin-bottom: $gap-smallest; | ||
} | ||
|
||
&__content-description { | ||
color: $gray-700; | ||
margin-bottom: $gap-smallest; | ||
} | ||
|
||
&__campaign-logo { | ||
img { | ||
display: block; | ||
} | ||
} | ||
|
||
&__campaign-title { | ||
a { | ||
color: #007cba; | ||
font-weight: 600; | ||
text-decoration: none; | ||
} | ||
} | ||
|
||
&__campaign-description { | ||
color: $gray-700; | ||
} | ||
|
||
&__footer { | ||
justify-content: center; | ||
|
||
// Remove the border-top because the table cells already has a border-bottom. | ||
border-top: none; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💅 Missed
@param response
docs