@cosla/sensemaking-web-ui 1.0.0

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.
Files changed (41) hide show
  1. package/README.md +35 -0
  2. package/angular.json +116 -0
  3. package/health_check.js +68 -0
  4. package/karma.conf.js +43 -0
  5. package/package.json +93 -0
  6. package/public/favicon.ico +0 -0
  7. package/server.ts +60 -0
  8. package/single-html-build.js +100 -0
  9. package/site-build.ts +54 -0
  10. package/src/app/app.component.html +1 -0
  11. package/src/app/app.component.scss +0 -0
  12. package/src/app/app.component.spec.ts +32 -0
  13. package/src/app/app.component.ts +21 -0
  14. package/src/app/app.config.server.ts +9 -0
  15. package/src/app/app.config.ts +19 -0
  16. package/src/app/app.routes.ts +8 -0
  17. package/src/app/components/dialog/dialog.component.html +15 -0
  18. package/src/app/components/dialog/dialog.component.scss +42 -0
  19. package/src/app/components/dialog/dialog.component.spec.ts +27 -0
  20. package/src/app/components/dialog/dialog.component.ts +40 -0
  21. package/src/app/components/sensemaking-chart-wrapper/sensemaking-chart-wrapper.component.ts +66 -0
  22. package/src/app/components/statement-card/statement-card.component.html +51 -0
  23. package/src/app/components/statement-card/statement-card.component.scss +134 -0
  24. package/src/app/components/statement-card/statement-card.component.spec.ts +23 -0
  25. package/src/app/components/statement-card/statement-card.component.ts +50 -0
  26. package/src/app/directives/custom-tooltip/custom-tooltip.directive.spec.ts +39 -0
  27. package/src/app/directives/custom-tooltip/custom-tooltip.directive.ts +89 -0
  28. package/src/app/models/report.model.ts +48 -0
  29. package/src/app/pages/report/report.component.html +363 -0
  30. package/src/app/pages/report/report.component.scss +600 -0
  31. package/src/app/pages/report/report.component.spec.ts +29 -0
  32. package/src/app/pages/report/report.component.ts +276 -0
  33. package/src/environments/environment.ts +5 -0
  34. package/src/index.html +17 -0
  35. package/src/main.server.ts +7 -0
  36. package/src/main.ts +5 -0
  37. package/src/style-vars.scss +40 -0
  38. package/src/styles.scss +23 -0
  39. package/tsconfig.app.json +19 -0
  40. package/tsconfig.json +32 -0
  41. package/tsconfig.spec.json +15 -0
@@ -0,0 +1,600 @@
1
+ @import "../../../style-vars";
2
+
3
+ @mixin breakdown-container {
4
+ background-color: $whisper;
5
+ border-radius: 13px;
6
+ padding: 13px 16px;
7
+ width: fit-content;
8
+ }
9
+
10
+ // style elements within <markdown> here
11
+ :host ::ng-deep markdown {
12
+ li:not(:first-child) {
13
+ margin-top: 20px;
14
+ }
15
+ }
16
+
17
+ :host ::ng-deep button {
18
+ font-family: $main-font;
19
+
20
+ &.icon-button-subtle.mdc-button--outlined {
21
+ border-color: $gray-nurse;
22
+ color: $cape-cod;
23
+ }
24
+
25
+ &.icon-button-main.mdc-button--outlined {
26
+ background-color: $black-squeeze;
27
+ border: none;
28
+ color: $cape-cod;
29
+ }
30
+
31
+ &[mat-flat-button], &[mat-stroked-button] {
32
+ mat-icon {
33
+ flex-shrink: 0;
34
+ }
35
+ }
36
+ }
37
+
38
+ .accordion-general ::ng-deep {
39
+ .mat-expansion-panel {
40
+ background-color: $white;
41
+ box-shadow: none;
42
+
43
+ &:not(:first-child) {
44
+ border-top: 1px solid $iron;
45
+ }
46
+
47
+ &:first-of-type, &:last-of-type {
48
+ border-radius: 0;
49
+ }
50
+
51
+ .mat-expansion-indicator svg {
52
+ fill: $shuttle-gray;
53
+ }
54
+
55
+ &.mat-expanded {
56
+ border-radius: 16px;
57
+ border-top: none;
58
+ box-shadow: 0px 1px 2px 0px rgba(60, 64, 67, 0.30), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
59
+ margin-bottom: 5px; // ensures box-shadow isn't eclipsed by neighboring accordion member
60
+
61
+ + .mat-expansion-panel {
62
+ border-top: none;
63
+ }
64
+ }
65
+ }
66
+
67
+ .mat-expansion-panel-body {
68
+ padding: 0;
69
+ }
70
+
71
+ .mat-expansion-panel-content {
72
+ // set baseline font for accordion "content"
73
+ font-family: $main-font;
74
+ letter-spacing: 0px;
75
+ }
76
+
77
+ .mat-expansion-panel-header {
78
+ // set baseline font for accordion "header"
79
+ font-family: $main-font;
80
+ height: 60px;
81
+ letter-spacing: 0px;
82
+ }
83
+ }
84
+
85
+ // custom styling for material accordion (for navigation)
86
+ .accordion-nav ::ng-deep {
87
+ mat-accordion {
88
+ display: flex;
89
+ flex-direction: column;
90
+ row-gap: 2px;
91
+ }
92
+
93
+ mat-expansion-panel.mat-expansion-panel {
94
+ border-radius: 4px;
95
+ box-shadow: none;
96
+
97
+ &:first-of-type {
98
+ border-top-left-radius: 30px;
99
+ border-top-right-radius: 30px;
100
+ }
101
+
102
+ &:last-of-type {
103
+ border-bottom-left-radius: 30px;
104
+ border-bottom-right-radius: 30px;
105
+ }
106
+ }
107
+
108
+ .mat-expansion-panel-body {
109
+ padding: 0;
110
+ }
111
+
112
+ .mat-expansion-panel-header {
113
+ background-color: $link-water-2;
114
+ padding-left: 14px;
115
+ padding-right: 22px;
116
+ height: 56px;
117
+ }
118
+ }
119
+
120
+ .breakdown {
121
+ display: flex;
122
+ align-items: center;
123
+ column-gap: 65px;
124
+ }
125
+
126
+ .breakdown-widget {
127
+ display: flex;
128
+ align-items: center;
129
+ column-gap: 12px;
130
+
131
+ .breakdown-data {
132
+ color: $cloud-burst;
133
+ letter-spacing: 0.1px;
134
+ }
135
+
136
+ .breakdown-icon {
137
+ background-color: $cloud-burst;
138
+ border-radius: 50%;
139
+ color: $white;
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ flex-shrink: 0;
144
+ height: 48px;
145
+ width: 48px;
146
+ }
147
+
148
+ .breakdown-number {
149
+ font-size: 20px;
150
+ font-weight: 600;
151
+ }
152
+
153
+ .breakdown-subject {
154
+ font-size: 14px;
155
+ font-weight: 500;
156
+ }
157
+ }
158
+
159
+ button.icon-button-fancy {
160
+ background-color: $hawkes-blue;
161
+ color: $mine-shaft-2;
162
+ font-size: 12px;
163
+ font-weight: 700;
164
+ height: 56px;
165
+ letter-spacing: 0.1px;
166
+ line-height: 1.33;
167
+ display: flex;
168
+ align-items: center;
169
+ justify-content: flex-start;
170
+ column-gap: 18px;
171
+ margin-bottom: 20px;
172
+ width: 100%;
173
+
174
+ mat-icon {
175
+ font-size: 24px;
176
+ height: 24px;
177
+ margin: 0;
178
+ width: 24px;
179
+ }
180
+ }
181
+
182
+ button[mat-icon-button] mat-icon {
183
+ transform: translateY(-2px);
184
+ }
185
+
186
+ .card {
187
+ background-color: $off-white;
188
+ border-radius: 16px;
189
+ margin-bottom: 22px;
190
+
191
+ .card-header {
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: space-between;
195
+ column-gap: 40px;
196
+ padding: 14px 30px;
197
+ }
198
+
199
+ .card-section {
200
+ border-top: 1px solid $white-lilac;
201
+ padding: 20px 30px;
202
+ }
203
+ }
204
+
205
+ .centered {
206
+ display: flex;
207
+ justify-content: center;
208
+ }
209
+
210
+ .drawer-close-button {
211
+ // shifting button position to account for empty space (padding) taken up by button
212
+ transform: translate(8px, -8px);
213
+ }
214
+
215
+ .drawer-header {
216
+ background-color: $link-water-2;
217
+ display: flex;
218
+ align-items: flex-start;
219
+ justify-content: space-between;
220
+ column-gap: 30px;
221
+ padding: 24px;
222
+ position: sticky;
223
+ top: 0;
224
+ }
225
+
226
+ .drawer-content {
227
+ display: flex;
228
+ flex-direction: column;
229
+ row-gap: 20px;
230
+ padding: 0 24px 24px 24px;
231
+ }
232
+
233
+ .drawer-statement-group {
234
+ h5 {
235
+ margin-bottom: 2px;
236
+ }
237
+
238
+ p {
239
+ color: $mine-shaft-2;
240
+ font-size: 12px;
241
+ letter-spacing: 0.1px;
242
+ line-height: 1.33;
243
+ }
244
+ }
245
+
246
+ .drawer-statement-list {
247
+ display: flex;
248
+ flex-direction: column;
249
+ row-gap: 6px;
250
+ margin-top: 12px;
251
+ }
252
+
253
+ h1 {
254
+ color: $shark;
255
+ font-size: 24px;
256
+ font-weight: 500;
257
+ line-height: 1.33;
258
+ }
259
+
260
+ h2 {
261
+ color: $shark;
262
+ font-size: 24px;
263
+ font-weight: 500;
264
+ line-height: 1.33;
265
+ }
266
+
267
+ h3 {
268
+ font-size: 22px;
269
+ line-height: 1.33;
270
+ }
271
+
272
+ h4 {
273
+ color: $shark;
274
+ font-size: 20px;
275
+ font-weight: 600;
276
+ line-height: 1.33;
277
+ }
278
+
279
+ h5 {
280
+ font-size: 12px;
281
+ font-weight: 500;
282
+ letter-spacing: 0.1px;
283
+ line-height: 1.33;
284
+ }
285
+
286
+ .heading-badge {
287
+ background-color: $hawkes-blue;
288
+ border-radius: 500px;
289
+ color: $cape-cod;
290
+ font-size: 22px;
291
+ line-height: 1.2;
292
+ padding: 11px 20px;
293
+ width: fit-content;
294
+ }
295
+
296
+ .heading-badge-wrapper {
297
+ padding: 18px 0 20px;
298
+ }
299
+
300
+ .icon-vote {
301
+ margin-bottom: 3px;
302
+ }
303
+
304
+ // custom styling for material button toggle group
305
+ mat-button-toggle-group.toggle-group {
306
+ border-color: $mystic;
307
+
308
+ mat-button-toggle {
309
+ border-color: $mystic;
310
+ color: $mine-shaft;
311
+
312
+ ::ng-deep .mat-button-toggle-button {
313
+ letter-spacing: 0.1px;
314
+ }
315
+
316
+ &.mat-button-toggle-checked {
317
+ background-color: $hawkes-blue;
318
+ color: $congress-blue;
319
+
320
+ // checkmark
321
+ ::ng-deep .mat-pseudo-checkbox::after {
322
+ color: $congress-blue;
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ mat-sidenav.drawer {
329
+ background-color: $link-water-2;
330
+ border-radius: 16px;
331
+ bottom: 10px;
332
+ right: 10px;
333
+ top: 10px;
334
+ width: 400px;
335
+ }
336
+
337
+ .nav {
338
+ flex-shrink: 0;
339
+ overflow-y: auto;
340
+ padding: 10px 10px 62px;
341
+ width: 300px;
342
+
343
+ .nav-item {
344
+ font-family: $main-font; // must be set here to overcome font from material component
345
+ display: flex;
346
+ align-items: center;
347
+ column-gap: 10px;
348
+ margin-right: 15px;
349
+ }
350
+
351
+ .nav-subitem {
352
+ background-color: $selago;
353
+ font-family: $main-font; // must be set here to overcome font from material component
354
+ display: flex;
355
+ align-items: center;
356
+ column-gap: 10px;
357
+ padding: 14px;
358
+ }
359
+
360
+ .nav-subtitle {
361
+ cursor: pointer;
362
+ font-size: 12px;
363
+ font-weight: 500;
364
+ letter-spacing: 0.1px;
365
+ line-height: 1.3;
366
+ }
367
+
368
+ .nav-title {
369
+ color: $mine-shaft-2;
370
+ font-size: 12px;
371
+ font-weight: 700;
372
+ letter-spacing: 0.1px;
373
+ line-height: 1.5;
374
+
375
+ &:hover {
376
+ text-decoration: underline;
377
+ }
378
+ }
379
+
380
+ .pill {
381
+ background-color: $link-water;
382
+ color: $cloud-burst;
383
+ letter-spacing: 0.1px;
384
+ }
385
+ }
386
+
387
+ .nav-label {
388
+ color: $cape-cod;
389
+ font-size: 11px;
390
+ font-weight: 700;
391
+ letter-spacing: 0.1px;
392
+ line-height: 1.33;
393
+ margin-bottom: 8px;
394
+ margin-left: 14px;
395
+ }
396
+
397
+ .overview-description {
398
+ margin-bottom: 30px;
399
+ margin-top: 20px;
400
+ text-align: center;
401
+ }
402
+
403
+ .overview-summary {
404
+ margin-bottom: 34px;
405
+ }
406
+
407
+ p {
408
+ font-size: 16px;
409
+ line-height: 1.5;
410
+ }
411
+
412
+ .paragraphs > p:not(:first-child) {
413
+ margin-top: 1.25em;
414
+ }
415
+
416
+ .pill {
417
+ border-radius: 500px;
418
+ font-size: 11px;
419
+ font-weight: 600;
420
+ line-height: 1.2;
421
+ min-width: 53px;
422
+ padding: 4px 11px;
423
+ text-align: center;
424
+ }
425
+
426
+ .report-content {
427
+ flex-grow: 1;
428
+ max-width: 1175px;
429
+ overflow-y: auto;
430
+ padding: 10px 0 40px;
431
+ }
432
+
433
+ .report-header {
434
+ display: flex;
435
+ align-items: center;
436
+ column-gap: 38px;
437
+ margin-bottom: 10px;
438
+ padding: 24px 30px;
439
+
440
+ .report-header-details {
441
+ flex-grow: 1;
442
+ }
443
+ }
444
+
445
+ .report-main {
446
+ display: flex;
447
+ column-gap: 26px;
448
+ flex-grow: 1;
449
+ overflow-y: hidden;
450
+ padding-left: 26px;
451
+ padding-right: 36px;
452
+ }
453
+
454
+ .report-page {
455
+ background-color: $link-water-3;
456
+ display: flex;
457
+ flex-direction: column;
458
+ height: 100vh;
459
+ }
460
+
461
+ .statement-card-group {
462
+ display: grid;
463
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
464
+ grid-auto-rows: 1fr;
465
+ gap: 12px;
466
+ }
467
+
468
+ .subtopic-breakdown {
469
+ @include breakdown-container;
470
+ display: flex;
471
+ align-items: center;
472
+ column-gap: 30px;
473
+ margin: 10px 0 44px;
474
+
475
+ .breakdown-divider {
476
+ align-self: stretch;
477
+ border-left: 1px solid $cloud-burst;
478
+ }
479
+
480
+ .subtopic-breakdown-description {
481
+ color: $cloud-burst;
482
+ font-size: 16px;
483
+ line-height: 1.5;
484
+ }
485
+ }
486
+
487
+ .subtopic-breakdown-item {
488
+ display: flex;
489
+ align-items: center;
490
+ column-gap: 7px;
491
+ flex-shrink: 0;
492
+
493
+ .pill {
494
+ background-color: $cloud-burst;
495
+ color: $white;
496
+ font-size: 14px;
497
+ }
498
+
499
+ .subtopic-breakdown-item-text {
500
+ color: $cloud-burst;
501
+ font-size: 16px;
502
+ font-weight: 500;
503
+ line-height: 1.2;
504
+ }
505
+ }
506
+
507
+ .subtopic-section {
508
+ padding: 40px 30px;
509
+
510
+ &:first-child {
511
+ padding-top: 0px;
512
+ }
513
+
514
+ &:not(:first-child) {
515
+ border-top: 1px solid $mystic-2;
516
+ }
517
+ }
518
+
519
+ .subtopic-section-description {
520
+ background-color: $concrete;
521
+ border-radius: 12px;
522
+ display: flex;
523
+ align-items: center;
524
+ column-gap: 10px;
525
+ max-width: fit-content;
526
+ padding: 12px 18px;
527
+
528
+ > mat-icon {
529
+ color: $cape-cod;
530
+ flex-shrink: 0;
531
+ }
532
+ }
533
+
534
+ .subtopic-section-summary {
535
+ margin: 8px 0 30px;
536
+
537
+ p {
538
+ color: $mine-shaft-2;
539
+ font-size: 14px;
540
+ line-height: 1.33;
541
+ letter-spacing: 0.1px;
542
+ }
543
+ }
544
+
545
+ .subtopic-themes-group {
546
+ margin-top: 25px;
547
+ }
548
+
549
+ .toggle-group-wrapper {
550
+ display: flex;
551
+ justify-content: center;
552
+ margin-top: 10px;
553
+ }
554
+
555
+ .tooltip-trigger {
556
+ text-decoration-line: underline;
557
+ text-decoration-style: dotted;
558
+ }
559
+
560
+ .topic-breakdown {
561
+ @include breakdown-container;
562
+ display: flex;
563
+ flex-wrap: wrap;
564
+ column-gap: 30px;
565
+ row-gap: 18px;
566
+ }
567
+
568
+ .topic-breakdown-item {
569
+ display: flex;
570
+ align-items: center;
571
+ column-gap: 7px;
572
+
573
+ .pill {
574
+ background-color: $cloud-burst;
575
+ color: $white;
576
+ font-size: 14px;
577
+ }
578
+
579
+ .topic-breakdown-item-text {
580
+ color: $cloud-burst;
581
+ font-size: 16px;
582
+ font-weight: 500;
583
+ line-height: 1.2;
584
+ }
585
+ }
586
+
587
+ .topic-breakdown-wrapper {
588
+ padding: 0 30px 15px;
589
+ }
590
+
591
+ @media screen and (max-width: 1000px) {
592
+ .report-main {
593
+ flex-direction: column;
594
+ overflow-y: visible;
595
+ }
596
+
597
+ .report-page {
598
+ height: auto;
599
+ }
600
+ }
@@ -0,0 +1,29 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
3
+ import { MarkdownModule, MarkdownService } from 'ngx-markdown';
4
+ import { ReportComponent } from './report.component';
5
+
6
+ describe('ReportComponent', () => {
7
+ let component: ReportComponent;
8
+ let fixture: ComponentFixture<ReportComponent>;
9
+
10
+ beforeEach(async () => {
11
+ await TestBed.configureTestingModule({
12
+ imports: [
13
+ MarkdownModule.forRoot(),
14
+ NoopAnimationsModule,
15
+ ReportComponent,
16
+ ],
17
+ providers: [MarkdownService]
18
+ })
19
+ .compileComponents();
20
+
21
+ fixture = TestBed.createComponent(ReportComponent);
22
+ component = fixture.componentInstance;
23
+ fixture.detectChanges();
24
+ });
25
+
26
+ it('should create', () => {
27
+ expect(component).toBeTruthy();
28
+ });
29
+ });