diff --git a/controllers/store.go b/controllers/store.go
index fa51e08..233a4ba 100644
--- a/controllers/store.go
+++ b/controllers/store.go
@@ -45,7 +45,13 @@ func (c *ApiController) GetStores() {
func (c *ApiController) GetStore() {
id := c.Input().Get("id")
- store, err := object.GetStore(id)
+ var store *object.Store
+ var err error
+ if id == "admin/_casibase_default_store_" {
+ store, err = object.GetDefaultStore("admin")
+ } else {
+ store, err = object.GetStore(id)
+ }
if err != nil {
c.ResponseError(err.Error())
return
@@ -57,7 +63,8 @@ func (c *ApiController) GetStore() {
err = store.Populate()
if err != nil {
- c.ResponseError(err.Error())
+ // gentle error
+ c.ResponseOk(store, err.Error())
return
}
diff --git a/object/store.go b/object/store.go
index 0a52a23..8297afe 100644
--- a/object/store.go
+++ b/object/store.go
@@ -70,7 +70,7 @@ func GetStores(owner string) ([]*Store, error) {
return stores, nil
}
-func getCurrentStore(owner string) (*Store, error) {
+func GetDefaultStore(owner string) (*Store, error) {
stores, err := GetStores(owner)
if err != nil {
return nil, err
@@ -81,6 +81,11 @@ func getCurrentStore(owner string) (*Store, error) {
return store, nil
}
}
+
+ if len(stores) > 0 {
+ return stores[0], nil
+ }
+
return nil, nil
}
diff --git a/object/video.go b/object/video.go
index a89074c..41d2488 100644
--- a/object/video.go
+++ b/object/video.go
@@ -129,7 +129,7 @@ func (video *Video) GetId() string {
}
func (video *Video) Populate() error {
- store, err := getCurrentStore("admin")
+ store, err := GetDefaultStore("admin")
if err != nil {
return err
}
diff --git a/web/src/App.js b/web/src/App.js
index 3c08c82..a0a8b9b 100644
--- a/web/src/App.js
+++ b/web/src/App.js
@@ -84,8 +84,8 @@ class App extends Component {
this.setState({
uri: uri,
});
- if (uri === "/home") {
- this.setState({selectedMenuKey: "/home"});
+ if (uri === "/" || uri === "/home") {
+ this.setState({selectedMenuKey: "/"});
} else if (uri.includes("/stores")) {
this.setState({selectedMenuKey: "/stores"});
} else if (uri.includes("/clustering")) {
diff --git a/web/src/FileTree.js b/web/src/FileTree.js
index 57a9963..779ae46 100644
--- a/web/src/FileTree.js
+++ b/web/src/FileTree.js
@@ -13,7 +13,8 @@
// limitations under the License.
import React from "react";
-import {Button, Card, Col, DatePicker, Descriptions, Empty, Input, Modal, Popconfirm, Radio, Row, Select, Spin, Tooltip, Tree, Upload} from "antd";
+import {withRouter} from "react-router-dom";
+import {Button, Card, Col, DatePicker, Descriptions, Empty, Input, Modal, Popconfirm, Radio, Result, Row, Select, Spin, Tooltip, Tree, Upload} from "antd";
import {CloudUploadOutlined, DeleteOutlined, DownloadOutlined, FileDoneOutlined, FolderAddOutlined, InfoCircleTwoTone, createFromIconfontCN} from "@ant-design/icons";
import moment from "moment";
import * as Setting from "./Setting";
@@ -847,29 +848,49 @@ class FileTree extends React.Component {
}
render() {
+ if (this.props.store.fileTree === null) {
+ return (
+
+ this.props.history.push(`/stores/${this.props.store.owner}/${this.props.store.name}`)}>
+ Go to Store
+
+ }
+ />
+
+ );
+ }
+
return (
-
+
-
- {
- this.renderSearch(this.props.store)
- }
- {
- this.renderTree(this.props.store)
- }
+
+
+ {
+ this.renderSearch(this.props.store)
+ }
+ {
+ this.renderTree(this.props.store)
+ }
+
-
+
+
+ {
+ this.renderFileViewer(this.props.store)
+ }
+
{
- this.renderFileViewer(this.props.store)
+ this.renderProperties()
}
- {
- this.renderProperties()
- }
@@ -881,4 +902,4 @@ class FileTree extends React.Component {
}
}
-export default FileTree;
+export default withRouter(FileTree);
diff --git a/web/src/FileTreePage.js b/web/src/FileTreePage.js
index c3c2fea..152dd32 100644
--- a/web/src/FileTreePage.js
+++ b/web/src/FileTreePage.js
@@ -36,13 +36,17 @@ class FileTreePage extends React.Component {
getStore() {
StoreBackend.getStore(this.state.owner, this.state.storeName)
- .then((res) => {
- if (res?.status !== "error") {
+ .then((store) => {
+ if (store.status === "ok") {
+ if (store.data2 !== null && store.data?.includes("error")) {
+ store.data.error = store.data2;
+ }
+
this.setState({
- store: res.data,
+ store: store.data,
});
} else {
- Setting.showMessage("error", res.msg);
+ Setting.showMessage("error", `Failed to get store: ${store.msg}`);
}
});
}
diff --git a/web/src/HomePage.js b/web/src/HomePage.js
index 48b5982..809e829 100644
--- a/web/src/HomePage.js
+++ b/web/src/HomePage.js
@@ -1,17 +1,17 @@
-// Copyright 2023 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.
-
+// Copyright 2023 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 FileTreePage from "./FileTreePage";
import {Redirect} from "react-router-dom";
@@ -28,22 +28,22 @@ class HomePage extends React.Component {
}
UNSAFE_componentWillMount() {
- this.getStores();
+ this.getStore();
}
- getStores() {
- StoreBackend.getGlobalStores()
- .then((res) => {
- if (res.status === "ok") {
- const stores = res.data;
- const store = stores.filter(store => store.domain !== "https://cdn.example.com")[0];
- if (store !== undefined) {
- this.setState({
- store: store,
- });
+ getStore() {
+ StoreBackend.getStore("admin", "_casibase_default_store_")
+ .then((store) => {
+ if (store.status === "ok") {
+ if (store.data2 !== null && store.data2.includes("error")) {
+ store.data.error = store.data2;
}
+
+ this.setState({
+ store: store.data,
+ });
} else {
- Setting.showMessage("error", `Failed to get stores: ${res.msg}`);
+ Setting.showMessage("error", `Failed to get store: ${store.msg}`);
}
});
}
diff --git a/web/src/StoreEditPage.js b/web/src/StoreEditPage.js
index 2616b3d..adc6d39 100644
--- a/web/src/StoreEditPage.js
+++ b/web/src/StoreEditPage.js
@@ -39,6 +39,10 @@ class StoreEditPage extends React.Component {
StoreBackend.getStore(this.state.owner, this.state.storeName)
.then((store) => {
if (store.status === "ok") {
+ if (store.data2 !== null && store.data2.includes("error")) {
+ store.data.error = store.data2;
+ }
+
this.setState({
store: store.data,
});
diff --git a/web/src/StoreListPage.js b/web/src/StoreListPage.js
index 402e4a9..20fac9b 100644
--- a/web/src/StoreListPage.js
+++ b/web/src/StoreListPage.js
@@ -114,14 +114,14 @@ class StoreListPage extends React.Component {
title: i18next.t("general:Display name"),
dataIndex: "displayName",
key: "displayName",
- width: "600px",
+ // width: "600px",
sorter: (a, b) => a.displayName.localeCompare(b.displayName),
},
{
title: i18next.t("general:Action"),
dataIndex: "action",
key: "action",
- width: "240px",
+ width: "300px",
render: (text, record, index) => {
return (