Newsroom Planner uses other plugins functionality to complete some of its tasks.
For example NRP relying on Naviga Photos to handle searching for images and handle images metadata.
Newsroom Planner uses Dashboard portals to render other plugins components in its own context.
Thanks to Dashboard mappings you can replace Naviga Photos with your own image service portal and integrate your plugin into Newsroom Planner
What kind of portals does Newsroom Planner use?
Newsroom Planner uses 4 different portals in order to search for images and link them or display images as a gallery or upload images.
Search for images and link them to an Assignment.
Display Assignment's images.
Change Assignment's images metadata.
Upload Images, and link them to an Assignment.
ImageSearch portal
This portal used to search for images and link the selected images to the active assignment.
Where is it rendered?
In My assignment view:
In assignment detail view:
Props:
A callback function expected to be called with array of image's uuid, filename .
A localizations object contains localized strings.
A flag to tell the portal that NRP in an edit mode or not.
Newsroom Planner doesn't call any methods from ImageSearch portal
Example:
Copy const MySearchPortal = props => {
const [ selectedImages , setSelectedImages ] = useState ([])
const {
onLink
} = props
const handleOnSelect = selectedImage => {
const images = selectedImages .push (selectedImage)
setSelectedImages (images)
}
const handleLinkImages = () => {
/*
selectedImages format:
[
{
filename: 'myImage.jpg'
uuid: '123-123-321321-123-123'
},
{
filename: 'logo.jpg'
uuid: '444-423-774238-321-006'
}
]
*/
onLink (selectedImages)
}
return (
< div >
< SearchInput />
< LinkButton onClick = {handleLinkImages}/>
< ImagesWrapper onSelect = {handleOnSelect}>
< img />
< img />
< img />
< img />
< img />
</ ImagesWrapper >
</ div >
)
}
Localizations
Supports English & Swedish
Copy console .log ( this . props .localizations)
/*
{
link: 'Link selected photos'
}
*/
How Newsroom Planner render ImageSearch
Copy const ImageSearchWrapper = props => {
const {
editMode ,
localize ,
linkImagesToAssignment
} = props
const handleOnLink = selectedImages => {
linkImagesToAssignment (selectedImages)
}
return (
< div >
< ImageSearch
editMode = {editMode}
onLink = {handlOnLink}
localizations = {{
link : localize ( 'linkSelectedPhotos' )
}}
/>
</ div >
)
}
ImageGallery portal
This portal used to display the active assignment's images.
Where is it rendered?
In My assignment view:
In assignment detail view:
Props:
A callback function expected to be called if the portal made any changes to the mages.
A callback function expected to be called if the portal made any changes to the images.
A callback helper function to close the confirm dialog if it's triggered.
A callback function expected to be called with all the images and a boolean for the selected images. Used in My Assignment view more info below
An array of the Assignment images.
A boolean to tell the portal that NRP in an edit mode or not.
A boolean to tell the portal if it can handle images metadata or not.
A boolean to tell the portal if it's rendered within My Assignment view or Assignment Detail view more info below
A localizations object contains localized strings.
NRP require some methods to be accessible from NRP components more info below
Example:
Copy const MyGalleryPortal = (props , ref) => {
const [ images , setImages ] = useState ( props .images)
const {
onSave ,
onCancel ,
onSelection
} = props
useEffect (() => {
/*
Methods will be called by NRP.
*/
if (ref && ref .current) {
ref .current = {
selectAll : () => {} ,
deselectAll : () => {} ,
updateImages : () => {}
}
}
})
const handleOnSelect = selectedImage => {
const mappedItems = images .map (item => {
if ( item .uuid === selectedImage .uuid) {
return {
... item ,
selected : true
}
} else {
return item
}
})
setImages (mappedItems)
// Update NRP with updated images
onSelection (mappedItems)
}
return (
< div >
< SearchInput />
< LinkButton onClick = {handleLinkImages}/>
< ImagesWrapper onSelect = {handleOnSelect}>
< img />
< img />
< img />
< img />
< img />
</ ImagesWrapper >
</ div >
)
}
export default forwardRef (MyGalleryPortal)
Localizations
Supports English & Swedish
Copy console .log ( this . props .localizations)
/*
{
link: 'Link selected photos'
}
*/
Functions should be accessible from NRP provided by ImageGallery portal
updateImages
A function will give the updated images from the Assignment.
selectAll
A function to handle selecting all images.
deselectAll
A function to handle deselect all images.
How NRP render ImageGallery
My Assignment view Assignment Detail view
Copy const MyAssignmentPortalWrapper = props => {
const {
assignment ,
confirm ,
closeConfirm ,
closeGallery ,
resetImageGalleryPortal
} = props
const imageGalleryRef = useRef ()
/*
This hook will track the active Assignemnt
if the user clicked on another assignment to show the images
this hook will call "updateImages" function from ImageGallery
portal and pass the new active Assignment's images
*/
useEffect (() => {
if ( imageGalleryRef .current && typeof imageGalleryRef . current .updateImages === 'function' ) {
const updatedImages = assignment . images .map (item => {
return {
uuid : item .uuid ,
filename : item .filename
}
})
imageGalleryRef . current .updateImages (updatedImages)
}
} , [ assignment .uuid])
const handleReset = () => {
resetImageGalleryPortal ()
}
const handleOnClose = () => {
if ( imageGalleryRef .current) {
if ( typeof imageGalleryRef . current .cancel === 'function' ) {
imageGalleryRef . current .cancel ()
}
}
closeGallery ()
}
const images = assignment . images .map (item => {
return {
uuid : item .uuid ,
filename : item .filename
}
})
return (
< div >
< CloseButton onClick = {handleOnClose}/>
< ImageGallery
editMode = { true }
managePhotos = { true }
confirm = {confirm}
images = { assignment .images}
ref = {imageGalleryRef}
onSave = {handleReset}
onCancel = {handleReset}
closeConfirm = {closeConfirm}
key = {imageGalleryRenderKey}
/>
</ div >
)
}
Copy const AssignmentDetailPortalWrapper = props => {
const {
assignment ,
confirm ,
closeConfirm ,
openMetadataModal
} = props
const [ selectedImages , setSelectedImages ] = useState ([])
const imageGalleryRef = useRef ()
const handleOnSelectction = images => {
setSelectedImages ( images .filter (image => image .selected))
}
const handleUnlinkFromAssignment = () => {
if ( selectedImages . length ) {
selectedImages .forEach (item => {
unlinkImage ( item .uuid)
})
if ( imageGalleryRef .current) {
if ( typeof imageGalleryRef . current .updateImages === 'function' ) {
const updatedImages = assignment . images .map (i => {
return {
uuid : i .uuid ,
filename : i .filename
}
})
imageGalleryRef . current .updateImages (updatedImages)
}
}
setSelectedImages ([])
}
}
const handleSelect = () => {
if ( imageGalleryRef .current) {
if ( ! selectedImages . length ) {
if ( typeof imageGalleryRef . current .selectAll === 'function' ) {
imageGalleryRef . current .selectAll ()
}
} else {
if ( typeof imageGalleryRef . current .desselectAll === 'function' ) {
imageGalleryRef . current .desselectAll ()
}
}
}
}
const handleImagesMetadata = () => {
/*
This function will open ImageMetadata portal inside a Modal
with all selected images
*/
openMetadataModal ({
images : selectedImages
})
}
const images = assignment . images .map (item => {
return {
uuid : item .uuid ,
filename : item .filename
}
})
return (
< div >
< OpenImagesMetadata onClick = {handleImagesMetadata}/>
< UnLinkButton onClick = {handleUnlinkFromAssignment}/>
< SelectButton onClick = {handleSelect}/>
< ImageGallery
editMode = { true }
fullWidth = { true }
confirm = {confirm}
images = {images}
ref = {imageGalleryRef}
closeConfirm = {closeConfirm}
onSelectction = {handleOnSelectction}
localizations = {{
link : localize ( 'linkSelectedPhotos' ) // 'Link selected photos'
}}
/>
</ div >
)
}
ImageUpload portal
This portal used to upload images, and provide the uploaded images to be linked to the active assignment.
Where is it rendered?
In My assignment view:
Props
A callback function expected to be called with images array when the images has been uploaded.
A callback function expected to be called when the portal starts uploading images.
A callback function expected to be called when the user cancel uploading images.
A callback helper function to close the confirm dialog if it's triggered.
NRP require some methods to be accessible from NRP components more info below
Example
Copy const MyUploadPortal = (props , ref) => {
const [ selectedFile , setSelectedFile ] = useState ( null )
const {
onDone ,
onUpload ,
onCancel
} = props
useEffect (() => {
/*
Methods will be called by NRP.
*/
if (ref && ref .current) {
ref .current = {
cancel : cancelProccess
}
}
})
const handlePhotos = file => {
setSelectedFile (file)
}
const handleUpload = () => {
if (selectedFile) {
onUpload ()
fetch ( 'api/upload' , {selectedFile})
.then ((response) => {
const uploadedImages = response . images .map (item => {
return {
uuid : item .uuid ,
filename : item .filename
}
})
onDone (uploadedImages)
})
}
}
const handleCancel = () => {
cancelProccess ()
onCancel ()
}
const cancelProcesses = () => {
// cacnel on going processes...
}
return (
< div >
< BrowsButton onChange = {handlePhotos}/>
< UploadButton onClick = {handleUpload}/>
< CancelButton onClick = {handleCancel}/>
</ div >
)
}
export default forwardRef (MyUploadPortal)
Functions should be accessible from NRP provided by ImageUpload portal
cancel
A function will be called when the ImageUpload portal is unmounted to clean up onGoing processes for example.
How NRP render ImageUpload
Copy const MyAssignmentPortalWrapper = props => {
const {
assignment ,
confirm ,
closeConfirm ,
closeUploadPortal
} = props
const imageUploadRef = useRef ()
const handleOnClose = () => {
if ( imageUploadRef .current) {
if ( typeof imageUploadRef . current .cancel === 'function' ) {
imageUploadRef . current .cancel ()
}
}
closeUploadPortal ()
}
const handleUploadedImages = uploadedImages => {
assignment .linkImages (uploadedImages)
}
const handleOnUploadStart = () => {
assignment .setUploadingFlag ()
}
return (
< div >
< CloseButton onClick = {handleOnClose}/>
< ImageUpload
confirm = {confirm}
ref = {imageUploadRef}
onCancel = {handleOnCancel}
closeConfirm = {closeConfirm}
onDone = {handleUploadedImages}
onUpload = {handleOnUploadStart}
/>
</ div >
)
}
ImageMetadata portal
This portal used to change images metadata
Where is it rendered?
In Assignment detail view:
Props
An array of the selected images to change metadata on them.
A callback function expected to be called when the user done with updating metadata for the images.
A callback function expected to be called when the user cancel updating images metadata.
A callback helper function to close the confirm dialog if it's triggered.
NRP require some methods to be accessible from NRP components more info below
Example
Copy const MyMetadataPortal = (props , ref) => {
const {
images ,
onSave ,
onCancel
} = props
useEffect (() => {
/*
Methods will be called by NRP.
*/
if (ref && ref .current) {
ref .current = {
cancel : cancelProccess
}
}
})
const handleSave = () => {
// Update images metadata
onSave ()
}
const handleCancel = () => {
cancelProccess ()
onCancel ()
}
const cancelProcesses = () => {
// cacnel on going processes...
}
const selectedImages = images .map (image => {
return (
< div key = { image .uuid}>
< TakenByField />
...
< img />
</ div >
)
})
return (
< div >
< SaveButton onChange = {handleSave}/>
< CancelButton onClick = {handleCancel}/>
{ selectedImages }
</ div >
)
}
export default forwardRef (MyUploadPortal)
Functions should be accessible from NRP provided by ImageMetadata portal
cancel
A function will be called when the ImageMetadata portal is unmounted to clean up onGoing processes for example.
How NRP render ImageMetadata
Copy const MyAssignmentPortalWrapper = props => {
const {
selectedImages ,
confirm ,
closeConfirm ,
closeMetadataPortal
} = props
const imageMetadataRef = useRef ()
const handleOnClose = () => {
if ( imageMetadataRef .current) {
if ( typeof imageMetadataRef . current .cancel === 'function' ) {
imageMetadataRef . current .cancel ()
}
}
closeMetadataPortal ()
}
const handleOnSave = () => {
closeMetadataPortal ()
}
const handleOnCancel = () => {
closeMetadataPortal ()
}
return (
< div >
< CloseButton onClick = {closeMetadataPortal}/>
< ImageMetadata
images = {selectedImages}
confirm = {confirm}
onSave = {handleOnSave}
onCancel = {handleOnCancel}
ref = {imageMetadataRef}
closeConfirm = {closeConfirm}
/>
</ div >
)
}