Skip to content
Snippets Groups Projects
Commit eca64cbf authored by Remco Tukker's avatar Remco Tukker
Browse files

Merge branch 'feature/add_react_router_to_survey' into 'develop'

Feature/add react router to survey

See merge request !51
parents 6bef7e61 4ef8a271
Branches
Tags
1 merge request!51Feature/add react router to survey
...@@ -6,6 +6,7 @@ from datetime import datetime ...@@ -6,6 +6,7 @@ from datetime import datetime
from enum import Enum from enum import Enum
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from typing import List
from typing_extensions import Annotated from typing_extensions import Annotated
from sqlalchemy import Table, Column from sqlalchemy import Table, Column
...@@ -62,7 +63,7 @@ class User(UserMixin, db.Model): ...@@ -62,7 +63,7 @@ class User(UserMixin, db.Model):
created_at: Mapped[_datetime] created_at: Mapped[_datetime]
last_login: Mapped[_datetime] last_login: Mapped[_datetime]
nrens: Mapped[NREN] = relationship(secondary=UserNrenMember, lazy='joined') nrens: Mapped[List[NREN]] = relationship(secondary=UserNrenMember, lazy='joined')
def __repr__(self): def __repr__(self):
return '<User %r>' % self.email return '<User %r>' % self.email
......
...@@ -3,7 +3,9 @@ from typing import Any, Union ...@@ -3,7 +3,9 @@ from typing import Any, Union
from flask import Blueprint, jsonify from flask import Blueprint, jsonify
from flask_login import current_user, AnonymousUserMixin # type: ignore from flask_login import current_user, AnonymousUserMixin # type: ignore
from sqlalchemy import select
from compendium_v2.db import db
from compendium_v2.db.auth_model import User from compendium_v2.db.auth_model import User
from compendium_v2.routes import common from compendium_v2.routes import common
...@@ -33,7 +35,7 @@ USER_RESPONSE_SCHEMA = { ...@@ -33,7 +35,7 @@ USER_RESPONSE_SCHEMA = {
@routes.route('/', methods=['GET']) @routes.route('/', methods=['GET'])
@common.require_accepts_json @common.require_accepts_json
def charging_structure_view() -> Any: def current_user_view() -> Any:
""" """
handler for /api/user/ requests handler for /api/user/ requests
...@@ -55,3 +57,22 @@ def charging_structure_view() -> Any: ...@@ -55,3 +57,22 @@ def charging_structure_view() -> Any:
} }
return jsonify(_extract_data(current_user)) return jsonify(_extract_data(current_user))
@routes.route('/list', methods=['GET'])
@common.require_accepts_json
def all_users_view() -> Any:
# TODO schema and docstring
def _extract_data(entry: User):
return {
'id': entry.id,
'email': entry.email,
'roles': entry.roles.value,
'active': entry.active,
'nrens': [nren.name for nren in entry.nrens]
}
entries = [_extract_data(entry) for entry in db.session.scalars(
select(User).order_by(User.email)).unique()]
return jsonify(entries)
This diff is collapsed.
...@@ -2073,3 +2073,25 @@ ...@@ -2073,3 +2073,25 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/**
* @remix-run/router v1.6.2
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router v6.11.2
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
"@types/webpack-dev-server": "^4.7.2" "@types/webpack-dev-server": "^4.7.2"
}, },
"scripts": { "scripts": {
"start": "webpack serve --mode development --open --port 4001", "start": "webpack serve --mode development --port 4001",
"build": "webpack --mode production" "build": "webpack --mode production"
}, },
"dependencies": { "dependencies": {
......
import React, { ReactElement } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import SurveySelectionComponent from './SurveySelectionComponent';
import ShowUser from './ShowUser';
import UserManagementComponent from "./UserManagementComponent";
function App(): ReactElement {
return (
<div className="app">
<Router>
<Routes>
<Route path="survey/admin/surveys" element={<SurveySelectionComponent />} />
<Route path="survey/admin/users" element={<UserManagementComponent />} />
<Route path="*" element={<ShowUser />} />
</Routes>
</Router>
</div>
);
}
export default App;
import React, { useState, useEffect } from "react";
async function fetchUsers(): Promise<User[]> {
try {
const response = await fetch('/api/user/list');
const userList = await response.json();
return userList
} catch (error) {
console.log('handle this better..');
return [];
}
}
interface User {
id: string,
email: string,
roles: string,
active: boolean,
nrens: string[]
}
function UserManagementComponent() {
const [users, setUsers] = useState<User[]>([]);
useEffect(() => {
// Fetch user
fetchUsers().then((userList) => {
setUsers(userList);
});
}, []);
return (
<div>
<table>
{users.map(user => (
<tr key={user.id}>
{user.id} - {user.email} - {user.active ? 'active' : 'inactive'} - {user.roles} - {user.nrens.join()}
</tr>
))}
</table>
</div>
);
}
export default UserManagementComponent;
import React from 'react'; import React from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import SurveySelectionComponent from './SurveySelectionComponent'; import App from './App';
import ShowUser from './ShowUser';
const container = document.getElementById('root') as HTMLElement; const container = document.getElementById('root') as HTMLElement;
const root = createRoot(container); const root = createRoot(container);
...@@ -11,7 +9,6 @@ const root = createRoot(container); ...@@ -11,7 +9,6 @@ const root = createRoot(container);
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<ShowUser /> <App />
<SurveySelectionComponent />
</React.StrictMode> </React.StrictMode>
) )
\ No newline at end of file
...@@ -80,6 +80,7 @@ const config: Configuration = { ...@@ -80,6 +80,7 @@ const config: Configuration = {
devServer: { devServer: {
static: path.resolve(__dirname, "..", "survey-frontend", "static"), static: path.resolve(__dirname, "..", "survey-frontend", "static"),
compress: true, compress: true,
open: ["http://localhost:4001/survey"],
port: 4001, port: 4001,
// Allow SPA urls to work with dev-server // Allow SPA urls to work with dev-server
historyApiFallback: true, historyApiFallback: true,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment