2019-03-25 02:24:49 +00:00
import React from 'react' ;
import PropTypes from 'prop-types' ;
import moment from 'moment' ;
import { gettext , siteRoot } from '../../utils/constants' ;
import { Utils } from '../../utils/utils' ;
const propTypes = {
noticeItem : PropTypes . object . isRequired ,
2023-09-13 00:40:50 +00:00
tr : PropTypes . any ,
2020-03-24 07:24:47 +00:00
onNoticeItemClick : PropTypes . func
2019-03-25 02:24:49 +00:00
} ;
2019-04-17 10:21:00 +00:00
const MSG _TYPE _ADD _USER _TO _GROUP = 'add_user_to_group' ;
const MSG _TYPE _REPO _SHARE = 'repo_share' ;
const MSG _TYPE _REPO _SHARE _TO _GROUP = 'repo_share_to_group' ;
const MSG _TYPE _REPO _TRANSFER = 'repo_transfer' ;
const MSG _TYPE _FILE _UPLOADED = 'file_uploaded' ;
2024-04-09 14:09:07 +00:00
const MSG _TYPE _FOLDER _UPLOADED = 'folder_uploaded' ;
2023-09-13 00:40:50 +00:00
// const MSG_TYPE_GUEST_INVITATION_ACCEPTED = 'guest_invitation_accepted';
2023-01-16 09:56:05 +00:00
const MSG _TYPE _REPO _MONITOR = 'repo_monitor' ;
2023-07-19 02:44:30 +00:00
const MSG _TYPE _DELETED _FILES = 'deleted_files' ;
2024-01-17 06:49:23 +00:00
const MSG _TYPE _SAML _SSO _FAILED = 'saml_sso_failed' ;
2024-02-23 06:38:19 +00:00
const MSG _TYPE _REPO _SHARE _PERM _CHANGE = 'repo_share_perm_change' ;
const MSG _TYPE _REPO _SHARE _PERM _DELETE = 'repo_share_perm_delete' ;
2019-03-25 02:24:49 +00:00
class NoticeItem extends React . Component {
generatorNoticeInfo ( ) {
let noticeItem = this . props . noticeItem ;
let noticeType = noticeItem . type ;
let detail = noticeItem . detail ;
if ( noticeType === MSG _TYPE _ADD _USER _TO _GROUP ) {
let avatar _url = detail . group _staff _avatar _url ;
let groupStaff = detail . group _staff _name ;
2020-11-02 05:56:35 +00:00
2021-04-14 08:31:48 +00:00
// group name does not support special characters
2019-03-25 02:24:49 +00:00
let userHref = siteRoot + 'profile/' + detail . group _staff _email + '/' ;
let groupHref = siteRoot + 'group/' + detail . group _id + '/' ;
let groupName = detail . group _name ;
let notice = gettext ( 'User {user_link} has added you to {group_link}' ) ;
let userLink = '<a href=' + userHref + '>' + groupStaff + '</a>' ;
let groupLink = '<a href=' + groupHref + '>' + groupName + '</a>' ;
notice = notice . replace ( '{user_link}' , userLink ) ;
notice = notice . replace ( '{group_link}' , groupLink ) ;
return { avatar _url , notice } ;
}
if ( noticeType === MSG _TYPE _REPO _SHARE ) {
let avatar _url = detail . share _from _user _avatar _url ;
let shareFrom = detail . share _from _user _name ;
let repoName = detail . repo _name ;
let repoUrl = siteRoot + 'library/' + detail . repo _id + '/' + repoName + '/' ;
let path = detail . path ;
let notice = '' ;
2021-04-14 08:31:48 +00:00
// 1. handle translate
2019-03-25 02:24:49 +00:00
if ( path === '/' ) { // share repo
notice = gettext ( '{share_from} has shared a library named {repo_link} to you.' ) ;
} else { // share folder
notice = gettext ( '{share_from} has shared a folder named {repo_link} to you.' ) ;
}
2021-04-14 08:31:48 +00:00
// 2. handle xss(cross-site scripting)
2019-03-25 02:24:49 +00:00
notice = notice . replace ( '{share_from}' , shareFrom ) ;
2021-04-14 08:31:48 +00:00
notice = notice . replace ( '{repo_link}' , ` {tagA} ${ repoName } {/tagA} ` ) ;
notice = Utils . HTMLescape ( notice ) ;
2023-01-16 09:56:05 +00:00
2021-04-14 08:31:48 +00:00
// 3. add jump link
notice = notice . replace ( '{tagA}' , ` <a href=' ${ Utils . encodePath ( repoUrl ) } '> ` ) ;
notice = notice . replace ( '{/tagA}' , '</a>' ) ;
2019-03-25 02:24:49 +00:00
return { avatar _url , notice } ;
}
2024-02-23 06:38:19 +00:00
if ( noticeType === MSG _TYPE _REPO _SHARE _PERM _CHANGE ) {
let avatar _url = detail . share _from _user _avatar _url ;
let shareFrom = detail . share _from _user _name ;
let permission = detail . permission ;
let repoName = detail . repo _name ;
let repoUrl = siteRoot + 'library/' + detail . repo _id + '/' + repoName + '/' ;
let path = detail . path ;
let notice = '' ;
// 1. handle translate
if ( path === '/' ) { // share repo
notice = gettext ( '{share_from} has changed the permission of library {repo_link} to {permission}.' ) ;
} else { // share folder
notice = gettext ( '{share_from} has changed the permission of folder {repo_link} to {permission}.' ) ;
}
// 2. handle xss(cross-site scripting)
notice = notice . replace ( '{share_from}' , shareFrom ) ;
notice = notice . replace ( '{repo_link}' , ` {tagA} ${ repoName } {/tagA} ` ) ;
notice = notice . replace ( '{permission}' , permission ) ;
notice = Utils . HTMLescape ( notice ) ;
// 3. add jump link
notice = notice . replace ( '{tagA}' , ` <a href=' ${ Utils . encodePath ( repoUrl ) } '> ` ) ;
notice = notice . replace ( '{/tagA}' , '</a>' ) ;
return { avatar _url , notice } ;
}
if ( noticeType === MSG _TYPE _REPO _SHARE _PERM _DELETE ) {
let avatar _url = detail . share _from _user _avatar _url ;
let shareFrom = detail . share _from _user _name ;
let repoName = detail . repo _name ;
let path = detail . path ;
let notice = '' ;
// 1. handle translate
if ( path === '/' ) { // share repo
notice = gettext ( '{share_from} has cancelled the sharing of library {repo_name}.' ) ;
} else { // share folder
notice = gettext ( '{share_from} has cancelled the sharing of folder {repo_name}.' ) ;
}
// 2. handle xss(cross-site scripting)
notice = notice . replace ( '{share_from}' , shareFrom ) ;
notice = notice . replace ( '{repo_name}' , repoName ) ;
notice = Utils . HTMLescape ( notice ) ;
return { avatar _url , notice } ;
}
2019-03-25 02:24:49 +00:00
if ( noticeType === MSG _TYPE _REPO _SHARE _TO _GROUP ) {
let avatar _url = detail . share _from _user _avatar _url ;
let shareFrom = detail . share _from _user _name ;
let repoName = detail . repo _name ;
let repoUrl = siteRoot + 'library/' + detail . repo _id + '/' + repoName + '/' ;
let groupUrl = siteRoot + 'group/' + detail . group _id + '/' ;
2020-11-02 05:56:35 +00:00
let groupName = detail . group _name ;
2019-03-25 02:24:49 +00:00
let path = detail . path ;
let notice = '' ;
2021-04-14 08:31:48 +00:00
// 1. handle translate
2019-03-25 02:24:49 +00:00
if ( path === '/' ) {
notice = gettext ( '{share_from} has shared a library named {repo_link} to group {group_link}.' ) ;
} else {
notice = gettext ( '{share_from} has shared a folder named {repo_link} to group {group_link}.' ) ;
}
2023-01-16 09:56:05 +00:00
2021-04-14 08:31:48 +00:00
// 2. handle xss(cross-site scripting)
2019-03-25 02:24:49 +00:00
notice = notice . replace ( '{share_from}' , shareFrom ) ;
2021-04-14 08:31:48 +00:00
notice = notice . replace ( '{repo_link}' , ` {tagA} ${ repoName } {/tagA} ` ) ;
notice = notice . replace ( '{group_link}' , ` {tagB} ${ groupName } {/tagB} ` ) ;
notice = Utils . HTMLescape ( notice ) ;
2023-01-16 09:56:05 +00:00
2021-04-14 08:31:48 +00:00
// 3. add jump link
notice = notice . replace ( '{tagA}' , ` <a href=' ${ Utils . encodePath ( repoUrl ) } '> ` ) ;
notice = notice . replace ( '{/tagA}' , '</a>' ) ;
notice = notice . replace ( '{tagB}' , ` <a href=' ${ Utils . encodePath ( groupUrl ) } '> ` ) ;
notice = notice . replace ( '{/tagB}' , '</a>' ) ;
2019-03-25 02:24:49 +00:00
return { avatar _url , notice } ;
}
if ( noticeType === MSG _TYPE _REPO _TRANSFER ) {
let avatar _url = detail . transfer _from _user _avatar _url ;
let repoOwner = detail . transfer _from _user _name ;
let repoName = detail . repo _name ;
let repoUrl = siteRoot + 'library/' + detail . repo _id + '/' + repoName + '/' ;
2021-04-14 08:31:48 +00:00
// 1. handle translate
2019-03-25 02:24:49 +00:00
let notice = gettext ( '{user} has transfered a library named {repo_link} to you.' ) ;
2021-04-14 08:31:48 +00:00
// 2. handle xss(cross-site scripting)
2019-03-25 02:24:49 +00:00
notice = notice . replace ( '{user}' , repoOwner ) ;
2021-04-14 08:31:48 +00:00
notice = notice . replace ( '{repo_link}' , ` {tagA} ${ repoName } {/tagA} ` ) ;
notice = Utils . HTMLescape ( notice ) ;
2023-01-16 09:56:05 +00:00
2021-04-14 08:31:48 +00:00
// 3. add jump link
notice = notice . replace ( '{tagA}' , ` <a href= ${ Utils . encodePath ( repoUrl ) } > ` ) ;
notice = notice . replace ( '{/tagA}' , '</a>' ) ;
2019-03-25 02:24:49 +00:00
return { avatar _url , notice } ;
}
if ( noticeType === MSG _TYPE _FILE _UPLOADED ) {
let avatar _url = detail . uploaded _user _avatar _url ;
let fileName = detail . file _name ;
2021-04-14 08:31:48 +00:00
let fileLink = siteRoot + 'lib/' + detail . repo _id + '/' + 'file' + detail . file _path ;
2019-03-25 02:24:49 +00:00
let folderName = detail . folder _name ;
2021-04-14 08:31:48 +00:00
let folderLink = siteRoot + 'library/' + detail . repo _id + '/' + detail . repo _name + detail . folder _path ;
2019-03-25 02:24:49 +00:00
let notice = '' ;
if ( detail . repo _id ) { // todo is repo exist ?
2021-04-14 08:31:48 +00:00
// 1. handle translate
2019-03-25 02:24:49 +00:00
notice = gettext ( 'A file named {upload_file_link} is uploaded to {uploaded_link}.' ) ;
2021-04-14 08:31:48 +00:00
// 2. handle xss(cross-site scripting)
notice = notice . replace ( '{upload_file_link}' , ` {tagA} ${ fileName } {/tagA} ` ) ;
notice = notice . replace ( '{uploaded_link}' , ` {tagB} ${ folderName } {/tagB} ` ) ;
notice = Utils . HTMLescape ( notice ) ;
2023-01-16 09:56:05 +00:00
2021-04-14 08:31:48 +00:00
// 3. add jump link
notice = notice . replace ( '{tagA}' , ` <a href= ${ Utils . encodePath ( fileLink ) } > ` ) ;
notice = notice . replace ( '{/tagA}' , '</a>' ) ;
notice = notice . replace ( '{tagB}' , ` <a href= ${ Utils . encodePath ( folderLink ) } > ` ) ;
notice = notice . replace ( '{/tagB}' , '</a>' ) ;
2019-03-25 02:24:49 +00:00
} else {
2021-04-14 08:31:48 +00:00
// 1. handle translate
2019-04-03 10:26:03 +00:00
notice = gettext ( 'A file named {upload_file_link} is uploaded to {uploaded_link}.' ) ;
2021-04-14 08:31:48 +00:00
// 2. handle xss(cross-site scripting)
notice = notice . replace ( '{upload_file_link}' , ` ${ fileName } ` ) ;
notice = Utils . HTMLescape ( notice ) ;
2023-02-03 01:51:18 +00:00
notice = notice . replace ( '{uploaded_link}' , '<strong>Deleted Library</strong>' ) ;
2019-03-25 02:24:49 +00:00
}
return { avatar _url , notice } ;
}
2024-04-09 14:09:07 +00:00
if ( noticeType === MSG _TYPE _FOLDER _UPLOADED ) {
let avatar _url = detail . uploaded _user _avatar _url ;
let folderName = detail . folder _name ;
let folderLink = siteRoot + 'library/' + detail . repo _id + '/' + detail . repo _name + detail . folder _path ;
let parentDirName = detail . parent _dir _name ;
let parentDirLink = siteRoot + 'library/' + detail . repo _id + '/' + detail . repo _name + detail . parent _dir _path ;
let notice = '' ;
if ( detail . repo _id ) { // todo is repo exist ?
// 1. handle translate
notice = gettext ( 'A folder named {upload_folder_link} is uploaded to {uploaded_link}.' ) ;
// 2. handle xss(cross-site scripting)
notice = notice . replace ( '{upload_folder_link}' , ` {tagA} ${ folderName } {/tagA} ` ) ;
notice = notice . replace ( '{uploaded_link}' , ` {tagB} ${ parentDirName } {/tagB} ` ) ;
notice = Utils . HTMLescape ( notice ) ;
// 3. add jump link
notice = notice . replace ( '{tagA}' , ` <a href= ${ Utils . encodePath ( folderLink ) } > ` ) ;
notice = notice . replace ( '{/tagA}' , '</a>' ) ;
notice = notice . replace ( '{tagB}' , ` <a href= ${ Utils . encodePath ( parentDirLink ) } > ` ) ;
notice = notice . replace ( '{/tagB}' , '</a>' ) ;
} else {
// 1. handle translate
notice = gettext ( 'A folder named {upload_folder_link} is uploaded to {uploaded_link}.' ) ;
// 2. handle xss(cross-site scripting)
notice = notice . replace ( '{upload_folder_link}' , ` ${ folderName } ` ) ;
notice = Utils . HTMLescape ( notice ) ;
notice = notice . replace ( '{uploaded_link}' , '<strong>Deleted Library</strong>' ) ;
}
return { avatar _url , notice } ;
}
2023-01-16 09:56:05 +00:00
if ( noticeType === MSG _TYPE _REPO _MONITOR ) {
2023-02-03 01:51:18 +00:00
const {
op _user _avatar _url : avatar _url ,
op _user _email ,
op _user _name ,
op _type ,
repo _id , repo _name ,
obj _type ,
obj _path _list ,
old _obj _path _list
} = detail ;
const userProfileURL = ` ${ siteRoot } profile/ ${ encodeURIComponent ( op _user _email ) } ` ;
const userLink = ` <a href= ${ userProfileURL } target="_blank"> ${ Utils . HTMLescape ( op _user _name ) } </a> ` ;
const repoURL = ` ${ siteRoot } library/ ${ repo _id } / ${ encodeURIComponent ( repo _name ) } / ` ;
const repoLink = ` <a href= ${ repoURL } target="_blank"> ${ Utils . HTMLescape ( repo _name ) } </a> ` ;
2023-01-16 09:56:05 +00:00
2023-02-03 01:51:18 +00:00
let notice = '' ;
if ( obj _type == 'file' ) {
const fileName = Utils . getFileName ( obj _path _list [ 0 ] ) ;
const fileURL = ` ${ siteRoot } lib/ ${ repo _id } /file ${ Utils . encodePath ( obj _path _list [ 0 ] ) } ` ;
const fileLink = ` <a href= ${ fileURL } target="_blank"> ${ Utils . HTMLescape ( fileName ) } </a> ` ;
switch ( op _type ) {
2023-01-16 09:56:05 +00:00
case 'create' :
2023-02-03 01:51:18 +00:00
notice = obj _path _list . length == 1 ? gettext ( '{user} created file {fileName} in library {libraryName}.' ) : gettext ( '{user} created file {fileName} and {fileCount} other file(s) in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'delete' :
2023-02-03 01:51:18 +00:00
notice = obj _path _list . length == 1 ? gettext ( '{user} deleted file {fileName} in library {libraryName}.' ) : gettext ( '{user} deleted file {fileName} and {fileCount} other file(s) in library {libraryName}.' ) ;
notice = notice . replace ( '{fileName}' , fileName ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'recover' :
2023-02-03 01:51:18 +00:00
notice = gettext ( '{user} restored file {fileName} in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'rename' :
2023-02-03 01:51:18 +00:00
notice = gettext ( '{user} renamed file {oldFileName} {fileName} in library {libraryName}.' ) ;
notice = notice . replace ( '{oldFileName}' , Utils . getFileName ( old _obj _path _list [ 0 ] ) ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'move' :
2023-02-03 01:51:18 +00:00
notice = obj _path _list . length == 1 ? gettext ( '{user} moved file {fileName} in library {libraryName}.' ) : gettext ( '{user} moved file {fileName} and {fileCount} other file(s) in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'edit' :
2023-02-03 01:51:18 +00:00
notice = gettext ( '{user} updated file {fileName} in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
2023-02-03 01:51:18 +00:00
// no default
2023-01-16 09:56:05 +00:00
}
2023-02-03 01:51:18 +00:00
notice = notice . replace ( '{fileName}' , fileLink ) ;
notice = notice . replace ( '{fileCount}' , obj _path _list . length - 1 ) ;
2023-01-16 09:56:05 +00:00
} else { // dir
2023-02-03 01:51:18 +00:00
const folderName = Utils . getFolderName ( obj _path _list [ 0 ] ) ;
const folderURL = ` ${ siteRoot } library/ ${ repo _id } / ${ encodeURIComponent ( repo _name ) } ${ Utils . encodePath ( obj _path _list [ 0 ] ) } ` ;
const folderLink = ` <a href= ${ folderURL } target="_blank"> ${ Utils . HTMLescape ( folderName ) } </a> ` ;
2023-01-16 09:56:05 +00:00
switch ( detail . op _type ) {
case 'create' :
2023-02-03 01:51:18 +00:00
notice = obj _path _list . length == 1 ? gettext ( '{user} created folder {folderName} in library {libraryName}.' ) : gettext ( '{user} created folder {folderName} and {folderCount} other folder(s) in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'delete' :
2023-02-03 01:51:18 +00:00
notice = obj _path _list . length == 1 ? gettext ( '{user} deleted folder {folderName} in library {libraryName}.' ) : gettext ( '{user} deleted folder {folderName} and {folderCount} other folder(s) in library {libraryName}.' ) ;
notice = notice . replace ( '{folderName}' , folderName ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'recover' :
2023-02-03 01:51:18 +00:00
notice = gettext ( '{user} restored folder {folderName} in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'rename' :
2023-02-03 01:51:18 +00:00
notice = gettext ( '{user} renamed folder {oldFolderName} {folderName} in library {libraryName}.' ) ;
notice = notice . replace ( '{oldFolderName}' , Utils . getFolderName ( old _obj _path _list [ 0 ] ) ) ;
2023-01-16 09:56:05 +00:00
break ;
case 'move' :
2023-02-03 01:51:18 +00:00
notice = obj _path _list . length == 1 ? gettext ( '{user} moved folder {folderName} in library {libraryName}.' ) : gettext ( '{user} moved folder {folderName} and {folderCount} other folder(s) in library {libraryName}.' ) ;
2023-01-16 09:56:05 +00:00
break ;
2023-02-03 01:51:18 +00:00
// no default
2023-01-16 09:56:05 +00:00
}
2023-02-03 01:51:18 +00:00
notice = notice . replace ( '{folderName}' , folderLink ) ;
notice = notice . replace ( '{folderCount}' , obj _path _list . length - 1 ) ;
2023-01-16 09:56:05 +00:00
}
2023-02-03 01:51:18 +00:00
notice = notice . replace ( '{user}' , userLink ) ;
notice = notice . replace ( '{libraryName}' , repoLink ) ;
2023-01-16 09:56:05 +00:00
2023-02-03 01:51:18 +00:00
return { avatar _url , notice } ;
2023-01-16 09:56:05 +00:00
}
2023-07-19 02:44:30 +00:00
if ( noticeType === MSG _TYPE _DELETED _FILES ) {
const {
repo _id ,
repo _name ,
} = detail ;
const repoURL = ` ${ siteRoot } library/ ${ repo _id } / ${ encodeURIComponent ( repo _name ) } / ` ;
const repoLink = ` <a href= ${ repoURL } target="_blank"> ${ Utils . HTMLescape ( repo _name ) } </a> ` ;
let notice = gettext ( 'Your library {libraryName} has recently deleted a large number of files.' ) ;
notice = notice . replace ( '{libraryName}' , repoLink ) ;
return { avatar _url : null , notice } ;
}
2024-01-17 06:49:23 +00:00
if ( noticeType === MSG _TYPE _SAML _SSO _FAILED ) {
const { error _msg } = detail ;
let notice = gettext ( error _msg ) ;
return { avatar _url : null , notice } ;
}
2019-03-25 02:24:49 +00:00
// if (noticeType === MSG_TYPE_GUEST_INVITATION_ACCEPTED) {
2020-11-02 05:56:35 +00:00
2019-03-25 02:24:49 +00:00
// }
2020-11-02 05:56:35 +00:00
2019-03-26 07:37:19 +00:00
return { avatar _url : null , notice : null } ;
2019-03-25 02:24:49 +00:00
}
onNoticeItemClick = ( ) => {
let item = this . props . noticeItem ;
if ( item . seen === true ) {
return ;
}
this . props . onNoticeItemClick ( item ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-03-25 02:24:49 +00:00
render ( ) {
let noticeItem = this . props . noticeItem ;
let { avatar _url , notice } = this . generatorNoticeInfo ( ) ;
2019-03-26 07:37:19 +00:00
if ( ! avatar _url && ! notice ) {
return '' ;
}
2020-03-24 07:24:47 +00:00
return this . props . tr ? (
< tr className = { noticeItem . seen ? 'read' : 'unread font-weight-bold' } >
< td className = "text-center" >
< img src = { avatar _url } width = "32" height = "32" className = "avatar" alt = "" / >
< / t d >
2020-03-30 13:27:45 +00:00
< td className = "pr-1 pr-md-8" >
2020-03-24 07:24:47 +00:00
< p className = "m-0" dangerouslySetInnerHTML = { { _ _html : notice } } > < / p >
< / t d >
< td >
{ moment ( noticeItem . time ) . fromNow ( ) }
< / t d >
< / t r >
) : (
2019-03-25 02:24:49 +00:00
< li onClick = { this . onNoticeItemClick } className = { noticeItem . seen ? 'read' : 'unread' } >
< div className = "notice-item" >
< div className = "main-info" >
2019-06-04 09:59:54 +00:00
< img src = { avatar _url } width = "32" height = "32" className = "avatar" alt = "" / >
2019-03-25 02:24:49 +00:00
< p className = "brief" dangerouslySetInnerHTML = { { _ _html : notice } } > < / p >
< / d i v >
2019-04-08 03:50:40 +00:00
< p className = "time" > { moment ( noticeItem . time ) . fromNow ( ) } < / p >
2019-03-25 02:24:49 +00:00
< / d i v >
< / l i >
2019-04-17 10:21:00 +00:00
) ;
2019-03-25 02:24:49 +00:00
}
}
NoticeItem . propTypes = propTypes ;
export default NoticeItem ;