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
b0dfce31
Unverified
Commit
b0dfce31
authored
Jul 22, 2019
by
Hannah Stepanek
Committed by
GitHub
Jul 22, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1254 from hypothesis/convert-search-status-bar
Convert search status bar to preact
parents
30d4004e
cdd54488
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
268 additions
and
222 deletions
+268
-222
search-status-bar.js
src/sidebar/components/search-status-bar.js
+101
-43
search-status-bar-test.js
src/sidebar/components/test/search-status-bar-test.js
+161
-142
index.js
src/sidebar/index.js
+4
-1
search-status-bar.html
src/sidebar/templates/search-status-bar.html
+0
-35
sidebar-content.html
src/sidebar/templates/sidebar-content.html
+2
-1
No files found.
src/sidebar/components/search-status-bar.js
View file @
b0dfce31
'use strict'
;
const
memoize
=
require
(
'../util/memoize'
);
const
{
Fragment
,
createElement
}
=
require
(
'preact'
);
const
propTypes
=
require
(
'prop-types'
);
const
{
useMemo
}
=
require
(
'preact/hooks'
);
const
{
withServices
}
=
require
(
'../util/service-context'
);
const
uiConstants
=
require
(
'../ui-constants'
);
const
useStore
=
require
(
'../store/use-store'
);
// @ngInject
function
SearchStatusBarController
(
store
,
rootThread
)
{
this
.
TAB_ANNOTATIONS
=
uiConstants
.
TAB_ANNOTATIONS
;
this
.
TAB_NOTES
=
uiConstants
.
TAB_NOTES
;
this
.
TAB_ORPHANS
=
uiConstants
.
TAB_ORPHANS
;
const
thread
=
()
=>
{
return
rootThread
.
thread
(
store
.
getState
());
};
const
visibleCount
=
memoize
(
thread
=>
{
return
thread
.
children
.
reduce
(
const
countVisibleAnns
=
annThread
=>
{
return
annThread
.
children
.
reduce
(
function
(
count
,
child
)
{
return
count
+
visibleCount
(
child
);
return
count
+
countVisibleAnns
(
child
);
},
t
hread
.
visible
?
1
:
0
annT
hread
.
visible
?
1
:
0
);
});
};
/**
* A bar where the user can clear a selection or search and see whether
* any search results were found.
* */
function
SearchStatusBar
({
selectedTab
,
totalAnnotations
,
totalNotes
,
rootThread
,
})
{
const
storeState
=
useStore
(
store
=>
store
.
getState
());
const
clearSelection
=
useStore
(
store
=>
store
.
clearSelection
);
const
filterQuery
=
storeState
.
filterQuery
;
const
filterActive
=
!!
storeState
.
filterQuery
;
this
.
filterMatchCount
=
function
()
{
return
visibleCount
(
thread
());
const
thread
=
rootThread
.
thread
(
storeState
);
const
visibleCount
=
useMemo
(()
=>
{
return
countVisibleAnns
(
thread
);
},
[
thread
]);
const
filterResults
=
()
=>
{
const
resultsCount
=
visibleCount
;
switch
(
resultsCount
)
{
case
0
:
return
'No results for "'
+
filterQuery
+
'"'
;
case
1
:
return
'1 search result'
;
default
:
return
resultsCount
+
' search results'
;
}
};
this
.
areAllAnnotationsVisible
=
function
()
{
if
(
store
.
getState
()
.
directLinkedGroupFetchFailed
)
{
const
areNotAllAnnotationsVisible
=
()
=>
{
if
(
store
State
.
directLinkedGroupFetchFailed
)
{
return
true
;
}
const
selection
=
store
.
getState
()
.
selectedAnnotationMap
;
const
selection
=
store
State
.
selectedAnnotationMap
;
if
(
!
selection
)
{
return
false
;
}
return
Object
.
keys
(
selection
).
length
>
0
;
};
this
.
filterQuery
=
function
()
{
return
store
.
getState
().
filterQuery
;
};
this
.
filterActive
=
function
()
{
return
!!
store
.
getState
().
filterQuery
;
};
this
.
onClearSelection
=
function
()
{
store
.
clearSelection
();
};
return
(
<
div
>
{
filterActive
&&
(
<
div
className
=
"search-status-bar"
>
<
button
className
=
"primary-action-btn primary-action-btn--short"
onClick
=
{
clearSelection
}
title
=
"Clear the search filter and show all annotations"
>
<
i
className
=
"primary-action-btn__icon h-icon-close"
/>
Clear
search
<
/button
>
<
span
>
{
filterResults
()}
<
/span
>
<
/div
>
)}
{
!
filterActive
&&
areNotAllAnnotationsVisible
()
&&
(
<
div
className
=
"search-status-bar"
>
<
button
className
=
"primary-action-btn primary-action-btn--short"
onClick
=
{
clearSelection
}
title
=
"Clear the selection and show all annotations"
>
{
selectedTab
===
uiConstants
.
TAB_ORPHANS
&&
(
<
Fragment
>
Show
all
annotations
and
notes
<
/Fragment
>
)}
{
selectedTab
===
uiConstants
.
TAB_ANNOTATIONS
&&
(
<
Fragment
>
Show
all
annotations
{
totalAnnotations
>
1
&&
<
span
>
({
totalAnnotations
})
<
/span>
}
<
/Fragment
>
)}
{
selectedTab
===
uiConstants
.
TAB_NOTES
&&
(
<
Fragment
>
Show
all
notes
{
totalNotes
>
1
&&
<
span
>
({
totalNotes
})
<
/span>
}
<
/Fragment
>
)}
<
/button
>
<
/div
>
)}
<
/div
>
);
}
module
.
export
s
=
{
controller
:
SearchStatusBarController
,
controllerAs
:
'vm'
,
bindings
:
{
selectedTab
:
'<'
,
totalAnnotations
:
'<'
,
totalNotes
:
'<'
,
}
,
template
:
require
(
'../templates/search-status-bar.html'
)
,
SearchStatusBar
.
propType
s
=
{
selectedTab
:
propTypes
.
oneOf
([
uiConstants
.
TAB_ANNOTATIONS
,
uiConstants
.
TAB_ORPHANS
,
uiConstants
.
TAB_NOTES
,
]).
isRequired
,
totalAnnotations
:
propTypes
.
number
.
isRequired
,
totalNotes
:
propTypes
.
number
.
isRequired
,
rootThread
:
propTypes
.
object
.
isRequired
,
};
SearchStatusBar
.
injectedProps
=
[
'rootThread'
];
module
.
exports
=
withServices
(
SearchStatusBar
);
src/sidebar/components/test/search-status-bar-test.js
View file @
b0dfce31
This diff is collapsed.
Click to expand it.
src/sidebar/index.js
View file @
b0dfce31
...
...
@@ -181,7 +181,10 @@ function startAngularApp(config) {
wrapReactComponent
(
require
(
'./components/moderation-banner'
))
)
.
component
(
'newNoteBtn'
,
require
(
'./components/new-note-btn'
))
.
component
(
'searchStatusBar'
,
require
(
'./components/search-status-bar'
))
.
component
(
'searchStatusBar'
,
wrapReactComponent
(
require
(
'./components/search-status-bar'
))
)
.
component
(
'selectionTabs'
,
require
(
'./components/selection-tabs'
))
.
component
(
'sidebarContent'
,
require
(
'./components/sidebar-content'
))
.
component
(
...
...
src/sidebar/templates/search-status-bar.html
deleted
100644 → 0
View file @
30d4004e
<div
class=
"search-status-bar"
ng-if=
"vm.filterActive()"
>
<button
class=
"primary-action-btn primary-action-btn--short"
ng-click=
"vm.onClearSelection()"
title=
"Clear the search filter and show all annotations"
>
<i
class=
"primary-action-btn__icon h-icon-close"
></i>
Clear search
</button>
<span
ng-pluralize
count=
"vm.filterMatchCount()"
when=
"{'0': 'No results for “{{vm.filterQuery()}}”',
'one': '1 search result',
'other': '{} search results'}"
></span>
</div>
<div
class=
"search-status-bar"
ng-if=
"!vm.filterActive() && vm.areAllAnnotationsVisible()"
>
<button
class=
"primary-action-btn primary-action-btn--short"
ng-click=
"vm.onClearSelection()"
title=
"Clear the selection and show all annotations"
>
<span
ng-if=
"!vm.selectedTab || vm.selectedTab === vm.TAB_ORPHANS"
>
Show all annotations and notes
</span>
<span
ng-if=
"vm.selectedTab === vm.TAB_ANNOTATIONS"
>
Show all annotations
<span
ng-if=
"vm.totalAnnotations > 1"
>
({{vm.totalAnnotations}})
</span>
</span>
<span
ng-if=
"vm.selectedTab === vm.TAB_NOTES"
>
Show all notes
<span
ng-if=
"vm.totalNotes > 1"
>
({{vm.totalNotes}})
</span>
</span>
</button>
</div>
src/sidebar/templates/sidebar-content.html
View file @
b0dfce31
...
...
@@ -9,7 +9,8 @@
</selection-tabs>
<search-status-bar
ng-show=
"!vm.isLoading()"
class=
"search-status-bar"
ng-if=
"!vm.isLoading()"
selected-tab=
"vm.selectedTab"
total-annotations=
"vm.totalAnnotations"
total-notes=
"vm.totalNotes"
>
...
...
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