diff --git a/frontend/src/components/cur-dir-path/dir-path.js b/frontend/src/components/cur-dir-path/dir-path.js
index eaf5afb5e1..5b638d1256 100644
--- a/frontend/src/components/cur-dir-path/dir-path.js
+++ b/frontend/src/components/cur-dir-path/dir-path.js
@@ -33,7 +33,6 @@ const propTypes = {
direntList: PropTypes.array.isRequired,
repoTags: PropTypes.array.isRequired,
filePermission: PropTypes.string,
- onFileTagChanged: PropTypes.func.isRequired,
onItemMove: PropTypes.func.isRequired,
loadDirentList: PropTypes.func.isRequired,
};
diff --git a/frontend/src/components/dialog/create-tag-dialog.js b/frontend/src/components/dialog/create-tag-dialog.js
deleted file mode 100644
index 63c30fa445..0000000000
--- a/frontend/src/components/dialog/create-tag-dialog.js
+++ /dev/null
@@ -1,126 +0,0 @@
-import React, { Fragment } from 'react';
-import PropTypes from 'prop-types';
-import { Button, ModalBody, ModalFooter, Input, Label } from 'reactstrap';
-import { gettext } from '../../utils/constants';
-import { TAG_COLORS } from '../../constants';
-import { seafileAPI } from '../../utils/seafile-api';
-import { Utils } from '../../utils/utils';
-import SeahubModalHeader from '@/components/common/seahub-modal-header';
-
-const propTypes = {
- repoID: PropTypes.string.isRequired,
- onRepoTagCreated: PropTypes.func,
- toggleCancel: PropTypes.func.isRequired,
- onClose: PropTypes.func.isRequired
-};
-
-class CreateTagDialog extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- tagName: '',
- tagColor: TAG_COLORS[0],
- newTag: {},
- errorMsg: '',
- };
- }
-
- inputNewName = (e) => {
- this.setState({
- tagName: e.target.value,
- });
- if (this.state.errorMsg) {
- this.setState({ errorMsg: '' });
- }
- };
-
- selectTagcolor = (e) => {
- this.setState({
- tagColor: e.target.value,
- });
- };
-
- createTag = () => {
- let name = this.state.tagName;
- let color = this.state.tagColor;
- let repoID = this.props.repoID;
- seafileAPI.createRepoTag(repoID, name, color).then((res) => {
- let repoTagID = res.data.repo_tag.repo_tag_id;
- if (this.props.onRepoTagCreated) this.props.onRepoTagCreated(repoTagID);
- this.props.toggleCancel();
- }).catch((error) => {
- let errMessage;
- if (error.response.status === 500) {
- errMessage = gettext('Internal Server Error');
- } else if (error.response.status === 400) {
- errMessage = gettext('Tag "{name}" already exists.');
- errMessage = errMessage.replace('{name}', Utils.HTMLescape(name));
- }
- this.setState({ errorMsg: errMessage });
- });
- };
-
- handleKeyDown = (e) => {
- if (e.key === 'Enter') {
- this.createTag();
- }
- };
-
- render() {
- let canSave = this.state.tagName.trim() ? true : false;
- return (
-
-
-
- {gettext('New Tag')}
-
-
-
-
-
{gettext('Name')}
-
-
{this.state.errorMsg}
-
-
-
{gettext('Select a color')}
-
-
-
-
-
- {gettext('Cancel')}
- {canSave ?
- {gettext('Save')} :
- {gettext('Save')}
- }
-
-
- );
- }
-}
-
-CreateTagDialog.propTypes = propTypes;
-
-export default CreateTagDialog;
diff --git a/frontend/src/components/dialog/edit-filetag-dialog.js b/frontend/src/components/dialog/edit-filetag-dialog.js
deleted file mode 100644
index 3ea407143d..0000000000
--- a/frontend/src/components/dialog/edit-filetag-dialog.js
+++ /dev/null
@@ -1,220 +0,0 @@
-import React, { Fragment } from 'react';
-import PropTypes from 'prop-types';
-import { Button, Modal, ModalBody, ModalFooter } from 'reactstrap';
-import { gettext } from '../../utils/constants';
-import { seafileAPI } from '../../utils/seafile-api';
-import { Utils } from '../../utils/utils';
-import CreateTagDialog from './create-tag-dialog';
-import toaster from '../toast';
-import SeahubModalHeader from '@/components/common/seahub-modal-header';
-
-require('../../css/repo-tag.css');
-
-const TagItemPropTypes = {
- repoID: PropTypes.string.isRequired,
- repoTag: PropTypes.object.isRequired,
- filePath: PropTypes.string.isRequired,
- fileTagList: PropTypes.array.isRequired,
- onFileTagChanged: PropTypes.func.isRequired,
-};
-
-class TagItem extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- isTagHighlighted: false
- };
- }
-
- onMouseEnter = () => {
- this.setState({
- isTagHighlighted: true
- });
- };
-
- onMouseLeave = () => {
- this.setState({
- isTagHighlighted: false
- });
- };
-
- getRepoTagIdList = () => {
- let repoTagIdList = [];
- let fileTagList = this.props.fileTagList || [];
- repoTagIdList = fileTagList.map((fileTag) => fileTag.repo_tag_id);
- return repoTagIdList;
- };
-
- onEditFileTag = () => {
- let { repoID, repoTag, filePath } = this.props;
- let repoTagIdList = this.getRepoTagIdList();
- if (repoTagIdList.indexOf(repoTag.id) === -1) {
- let id = repoTag.id;
- seafileAPI.addFileTag(repoID, filePath, id).then(() => {
- repoTagIdList = this.getRepoTagIdList();
- this.props.onFileTagChanged();
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- } else {
- let fileTag = null;
- let fileTagList = this.props.fileTagList;
- for (let i = 0; i < fileTagList.length; i++) {
- if (fileTagList[i].repo_tag_id === repoTag.id) {
- fileTag = fileTagList[i];
- break;
- }
- }
- seafileAPI.deleteFileTag(repoID, fileTag.id).then(() => {
- repoTagIdList = this.getRepoTagIdList();
- this.props.onFileTagChanged();
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
- };
-
- render() {
- const { isTagHighlighted } = this.state;
- const { repoTag } = this.props;
- const repoTagIdList = this.getRepoTagIdList();
- const isTagSelected = repoTagIdList.indexOf(repoTag.id) != -1;
- return (
-
-
-
- {repoTag.name}
-
- {isTagSelected && }
-
- );
- }
-
-}
-
-TagItem.propTypes = TagItemPropTypes;
-
-const TagListPropTypes = {
- repoID: PropTypes.string.isRequired,
- repoTags: PropTypes.array.isRequired,
- filePath: PropTypes.string.isRequired,
- fileTagList: PropTypes.array.isRequired,
- onFileTagChanged: PropTypes.func.isRequired,
- toggleCancel: PropTypes.func.isRequired,
- createNewTag: PropTypes.func.isRequired,
-};
-
-class TagList extends React.Component {
-
- render() {
- const { repoTags } = this.props;
- return (
-
- {gettext('Select Tags')}
-
-
- {repoTags.map((repoTag) => {
- return (
-
- );
- })}
-
-
-
- {gettext('Create a new tag')}
-
-
-
- {gettext('Close')}
-
-
- );
- }
-}
-
-TagList.propTypes = TagListPropTypes;
-
-const propTypes = {
- repoID: PropTypes.string.isRequired,
- repoTags: PropTypes.array.isRequired,
- filePath: PropTypes.string.isRequired,
- fileTagList: PropTypes.array.isRequired,
- toggleCancel: PropTypes.func.isRequired,
- onFileTagChanged: PropTypes.func.isRequired,
-};
-
-class EditFileTagDialog extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isCreateRepoTagShow: false,
- isListRepoTagShow: true,
- };
- }
-
- createNewTag = () => {
- this.setState({
- isCreateRepoTagShow: !this.state.isCreateRepoTagShow,
- isListRepoTagShow: !this.state.isListRepoTagShow,
- });
- };
-
- onRepoTagCreated = (repoTagID) => {
- let { repoID, filePath } = this.props;
- seafileAPI.addFileTag(repoID, filePath, repoTagID).then(() => {
- this.props.onFileTagChanged();
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- };
-
- render() {
- return (
-
- {this.state.isListRepoTagShow &&
-
- }
- {this.state.isCreateRepoTagShow &&
-
- }
-
- );
- }
-}
-
-EditFileTagDialog.propTypes = propTypes;
-
-export default EditFileTagDialog;
diff --git a/frontend/src/components/dialog/tag-color.js b/frontend/src/components/dialog/tag-color.js
deleted file mode 100644
index e4e0281fa2..0000000000
--- a/frontend/src/components/dialog/tag-color.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Popover, PopoverBody } from 'reactstrap';
-import { seafileAPI } from '../../utils/seafile-api';
-import { Utils } from '../../utils/utils';
-import { TAG_COLORS } from '../../constants';
-import toaster from '../toast';
-
-import '../../css/repo-tag.css';
-
-const tagColorPropTypes = {
- tag: PropTypes.object.isRequired,
- repoID: PropTypes.string.isRequired
-};
-
-class TagColor extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- tagColor: this.props.tag.color,
- isPopoverOpen: false
- };
- }
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.tag.color !== this.props.tag.color) {
- this.setState({
- tagColor: nextProps.tag.color,
- });
- }
- }
-
- togglePopover = () => {
- this.setState({
- isPopoverOpen: !this.state.isPopoverOpen
- });
- };
-
- selectTagColor = (e) => {
- const newColor = e.target.value;
- const { repoID, tag } = this.props;
- const { id, name } = tag;
- seafileAPI.updateRepoTag(repoID, id, name, newColor).then(() => {
- this.setState({
- tagColor: newColor,
- isPopoverOpen: !this.state.isPopoverOpen
- });
- }).catch((error) => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- };
-
- render() {
- const { isPopoverOpen, tagColor } = this.state;
- const { tag } = this.props;
- const { id, color } = tag;
-
- let colorList = [...TAG_COLORS];
- // for color from previous color options
- if (colorList.indexOf(color) == -1) {
- colorList.unshift(color);
- }
-
- return (
-
-
-
-
-
-
-
- {colorList.map((item, index) => {
- return (
-
-
-
-
-
-
-
-
- );
- })
- }
-
-
-
-
- );
- }
-}
-
-TagColor.propTypes = tagColorPropTypes;
-
-export default TagColor;
diff --git a/frontend/src/components/dialog/tag-name.js b/frontend/src/components/dialog/tag-name.js
deleted file mode 100644
index a5925da2b7..0000000000
--- a/frontend/src/components/dialog/tag-name.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { seafileAPI } from '../../utils/seafile-api';
-import { Utils } from '../../utils/utils';
-import toaster from '../toast';
-
-import '../../css/repo-tag.css';
-
-const tagNamePropTypes = {
- tag: PropTypes.object.isRequired,
- repoID: PropTypes.string.isRequired
-};
-
-class TagName extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- tagName: this.props.tag.name,
- isEditing: false
- };
- this.input = React.createRef();
- }
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.tag.name !== this.props.tag.name) {
- this.setState({
- tagName: nextProps.tag.name,
- });
- }
- }
-
- toggleMode = () => {
- this.setState({
- isEditing: !this.state.isEditing
- }, () => {
- if (this.state.isEditing) {
- this.input.current.focus();
- }
- });
- };
-
- updateTagName = (e) => {
- const newName = e.target.value;
- const { repoID, tag } = this.props;
- const { id, color } = tag;
- seafileAPI.updateRepoTag(repoID, id, newName, color).then(() => {
- this.setState({
- tagName: newName
- });
- }).catch((error) => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- };
-
- onInputKeyDown = (e) => {
- if (e.key == 'Enter') {
- this.toggleMode();
- this.updateTagName(e);
- }
- else if (e.key == 'Escape') {
- e.nativeEvent.stopImmediatePropagation();
- this.toggleMode();
- }
- };
-
- onInputBlur = (e) => {
- this.toggleMode();
- this.updateTagName(e);
- };
-
- render() {
- const { isEditing, tagName } = this.state;
- return (
-
- {isEditing ?
- :
- {tagName}
-
- }
-
- );
- }
-}
-
-TagName.propTypes = tagNamePropTypes;
-
-export default TagName;
diff --git a/frontend/src/components/dirent-grid-view/dirent-grid-view.js b/frontend/src/components/dirent-grid-view/dirent-grid-view.js
index 20bfc860df..319dc8af88 100644
--- a/frontend/src/components/dirent-grid-view/dirent-grid-view.js
+++ b/frontend/src/components/dirent-grid-view/dirent-grid-view.js
@@ -15,7 +15,6 @@ import MoveDirentDialog from '../dialog/move-dirent-dialog';
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
import ShareDialog from '../dialog/share-dialog';
import ZipDownloadDialog from '../dialog/zip-download-dialog';
-import EditFileTagDialog from '../dialog/edit-filetag-dialog';
import Rename from '../../components/dialog/rename-dirent';
import CreateFile from '../dialog/create-file-dialog';
import CreateFolder from '../dialog/create-folder-dialog';
@@ -53,7 +52,6 @@ const propTypes = {
updateDirent: PropTypes.func.isRequired,
onGridItemClick: PropTypes.func,
repoTags: PropTypes.array.isRequired,
- onFileTagChanged: PropTypes.func,
onAddFolder: PropTypes.func.isRequired,
showDirentDetail: PropTypes.func.isRequired,
onItemRename: PropTypes.func.isRequired,
@@ -80,7 +78,6 @@ class DirentGridView extends React.Component {
isShareDialogShow: false,
isMoveDialogShow: false,
isCopyDialogShow: false,
- isEditFileTagShow: false,
isZipDialogOpen: false,
isRenameDialogShow: false,
isCreateFolderDialogShow: false,
@@ -376,9 +373,6 @@ class DirentGridView extends React.Component {
case 'Convert to sdoc':
this.onItemConvert(currentObject, event, 'sdoc');
break;
- case 'Tags':
- this.onEditFileTagToggle();
- break;
case 'Permission':
this.onPermissionItem();
break;
@@ -453,18 +447,6 @@ class DirentGridView extends React.Component {
hideMenu();
};
- onEditFileTagToggle = () => {
- this.setState({
- isEditFileTagShow: !this.state.isEditFileTagShow
- });
- };
-
- onFileTagChanged = () => {
- let dirent = this.state.activeDirent ? this.state.activeDirent : '';
- let direntPath = Utils.joinPath(this.props.path, dirent.name);
- this.props.onFileTagChanged(dirent, direntPath);
- };
-
getDirentPath = (dirent) => {
let path = this.props.path;
return path === '/' ? path + dirent.name : path + '/' + dirent.name;
@@ -1004,16 +986,6 @@ class DirentGridView extends React.Component {
onAddFolder={this.props.onAddFolder}
/>
}
- {this.state.isEditFileTagShow &&
-
- }
{this.state.isShareDialogShow &&
{};
- }
-
- loadTags = () => {
- seafileAPI.listRepoTags(this.props.repoID).then(res => {
- let repotagList = [];
- res.data.repo_tags.forEach(item => {
- let repo_tag = new RepoTag(item);
- repotagList.push(repo_tag);
- });
- this.setState({ repotagList });
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- };
-
- updateTags = (newRepotagList) => {
- this.setState({
- repotagList: [...this.state.repotagList, ...newRepotagList],
- });
- };
-
- onDeleteTag = (tag) => {
- const { repoID } = this.props;
- const { id: targetTagID } = tag;
- seafileAPI.deleteRepoTag(repoID, targetTagID).then((res) => {
- this.setState({
- repotagList: this.state.repotagList.filter(tag => tag.id != targetTagID)
- });
- }).catch((error) => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- };
-
- createVirtualTag = (e) => {
- e.preventDefault();
- let { repotagList } = this.state;
- let virtual_repo_tag = {
- name: '',
- color: TAG_COLORS[Math.floor(Math.random() * TAG_COLORS.length)], // generate random tag color for virtual tag
- id: `virtual-tag-${uuidv4()}`,
- is_virtual: true,
- };
- repotagList.push(virtual_repo_tag);
- this.setState({ repotagList });
- };
-
- deleteVirtualTag = (virtualTag) => {
- let { repotagList } = this.state;
- let index = repotagList.findIndex(item => item.id === virtualTag.id);
- repotagList.splice(index, 1);
- this.setState({ repotagList });
- };
-
- updateVirtualTag = (virtualTag, data) => {
- const repoID = this.props.repoID;
- const { repotagList } = this.state;
- const index = repotagList.findIndex(item => item.id === virtualTag.id);
- if (index < 0) return null;
-
- // If virtual tag color is updated and virtual tag name is empty, it will be saved to local state, don't save it to the server
- if (data.color) {
- virtualTag.color = data.color;
- repotagList[index] = virtualTag;
- this.setState({ repotagList });
- return;
- }
-
- // If virtual tag name is updated and name is not empty, virtual tag color use default, save it to the server
- if (data.name && data.name.length > 0) {
- let color = virtualTag.color;
- let name = data.name;
- seafileAPI.createRepoTag(repoID, name, color).then((res) => {
- // After saving sag to the server, replace the virtual tag with newly created tag
- repotagList[index] = new RepoTag(res.data.repo_tag);
- this.setState({ repotagList });
- }).catch((error) => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
- };
-
- render() {
- return (
-
-
- {this.state.repotagList.map((repoTag, index) => {
- if (repoTag.is_virtual) {
- return (
-
- );
- } else {
- return (
-
- );
- }
- })}
-
-
- {gettext('Create a new tag')}
-
-
-
- );
- }
-}
diff --git a/frontend/src/components/popover/tag-list-footer.js b/frontend/src/components/popover/tag-list-footer.js
deleted file mode 100644
index ab0f584922..0000000000
--- a/frontend/src/components/popover/tag-list-footer.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { Tooltip } from 'reactstrap';
-import { seafileAPI } from '../../utils/seafile-api';
-import { gettext } from '../../utils/constants';
-import { Utils } from '../../utils/utils';
-import RepoTag from '../../models/repo-tag';
-import toaster from '../toast';
-
-export default class TagListFooter extends Component {
-
- static propTypes = {
- repoID: PropTypes.string.isRequired,
- toggle: PropTypes.func.isRequired,
- repotagList: PropTypes.array.isRequired,
- updateTags: PropTypes.func.isRequired,
- };
-
- constructor(props) {
- super(props);
- this.state = {
- showTooltip: false,
- };
- }
-
- toggleTooltip = () => {
- this.setState({ showTooltip: !this.state.showTooltip });
- };
-
- onClickImport = () => {
- this.importOptionsInput.click();
- };
-
- importTagsInputChange = () => {
- if (!this.importOptionsInput.files || !this.importOptionsInput.files.length) {
- toaster.warning(gettext('Please select a file'));
- return;
- }
- const fileReader = new FileReader();
- fileReader.onload = this.onImportTags.bind(this);
- fileReader.onerror = this.onImportTagsError.bind(this);
- fileReader.readAsText(this.importOptionsInput.files[0]);
- };
-
- getValidTags = (tags) => {
- let validTags = [];
- let tagNameMap = {};
- this.props.repotagList.forEach(tag => tagNameMap[tag.name] = true);
- for (let i = 0; i < tags.length; i++) {
- if (!tags[i] || typeof tags[i] !== 'object' || !tags[i].name || !tags[i].color) {
- continue;
- }
- if (!tagNameMap[tags[i].name]) {
- validTags.push(
- {
- name: tags[i].name,
- color: tags[i].color,
- }
- );
- tagNameMap[tags[i].name] = true;
- }
- }
- return validTags;
- };
-
- onImportTags = (event) => {
- let tags = [];
- try {
- tags = JSON.parse(event.target.result); // handle JSON file format is error
- } catch (error) {
- toaster.danger(gettext('The imported tags are invalid'));
- return;
- }
- if (!Array.isArray(tags) || tags.length === 0) {
- toaster.danger(gettext('The imported tags are invalid'));
- return;
- }
- let validTags = this.getValidTags(tags);
- if (validTags.length === 0) {
- toaster.warning(gettext('The imported tag already exists'));
- return;
- }
- seafileAPI.createRepoTags(this.props.repoID, validTags).then((res) => {
- toaster.success(gettext('Tags imported'));
- let repotagList = [];
- res.data.repo_tags.forEach(item => {
- let repo_tag = new RepoTag(item);
- repotagList.push(repo_tag);
- });
- this.props.updateTags(repotagList);
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- this.importOptionsInput.value = null;
- };
-
- onImportTagsError = () => {
- toaster.success(gettext('Failed to import tags. Please reupload.'));
- };
-
- getDownloadUrl = () => {
- const tags = this.props.repotagList.map(item => {
- return { name: item.name, color: item.color };
- });
- return `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(tags))}`;
- };
-
- render() {
- return (
-
-
-
- {gettext('Use the import/export function to transfer tags quickly to another library. (The export is in JSON format.)')}
-
-
this.importOptionsInput = ref}
- accept='.json'
- className="d-none"
- onChange={this.importTagsInputChange}
- />
-
{gettext('Import tags')}
-
|
-
- {gettext('Export tags')}
-
-
- );
- }
-}
diff --git a/frontend/src/components/popover/tag-list-item.js b/frontend/src/components/popover/tag-list-item.js
deleted file mode 100644
index ec9ba5d2da..0000000000
--- a/frontend/src/components/popover/tag-list-item.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { gettext } from '../../utils/constants';
-import TagColor from '../dialog/tag-color';
-import TagName from '../dialog/tag-name';
-
-import '../../css/repo-tag.css';
-import './list-tag-popover.css';
-
-const tagListItemPropTypes = {
- item: PropTypes.object.isRequired,
- repoID: PropTypes.string.isRequired,
- onDeleteTag: PropTypes.func.isRequired
-};
-
-class TagListItem extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- isTagHighlighted: false
- };
- }
-
- onMouseOver = () => {
- this.setState({
- isTagHighlighted: true
- });
- };
-
- onMouseOut = () => {
- this.setState({
- isTagHighlighted: false
- });
- };
-
- deleteTag = () => {
- this.props.onDeleteTag(this.props.item);
- };
-
- render() {
- const { isTagHighlighted } = this.state;
- const { item, repoID } = this.props;
- return (
-
-
-
-
-
-
- );
- }
-}
-
-TagListItem.propTypes = tagListItemPropTypes;
-
-export default TagListItem;
diff --git a/frontend/src/components/popover/virtual-tag-color.js b/frontend/src/components/popover/virtual-tag-color.js
deleted file mode 100644
index b720ddd762..0000000000
--- a/frontend/src/components/popover/virtual-tag-color.js
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Popover, PopoverBody } from 'reactstrap';
-import { TAG_COLORS } from '../../constants';
-
-import '../../css/repo-tag.css';
-
-export default class VirtualTagColor extends React.Component {
-
- static propTypes = {
- updateVirtualTag: PropTypes.func.isRequired,
- tag: PropTypes.object.isRequired,
- repoID: PropTypes.string.isRequired
- };
-
- constructor(props) {
- super(props);
- this.state = {
- tagColor: this.props.tag.color,
- isPopoverOpen: false
- };
- }
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.tag.color !== this.props.tag.color) {
- this.setState({
- tagColor: nextProps.tag.color,
- });
- }
- }
-
- togglePopover = () => {
- this.setState({
- isPopoverOpen: !this.state.isPopoverOpen
- });
- };
-
- selectTagColor = (e) => {
- const newColor = e.target.value;
- this.props.updateVirtualTag(this.props.tag, { color: newColor });
- this.setState({
- tagColor: newColor,
- isPopoverOpen: !this.state.isPopoverOpen,
- });
- };
-
- render() {
- const { isPopoverOpen, tagColor } = this.state;
- const { tag } = this.props;
- const { id, color } = tag;
-
- let colorList = [...TAG_COLORS];
- // for color from previous color options
- if (colorList.indexOf(color) == -1) {
- colorList.unshift(color);
- }
-
- return (
-
-
-
-
-
-
-
- {colorList.map((item, index) => {
- return (
-
-
-
-
-
-
-
-
- );
- })
- }
-
-
-
-
- );
- }
-}
diff --git a/frontend/src/components/popover/virtual-tag-list-item.js b/frontend/src/components/popover/virtual-tag-list-item.js
deleted file mode 100644
index f5ae5d510e..0000000000
--- a/frontend/src/components/popover/virtual-tag-list-item.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { gettext } from '../../utils/constants';
-import VirtualTagColor from './virtual-tag-color';
-import VirtualTagName from './virtual-tag-name';
-
-import '../../css/repo-tag.css';
-import './list-tag-popover.css';
-
-export default class VirtualTagListItem extends React.Component {
-
- static propTypes = {
- item: PropTypes.object.isRequired,
- repoID: PropTypes.string.isRequired,
- deleteVirtualTag: PropTypes.func.isRequired,
- updateVirtualTag: PropTypes.func.isRequired,
- };
-
- constructor(props) {
- super(props);
- this.state = {
- isTagHighlighted: false
- };
- }
-
- onMouseOver = () => {
- this.setState({ isTagHighlighted: true });
- };
-
- onMouseOut = () => {
- this.setState({ isTagHighlighted: false });
- };
-
- deleteVirtualTag = () => {
- this.props.deleteVirtualTag(this.props.item);
- };
-
- render() {
- const { isTagHighlighted } = this.state;
- const { item, repoID } = this.props;
- return (
-
-
-
-
-
-
- );
- }
-}
diff --git a/frontend/src/components/popover/virtual-tag-name.js b/frontend/src/components/popover/virtual-tag-name.js
deleted file mode 100644
index b50dbdf48e..0000000000
--- a/frontend/src/components/popover/virtual-tag-name.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import '../../css/repo-tag.css';
-
-export default class VirtualTagName extends React.Component {
-
- static propTypes = {
- updateVirtualTag: PropTypes.func.isRequired,
- tag: PropTypes.object.isRequired,
- repoID: PropTypes.string.isRequired
- };
-
- constructor(props) {
- super(props);
- this.state = {
- tagName: this.props.tag.name,
- isEditing: true,
- };
- this.input = React.createRef();
- }
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.tag.name !== this.props.tag.name) {
- this.setState({
- tagName: nextProps.tag.name,
- });
- }
- }
-
- componentDidMount() {
- setTimeout(() => {
- this.input.current.focus();
- }, 1);
- }
-
- toggleMode = () => {
- this.setState({
- isEditing: !this.state.isEditing
- });
- };
-
- updateTagName = (e) => {
- const newName = e.target.value;
- this.props.updateVirtualTag(this.props.tag, { name: newName });
- this.setState({
- tagName: newName
- });
- };
-
- onInputKeyDown = (e) => {
- if (e.key == 'Enter') {
- this.toggleMode();
- this.updateTagName(e);
- }
- else if (e.key == 'Escape') {
- e.nativeEvent.stopImmediatePropagation();
- this.toggleMode();
- }
- };
-
- onInputBlur = (e) => {
- this.toggleMode();
- this.updateTagName(e);
- };
-
- render() {
- const { isEditing, tagName } = this.state;
- return (
-
- {isEditing ?
- :
- {tagName}
-
- }
-
- );
- }
-}
diff --git a/frontend/src/components/toolbar/selected-dirents-toolbar.js b/frontend/src/components/toolbar/selected-dirents-toolbar.js
index 7a313e0896..b4b135c843 100644
--- a/frontend/src/components/toolbar/selected-dirents-toolbar.js
+++ b/frontend/src/components/toolbar/selected-dirents-toolbar.js
@@ -6,7 +6,6 @@ import { seafileAPI } from '../../utils/seafile-api';
import URLDecorator from '../../utils/url-decorator';
import MoveDirentDialog from '../dialog/move-dirent-dialog';
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
-import EditFileTagDialog from '../dialog/edit-filetag-dialog';
import ZipDownloadDialog from '../dialog/zip-download-dialog';
import ShareDialog from '../dialog/share-dialog';
import Rename from '../dialog/rename-dirent';
@@ -23,7 +22,6 @@ const propTypes = {
userPerm: PropTypes.string.isRequired,
repoID: PropTypes.string.isRequired,
repoEncrypted: PropTypes.bool.isRequired,
- repoTags: PropTypes.array.isRequired,
selectedDirentList: PropTypes.array.isRequired,
onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired,
@@ -54,9 +52,7 @@ class SelectedDirentsToolbar extends React.Component {
isMultipleOperation: true,
showLibContentViewDialogs: false,
showShareDialog: false,
- showEditFileTagDialog: false,
fileTagList: [],
- multiFileTagList: [],
isRenameDialogOpen: false,
isPermissionDialogOpen: false
};
@@ -174,9 +170,6 @@ class SelectedDirentsToolbar extends React.Component {
case 'Permission':
this.onPermissionItem();
break;
- case 'Tags':
- this.listFileTags(dirent);
- break;
case 'Lock':
this.lockFile(dirent);
break;
@@ -297,46 +290,17 @@ class SelectedDirentsToolbar extends React.Component {
this.setState({
showLibContentViewDialogs: false,
showShareDialog: false,
- showEditFileTagDialog: false,
isRenameDialogOpen: false,
isPermissionDialogOpen: false,
});
};
- listFileTags = (dirent) => {
- let filePath = this.getDirentPath(dirent);
- seafileAPI.listFileTags(this.props.repoID, filePath).then(res => {
- let fileTagList = res.data.file_tags;
- for (let i = 0, length = fileTagList.length; i < length; i++) {
- fileTagList[i].id = fileTagList[i].file_tag_id;
- }
- this.setState({
- fileTagList: fileTagList,
- showLibContentViewDialogs: true,
- showEditFileTagDialog: true,
- });
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- };
-
- onMenuFileTagChanged = () => {
- this.listFileTags(this.props.selectedDirentList[0]);
- let length = this.props.selectedDirentList.length;
- for (let i = 0; i < length; i++) {
- const dirent = this.props.selectedDirentList[i];
- const direntPath = this.getDirentPath(dirent);
- this.props.onFilesTagChanged(dirent, direntPath);
- }
- };
-
getDirentPath = (dirent) => {
if (dirent) return Utils.joinPath(this.props.path, dirent.name);
};
render() {
- const { repoID, repoTags, userPerm, selectedDirentList } = this.props;
+ const { repoID, userPerm, selectedDirentList } = this.props;
const dirent = selectedDirentList[0];
const selectedLen = selectedDirentList.length;
const direntPath = this.getDirentPath(dirent);
@@ -480,18 +444,6 @@ class SelectedDirentsToolbar extends React.Component {
/>
}
- {this.state.showEditFileTagDialog &&
-
-
-
- }
{this.state.isFileAccessLogDialogOpen &&
{
- this.setState({ isEditTagDialogShow: !this.state.isEditTagDialogShow });
- };
-
onHistoryClick = () => {
let historyUrl = siteRoot + 'repo/file_revisions/' + this.props.repoID + '/?p=' + Utils.encodePath(this.props.path);
location.href = historyUrl;
@@ -111,25 +105,6 @@ class ViewFileToolbar extends React.Component {
});
}
if (filePermission === 'rw') {
- /*
- let newSubOpList = [];
- if (showShareBtn) {
- newSubOpList.push({
- 'text': gettext('Share'),
- 'onClick': this.onShareToggle
- });
- }
- newSubOpList.push(
- {'text': gettext('Tags'), 'onClick': this.onEditFileTagToggle},
- {'text': gettext('History'), 'onClick': this.onHistoryClick}
- );
-
- opList.push({
- 'icon': 'more-vertical',
- 'text': gettext('More'),
- 'subOpList': newSubOpList
- });
- */
if (showShareBtn) {
opList.push({
'icon': 'share',
@@ -137,9 +112,7 @@ class ViewFileToolbar extends React.Component {
'onClick': this.onShareToggle
});
}
-
opList.push(
- { 'icon': 'tag', 'text': gettext('Tags'), 'onClick': this.onEditFileTagToggle },
{ 'icon': 'history', 'text': gettext('History'), 'onClick': this.onHistoryClick }
);
}
@@ -220,18 +193,6 @@ class ViewFileToolbar extends React.Component {
/>
)}
- {this.state.isEditTagDialogShow && (
-
-
-
- )}
);
}
diff --git a/frontend/src/shared-dir-view.js b/frontend/src/shared-dir-view.js
index 5d9c32f5c8..91ad646373 100644
--- a/frontend/src/shared-dir-view.js
+++ b/frontend/src/shared-dir-view.js
@@ -1,8 +1,7 @@
-import React, { Fragment } from 'react';
+import React from 'react';
import PropTypes from 'prop-types';
-import MD5 from 'MD5';
import { createRoot } from 'react-dom/client';
-import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, UncontrolledTooltip } from 'reactstrap';
+import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import Account from './components/common/account';
@@ -1113,14 +1112,6 @@ class Item extends React.Component {
render() {
const { item, isDesktop, mode } = this.props;
const { isIconShown } = this.state;
-
- let toolTipID = '';
- let tagTitle = '';
- if (item.file_tags && item.file_tags.length > 0) {
- toolTipID = MD5(item.file_name).slice(0, 7);
- tagTitle = item.file_tags.map(item => item.tag_name).join(' ');
- }
-
if (item.is_dir) {
return isDesktop ? (