Merge branch 'tat_remove' into 'master'
make tags deleteable See merge request lukas/openmediacenter!30
This commit is contained in:
commit
f06da8044f
@ -9,6 +9,7 @@ class Tags extends RequestBase {
|
||||
function initHandlers() {
|
||||
$this->addToDB();
|
||||
$this->getFromDB();
|
||||
$this->delete();
|
||||
}
|
||||
|
||||
private function addToDB() {
|
||||
@ -65,4 +66,36 @@ class Tags extends RequestBase {
|
||||
$this->commitMessage(json_encode($rows));
|
||||
});
|
||||
}
|
||||
|
||||
private function delete() {
|
||||
/**
|
||||
* delete a Tag with specified id
|
||||
*/
|
||||
$this->addActionHandler("deleteTag", function () {
|
||||
$tag_id = $_POST['tagId'];
|
||||
$force = $_POST['force'];
|
||||
|
||||
// delete key constraints first
|
||||
if ($force === "true") {
|
||||
$query = "DELETE FROM video_tags WHERE tag_id=$tag_id";
|
||||
|
||||
if ($this->conn->query($query) !== TRUE) {
|
||||
$this->commitMessage('{"result":"' . $this->conn->error . '"}');
|
||||
}
|
||||
}
|
||||
|
||||
$query = "DELETE FROM tags WHERE tag_id=$tag_id";
|
||||
|
||||
if ($this->conn->query($query) === TRUE) {
|
||||
$this->commitMessage('{"result":"success"}');
|
||||
} else {
|
||||
// check if error is a constraint error
|
||||
if (preg_match('/^.*a foreign key constraint fails.*$/i', $this->conn->error)) {
|
||||
$this->commitMessage('{"result":"not empty tag"}');
|
||||
} else {
|
||||
$this->commitMessage('{"result":"' . $this->conn->eror . '"}');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import GlobalInfos from '../../utils/GlobalInfos';
|
||||
|
||||
interface props {
|
||||
title: string;
|
||||
subtitle: string | null;
|
||||
subtitle: string | number | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,60 +22,14 @@ describe('<AddTagPopup/>', function () {
|
||||
});
|
||||
|
||||
it('test tag click', function () {
|
||||
const wrapper = shallow(<AddTagPopup/>);
|
||||
wrapper.instance().addTag = jest.fn();
|
||||
const wrapper = shallow(<AddTagPopup submit={jest.fn()} onHide={jest.fn()}/>);
|
||||
|
||||
wrapper.setState({
|
||||
items: [{tag_id: 1, tag_name: 'test'}]
|
||||
}, () => {
|
||||
wrapper.find('Tag').first().dive().simulate('click');
|
||||
expect(wrapper.instance().addTag).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('test addtag', done => {
|
||||
const wrapper = shallow(<AddTagPopup movie_id={1}/>);
|
||||
|
||||
global.fetch = prepareFetchApi({result: 'success'});
|
||||
|
||||
wrapper.setProps({
|
||||
submit: jest.fn(() => {}),
|
||||
onHide: jest.fn()
|
||||
}, () => {
|
||||
wrapper.instance().addTag(1, 'test');
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.instance().props.submit).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.onHide).toHaveBeenCalledTimes(1);
|
||||
|
||||
global.fetch.mockClear();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('test failing addTag', done => {
|
||||
const wrapper = shallow(<AddTagPopup movie_id={1}/>);
|
||||
|
||||
global.fetch = prepareFetchApi({result: 'fail'});
|
||||
|
||||
wrapper.setProps({
|
||||
submit: jest.fn(() => {}),
|
||||
onHide: jest.fn()
|
||||
}, () => {
|
||||
wrapper.instance().addTag(1, 'test');
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.instance().props.submit).toHaveBeenCalledTimes(0);
|
||||
expect(wrapper.instance().props.onHide).toHaveBeenCalledTimes(1);
|
||||
|
||||
global.fetch.mockClear();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -3,7 +3,6 @@ import Tag from '../../Tag/Tag';
|
||||
import PopupBase from '../PopupBase';
|
||||
import {callAPI} from '../../../utils/Api';
|
||||
import {TagType} from '../../../types/VideoTypes';
|
||||
import {GeneralSuccess} from '../../../types/GeneralTypes';
|
||||
|
||||
interface props {
|
||||
onHide: () => void;
|
||||
@ -41,29 +40,13 @@ class AddTagPopup extends React.Component<props, state> {
|
||||
this.state.items.map((i) => (
|
||||
<Tag tagInfo={i}
|
||||
onclick={(): void => {
|
||||
this.addTag(i.tag_id, i.tag_name);
|
||||
this.props.submit(i.tag_id, i.tag_name);
|
||||
this.props.onHide();
|
||||
}}/>
|
||||
)) : null}
|
||||
</PopupBase>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new tag to this video
|
||||
* @param tagid tag id to add
|
||||
* @param tagname tag name to add
|
||||
*/
|
||||
addTag(tagid: number, tagname: string): void {
|
||||
callAPI('tags.php', {action: 'addTag', id: tagid, movieid: this.props.movie_id}, (result: GeneralSuccess) => {
|
||||
if (result.result !== 'success') {
|
||||
console.log('error occured while writing to db -- todo error handling');
|
||||
console.log(result.result);
|
||||
} else {
|
||||
this.props.submit(tagid, tagname);
|
||||
}
|
||||
this.props.onHide();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default AddTagPopup;
|
||||
|
28
src/elements/Popups/SubmitPopup/SubmitPopup.test.js
Normal file
28
src/elements/Popups/SubmitPopup/SubmitPopup.test.js
Normal file
@ -0,0 +1,28 @@
|
||||
import {shallow} from "enzyme";
|
||||
import React from "react";
|
||||
import SubmitPopup from "./SubmitPopup";
|
||||
|
||||
describe('<SubmitPopup/>', function () {
|
||||
it('renders without crashing ', function () {
|
||||
const wrapper = shallow(<SubmitPopup/>);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('test submit click', function () {
|
||||
const func = jest.fn();
|
||||
const wrapper = shallow(<SubmitPopup submit={() => func()}/>);
|
||||
|
||||
wrapper.find('Button').findWhere(p => p.props().title === 'Submit').simulate('click');
|
||||
|
||||
expect(func).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('test cancel click', function () {
|
||||
const func = jest.fn();
|
||||
const wrapper = shallow(<SubmitPopup onHide={() => func()}/>);
|
||||
|
||||
wrapper.find('Button').findWhere(p => p.props().title === 'Cancel').simulate('click');
|
||||
|
||||
expect(func).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
18
src/elements/Popups/SubmitPopup/SubmitPopup.tsx
Normal file
18
src/elements/Popups/SubmitPopup/SubmitPopup.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import PopupBase from '../PopupBase';
|
||||
import {Button} from '../../GPElements/Button';
|
||||
|
||||
interface props {
|
||||
onHide: (_: void) => void;
|
||||
submit: (_: void) => void;
|
||||
}
|
||||
|
||||
export default function SubmitPopup(props: props): JSX.Element {
|
||||
return (
|
||||
<PopupBase title='Are you sure?' onHide={props.onHide} height='160px' width='300px'>
|
||||
<Button title='Submit' color={{backgroundColor: 'green'}} onClick={(): void => props.submit()}/>
|
||||
<Button title='Cancel' color={{backgroundColor: 'red'}} onClick={(): void => props.onHide()}/>
|
||||
</PopupBase>
|
||||
);
|
||||
|
||||
}
|
@ -7,41 +7,4 @@ describe('<CategoryPage/>', function () {
|
||||
const wrapper = shallow(<CategoryPage/>);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('test new tag popup', function () {
|
||||
const wrapper = shallow(<CategoryPage/>);
|
||||
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
|
||||
wrapper.find('[data-testid="btnaddtag"]').simulate('click');
|
||||
// newtagpopup should be showing now
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('test add popup', function () {
|
||||
const wrapper = shallow(<CategoryPage/>);
|
||||
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
|
||||
wrapper.setState({popupvisible: true});
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('test hiding of popup', function () {
|
||||
const wrapper = shallow(<CategoryPage/>);
|
||||
wrapper.setState({popupvisible: true});
|
||||
|
||||
wrapper.find('NewTagPopup').props().onHide();
|
||||
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('test setting of subtitle', function () {
|
||||
const wrapper = shallow(<CategoryPage/>);
|
||||
|
||||
expect(wrapper.find('PageTitle').props().subtitle).not.toBe('testtitle');
|
||||
|
||||
wrapper.instance().setSubTitle('testtitle');
|
||||
|
||||
// test if prop of title is set correctly
|
||||
expect(wrapper.find('PageTitle').props().subtitle).toBe('testtitle');
|
||||
});
|
||||
});
|
||||
|
@ -1,82 +1,25 @@
|
||||
import React from 'react';
|
||||
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
|
||||
import Tag from '../../elements/Tag/Tag';
|
||||
import NewTagPopup from '../../elements/Popups/NewTagPopup/NewTagPopup';
|
||||
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
|
||||
import {Route, Switch} from 'react-router-dom';
|
||||
import {DefaultTags} from '../../types/GeneralTypes';
|
||||
import {CategoryViewWR} from './CategoryView';
|
||||
import TagView from './TagView';
|
||||
|
||||
|
||||
interface CategoryPageState {
|
||||
popupvisible: boolean;
|
||||
subtitle: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component for Category Page
|
||||
* Contains a Tag Overview and loads specific Tag videos in VideoContainer
|
||||
*/
|
||||
class CategoryPage extends React.Component<{}, CategoryPageState> {
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
popupvisible: false,
|
||||
subtitle: ''
|
||||
};
|
||||
|
||||
this.setSubTitle = this.setSubTitle.bind(this);
|
||||
}
|
||||
|
||||
class CategoryPage extends React.Component {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<PageTitle
|
||||
title='Categories'
|
||||
subtitle={this.state.subtitle}/>
|
||||
|
||||
<SideBar>
|
||||
<SideBarTitle>Default Tags:</SideBarTitle>
|
||||
<Tag tagInfo={DefaultTags.all}/>
|
||||
<Tag tagInfo={DefaultTags.fullhd}/>
|
||||
<Tag tagInfo={DefaultTags.hd}/>
|
||||
<Tag tagInfo={DefaultTags.lowq}/>
|
||||
|
||||
<Line/>
|
||||
<button data-testid='btnaddtag' className='btn btn-success' onClick={(): void => {
|
||||
this.setState({popupvisible: true});
|
||||
}}>Add a new Tag!
|
||||
</button>
|
||||
</SideBar>
|
||||
<Switch>
|
||||
<Route path='/categories/:id'>
|
||||
<CategoryViewWR setSubTitle={this.setSubTitle}/>
|
||||
<CategoryViewWR/>
|
||||
</Route>
|
||||
<Route path='/categories'>
|
||||
<TagView setSubTitle={this.setSubTitle}/>
|
||||
<TagView/>
|
||||
</Route>
|
||||
</Switch>
|
||||
|
||||
{this.state.popupvisible ?
|
||||
<NewTagPopup onHide={(): void => {
|
||||
this.setState({popupvisible: false});
|
||||
// this.loadTags();
|
||||
}}/> :
|
||||
null
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the subtitle of this page
|
||||
* @param subtitle string as subtitle
|
||||
*/
|
||||
setSubTitle(subtitle: string): void {
|
||||
this.setState({subtitle: subtitle});
|
||||
}
|
||||
}
|
||||
|
||||
export default CategoryPage;
|
||||
|
@ -4,7 +4,7 @@ import {CategoryView} from './CategoryView';
|
||||
|
||||
describe('<CategoryView/>', function () {
|
||||
function instance() {
|
||||
return shallow(<CategoryView match={{params: {id: 10}}}/>);
|
||||
return shallow(<CategoryView match={{params: {id: 10}}} history={{push: jest.fn()}}/>);
|
||||
}
|
||||
|
||||
it('renders without crashing ', function () {
|
||||
@ -21,4 +21,54 @@ describe('<CategoryView/>', function () {
|
||||
wrapper.find('button').simulate('click');
|
||||
expect(func).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('test delete of tag', function () {
|
||||
const wrapper = instance();
|
||||
callAPIMock({result: 'success'});
|
||||
|
||||
// simulate button click
|
||||
wrapper.find('Button').props().onClick();
|
||||
|
||||
expect(wrapper.instance().props.history.push).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('test delete of non empty tag', function () {
|
||||
const wrapper = instance();
|
||||
callAPIMock({result: 'not empty tag'});
|
||||
|
||||
// simulate button click
|
||||
wrapper.find('Button').props().onClick();
|
||||
|
||||
// expect SubmitPopup showing
|
||||
expect(wrapper.find('SubmitPopup')).toHaveLength(1);
|
||||
|
||||
// mock deleteTag function
|
||||
wrapper.instance().deleteTag = jest.fn((v) => {});
|
||||
|
||||
// simulate submit
|
||||
wrapper.find('SubmitPopup').props().submit();
|
||||
|
||||
// expect deleteTag function to have been called with force parameter
|
||||
expect(wrapper.instance().deleteTag).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('test cancel of ', function () {
|
||||
const wrapper = instance();
|
||||
callAPIMock({result: 'not empty tag'});
|
||||
|
||||
// simulate button click
|
||||
wrapper.find('Button').props().onClick();
|
||||
|
||||
// expect SubmitPopup showing
|
||||
expect(wrapper.find('SubmitPopup')).toHaveLength(1);
|
||||
|
||||
// mock deleteTag function
|
||||
wrapper.instance().deleteTag = jest.fn((v) => {});
|
||||
|
||||
// simulate submit
|
||||
wrapper.find('SubmitPopup').props().onHide();
|
||||
|
||||
// expect deleteTag function to have been called with force parameter
|
||||
expect(wrapper.instance().deleteTag).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
@ -4,13 +4,18 @@ import VideoContainer from '../../elements/VideoContainer/VideoContainer';
|
||||
import {callAPI} from '../../utils/Api';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import {VideoTypes} from '../../types/ApiTypes';
|
||||
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
|
||||
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
|
||||
import Tag from '../../elements/Tag/Tag';
|
||||
import {DefaultTags, GeneralSuccess} from '../../types/GeneralTypes';
|
||||
import {Button} from '../../elements/GPElements/Button';
|
||||
import SubmitPopup from '../../elements/Popups/SubmitPopup/SubmitPopup';
|
||||
|
||||
interface CategoryViewProps extends RouteComponentProps<{ id: string }> {
|
||||
setSubTitle: (title: string) => void
|
||||
}
|
||||
interface CategoryViewProps extends RouteComponentProps<{ id: string }> {}
|
||||
|
||||
interface CategoryViewState {
|
||||
loaded: boolean
|
||||
loaded: boolean;
|
||||
submitForceDelete: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,7 +28,8 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
loaded: false
|
||||
loaded: false,
|
||||
submitForceDelete: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -42,6 +48,20 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<PageTitle
|
||||
title='Categories'
|
||||
subtitle={this.videodata.length + ' Videos'}/>
|
||||
|
||||
<SideBar>
|
||||
<SideBarTitle>Default Tags:</SideBarTitle>
|
||||
<Tag tagInfo={DefaultTags.all}/>
|
||||
<Tag tagInfo={DefaultTags.fullhd}/>
|
||||
<Tag tagInfo={DefaultTags.hd}/>
|
||||
<Tag tagInfo={DefaultTags.lowq}/>
|
||||
|
||||
<Line/>
|
||||
<Button title='Delete Tag' onClick={(): void => {this.deleteTag(false);}} color={{backgroundColor: 'red'}}/>
|
||||
</SideBar>
|
||||
{this.state.loaded ?
|
||||
<VideoContainer
|
||||
data={this.videodata}/> : null}
|
||||
@ -51,22 +71,50 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
|
||||
this.props.history.push('/categories');
|
||||
}}>Back to Categories
|
||||
</button>
|
||||
{this.handlePopups()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private handlePopups(): JSX.Element {
|
||||
if (this.state.submitForceDelete) {
|
||||
return (<SubmitPopup
|
||||
onHide={(): void => this.setState({submitForceDelete: false})}
|
||||
submit={(): void => {this.deleteTag(true);}}/>);
|
||||
} else {
|
||||
return <></>;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch data for a specific tag from backend
|
||||
* @param id tagid
|
||||
*/
|
||||
fetchVideoData(id: number): void {
|
||||
private fetchVideoData(id: number): void {
|
||||
callAPI<VideoTypes.VideoUnloadedType[]>('video.php', {action: 'getMovies', tag: id}, result => {
|
||||
this.videodata = result;
|
||||
this.setState({loaded: true});
|
||||
this.props.setSubTitle(this.videodata.length + ' Videos');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* delete the current tag
|
||||
*/
|
||||
private deleteTag(force: boolean): void {
|
||||
callAPI<GeneralSuccess>('tags.php', {
|
||||
action: 'deleteTag',
|
||||
tagId: parseInt(this.props.match.params.id),
|
||||
force: force
|
||||
}, result => {
|
||||
console.log(result.result);
|
||||
if (result.result === 'success') {
|
||||
this.props.history.push('/categories');
|
||||
} else if (result.result === 'not empty tag') {
|
||||
// show submisison tag to ask if really delete
|
||||
this.setState({submitForceDelete: true});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,4 +14,30 @@ describe('<TagView/>', function () {
|
||||
|
||||
expect(wrapper.find('TagPreview')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('test new tag popup', function () {
|
||||
const wrapper = shallow(<TagView/>);
|
||||
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
|
||||
wrapper.find('[data-testid="btnaddtag"]').simulate('click');
|
||||
// newtagpopup should be showing now
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('test add popup', function () {
|
||||
const wrapper = shallow(<TagView/>);
|
||||
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
|
||||
wrapper.setState({popupvisible: true});
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('test hiding of popup', function () {
|
||||
const wrapper = shallow(<TagView/>);
|
||||
wrapper.setState({popupvisible: true});
|
||||
|
||||
wrapper.find('NewTagPopup').props().onHide();
|
||||
|
||||
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
@ -4,20 +4,27 @@ import videocontainerstyle from '../../elements/VideoContainer/VideoContainer.mo
|
||||
import {Link} from 'react-router-dom';
|
||||
import {TagPreview} from '../../elements/Preview/Preview';
|
||||
import {callAPI} from '../../utils/Api';
|
||||
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
|
||||
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
|
||||
import Tag from '../../elements/Tag/Tag';
|
||||
import {DefaultTags} from '../../types/GeneralTypes';
|
||||
import NewTagPopup from '../../elements/Popups/NewTagPopup/NewTagPopup';
|
||||
|
||||
interface TagViewState {
|
||||
loadedtags: TagType[];
|
||||
popupvisible: boolean;
|
||||
}
|
||||
|
||||
interface props {
|
||||
setSubTitle: (title: string) => void
|
||||
}
|
||||
interface props {}
|
||||
|
||||
class TagView extends React.Component<props, TagViewState> {
|
||||
constructor(props: props) {
|
||||
super(props);
|
||||
|
||||
this.state = {loadedtags: []};
|
||||
this.state = {
|
||||
loadedtags: [],
|
||||
popupvisible: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
@ -27,6 +34,23 @@ class TagView extends React.Component<props, TagViewState> {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<PageTitle
|
||||
title='Categories'
|
||||
subtitle={this.state.loadedtags.length + ' different Tags'}/>
|
||||
|
||||
<SideBar>
|
||||
<SideBarTitle>Default Tags:</SideBarTitle>
|
||||
<Tag tagInfo={DefaultTags.all}/>
|
||||
<Tag tagInfo={DefaultTags.fullhd}/>
|
||||
<Tag tagInfo={DefaultTags.hd}/>
|
||||
<Tag tagInfo={DefaultTags.lowq}/>
|
||||
|
||||
<Line/>
|
||||
<button data-testid='btnaddtag' className='btn btn-success' onClick={(): void => {
|
||||
this.setState({popupvisible: true});
|
||||
}}>Add a new Tag!
|
||||
</button>
|
||||
</SideBar>
|
||||
<div className={videocontainerstyle.maincontent}>
|
||||
{this.state.loadedtags ?
|
||||
this.state.loadedtags.map((m) => (
|
||||
@ -36,6 +60,7 @@ class TagView extends React.Component<props, TagViewState> {
|
||||
)) :
|
||||
'loading'}
|
||||
</div>
|
||||
{this.handlePopups()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -46,9 +71,21 @@ class TagView extends React.Component<props, TagViewState> {
|
||||
loadTags(): void {
|
||||
callAPI<TagType[]>('tags.php', {action: 'getAllTags'}, result => {
|
||||
this.setState({loadedtags: result});
|
||||
this.props.setSubTitle(result.length + ' different Tags');
|
||||
});
|
||||
}
|
||||
|
||||
private handlePopups(): JSX.Element {
|
||||
if (this.state.popupvisible) {
|
||||
return (
|
||||
<NewTagPopup onHide={(): void => {
|
||||
this.setState({popupvisible: false});
|
||||
this.loadTags();
|
||||
}}/>
|
||||
);
|
||||
} else {
|
||||
return (<></>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default TagView;
|
||||
|
Loading…
Reference in New Issue
Block a user