@chat21/chat21-ionic 3.4.32-rc1 → 3.4.32-rc10

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/CHANGELOG.md CHANGED
@@ -8,6 +8,46 @@
8
8
  ### **Copyrigth**:
9
9
  *Tiledesk SRL*
10
10
 
11
+ # 3.4.32-rc10
12
+ - **bug-fixed**: minor ui fix
13
+
14
+ # 3.4.32-rc9
15
+ - **added**: sidebar-user-details — MutationObserver to close dropdowns when user details panel is hidden (watches #user-details class); cleanup in ngOnDestroy to prevent memory leaks.
16
+ - **changed**: sidebar-user-details — refined closeDropdowns for better dropdown management when panel closes.
17
+ - **added**: sidebar-user-details — hover to open status dropdown; improved status dropdown positioning logic.
18
+ - **changed**: sidebar-user-details — flexbox layout (justify-content: space-between) for improved project item spacing.
19
+ - **changed**: sidebar-user-details — HTML structure for conditional rendering of teammate status images and titles; cleaned up unused SCSS.
20
+
21
+ # 3.4.32-rc8
22
+ - **bug-fixed**: sidebar-user-details — status dropdown not visible when clicking first/last project; moved outside #user-details container to avoid overflow clipping.
23
+ - **bug-fixed**: sidebar-user-details — replaced `transform` on #user-details with `left` animation to fix `position: fixed` containing block (dropdown positioning).
24
+ - **changed**: sidebar-user-details — projects_dropdown_container and status-dropdown now use same colors as ng-select teammate-status-in-drawer.
25
+ - **changed**: sidebar-user-details — projects-dropdown-wrapper styled to match ng-select container.
26
+ - **added**: sidebar-user-details — MPA feature flag in featuresToken: if MPA is true show projects_dropdown_container, else show availability_dropdown_container.
27
+ - **bug-fixed**: RouterModule.forRoot() called twice when clicking conversation — SharedModule now imports RouterModule.forChild([]) instead of AppRoutingModule.
28
+ - **changed**: FindPipe and FilterPipe moved from AppModule to SharedModule for app-wide availability.
29
+ - **added**: conversations-list — postMessage to hosting app on conversation selection (event: `onConversationChanged`, data: full conversation object).
30
+
31
+ # 3.4.32-rc7
32
+ - **addded**: ability to change availability status for each project the logged-in user in sidebar-user-detail
33
+
34
+ # 3.4.32-rc6
35
+ - **bug-fixed**: convertRequestToConversation timestamp wrong unit
36
+
37
+ # 3.4.32-rc5
38
+ - **added**: conversations-list — on init, fetches all projects via `getProjects` and stores them in AppStorageService under `all_projects`; before saving, checks that the key does not already contain each project (avoids duplicates).
39
+ - **changed**: conversations-list `onConversationLoaded` — project name and id are now resolved from the `all_projects` storage key instead of per-project localStorage entries.
40
+
41
+ # 3.4.32-rc4
42
+ - **changed**: unassigned conversations page — `onImageLoaded` and `onConversationLoaded` are now invoked for each conversation in the list (avatar URLs, last message formatting, project name).
43
+ - **bug-fixed**: navbar project dropdown — descenders (letters like g, p, q) were being clipped; added `line-height: 1.4` and vertical padding to prevent clipping.
44
+
45
+ # 3.4.32-rc3
46
+ - **bug-fixed**: unassigned conversations list was reset on each WebSocket subscription; conversations from other projects were lost when subscribing to multiple online projects. Added `skipClear` parameter to `subscriptionToWsConversations` so the list is cleared only once when subscribing to all online projects.
47
+ - **changed**: unassigned conversations empty state — centered the "no conversations" label both vertically and horizontally within the full viewport height.
48
+
49
+ # 3.4.32-rc2
50
+
11
51
  # 3.4.32-rc1
12
52
  - **added**: ability to change availability status for each project the logged-in user belongs to.
13
53
  - **changed**: unserved-request.page refactor html and ts refactor
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-ionic",
3
3
  "author": "Tiledesk SRL",
4
- "version": "3.4.32-rc1",
4
+ "version": "3.4.32-rc10",
5
5
  "license": "MIT License",
6
6
  "homepage": "https://tiledesk.com/",
7
7
  "repository": {
@@ -94,12 +94,18 @@ ion-navbar{
94
94
  overflow: hidden;
95
95
  text-overflow: ellipsis;
96
96
  font-family: var(--header-font-family);
97
-
97
+ line-height: 1.4;
98
+
98
99
  .material-icons{
99
100
  font-size: 20px;
100
101
  }
101
102
  }
102
103
 
104
+ button.btn.project-dropdown {
105
+ padding-top: 4px;
106
+ padding-bottom: 4px;
107
+ }
108
+
103
109
  li{
104
110
  position: relative;
105
111
  display: block
@@ -16,7 +16,6 @@ import { ConvertRequestToConversation } from 'src/chat21-core/utils/convertReque
16
16
  import { compareValues, getUserStatusFromProjectUser } from 'src/chat21-core/utils/utils';
17
17
  import { ProjectService } from 'src/app/services/projects/project.service';
18
18
  import { ProjectUser } from 'src/chat21-core/models/project_user';
19
- import { Project } from 'src/chat21-core/models/projects';
20
19
 
21
20
  @Component({
22
21
  selector: 'app-project-item',
@@ -71,7 +71,8 @@
71
71
  </span>
72
72
  </mat-slide-toggle> -->
73
73
 
74
- <ng-select style="text-align: left;"
74
+ <ng-container *ngIf="!isVisibleMPA" id="availability_dropdown_container">
75
+ <ng-select style="text-align: left;"
75
76
  (change)="changeAvailabilityStateInUserDetailsSidebar(selectedStatus)"
76
77
  [(ngModel)]="selectedStatus"
77
78
  class="teammate-status-in-drawer sidebar"
@@ -79,15 +80,43 @@
79
80
  bindLabel="name" bindValue="id"
80
81
  [clearable]="false"
81
82
  [searchable]="false">
82
- <ng-template ng-label-tmp let-item="item">
83
- <img style="width: 15px;height: 15px;position: relative; top: 1px;" height="15" width="15" [src]="item?.avatar" />
84
- <span id="sidebaravatar_{{item.name}}" style="text-transform: capitalize; margin-left:8px"> {{item.label | translate}} </span>
85
- </ng-template>
86
- <ng-template ng-option-tmp let-item="item" let-index="index">
87
- <img style="width: 15px;height: 15px;position: relative; top: 1px;" height="15" width="15" [src]="item?.avatar" />
88
- <span id="sidebaravatar_{{item.name}}" style="text-transform: capitalize; margin-left:8px"> {{item.label | translate}} </span>
89
- </ng-template>
90
- </ng-select>
83
+ <ng-template ng-label-tmp let-item="item">
84
+ <img style="width: 15px;height: 15px;position: relative; top: 1px;" height="15" width="15" [src]="item?.avatar" />
85
+ <span id="sidebaravatar_{{item.name}}" style="text-transform: capitalize; margin-left:8px"> {{item.label | translate}} </span>
86
+ </ng-template>
87
+ <ng-template ng-option-tmp let-item="item" let-index="index">
88
+ <img style="width: 15px;height: 15px;position: relative; top: 1px;" height="15" width="15" [src]="item?.avatar" />
89
+ <span id="sidebaravatar_{{item.name}}" style="text-transform: capitalize; margin-left:8px"> {{item.label | translate}} </span>
90
+ </ng-template>
91
+ </ng-select>
92
+ </ng-container>
93
+
94
+ <ng-container *ngIf="isVisibleMPA && projects?.length > 0" id="projects_dropdown_container">
95
+ <div class="projects-dropdown-wrapper">
96
+ <button class="btn projects-dropdown-toggle" (click)="toggleProjectsDropdown()">
97
+ <span class="projects-dropdown-toggle-label">
98
+ {{ project?.name || 'Progetti' }}
99
+ <img *ngIf="project?.teammateStatus" style="width: 15px; height: 15px; position: relative; top: 1px; cursor: pointer;" height="15" width="15" [src]="project?.teammateStatus?.avatar" />
100
+ </span>
101
+ <i class="material-icons" style="margin-left: 4px; font-size: 18px;">arrow_drop_down</i>
102
+ </button>
103
+ <div id="projects_dropdown" class="dropdown-menu" [ngClass]="{'open': openDropdownProjects}">
104
+ <li *ngFor="let prjct of projects?.slice() | slice:0:10; let i=index" style="cursor: pointer"
105
+ (mouseenter)="openStatusDropdownOnHover($event, prjct)"
106
+ (mouseleave)="closeStatusDropdownOnLeave()">
107
+ <a [ngClass]="{'li-selected' : prjct?.id_project?._id === openStatusDropdownProjectId }"
108
+ class="project-item-row">
109
+ <span class="project-item-name">{{ prjct?.id_project?.name }}</span>
110
+ <span class="project-item-status project-item-status-wrapper"
111
+ [attr.title]="prjct?.teammateStatus?.name">
112
+ <span class="project-item-status-name">{{prjct?.teammateStatus?.name}}</span>
113
+ <img [src]="prjct?.teammateStatus?.avatar" />
114
+ </span>
115
+ </a>
116
+ </li>
117
+ </div>
118
+ </div>
119
+ </ng-container>
91
120
  </section>
92
121
 
93
122
  <hr class="first-divider">
@@ -140,4 +169,16 @@
140
169
  <div class="chat-version"> ver {{version}}</div>
141
170
  </section>
142
171
 
172
+ </div>
173
+
174
+ <!-- Status dropdown fuori da #user-details per evitare clipping da overflow -->
175
+ <div class="status-dropdown status-dropdown-fixed status-dropdown-outside" *ngIf="openStatusDropdownProjectId && selectedProjectForStatus"
176
+ [style.top.px]="statusDropdownPosition.top" [style.left.px]="statusDropdownPosition.left"
177
+ (mouseenter)="cancelStatusDropdownClose()"
178
+ (mouseleave)="closeStatusDropdownOnLeave()">
179
+ <div class="status-dropdown-option" *ngFor="let status of TEAMMATE_STATUS"
180
+ (click)="$event.stopPropagation(); onChangeProjectStatus(selectedProjectForStatus, status.id)">
181
+ <img style="width: 15px; height: 15px; margin-right: 6px;" [src]="status.avatar" />
182
+ <span>{{ status.name }}</span>
183
+ </div>
143
184
  </div>
@@ -2,23 +2,13 @@
2
2
  #user-details {
3
3
  background-color: var(--sidebar-background-color);
4
4
  color: var(--sidebar-color);
5
- // height: calc(100% - 60px);
6
5
  height: 100%;
7
6
  overflow-y: auto;
8
7
  padding: 16px 12px 32px;
9
8
  position: absolute;
10
- // left: -60px;
11
- // top: 60px;
12
- // top: 0px;
13
- // transform: translate(305px);
14
- // transform: translate(60px);
15
- transition: transform 0.5s;
9
+ transition: left 0.5s;
16
10
  width: 305px;
17
11
  left: -245px;
18
- // z-index: 1029;
19
- // transform: translateX(-100%);
20
- // -webkit-transform: translateX(-100%);
21
- // display: none;
22
12
  }
23
13
 
24
14
  // #user-details::-webkit-scrollbar {
@@ -33,11 +23,8 @@
33
23
  // }
34
24
 
35
25
  #user-details.active {
36
- // transform: translate(0);
37
- transform: translate(60px);
38
26
  display: block;
39
- // left: 0px;
40
- left: 10px;
27
+ left: 70px; /* 10px + 60px (equivalente a transform: translate(60px)) - evita containing block per position: fixed */
41
28
  }
42
29
 
43
30
  .user-details-btn-close {
@@ -175,15 +162,315 @@
175
162
  .availability-section {
176
163
  top: 320px;
177
164
  text-align: center;
178
- background-color: var(--user-detail-select-background);
165
+ background-color: var(--sidebar-user-detail-select-background);
179
166
  padding: 4px 0px;
180
- width: 192px;
181
167
  border-radius: 4px;
168
+ // width: 192px;
182
169
  -webkit-transform: translateX(-50%);
183
170
  transform: translateX(-50%);
184
171
  left: 50%;
185
172
  margin: auto;
186
173
  position: absolute;
174
+ font-size: 14px;
175
+ z-index: 2;
176
+
177
+ .btn{
178
+ display: flex;
179
+ position: relative;
180
+ flex-flow: row nowrap;
181
+ align-items: center;
182
+ justify-content: center;
183
+
184
+ border: 1px solid transparent;
185
+ transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
186
+ margin: 0px;
187
+ box-shadow: none;
188
+ }
189
+
190
+ .dropdown-toggle{
191
+ background-color: transparent;
192
+ color: inherit;
193
+ padding: 0px 15px;
194
+ }
195
+
196
+ .project-dropdown,
197
+ .projects-dropdown-toggle {
198
+ // max-width: 180px;
199
+ white-space: nowrap;
200
+ overflow: hidden;
201
+ text-overflow: ellipsis;
202
+ font-family: var(--header-font-family);
203
+
204
+ .material-icons{
205
+ font-size: 20px;
206
+ }
207
+ }
208
+
209
+ button.btn.project-dropdown,
210
+ button.btn.projects-dropdown-toggle {
211
+ padding-top: 4px;
212
+ padding-bottom: 4px;
213
+ background-color: var(--sidebar-user-detail-select-background);
214
+ color: var(--sidebar-user-detail-select-color);
215
+ border: 1px solid var(--sidebar-user-detail-select-background);
216
+ }
217
+
218
+ .teammate-status-in-drawer {
219
+ width: 190px;
220
+ }
221
+
222
+ /* projects-dropdown-wrapper - stile come ng-select .ng-select-container (teammate-status-in-drawer) */
223
+ .projects-dropdown-wrapper {
224
+ position: relative;
225
+ min-height: 36px;
226
+ padding: 6px 12px;
227
+ background-color: var(--sidebar-user-detail-select-background);
228
+ color: var(--sidebar-user-detail-select-color);
229
+ border: 1px solid var(--sidebar-user-detail-select-background);
230
+ border-radius: 4px;
231
+ display: flex;
232
+ align-items: center;
233
+ text-align: left;
234
+ font-size: 14px;
235
+ line-height: 1.4;
236
+ width: 250px;
237
+
238
+ .projects-dropdown-toggle {
239
+ background-color: transparent !important;
240
+ border: none !important;
241
+ padding: 0 !important;
242
+ min-height: auto;
243
+ flex: 1;
244
+ justify-content: space-between;
245
+ color: inherit;
246
+ font-size: inherit;
247
+ }
248
+
249
+ .projects-dropdown-toggle-label {
250
+ text-transform: capitalize;
251
+ overflow: hidden;
252
+ text-overflow: ellipsis;
253
+ white-space: nowrap;
254
+ display: flex;
255
+ align-items: center;
256
+ gap: 8px;
257
+ }
258
+
259
+ .dropdown-menu {
260
+ left: 0;
261
+ right: 0;
262
+ min-width: 100%;
263
+ }
264
+ }
265
+
266
+ li{
267
+ position: relative;
268
+ display: block
269
+ }
270
+
271
+ /* projects_dropdown - stessi colori ng-select (.ng-dropdown-panel) */
272
+ .dropdown-menu {
273
+ border-radius: 4px;
274
+ border: 1px solid var(--sidebar-user-detail-select-background);
275
+ box-shadow: 0 2px 5px 0 rgb(0, 0, 0, 0.26);
276
+
277
+ position: absolute;
278
+ top: 100%;
279
+ right: 0;
280
+ left: auto;
281
+ z-index: 1000;
282
+ display: none;
283
+ float: left;
284
+ min-width: 160px;
285
+ padding: 5px 0;
286
+ margin: 8px 0 0;
287
+ font-size: 14px;
288
+ text-align: left;
289
+ list-style: none;
290
+ background-color: var(--sidebar-user-detail-select-background);
291
+ -webkit-background-clip: padding-box;
292
+ background-clip: padding-box;
293
+ color: var(--sidebar-user-detail-select-color);
294
+ max-height: 250px;
295
+ overflow-y: auto;
296
+ }
297
+
298
+ .dropdown-menu:not(.open){
299
+ margin-top: -20px;
300
+ opacity: 0;
301
+ visibility: hidden;
302
+ display: block;
303
+ }
304
+
305
+ .dropdown-menu.open{
306
+ margin-top: 12px; //0;
307
+ opacity: 1;
308
+ visibility: visible;
309
+ display: block;
310
+ transition: all 150ms linear;
311
+ }
312
+
313
+ .dropdown-menu li {
314
+ position: relative;
315
+
316
+ .li-selected{
317
+ color: var(--sidebar-user-detail-select-color);
318
+ background-color: var(--sidebar-user-detail-select-hover-background);
319
+ }
320
+
321
+ &.section-title{
322
+ padding-left: 24px;
323
+ font-size: 12px;
324
+ color: var(--sidebar-user-detail-color);
325
+ font-weight: 400
326
+ }
327
+ }
328
+
329
+ .dropdown-menu li>a{
330
+ font-size: 13px;
331
+ padding: 10px 12px;
332
+ border-radius: 2px;
333
+ transition: all 150ms linear;
334
+
335
+ display: block;
336
+ clear: both;
337
+ font-weight: 400;
338
+ line-height: 1.42857143;
339
+ color: var(--sidebar-user-detail-select-color);
340
+ white-space: nowrap;
341
+ text-decoration: none;
342
+ margin: 0px;
343
+ cursor: auto;
344
+
345
+ img {
346
+ width: 15px;
347
+ height: 15px;
348
+ position: relative;
349
+ top: 1px;
350
+ }
351
+ .material-icons {
352
+ vertical-align: middle;
353
+ }
354
+
355
+ &:hover{
356
+ background-color: var(--sidebar-user-detail-select-hover-background);
357
+ color: var(--sidebar-user-detail-select-color);
358
+ box-shadow: none;
359
+ }
360
+
361
+ &.project-item-row {
362
+ display: flex;
363
+ align-items: center;
364
+ justify-content: space-between;
365
+ gap: 8px;
366
+
367
+ .project-item-name {
368
+ flex: 1;
369
+ min-width: 0;
370
+ text-align: left;
371
+ overflow: hidden;
372
+ text-overflow: ellipsis;
373
+ }
374
+
375
+ .project-item-status {
376
+ cursor: pointer;
377
+ flex: 0 0 10%;
378
+ display: flex;
379
+ justify-content: flex-end;
380
+ align-items: center;
381
+
382
+ &.project-item-status-wrapper {
383
+ position: relative;
384
+
385
+ .project-item-status-name {
386
+ margin-right: 4px;
387
+ color: #a9afbb;
388
+ font-size: 9px;
389
+
390
+ }
391
+ }
392
+
393
+ .status-dropdown {
394
+ position: absolute;
395
+ right: 100%;
396
+ top: 50%;
397
+ transform: translateY(-50%);
398
+ margin-right: 4px;
399
+ min-width: 140px;
400
+ padding: 4px 0;
401
+ background-color: var(--sidebar-user-detail-select-background);
402
+ border: 1px solid var(--sidebar-user-detail-select-background);
403
+ border-radius: 4px;
404
+ box-shadow: 0 2px 5px 0 rgb(0, 0, 0, 0.26);
405
+ z-index: 1001;
406
+ list-style: none;
407
+
408
+ &.status-dropdown-fixed {
409
+ right: auto;
410
+ left: auto;
411
+ margin-right: 0;
412
+ transform: translateY(-50%);
413
+ }
414
+
415
+ .status-dropdown-option {
416
+ display: flex;
417
+ align-items: center;
418
+ padding: 8px 16px;
419
+ font-size: 13px;
420
+ color: var(--sidebar-user-detail-select-color);
421
+ cursor: pointer;
422
+ white-space: nowrap;
423
+
424
+ &:hover {
425
+ background-color: var(--sidebar-user-detail-select-hover-background);
426
+ color: var(--sidebar-user-detail-select-color);
427
+ }
428
+ }
429
+ }
430
+ }
431
+ }
432
+ }
433
+ }
434
+
435
+ /* Status dropdown fuori da #user-details - stessi colori ng-select */
436
+ .status-dropdown-outside {
437
+ position: fixed !important;
438
+ z-index: 1100;
439
+ min-width: 140px;
440
+ padding: 4px 0;
441
+ background-color: var(--sidebar-user-detail-select-background);
442
+ border: 1px solid var(--sidebar-user-detail-select-background);
443
+ border-radius: 4px;
444
+ box-shadow: 0 2px 5px 0 rgb(0, 0, 0, 0.26);
445
+ list-style: none;
446
+
447
+ /* Triangolino in alto a sinistra, fuori dal container, con leggero gap in basso */
448
+ &::before {
449
+ content: '';
450
+ position: absolute;
451
+ left: -7px;
452
+ top: 10px;
453
+ width: 0;
454
+ height: 0;
455
+ border-top: 7px solid transparent;
456
+ border-bottom: 7px solid transparent;
457
+ border-right: 7px solid var(--sidebar-user-detail-select-background);
458
+ }
459
+
460
+ .status-dropdown-option {
461
+ display: flex;
462
+ align-items: center;
463
+ padding: 8px 16px;
464
+ font-size: 13px;
465
+ color: var(--sidebar-user-detail-select-color);
466
+ cursor: pointer;
467
+ white-space: nowrap;
468
+
469
+ &:hover {
470
+ background-color: var(--sidebar-user-detail-select-hover-background);
471
+ color: var(--sidebar-user-detail-select-color);
472
+ }
473
+ }
187
474
  }
188
475
 
189
476
  .first-divider {