diff --git a/frontend/src/app.js b/frontend/src/app.js index 644fb114fa..2e310ebf21 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -39,7 +39,7 @@ const ShareAdminLibrariesWrapper = MainContentWrapper(ShareAdminLibraries); const ShareAdminFoldersWrapper = MainContentWrapper(ShareAdminFolders); const ShareAdminShareLinksWrapper = MainContentWrapper(ShareAdminShareLinks); const ShareAdminUploadLinksWrapper = MainContentWrapper(ShareAdminUploadLinks); -const Wikiswrapper = MainContentWrapper(Wikis); +const WikisWrapper = MainContentWrapper(Wikis); class App extends Component { @@ -144,7 +144,7 @@ class App extends Component { - + diff --git a/frontend/src/pages/wikis/wiki-create.js b/frontend/src/components/dialog/new-wiki-dialog.js similarity index 93% rename from frontend/src/pages/wikis/wiki-create.js rename to frontend/src/components/dialog/new-wiki-dialog.js index 259cdc9fe8..e84e38650e 100644 --- a/frontend/src/pages/wikis/wiki-create.js +++ b/frontend/src/components/dialog/new-wiki-dialog.js @@ -8,7 +8,7 @@ const propTypes = { addWiki: PropTypes.func.isRequired, }; -class WikiDelete extends React.Component { +class NewWikiDialog extends React.Component { constructor(props) { super(props); @@ -64,6 +64,6 @@ class WikiDelete extends React.Component { } } -WikiDelete.propTypes = propTypes; +NewWikiDialog.propTypes = propTypes; -export default WikiDelete; +export default NewWikiDialog; diff --git a/frontend/src/pages/wikis/wiki-delete.js b/frontend/src/components/dialog/wiki-delete-dialog.js similarity index 87% rename from frontend/src/pages/wikis/wiki-delete.js rename to frontend/src/components/dialog/wiki-delete-dialog.js index 448add563e..7f0980da8d 100644 --- a/frontend/src/pages/wikis/wiki-delete.js +++ b/frontend/src/components/dialog/wiki-delete-dialog.js @@ -8,7 +8,7 @@ const propTypes = { handleSubmit: PropTypes.func.isRequired, }; -class WikiDelete extends React.Component { +class WikiDeleteDialog extends React.Component { toggle = () => { this.props.toggleCancel(); @@ -30,6 +30,6 @@ class WikiDelete extends React.Component { } } -WikiDelete.propTypes = propTypes; +WikiDeleteDialog.propTypes = propTypes; -export default WikiDelete; +export default WikiDeleteDialog; diff --git a/frontend/src/pages/wikis/wiki-select.js b/frontend/src/components/dialog/wiki-select-dialog.js similarity index 95% rename from frontend/src/pages/wikis/wiki-select.js rename to frontend/src/components/dialog/wiki-select-dialog.js index fa4dc386d1..468f36dfab 100644 --- a/frontend/src/pages/wikis/wiki-select.js +++ b/frontend/src/components/dialog/wiki-select-dialog.js @@ -10,7 +10,7 @@ const propTypes = { addWiki: PropTypes.func.isRequired, }; -class WikiSelect extends React.Component { +class WikiSelectDialog extends React.Component { constructor(props) { super(props); @@ -84,6 +84,6 @@ class WikiSelect extends React.Component { } } -WikiSelect.propTypes = propTypes; +WikiSelectDialog.propTypes = propTypes; -export default WikiSelect; +export default WikiSelectDialog; diff --git a/frontend/src/components/main-side-nav.js b/frontend/src/components/main-side-nav.js index 1dfc7028d4..c33eff4d7e 100644 --- a/frontend/src/components/main-side-nav.js +++ b/frontend/src/components/main-side-nav.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Link } from '@reach/router'; -import { gettext, siteRoot } from '../utils/constants'; +import { gettext, siteRoot, enableWiki } from '../utils/constants'; import { seafileAPI } from '../utils/seafile-api'; import { Badge } from 'reactstrap'; @@ -170,12 +170,14 @@ class MainSideNav extends React.Component { {gettext('Acitivities')} -
  • + {enableWiki && +
  • this.tabItemClick('wikis')}> {gettext('Wikis')}
  • + }
  • this.tabItemClick('linked-devices')}> diff --git a/frontend/src/pages/wikis/wiki-add.js b/frontend/src/pages/wikis/wiki-add.js index 2be9b8431a..3a452b1dcf 100644 --- a/frontend/src/pages/wikis/wiki-add.js +++ b/frontend/src/pages/wikis/wiki-add.js @@ -4,7 +4,7 @@ import { gettext } from '../../utils/constants'; const propTypes = { isShowWikiAdd: PropTypes.bool.isRequired, - addPosition: PropTypes.object.isRequired, + position: PropTypes.object.isRequired, onSelectToggle: PropTypes.func.isRequired, onCreateToggle: PropTypes.func.isRequired, }; @@ -13,9 +13,9 @@ class WikiAdd extends React.Component { render() { let style = {}; - let {isShowWikiAdd, addPosition} = this.props; + let {isShowWikiAdd, position} = this.props; if (isShowWikiAdd) { - style = {position: 'fixed', top: addPosition.top, left: addPosition.left, display: 'block'}; + style = {position: 'fixed', top: position.top, left: position.left, display: 'block'}; } return (
      diff --git a/frontend/src/pages/wikis/wiki-menu.js b/frontend/src/pages/wikis/wiki-menu.js index c462d8d33e..1979178518 100644 --- a/frontend/src/pages/wikis/wiki-menu.js +++ b/frontend/src/pages/wikis/wiki-menu.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { gettext } from '../../utils/constants'; const propTypes = { - menuPosition: PropTypes.object.isRequired, + position: PropTypes.object.isRequired, onRenameToggle: PropTypes.func.isRequired, onDeleteToggle: PropTypes.func.isRequired, }; @@ -11,8 +11,8 @@ const propTypes = { class WikiMenu extends React.Component { render() { - let menuPosition = this.props.menuPosition; - let style = {position: 'fixed', top: menuPosition.top, left: menuPosition.left, display: 'block'}; + let position = this.props.position; + let style = {position: 'fixed', top: position.top, left: position.left, display: 'block'}; return (
        diff --git a/frontend/src/pages/wikis/wikis.js b/frontend/src/pages/wikis/wikis.js index 766daa6bc8..90e7e181db 100644 --- a/frontend/src/pages/wikis/wikis.js +++ b/frontend/src/pages/wikis/wikis.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { seafileAPI } from '../../utils/seafile-api'; import { gettext, siteRoot, loginUrl } from '../../utils/constants'; @@ -9,9 +9,10 @@ import MenuControl from '../../components/menu-control'; import WikiAdd from './wiki-add'; import WikiMenu from './wiki-menu'; import WikiRename from './wiki-rename'; -import WikiDelete from './wiki-delete'; -import WikiSelect from './wiki-select'; -import WikiCreate from './wiki-create'; +import NewWikiDialog from '../../components/dialog/new-wiki-dialog'; +import WikiDeleteDialog from '../../components/dialog/wiki-delete-dialog'; +import WikiSelectDialog from '../../components/dialog/wiki-select-dialog'; +import ModalPortal from '../../components/modal-portal'; const itempropTypes = { @@ -25,7 +26,7 @@ class Item extends Component { super(props); this.state = { isShowWikiMenu: false, - menuPosition: {top:'', left: ''}, + position: {top:'', left: ''}, isItemFreezed: false, isShowDeleteDialog: false, isShowMenuControl: false, @@ -59,7 +60,7 @@ class Item extends Component { let position = {top: top, left: left}; this.setState({ isShowWikiMenu: true, - menuPosition: position, + position: position, isItemFreezed: true, }); } @@ -149,35 +150,39 @@ class Item extends Component { let userProfileURL = `${siteRoot}profile/${encodeURIComponent(wiki.owner)}/`; return ( - - - {this.state.isRenameing ? - : - {gettext(wiki.name)} - } - - {gettext(wiki.owner_nickname)} - {moment(wiki.updated_at).fromNow()} - - - {this.state.isShowWikiMenu && - + + + {this.state.isRenameing ? + : + {gettext(wiki.name)} + } + + {gettext(wiki.owner_nickname)} + {moment(wiki.updated_at).fromNow()} + + - } - {this.state.isShowDeleteDialog && - + } + + + {this.state.isShowDeleteDialog && + + - } - - + + } + ); } } @@ -237,7 +242,7 @@ class Wikis extends Component { errorMsg: '', wikis: [], isShowWikiAdd: false, - addPosition: {top:'', left: ''}, + position: {top:'', left: ''}, isShowSelectDialog: false, isShowCreateDialog: false, }; @@ -248,10 +253,6 @@ class Wikis extends Component { this.getWikis(); } - componentWillReceiveProps() { - this.getWikis(); - } - componentWillUnmount() { document.removeEventListener('click', this.onHideWikiAdd); } @@ -302,7 +303,7 @@ class Wikis extends Component { let position = {top: top, left: left}; this.setState({ isShowWikiAdd: true, - addPosition: position, + position: position, }); } @@ -374,53 +375,59 @@ class Wikis extends Component { render() { return ( -
        -
        -
        -

        {gettext('Wikis')}

        -
        - -
        - {this.state.isShowWikiAdd && - - } - {this.state.isShowCreateDialog && - - } - {this.state.isShowSelectDialog && - - } -
        -
        - {(this.state.loading || this.state.wikis.length !== 0) && - - } - {(!this.state.loading && this.state.wikis.length === 0) && -
        -

        {gettext('You do not have any Wiki.')}

        -

        {gettext('Seafile Wiki enables you to organize your knowledge in a simple way. The contents of wiki is stored in a normal library with pre-defined file/folder structure. This enables you to edit your wiki in your desktop and then sync back to the server.')}

        + +
        +
        +
        +

        {gettext('Wikis')}

        +
        +
        - } + {this.state.isShowWikiAdd && + + } +
        +
        + {(this.state.loading || this.state.wikis.length !== 0) && + + } + {(!this.state.loading && this.state.wikis.length === 0) && +
        +

        {gettext('You do not have any Wiki.')}

        +

        {gettext('Seafile Wiki enables you to organize your knowledge in a simple way. The contents of wiki is stored in a normal library with pre-defined file/folder structure. This enables you to edit your wiki in your desktop and then sync back to the server.')}

        +
        + } +
        -
        + {this.state.isShowCreateDialog && + + + + } + {this.state.isShowSelectDialog && + + + + } + ); } } diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index e7acdb2347..8a9d502fc5 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -28,6 +28,7 @@ export const enableRepoSnapshotLabel = window.app.pageOptions.enableRepoSnapshot export const shareLinkExpireDaysMin = window.app.pageOptions.shareLinkExpireDaysMin; export const shareLinkExpireDaysMax = window.app.pageOptions.shareLinkExpireDaysMax; export const maxFileName = window.app.pageOptions.maxFileName; +export const enableWiki = window.app.pageOptions.enableWiki; // wiki export const slug = window.wiki ? window.wiki.config.slug : ''; diff --git a/seahub/settings.py b/seahub/settings.py index f695ef62c1..89b725d766 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -718,7 +718,7 @@ OTP_LOGIN_URL = '/profile/two_factor_authentication/setup/' TWO_FACTOR_DEVICE_REMEMBER_DAYS = 90 # Enable personal wiki, group wiki -ENABLE_WIKI = False +ENABLE_WIKI = True # Enable 'repo snapshot label' feature ENABLE_REPO_SNAPSHOT_LABEL = False diff --git a/seahub/templates/base_for_react.html b/seahub/templates/base_for_react.html index 3aeb0fb049..98857b8dc7 100644 --- a/seahub/templates/base_for_react.html +++ b/seahub/templates/base_for_react.html @@ -61,7 +61,8 @@ enableRepoSnapshotLabel: {% if enable_repo_snapshot_label %} true {% else %} false {% endif %}, shareLinkExpireDaysMin: "{{ share_link_expire_days_min }}", shareLinkExpireDaysMax: "{{ share_link_expire_days_max }}", - maxFileName: "{{ max_file_name }}" + maxFileName: "{{ max_file_name }}", + enableWiki: {% if enable_wiki %} true {% else %} false {% endif %}, } }; diff --git a/seahub/views/__init__.py b/seahub/views/__init__.py index a80e0c38ee..13ba57831f 100644 --- a/seahub/views/__init__.py +++ b/seahub/views/__init__.py @@ -1205,6 +1205,7 @@ def react_fake_view(request): return render(request, "react_app.html", { 'storages': get_library_storages(request), + 'enable_wiki': settings.ENABLE_WIKI, 'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL, 'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN, 'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,