diff --git a/frontend/src/components/dialog/sort-options.js b/frontend/src/components/dialog/sort-options.js
new file mode 100644
index 0000000000..00e311d215
--- /dev/null
+++ b/frontend/src/components/dialog/sort-options.js
@@ -0,0 +1,65 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import { Modal, ModalBody } from 'reactstrap';
+import { gettext } from '../../utils/constants';
+
+const propTypes = {
+ toggleDialog: PropTypes.func.isRequired,
+ sortBy: PropTypes.string.isRequired,
+ sortOrder: PropTypes.string.isRequired,
+ sortList: PropTypes.func.isRequired
+};
+
+class SortOptions extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.sortOptions = [
+ {id: 'sort-option-1', value: 'name-asc', text: gettext('By name ascending')},
+ {id: 'sort-option-2', value: 'name-desc', text: gettext('By name descending')},
+ {id: 'sort-option-3', value: 'size-asc', text: gettext('By size ascending')},
+ {id: 'sort-option-4', value: 'size-desc', text: gettext('By size descending')},
+ {id: 'sort-option-5', value: 'time-asc', text: gettext('By time ascending')},
+ {id: 'sort-option-6', value: 'time-desc', text: gettext('By time descending')}
+ ];
+ const { sortBy, sortOrder } = this.props;
+ this.state = {
+ currentOption: `${sortBy}-${sortOrder}`
+ };
+ }
+
+ switchOption = (e) => {
+ if (!e.target.checked) {
+ return;
+ }
+
+ this.setState({
+ currentOption: e.target.value
+ });
+
+ const [sortBy, sortOrder] = e.target.value.split('-');
+ this.props.sortList(sortBy, sortOrder);
+ this.props.toggleDialog();
+ }
+
+ render() {
+ return (
+
+
+ {this.sortOptions.map((item, index) => {
+ return (
+
+
+
+
+ );
+ })}
+
+
+ );
+ }
+}
+
+SortOptions.propTypes = propTypes;
+
+export default SortOptions;
diff --git a/frontend/src/pages/my-libs/my-libs.js b/frontend/src/pages/my-libs/my-libs.js
index cfc153b52e..10ee963e5d 100644
--- a/frontend/src/pages/my-libs/my-libs.js
+++ b/frontend/src/pages/my-libs/my-libs.js
@@ -11,6 +11,7 @@ import CommonToolbar from '../../components/toolbar/common-toolbar';
import RepoViewToolbar from '../../components/toolbar/repo-view-toobar';
import LibDetail from '../../components/dirent-detail/lib-details';
import MylibRepoListView from './mylib-repo-list-view';
+import SortOptionsDialog from '../../components/dialog/sort-options';
const propTypes = {
onShowSidePanel: PropTypes.func.isRequired,
@@ -25,6 +26,7 @@ class MyLibraries extends Component {
isLoading: true,
repoList: [],
isShowDetails: false,
+ isSortOptionsDialogOpen: false,
sortBy: cookie.load('seafile-repo-dir-sort-by') || 'name', // 'name' or 'time' or 'size'
sortOrder: cookie.load('seafile-repo-dir-sort-order') || 'asc', // 'asc' or 'desc'
};
@@ -70,6 +72,12 @@ class MyLibraries extends Component {
});
}
+ toggleSortOptionsDialog = () => {
+ this.setState({
+ isSortOptionsDialogOpen: !this.state.isSortOptionsDialogOpen
+ });
+ }
+
onCreateRepo = (repo) => {
let permission = repo.permission;
seafileAPI.createMineRepo(repo).then((res) => {
@@ -147,8 +155,9 @@ class MyLibraries extends Component {
-
-
{gettext('My Libraries')}
+
+
{gettext('My Libraries')}
+ {(window.innerWidth < 768) && }
{this.state.isLoading && }
@@ -168,6 +177,14 @@ class MyLibraries extends Component {
}
+ {this.state.isSortOptionsDialogOpen &&
+
+ }
{this.state.isShowDetails && (
{
switch(item) {
+ case 'Star':
+ case 'Unstar':
+ this.onStarRepo();
+ break;
case 'Share':
this.onShareToggle();
break;
@@ -109,10 +113,16 @@ class MylibRepoListItem extends React.Component {
if (this.state.isStarred) {
seafileAPI.unstarItem(this.props.repo.repo_id, '/').then(() => {
this.setState({isStarred: !this.state.isStarred});
+ if (window.innerWidth < 728) {
+ toaster.success(gettext('Successfully unstarred the library.'));
+ }
});
} else {
seafileAPI.starItem(this.props.repo.repo_id, '/').then(() => {
this.setState({isStarred: !this.state.isStarred});
+ if (window.innerWidth < 728) {
+ toaster.success(gettext('Successfully starred the library.'));
+ }
});
}
}
@@ -284,6 +294,7 @@ class MylibRepoListItem extends React.Component {
{repo.repo_name && (
{
- const sortIcon = this.props.sortOrder === 'asc' ? : ;
return (
-
+
{gettext('Library Type')} |
-
- {gettext('Sort:')}
- {gettext('name')} {this.props.sortBy === 'name' && sortIcon}
- {gettext('last update')} {this.props.sortBy === 'time' && sortIcon}
- |
+ |
{gettext('Actions')} |
diff --git a/frontend/src/pages/my-libs/mylib-repo-menu.js b/frontend/src/pages/my-libs/mylib-repo-menu.js
index e4c040a815..6dc2f0623e 100644
--- a/frontend/src/pages/my-libs/mylib-repo-menu.js
+++ b/frontend/src/pages/my-libs/mylib-repo-menu.js
@@ -7,6 +7,7 @@ import { Utils } from '../../utils/utils';
const propTypes = {
isPC: PropTypes.bool,
repo: PropTypes.object.isRequired,
+ isStarred: PropTypes.bool,
onFreezedItem: PropTypes.func.isRequired,
onUnfreezedItem: PropTypes.func.isRequired,
onMenuItemClick: PropTypes.func.isRequired,
@@ -71,6 +72,12 @@ class MylibRepoMenu extends React.Component {
translateOperations = (item) => {
let translateResult = '';
switch(item) {
+ case 'Star':
+ translateResult = gettext('Star');
+ break;
+ case 'Unstar':
+ translateResult = gettext('Unstar');
+ break;
case 'Share':
translateResult = gettext('Share');
break;
@@ -130,14 +137,15 @@ class MylibRepoMenu extends React.Component {
}
// mobile menu
- operations.unshift('Share');
operations.unshift('Delete');
+ operations.unshift('Share');
+ this.props.isStarred ? operations.unshift('Unstar') : operations.unshift('Star');
return (
',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!d.__iconfont__svg__cssinject__){d.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(c=t,o=d.document,i=!1,(l=function(){try{o.documentElement.doScroll("left")}catch(t){return void setTimeout(l,50)}n()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,n())});function n(){i||(i=!0,c())}var c,o,i,l}(function(){var t,e;(t=document.createElement("div")).innerHTML=n,n=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",function(t,e){e.firstChild?function(t,e){e.parentNode.insertBefore(t,e)}(t,e.firstChild):e.appendChild(t)}(e,document.body))})}(window);
\ No newline at end of file
+!function(h){var c,e='',t=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(t&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var t=function(){document.removeEventListener("DOMContentLoaded",t,!1),c()};document.addEventListener("DOMContentLoaded",t,!1)}else document.attachEvent&&(n=c,o=h.document,l=!1,(i=function(){try{o.documentElement.doScroll("left")}catch(c){return void setTimeout(i,50)}e()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,e())});function e(){l||(l=!0,n())}var n,o,l,i}(function(){var c,t;(c=document.createElement("div")).innerHTML=e,e=null,(t=c.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",function(c,t){t.firstChild?function(c,t){t.parentNode.insertBefore(c,t)}(c,t.firstChild):t.appendChild(c)}(t,document.body))})}(window);
\ No newline at end of file
diff --git a/media/css/sf_font3/iconfont.svg b/media/css/sf_font3/iconfont.svg
index 0312ad4495..05920c8701 100644
--- a/media/css/sf_font3/iconfont.svg
+++ b/media/css/sf_font3/iconfont.svg
@@ -20,10 +20,19 @@ Created by iconfont
/>
-
+
-
+
+
+
+
+
+
+
+
+
+
diff --git a/media/css/sf_font3/iconfont.ttf b/media/css/sf_font3/iconfont.ttf
index bddfff53f1..05c8fb3953 100644
Binary files a/media/css/sf_font3/iconfont.ttf and b/media/css/sf_font3/iconfont.ttf differ
diff --git a/media/css/sf_font3/iconfont.woff b/media/css/sf_font3/iconfont.woff
index 194b8459a7..e8aa715e1d 100644
Binary files a/media/css/sf_font3/iconfont.woff and b/media/css/sf_font3/iconfont.woff differ
diff --git a/media/css/sf_font3/iconfont.woff2 b/media/css/sf_font3/iconfont.woff2
index dafdbaab2c..f15e9bf543 100644
Binary files a/media/css/sf_font3/iconfont.woff2 and b/media/css/sf_font3/iconfont.woff2 differ