diff --git a/web/client/assets/images/install/long_logo.png b/web/client/assets/images/install/long_logo.png
new file mode 100644
index 0000000..1bbad23
Binary files /dev/null and b/web/client/assets/images/install/long_logo.png differ
diff --git a/web/client/assets/images/install/watting.png b/web/client/assets/images/install/watting.png
new file mode 100644
index 0000000..b0f6902
Binary files /dev/null and b/web/client/assets/images/install/watting.png differ
diff --git a/web/client/src/app.jsx b/web/client/src/app.jsx
index a091d81..baca1e8 100644
--- a/web/client/src/app.jsx
+++ b/web/client/src/app.jsx
@@ -4,10 +4,12 @@ import React, { useEffect } from 'react';
import Layout from './layout';
import Auth from './sections/auth';
import Example from './sections/example';
+import Analysis from './sections/analysis';
import Install from './sections/install';
import Problem from './sections/problem';
import NoMatch from './sections/noMatch';
import Console from './sections/console';
+import Data from './sections/data';
const App = props => {
const { projectName } = props
@@ -32,8 +34,8 @@ const App = props => {
return (
diff --git a/web/client/src/layout/components/header/index.jsx b/web/client/src/layout/components/header/index.jsx
index 6c1014a..441e986 100644
--- a/web/client/src/layout/components/header/index.jsx
+++ b/web/client/src/layout/components/header/index.jsx
@@ -30,22 +30,10 @@ const Header = (props) => {
}}
header={{
logo: (
-
-
-
-
-
-
运维管理系统
-
RUNNING MANAGEMENT SYSTEM
-
-
- //
+
),
// text: (
// 运维管理系统
diff --git a/web/client/src/sections/analysis/actions/console.js b/web/client/src/sections/analysis/actions/console.js
new file mode 100644
index 0000000..ff08638
--- /dev/null
+++ b/web/client/src/sections/analysis/actions/console.js
@@ -0,0 +1,14 @@
+'use strict';
+
+import { ApiTable ,basicAction} from '$utils'
+
+// export function getMembers (orgId) {
+// return dispatch => basicAction({
+// type: 'get',
+// dispatch: dispatch,
+// actionType: 'GET_MEMBERS',
+// url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`,
+// msg: { error: '获取用户列表失败' },
+// reducer: { name: 'members' }
+// });
+// }
diff --git a/web/client/src/sections/analysis/actions/index.js b/web/client/src/sections/analysis/actions/index.js
new file mode 100644
index 0000000..33cdd8b
--- /dev/null
+++ b/web/client/src/sections/analysis/actions/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+import * as console from './console'
+
+export default {
+ ...console
+}
\ No newline at end of file
diff --git a/web/client/src/sections/analysis/containers/index.js b/web/client/src/sections/analysis/containers/index.js
new file mode 100644
index 0000000..eaa6303
--- /dev/null
+++ b/web/client/src/sections/analysis/containers/index.js
@@ -0,0 +1,6 @@
+'use strict';
+
+import ProblemData from './problemData';
+import OperationData from './operationData';
+import WorkorderData from './workorderData';
+export { ProblemData,OperationData ,WorkorderData};
\ No newline at end of file
diff --git a/web/client/src/sections/analysis/containers/operationData.jsx b/web/client/src/sections/analysis/containers/operationData.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/analysis/containers/operationData.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/analysis/containers/problemData.jsx b/web/client/src/sections/analysis/containers/problemData.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/analysis/containers/problemData.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/analysis/containers/workorderData.jsx b/web/client/src/sections/analysis/containers/workorderData.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/analysis/containers/workorderData.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/analysis/index.js b/web/client/src/sections/analysis/index.js
new file mode 100644
index 0000000..d20633b
--- /dev/null
+++ b/web/client/src/sections/analysis/index.js
@@ -0,0 +1,15 @@
+'use strict';
+
+import reducers from './reducers';
+import routes from './routes';
+import actions from './actions';
+import { getNavItem } from './nav-item';
+
+export default {
+ key: 'analysis',
+ name: '分析',
+ reducers: reducers,
+ routes: routes,
+ actions: actions,
+ getNavItem: getNavItem
+};
\ No newline at end of file
diff --git a/web/client/src/sections/analysis/nav-item.jsx b/web/client/src/sections/analysis/nav-item.jsx
new file mode 100644
index 0000000..1fdac6c
--- /dev/null
+++ b/web/client/src/sections/analysis/nav-item.jsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import { IconCode } from '@douyinfe/semi-icons';
+
+export function getNavItem (user, dispatch) {
+ return (
+ [
+ {
+ itemKey: 'analysis',
+ text: '分析',
+ icon: ,
+ items: [
+ {
+ itemKey: 'problemAnalysis',
+ text: '问题分析',
+ icon: ,
+ to: '/analysis/problemAnalysis/problemData',
+ items: [{
+ itemKey: 'problemData', to: '/analysis/problemAnalysis/problemData', text: '问题数据'
+ }]
+ }, {
+ itemKey: 'operationAnalysis',
+ text: '运维分析',
+ icon: ,
+ to: '/analysis/operationAnalysis/operationData',
+ items: [{
+ itemKey: 'operationData', to: '/analysis/operationAnalysis/operationData', text: '运维数据'
+ }]
+ },{
+ itemKey: 'workorderAnalysis',
+ text: '工单分析',
+ icon: ,
+ to: '/analysis/workorderAnalysis/workorderData',
+ items: [{
+ itemKey: 'workorderData', to: '/analysis/workorderAnalysis/workorderData', text: '工单数据'
+ }]
+ },
+ ]
+ },
+ ]
+ );
+}
\ No newline at end of file
diff --git a/web/client/src/sections/analysis/reducers/index.js b/web/client/src/sections/analysis/reducers/index.js
new file mode 100644
index 0000000..7ed1088
--- /dev/null
+++ b/web/client/src/sections/analysis/reducers/index.js
@@ -0,0 +1,5 @@
+'use strict';
+
+export default {
+
+}
\ No newline at end of file
diff --git a/web/client/src/sections/analysis/routes.js b/web/client/src/sections/analysis/routes.js
new file mode 100644
index 0000000..789dd9d
--- /dev/null
+++ b/web/client/src/sections/analysis/routes.js
@@ -0,0 +1,42 @@
+import { ProblemData, OperationData, WorkorderData } from './containers';
+
+export default [{
+ type: 'inner',
+ route: {
+ path: '/analysis',
+ key: 'analysis',
+ breadcrumb: '分析',
+ // 不设置 component 则面包屑禁止跳转
+ childRoutes: [{
+ path: '/problemAnalysis',
+ key: 'problemAnalysis',
+ breadcrumb: '问题分析',
+ childRoutes: [{
+ path: '/problemData',
+ key: 'problemData',
+ component: ProblemData,
+ breadcrumb: '分析数据',
+ }]
+ }, {
+ path: '/operationAnalysis',
+ key: 'operationAnalysis',
+ breadcrumb: '运维分析',
+ childRoutes: [{
+ path: '/operationData',
+ key: 'operationData',
+ component: OperationData,
+ breadcrumb: '运维数据',
+ }]
+ }, {
+ path: '/workorderAnalysis',
+ key: 'workorderAnalysis',
+ breadcrumb: '工单分析',
+ childRoutes: [{
+ path: '/workorderData',
+ key: 'workorderData',
+ component: WorkorderData,
+ breadcrumb: '工单数据',
+ }]
+ }]
+ }
+}];
\ No newline at end of file
diff --git a/web/client/src/sections/analysis/style.less b/web/client/src/sections/analysis/style.less
new file mode 100644
index 0000000..75ecdb6
--- /dev/null
+++ b/web/client/src/sections/analysis/style.less
@@ -0,0 +1,7 @@
+#example {
+ box-shadow: 3px 3px 2px black;
+}
+
+#example:hover {
+ color: yellowgreen;
+}
\ No newline at end of file
diff --git a/web/client/src/sections/console/containers/console.jsx b/web/client/src/sections/console/containers/console.jsx
index 653c238..e37e5de 100644
--- a/web/client/src/sections/console/containers/console.jsx
+++ b/web/client/src/sections/console/containers/console.jsx
@@ -5,45 +5,45 @@ import '../style.less'
const { Meta } = Card;
const Console = (props) => {
- const { dispatch, actions, user, loading, socket } = props
+ const { dispatch, actions, user, loading, socket } = props
- useEffect(() => {
- // ACTION 示例
- // dispatch(actions.example.getMembers(user.orgId))
- }, [])
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
- // websocket 使用测试
-// useEffect(() => {
-// console.log(socket)
-// if (socket) {
-// socket.on('TEST', function (msg) {
-// console.info(msg);
-// });
-// return () => {
-// socket.off("TEST");
-// }
-// }
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
-// }, [socket])
+ // }, [socket])
- return (
- <>
-
- texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
-
- >
- )
+ return (
+ <>
+
+
+
+ >
+ )
}
function mapStateToProps (state) {
- const { auth, global, members, webSocket } = state;
- return {
- // loading: members.isRequesting,
- // user: auth.user,
- // actions: global.actions,
- // members: members.data,
- // socket: webSocket.socket
- };
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
}
export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/data/actions/console.js b/web/client/src/sections/data/actions/console.js
new file mode 100644
index 0000000..ff08638
--- /dev/null
+++ b/web/client/src/sections/data/actions/console.js
@@ -0,0 +1,14 @@
+'use strict';
+
+import { ApiTable ,basicAction} from '$utils'
+
+// export function getMembers (orgId) {
+// return dispatch => basicAction({
+// type: 'get',
+// dispatch: dispatch,
+// actionType: 'GET_MEMBERS',
+// url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`,
+// msg: { error: '获取用户列表失败' },
+// reducer: { name: 'members' }
+// });
+// }
diff --git a/web/client/src/sections/data/actions/index.js b/web/client/src/sections/data/actions/index.js
new file mode 100644
index 0000000..33cdd8b
--- /dev/null
+++ b/web/client/src/sections/data/actions/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+import * as console from './console'
+
+export default {
+ ...console
+}
\ No newline at end of file
diff --git a/web/client/src/sections/data/containers/dataAssociation.jsx b/web/client/src/sections/data/containers/dataAssociation.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/data/containers/dataAssociation.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/data/containers/dataComparison.jsx b/web/client/src/sections/data/containers/dataComparison.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/data/containers/dataComparison.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/data/containers/dataQuery.jsx b/web/client/src/sections/data/containers/dataQuery.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/data/containers/dataQuery.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/data/containers/index.js b/web/client/src/sections/data/containers/index.js
new file mode 100644
index 0000000..4c93e75
--- /dev/null
+++ b/web/client/src/sections/data/containers/index.js
@@ -0,0 +1,6 @@
+'use strict';
+import DataQuery from './dataQuery';
+import DataComparison from './dataComparison';
+import DataAssociation from './dataAssociation';
+import Notebook from './notebook';
+export { DataQuery, DataComparison, DataAssociation,Notebook};
\ No newline at end of file
diff --git a/web/client/src/sections/data/containers/notebook.jsx b/web/client/src/sections/data/containers/notebook.jsx
new file mode 100644
index 0000000..e37e5de
--- /dev/null
+++ b/web/client/src/sections/data/containers/notebook.jsx
@@ -0,0 +1,49 @@
+import React, { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Spin, Card } from '@douyinfe/semi-ui';
+import '../style.less'
+const { Meta } = Card;
+
+const Console = (props) => {
+ const { dispatch, actions, user, loading, socket } = props
+
+ useEffect(() => {
+ // ACTION 示例
+ // dispatch(actions.example.getMembers(user.orgId))
+ }, [])
+
+ // websocket 使用测试
+ // useEffect(() => {
+ // console.log(socket)
+ // if (socket) {
+ // socket.on('TEST', function (msg) {
+ // console.info(msg);
+ // });
+ // return () => {
+ // socket.off("TEST");
+ // }
+ // }
+
+ // }, [socket])
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function mapStateToProps (state) {
+ const { auth, global, members, webSocket } = state;
+ return {
+ // loading: members.isRequesting,
+ // user: auth.user,
+ // actions: global.actions,
+ // members: members.data,
+ // socket: webSocket.socket
+ };
+}
+
+export default connect(mapStateToProps)(Console);
diff --git a/web/client/src/sections/data/index.js b/web/client/src/sections/data/index.js
new file mode 100644
index 0000000..e3946b0
--- /dev/null
+++ b/web/client/src/sections/data/index.js
@@ -0,0 +1,15 @@
+'use strict';
+
+import reducers from './reducers';
+import routes from './routes';
+import actions from './actions';
+import { getNavItem } from './nav-item';
+
+export default {
+ key: 'data',
+ name: '数据',
+ reducers: reducers,
+ routes: routes,
+ actions: actions,
+ getNavItem: getNavItem
+};
\ No newline at end of file
diff --git a/web/client/src/sections/data/nav-item.jsx b/web/client/src/sections/data/nav-item.jsx
new file mode 100644
index 0000000..b131deb
--- /dev/null
+++ b/web/client/src/sections/data/nav-item.jsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { IconCode } from '@douyinfe/semi-icons';
+
+export function getNavItem (user, dispatch) {
+ return (
+ [
+ {
+ itemKey: 'data',
+ text: '数据',
+ icon: ,
+ items: [
+ {
+ itemKey: 'dataMonitoring',
+ text: '数据监控',
+ icon: ,
+ to: '/data/dataMonitoring/dataQuery',
+ items: [{
+ itemKey: 'dataQuery', to: '/data/dataMonitoring/dataQuery', text: '数据查询'
+ }]
+ }, {
+ itemKey: 'dataAnalysis',
+ text: '数据分析',
+ icon: ,
+ to: '/data/dataAnalysis/dataComparison',
+ items: [{
+ itemKey: 'dataComparison', to: '/data/dataAnalysis/dataComparison', text: '数据对比'
+ },{
+ itemKey: 'dataAssociation', to: '/data/dataAnalysis/dataAssociation', text: '数据关联'
+ },{
+ itemKey: 'notebook', to: '/data/dataAnalysis/notebook', text: 'notebook'
+ }]
+ },
+ ]
+ },
+ ]
+ );
+}
\ No newline at end of file
diff --git a/web/client/src/sections/data/reducers/index.js b/web/client/src/sections/data/reducers/index.js
new file mode 100644
index 0000000..7ed1088
--- /dev/null
+++ b/web/client/src/sections/data/reducers/index.js
@@ -0,0 +1,5 @@
+'use strict';
+
+export default {
+
+}
\ No newline at end of file
diff --git a/web/client/src/sections/data/routes.js b/web/client/src/sections/data/routes.js
new file mode 100644
index 0000000..d3e4627
--- /dev/null
+++ b/web/client/src/sections/data/routes.js
@@ -0,0 +1,42 @@
+import { DataQuery, DataComparison, DataAssociation,Notebook } from './containers';
+
+export default [{
+ type: 'inner',
+ route: {
+ path: '/data',
+ key: 'data',
+ breadcrumb: '数据',
+ // 不设置 component 则面包屑禁止跳转
+ childRoutes: [{
+ path: '/dataMonitoring',
+ key: 'dataMonitoring',
+ breadcrumb: '数据监控',
+ childRoutes: [{
+ path: '/dataQuery',
+ key: 'dataQuery',
+ component: DataQuery,
+ breadcrumb: '数据查询',
+ }]
+ }, {
+ path: '/dataAnalysis',
+ key: 'dataAnalysis',
+ breadcrumb: '数据分析',
+ childRoutes: [{
+ path: '/dataComparison',
+ key: 'dataComparison',
+ component: DataComparison,
+ breadcrumb: '数据对比',
+ },{
+ path: '/dataAssociation',
+ key: 'dataAssociation',
+ component: DataAssociation,
+ breadcrumb: '数据关联',
+ },{
+ path: '/notebook',
+ key: 'notebook',
+ component: Notebook,
+ breadcrumb: 'notebook',
+ }]
+ }]
+ }
+}];
\ No newline at end of file
diff --git a/web/client/src/sections/data/style.less b/web/client/src/sections/data/style.less
new file mode 100644
index 0000000..75ecdb6
--- /dev/null
+++ b/web/client/src/sections/data/style.less
@@ -0,0 +1,7 @@
+#example {
+ box-shadow: 3px 3px 2px black;
+}
+
+#example:hover {
+ color: yellowgreen;
+}
\ No newline at end of file