Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
05f003d3
Unverified
Commit
05f003d3
authored
Apr 01, 2019
by
Robert Knight
Committed by
GitHub
Apr 01, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1028 from hypothesis/group-list-item-react
Convert `<group-list-item>` component to React
parents
ca1e0ed9
c1f7c449
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
92 additions
and
93 deletions
+92
-93
group-list-item.js
src/sidebar/components/group-list-item.js
+55
-26
group-list-item-test.js
src/sidebar/components/test/group-list-item-test.js
+32
-41
index.js
src/sidebar/index.js
+5
-1
group-list-item.html
src/sidebar/templates/group-list-item.html
+0
-25
No files found.
src/sidebar/components/group-list-item.js
View file @
05f003d3
'use strict'
;
'use strict'
;
const
{
const
classnames
=
require
(
'classnames'
);
orgName
,
const
propTypes
=
require
(
'prop-types'
);
trackViewGroupActivity
,
const
{
createElement
}
=
require
(
'preact'
);
}
=
require
(
'../util/group-list-item-common'
);
// @ngInject
function
GroupListItemController
(
analytics
,
store
)
{
this
.
focusGroup
=
function
()
{
analytics
.
track
(
analytics
.
events
.
GROUP_SWITCH
);
store
.
focusGroup
(
this
.
group
.
id
);
};
this
.
isSelected
=
function
()
{
const
{
orgName
}
=
require
(
'../util/group-list-item-common'
);
return
this
.
group
.
id
===
store
.
focusedGroupId
();
};
this
.
orgName
=
function
()
{
function
GroupListItem
({
analytics
,
group
,
store
})
{
return
orgName
(
this
.
group
);
const
focusGroup
=
()
=>
{
analytics
.
track
(
analytics
.
events
.
GROUP_SWITCH
);
store
.
focusGroup
(
group
.
id
);
};
};
this
.
trackViewGroupActivity
=
function
()
{
const
isSelected
=
group
.
id
===
store
.
focusedGroupId
();
trackViewGroupActivity
(
analytics
);
const
groupOrgName
=
orgName
(
group
);
};
return
(
<
div
className
=
{
classnames
({
'group-list-item__item'
:
true
,
'is-selected'
:
isSelected
,
})}
onClick
=
{
focusGroup
}
tabIndex
=
"0"
>
{
/* the group icon */
}
<
div
className
=
"group-list-item__icon-container"
>
{
group
.
logo
&&
(
<
img
className
=
"group-list-item__icon group-list-item__icon--organization"
alt
=
{
groupOrgName
}
src
=
{
group
.
logo
}
/
>
)}
<
/div
>
{
/* the group name */
}
<
div
className
=
"group-list-item__details"
>
<
a
className
=
"group-list-item__name-link"
href
=
""
title
=
{
group
.
type
===
'private'
?
`Show and create annotations in
${
group
.
name
}
`
:
'Show public annotations'
}
>
{
group
.
name
}
<
/a
>
<
/div
>
<
/div
>
);
}
}
module
.
exports
=
{
GroupListItem
.
propTypes
=
{
controller
:
GroupListItemController
,
group
:
propTypes
.
object
.
isRequired
,
controllerAs
:
'vm'
,
bindings
:
{
analytics
:
propTypes
.
object
.
isRequired
,
group
:
'<'
,
store
:
propTypes
.
object
.
isRequired
,
},
template
:
require
(
'../templates/group-list-item.html'
),
};
};
GroupListItem
.
injectedProps
=
[
'analytics'
,
'store'
];
module
.
exports
=
GroupListItem
;
src/sidebar/components/test/group-list-item-test.js
View file @
05f003d3
'use strict'
;
'use strict'
;
const
angular
=
require
(
'angular'
);
const
{
createElement
}
=
require
(
'preact'
);
const
{
mount
}
=
require
(
'enzyme'
);
const
proxyquire
=
require
(
'proxyquire'
);
const
proxyquire
=
require
(
'proxyquire'
);
const
util
=
require
(
'../../directive/test/util'
);
const
{
events
}
=
require
(
'../../services/analytics'
);
const
{
events
}
=
require
(
'../../services/analytics'
);
describe
(
'
g
roupListItem'
,
()
=>
{
describe
(
'
G
roupListItem'
,
()
=>
{
let
fakeAnalytics
;
let
fakeAnalytics
;
let
fakeStore
;
let
fakeStore
;
let
fakeGroupListItemCommon
;
let
fakeGroupListItemCommon
;
let
GroupListItem
;
before
(()
=>
{
before
(()
=>
{
fakeGroupListItemCommon
=
{
fakeGroupListItemCommon
=
{
...
@@ -17,13 +18,10 @@ describe('groupListItem', () => {
...
@@ -17,13 +18,10 @@ describe('groupListItem', () => {
trackViewGroupActivity
:
sinon
.
stub
(),
trackViewGroupActivity
:
sinon
.
stub
(),
};
};
// Return groupListItem with groupListItemCommon stubbed out.
GroupListItem
=
proxyquire
(
'../group-list-item'
,
{
const
groupListItem
=
proxyquire
(
'../group-list-item'
,
{
'../util/group-list-item-common'
:
fakeGroupListItemCommon
,
'../util/group-list-item-common'
:
fakeGroupListItemCommon
,
'@noCallThru'
:
true
,
'@noCallThru'
:
true
,
});
});
angular
.
module
(
'app'
,
[]).
component
(
'groupListItem'
,
groupListItem
);
});
});
beforeEach
(()
=>
{
beforeEach
(()
=>
{
...
@@ -36,64 +34,54 @@ describe('groupListItem', () => {
...
@@ -36,64 +34,54 @@ describe('groupListItem', () => {
track
:
sinon
.
stub
(),
track
:
sinon
.
stub
(),
events
,
events
,
};
};
angular
.
mock
.
module
(
'app'
,
{
analytics
:
fakeAnalytics
,
store
:
fakeStore
,
});
});
});
const
createGroupListItem
=
fakeGroup
=>
{
const
createGroupListItem
=
fakeGroup
=>
{
return
util
.
createDirective
(
document
,
'groupListItem'
,
{
return
mount
(
group
:
fakeGroup
,
<
GroupListItem
});
group
=
{
fakeGroup
}
analytics
=
{
fakeAnalytics
}
store
=
{
fakeStore
}
/
>
);
};
};
it
(
'changes the focused group when group is clicked'
,
()
=>
{
it
(
'changes the focused group when group is clicked'
,
()
=>
{
const
fakeGroup
=
{
id
:
'groupid'
};
const
fakeGroup
=
{
id
:
'groupid'
};
const
element
=
createGroupListItem
(
fakeGroup
);
const
wrapper
=
createGroupListItem
(
fakeGroup
);
const
group
=
element
.
find
(
'.group-list-item__item'
);
wrapper
.
find
(
'.group-list-item__item'
).
simulate
(
'click'
);
group
[
0
].
click
();
assert
.
calledWith
(
fakeStore
.
focusGroup
,
fakeGroup
.
id
);
assert
.
calledWith
(
fakeStore
.
focusGroup
,
fakeGroup
.
id
);
assert
.
calledWith
(
fakeAnalytics
.
track
,
fakeAnalytics
.
events
.
GROUP_SWITCH
);
assert
.
calledWith
(
fakeAnalytics
.
track
,
fakeAnalytics
.
events
.
GROUP_SWITCH
);
});
});
it
(
'calls groupListItemCommon.trackViewGroupActivity when trackViewGroupActivity is called'
,
()
=>
{
it
(
'sets alt text for organization logo'
,
()
=>
{
const
fakeGroup
=
{
id
:
'groupid'
};
const
fakeGroup
=
{
id
:
'groupid'
,
const
element
=
createGroupListItem
(
fakeGroup
);
// Dummy scheme to avoid actually trying to load image.
element
.
ctrl
.
trackViewGroupActivity
();
logo
:
'dummy://hypothes.is/logo.svg'
,
organization
:
{
name
:
'org'
},
assert
.
calledWith
(
};
fakeGroupListItemCommon
.
trackViewGroupActivity
,
fakeAnalytics
);
});
it
(
'returns groupListItemCommon.orgName when orgName is called'
,
()
=>
{
const
fakeGroup
=
{
id
:
'groupid'
,
organization
:
{
name
:
'org'
}
};
fakeGroupListItemCommon
.
orgName
fakeGroupListItemCommon
.
orgName
.
withArgs
(
fakeGroup
)
.
withArgs
(
fakeGroup
)
.
returns
(
fakeGroup
.
organization
.
name
);
.
returns
(
fakeGroup
.
organization
.
name
);
const
element
=
createGroupListItem
(
fakeGroup
);
const
wrapper
=
createGroupListItem
(
fakeGroup
);
const
orgName
=
element
.
ctrl
.
orgName
()
;
const
altText
=
wrapper
.
find
(
'img'
).
props
().
alt
;
assert
.
equal
(
orgName
,
fakeGroup
.
organization
.
name
);
assert
.
equal
(
altText
,
fakeGroup
.
organization
.
name
);
});
});
describe
(
'
isSelected
'
,
()
=>
{
describe
(
'
selected state
'
,
()
=>
{
[
[
{
{
description
:
'
returns true
if group is the focused group'
,
description
:
'
is selected
if group is the focused group'
,
focusedGroupId
:
'groupid'
,
focusedGroupId
:
'groupid'
,
expectedIsSelected
:
true
,
expectedIsSelected
:
true
,
},
},
{
{
description
:
'
returns false
if group is not the focused group'
,
description
:
'
is not selected
if group is not the focused group'
,
focusedGroupId
:
'other'
,
focusedGroupId
:
'other'
,
expectedIsSelected
:
false
,
expectedIsSelected
:
false
,
},
},
...
@@ -102,9 +90,12 @@ describe('groupListItem', () => {
...
@@ -102,9 +90,12 @@ describe('groupListItem', () => {
fakeStore
.
focusedGroupId
.
returns
(
focusedGroupId
);
fakeStore
.
focusedGroupId
.
returns
(
focusedGroupId
);
const
fakeGroup
=
{
id
:
'groupid'
};
const
fakeGroup
=
{
id
:
'groupid'
};
const
element
=
createGroupListItem
(
fakeGroup
);
const
wrapper
=
createGroupListItem
(
fakeGroup
);
assert
.
equal
(
element
.
ctrl
.
isSelected
(),
expectedIsSelected
);
assert
.
equal
(
wrapper
.
find
(
'.group-list-item__item'
).
hasClass
(
'is-selected'
),
expectedIsSelected
);
});
});
});
});
});
});
...
...
src/sidebar/index.js
View file @
05f003d3
...
@@ -30,6 +30,7 @@ document.body.setAttribute('ng-csp', '');
...
@@ -30,6 +30,7 @@ document.body.setAttribute('ng-csp', '');
disableOpenerForExternalLinks
(
document
.
body
);
disableOpenerForExternalLinks
(
document
.
body
);
const
angular
=
require
(
'angular'
);
const
angular
=
require
(
'angular'
);
const
wrapReactComponent
=
require
(
'./util/wrap-react-component'
);
// autofill-event relies on the existence of window.angular so
// autofill-event relies on the existence of window.angular so
// it must be require'd after angular is first require'd
// it must be require'd after angular is first require'd
...
@@ -154,7 +155,10 @@ function startAngularApp(config) {
...
@@ -154,7 +155,10 @@ function startAngularApp(config) {
.
component
(
'dropdownMenuBtn'
,
require
(
'./components/dropdown-menu-btn'
))
.
component
(
'dropdownMenuBtn'
,
require
(
'./components/dropdown-menu-btn'
))
.
component
(
'excerpt'
,
require
(
'./components/excerpt'
))
.
component
(
'excerpt'
,
require
(
'./components/excerpt'
))
.
component
(
'groupList'
,
require
(
'./components/group-list'
))
.
component
(
'groupList'
,
require
(
'./components/group-list'
))
.
component
(
'groupListItem'
,
require
(
'./components/group-list-item'
))
.
component
(
'groupListItem'
,
wrapReactComponent
(
require
(
'./components/group-list-item'
))
)
.
component
(
.
component
(
'groupListItemOutOfScope'
,
'groupListItemOutOfScope'
,
require
(
'./components/group-list-item-out-of-scope'
)
require
(
'./components/group-list-item-out-of-scope'
)
...
...
src/sidebar/templates/group-list-item.html
deleted
100644 → 0
View file @
ca1e0ed9
<div
ng-class=
"{'group-list-item__item': true, 'is-selected': vm.isSelected()}"
ng-click=
"vm.focusGroup()"
tabindex=
"0"
>
<!-- the group icon !-->
<div
class=
"group-list-item__icon-container"
>
<img
class=
"group-list-item__icon group-list-item__icon--organization"
alt=
"{{ vm.orgName() }}"
ng-src=
"{{ vm.group.logo }}"
ng-if=
"vm.group.logo"
/>
</div>
<!-- the group name and share link -->
<div
class=
"group-list-item__details"
>
<a
class=
"group-list-item__name-link"
href=
""
title=
"{{ vm.group.type === 'private' ? 'Show and create annotations in ' + vm.group.name : 'Show public annotations' }}"
>
{{vm.group.name}}
</a>
</div>
</div>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment