casnode/web/src/admin/AdminTab.js

544 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2020 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import {withRouter} from "react-router-dom";
import * as TabBackend from "../backend/TabBackend.js";
import * as Setting from "../Setting";
import Select2 from "react-select2-wrapper";
import $ from "jquery";
import i18next from "i18next";
class AdminTab extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
nodes: [],
tabs: [],
message: "",
errorMessage: "",
form: {},
tab: [],
//event: props.match.params.event,
tabId: props.match.params.tabId,
width: "",
event: "basic",
Management_LIST: [
{label: "Basic Info", value: "basic"},
],
};
}
componentDidMount() {
this.getTabNodes();
this.getTab();
this.getTabs();
}
getTabs() {
TabBackend.getTabsAdmin()
.then((res) => {
this.setState({
tabs: res,
});
});
}
getTabNodes() {
if (this.state.tabId === undefined && this.props.event !== "new") {
return;
}
TabBackend.getTabWithNode(this.state.tabId)
.then((res) => {
this.setState({
nodes: res?.data2,
});
});
}
getTab() {
if (this.state.tabId === undefined && this.props.event !== "new") {
return;
}
TabBackend.getTabAdmin(this.state.tabId)
.then((res) => {
this.setState({
tab: res,
}, () => {
this.initForm();
});
});
}
initForm() {
let form = this.state.form;
if (this.props.event === "new") {
form["sorter"] = 1;
form["homePage"] = false;
} else {
form["id"] = this.state.tab?.id;
form["name"] = this.state.tab?.name;
form["createdTime"] = this.state.tab?.createdTime;
form["sorter"] = this.state.tab?.sorter;
form["defaultNode"] = this.state.tab?.defaultNode;
form["homePage"] = this.state.tab?.homePage;
}
this.setState({
form: form,
});
}
updateFormField(key, value) {
let form = this.state.form;
form[key] = value;
this.setState({
form: form,
});
}
getIndexFromNodeId(nodeId) {
for (let i = 0; i < this.state.nodes.length; i++) {
if (this.state.nodes[i].id === nodeId) {
return i;
}
}
return -1;
}
deleteTab(tab, topicsNum, nodesNum) {
if (window.confirm(`${i18next.t(`tab:Are you sure to delete tab`)} ${tab} ?`)) {
if (topicsNum !== 0 || nodesNum !== 0) {
alert(`
${i18next.t("tab:Please delete all the nodes and posts under the tab before deleting the tab")}
${i18next.t("tab:Currently the number of nodes under the tab is")} ${nodesNum} ${i18next.t("tab:, the number of posts is")} ${nodesNum}
`);
} else {
TabBackend.deleteTab(tab)
.then((res) => {
if (res.status === 'ok') {
this.setState({
message: `${i18next.t("tab:Delete tab")} ${tab} ${i18next.t("tab:success")}`,
});
this.getTabs();
} else {
this.setState({
errorMessage: res?.msg,
});
}
});
}
}
}
updateTabInfo() {
TabBackend.updateTab(this.state.tabId, this.state.form)
.then((res) => {
if (res.status === 'ok') {
this.getTab();
this.getTabNodes();
this.setState({
message: i18next.t("tab:Update tab information success"),
});
} else {
this.setState({
message: res?.msg,
});
}
});
}
postNewTab() {
if (this.state.form.id === undefined || this.state.form.id === "") {
this.setState({
errorMessage: "Please input tab ID",
});
return;
}
if (this.state.form.name === "" || this.state.form.name === undefined) {
this.setState({
errorMessage: "Please input tab name",
});
return;
}
TabBackend.addTab(this.state.form)
.then((res) => {
if (res.status === 'ok') {
this.getTab();
this.setState({
errorMessage: "",
message: i18next.t("tab:Creat tab success"),
}, () => {
setTimeout(() => Setting.goToLink(`/admin/tab/edit/${this.state.form.id}`), 1600);
});
} else {
this.setState({
errorMessage: res?.msg,
});
}
});
}
clearMessage() {
this.setState({
message: "",
});
}
clearErrorMessage() {
this.setState({
errorMessage: "",
});
}
changeEvent(event) {
this.setState({
event: event,
message: "",
});
if (this.props.event !== "new") {
this.initForm();
}
}
renderProblem() {
let problems = [];
if (this.state.errorMessage !== "") {
problems.push(i18next.t(`error:${this.state.errorMessage}`));
}
if (problems.length === 0) {
return null;
}
return (
<div className="problem" onClick={() => this.clearErrorMessage()}>
{i18next.t("error:Please resolve the following issues before submitting")}
<ul>
{
problems.map((problem, i) => {
return <li>{problem}</li>;
})
}
</ul>
</div>
);
}
renderManagementList(item){
return (
<a href="javascript:void(0);" className={this.state.event === item.value ? "tab_current" : "tab"} onClick={() => this.changeEvent(item.value)}>{i18next.t(`tab:${item.label}`)}</a>
);
}
renderHeader() {
return (
<div className="box">
<div className="header"><a href="/">{Setting.getForumName()}</a>
{" "}<span className="chevron">&nbsp;&nbsp;</span>
<a href={`/admin`}>{i18next.t("admin:Backstage management")}</a>
{" "}<span className="chevron">&nbsp;&nbsp;</span>
<a href={`/admin/tab`}>{i18next.t("tab:Tab management")}</a>
{" "}<span className="chevron">&nbsp;&nbsp;</span>
<span>
{
this.props.event === "new" ?
i18next.t("tab:New tab") : this.state.tabId
}
</span>
</div>
<div className="cell">
{
this.state.Management_LIST.map((item) => {
return this.renderManagementList(item);
})
}
</div>
</div>
);
}
renderTabs(tab) {
const pcBrowser = Setting.PcBrowser;
return (
<div className="cell">
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width={pcBrowser ? "200" : "auto"} align="left">
<span className="gray">
{tab?.name}
</span>
</td>
<td width={pcBrowser ? "100" : "auto"} align="center">
<a href={`/admin/tab/edit/${tab?.id}`}>
{i18next.t("tab:Manage")}
</a>
</td>
<td width="10"></td>
<td width={pcBrowser ? "120" : "80"} valign="middle" style={{textAlign: "center"}}>
<span style={{fontSize: "13px"}}>
{tab?.topicsNum}{" "}{i18next.t("tab:topics")}
</span>
</td>
<td width={pcBrowser ? "120" : "80"} align="left" style={{textAlign: "center"}}>
{tab?.nodesNum}{" "}{i18next.t("tab:nodes")}
</td>
<td width="50" align="left" style={{textAlign: "right"}}>
<a href="#" onClick={() => this.deleteTab(tab?.id, tab?.topicsNum, tab?.nodesNum)}>
{i18next.t("tab:Delete")}
</a>
</td>
</tr>
</tbody>
</table>
</div>
);
}
render() {
const newTab = (this.props.event === "new");
if (this.state.tabId !== undefined || newTab) {
if (this.state.tabId !== undefined) {
if (this.state.tab !== null && this.state.tab.length === 0) {
return (
<div className="box">
<div className="header"><a href="/">{Setting.getForumName()}</a><span className="chevron">&nbsp;&nbsp;</span>{" "}{i18next.t("loading:Page is loading")}</div>
<div className="cell"><span className="gray bigger">{i18next.t("loading:Please wait patiently...")}</span></div>
</div>
);
}
if (this.state.tab === null) {
return (
<div class="box">
<div class="header">
<a href="/">{Setting.getForumName()}</a>
<span className="chevron">&nbsp;&nbsp;</span>{" "}{i18next.t("error:Tab not found")}</div>
<div class="cell">
{i18next.t("error:The tab you are trying to view does not exist")}
</div>
</div>
);
}
}
const tab = this.state.tab;
return (
<div>
{this.renderHeader()}
<div className="box">
{this.renderProblem()}
{
this.state.message !== "" ?
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle"></li>
&nbsp;{" "}
{this.state.message}
</div> : null
}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
{
newTab ?
<tr>
<td width="120" align="right">{i18next.t("tab:Tab ID")}</td>
<td width="auto" align="left">
<input type="text" className="sl" name="id" id="tab_id" value={this.state.form?.id} onChange={event => this.updateFormField("id", event.target.value)} autoComplete="off" />
</td>
</tr> : null
}
<tr>
<td width="120" align="right">{i18next.t("tab:Tab name")}</td>
<td width="auto" align="left">
<input type="text" className="sl" name="name" id="tab_name" value={this.state.form?.name===undefined ? "" : this.state.form?.name} onChange={event => this.updateFormField("name", event.target.value)} autoComplete="off" />
</td>
</tr>
{
!newTab ?
<tr>
<td width="120" align="right">{i18next.t("tab:Created time")}</td>
<td width="auto" align="left">
<span className="gray">
{tab?.createdTime}
</span>
</td>
</tr> : null
}
{
!newTab ?
<tr>
<td width="120" align="right">{i18next.t("tab:Total topics")}</td>
<td width="auto" align="left">
<span className="gray">
{tab?.topicsNum}
</span>
</td>
</tr> : null
}
{
!newTab ?
<tr>
<td width="120" align="right">{i18next.t("tab:Total nodes")}</td>
<td width="auto" align="left">
<span className="gray">
{tab?.nodesNum}
</span>
</td>
</tr> : null
}
<tr>
<td width="120" align="right">{i18next.t("tab:Sorter")}</td>
<td width="auto" align="left">
<input type="range" min="1" max="1000" step="1" value={this.state.form?.sorter === undefined ? 1 : this.state.form?.sorter} onChange={event => this.updateFormField("sorter", parseInt(event.target.value))}/>
&nbsp;{" "}&nbsp;{" "}
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{width: "50px"}} onChange={event => this.updateFormField("sorter", parseInt(event.target.value))} />
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<span className="gray">
{i18next.t("tab:Decide the order of node navigation and homepage")}
</span>
</td>
</tr>
<tr>
<td width="120" align="right">{i18next.t("tab:Home page")}</td>
<td width="auto" align="left">
<input type="radio" onClick={() => this.updateFormField("homePage", true)} checked={this.state.form?.homePage} name="homePage" />{i18next.t("tab:show")}{" "}
<input type="radio" onClick={() => this.updateFormField("homePage", false)} checked={!this.state.form?.homePage} name="homePage" />{i18next.t("tab:hidden")}
</td>
</tr>
{
this.state.form?.homePage ?
<tr>
<td width="120" align="right">{i18next.t("tab:Default node")}</td>
<td width="auto" align="left">
{
tab?.nodesNum !== 0 && tab?.nodesNum !== undefined ?
<Select2
value={this.getIndexFromNodeId(this.state.form?.defaultNode)}
style={{width: "300px", fontSize: "14px"}}
data={
this.state.nodes.map((node, i) => {
return {text: `${node.name} / ${node.id}`, id: i};
})
}
onSelect={event => {
const s = $(event.target).val();
if (s === null) {
return;
}
const index = parseInt(s);
const nodeId = this.state.nodes[index].id;
this.updateFormField("defaultNode", nodeId);
}}
options={
{
placeholder: i18next.t("tab:Please select a default node"),
}
}
/> :
<span className="gray">
{i18next.t("tab:No node exists in this tab")}
</span>
}
</td>
</tr> : null
}
{
this.state.form?.homePage ?
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<span className="gray">
{i18next.t("tab:The default node when creating a topic on the homepage")}
</span>
</td>
</tr> : null
}
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
{
!newTab ?
<input type="submit" className="super normal button" value={i18next.t("tab:Save")} onClick={() => this.updateTabInfo()}/> :
<input type="submit" className="super normal button" value={i18next.t("tab:Create")} onClick={() => this.postNewTab()}/>
}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
);
}
return (
<div className="box">
<div className="header">
<a href="/">{Setting.getForumName()}</a>
{" "}<span className="chevron">&nbsp;&nbsp;</span>
<a href={`/admin`}>{i18next.t("admin:Backstage management")}</a>
<span className="chevron">&nbsp;&nbsp;</span>{" "}{i18next.t("tab:Tab management")}
<div className="fr f12">
<span className="snow">{i18next.t("tab:Total tabs")}{" "}&nbsp;</span>
<strong className="gray">{this.state.tabs === null ? 0 : this.state.tabs.length}</strong>
</div>
<div className="fr f12">
<strong className="gray">
<a href="tab/new">{i18next.t("tab:Add new tab")}</a>
{" "}&nbsp;
</strong>
</div>
</div>
{
this.state.message !== "" ?
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle"></li>
&nbsp;{" "}
{this.state.message}
</div> : null
}
<div id="all-tabs">
{
this.state.tabs !== null && this.state.tabs.length !== 0 ?
this.state.tabs.map(tab => this.renderTabs(tab)) :
<div className="cell" style={{textAlign: "center", height: "100px", lineHeight: "100px"}}>
{
this.state.tabs === null ?
i18next.t("tab:No tab yet") : i18next.t("loading:Data is loading...")
}
</div>
}
</div>
</div>
);
}
}
export default withRouter(AdminTab);