@igea/oac_frontend 1.0.16 → 1.0.18

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.16",
3
+ "version": "1.0.18",
4
4
  "description": "Frontend service for the OAC project",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -17,7 +17,8 @@
17
17
  "role": "Role",
18
18
  "edit": "Edit",
19
19
  "delete": "Delete",
20
- "new": "New"
20
+ "new": "New",
21
+ "confirm_delete": "Are you sure you want to delete this user?"
21
22
  },
22
23
  "edit": {
23
24
  "title": "User",
@@ -26,7 +27,14 @@
26
27
  "password": "Password",
27
28
  "confirm_password": "Confirm password",
28
29
  "save": "Save",
29
- "cancel": "Cancel"
30
+ "cancel": "Cancel",
31
+ "invalid_name": "Invalid name",
32
+ "invalid_surname": "Invalid surname",
33
+ "invalid_username": "Invalid username",
34
+ "invalid_email": "Invalid email address",
35
+ "invalid_password": "Invalid password (must be at least 6 characters)",
36
+ "different_password": "Passwords do not match",
37
+ "save_ok": "Data saved successfully"
30
38
  },
31
39
  "profile": {
32
40
  "title": "Profile"
@@ -37,5 +45,14 @@
37
45
  "editor": "Editor",
38
46
  "reader": "Reader"
39
47
  }
48
+ },
49
+ "search": {
50
+ "fast": {
51
+ "title": "Fast search"
52
+ },
53
+ "advanced": {
54
+ "title": "Advanced search"
55
+ }
56
+
40
57
  }
41
58
  }
@@ -17,7 +17,8 @@
17
17
  "role": "Ruolo",
18
18
  "edit": "Modifica",
19
19
  "delete": "Elimina",
20
- "new": "Nuovo"
20
+ "new": "Nuovo",
21
+ "confirm_delete": "Sei sicuro di voler eliminare questo utente?"
21
22
  },
22
23
  "edit": {
23
24
  "title": "Utente",
@@ -26,7 +27,14 @@
26
27
  "password": "Password",
27
28
  "confirm_password": "Conferma password",
28
29
  "save": "Salva",
29
- "cancel": "Annulla"
30
+ "cancel": "Annulla",
31
+ "invalid_name": "Nome non valido",
32
+ "invalid_surname": "Cognome non valido",
33
+ "invalid_username": "Nome utente non valido",
34
+ "invalid_email": "Indirizzo email non valido",
35
+ "invalid_password": "Password non valida (deve contenere almeno 6 caratteri)",
36
+ "different_password": "Le password non corrispondono",
37
+ "save_ok": "Salvataggio dati eseguito correttamente"
30
38
  },
31
39
  "profile": {
32
40
  "title": "Profilo"
@@ -37,5 +45,14 @@
37
45
  "editor": "Editore",
38
46
  "reader": "Lettore"
39
47
  }
48
+ },
49
+ "search": {
50
+ "fast": {
51
+ "title": "Ricerca veloce"
52
+ },
53
+ "advanced": {
54
+ "title": "Ricerca avanzata"
55
+ }
56
+
40
57
  }
41
58
  }
@@ -6,12 +6,14 @@ class DataModel {
6
6
  this.options = options;
7
7
  }
8
8
 
9
- toJson(){
10
- return {
9
+ toJson(){
10
+ let json = {
11
11
  user: this.user,
12
12
  cur_id: this.user.id || 0,
13
13
  ...this.options
14
14
  };
15
+ console.log(json)
16
+ return json
15
17
  }
16
18
 
17
19
  }
@@ -31,7 +31,7 @@ html, body {
31
31
  display: flex;
32
32
  margin-top: 100px;
33
33
  margin-bottom: 80px;
34
- min-height: calc(100vh - 220px);
34
+ min-height: calc(100vh + 150px);
35
35
  overflow: auto;
36
36
  }
37
37
 
@@ -71,11 +71,18 @@ html, body {
71
71
  border-radius: 8px;
72
72
  }
73
73
 
74
-
75
74
  .main-content {
76
75
  flex: 1;
77
76
  padding: 1em;
78
77
  overflow-y: auto;
79
78
  }
80
79
 
80
+ .warning {
81
+ background: #f8d7da;
82
+ color: #721c24;
83
+ padding: 5px;
84
+ border-radius: 5px;
85
+ margin-bottom: 20px;
86
+ }
87
+
81
88
  /*# sourceMappingURL=style.css.map */
@@ -15,41 +15,101 @@ document.addEventListener('DOMContentLoaded', () => {
15
15
  role_admin: el.dataset.role_admin,
16
16
  role_editor: el.dataset.role_editor,
17
17
  role_reader: el.dataset.role_reader,
18
+ save_ok: el.dataset.save_ok
18
19
  },
19
20
  user: {
21
+ id: parseInt(el.dataset.user_id) || 0,
20
22
  name: "",
21
23
  surname: "",
22
24
  username: "",
23
25
  email: "",
26
+ mobile: "",
24
27
  password: "",
25
28
  confirm_password: "",
26
29
  role: 2
27
- }
30
+ }
28
31
  }
29
32
  },
30
33
  mounted() {
31
34
  this.getUser();
32
35
  },
36
+ computed:{
37
+ validator(){
38
+ let name = this.user.name.length > 0;
39
+ let surname = this.user.surname.length > 0;
40
+ let username = this.user.username.length > 0;
41
+ let email = this.user.email.length > 0 && this.user.email.includes("@");
42
+ let password = this.user.password.length >= 6 || (this.user.id > 0 && this.user.password.length == 0);
43
+ let confirm_password = this.user.password == this.user.confirm_password;
44
+ return {
45
+ name: name,
46
+ surname: surname,
47
+ username: username,
48
+ email: email,
49
+ password: password,
50
+ confirm_password: confirm_password
51
+ }
52
+ },
53
+ validForm(){
54
+ return this.validator.name && this.validator.surname && this.validator.username && this.validator.email && this.validator.password && this.validator.confirm_password;
55
+ }
56
+ },
33
57
  methods: {
34
58
  getUser() {
35
- /*
36
- axios.get("/backend/users/").then(response => {
59
+ if(this.user.id == 0) return;
60
+ axios.get("/backend/users/" + this.user.id).then(response => {
37
61
  var data = response.data;
38
62
  if(data.success) {
39
- this.users = data.data;
63
+ this.user = data.data;
64
+ this.user.password = "";
65
+ this.user.confirm_password = "";
40
66
  } else {
41
- console.error("Failed to fetch users:", data.message);
67
+ console.error("Failed to fetch user:", data.message);
42
68
  }
43
69
  }).catch(error => {
44
70
  console.log(error);
45
71
  });
46
- */
47
72
  },
48
73
  save() {
49
- // Here you would also make an API call to save the user to the server
74
+ if(!this.validForm) return;
75
+ let payload = {
76
+ id: this.user.id,
77
+ name: this.user.name,
78
+ surname: this.user.surname,
79
+ username: this.user.username,
80
+ email: this.user.email,
81
+ mobile: this.user.mobile,
82
+ role: this.user.role
83
+ };
84
+ if(this.user.password.length > 0)
85
+ payload["password"] = this.user.password;
86
+ let request;
87
+ if(this.user.id == 0) {
88
+ delete payload["id"];
89
+ request = axios.post("/backend/users", payload);
90
+ } else {
91
+ request = axios.put("/backend/users/" + this.user.id, payload);
92
+ }
93
+ request.then(response => {
94
+ var data = response.data;
95
+ if(data.success) {
96
+ alert(this.labels.save_ok);
97
+ if(document.referrer)
98
+ window.location.href = document.referrer;
99
+ else
100
+ window.history.back();
101
+ } else {
102
+ alert(data.message);
103
+ }
104
+ }).catch(error => {
105
+ alert(error);
106
+ });
50
107
  },
51
108
  cancel() {
52
- window.history.back();
109
+ if(document.referrer)
110
+ window.location.href = document.referrer;
111
+ else
112
+ window.history.back();
53
113
  }
54
114
  }
55
115
  });
@@ -11,11 +11,13 @@ document.addEventListener('DOMContentLoaded', () => {
11
11
  return {
12
12
  root: el.dataset.root,
13
13
  cur_id: parseInt(el.dataset.cur_id) || 0,
14
+ cur_role: parseInt(el.dataset.cur_role),
14
15
  labels: {
15
16
  role_sudo: el.dataset.role_sudo,
16
17
  role_admin: el.dataset.role_admin,
17
18
  role_editor: el.dataset.role_editor,
18
19
  role_reader: el.dataset.role_reader,
20
+ confirm_delete: el.dataset.confirm_delete
19
21
  },
20
22
  users: []
21
23
  }
@@ -28,7 +30,7 @@ document.addEventListener('DOMContentLoaded', () => {
28
30
  axios.get("/backend/users/").then(response => {
29
31
  var data = response.data;
30
32
  if(data.success) {
31
- this.users = data.data;
33
+ this.users = data.data.filter(u => u.role != 0 || this.cur_role == 0);
32
34
  } else {
33
35
  console.error("Failed to fetch users:", data.message);
34
36
  }
@@ -45,8 +47,17 @@ document.addEventListener('DOMContentLoaded', () => {
45
47
  return label;
46
48
  },
47
49
  deleteUser(userId) {
48
- // Here you would also make an API call to delete the user from the server
49
- this.users = this.users.filter(user => user.id !== userId);
50
+ if(!confirm(this.labels.confirm_delete)) return;
51
+ axios.delete("/backend/users/" + userId).then(response => {
52
+ var data = response.data;
53
+ if(data.success) {
54
+ this.users = this.users.filter(user => user.id !== userId);
55
+ } else {
56
+ console.error("Failed to fetch user:", data.message);
57
+ }
58
+ }).catch(error => {
59
+ console.log(error);
60
+ });
50
61
  },
51
62
  editUser(userId) {
52
63
  window.location.href = `/${this.root}/users/${userId}`;
@@ -1,24 +1,36 @@
1
1
  {% block sidebar %}
2
-
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
2
 
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') }}
3
+ <!-- abilitare solo per utenti ADMIN -->
4
+ {% if user.role == 0 or user.role == 1 %}
5
+ <div class="menu-item">
6
+ <a href="/{{ root }}/users/manage">
7
+ <i class="fa-solid fa-users-between-lines"></i>
8
+ <span>{{ t('users.manage.title') }}</span>
19
9
  </a>
20
10
  </div>
11
+ {% endif %}
21
12
 
13
+ {% if user.id > 0 %}
14
+ <div class="menu-item">
15
+ <a href="/{{ root }}/users/{{ cur_id }}">
16
+ <i class="fa-solid fa-id-badge"></i>
17
+ {{ t('users.profile.title') }}
18
+ </a>
19
+ </div>
22
20
  {% endif %}
23
21
 
22
+ <div class="menu-item">
23
+ <a href="/{{ root }}/search/fast">
24
+ <i class="fa-solid fa-magnifying-glass"></i>
25
+ {{ t('search.fast.title') }}
26
+ </a>
27
+ </div>
28
+
29
+ <div class="menu-item">
30
+ <a href="/{{ root }}/search/advanced">
31
+ <i class="fa-solid fa-magnifying-glass-dollar"></i>
32
+ {{ t('search.advanced.title') }}
33
+ </a>
34
+ </div>
35
+
24
36
  {% endblock %}
@@ -12,7 +12,9 @@
12
12
  data-role_sudo="{{ t('users.role.sudo') }}"
13
13
  data-role_admin="{{ t('users.role.admin') }}"
14
14
  data-role_editor="{{ t('users.role.editor') }}"
15
- data-role_reader="{{ t('users.role.reader') }}"
15
+ data-role_reader="{{ t('users.role.reader') }}"
16
+ data-user_id = "{{ id }}"
17
+ data-save_ok="{{ t('users.edit.save_ok') }}"
16
18
  >
17
19
  <h2 style="display:flex; justify-content:space-between; align-items:center;">
18
20
  {% if id == 0 %}
@@ -27,55 +29,67 @@
27
29
 
28
30
  <!-- Name -->
29
31
  <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>
32
+ <label for="name" class="form-label">{{ t('users.manage.name') }}:</label>
33
+ <input v-model="user.name" type="text" class="form-control" id="name" placeholder="">
34
+ <div v-if="!validator.name" id="nameHelp" class="form-text warning">
35
+ <i class="fa-solid fa-circle-exclamation"></i>
36
+ {{ t('users.edit.invalid_name') }}
37
+ </div>
33
38
  </div>
34
39
 
35
40
  <!-- Surname -->
36
41
  <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>
42
+ <label for="surname" class="form-label">{{ t('users.manage.surname') }}:</label>
43
+ <input v-model="user.surname" type="text" class="form-control" id="surname" placeholder="">
44
+ <div v-if="!validator.surname" id="surnameHelp" class="form-text warning">
45
+ <i class="fa-solid fa-circle-exclamation"></i>
46
+ {{ t('users.edit.invalid_surname') }}
47
+ </div>
40
48
  </div>
41
49
 
42
50
  <!-- Username -->
43
51
  <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>
52
+ <label for="username" class="form-label">{{ t('users.manage.username') }}:</label>
53
+ <input v-model="user.username" type="text" class="form-control" id="username" placeholder="">
54
+ <div v-if="!validator.username" id="usernameHelp" class="form-text warning">
55
+ <i class="fa-solid fa-circle-exclamation"></i>
56
+ {{ t('users.edit.invalid_username') }}
57
+ </div>
47
58
  </div>
48
59
 
49
60
  <!-- Email -->
50
61
  <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>
62
+ <label for="email" class="form-label">{{ t('users.manage.email') }}:</label>
63
+ <input v-model="user.email" type="email" class="form-control" id="email" placeholder="">
64
+ <div v-if="!validator.email" id="emailHelp" class="form-text warning">
65
+ <i class="fa-solid fa-circle-exclamation"></i>
66
+ {{ t('users.edit.invalid_email') }}
67
+ </div>
56
68
  </div>
57
69
 
58
70
  <!-- Password -->
59
71
  <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>
72
+ <label for="password" class="form-label">{{ t('users.edit.password') }}:</label>
73
+ <input v-model="user.password" type="password" class="form-control" id="password" placeholder="">
74
+ <div v-if="!validator.password" id="passwordHelp" class="form-text warning">
75
+ <i class="fa-solid fa-circle-exclamation"></i>
76
+ {{ t('users.edit.invalid_password') }}
77
+ </div>
65
78
  </div>
66
79
 
67
80
  <!-- Confirm Password -->
68
81
  <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>
82
+ <label for="password2" class="form-label">{{ t('users.edit.confirm_password') }}:</label>
83
+ <input v-model="user.confirm_password" type="password" class="form-control" id="password2" placeholder="">
84
+ <div v-if="!validator.confirm_password" id="password2Help" class="form-text warning">
85
+ <i class="fa-solid fa-circle-exclamation"></i>
86
+ {{ t('users.edit.different_password') }}
87
+ </div>
74
88
  </div>
75
89
 
76
90
  <!-- Role -->
77
91
  <div class="col-md-6">
78
- <label for="role" class="form-label">Role</label>
92
+ <label for="role" class="form-label">{{ t('users.manage.role') }}:</label>
79
93
  <select v-model.number="user.role" id="role" class="form-select">
80
94
  <option :value="0">{{ t('users.role.sudo') }}</option>
81
95
  <option :value="1">{{ t('users.role.admin') }}</option>
@@ -85,7 +99,7 @@
85
99
  </div>
86
100
 
87
101
  <!-- Buttons -->
88
- <div class="col-12 text-center mt-4">
102
+ <div v-if="validForm" class="col-12 text-center mt-4">
89
103
  <button @click="save()" type="submit" class="btn btn-primary me-2">{{ t('users.edit.save') }}</button>
90
104
  <button @click="cancel()" type="button" class="btn btn-secondary">{{ t('users.edit.cancel') }}</button>
91
105
  </div>
@@ -14,7 +14,9 @@
14
14
  data-role_admin="{{ t('users.role.admin') }}"
15
15
  data-role_editor="{{ t('users.role.editor') }}"
16
16
  data-role_reader="{{ t('users.role.reader') }}"
17
+ data-confirm_delete="{{ t('users.manage.confirm_delete') }}"
17
18
  data-cur_id="{{ cur_id }}"
19
+ data-cur_role="{{ user.role }}"
18
20
  >
19
21
  <h2 style="display:flex; justify-content:space-between; align-items:center;">
20
22
  <span>{{ t('users.manage.title') }}</span>