Skip to content

Commit

Permalink
Merge pull request #84 from oatear/feature/table-stats
Browse files Browse the repository at this point in the history
Feature/table stats
  • Loading branch information
hristoiankov committed Jul 22, 2023
2 parents d51dc33 + 8939a4c commit a207696
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 1 deletion.
2 changes: 1 addition & 1 deletion cider-app/src/app/cards/cards.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<app-page-header header="Cards" subheader="List of all the cards in the deck"></app-page-header>
<app-cards-tab-menu></app-cards-tab-menu>
<p-card styleClass="page-card tabbed-card">
<app-entity-table [service]="cardsService" [allowImportExport]="true"></app-entity-table>
<app-entity-table [service]="cardsService" [allowImportExport]="true" [showStats]="true"></app-entity-table>
</p-card>
36 changes: 36 additions & 0 deletions cider-app/src/app/entity-table/entity-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
<button pButton pRipple label="Clear" icon="pi pi-filter-slash" class="p-button p-mr-2" (click)="clear(dt)"></button>
<button *ngIf="allowEditing && showActions" pButton pRipple label="New" icon="pi pi-plus" class="p-button p-mr-2" (click)="openCreateNew()"></button>
<div class="p-ml-auto">
<ng-container *ngIf="showStats">
<button pButton pRipple label="" icon="pi pi-percentage" class="p-button-info p-mr-2"
pTooltip="Show token stats" (click)="openStatsDialog()"></button>
</ng-container>
<ng-container *ngIf="allowImportExport">
<button pButton pRipple label="" icon="pi pi-upload" class="p-button-success p-mr-2"
pTooltip="Import data" (click)="openImportDialog()"></button>
Expand Down Expand Up @@ -190,3 +194,35 @@
<button pButton pRipple label="Import" icon="pi pi-check" class="p-button-text" (click)="confirmImport(dt)"></button>
</ng-template>
</p-dialog>
<p-dialog [header]="'Token Stats (Top ' + statsTopX + ')'" [(visible)]="statsVisible" [style]="{width: '50%'}"
[modal]="true" class="stats-dialog">
<ng-template pTemplate="content">
<div class="token-stats token-table">
<div class="token-row token-header">
<div class="field">Field</div>
<div>Token</div>
<div>Count</div>
<div>Copy Count</div>
</div>
<ng-container *ngFor="let stat of stats">
<div class="token-row">
<div class="field"><h3>{{stat.header}}</h3></div>
<div class="token"></div>
<div></div>
<div></div>
</div>
<ng-container *ngFor="let token of stat.tokens">
<div class="token-row">
<div class="field"></div>
<div class="token"><span>{{token.token}}</span></div>
<div>{{token.count}}</div>
<div>{{token.copiesCount}}</div>
</div>
</ng-container>
</ng-container>
</div>
</ng-template>
<ng-template pTemplate="footer">
<button pButton pRipple label="Cancel" icon="pi pi-times" class="p-button-text" (click)="closeStatsDialog()"></button>
</ng-template>
</p-dialog>
41 changes: 41 additions & 0 deletions cider-app/src/app/entity-table/entity-table.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,45 @@
:host ::ng-deep .p-datatable .p-datatable-tbody > tr.p-highlight {
background: var(--surface-d);
color: var(--text-color);
}

:host ::ng-deep .stats-dialog .p-dialog-content {
padding-top: 0;

}

.token-stats.token-table {
display: table;
width: 100%;
.token-row {
display: table-row;
&.token-header {
color: #5c7089;
top: 0;
position: sticky;
background-color: #2b313d;
& > div {
padding-top: 1rem;
padding-bottom: 1rem;
}
}
& > div {
display: table-cell;
padding-left: 5px;
padding-right: 5px;
max-width: 200px;
h3 {
color: #5c7089;
}
span {
background-color: #333e4d;
border-radius: 10px;
padding: 2px;
padding-left: 7px;
padding-right: 7px;
margin: 1px;
display: inline-block;
}
}
}
}
55 changes: 55 additions & 0 deletions cider-app/src/app/entity-table/entity-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { FieldType } from '../data-services/types/field-type.type';
import { SortDirection } from '../data-services/types/search-sort.type';
import XlsxUtils from '../shared/utils/xlsx-utils';
import { Subject, debounceTime } from 'rxjs';
import { TableStat, TokenStat } from './table-stat.type';

@Component({
selector: 'app-entity-table',
Expand All @@ -27,6 +28,7 @@ export class EntityTableComponent<Entity, Identifier extends string | number> im
@Input() lazy: boolean = true;
@Input() showActions: boolean = true;
@Input() showInlineEditor: boolean = true;
@Input() showStats: boolean = false;
@Input() saveToService: boolean = true;
@Output() selectionChange: EventEmitter<Entity | Entity[] | undefined> = new EventEmitter<Entity | Entity[] | undefined>();
FieldType = FieldType;
Expand All @@ -37,6 +39,9 @@ export class EntityTableComponent<Entity, Identifier extends string | number> im
idField?: string;
lookups: Map<EntityService<any, string | number>, Map<string | number, string>> = new Map();
importVisible: boolean = false;
statsVisible: boolean = false;
stats: TableStat[] = [];
statsTopX: number = 20;
importFile: File | undefined = undefined;
saveSubject: Subject<Entity> = new Subject();
optionsCache: Map<EntityService<any, string | number>, any[]>;
Expand Down Expand Up @@ -150,6 +155,56 @@ export class EntityTableComponent<Entity, Identifier extends string | number> im
});
}

public openStatsDialog() {
// calculate the stats
//
// field-name:
// token-name token-count token-copies-count
// token-name-2 token-count-2 token-copies-count-2
// ...
// ...
//
// text = 'text',
// textArea = 'text-area',
// number = 'number',
// file = 'file',
// option = 'option',
// optionList = 'optionList'
//
const stats = this.columns.filter(column => !column.hidden).map(column => {
const tokenStats = new Map<string, TokenStat>();
this.records.forEach(record => {
const copies = (record as any)['count'] || 1;
const value = record[column.field];
if (value) {
const strValue = '' + value;
strValue.replace(/[<][^>]*[>]|["'.,]/g, '').split(/ |\n|\r/).filter(str => str).forEach(token => {
const tokenStat = tokenStats.get(token);
if (tokenStat) {
tokenStats.set(token,
{token: token, count: tokenStat.count + 1,
copiesCount: tokenStat.copiesCount + copies} as TokenStat);
} else if (tokenStats.size < this.statsTopX) {
tokenStats.set(token,
{token: token, count: 1, copiesCount: copies} as TokenStat);
}
});
}
});
const tokens = Array.from(tokenStats.values()).sort((a, b) => b.count - a.count);
return {
header: column.header,
tokens: tokens
} as TableStat;
});
this.stats = stats;
this.statsVisible = true;
}

public closeStatsDialog() {
this.statsVisible = false;
}

public openCreateNew() {
this.entity = {} as Entity;
this.dialogVisible = true;
Expand Down
19 changes: 19 additions & 0 deletions cider-app/src/app/entity-table/table-stat.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

// TableStat
//
// field-name:
// token-name token-count token-copies-count
// token-name-2 token-count-2 token-copies-count-2
// ...
// ...

export interface TableStat {
header: string;
tokens: TokenStat[];
}

export interface TokenStat {
token: string;
count: number;
copiesCount: number;
}

0 comments on commit a207696

Please sign in to comment.