From 46209eb83fa7160bd7ce1ee5a0868b8ff2f321df Mon Sep 17 00:00:00 2001 From: Yang Luo Date: Sat, 22 Jul 2023 22:11:56 +0800 Subject: [PATCH] Improve default store logic --- controllers/store.go | 11 +++++++-- object/store.go | 7 +++++- object/video.go | 2 +- web/src/App.js | 4 ++-- web/src/FileTree.js | 51 +++++++++++++++++++++++++++------------ web/src/FileTreePage.js | 12 ++++++---- web/src/HomePage.js | 52 ++++++++++++++++++++-------------------- web/src/StoreEditPage.js | 4 ++++ web/src/StoreListPage.js | 4 ++-- 9 files changed, 94 insertions(+), 53 deletions(-) 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 (