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
b382243d
Commit
b382243d
authored
Sep 23, 2015
by
Nick Stenning
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2514 from robertknight/t87-group_scope_dropdown_ui
T87 - Improve group scope dropdown ui
parents
89bfa6b3
8699869d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
336 additions
and
52 deletions
+336
-52
app.coffee
h/static/scripts/app.coffee
+1
-1
group-list.js
h/static/scripts/directive/group-list.js
+53
-4
privacy.js
h/static/scripts/directive/privacy.js
+4
-3
group-list-test.js
h/static/scripts/directive/test/group-list-test.js
+135
-0
privacy-test.js
h/static/scripts/directive/test/privacy-test.js
+1
-1
app.scss
h/static/styles/app.scss
+88
-15
common.scss
h/static/styles/common.scss
+4
-12
variables.scss
h/static/styles/variables.scss
+3
-0
group_list.html
h/templates/client/group_list.html
+47
-16
No files found.
h/static/scripts/app.coffee
View file @
b382243d
...
...
@@ -134,7 +134,7 @@ module.exports = angular.module('h', [
.
directive
(
'deepCount'
,
require
(
'./directive/deep-count'
))
.
directive
(
'formInput'
,
require
(
'./directive/form-input'
))
.
directive
(
'formValidate'
,
require
(
'./directive/form-validate'
))
.
directive
(
'groupList'
,
require
(
'./directive/group-list'
))
.
directive
(
'groupList'
,
require
(
'./directive/group-list'
)
.
directive
)
.
directive
(
'markdown'
,
require
(
'./directive/markdown'
))
.
directive
(
'privacy'
,
require
(
'./directive/privacy'
).
directive
)
.
directive
(
'simpleSearch'
,
require
(
'./directive/simple-search'
))
...
...
h/static/scripts/directive/group-list.js
View file @
b382243d
'use strict'
;
// @ngInject
function
GroupListController
(
$scope
)
{
$scope
.
expandedGroupId
=
undefined
;
// show the share link for the specified group or clear it if
// null
$scope
.
toggleShareLink
=
function
(
groupId
)
{
if
(
!
groupId
||
$scope
.
expandedGroupId
===
groupId
)
{
$scope
.
expandedGroupId
=
undefined
;
}
else
{
$scope
.
expandedGroupId
=
groupId
;
}
};
$scope
.
shouldShowShareLink
=
function
(
groupId
)
{
return
$scope
.
expandedGroupId
===
groupId
;
}
$scope
.
sortedGroups
=
function
()
{
return
$scope
.
groups
.
all
().
concat
().
sort
(
function
(
a
,
b
)
{
if
(
a
.
public
!==
b
.
public
)
{
return
a
.
public
?
-
1
:
1
;
}
return
a
.
name
.
localeCompare
(
b
.
name
);
});
}
}
/**
* @ngdoc directive
* @name groupList
* @restrict AE
* @description Displays a list of groups of which the user is a member.
*/
// @ngInject
module
.
exports
=
function
(
groups
)
{
function
groupList
(
groups
,
$window
)
{
return
{
link
:
function
(
scope
,
elem
,
attrs
)
{
scope
.
groups
=
groups
;
controller
:
GroupListController
,
link
:
function
(
$scope
,
elem
,
attrs
)
{
$scope
.
groups
=
groups
;
$scope
.
createNewGroup
=
function
()
{
$window
.
open
(
'/groups/new'
,
'_blank'
);
}
$scope
.
$watch
(
'expandedGroupId'
,
function
(
activeGroupId
)
{
if
(
activeGroupId
)
{
// wait for the share link field to be revealed and then select
// the link's text
setTimeout
(
function
()
{
var
activeShareLinkField
=
elem
[
0
].
querySelector
(
'.share-link-field[data-group-id='
+
activeGroupId
+
']'
);
activeShareLinkField
.
focus
();
activeShareLinkField
.
select
();
},
0
);
}
});
},
restrict
:
'AE'
,
scope
:
{},
templateUrl
:
'group_list.html'
};
};
module
.
exports
=
{
directive
:
groupList
,
Controller
:
GroupListController
};
h/static/scripts/directive/privacy.js
View file @
b382243d
...
...
@@ -125,6 +125,7 @@ var directive = function () {
};
};
exports
.
PrivacyController
=
PrivacyController
;
exports
.
directive
=
directive
;
module
.
exports
=
{
directive
:
directive
,
Controller
:
PrivacyController
};
h/static/scripts/directive/test/group-list-test.js
0 → 100644
View file @
b382243d
'use strict'
;
var
groupList
=
require
(
'../group-list'
);
describe
(
'GroupListController'
,
function
()
{
var
controller
;
var
$scope
;
beforeEach
(
function
()
{
$scope
=
{};
controller
=
new
groupList
.
Controller
(
$scope
);
});
it
(
'toggles share links'
,
function
()
{
$scope
.
toggleShareLink
(
'group-a'
);
assert
.
equal
(
$scope
.
expandedGroupId
,
'group-a'
);
$scope
.
toggleShareLink
(
'group-a'
);
assert
.
equal
(
$scope
.
expandedGroupId
,
undefined
);
$scope
.
toggleShareLink
(
'group-b'
);
assert
.
equal
(
$scope
.
expandedGroupId
,
'group-b'
);
$scope
.
toggleShareLink
(
'group-c'
);
assert
.
equal
(
$scope
.
expandedGroupId
,
'group-c'
);
});
it
(
'shows share link for selected group'
,
function
()
{
assert
.
equal
(
$scope
.
shouldShowShareLink
(
'group-a'
),
false
);
$scope
.
toggleShareLink
(
'group-a'
);
assert
.
equal
(
$scope
.
shouldShowShareLink
(
'group-a'
),
true
);
$scope
.
toggleShareLink
(
'group-b'
);
assert
.
equal
(
$scope
.
shouldShowShareLink
(
'group-a'
),
false
);
assert
.
equal
(
$scope
.
shouldShowShareLink
(
'group-b'
),
true
);
});
it
(
'sorts groups'
,
function
()
{
$scope
.
groups
=
{
all
:
function
()
{
return
[{
id
:
'c'
,
name
:
'Zebrafish Study Group'
},{
id
:
'a'
,
name
:
'Antimatter Research'
},{
public
:
true
}];
}
};
var
sorted
=
$scope
.
sortedGroups
();
assert
.
ok
(
sorted
[
0
].
public
);
assert
.
equal
(
sorted
[
1
].
name
,
'Antimatter Research'
);
assert
.
equal
(
sorted
[
2
].
name
,
'Zebrafish Study Group'
);
});
});
// returns true if a jQuery-like element has
// been hidden directly via an ng-show directive.
//
// This does not check whether the element is a descendant
// of a hidden element
function
isElementHidden
(
element
)
{
return
element
.
hasClass
(
'ng-hide'
);
}
describe
(
'groupList'
,
function
()
{
var
$compile
;
var
$scope
;
var
GROUP_LINK
=
'https://hypothes.is/groups/hdevs'
;
var
groups
=
[{
id
:
'public'
,
public
:
true
},{
id
:
'h-devs'
,
name
:
'Hypothesis Developers'
,
url
:
GROUP_LINK
}];
before
(
function
()
{
angular
.
module
(
'app'
,
[])
.
directive
(
'groupList'
,
groupList
.
directive
)
.
factory
(
'groups'
,
function
()
{
return
{
all
:
function
()
{
return
groups
;
}
};
});
});
beforeEach
(
function
()
{
angular
.
mock
.
module
(
'app'
);
angular
.
mock
.
module
(
'h.templates'
);
});
beforeEach
(
angular
.
mock
.
inject
(
function
(
_$compile_
,
_$rootScope_
)
{
$compile
=
_$compile_
;
$scope
=
_$rootScope_
.
$new
();
}));
function
createGroupList
()
{
var
element
=
$compile
(
'<group-list></group-list>'
)(
$scope
);
$scope
.
$digest
();
return
element
;
}
it
(
'should render groups'
,
function
()
{
var
element
=
createGroupList
();
var
groupItems
=
element
.
find
(
'.group-item'
);
assert
.
equal
(
groupItems
.
length
,
groups
.
length
+
1
);
});
it
(
'should render share links'
,
function
()
{
var
element
=
createGroupList
();
var
shareLinks
=
element
.
find
(
'.share-link-container'
);
assert
.
equal
(
shareLinks
.
length
,
1
);
var
linkField
=
element
.
find
(
'.share-link-field'
);
assert
.
equal
(
linkField
.
length
,
1
);
assert
.
equal
(
linkField
[
0
].
value
,
GROUP_LINK
);
});
it
(
'should toggle share link on click'
,
function
()
{
var
element
=
createGroupList
();
var
toggleLink
=
element
.
find
(
'.share-link-toggle'
);
var
expander
=
element
.
find
(
'.share-link-expander'
);
assert
.
ok
(
isElementHidden
(
expander
));
toggleLink
.
click
();
assert
.
ok
(
!
isElementHidden
(
expander
));
toggleLink
.
click
();
assert
.
ok
(
isElementHidden
(
expander
));
});
});
h/static/scripts/directive/test/privacy-test.js
View file @
b382243d
'use strict'
;
var
PrivacyController
=
require
(
'../privacy'
).
Privacy
Controller
;
var
PrivacyController
=
require
(
'../privacy'
).
Controller
;
describe
(
'PrivacyController'
,
function
()
{
var
fakeScope
;
...
...
h/static/styles/app.scss
View file @
b382243d
@import
'compass'
;
@import
'compass/css3/flexbox'
;
$base-font-size
:
12px
;
$base-line-height
:
20px
;
...
...
@@ -82,27 +83,99 @@ ol {
/* The groups dropdown list. */
$group-list-width
:
2
25
px
;
$group-list-width
:
2
70
px
;
.group-list
.dropdown
{
white-space
:
nowrap
;
}
.group-list
{
.dropdown
{
white-space
:
nowrap
;
}
.group-list
.dropdown-menu
{
width
:
$group-list-width
;
}
.dropdown-menu
{
width
:
$group-list-width
;
.group-list
.dropdown-menu
li
{
@include
pie-clearfix
;
}
.group-name
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
width
:
$group-list-width
-
30px
;
}
}
.group-item
{
@include
display-flex
;
@include
flex-direction
(
row
);
// IE 10 support
display
:
-
ms-flexbox
;
-ms-flex-direction
:
row
;
padding
:
10px
;
cursor
:
pointer
;
&
:hover
{
.share-link-toggle
{
color
:
inherit
;
}
.group-name-link
{
color
:
$brand-color
;
}
}
&
.selected
{
.group-name-link
{
font-weight
:
600
;
}
}
}
.group-list
.dropdown-menu
.group-name
{
float
:
left
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
width
:
$group-list-width
-
30px
;
.group-icon-container
{
margin-right
:
10px
;
}
.group-details
{
margin-right
:
20px
;
}
.share-link-container
{
font-size
:
$body1-font-size
;
line-height
:
$body1-line-height
;
margin-top
:
1px
;
white-space
:
normal
;
}
.share-link-toggle
{
color
:
$gray-light
;
}
.share-link-toggle
:hover
{
text-decoration
:
underline
;
color
:
$gray-dark
;
}
.share-link-field
{
padding
:
3px
;
padding-top
:
5px
;
padding-bottom
:
5px
;
margin-top
:
12px
;
margin-bottom
:
8px
;
border
:
1px
solid
$gray-lighter
;
width
:
100%
;
}
.new-group-btn
{
background-color
:
$gray-lightest
;
.group-item
{
padding-top
:
12px
;
padding-bottom
:
12px
;
}
.h-icon-add
{
font-weight
:
bold
;
}
}
}
/* The user account dropdown menu */
.user-picker
{
.avatar
{
border-radius
:
2px
;
...
...
h/static/styles/common.scss
View file @
b382243d
...
...
@@ -180,25 +180,17 @@ html {
li
:not
(
.ng-hide
)
{
text-align
:
left
;
a
{
&
>
a
{
display
:
block
;
line-height
:
1
;
padding
:
1em
;
white-space
:
nowrap
;
}
&
:hover
{
color
:
black
;
}
&
.selected
{
color
:
black
;
font-weight
:
600
;
line-height
:
1
;
&
:before
{
font-size
:
.7em
;
:hover
{
color
:
$brand-color
;
}
}
&
.inactive
{
font-weight
:
400
;
color
:
$gray-lighter
;
...
...
h/static/styles/variables.scss
View file @
b382243d
...
...
@@ -67,6 +67,9 @@ $alt-font-family: $serif-font-family !default;
$headings-font-family
:
inherit
!
default
;
$headings-color
:
inherit
!
default
;
$body1-font-size
:
12px
;
$body1-line-height
:
1
.4em
;
//STANCE COLORS
$positive
:
#3aab39
;
$negative
:
#d11c2b
;
...
...
h/templates/client/group_list.html
View file @
b382243d
...
...
@@ -2,29 +2,60 @@
<span
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
ng-switch
on=
"groups.focused().public"
>
ng-switch
on=
"groups.focused().public"
ng-click=
"toggleShareLink(undefined)"
>
<i
class=
"h-icon-public"
ng-switch-when=
"true"
></i>
<i
class=
"h-icon-group"
ng-switch-default
></i>
{{groups.focused().name}}
<i
class=
"h-icon-arrow-drop-down"
></i>
</span>
<ul
class=
"dropdown-menu pull-right"
role=
"menu"
>
<li
ng-repeat=
"group in groups.all()"
ng-class=
"group.id == groups.focused().id? 'selected' : ''"
>
<a
class=
"group-name"
href=
""
ng-click=
"groups.focus(group.id)"
ng-switch
on=
"group.public"
>
<i
class=
"h-icon-public"
ng-switch-when=
"true"
></i>
<i
class=
"h-icon-group"
ng-switch-default
></i>
{{group.name}}
</a>
<a
ng-href=
"{{group.url}}"
ng-if=
"group.url"
target=
"_blank"
class=
"h-icon-link"
title=
"Share this group"
></a>
<li
ng-repeat=
"group in sortedGroups()"
>
<div
ng-class=
"{'group-item': true, selected: group.id == groups.focused().id}"
ng-click=
"groups.focus(group.id)"
>
<!-- the group icon !-->
<div
class=
"group-icon-container"
ng-switch
on=
"group.public"
>
<i
class=
"h-icon-public"
ng-switch-when=
"true"
></i>
<i
class=
"h-icon-group"
ng-switch-default
></i>
</div>
<!-- the group name and share link !-->
<div
class=
"group-details"
>
<div
class=
"group-name-container"
>
<a
class=
"group-name-link"
href=
""
title=
"{{ group.public ? 'Show public annotations' : 'Show and create annotations in ' + group.name }}"
>
{{group.name}}
</a>
</div>
<div
class=
"share-link-container"
ng-click=
"$event.stopPropagation()"
ng-if=
"!group.public"
>
<div>
<a
class=
"share-link-toggle"
href=
""
ng-click=
"toggleShareLink(group.id)"
title=
"Invite others to join this group"
>
Invite others to join this group
</a>
</div>
<div
class=
"share-link-expander"
ng-show=
"shouldShowShareLink(group.id)"
>
<input
class=
"share-link-field"
data-group-id=
"{{group.id}}"
ng-value=
"group.url"
>
<p>
You can invite other people to join this group
by sending them this link
</p>
</div>
</div>
</div>
</div>
</li>
<li>
<a
href=
"/groups/new"
target=
"_blank"
><i
class=
"h-icon-add"
></i>
New Group
</a>
<li
class=
"new-group-btn"
>
<div
class=
"group-item"
ng-click=
"createNewGroup()"
>
<div
class=
"group-icon-container"
><i
class=
"h-icon-add"
></i></div>
<div
class=
"group-details"
>
<a
href=
""
title=
"Create a new group to share annotations"
>
New group
</a>
</div>
</div>
</li>
</ul>
</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