@igea/oac_frontend 1.0.14 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/controllers/users.js +8 -10
- package/src/index.js +6 -1
- package/src/locales/en.json +5 -1
- package/src/locales/it.json +5 -1
- package/src/models/DataModel +19 -0
- package/src/public/js/app/vue-users-edit.js +57 -0
- package/src/views/home.twig +0 -2
- package/src/views/sidebar.twig +20 -13
- package/src/views/users/edit.twig +71 -0
package/package.json
CHANGED
package/src/controllers/users.js
CHANGED
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const router = express.Router();
|
|
3
|
-
|
|
3
|
+
const DataModel = require('../models/DataModel');
|
|
4
4
|
|
|
5
5
|
module.exports = function(serviceName) {
|
|
6
6
|
/**
|
|
7
7
|
* @route GET /users/manage: redirect to the users page with list of users
|
|
8
8
|
*/
|
|
9
9
|
router.get('/manage', (req, res) => {
|
|
10
|
-
let
|
|
11
|
-
res.render('users/manage.twig', {
|
|
10
|
+
let data = new DataModel(req, {
|
|
12
11
|
root: serviceName,
|
|
13
12
|
title: 'User Management',
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
});
|
|
14
|
+
res.render('users/manage.twig', data.toJson());
|
|
16
15
|
});
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* @route GET /users/:id: redirect to the user page with user details
|
|
20
19
|
*/
|
|
21
20
|
router.get('/:id', (req, res) => {
|
|
22
|
-
let
|
|
23
|
-
res.render('users/edit.twig', {
|
|
21
|
+
let data = new DataModel(req, {
|
|
24
22
|
root: serviceName,
|
|
25
23
|
title: 'User Edit',
|
|
26
|
-
id: req.params.id
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
id: req.params.id
|
|
25
|
+
});
|
|
26
|
+
res.render('users/edit.twig', data.toJson());
|
|
29
27
|
});
|
|
30
28
|
|
|
31
29
|
/**
|
package/src/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const path = require("path");
|
|
|
7
7
|
const i18n = require('i18n');
|
|
8
8
|
const jwtLibFactory = require('@igea/oac_jwt_helpers')
|
|
9
9
|
const serviceName = "frontend"
|
|
10
|
+
const DataModel = require('./models/DataModel');
|
|
10
11
|
const jwtLib = jwtLibFactory({
|
|
11
12
|
secret: process.env.JWT_SECRET || config.jwt_secret,
|
|
12
13
|
excludePaths: [
|
|
@@ -78,7 +79,11 @@ getPort.default({
|
|
|
78
79
|
res.render('login', { root: serviceName, title: 'Login' });
|
|
79
80
|
});
|
|
80
81
|
app.get(`/${serviceName}/home`, (req, res) => {
|
|
81
|
-
|
|
82
|
+
let data = new DataModel(req, {
|
|
83
|
+
root: serviceName,
|
|
84
|
+
title: 'Home',
|
|
85
|
+
});
|
|
86
|
+
res.render('home', data.toJson());
|
|
82
87
|
});
|
|
83
88
|
// ---------------------------------------------------------------------
|
|
84
89
|
// Start listing on the specified port
|
package/src/locales/en.json
CHANGED
package/src/locales/it.json
CHANGED
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
"edit": {
|
|
23
23
|
"title": "Utente",
|
|
24
24
|
"update": "Modifica",
|
|
25
|
-
"new": "Nuovo"
|
|
25
|
+
"new": "Nuovo",
|
|
26
|
+
"password": "Password",
|
|
27
|
+
"confirm_password": "Conferma password",
|
|
28
|
+
"save": "Salva",
|
|
29
|
+
"cancel": "Annulla"
|
|
26
30
|
},
|
|
27
31
|
"profile": {
|
|
28
32
|
"title": "Profilo"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
class DataModel {
|
|
3
|
+
|
|
4
|
+
constructor(req, options = {}){
|
|
5
|
+
this.user = req.user || {};
|
|
6
|
+
this.options = options;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
toJson(){
|
|
10
|
+
return {
|
|
11
|
+
user: this.user,
|
|
12
|
+
cur_id: this.user.id || 0,
|
|
13
|
+
...this.options
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = DataModel;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const {createApp} = Vue;
|
|
2
|
+
|
|
3
|
+
const elementId = 'edit-user';
|
|
4
|
+
|
|
5
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
6
|
+
const el = document.getElementById(elementId);
|
|
7
|
+
|
|
8
|
+
const app = createApp({
|
|
9
|
+
delimiters: ['{%', '%}'],
|
|
10
|
+
data() {
|
|
11
|
+
return {
|
|
12
|
+
root: el.dataset.root,
|
|
13
|
+
labels: {
|
|
14
|
+
role_sudo: el.dataset.role_sudo,
|
|
15
|
+
role_admin: el.dataset.role_admin,
|
|
16
|
+
role_editor: el.dataset.role_editor,
|
|
17
|
+
role_reader: el.dataset.role_reader,
|
|
18
|
+
},
|
|
19
|
+
user: {
|
|
20
|
+
name: "",
|
|
21
|
+
surname: "",
|
|
22
|
+
username: "",
|
|
23
|
+
email: "",
|
|
24
|
+
password: "",
|
|
25
|
+
confirm_password: "",
|
|
26
|
+
role: 2
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
mounted() {
|
|
31
|
+
this.getUser();
|
|
32
|
+
},
|
|
33
|
+
methods: {
|
|
34
|
+
getUser() {
|
|
35
|
+
/*
|
|
36
|
+
axios.get("/backend/users/").then(response => {
|
|
37
|
+
var data = response.data;
|
|
38
|
+
if(data.success) {
|
|
39
|
+
this.users = data.data;
|
|
40
|
+
} else {
|
|
41
|
+
console.error("Failed to fetch users:", data.message);
|
|
42
|
+
}
|
|
43
|
+
}).catch(error => {
|
|
44
|
+
console.log(error);
|
|
45
|
+
});
|
|
46
|
+
*/
|
|
47
|
+
},
|
|
48
|
+
save() {
|
|
49
|
+
// Here you would also make an API call to save the user to the server
|
|
50
|
+
},
|
|
51
|
+
cancel() {
|
|
52
|
+
window.history.back();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
app.mount(`#${elementId}`);
|
|
57
|
+
});
|
package/src/views/home.twig
CHANGED
package/src/views/sidebar.twig
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
{% block sidebar %}
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
{% if user.id > 0 %}
|
|
4
|
+
|
|
5
|
+
<!-- abilitare solo per utenti ADMIN -->
|
|
6
|
+
{% if cur_role != "admin" %}
|
|
7
|
+
<div class="menu-item">
|
|
8
|
+
<a href="/{{ root }}/users/manage">
|
|
9
|
+
<i class="fa-solid fa-users-between-lines"></i>
|
|
10
|
+
<span>{{ t('users.manage.title') }}</span>
|
|
11
|
+
</a>
|
|
12
|
+
</div>
|
|
13
|
+
{% endif %}
|
|
14
|
+
|
|
15
|
+
<div class="menu-item">
|
|
16
|
+
<a href="/{{ root }}/users/{{ cur_id }}">
|
|
17
|
+
<i class="fa-solid fa-id-badge"></i>
|
|
18
|
+
{{ t('users.profile.title') }}
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{% endif %}
|
|
9
23
|
|
|
10
|
-
<div class="menu-item">
|
|
11
|
-
<a href="/{{ root }}/users/profile">
|
|
12
|
-
<i class="fa-solid fa-id-badge"></i>
|
|
13
|
-
{{ t('users.profile.title') }}
|
|
14
|
-
</a>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
24
|
{% endblock %}
|
|
@@ -22,6 +22,77 @@
|
|
|
22
22
|
{% endif %}
|
|
23
23
|
</h2>
|
|
24
24
|
|
|
25
|
+
<form class="container mt-4" style="width:80%; margin-left:10%;">
|
|
26
|
+
<div class="row g-3">
|
|
27
|
+
|
|
28
|
+
<!-- Name -->
|
|
29
|
+
<div class="col-md-6">
|
|
30
|
+
<label for="name" class="form-label">{{ t('users.manage.name') }}</label>
|
|
31
|
+
<input v-model="user.name" type="text" class="form-control" id="name" placeholder="">
|
|
32
|
+
<div id="nameHelp" class="form-text"></div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<!-- Surname -->
|
|
36
|
+
<div class="col-md-6">
|
|
37
|
+
<label for="surname" class="form-label">{{ t('users.manage.surname') }}</label>
|
|
38
|
+
<input v-model="user.surname" type="text" class="form-control" id="surname" placeholder="">
|
|
39
|
+
<div id="surnameHelp" class="form-text"></div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<!-- Username -->
|
|
43
|
+
<div class="col-md-6">
|
|
44
|
+
<label for="username" class="form-label">{{ t('users.manage.username') }}</label>
|
|
45
|
+
<input v-model="user.username" type="text" class="form-control" id="username" placeholder="">
|
|
46
|
+
<div id="usernameHelp" class="form-text"></div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Email -->
|
|
50
|
+
<div class="col-md-6">
|
|
51
|
+
<label for="email" class="form-label">{{ t('users.manage.email') }}</label>
|
|
52
|
+
<input v-model="user.email" type="email" class="form-control" id="email" placeholder="">
|
|
53
|
+
<div id="emailHelp" class="form-text text-danger">
|
|
54
|
+
We'll never share your email with anyone else.
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Password -->
|
|
59
|
+
<div class="col-md-6">
|
|
60
|
+
<label for="password" class="form-label">{{ t('users.edit.password') }}</label>
|
|
61
|
+
<input v-model="user.password" type="password" class="form-control" id="password" placeholder="">
|
|
62
|
+
<div id="passwordHelp" class="form-text text-danger">
|
|
63
|
+
We'll never share your email with anyone else.
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Confirm Password -->
|
|
68
|
+
<div class="col-md-6">
|
|
69
|
+
<label for="password2" class="form-label">{{ t('users.edit.confirm_password') }}</label>
|
|
70
|
+
<input v-model="user.confirm_password" type="password" class="form-control" id="password2" placeholder="">
|
|
71
|
+
<div id="password2Help" class="form-text text-danger">
|
|
72
|
+
We'll never share your email with anyone else.
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<!-- Role -->
|
|
77
|
+
<div class="col-md-6">
|
|
78
|
+
<label for="role" class="form-label">Role</label>
|
|
79
|
+
<select v-model.number="user.role" id="role" class="form-select">
|
|
80
|
+
<option :value="0">{{ t('users.role.sudo') }}</option>
|
|
81
|
+
<option :value="1">{{ t('users.role.admin') }}</option>
|
|
82
|
+
<option :value="2">{{ t('users.role.editor') }}</option>
|
|
83
|
+
<option :value="3">{{ t('users.role.reader') }}</option>
|
|
84
|
+
</select>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Buttons -->
|
|
88
|
+
<div class="col-12 text-center mt-4">
|
|
89
|
+
<button @click="save()" type="submit" class="btn btn-primary me-2">{{ t('users.edit.save') }}</button>
|
|
90
|
+
<button @click="cancel()" type="button" class="btn btn-secondary">{{ t('users.edit.cancel') }}</button>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
</div>
|
|
94
|
+
</form>
|
|
95
|
+
|
|
25
96
|
</div>
|
|
26
97
|
|
|
27
98
|
{% endblock %}
|