@igea/oac_frontend 1.0.13 → 1.0.15

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@igea/oac_frontend",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "Frontend service for the OAC project",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "homepage": "https://github.com/chpigea/oac_frontend#readme",
22
22
  "dependencies": {
23
- "@igea/oac_jwt_helpers": "1.0.6",
23
+ "@igea/oac_jwt_helpers": "1.0.10",
24
24
  "axios": "1.10.0",
25
25
  "cookie-parser": "1.4.7",
26
26
  "express": "5.1.0",
@@ -1,28 +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
- res.render('users/manage.twig', {
10
+ let data = new DataModel(req, {
11
11
  root: serviceName,
12
12
  title: 'User Management',
13
- users: [
14
- { id: 1, name: 'alice', role: 'admin' },
15
- { id: 2, name: 'bob', role: 'user' },
16
- { id: 3, name: 'charlie', role: 'user' },
17
- ]
18
- });
13
+ });
14
+ res.render('users/manage.twig', data.toJson());
19
15
  });
20
16
 
21
17
  /**
22
18
  * @route GET /users/:id: redirect to the user page with user details
23
19
  */
24
20
  router.get('/:id', (req, res) => {
25
-
21
+ let data = new DataModel(req, {
22
+ root: serviceName,
23
+ title: 'User Edit',
24
+ id: req.params.id
25
+ });
26
+ res.render('users/edit.twig', data.toJson());
26
27
  });
27
28
 
28
29
  /**
package/src/index.js CHANGED
@@ -78,7 +78,8 @@ getPort.default({
78
78
  res.render('login', { root: serviceName, title: 'Login' });
79
79
  });
80
80
  app.get(`/${serviceName}/home`, (req, res) => {
81
- res.render('home', { root: serviceName, title: 'Login' });
81
+ let user = req.user;
82
+ res.render('home', { root: serviceName, title: 'Login', cur_id: user.id || 0 });
82
83
  });
83
84
  // ---------------------------------------------------------------------
84
85
  // Start listing on the specified port
@@ -19,6 +19,15 @@
19
19
  "delete": "Delete",
20
20
  "new": "New"
21
21
  },
22
+ "edit": {
23
+ "title": "User",
24
+ "update": "Update",
25
+ "new": "New",
26
+ "password": "Password",
27
+ "confirm_password": "Confirm password",
28
+ "save": "Save",
29
+ "cancel": "Cancel"
30
+ },
22
31
  "profile": {
23
32
  "title": "Profile"
24
33
  },
@@ -19,6 +19,15 @@
19
19
  "delete": "Elimina",
20
20
  "new": "Nuovo"
21
21
  },
22
+ "edit": {
23
+ "title": "Utente",
24
+ "update": "Modifica",
25
+ "new": "Nuovo",
26
+ "password": "Password",
27
+ "confirm_password": "Conferma password",
28
+ "save": "Salva",
29
+ "cancel": "Annulla"
30
+ },
22
31
  "profile": {
23
32
  "title": "Profilo"
24
33
  },
@@ -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,49 @@
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
+ }
21
+ },
22
+ mounted() {
23
+ this.getUser();
24
+ },
25
+ methods: {
26
+ getUser() {
27
+ /*
28
+ axios.get("/backend/users/").then(response => {
29
+ var data = response.data;
30
+ if(data.success) {
31
+ this.users = data.data;
32
+ } else {
33
+ console.error("Failed to fetch users:", data.message);
34
+ }
35
+ }).catch(error => {
36
+ console.log(error);
37
+ });
38
+ */
39
+ },
40
+ save() {
41
+ // Here you would also make an API call to save the user to the server
42
+ },
43
+ cancel() {
44
+ window.history.back();
45
+ }
46
+ }
47
+ });
48
+ app.mount(`#${elementId}`);
49
+ });
@@ -10,6 +10,7 @@ document.addEventListener('DOMContentLoaded', () => {
10
10
  data() {
11
11
  return {
12
12
  root: el.dataset.root,
13
+ cur_id: parseInt(el.dataset.cur_id) || 0,
13
14
  labels: {
14
15
  role_sudo: el.dataset.role_sudo,
15
16
  role_admin: el.dataset.role_admin,
@@ -48,7 +49,10 @@ document.addEventListener('DOMContentLoaded', () => {
48
49
  this.users = this.users.filter(user => user.id !== userId);
49
50
  },
50
51
  editUser(userId) {
51
- window.location.href = `/${this.root}/users/edit/${userId}`;
52
+ window.location.href = `/${this.root}/users/${userId}`;
53
+ },
54
+ newUser() {
55
+ window.location.href = `/${this.root}/users/0`;
52
56
  }
53
57
  }
54
58
  });
@@ -1,8 +1,6 @@
1
1
  {% set showSidebar = true %}
2
2
  {% extends "base.twig" %}
3
3
 
4
-
5
-
6
4
  {% block content %}
7
5
  <h2>Home Page</h2>
8
6
  <p>{{ mainContent }}</p>
@@ -1,17 +1,24 @@
1
1
  {% block sidebar %}
2
2
 
3
- <div class="menu-item">
4
- <a href="/{{ root }}/users/manage">
5
- <i class="fa-solid fa-users-between-lines"></i>
6
- <span>{{ t('users.manage.title') }}</span>
7
- </a>
8
- </div>
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 %}
@@ -0,0 +1,98 @@
1
+ {% set showSidebar = true %}
2
+ {% extends "../base.twig" %}
3
+
4
+ {% block extendHead %}
5
+ <script src="/{{ root }}/js/app/vue-users-edit.js"></script>
6
+ {% endblock %}
7
+
8
+ {% block content %}
9
+
10
+ <div id="edit-user"
11
+ data-root="{{ root }}"
12
+ data-role_sudo="{{ t('users.role.sudo') }}"
13
+ data-role_admin="{{ t('users.role.admin') }}"
14
+ data-role_editor="{{ t('users.role.editor') }}"
15
+ data-role_reader="{{ t('users.role.reader') }}"
16
+ >
17
+ <h2 style="display:flex; justify-content:space-between; align-items:center;">
18
+ {% if id == 0 %}
19
+ <span>{{ t('users.edit.title') }}: {{ t('users.edit.new') }}</span>
20
+ {% else %}
21
+ <span>{{ t('users.edit.title') }} #{{id}}: {{ t('users.edit.update') }}</span>
22
+ {% endif %}
23
+ </h2>
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 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 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 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 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 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 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 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
+
96
+ </div>
97
+
98
+ {% endblock %}
@@ -8,45 +8,51 @@
8
8
 
9
9
  {% block content %}
10
10
 
11
- <h2 style="display:flex; justify-content:space-between; align-items:center;">
12
- <span>{{ t('users.manage.title') }}</span>
13
- <i style="color:gray; cursor:pointer; font-size:24px;"
14
- class="fa-solid fa-user-plus" title="{{ t('users.manage.new') }}"></i>
15
- </h2>
16
- <table id="manage-users" class="table"
11
+ <div id="manage-users"
17
12
  data-root="{{ root }}"
18
13
  data-role_sudo="{{ t('users.role.sudo') }}"
19
14
  data-role_admin="{{ t('users.role.admin') }}"
20
15
  data-role_editor="{{ t('users.role.editor') }}"
21
16
  data-role_reader="{{ t('users.role.reader') }}"
17
+ data-cur_id="{{ cur_id }}"
22
18
  >
23
- <thead>
24
- <tr>
25
- <td>#</td>
26
- <td>{{ t('users.manage.name') }}</td>
27
- <td>{{ t('users.manage.surname') }}</td>
28
- <td>{{ t('users.manage.username') }}</td>
29
- <td>{{ t('users.manage.email') }}</td>
30
- <td>{{ t('users.manage.role') }}</td>
31
- <td></td>
32
- <td></td>
33
- </tr>
34
- </thead>
35
- <tbody>
36
- <tr v-for="user in users">
37
- <td v-text="user.id"></td>
38
- <td v-text="user.name"></td>
39
- <td v-text="user.surname"></td>
40
- <td v-text="user.username"></td>
41
- <td v-text="user.email"></td>
42
- <td v-text="roleByCode(user.role)"></td>
43
- <td @click="editUser(user.id)"><i style="cursor:pointer; color:blue"
44
- class="fa-solid fa-pen-to-square" title="{{ t('users.manage.edit') }}"></i>
45
- </td>
46
- <td @click="deleteUser(user.id)"><i style="cursor:pointer; color:red"
47
- class="fa-solid fa-trash-can" title="{{ t('users.manage.delete') }}"></i>
48
- </td>
49
- </tr>
50
- </tbody>
51
- </table>
19
+ <h2 style="display:flex; justify-content:space-between; align-items:center;">
20
+ <span>{{ t('users.manage.title') }}</span>
21
+ <i @click="newUser()" style="color:gray; cursor:pointer; font-size:24px;"
22
+ class="fa-solid fa-user-plus" title="{{ t('users.manage.new') }}"></i>
23
+ </h2>
24
+ <table class="table">
25
+ <thead>
26
+ <tr>
27
+ <td>#</td>
28
+ <td>{{ t('users.manage.name') }}</td>
29
+ <td>{{ t('users.manage.surname') }}</td>
30
+ <td>{{ t('users.manage.username') }}</td>
31
+ <td>{{ t('users.manage.email') }}</td>
32
+ <td>{{ t('users.manage.role') }}</td>
33
+ <td></td>
34
+ <td></td>
35
+ </tr>
36
+ </thead>
37
+ <tbody>
38
+ <tr v-for="user in users">
39
+ <td v-text="user.id"></td>
40
+ <td v-text="user.name"></td>
41
+ <td v-text="user.surname"></td>
42
+ <td v-text="user.username"></td>
43
+ <td v-text="user.email"></td>
44
+ <td v-text="roleByCode(user.role)"></td>
45
+ <td @click="editUser(user.id)"><i style="cursor:pointer; color:blue"
46
+ class="fa-solid fa-pen-to-square" title="{{ t('users.manage.edit') }}"></i>
47
+ </td>
48
+ <td v-if="cur_id != user.id" @click="deleteUser(user.id)">
49
+ <i style="cursor:pointer; color:red"
50
+ class="fa-solid fa-trash-can" title="{{ t('users.manage.delete') }}">
51
+ </i>
52
+ </td>
53
+ <td v-else></td>
54
+ </tr>
55
+ </tbody>
56
+ </table>
57
+ </div>
52
58
  {% endblock %}