Improve app subscription functionality

Further integrate app management component with device mgt
feature/appm-store/pbac
Jayasanka Weerasinghe 6 years ago committed by Dharmakeerthi Lasantha
parent 157641498b
commit e0f2d1e16a

@ -16,6 +16,7 @@
"d3": "^5.9.2", "d3": "^5.9.2",
"dagre": "^0.8.4", "dagre": "^0.8.4",
"keymirror": "^0.1.1", "keymirror": "^0.1.1",
"rc-tween-one": "^2.4.1",
"react": "^16.8.4", "react": "^16.8.4",
"react-d3-graph": "^2.0.2", "react-d3-graph": "^2.0.2",
"react-dom": "^16.8.4", "react-dom": "^16.8.4",

@ -0,0 +1,407 @@
import React from "react";
import {Card, Tag, message, Icon, Input, notification, Divider, Button, Spin, Tooltip, Popconfirm, Modal} from "antd";
import axios from "axios";
import config from "../../../../public/conf/config.json";
import {TweenOneGroup} from 'rc-tween-one';
class ManageCategories extends React.Component {
state = {
loading: false,
searchText: '',
categories: [],
tempElements: [],
inputVisible: false,
inputValue: '',
isAddNewVisible: false,
isEditModalVisible: false,
currentlyEditingId: null,
editingValue: null
};
componentDidMount() {
const request = "method=get&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications/categories";
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
let categories = JSON.parse(res.data.data);
this.setState({
categories: categories,
loading: false
});
}
}).catch((error) => {
if (error.response.status === 401) {
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false
});
});
}
handleCloseButton = () => {
this.setState({
tempElements: [],
isAddNewVisible: false
});
};
deleteCategory = (id) => {
this.setState({
loading: true
});
const request = "method=delete&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/admin/applications/categories/" + id;
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
notification["success"]({
message: "Done!",
description:
"Category Removed Successfully!",
});
this.setState({
loading: false
});
// this.setState({
// categories: [...categories, ...tempElements],
// tempElements: [],
// inputVisible: false,
// inputValue: '',
// loading: false,
// isAddNewVisible: false
// });
}
}).catch((error) => {
if (error.response.hasOwnProperty("status") && error.response.status === 401) {
message.error('You are not logged in');
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false
});
});
};
renderElement = (category) => {
const categoryName = category.categoryName;
const tagElem = (
<Tag
color="blue"
>
{categoryName}
<Divider type="vertical"/>
<Tooltip title="edit">
<Icon onClick={() => {
this.openEditModal(categoryName)
}} style={{color: 'rgba(0,0,0,0.45)'}} type="edit"/>
</Tooltip>
<Divider type="vertical"/>
<Tooltip title="delete">
<Popconfirm
title="Are you sure delete this category?"
onConfirm={() => {
if (category.isCategoryDeletable) {
this.deleteCategory(categoryName);
} else {
notification["error"]({
message: 'Cannot delete "' + categoryName + '"',
description:
"This category is currently used. Please unassign the category from apps.",
});
}
}}
okText="Yes"
cancelText="No"
>
<Icon style={{color: 'rgba(0,0,0,0.45)'}} type="delete"/>
</Popconfirm>
</Tooltip>
</Tag>
);
return (
<span key={category.categoryName} style={{display: 'inline-block'}}>
{tagElem}
</span>
);
};
renderTempElement = (category) => {
const {tempElements} = this.state;
const tagElem = (
<Tag
closable
onClose={e => {
e.preventDefault();
const remainingElements = tempElements.filter(function (value) {
return value.categoryName !== category.categoryName;
});
this.setState({
tempElements: remainingElements
});
}}
>
{category.categoryName}
</Tag>
);
return (
<span key={category.categoryName} style={{display: 'inline-block'}}>
{tagElem}
</span>
);
};
showInput = () => {
this.setState({inputVisible: true}, () => this.input.focus());
};
handleInputChange = e => {
this.setState({inputValue: e.target.value});
};
handleInputConfirm = () => {
const {inputValue, categories} = this.state;
let {tempElements} = this.state;
if (inputValue) {
if ((categories.findIndex(i => i.categoryName === inputValue) === -1) && (tempElements.findIndex(i => i.categoryName === inputValue) === -1)) {
tempElements = [...tempElements, {categoryName: inputValue, isCategoryDeletable: true}];
} else {
message.warning('Category already exists');
}
}
this.setState({
tempElements,
inputVisible: false,
inputValue: '',
});
};
handleSave = () => {
const {tempElements, categories} = this.state;
this.setState({
loading: true
});
const dataArray = JSON.stringify(tempElements.map(category => category.categoryName));
const request = "method=post&content-type=application/json&payload=" + dataArray + "&api-endpoint=/application-mgt-publisher/v1.0/admin/applications/categories";
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
notification["success"]({
message: "Done!",
description:
"New Categories were added successfully",
});
this.setState({
categories: [...categories, ...tempElements],
tempElements: [],
inputVisible: false,
inputValue: '',
loading: false,
isAddNewVisible: false
});
}
}).catch((error) => {
if (error.response.hasOwnProperty("status") && error.response.status === 401) {
message.error('You are not logged in');
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false
});
});
};
saveInputRef = input => (this.input = input);
closeEditModal = e => {
console.log(e);
this.setState({
isEditModalVisible: false,
currentlyEditingId: null
});
};
openEditModal = (id) => {
this.setState({
isEditModalVisible: true,
currentlyEditingId: id,
editingValue: id
})
};
editItem = () => {
const {editingValue, currentlyEditingId, categories} = this.state;
this.setState({
loading: true,
isEditModalVisible: false,
});
const request = "method=put&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/admin/applications/categories?from="+currentlyEditingId+"%26to="+editingValue;
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
notification["success"]({
message: "Done!",
description:
"Category was edited successfully",
});
categories[categories.findIndex(i => i.categoryName === currentlyEditingId)].categoryName = editingValue;
this.setState({
categories: categories,
loading: false,
editingValue: null
});
}
}).catch((error) => {
if (error.response.hasOwnProperty("status") && error.response.status === 401) {
message.error('You are not logged in');
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false,
editingValue: null
});
});
};
handleEditInputChange = (e) => {
this.setState({
editingValue: e.target.value
});
};
render() {
const {categories, inputVisible, inputValue, tempElements, isAddNewVisible} = this.state;
const categoriesElements = categories.map(this.renderElement);
const temporaryElements = tempElements.map(this.renderTempElement);
return (
<div>
<Card title="Categories">
<Spin tip="Working on it..." spinning={this.state.loading}>
{!isAddNewVisible &&
<Button
size="small"
onClick={() => {
this.setState({
isAddNewVisible: true,
inputVisible: true
}, () => this.input.focus())
}} htmlType="button">Add Categories
</Button>
}
{isAddNewVisible &&
<div>
<div style={{marginBottom: 16}}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: 'from',
duration: 100,
onComplete: e => {
e.target.style = '';
},
}}
leave={{opacity: 0, width: 0, scale: 0, duration: 200}}
appear={false}
>
{temporaryElements}
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{width: 120}}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag onClick={this.showInput}
style={{background: '#fff', borderStyle: 'dashed'}}>
<Icon type="plus"/> New Category
</Tag>
)}
</TweenOneGroup>
</div>
<div>
<Button
onClick={this.handleSave}
htmlType="button" type="primary"
size="small"
disabled={tempElements.length === 0}>
Save
</Button>
<Divider type="vertical"/>
<Button
onClick={this.handleCloseButton}
size="small">
Cancel
</Button>
</div>
</div>
}
<Divider dashed="true"/>
<div style={{marginTop: 16}}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: 'from',
duration: 100,
onComplete: e => {
e.target.style = '';
},
}}
leave={{opacity: 0, width: 0, scale: 0, duration: 200}}
appear={false}
>
{categoriesElements}
</TweenOneGroup>
</div>
</Spin>
</Card>
<Modal
title="Edit"
visible={this.state.isEditModalVisible}
onCancel={this.closeEditModal}
onOk={this.editItem}
>
<Input value={this.state.editingValue} ref={(input) => this.editingInput = input} onChange={this.handleEditInputChange}/>
</Modal>
</div>
);
}
}
export default ManageCategories;

@ -0,0 +1,407 @@
import React from "react";
import {Card, Tag, message, Icon, Input, notification, Divider, Button, Spin, Tooltip, Popconfirm, Modal} from "antd";
import axios from "axios";
import config from "../../../../public/conf/config.json";
import {TweenOneGroup} from 'rc-tween-one';
class ManageTags extends React.Component {
state = {
loading: false,
searchText: '',
categories: [],
tempElements: [],
inputVisible: false,
inputValue: '',
isAddNewVisible: false,
isEditModalVisible: false,
currentlyEditingId: null,
editingValue: null
};
componentDidMount() {
const request = "method=get&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications/tags";
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
let categories = JSON.parse(res.data.data);
this.setState({
categories: categories,
loading: false
});
}
}).catch((error) => {
if (error.response.status === 401) {
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false
});
});
}
handleCloseButton = () => {
this.setState({
tempElements: [],
isAddNewVisible: false
});
};
deleteCategory = (id) => {
this.setState({
loading: true
});
const request = "method=delete&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/admin/applications/categories/" + id;
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
notification["success"]({
message: "Done!",
description:
"Category Removed Successfully!",
});
this.setState({
loading: false
});
// this.setState({
// categories: [...categories, ...tempElements],
// tempElements: [],
// inputVisible: false,
// inputValue: '',
// loading: false,
// isAddNewVisible: false
// });
}
}).catch((error) => {
if (error.response.hasOwnProperty("status") && error.response.status === 401) {
message.error('You are not logged in');
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false
});
});
};
renderElement = (category) => {
const categoryName = category.tagName;
const tagElem = (
<Tag
color="gold"
>
{categoryName}
<Divider type="vertical"/>
<Tooltip title="edit">
<Icon onClick={() => {
this.openEditModal(categoryName)
}} style={{color: 'rgba(0,0,0,0.45)'}} type="edit"/>
</Tooltip>
<Divider type="vertical"/>
<Tooltip title="delete">
<Popconfirm
title="Are you sure delete this category?"
onConfirm={() => {
if (category.isTagDeletable) {
this.deleteCategory(categoryName);
} else {
notification["error"]({
message: 'Cannot delete "' + categoryName + '"',
description:
"This category is currently used. Please unassign the category from apps.",
});
}
}}
okText="Yes"
cancelText="No"
>
<Icon style={{color: 'rgba(0,0,0,0.45)'}} type="delete"/>
</Popconfirm>
</Tooltip>
</Tag>
);
return (
<span key={category.tagName} style={{display: 'inline-block'}}>
{tagElem}
</span>
);
};
renderTempElement = (category) => {
const {tempElements} = this.state;
const tagElem = (
<Tag
closable
onClose={e => {
e.preventDefault();
const remainingElements = tempElements.filter(function (value) {
return value.categoryName !== category.categoryName;
});
this.setState({
tempElements: remainingElements
});
}}
>
{category.categoryName}
</Tag>
);
return (
<span key={category.categoryName} style={{display: 'inline-block'}}>
{tagElem}
</span>
);
};
showInput = () => {
this.setState({inputVisible: true}, () => this.input.focus());
};
handleInputChange = e => {
this.setState({inputValue: e.target.value});
};
handleInputConfirm = () => {
const {inputValue, categories} = this.state;
let {tempElements} = this.state;
if (inputValue) {
if ((categories.findIndex(i => i.categoryName === inputValue) === -1) && (tempElements.findIndex(i => i.categoryName === inputValue) === -1)) {
tempElements = [...tempElements, {categoryName: inputValue, isTagDeletable: true}];
} else {
message.warning('Category already exists');
}
}
this.setState({
tempElements,
inputVisible: false,
inputValue: '',
});
};
handleSave = () => {
const {tempElements, categories} = this.state;
this.setState({
loading: true
});
const dataArray = JSON.stringify(tempElements.map(category => category.categoryName));
const request = "method=post&content-type=application/json&payload=" + dataArray + "&api-endpoint=/application-mgt-publisher/v1.0/admin/applications/categories";
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
notification["success"]({
message: "Done!",
description:
"New Categories were added successfully",
});
this.setState({
categories: [...categories, ...tempElements],
tempElements: [],
inputVisible: false,
inputValue: '',
loading: false,
isAddNewVisible: false
});
}
}).catch((error) => {
if (error.response.hasOwnProperty("status") && error.response.status === 401) {
message.error('You are not logged in');
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false
});
});
};
saveInputRef = input => (this.input = input);
closeEditModal = e => {
console.log(e);
this.setState({
isEditModalVisible: false,
currentlyEditingId: null
});
};
openEditModal = (id) => {
this.setState({
isEditModalVisible: true,
currentlyEditingId: id,
editingValue: id
})
};
editItem = () => {
const {editingValue, currentlyEditingId, categories} = this.state;
this.setState({
loading: true,
isEditModalVisible: false,
});
const request = "method=put&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/admin/applications/categories?from="+currentlyEditingId+"%26to="+editingValue;
axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
notification["success"]({
message: "Done!",
description:
"Category was edited successfully",
});
categories[categories.findIndex(i => i.categoryName === currentlyEditingId)].categoryName = editingValue;
this.setState({
categories: categories,
loading: false,
editingValue: null
});
}
}).catch((error) => {
if (error.response.hasOwnProperty("status") && error.response.status === 401) {
message.error('You are not logged in');
window.location.href = 'https://localhost:9443/publisher/login';
} else {
message.warning('Something went wrong');
}
this.setState({
loading: false,
editingValue: null
});
});
};
handleEditInputChange = (e) => {
this.setState({
editingValue: e.target.value
});
};
render() {
const {categories, inputVisible, inputValue, tempElements, isAddNewVisible} = this.state;
const categoriesElements = categories.map(this.renderElement);
const temporaryElements = tempElements.map(this.renderTempElement);
return (
<div>
<Card title="Tags">
<Spin tip="Working on it..." spinning={this.state.loading}>
{!isAddNewVisible &&
<Button
size="small"
onClick={() => {
this.setState({
isAddNewVisible: true,
inputVisible: true
}, () => this.input.focus())
}} htmlType="button">Add Tags
</Button>
}
{isAddNewVisible &&
<div>
<div style={{marginBottom: 16}}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: 'from',
duration: 100,
onComplete: e => {
e.target.style = '';
},
}}
leave={{opacity: 0, width: 0, scale: 0, duration: 200}}
appear={false}
>
{temporaryElements}
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{width: 120}}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag onClick={this.showInput}
style={{background: '#fff', borderStyle: 'dashed'}}>
<Icon type="plus"/> New Category
</Tag>
)}
</TweenOneGroup>
</div>
<div>
<Button
onClick={this.handleSave}
htmlType="button" type="primary"
size="small"
disabled={tempElements.length === 0}>
Save
</Button>
<Divider type="vertical"/>
<Button
onClick={this.handleCloseButton}
size="small">
Cancel
</Button>
</div>
</div>
}
<Divider dashed="true"/>
<div style={{marginTop: 16}}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: 'from',
duration: 100,
onComplete: e => {
e.target.style = '';
},
}}
leave={{opacity: 0, width: 0, scale: 0, duration: 200}}
appear={false}
>
{categoriesElements}
</TweenOneGroup>
</div>
</Spin>
</Card>
<Modal
title="Edit"
visible={this.state.isEditModalVisible}
onCancel={this.closeEditModal}
onOk={this.editItem}
>
<Input value={this.state.editingValue} ref={(input) => this.editingInput = input} onChange={this.handleEditInputChange}/>
</Modal>
</div>
);
}
}
export default ManageTags;

@ -7,6 +7,7 @@ import Dashboard from "./pages/dashboard/Dashboard";
import Apps from "./pages/dashboard/apps/Apps"; import Apps from "./pages/dashboard/apps/Apps";
import Release from "./pages/dashboard/apps/release/Release"; import Release from "./pages/dashboard/apps/release/Release";
import AddNewApp from "./pages/dashboard/add-new-app/AddNewApp"; import AddNewApp from "./pages/dashboard/add-new-app/AddNewApp";
import Mange from "./pages/dashboard/manage/Manage";
import './index.css'; import './index.css';
import store from "./js/store/index"; import store from "./js/store/index";
import {Provider} from "react-redux"; import {Provider} from "react-redux";
@ -39,6 +40,17 @@ const routes = [
component: Release component: Release
} }
] ]
},{
path: '/publisher/manage',
exact: false,
component: Dashboard,
routes: [
{
path: '/publisher/manage',
component: Mange,
exact: true
}
]
} }
]; ];

@ -32,10 +32,10 @@ class Dashboard extends React.Component {
style={{lineHeight: '64px'}} style={{lineHeight: '64px'}}
> >
<Menu.Item key="1"><Link to="/publisher/apps"><Icon type="appstore"/>Apps</Link></Menu.Item> <Menu.Item key="1"><Link to="/publisher/apps"><Icon type="appstore"/>Apps</Link></Menu.Item>
<Menu.Item key="2"><Link to="/publisher/apps"><Icon
type="line-chart"/>Apps</Link></Menu.Item>
<Menu.Item key="3"><Link to="/publisher/apps/new-app"><Icon type="upload"/>Add New <Menu.Item key="3"><Link to="/publisher/apps/new-app"><Icon type="upload"/>Add New
App</Link></Menu.Item> App</Link></Menu.Item>
<Menu.Item key="2"><Link to="/publisher/manage"><Icon
type="control"/>Manage</Link></Menu.Item>
</Menu> </Menu>
</Header> </Header>
</Layout> </Layout>

@ -1,226 +0,0 @@
import React from "react";
import "antd/dist/antd.css";
import {Table, Divider, Tag, Card, PageHeader, Typography, Avatar,Input, Button, Icon, Row, Col} from "antd";
import Highlighter from 'react-highlight-words';
import axios from "axios";
const Paragraph = Typography;
const Search = Input.Search;
const routes = [
{
path: 'index',
breadcrumbName: 'Publisher',
},
{
path: 'first',
breadcrumbName: 'Dashboard',
},
{
path: 'second',
breadcrumbName: 'OldApps',
},
];
class OldApps extends React.Component {
routes;
state = {
searchText: '',
};
constructor(props) {
super(props);
this.routes = props.routes;
this.state = {
data: []
};
this.loadData = this.loadData.bind(this);
}
loadData(){
const thisComponent = this;
const request = "method=post&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications";
axios.post('https://localhost:9443/api/application-mgt-handler/v1.0/invoke', request
).then(res => {
if(res.status === 200){
console.log(res.status);
let apps = [];
res.data['data']['applications'].forEach(function (app) {
apps.push({
key: app.id,
icon: app["applicationReleases"][0]["iconPath"],
name: app.name,
platform: 'undefined',
type: app.type,
status: 'undefined',
version: 'undefined',
updated_at: 'undefined'
});
});
thisComponent.setState({
data : apps
})
}
}).catch(function (error) {
if(error.response.status === 401){
window.location.href = 'https://localhost:9443/publisher/login';
}
});
}
componentDidMount() {
this.loadData();
}
getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
setSelectedKeys, selectedKeys, confirm, clearFilters,
}) => (
<div style={{ padding: 8 }}>
<Input
ref={node => { this.searchInput = node; }}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
style={{ width: 188, marginBottom: 8, display: 'block' }}
/>
<Button
type="primary"
onClick={() => this.handleSearch(selectedKeys, confirm)}
icon="search"
size="small"
style={{ width: 90, marginRight: 8 }}
>
Search
</Button>
<Button
onClick={() => this.handleReset(clearFilters)}
size="small"
style={{ width: 90 }}
>
Reset
</Button>
</div>
),
filterIcon: filtered => <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) => record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()),
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => this.searchInput.select());
}
},
render: (text) => (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[this.state.searchText]}
autoEscape
textToHighlight={text.toString()}
/>
),
});
handleSearch = (selectedKeys, confirm) => {
confirm();
this.setState({ searchText: selectedKeys[0] });
};
handleReset = (clearFilters) => {
clearFilters();
this.setState({ searchText: '' });
};
render() {
const columns = [{
title: '',
dataIndex: 'icon',
key: 'icon',
render: text => <Avatar size="large" src={text}/>,
}, {
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a href="javascript:;">{text}</a>,
...this.getColumnSearchProps('name'),
}, {
title: 'Platform',
dataIndex: 'platform',
key: 'platform',
}, {
title: 'Type',
dataIndex: 'type',
key: 'type',
}, {
title: 'Status',
key: 'status',
dataIndex: 'status',
render: tag => {
let color;
switch (tag) {
case 'published':
color = 'green';
break;
case 'removed':
color = 'red';
break;
case 'default':
color = 'blue';
}
return <Tag color={color} key={tag}>{tag.toUpperCase()}</Tag>;
},
}, {
title: 'Published Version',
dataIndex: 'version',
key: 'version',
}, {
title: 'Last Updated',
dataIndex: 'updated_at',
key: 'updated_at',
},{
title: 'Action',
key: 'action',
render: () => (
<span>
<a href="javascript:;">Edit</a>
<Divider type="vertical" />
<a href="javascript:;">Manage</a>
</span>
),
}];
return (
<div>
<PageHeader
breadcrumb={{routes}}
/>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
<Card>
<Row style={{padding:10}}>
<Col span={6} offset={18}>
<Search
placeholder="search"
onSearch={value => console.log(value)}
style={{ width: 200}}
/>
<Button style={{margin:5}}>Advanced Search</Button>
</Col>
</Row>
<Table columns={columns} dataSource={this.state.data}/>
</Card>
</div>
</div>
);
}
}
export default OldApps;

@ -0,0 +1,62 @@
import React from "react";
import "antd/dist/antd.css";
import {PageHeader, Typography, Input, Button, Row, Col} from "antd";
import ManageCategories from "../../../components/manage/categories/ManageCategories";
import ManageTags from "../../../components/manage/categories/ManageTags";
const {Paragraph} = Typography;
const routes = [
{
path: 'index',
breadcrumbName: 'Publisher',
},
{
path: 'first',
breadcrumbName: 'Dashboard',
},
{
path: 'second',
breadcrumbName: 'Manage',
},
];
class Manage extends React.Component {
routes;
constructor(props) {
super(props);
this.routes = props.routes;
}
render() {
return (
<div>
<PageHeader
breadcrumb={{routes}}
title = "Manage"
>
<div className="wrap">
<div className="content">
<Paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempo.
</Paragraph>
</div>
</div>
</PageHeader>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
<ManageCategories/>
<br/>
<ManageTags/>
</div>
</div>
);
}
}
export default Manage;

@ -15,7 +15,7 @@ class App extends React.Component {
} }
render() { render() {
console.log(this.routes); // console.log(this.routes);
return ( return (
<Router> <Router>
<div> <div>

@ -29,7 +29,7 @@ class ConnectedAppCard extends React.Component {
render() { render() {
const app = this.props.app; const app = this.props.app;
const release = this.props.app.applicationReleases[0]; const release = this.props.app.applicationReleases[0];
console.log(this.props); // console.log(this.props);
const description = ( const description = (
<div className="appCard"> <div className="appCard">

@ -27,6 +27,8 @@ class ConnectedDetailedRating extends React.Component{
render() { render() {
const detailedRating = this.props.detailedRating; const detailedRating = this.props.detailedRating;
console.log(detailedRating);
if(detailedRating ==null){ if(detailedRating ==null){
return null; return null;
} }
@ -42,7 +44,15 @@ class ConnectedDetailedRating extends React.Component{
const maximumRating = Math.max(...ratingArray); const maximumRating = Math.max(...ratingArray);
console.log(maximumRating); const ratingBarPercentages = [0,0,0,0,0];
if(maximumRating>0){
for(let i = 0; i<5; i++){
ratingBarPercentages[i] = (ratingVariety[(i+1).toString()])/maximumRating*100;
}
}
console.log(ratingBarPercentages);
return ( return (
<Row className="d-rating"> <Row className="d-rating">
@ -62,23 +72,23 @@ class ConnectedDetailedRating extends React.Component{
<div className="bar-containers"> <div className="bar-containers">
<div className="bar-container"> <div className="bar-container">
<span className="number">5</span> <span className="number">5</span>
<span className="bar rate-5" style={{width: (ratingVariety["5"]/maximumRating*100)+"%"}}> </span> <span className="bar rate-5" style={{width: ratingBarPercentages[4]+"%"}}> </span>
</div> </div>
<div className="bar-container"> <div className="bar-container">
<span className="number">4</span> <span className="number">4</span>
<span className="bar rate-4" style={{width: (ratingVariety["4"]/maximumRating*100)+"%"}}> </span> <span className="bar rate-4" style={{width: ratingBarPercentages[3]+"%"}}> </span>
</div> </div>
<div className="bar-container"> <div className="bar-container">
<span className="number">3</span> <span className="number">3</span>
<span className="bar rate-3" style={{width: (ratingVariety["3"]/maximumRating*100)+"%"}}> </span> <span className="bar rate-3" style={{width: ratingBarPercentages[2]+"%"}}> </span>
</div> </div>
<div className="bar-container"> <div className="bar-container">
<span className="number">2</span> <span className="number">2</span>
<span className="bar rate-2" style={{width: (ratingVariety["2"]/maximumRating*100)+"%"}}> </span> <span className="bar rate-2" style={{width: ratingBarPercentages[1]+"%"}}> </span>
</div> </div>
<div className="bar-container"> <div className="bar-container">
<span className="number">1</span> <span className="number">1</span>
<span className="bar rate-1" style={{width: (ratingVariety["1"]/maximumRating*100)+"%"}}> </span> <span className="bar rate-1" style={{width: ratingBarPercentages[0]+"%"}}> </span>
</div> </div>
</div> </div>
</Row> </Row>

@ -38,7 +38,9 @@ class Reviews extends React.Component {
}).catch(function (error) { }).catch(function (error) {
if (error.response.status === 401) { if (error.response.status === 401) {
window.location.href = 'https://localhost:9443/store/login'; window.location.href = 'https://localhost:9443/store/login';
}else{
message.warning('Something went wrong'); message.warning('Something went wrong');
} }
}); });
}; };
@ -90,8 +92,8 @@ class Reviews extends React.Component {
rating: 4, rating: 4,
replies: [] replies: []
}; };
console.log(this.state.loadMore); // console.log(this.state.loadMore);
console.log(this.state.data.length); // console.log(this.state.data.length);
return ( return (
<div className="demo-infinite-container"> <div className="demo-infinite-container">
<InfiniteScroll <InfiniteScroll

@ -57,7 +57,6 @@ class NormalLoginForm extends React.Component {
thisForm.setState({ thisForm.setState({
loading: true loading: true
}); });
console.log('Received values of form: ', values);
let data = "username=" + values.username + "&password=" + values.password + "&platform=store"; let data = "username=" + values.username + "&password=" + values.password + "&platform=store";
axios.post('https://'+config.serverConfig.hostname+':'+config.serverConfig.httpsPort+config.serverConfig.loginUri, data axios.post('https://'+config.serverConfig.hostname+':'+config.serverConfig.httpsPort+config.serverConfig.loginUri, data
).then(res => { ).then(res => {

@ -50,7 +50,7 @@ const props = {
onChange(info) { onChange(info) {
const status = info.file.status; const status = info.file.status;
if (status !== 'uploading') { if (status !== 'uploading') {
console.log(info.file, info.fileList); // console.log(info.file, info.fileList);
} }
if (status === 'done') { if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`); message.success(`${info.file.name} file uploaded successfully.`);
@ -98,7 +98,7 @@ class EditableTagGroup extends React.Component {
handleClose = (removedTag) => { handleClose = (removedTag) => {
const tags = this.state.tags.filter(tag => tag !== removedTag); const tags = this.state.tags.filter(tag => tag !== removedTag);
console.log(tags); // console.log(tags);
this.setState({tags}); this.setState({tags});
} }
@ -116,7 +116,7 @@ class EditableTagGroup extends React.Component {
if (inputValue && tags.indexOf(inputValue) === -1) { if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [...tags, inputValue]; tags = [...tags, inputValue];
} }
console.log(tags); // console.log(tags);
this.setState({ this.setState({
tags, tags,
inputVisible: false, inputVisible: false,

@ -24,7 +24,7 @@ class EditableTagGroup extends React.Component {
handleClose = (removedTag) => { handleClose = (removedTag) => {
const tags = this.state.tags.filter(tag => tag !== removedTag); const tags = this.state.tags.filter(tag => tag !== removedTag);
console.log(tags); // console.log(tags);
this.setState({ tags }); this.setState({ tags });
} }
@ -42,7 +42,7 @@ class EditableTagGroup extends React.Component {
if (inputValue && tags.indexOf(inputValue) === -1) { if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [...tags, inputValue]; tags = [...tags, inputValue];
} }
console.log(tags); // console.log(tags);
this.setState({ this.setState({
tags, tags,
inputVisible: false, inputVisible: false,
@ -92,7 +92,6 @@ class EditableTagGroup extends React.Component {
class Step1 extends React.Component { class Step1 extends React.Component {
render() { render() {
console.log("hhhoohh");
return ( return (
<div> <div>
<Form layout="horizontal" className={styles.stepForm} hideRequiredMark> <Form layout="horizontal" className={styles.stepForm} hideRequiredMark>

@ -2,7 +2,6 @@ import React from "react"
class Step2 extends React.Component { class Step2 extends React.Component {
render() { render() {
console.log("hhhoohh");
return ( return (
<p>tttoooeeee</p> <p>tttoooeeee</p>
); );

@ -2,7 +2,6 @@ import React from "react"
class Step3 extends React.Component { class Step3 extends React.Component {
render() { render() {
console.log("hhhoohh");
return ( return (
<p>tttoooeeee</p> <p>tttoooeeee</p>
); );

Loading…
Cancel
Save