-
Notifications
You must be signed in to change notification settings - Fork 53
Participant import rework #6182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f57333f
efd249b
64c20cb
38966a5
a1643e7
15e9ffa
391d9a6
b472386
2047cf8
36004ec
c6eea21
4377152
9e7da3b
5dcb2c0
9903b03
9c50fd7
91dae4a
eca9b09
25789f2
f343c93
0d101c9
2361b05
2c5b73d
116e398
9b3efcf
aa0764d
1756142
f82fb3d
ebdfcd7
ec4402d
b0d8da1
c2f4836
ecb5a5f
0fb4ddb
b3ebeae
74e1b21
36b60b6
8d28b63
1979cd1
90ba0aa
e06dfde
c963e57
f682a20
78812f9
40625a3
b30df3f
9b388a7
b6186e3
d1b4db9
b012418
2dc19c7
46cbeba
80981a3
c320d07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,222 @@ | ||||||||||||||||||||||
| <os-head-bar [goBack]="false" [nav]="false"> | ||||||||||||||||||||||
| <div class="title-slot"> | ||||||||||||||||||||||
| <h1 class="mock-h2" translate>Import participants</h1> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| <ng-container class="menu-slot"> | ||||||||||||||||||||||
| <button mat-button [disabled]="uploadButton" (click)="importData(ImportDialog, ImportDialogSummary)"> | ||||||||||||||||||||||
| <span class="upper">Import</span> | ||||||||||||||||||||||
| </button> | ||||||||||||||||||||||
| </ng-container> | ||||||||||||||||||||||
| </os-head-bar> | ||||||||||||||||||||||
| <div class="static-sort-filter-bar"> | ||||||||||||||||||||||
| <os-view-list | ||||||||||||||||||||||
| [csvConfiguration]="csvConfiguration" | ||||||||||||||||||||||
| [csvReload]="importer" | ||||||||||||||||||||||
| [csvReloadButton]="csvReloadButton" | ||||||||||||||||||||||
| [filterProps]="filterProps" | ||||||||||||||||||||||
| [filterService]="filterService" | ||||||||||||||||||||||
| [horizontalScroll]="horizontalScroll" | ||||||||||||||||||||||
| [listObservable]="dataSource" | ||||||||||||||||||||||
| [searchFieldInput]="searchFieldInput" | ||||||||||||||||||||||
| [searchService]="searchService" | ||||||||||||||||||||||
| [shortenedSummary]="shortenSummary(summary)" | ||||||||||||||||||||||
| [showFilterBar]="showFilterBar" | ||||||||||||||||||||||
| [showHeader]="showHeader" | ||||||||||||||||||||||
| [totalCount]="_totalCountObservable | async" | ||||||||||||||||||||||
| [vScrollFixed]="50" | ||||||||||||||||||||||
| (searchFilterUpdated)="searchFilterUpdated.emit($event)" | ||||||||||||||||||||||
| (selectNewFile)="getCsvReload($event)" | ||||||||||||||||||||||
| (selectedColSepOutput)="onColSepChanged($event)" | ||||||||||||||||||||||
| (selectedEncodingOutput)="onEncodingChanged($event)" | ||||||||||||||||||||||
| (selectedTextSeparatorOutput)="onTextSeparatorChanged($event)" | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| @if (dataSource | async) { | ||||||||||||||||||||||
| @for (column of previewColumns; track column) { | ||||||||||||||||||||||
| <div | ||||||||||||||||||||||
| *osScrollingTableCell=" | ||||||||||||||||||||||
| column.property; | ||||||||||||||||||||||
| row as row; | ||||||||||||||||||||||
| definition as def; | ||||||||||||||||||||||
| isDefault: true; | ||||||||||||||||||||||
| config: getColumnConfig(column.property) | ||||||||||||||||||||||
| " | ||||||||||||||||||||||
| [class.error-icon]="containsError(row.data, def)" | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| @let entry = row.data; | ||||||||||||||||||||||
| @let type = column.type; | ||||||||||||||||||||||
| <div *osScrollingTableCellLabel>{{ getColumnLabel(column.property) }}</div> | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not translated |
||||||||||||||||||||||
| @if (entry && (entry[def] || type === 'boolean')) { | ||||||||||||||||||||||
| <div class="flex-vertical-center"> | ||||||||||||||||||||||
| @if (getHeader(def).is_list && entry[def]) { | ||||||||||||||||||||||
| @for (item of entry[def]; track item) { | ||||||||||||||||||||||
| @if (getHeader(def).is_object) { | ||||||||||||||||||||||
| <div> | ||||||||||||||||||||||
| @if (getHeader(def).type === 'string') { | ||||||||||||||||||||||
| {{ item.value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'number') { | ||||||||||||||||||||||
| {{ item.value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'date') { | ||||||||||||||||||||||
| {{ item.value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'boolean') { | ||||||||||||||||||||||
| <mat-checkbox disabled [checked]="item.value" /> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @if (getActionIconRow(item)) { | ||||||||||||||||||||||
| <mat-icon class="lower-margin-top" color="accent" inline> | ||||||||||||||||||||||
| {{ getEntryIcon(item) }} | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| } @else { | ||||||||||||||||||||||
| @if (getHeader(def).type === 'string') { | ||||||||||||||||||||||
| {{ item.value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'number') { | ||||||||||||||||||||||
| {{ item.value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'decimal') { | ||||||||||||||||||||||
| {{ this.getShortenedDecimal(entry[def].value) }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'date') { | ||||||||||||||||||||||
| {{ item.value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'boolean') { | ||||||||||||||||||||||
| <mat-checkbox disabled [checked]="item.value" /> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrap in span if possible. |
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (!getHeader(def).is_list && entry[def] !== undefined) { | ||||||||||||||||||||||
| @if (getHeader(def).is_object) { | ||||||||||||||||||||||
| @let icon = getActionIconEntry(entry[def]); | ||||||||||||||||||||||
| <div class="cell-wrapper"> | ||||||||||||||||||||||
| <div [class.email-cell]="getHeader(def).property === 'email'"> | ||||||||||||||||||||||
| @if (getHeader(def).type === 'string') { | ||||||||||||||||||||||
| {{ entry[def].value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'number') { | ||||||||||||||||||||||
| {{ entry[def].value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'decimal') { | ||||||||||||||||||||||
| {{ this.getShortenedDecimal(entry[def].value) }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'date') { | ||||||||||||||||||||||
| {{ entry[def].value }} | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (getHeader(def).type === 'boolean') { | ||||||||||||||||||||||
| <mat-checkbox disabled [checked]="entry[def].value" /> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| <div> | ||||||||||||||||||||||
| @if (getEntryIcon(entry[def]) || checkChanges(row, column.property)) { | ||||||||||||||||||||||
| <mat-icon | ||||||||||||||||||||||
| class="lower-margin-top" | ||||||||||||||||||||||
| inline | ||||||||||||||||||||||
| [class.error-icon]="icon === 'error_outline'" | ||||||||||||||||||||||
| [color]="icon !== 'error_outline' ? 'accent' : null" | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| {{ icon }} | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| <div | ||||||||||||||||||||||
| *osScrollingTableCell="'errors'; row as row; config: { width: 55, position: START_POSITION }" | ||||||||||||||||||||||
| class="flex-vertical-center icon-container" | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| <div *osScrollingTableCellLabel style="text-align: center; width: 100%">Action</div> | ||||||||||||||||||||||
| @if (row.state === 'error') { | ||||||||||||||||||||||
| <mat-icon class="red-warning-text" matTooltip="{{ getRowTooltip(row) }}" matTooltipPosition="right"> | ||||||||||||||||||||||
| {{ getActionIconRow(row) }} | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @if (row.state !== 'error' && row.messages.length) { | ||||||||||||||||||||||
| <mat-icon class="warn" matTooltip="{{ getWarningRowTooltip(row) }}" matTooltipPosition="right"> | ||||||||||||||||||||||
| warning | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| @let icon = getActionIconRow(row); | ||||||||||||||||||||||
| @if (row.state !== 'error' && icon !== '') { | ||||||||||||||||||||||
| <mat-icon | ||||||||||||||||||||||
| matTooltip="{{ getRowTooltip(row) }}" | ||||||||||||||||||||||
| matTooltipPosition="right" | ||||||||||||||||||||||
| [ngClass]="getColorIcon(row)" | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| {{ icon }} | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </os-view-list> | ||||||||||||||||||||||
| <!-- <footer class="footer"> | ||||||||||||||||||||||
| @let cols = shortenSummary(summary); | ||||||||||||||||||||||
| @for (col of cols; track col; let i = $index) { | ||||||||||||||||||||||
| @let colInfo = getSummaryInformation(col.name); | ||||||||||||||||||||||
| <mat-icon inline style="margin-top: 5px; font-size: x-large" [ngClass]="colInfo[1]"> | ||||||||||||||||||||||
| {{ colInfo[0] }} | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| <div style="margin-bottom: 8px"> {{ col.value }} {{ col.name }} </div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </footer> --> | ||||||||||||||||||||||
|
Comment on lines
+162
to
+171
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleanup
Suggested change
|
||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <ng-template #ImportDialog> | ||||||||||||||||||||||
| <div class="import-dialog"> | ||||||||||||||||||||||
| <h2 class="import-dialog-title" mat-dialog-title style="margin-bottom: 1em" translate> | ||||||||||||||||||||||
| Importing participants | ||||||||||||||||||||||
| </h2> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <mat-dialog-content class="import-dialog-content"> | ||||||||||||||||||||||
| <mat-spinner color="accent" diameter="100" strokeWidth="8"></mat-spinner> | ||||||||||||||||||||||
| <div class="import-status"> | ||||||||||||||||||||||
| <div class="import-status-title" translate>Import in progress!</div> | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Translation via attribute is deprecated. Please do not add new code using it.
Suggested change
|
||||||||||||||||||||||
| <div class="import-status-subtitle" translate> | ||||||||||||||||||||||
| Do not close the tab if you want to see the import status! | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </mat-dialog-content> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </ng-template> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <ng-template #ImportDialogSummary> | ||||||||||||||||||||||
| <div class="summary-dialog"> | ||||||||||||||||||||||
| <div cdk-focus-start class="summary-dialog-header"> | ||||||||||||||||||||||
| <h2 class="summary-dialog-title" mat-dialog-title translate>Import successful</h2> | ||||||||||||||||||||||
| <button class="close-button" mat-dialog-close mat-icon-button translate> | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing to translate in there
Suggested change
|
||||||||||||||||||||||
| <mat-icon>close</mat-icon> | ||||||||||||||||||||||
| </button> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| <h4 class="summary-dialog-subtitle">{{ summary[0]?.value }} participants have been processed</h4> | ||||||||||||||||||||||
| <div style="justify-content: center; margin-bottom: 22px"> | ||||||||||||||||||||||
| <mat-dialog-content class="summary-dialog-content"> | ||||||||||||||||||||||
| <div> | ||||||||||||||||||||||
| @let shortenedSummary = shortenSummary(summary); | ||||||||||||||||||||||
| @for (row of shortenedSummary; track row) { | ||||||||||||||||||||||
| @let colInfo = getSummaryInformation(row.name); | ||||||||||||||||||||||
| <div class="summary-row"> | ||||||||||||||||||||||
| <mat-icon inline [ngClass]="colInfo[1]"> | ||||||||||||||||||||||
| {{ colInfo[0] }} | ||||||||||||||||||||||
| </mat-icon> | ||||||||||||||||||||||
| <div class="summary-text">{{ row.value }} {{ row.name }}</div> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </mat-dialog-content> | ||||||||||||||||||||||
| @let extraInformation = summaryRest(summary); | ||||||||||||||||||||||
| @for (row of extraInformation; track row) { | ||||||||||||||||||||||
| <div class="summary-dialog-extraInfo">{{ row.value }} {{ row.name }}</div> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </ng-template> | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| $os-green: rgb(15, 228, 15); | ||
| $os-yellow: rgb(255, 193, 7); | ||
|
|
||
| .os-green { | ||
| color: $os-green; | ||
| } | ||
|
|
||
| .os-yellow { | ||
| color: $os-yellow; | ||
| } | ||
|
|
||
| .icon-container { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 10px; | ||
| width: 100%; | ||
| } | ||
|
|
||
| .error-icon { | ||
| color: red; | ||
| font-weight: 500; | ||
| } | ||
|
|
||
| .lower-margin-top { | ||
| margin-top: -4px; | ||
| padding-left: 2px; | ||
| } | ||
|
|
||
| .list-field-entry { | ||
| display: inline-flex; | ||
| margin-right: 10px; | ||
| } | ||
|
|
||
| .cell-wrapper { | ||
| display: flex; | ||
| align-items: center; | ||
| width: 100%; | ||
| max-width: 300px; | ||
| overflow: hidden; | ||
|
|
||
| .email-cell { | ||
| flex: 1 1 auto; | ||
| min-width: 0; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| } | ||
| } | ||
|
|
||
| .static-sort-filter-bar { | ||
| margin: 0; | ||
| height: 100%; | ||
| overflow: hidden; | ||
| } | ||
|
|
||
| .import-dialog { | ||
| padding: 8px; | ||
| color: var(--theme-accent-400); | ||
|
|
||
| .import-dialog-title { | ||
| color: var(--theme-accent-400); | ||
| font-size: 20px; | ||
| font-weight: 500; | ||
| margin-bottom: 0; | ||
| } | ||
|
|
||
| .import-dialog-content { | ||
| min-height: fit-content; | ||
| display: flex; | ||
| flex-direction: column; | ||
| justify-content: center; | ||
| align-items: center; | ||
| color: var(--theme-accent-400); | ||
| text-align: center; | ||
| } | ||
|
|
||
| .import-status { | ||
| margin-top: 32px; | ||
| color: var(--theme-accent-400); | ||
| } | ||
|
|
||
| .import-status-title { | ||
| font-size: 23px; | ||
| font-weight: 400; | ||
| margin-bottom: 12px; | ||
| } | ||
|
|
||
| .import-status-subtitle { | ||
| font-size: 18px; | ||
| } | ||
| } | ||
|
|
||
| .summary-dialog { | ||
| .summary-dialog-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| } | ||
|
|
||
| .close-button { | ||
| margin-right: 0.5em; | ||
| margin-top: 0.5em; | ||
| } | ||
|
|
||
| .summary-dialog-title { | ||
| font-size: 20px; | ||
| font-weight: 500; | ||
| margin: 0; | ||
| } | ||
|
|
||
| .summary-dialog-content { | ||
| display: flex; | ||
| font-size: 17px; | ||
| color: var(--theme-contrast-400); | ||
| text-align: center; | ||
| justify-content: center; | ||
| } | ||
|
|
||
| .summary-row { | ||
| display: flex; | ||
| justify-content: start; | ||
| gap: 10px; | ||
| margin: 6px 0; | ||
| } | ||
|
|
||
| .summary-row mat-icon { | ||
| font-size: x-large; | ||
| } | ||
|
|
||
| .summary-dialog-subtitle { | ||
| font-size: 18px; | ||
| margin-left: 1.4em; | ||
| margin-top: 0; | ||
| } | ||
|
|
||
| .summary-dialog-extraInfo { | ||
| font-size: 17px; | ||
| margin-left: 1.4em; | ||
| } | ||
|
|
||
| .summary-dialog-extraInfo:last-child { | ||
| margin-bottom: 16px; | ||
| } | ||
| } |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remarks regarding translations in the file are non exhaustive.