11import PropTypes from 'prop-types' ;
22import React from 'react' ;
3- import { connect } from 'react-redux' ;
3+ import { connect , useDispatch } from 'react-redux' ;
44import { bindActionCreators } from 'redux' ;
55import { Link } from 'react-router-dom' ;
66import { Helmet } from 'react-helmet' ;
77import prettyBytes from 'pretty-bytes' ;
8- import { withTranslation } from 'react-i18next' ;
8+ import { useTranslation , withTranslation } from 'react-i18next' ;
9+ import MenuItem from '../../../components/Dropdown/MenuItem' ;
10+ import TableDropdown from '../../../components/Dropdown/TableDropdown' ;
911
1012import Loader from '../../App/components/loader' ;
13+ import { deleteAssetRequest } from '../actions/assets' ;
1114import * as AssetActions from '../actions/assets' ;
12- import DownFilledTriangleIcon from '../../../images/down-filled-triangle.svg' ;
1315
14- class AssetListRowBase extends React . Component {
15- constructor ( props ) {
16- super ( props ) ;
17- this . state = {
18- isFocused : false ,
19- optionsOpen : false
20- } ;
21- }
22-
23- onFocusComponent = ( ) => {
24- this . setState ( { isFocused : true } ) ;
25- } ;
26-
27- onBlurComponent = ( ) => {
28- this . setState ( { isFocused : false } ) ;
29- setTimeout ( ( ) => {
30- if ( ! this . state . isFocused ) {
31- this . closeOptions ( ) ;
32- }
33- } , 200 ) ;
34- } ;
35-
36- openOptions = ( ) => {
37- this . setState ( {
38- optionsOpen : true
39- } ) ;
40- } ;
16+ const AssetMenu = ( { item : asset } ) => {
17+ const { t } = useTranslation ( ) ;
4118
42- closeOptions = ( ) => {
43- this . setState ( {
44- optionsOpen : false
45- } ) ;
46- } ;
19+ const dispatch = useDispatch ( ) ;
4720
48- toggleOptions = ( ) => {
49- if ( this . state . optionsOpen ) {
50- this . closeOptions ( ) ;
51- } else {
52- this . openOptions ( ) ;
21+ const handleAssetDelete = ( ) => {
22+ const { key, name } = asset ;
23+ if ( window . confirm ( t ( 'Common.DeleteConfirmation' , { name } ) ) ) {
24+ dispatch ( deleteAssetRequest ( key ) ) ;
5325 }
5426 } ;
5527
56- handleDropdownOpen = ( ) => {
57- this . closeOptions ( ) ;
58- this . openOptions ( ) ;
59- } ;
28+ return (
29+ < TableDropdown aria-label = { t ( 'AssetList.ToggleOpenCloseARIA' ) } >
30+ < MenuItem onClick = { handleAssetDelete } > { t ( 'AssetList.Delete' ) } </ MenuItem >
31+ < MenuItem href = { asset . url } target = "_blank" >
32+ { t ( 'AssetList.OpenNewTab' ) }
33+ </ MenuItem >
34+ </ TableDropdown >
35+ ) ;
36+ } ;
6037
61- handleAssetDelete = ( ) => {
62- const { key , name } = this . props . asset ;
63- this . closeOptions ( ) ;
64- if ( window . confirm ( this . props . t ( 'Common.DeleteConfirmation' , { name } ) ) ) {
65- this . props . deleteAssetRequest ( key ) ;
66- }
67- } ;
38+ AssetMenu . propTypes = {
39+ item : PropTypes . shape ( {
40+ key : PropTypes . string . isRequired ,
41+ url : PropTypes . string . isRequired ,
42+ name : PropTypes . string . isRequired
43+ } ) . isRequired
44+ } ;
6845
69- render ( ) {
70- const { asset, username, t } = this . props ;
71- const { optionsOpen } = this . state ;
72- return (
73- < tr className = "asset-table__row" key = { asset . key } >
74- < th scope = "row" >
75- < Link to = { asset . url } target = "_blank" >
76- { asset . name }
77- </ Link >
78- </ th >
79- < td > { prettyBytes ( asset . size ) } </ td >
80- < td >
81- { asset . sketchId && (
82- < Link to = { `/${ username } /sketches/${ asset . sketchId } ` } >
83- { asset . sketchName }
84- </ Link >
85- ) }
86- </ td >
87- < td className = "asset-table__dropdown-column" >
88- < button
89- className = "asset-table__dropdown-button"
90- onClick = { this . toggleOptions }
91- onBlur = { this . onBlurComponent }
92- onFocus = { this . onFocusComponent }
93- aria-label = { t ( 'AssetList.ToggleOpenCloseARIA' ) }
94- >
95- < DownFilledTriangleIcon focusable = "false" aria-hidden = "true" />
96- </ button >
97- { optionsOpen && (
98- < ul className = "asset-table__action-dialogue" >
99- < li >
100- < button
101- className = "asset-table__action-option"
102- onClick = { this . handleAssetDelete }
103- onBlur = { this . onBlurComponent }
104- onFocus = { this . onFocusComponent }
105- >
106- { t ( 'AssetList.Delete' ) }
107- </ button >
108- </ li >
109- < li >
110- < a
111- href = { asset . url }
112- target = "_blank"
113- rel = "noreferrer"
114- onBlur = { this . onBlurComponent }
115- onFocus = { this . onFocusComponent }
116- className = "asset-table__action-option"
117- >
118- { t ( 'AssetList.OpenNewTab' ) }
119- </ a >
120- </ li >
121- </ ul >
122- ) }
123- </ td >
124- </ tr >
125- ) ;
126- }
127- }
46+ const AssetListRowBase = ( { asset, username } ) => (
47+ < tr className = "asset-table__row" key = { asset . key } >
48+ < th scope = "row" >
49+ < a href = { asset . url } target = "_blank" rel = "noopener noreferrer" >
50+ { asset . name }
51+ </ a >
52+ </ th >
53+ < td > { prettyBytes ( asset . size ) } </ td >
54+ < td >
55+ { asset . sketchId && (
56+ < Link to = { `/${ username } /sketches/${ asset . sketchId } ` } >
57+ { asset . sketchName }
58+ </ Link >
59+ ) }
60+ </ td >
61+ < td className = "asset-table__dropdown-column" >
62+ < AssetMenu item = { asset } />
63+ </ td >
64+ </ tr >
65+ ) ;
12866
12967AssetListRowBase . propTypes = {
13068 asset : PropTypes . shape ( {
@@ -135,9 +73,7 @@ AssetListRowBase.propTypes = {
13573 name : PropTypes . string . isRequired ,
13674 size : PropTypes . number . isRequired
13775 } ) . isRequired ,
138- deleteAssetRequest : PropTypes . func . isRequired ,
139- username : PropTypes . string . isRequired ,
140- t : PropTypes . func . isRequired
76+ username : PropTypes . string . isRequired
14177} ;
14278
14379function mapStateToPropsAssetListRow ( state ) {
0 commit comments