feat: add transaction pages (#2761)

This commit is contained in:
DacongDA 2024-03-02 10:41:16 +08:00 committed by GitHub
parent ba1ddc7e50
commit 12acb24dbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 1095 additions and 0 deletions

167
controllers/transaction.go Normal file
View File

@ -0,0 +1,167 @@
// Copyright 2024 The Casdoor 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.
package controllers
import (
"encoding/json"
"github.com/beego/beego/utils/pagination"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"
)
// GetTransactions
// @Title GetTransactions
// @Tag Transaction API
// @Description get transactions
// @Param owner query string true "The owner of transactions"
// @Success 200 {array} object.Transaction The Response object
// @router /get-transactions [get]
func (c *ApiController) GetTransactions() {
owner := c.Input().Get("owner")
limit := c.Input().Get("pageSize")
page := c.Input().Get("p")
field := c.Input().Get("field")
value := c.Input().Get("value")
sortField := c.Input().Get("sortField")
sortOrder := c.Input().Get("sortOrder")
if limit == "" || page == "" {
transactions, err := object.GetTransactions(owner)
if err != nil {
c.ResponseError(err.Error())
return
}
c.ResponseOk(transactions)
} else {
limit := util.ParseInt(limit)
count, err := object.GetTransactionCount(owner, field, value)
if err != nil {
c.ResponseError(err.Error())
return
}
paginator := pagination.SetPaginator(c.Ctx, limit, count)
transactions, err := object.GetPaginationTransactions(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
if err != nil {
c.ResponseError(err.Error())
return
}
c.ResponseOk(transactions, paginator.Nums())
}
}
// GetUserTransactions
// @Title GetUserTransaction
// @Tag Transaction API
// @Description get transactions for a user
// @Param owner query string true "The owner of transactions"
// @Param organization query string true "The organization of the user"
// @Param user query string true "The username of the user"
// @Success 200 {array} object.Transaction The Response object
// @router /get-user-transactions [get]
func (c *ApiController) GetUserTransactions() {
owner := c.Input().Get("owner")
user := c.Input().Get("user")
transactions, err := object.GetUserTransactions(owner, user)
if err != nil {
c.ResponseError(err.Error())
return
}
c.ResponseOk(transactions)
}
// GetTransaction
// @Title GetTransaction
// @Tag Transaction API
// @Description get transaction
// @Param id query string true "The id ( owner/name ) of the transaction"
// @Success 200 {object} object.Transaction The Response object
// @router /get-transaction [get]
func (c *ApiController) GetTransaction() {
id := c.Input().Get("id")
transaction, err := object.GetTransaction(id)
if err != nil {
c.ResponseError(err.Error())
return
}
c.ResponseOk(transaction)
}
// UpdateTransaction
// @Title UpdateTransaction
// @Tag Transaction API
// @Description update transaction
// @Param id query string true "The id ( owner/name ) of the transaction"
// @Param body body object.Transaction true "The details of the transaction"
// @Success 200 {object} controllers.Response The Response object
// @router /update-transaction [post]
func (c *ApiController) UpdateTransaction() {
id := c.Input().Get("id")
var transaction object.Transaction
err := json.Unmarshal(c.Ctx.Input.RequestBody, &transaction)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = wrapActionResponse(object.UpdateTransaction(id, &transaction))
c.ServeJSON()
}
// AddTransaction
// @Title AddTransaction
// @Tag Transaction API
// @Description add transaction
// @Param body body object.Transaction true "The details of the transaction"
// @Success 200 {object} controllers.Response The Response object
// @router /add-transaction [post]
func (c *ApiController) AddTransaction() {
var transaction object.Transaction
err := json.Unmarshal(c.Ctx.Input.RequestBody, &transaction)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = wrapActionResponse(object.AddTransaction(&transaction))
c.ServeJSON()
}
// DeleteTransaction
// @Title DeleteTransaction
// @Tag Transaction API
// @Description delete transaction
// @Param body body object.Transaction true "The details of the transaction"
// @Success 200 {object} controllers.Response The Response object
// @router /delete-transaction [post]
func (c *ApiController) DeleteTransaction() {
var transaction object.Transaction
err := json.Unmarshal(c.Ctx.Input.RequestBody, &transaction)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = wrapActionResponse(object.DeleteTransaction(&transaction))
c.ServeJSON()
}

View File

@ -388,6 +388,11 @@ func (a *Ormer) createTable() {
panic(err) panic(err)
} }
err = a.Engine.Sync2(new(Transaction))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Syncer)) err = a.Engine.Sync2(new(Syncer))
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -221,6 +221,12 @@ func initAPI() {
beego.Router("/api/add-subscription", &controllers.ApiController{}, "POST:AddSubscription") beego.Router("/api/add-subscription", &controllers.ApiController{}, "POST:AddSubscription")
beego.Router("/api/delete-subscription", &controllers.ApiController{}, "POST:DeleteSubscription") beego.Router("/api/delete-subscription", &controllers.ApiController{}, "POST:DeleteSubscription")
beego.Router("/api/get-transactions", &controllers.ApiController{}, "GET:GetTransactions")
beego.Router("/api/get-transaction", &controllers.ApiController{}, "GET:GetTransaction")
beego.Router("/api/update-transaction", &controllers.ApiController{}, "POST:UpdateTransaction")
beego.Router("/api/add-transaction", &controllers.ApiController{}, "POST:AddTransaction")
beego.Router("/api/delete-transaction", &controllers.ApiController{}, "POST:DeleteTransaction")
beego.Router("/api/get-system-info", &controllers.ApiController{}, "GET:GetSystemInfo") beego.Router("/api/get-system-info", &controllers.ApiController{}, "GET:GetSystemInfo")
beego.Router("/api/get-version-info", &controllers.ApiController{}, "GET:GetVersionInfo") beego.Router("/api/get-version-info", &controllers.ApiController{}, "GET:GetVersionInfo")
beego.Router("/api/health", &controllers.ApiController{}, "GET:Health") beego.Router("/api/health", &controllers.ApiController{}, "GET:Health")

View File

@ -90,6 +90,8 @@ import AccountAvatar from "./account/AccountAvatar";
import {Content, Header} from "antd/es/layout/layout"; import {Content, Header} from "antd/es/layout/layout";
import * as AuthBackend from "./auth/AuthBackend"; import * as AuthBackend from "./auth/AuthBackend";
import {clearWeb3AuthToken} from "./auth/Web3Auth"; import {clearWeb3AuthToken} from "./auth/Web3Auth";
import TransactionListPage from "./TransactionListPage";
import TransactionEditPage from "./TransactionEditPage";
function ManagementPage(props) { function ManagementPage(props) {
@ -279,6 +281,7 @@ function ManagementPage(props) {
Setting.getItem(<Link to="/plans">{i18next.t("general:Plans")}</Link>, "/plans"), Setting.getItem(<Link to="/plans">{i18next.t("general:Plans")}</Link>, "/plans"),
Setting.getItem(<Link to="/pricings">{i18next.t("general:Pricings")}</Link>, "/pricings"), Setting.getItem(<Link to="/pricings">{i18next.t("general:Pricings")}</Link>, "/pricings"),
Setting.getItem(<Link to="/subscriptions">{i18next.t("general:Subscriptions")}</Link>, "/subscriptions"), Setting.getItem(<Link to="/subscriptions">{i18next.t("general:Subscriptions")}</Link>, "/subscriptions"),
Setting.getItem(<Link to="/transactions">{i18next.t("general:Transactions")}</Link>, "/transactions"),
])); ]));
if (Setting.isAdminUser(props.account)) { if (Setting.isAdminUser(props.account)) {
@ -365,6 +368,8 @@ function ManagementPage(props) {
<Route exact path="/sysinfo" render={(props) => renderLoginIfNotLoggedIn(<SystemInfo account={account} {...props} />)} /> <Route exact path="/sysinfo" render={(props) => renderLoginIfNotLoggedIn(<SystemInfo account={account} {...props} />)} />
<Route exact path="/syncers" render={(props) => renderLoginIfNotLoggedIn(<SyncerListPage account={account} {...props} />)} /> <Route exact path="/syncers" render={(props) => renderLoginIfNotLoggedIn(<SyncerListPage account={account} {...props} />)} />
<Route exact path="/syncers/:syncerName" render={(props) => renderLoginIfNotLoggedIn(<SyncerEditPage account={account} {...props} />)} /> <Route exact path="/syncers/:syncerName" render={(props) => renderLoginIfNotLoggedIn(<SyncerEditPage account={account} {...props} />)} />
<Route exact path="/transactions" render={(props) => renderLoginIfNotLoggedIn(<TransactionListPage account={account} {...props} />)} />
<Route exact path="/transactions/:organizationName/:transactionName" render={(props) => renderLoginIfNotLoggedIn(<TransactionEditPage account={account} {...props} />)} />
<Route exact path="/webhooks" render={(props) => renderLoginIfNotLoggedIn(<WebhookListPage account={account} {...props} />)} /> <Route exact path="/webhooks" render={(props) => renderLoginIfNotLoggedIn(<WebhookListPage account={account} {...props} />)} />
<Route exact path="/webhooks/:webhookName" render={(props) => renderLoginIfNotLoggedIn(<WebhookEditPage account={account} {...props} />)} /> <Route exact path="/webhooks/:webhookName" render={(props) => renderLoginIfNotLoggedIn(<WebhookEditPage account={account} {...props} />)} />
<Route exact path="/ldap/:organizationName/:ldapId" render={(props) => renderLoginIfNotLoggedIn(<LdapEditPage account={account} {...props} />)} /> <Route exact path="/ldap/:organizationName/:ldapId" render={(props) => renderLoginIfNotLoggedIn(<LdapEditPage account={account} {...props} />)} />

View File

@ -0,0 +1,324 @@
// Copyright 2024 The Casdoor 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 * as TransactionBackend from "./backend/TransactionBackend";
import * as Setting from "./Setting";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import {Button, Card, Col, Input, Row} from "antd";
import i18next from "i18next";
class TransactionEditPage extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName,
transactionName: props.match.params.transactionName,
application: null,
transaction: null,
providers: [],
mode: props.location.mode !== undefined ? props.location.mode : "edit",
};
}
UNSAFE_componentWillMount() {
this.getTransaction();
}
getTransaction() {
TransactionBackend.getTransaction(this.state.organizationName, this.state.transactionName)
.then((res) => {
if (res.data === null) {
this.props.history.push("/404");
return;
}
this.setState({
transaction: res.data,
});
Setting.scrollToDiv("invoice-area");
});
}
submitTransactionEdit(exitAfterSave) {
const transaction = Setting.deepCopy(this.state.transaction);
TransactionBackend.updateTransaction(this.state.transaction.owner, this.state.transactionName, transaction)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
transactionName: this.state.transaction.name,
});
if (exitAfterSave) {
this.props.history.push("/transactions");
} else {
this.props.history.push(`/transactions/${this.state.organizationName}/${this.state.transaction.name}`);
}
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updatePaymentField("name", this.state.transactionName);
}
})
.catch(error => {
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteTransaction() {
TransactionBackend.deleteTransaction(this.state.transaction)
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/transactions");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
parseTransactionField(key, value) {
if ([""].includes(key)) {
value = Setting.myParseInt(value);
}
return value;
}
getApplication() {
ApplicationBackend.getApplication("admin", this.state.applicationName)
.then((res) => {
if (res.data === null) {
this.props.history.push("/404");
return;
}
if (res.status === "error") {
Setting.showMessage("error", res.msg);
return;
}
const application = res.data;
if (application.grantTypes === null || application.grantTypes === undefined || application.grantTypes.length === 0) {
application.grantTypes = ["authorization_code"];
}
if (application.tags === null || application.tags === undefined) {
application.tags = [];
}
this.setState({
application: application,
});
this.getCerts(application.organization);
this.getSamlMetadata(application.enableSamlPostBinding);
});
}
renderTransaction() {
return (
<Card size="small" title={
<div>
{this.state.mode === "add" ? i18next.t("transaction:New Transaction") : i18next.t("transaction:Edit Transaction")}&nbsp;&nbsp;&nbsp;&nbsp;
<Button onClick={() => this.submitTransactionEdit(false)}>{i18next.t("general:Save")}</Button>
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitTransactionEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteTransaction()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.owner} onChange={e => {
// this.updatePaymentField('organization', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.name} onChange={e => {
// this.updatePaymentField('name', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Display name"), i18next.t("general:Display name - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.displayName} onChange={e => {
this.updatePaymentField("displayName", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Provider"), i18next.t("general:Provider - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.provider} onChange={e => {
// this.updatePaymentField('provider', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Category"), i18next.t("provider:Category - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.category} onChange={e => {
this.updatePaymentField("displayName", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Type"), i18next.t("payment:Type - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.type} onChange={e => {
// this.updatePaymentField('type', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Product"), i18next.t("payment:Product - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.productName} onChange={e => {
// this.updatePaymentField('productName', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("product:Detail"), i18next.t("product:Detail - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.detail} onChange={e => {
// this.updatePaymentField('currency', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("user:Tag"), i18next.t("transaction:Tag - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.tag} onChange={e => {
// this.updatePaymentField('currency', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Currency"), i18next.t("payment:Currency - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.currency} onChange={e => {
// this.updatePaymentField('currency', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("transaction:Amount"), i18next.t("transaction:Amount - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.amount} onChange={e => {
// this.updatePaymentField('amount', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("product:Return URL"), i18next.t("product:Return URL - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.user} onChange={e => {
// this.updatePaymentField('amount', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:User"), i18next.t("general:User - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.user} onChange={e => {
// this.updatePaymentField('amount', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Application"), i18next.t("general:Application - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.application} onChange={e => {
// this.updatePaymentField('amount', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Payment"), i18next.t("general:Payment - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.payment} onChange={e => {
// this.updatePaymentField('amount', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:State"), i18next.t("general:State - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={true} value={this.state.transaction.state} onChange={e => {
// this.updatePaymentField('state', e.target.value);
}} />
</Col>
</Row>
</Card>
);
}
render() {
return (
<div>
{
this.state.transaction !== null ? this.renderTransaction() : null
}
<div style={{marginTop: "20px", marginLeft: "40px"}}>
<Button size="large" onClick={() => this.submitTransactionEdit(false)}>{i18next.t("general:Save")}</Button>
<Button style={{marginLeft: "20px"}} type="primary" size="large" onClick={() => this.submitTransactionEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} size="large" onClick={() => this.deleteTransaction()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
</div>
);
}
}
export default TransactionEditPage;

View File

@ -0,0 +1,333 @@
// Copyright 2024 The Casdoor 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 BaseListPage from "./BaseListPage";
import i18next from "i18next";
import {Link} from "react-router-dom";
import * as Setting from "./Setting";
import * as Provider from "./auth/Provider";
import {Button, Table} from "antd";
import PopconfirmModal from "./common/modal/PopconfirmModal";
import React from "react";
import * as TransactionBackend from "./backend/TransactionBackend";
import moment from "moment/moment";
class TransactionListPage extends BaseListPage {
newTransaction() {
const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return {
owner: organizationName,
name: `transaction_${randomName}`,
createdTime: moment().format(),
displayName: `New Transaction - ${randomName}`,
provider: "provider_pay_paypal",
category: "",
type: "PayPal",
productName: "computer-1",
productDisplayName: "A notebook computer",
detail: "This is a computer with excellent CPU, memory and disk",
tag: "Promotion-1",
currency: "USD",
amount: 0,
returnUrl: "https://door.casdoor.com/transactions",
user: "admin",
application: "",
payment: "payment_bhn1ra",
state: "Paid",
};
}
deleteTransaction(i) {
TransactionBackend.deleteTransaction(this.state.data[i])
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
addTransaction() {
const newTransaction = this.newTransaction();
TransactionBackend.addTransaction(newTransaction)
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/transactions/${newTransaction.owner}/${newTransaction.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
}
)
.catch(error => {
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
renderTable(transactions) {
const columns = [
{
title: i18next.t("general:Name"),
dataIndex: "name",
key: "name",
width: "180px",
fixed: "left",
sorter: true,
...this.getColumnSearchProps("name"),
render: (text, record, index) => {
return (
<Link to={`/transactions/${record.owner}/${text}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("general:Organization"),
dataIndex: "owner",
key: "owner",
width: "120px",
fixed: "left",
sorter: true,
...this.getColumnSearchProps("owner"),
render: (text, record, index) => {
return (
<Link to={`/organizations/${text}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("general:Provider"),
dataIndex: "provider",
key: "provider",
width: "150px",
sorter: true,
...this.getColumnSearchProps("provider"),
render: (text, record, index) => {
return (
<Link to={`/providers/${record.owner}/${text}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("general:User"),
dataIndex: "user",
key: "user",
width: "120px",
sorter: true,
...this.getColumnSearchProps("user"),
render: (text, record, index) => {
return (
<Link to={`/users/${record.owner}/${text}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("general:Created time"),
dataIndex: "createdTime",
key: "createdTime",
width: "160px",
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
},
},
{
title: i18next.t("provider:Type"),
dataIndex: "type",
key: "type",
width: "140px",
align: "center",
filterMultiple: false,
filters: Setting.getProviderTypeOptions("Payment").map((o) => {return {text: o.id, value: o.name};}),
sorter: true,
render: (text, record, index) => {
record.category = "Payment";
return Provider.getProviderLogoWidget(record);
},
},
{
title: i18next.t("payment:Product"),
dataIndex: "productDisplayName",
key: "productDisplayName",
// width: '160px',
sorter: true,
...this.getColumnSearchProps("productDisplayName"),
render: (text, record, index) => {
return (
<Link to={`/products/${record.owner}/${record.productName}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("payment:Currency"),
dataIndex: "currency",
key: "currency",
width: "120px",
sorter: true,
...this.getColumnSearchProps("currency"),
},
{
title: i18next.t("transaction:Amount"),
dataIndex: "amount",
key: "amount",
width: "120px",
sorter: true,
...this.getColumnSearchProps("amount"),
},
{
title: i18next.t("general:User"),
dataIndex: "user",
key: "user",
width: "120px",
sorter: true,
...this.getColumnSearchProps("user"),
},
{
title: i18next.t("general:Application"),
dataIndex: "application",
key: "application",
width: "120px",
sorter: true,
...this.getColumnSearchProps("application"),
render: (text, record, index) => {
return (
<Link to={`/applications/${record.owner}/${record.application}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("general:Payment"),
dataIndex: "payment",
key: "payment",
width: "120px",
sorter: true,
...this.getColumnSearchProps("payment"),
render: (text, record, index) => {
return (
<Link to={`/payments/${record.owner}/${record.payment}`}>
{text}
</Link>
);
},
},
{
title: i18next.t("general:State"),
dataIndex: "state",
key: "state",
width: "120px",
sorter: true,
...this.getColumnSearchProps("state"),
},
{
title: i18next.t("general:Action"),
dataIndex: "",
key: "op",
width: "240px",
fixed: (Setting.isMobile()) ? "false" : "right",
render: (text, record, index) => {
return (
<div>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/transactions/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
<PopconfirmModal
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
onConfirm={() => this.deleteTransaction(index)}
>
</PopconfirmModal>
</div>
);
},
},
];
const paginationProps = {
total: this.state.pagination.total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
};
return (
<div>
<Table scroll={{x: "max-content"}} columns={columns} dataSource={transactions} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Transactions")}&nbsp;&nbsp;&nbsp;&nbsp;
<Button type="primary" size="small" onClick={this.addTransaction.bind(this)}>{i18next.t("general:Add")}</Button>
</div>
)}
loading={this.state.loading}
onChange={this.handleTableChange}
/>
</div>
);
}
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
const sortField = params.sortField, sortOrder = params.sortOrder;
if (params.type !== undefined && params.type !== null) {
field = "type";
value = params.type;
}
this.setState({loading: true});
TransactionBackend.getTransactions(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => {
this.setState({
loading: false,
});
if (res.status === "ok") {
this.setState({
data: res.data,
pagination: {
...params.pagination,
total: res.data2,
},
searchText: params.searchText,
searchedColumn: params.searchedColumn,
});
} else {
if (Setting.isResponseDenied(res)) {
this.setState({
isAuthorized: false,
});
} else {
Setting.showMessage("error", res.msg);
}
}
});
};
}
export default TransactionListPage;

View File

@ -0,0 +1,71 @@
// Copyright 2024 The Casdoor 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 * as Setting from "../Setting";
export function getTransactions(owner, page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") {
return fetch(`${Setting.ServerUrl}/api/get-transactions?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
method: "GET",
credentials: "include",
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},
}).then(res => res.json());
}
export function getTransaction(owner, name) {
return fetch(`${Setting.ServerUrl}/api/get-transaction?id=${owner}/${encodeURIComponent(name)}`, {
method: "GET",
credentials: "include",
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},
}).then(res => res.json());
}
export function updateTransaction(owner, name, transaction) {
const newTransaction = Setting.deepCopy(transaction);
return fetch(`${Setting.ServerUrl}/api/update-transaction?id=${owner}/${encodeURIComponent(name)}`, {
method: "POST",
credentials: "include",
body: JSON.stringify(newTransaction),
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},
}).then(res => res.json());
}
export function addTransaction(transaction) {
const newTransaction = Setting.deepCopy(transaction);
return fetch(`${Setting.ServerUrl}/api/add-transaction`, {
method: "POST",
credentials: "include",
body: JSON.stringify(newTransaction),
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},
}).then(res => res.json());
}
export function deleteTransaction(transaction) {
const newTransaction = Setting.deepCopy(transaction);
return fetch(`${Setting.ServerUrl}/api/delete-transaction`, {
method: "POST",
credentials: "include",
body: JSON.stringify(newTransaction),
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},
}).then(res => res.json());
}

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Dies ist eine schreibgeschützte Demo-Seite!", "This is a read-only demo site!": "Dies ist eine schreibgeschützte Demo-Seite!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Token", "Tokens": "Token",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token-Typ", "Token type": "Token-Typ",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Drittanbieter-Logins", "3rd-party logins": "Drittanbieter-Logins",
"3rd-party logins - Tooltip": "Drittanbieter-Anmeldungen, die mit dem Benutzer verknüpft sind", "3rd-party logins - Tooltip": "Drittanbieter-Anmeldungen, die mit dem Benutzer verknüpft sind",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "¡Este es un sitio de demostración solo de lectura!", "This is a read-only demo site!": "¡Este es un sitio de demostración solo de lectura!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "Dirección URL", "URL": "Dirección URL",
@ -1031,6 +1032,13 @@
"Token type": "Tipo de token", "Token type": "Tipo de token",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Inicio de sesión de terceros", "3rd-party logins": "Inicio de sesión de terceros",
"3rd-party logins - Tooltip": "Accesos sociales ligados por el usuario", "3rd-party logins - Tooltip": "Accesos sociales ligados por el usuario",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Ceci est un site de démonstration en lecture seule !", "This is a read-only demo site!": "Ceci est un site de démonstration en lecture seule !",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Jetons", "Tokens": "Jetons",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Infobulle", "Type - Tooltip": "Type - Infobulle",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Type de jeton", "Token type": "Type de jeton",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Services de connexions tiers", "3rd-party logins": "Services de connexions tiers",
"3rd-party logins - Tooltip": "Service de connexions tiers liés au compte", "3rd-party logins - Tooltip": "Service de connexions tiers liés au compte",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Ini adalah situs demo hanya untuk dibaca saja!", "This is a read-only demo site!": "Ini adalah situs demo hanya untuk dibaca saja!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Token-token", "Tokens": "Token-token",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Jenis token", "Token type": "Jenis token",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Masuk pihak ketiga", "3rd-party logins": "Masuk pihak ketiga",
"3rd-party logins - Tooltip": "Masuk sosial yang terhubung oleh pengguna", "3rd-party logins - Tooltip": "Masuk sosial yang terhubung oleh pengguna",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "これは読み取り専用のデモサイトです!", "This is a read-only demo site!": "これは読み取り専用のデモサイトです!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "トークン", "Tokens": "トークン",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "トークンタイプ", "Token type": "トークンタイプ",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "サードパーティログイン", "3rd-party logins": "サードパーティログイン",
"3rd-party logins - Tooltip": "ユーザーによってリンクされたソーシャルログイン", "3rd-party logins - Tooltip": "ユーザーによってリンクされたソーシャルログイン",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "이것은 읽기 전용 데모 사이트입니다!", "This is a read-only demo site!": "이것은 읽기 전용 데모 사이트입니다!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "토큰", "Tokens": "토큰",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "토큰 유형", "Token type": "토큰 유형",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "제3자 로그인", "3rd-party logins": "제3자 로그인",
"3rd-party logins - Tooltip": "사용자가 연결한 소셜 로그인", "3rd-party logins - Tooltip": "사용자가 연결한 소셜 로그인",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Este é um site de demonstração apenas para leitura!", "This is a read-only demo site!": "Este é um site de demonstração apenas para leitura!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Tipo", "Type": "Tipo",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Tipo de Token", "Token type": "Tipo de Token",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Logins de terceiros", "3rd-party logins": "Logins de terceiros",
"3rd-party logins - Tooltip": "Logins sociais vinculados pelo usuário", "3rd-party logins - Tooltip": "Logins sociais vinculados pelo usuário",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Это демонстрационный сайт только для чтения!", "This is a read-only demo site!": "Это демонстрационный сайт только для чтения!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Токены", "Tokens": "Токены",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Тип токена", "Token type": "Тип токена",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Авторизация сторонних участников", "3rd-party logins": "Авторизация сторонних участников",
"3rd-party logins - Tooltip": "Социальные логины, связанные пользователем", "3rd-party logins - Tooltip": "Социальные логины, связанные пользователем",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Bu site sadece görüntüleme amaçlıdır!", "This is a read-only demo site!": "Bu site sadece görüntüleme amaçlıdır!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "This is a read-only demo site!", "This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Tokens", "Tokens": "Tokens",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Token type", "Token type": "Token type",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "3rd-party logins", "3rd-party logins": "3rd-party logins",
"3rd-party logins - Tooltip": "Social logins linked by the user", "3rd-party logins - Tooltip": "Social logins linked by the user",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "Đây là trang web giới thiệu chỉ có chức năng đọc!", "This is a read-only demo site!": "Đây là trang web giới thiệu chỉ có chức năng đọc!",
"Timestamp": "Timestamp", "Timestamp": "Timestamp",
"Tokens": "Mã thông báo", "Tokens": "Mã thông báo",
"Transactions": "Transactions",
"Type": "Type", "Type": "Type",
"Type - Tooltip": "Type - Tooltip", "Type - Tooltip": "Type - Tooltip",
"URL": "URL", "URL": "URL",
@ -1031,6 +1032,13 @@
"Token type": "Loại mã thông báo", "Token type": "Loại mã thông báo",
"Token type - Tooltip": "Token type - Tooltip" "Token type - Tooltip": "Token type - Tooltip"
}, },
"transaction": {
"Amount": "Amount",
"Amount - Tooltip": "The amount of traded products",
"Edit Transaction": "Edit Transaction",
"New Transaction": "New Transaction",
"Tag - Tooltip": "The tag of the transaction"
},
"user": { "user": {
"3rd-party logins": "Đăng nhập bên thứ ba", "3rd-party logins": "Đăng nhập bên thứ ba",
"3rd-party logins - Tooltip": "Đăng nhập xã hội liên kết bởi người dùng", "3rd-party logins - Tooltip": "Đăng nhập xã hội liên kết bởi người dùng",

View File

@ -367,6 +367,7 @@
"This is a read-only demo site!": "这是一个只读演示站点!", "This is a read-only demo site!": "这是一个只读演示站点!",
"Timestamp": "时间", "Timestamp": "时间",
"Tokens": "令牌", "Tokens": "令牌",
"Transactions": "交易",
"Type": "类型", "Type": "类型",
"Type - Tooltip": "类型", "Type - Tooltip": "类型",
"URL": "链接", "URL": "链接",
@ -1031,6 +1032,13 @@
"Token type": "令牌类型", "Token type": "令牌类型",
"Token type - Tooltip": "令牌类型" "Token type - Tooltip": "令牌类型"
}, },
"transaction": {
"Amount": "数量",
"Amount - Tooltip": "交易产品的数量",
"Edit Transaction": "编辑交易",
"New Transaction": "添加交易",
"Tag - Tooltip": "交易的标签"
},
"user": { "user": {
"3rd-party logins": "第三方登录", "3rd-party logins": "第三方登录",
"3rd-party logins - Tooltip": "用户所绑定的社会化登录", "3rd-party logins - Tooltip": "用户所绑定的社会化登录",