feat(export): Added export deltagare. (TV-872)
Squashed commit of the following: commit 9c06b7f1d44a4b48d7f31a22b6bfbd233e09d2f7 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 15:07:15 2021 +0100 Updated api endpoint commit f9bfbecda6d03b70d87febbada920d0eca798b1f Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 15:01:13 2021 +0100 Updated libs commit 9edb413d537288fa0708b8a04eb54f801ebc23a0 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:58:13 2021 +0100 Added @types/file-saver commit 624affac55ce771fd58e2770a0d4a98233a8e9ba Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:42:29 2021 +0100 Updated libs commit 65dae1d906bbcec474581692b2aced9e47d2484c Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:36:42 2021 +0100 Added utils lib config commit 223bd59724663523bdbaf87b5502396156ddb9eb Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:06:13 2021 +0100 Added validation commit 166dfcf0448155ac21c0eaa904b4ce1271f73193 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 13:25:35 2021 +0100 Changed styling and removed some fake data commit 3906f2793dd52b626b95c13e115495451332c894 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 13:18:52 2021 +0100 Added digi-ng datepicker commit de0d51434d15cac5476303d4b417c591da16fd8f Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 12:31:48 2021 +0100 Added checkbox
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
@@ -23,8 +23,8 @@ import { UtforandeVerksamhet } from '@msfa-models/utforande-verksamhet.model';
|
||||
import { UtforandeVerksamheterService } from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
|
||||
import { ValidationErrorLink } from '@msfa-shared/components/error-list/error-list.component';
|
||||
import { TreeNodesSelectorService } from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { EmployeeValidator } from '@msfa-utils/validators/employee.validator';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
import { EmployeeFormService } from '../services/employee-form.service';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ExportsComponent } from './exports.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', data: { title: 'Exporter' }, component: ExportsComponent },
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'deltagare',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'deltagare',
|
||||
data: { title: 'Skapa export för deltagare' },
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
<digi-typography>
|
||||
<header class="exports__header">
|
||||
<h1>Exporter</h1>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut corporis voluptatum magnam cumque fugiat, neque, totam explicabo est reprehenderit perspiciatis ratione error ad eveniet inventore, tempora facilis nostrum earum! Unde!</p>
|
||||
</header>
|
||||
<main class="exports__contents"></main>
|
||||
<main class="exports__contents">
|
||||
|
||||
</main>
|
||||
</digi-typography>
|
||||
</section>
|
||||
</msfa-layout>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
|
||||
import { ExportsRoutingModule } from './exports-routing.module';
|
||||
import { ExportsComponent } from './exports.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ExportsComponent],
|
||||
imports: [CommonModule, RouterModule.forChild([{ path: '', component: ExportsComponent }]), LayoutModule],
|
||||
imports: [CommonModule, ExportsRoutingModule, LayoutModule, ReactiveFormsModule],
|
||||
})
|
||||
export class ExportsModule {}
|
||||
|
||||
@@ -1,10 +1,62 @@
|
||||
<msfa-layout>
|
||||
<section class="deltagare-export">
|
||||
<digi-typography>
|
||||
<digi-typography>
|
||||
<header class="deltagare-export__header">
|
||||
<h1>Deltagare export</h1>
|
||||
<h1>Exportera information om deltagare</h1>
|
||||
<p>
|
||||
Här kan du exportera deltagarinformation. Informationen laddas ner till din dator i CSV-format. Du kan endast
|
||||
exportera deltagare som du har behörighet att se. Detta innebär att du bara kan få ut de deltagare som är
|
||||
kopplade till samma utförande verksamhet och adress som du är inloggad på. Du kan även välja att inkludera
|
||||
deltagare som exporterats vid tidigare tillfälle. Deltagare som exporterats tidigare markeras i filen.
|
||||
</p>
|
||||
</header>
|
||||
<main class="deltagare-export__contents"></main>
|
||||
<form class="deltagare-export__form" [formGroup]="formGroup" (ngSubmit)="fetchExportFile()">
|
||||
<div
|
||||
class="deltagare-export__period-wrapper"
|
||||
[ngClass]="{'deltagare-export__period-wrapper--error': showPeriodError}"
|
||||
>
|
||||
<div class="deltagare-export__period-inputs">
|
||||
<digi-ng-form-datepicker
|
||||
[afDisableValidStyle]="true"
|
||||
[afMaxDate]="maxDate"
|
||||
[afInvalid]="showPeriodError"
|
||||
afLabel="Från datum"
|
||||
[formControl]="startDateFormControl"
|
||||
></digi-ng-form-datepicker>
|
||||
<digi-ng-form-datepicker
|
||||
[afDisableValidStyle]="true"
|
||||
[afMaxDate]="maxDate"
|
||||
[afInvalid]="showPeriodError"
|
||||
afLabel="Till och med datum"
|
||||
[formControl]="endDateFormControl"
|
||||
></digi-ng-form-datepicker>
|
||||
</div>
|
||||
<div aria-atomic="true" role="alert">
|
||||
<digi-form-validation-message *ngIf="showPeriodError" af-variation="error"
|
||||
>{{formErrors.datesMismatch}}</digi-form-validation-message
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<ui-checkbox
|
||||
[formControl]="includeExportedDeltagareFormControl"
|
||||
uiLabel="Inkludera redan exporterade deltagare"
|
||||
></ui-checkbox>
|
||||
<footer class="deltagare-export__footer">
|
||||
<digi-notification-alert
|
||||
*ngIf="fetchError$ | async as error"
|
||||
class="deltagare-export__alert"
|
||||
af-variation="danger"
|
||||
af-heading="Någonting gick fel"
|
||||
>
|
||||
<p>Kunde inte hämta exportfilen för deltagare. Ladda om sidan och försök igen.</p>
|
||||
<p class="msfa__small-text" *ngIf="error.message">{{error.message}}</p>
|
||||
</digi-notification-alert>
|
||||
<div class="deltagare-export__cta-wrapper">
|
||||
<digi-button af-type="submit" af-size="m">Exportera deltagare</digi-button>
|
||||
</div>
|
||||
</footer>
|
||||
</form>
|
||||
</digi-typography>
|
||||
</section>
|
||||
<ui-loader *ngIf="fetchIsLoading$ | async" uiType="absolute"></ui-loader>
|
||||
</section>
|
||||
</msfa-layout>
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/z-index';
|
||||
|
||||
.deltagare-export {
|
||||
&__contents {
|
||||
max-width: var(--digi--typography--text--max-width);
|
||||
position: relative;
|
||||
z-index: $msfa__z-index-default;
|
||||
|
||||
&__form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $digi--layout--gutter--l;
|
||||
margin-top: $digi--layout--gutter--l;
|
||||
}
|
||||
|
||||
&__period-inputs {
|
||||
display: flex;
|
||||
gap: $digi--layout--gutter--xl;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--digi--layout--gutter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { UiCheckboxModule } from '@ui/checkbox/checkbox.module';
|
||||
import { DeltagareExportComponent } from './deltagare-export.component';
|
||||
import { DeltagareExportService } from './deltagare-export.service';
|
||||
|
||||
describe('DeltagareExportComponent', () => {
|
||||
let component: DeltagareExportComponent;
|
||||
@@ -13,7 +17,15 @@ describe('DeltagareExportComponent', () => {
|
||||
void TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [DeltagareExportComponent],
|
||||
imports: [HttpClientTestingModule, RouterTestingModule],
|
||||
imports: [
|
||||
HttpClientTestingModule,
|
||||
RouterTestingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
DigiNgFormDatepickerModule,
|
||||
UiCheckboxModule,
|
||||
],
|
||||
providers: [DeltagareExportService],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
|
||||
import { CustomError } from '@msfa-models/error/custom-error';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { DeltagareExportFormData, DeltagareExportFormErrors } from './deltagare-export.model';
|
||||
import { DeltagareExportService } from './deltagare-export.service';
|
||||
import { DeltagareExportValidator } from './deltagare-export.validator';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-deltagare-export',
|
||||
@@ -6,4 +15,80 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
styleUrls: ['./deltagare-export.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DeltagareExportComponent {}
|
||||
export class DeltagareExportComponent {
|
||||
maxDate = new Date();
|
||||
shouldValidate$ = new BehaviorSubject<boolean>(false);
|
||||
fetchIsLoading$ = new BehaviorSubject<boolean>(false);
|
||||
fetchError$ = new BehaviorSubject<CustomError>(null);
|
||||
formGroup = new FormGroup(
|
||||
{
|
||||
startDate: new FormControl(null),
|
||||
endDate: new FormControl(null),
|
||||
includeExportedDeltagare: new FormControl(false),
|
||||
},
|
||||
[DeltagareExportValidator.isDeltagareExportValid()]
|
||||
);
|
||||
constructor(private deltagareExportService: DeltagareExportService) {}
|
||||
|
||||
get startDateFormControl(): FormControl {
|
||||
return this.formGroup.get('startDate') as FormControl;
|
||||
}
|
||||
get endDateFormControl(): FormControl {
|
||||
return this.formGroup.get('endDate') as FormControl;
|
||||
}
|
||||
get includeExportedDeltagareFormControl(): FormControl {
|
||||
return this.formGroup.get('includeExportedDeltagare') as FormControl;
|
||||
}
|
||||
|
||||
get deltagagareExportFormData(): DeltagareExportFormData {
|
||||
return this.formGroup.value as DeltagareExportFormData;
|
||||
}
|
||||
|
||||
get formErrors(): DeltagareExportFormErrors {
|
||||
return this.formGroup.errors as DeltagareExportFormErrors;
|
||||
}
|
||||
|
||||
get showPeriodError(): boolean {
|
||||
return this.formErrors?.datesMismatch && this.shouldValidate$.getValue();
|
||||
}
|
||||
|
||||
fetchExportFile(): void {
|
||||
if (this.formGroup.invalid) {
|
||||
this.shouldValidate$.next(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const requestData = this._formDataToRequestData(this.deltagagareExportFormData);
|
||||
|
||||
this.fetchIsLoading$.next(true);
|
||||
this.deltagareExportService
|
||||
.fetchExportFile$(requestData)
|
||||
.pipe(take(1))
|
||||
.subscribe({
|
||||
next: response => {
|
||||
const blob = new Blob([response], { type: 'application/csv' });
|
||||
saveAs(blob, 'deltagare-export.csv');
|
||||
this.fetchIsLoading$.next(false);
|
||||
},
|
||||
error: (customError: CustomError) => {
|
||||
this.fetchError$.next({ ...customError, message: customError.error.message });
|
||||
this.fetchIsLoading$.next(false);
|
||||
throw { ...customError, avoidToast: true };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _formDataToRequestData(formData: DeltagareExportFormData): DeltagareExportRequest {
|
||||
const { startDate, endDate, includeExportedDeltagare } = formData;
|
||||
const requestData: DeltagareExportRequest = {
|
||||
includeExportedDeltagare,
|
||||
};
|
||||
if (startDate) {
|
||||
requestData.startDate = startDate;
|
||||
}
|
||||
if (endDate) {
|
||||
requestData.endDate = endDate;
|
||||
}
|
||||
return requestData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export interface DeltagareExportFormData {
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
includeExportedDeltagare: boolean;
|
||||
}
|
||||
|
||||
export type DeltagareExportFormKeys = keyof DeltagareExportFormData;
|
||||
|
||||
export interface DeltagareExportFormErrors {
|
||||
datesMismatch?: string;
|
||||
}
|
||||
@@ -1,12 +1,27 @@
|
||||
import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
|
||||
import { UiCheckboxModule } from '@ui/checkbox/checkbox.module';
|
||||
import { UiLoaderModule } from '@ui/loader/loader.module';
|
||||
import { DeltagareExportComponent } from './deltagare-export.component';
|
||||
import { DeltagareExportService } from './deltagare-export.service';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [DeltagareExportComponent],
|
||||
imports: [CommonModule, RouterModule.forChild([{ path: '', component: DeltagareExportComponent }]), LayoutModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{ path: '', component: DeltagareExportComponent }]),
|
||||
LayoutModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
UiCheckboxModule,
|
||||
UiLoaderModule,
|
||||
DigiNgFormDatepickerModule,
|
||||
],
|
||||
providers: [DeltagareExportService],
|
||||
})
|
||||
export class DeltagareExportModule {}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
|
||||
import { ExportApiService } from '@msfa-services/api/export.api.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class DeltagareExportService {
|
||||
constructor(private exportApiService: ExportApiService) {}
|
||||
|
||||
public fetchExportFile$(requestData: DeltagareExportRequest): Observable<Blob> {
|
||||
return this.exportApiService.fetchDeltagareExportFile$(requestData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||
import { DeltagareExportFormData, DeltagareExportFormErrors } from './deltagare-export.model';
|
||||
|
||||
export class DeltagareExportValidator {
|
||||
static isDeltagareExportValid(): ValidatorFn {
|
||||
return (c: AbstractControl): DeltagareExportFormErrors => {
|
||||
let errors: DeltagareExportFormErrors = null;
|
||||
const { startDate, endDate } = c.value as DeltagareExportFormData;
|
||||
|
||||
if (startDate && endDate && startDate > endDate) {
|
||||
errors = {
|
||||
...errors,
|
||||
datesMismatch: 'Från datum får inte vara senare än till och med datum',
|
||||
};
|
||||
}
|
||||
return errors;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { DropdownTriggerForDirective } from '@msfa-shared/components/dropdown/dropdown-trigger-for.directive';
|
||||
import { MultiselectFilterOption } from '@msfa-shared/components/multiselect/multiselect-filter-option';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
|
||||
interface PropagateChangeFn {
|
||||
(_: unknown): void;
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
import { TreeNode, TreeNodeModel, TreeNodesSelectorService } from '../../services/tree-nodes-selector.service';
|
||||
import { TreeNodesSelectorPanelComponent } from '../tree-nodes-selector-panel/tree-nodes-selector-panel.component';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
|
||||
export interface TreeNode {
|
||||
label: string;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface DeltagareExportRequest {
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
includeExportedDeltagare: boolean;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ErrorType } from '@msfa-enums/error-type.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import { CustomError } from '@msfa-models/error/custom-error';
|
||||
import { Observable } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ExportApiService {
|
||||
private _apiBaseUrl = `${environment.api.url}/export`;
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
|
||||
public fetchDeltagareExportFile$(requestData: DeltagareExportRequest): Observable<Blob> {
|
||||
const params: Params = {
|
||||
...requestData,
|
||||
includeExportedDeltagare: requestData.includeExportedDeltagare.toString(),
|
||||
};
|
||||
|
||||
return this.httpClient
|
||||
.get<Blob>(`${this._apiBaseUrl}/deltagare`, { params, responseType: 'blob' as 'json' })
|
||||
.pipe(
|
||||
catchError((error: Error) => {
|
||||
throw new CustomError({
|
||||
error,
|
||||
message: `Kunde inte hämta exportfilen för deltagare.\n\n${error.message}`,
|
||||
type: ErrorType.API,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ export function mapPathsToBreadcrumbs(
|
||||
} else if (isDeltagareReportingRoute(paths)) {
|
||||
breadcrumbs = breadcrumbs.slice(0, -1);
|
||||
breadcrumbs[breadcrumbs.length - 2].text = 'Deltagarinformation';
|
||||
} else if (isExportRoute(paths)) {
|
||||
breadcrumbs[breadcrumbs.length - 1].text = `Exportera ${paths[paths.length - 1]}`;
|
||||
}
|
||||
|
||||
return breadcrumbs;
|
||||
@@ -54,3 +56,7 @@ function isDeltagareReportingFormRoute(paths: string[]): boolean {
|
||||
function isDeltagareReportingRoute(paths: string[]): boolean {
|
||||
return paths.length === 4 && paths[0] === 'deltagare' && paths[2] in DELTAGARE_REPORTING_ROUTES;
|
||||
}
|
||||
|
||||
function isExportRoute(paths: string[]): boolean {
|
||||
return paths[0] === 'exporter';
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// From https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid
|
||||
export function uuid(): string {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
const r = (Math.random() * 16) | 0,
|
||||
v = c == 'x' ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
100
apps/mina-sidor-fa/src/assets/files/test.csv
Normal file
100
apps/mina-sidor-fa/src/assets/files/test.csv
Normal file
@@ -0,0 +1,100 @@
|
||||
Serial Number,Company Name,Employee Markme,Description,Leave
|
||||
9788189999599,TALES OF SHIVA,Mark,mark,0
|
||||
9780099578079,1Q84 THE COMPLETE TRILOGY,HARUKI MURAKAMI,Mark,0
|
||||
9780198082897,MY KUMAN,Mark,Mark,0
|
||||
9780007880331,THE GOD OF SMAAL THINGS,ARUNDHATI ROY,4TH HARPER COLLINS,2
|
||||
9780545060455,THE BLACK CIRCLE,Mark,4TH HARPER COLLINS,0
|
||||
9788126525072,THE THREE LAWS OF PERFORMANCE,Mark,4TH HARPER COLLINS,0
|
||||
9789381626610,CHAMarkKYA MANTRA,Mark,4TH HARPER COLLINS,0
|
||||
9788184513523,59.FLAGS,Mark,4TH HARPER COLLINS,0
|
||||
9780743234801,THE POWER OF POSITIVE THINKING FROM,Mark,A & A PUBLISHER,0
|
||||
9789381529621,YOU CAN IF YO THINK YO CAN,PEALE,A & A PUBLISHER,0
|
||||
9788183223966,DONGRI SE DUBAI TAK (MPH),Mark,A & A PUBLISHER,0
|
||||
9788187776005,MarkLANDA ADYTAN KOSH,Mark,AADISH BOOK DEPOT,0
|
||||
9788187776013,MarkLANDA VISHAL SHABD SAGAR,-,AADISH BOOK DEPOT,1
|
||||
8187776021,MarkLANDA CONCISE DICT(ENG TO HINDI),Mark,AADISH BOOK DEPOT,0
|
||||
9789384716165,LIEUTEMarkMarkT GENERAL BHAGAT: A SAGA OF BRAVERY AND LEADERSHIP,Mark,AAM COMICS,2
|
||||
9789384716233,LN. MarkIK SUNDER SINGH,N.A,AAN COMICS,0
|
||||
9789384850319,I AM KRISHMark,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,1
|
||||
9789384850357,DON'T TEACH ME TOLERANCE INDIA,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,0
|
||||
9789384850364,MUJHE SAHISHNUTA MAT SIKHAO BHARAT,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,0
|
||||
9789384850746,SECRETS OF DESTINY,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,1
|
||||
9789384850753,BHAGYA KE RAHASYA (HINDI) SECRET OF DESTINY,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,1
|
||||
9788192669038,MEIN MANN HOON,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,0
|
||||
9789384850098,I AM THE MIND,DEEP TRIVEDI,AATMARAM & SONS,0
|
||||
9780349121420,THE ART OF CHOOSING,SHEEMark IYENGAR,ABACUS,0
|
||||
9780349123462,IN SPITE OF THE GODS,EDWARD LUCE,ABACUS,1
|
||||
9788188440061,QUESTIONS & ANWERS ABOUT THE GREAT BIBLE,Mark,ABC PUBLISHERS DISTRIBUTORS,4
|
||||
9789382088189,NIBANDH EVAM KAHANI LEKHAN { HINDI },Mark,ABHI BOOKS,1
|
||||
9789332703759,INDIAN ECONOMY SINCE INDEPENDENCE 27TH /E,UMA KAPILA,ACADEMIC FOUNDATION,1
|
||||
9788171888016,ECONOMIC DEVELOPMENT AND POLICY IN INDIA,UMA KAPILA,ACADEMIC FOUNDATION,1
|
||||
9789332704343,INDIAN ECONOMY PERFORMANCE 18TH/E 2017-2018,UMA KAPILA,ACADEMIC FOUNDATION,2
|
||||
9789332703735,INDIAN ECONOMIC DEVELOPMENTSINCE 1947 (NO RETURMarkBLE),UMA KAPILA,ACADEMIC FOUNDATION,1
|
||||
9789383454143,PRELIMS SPECIAL READING COMPREHENSION PAPER II CSAT,MarkGENDRA PRATAP,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454204,THE CONSTITUTION OF INDIA 2ND / E,AR KHAN,ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789386361011,"INDIAN HERITAGE ,ART & CULTURE",MADHUKAR,ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789383454303,BHARAT KA SAMVIDHAN,AR KHAN,ACCESS PUBLISHING INDIA PVT.LTD,4
|
||||
9789383454471,"ETHICS, INTEGRITY & APTITUDE ( 3RD/E)","P N ROY ,G SUBBA RAO",ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789383454563,GENERAL STUDIES PAPER -- I (2016),Mark,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454570,GENERAL STUDIES PAPER - II (2016),Mark,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454693,INDIAN AND WORLD GEOGRAPHY 2E,D R KHULLAR,ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789383454709,VASTUNISTHA PRASHN SANGRAHA: BHARAT KA ITIHAS,MEEMarkKSHI KANT,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454723,"PHYSICAL, HUMAN AND ECONOMIC GEOGRAPHY",D R KHULLAR,ACCESS PUBLISHING INDIA PVT.LTD,4
|
||||
9789383454730,WORLD GEOGRAPHY,DR KHULLAR,ACCESS PUBLISHING INDIA PVT.LTD,5
|
||||
9789383454822,INDIA: MAP ENTRIES IN GEOGRAPHY,MAJID HUSAIN,ACCESS PUBLISHING INDIA PVT.LTD,5
|
||||
9789383454853,GOOD GOVERMarkNCE IN INDIA 2/ED.,G SUBBA RAO,ACCESS PUBLISHING INDIA PVT.LTD,1
|
||||
9789383454884,KAMYABI KE SUTRA-CIVIL SEWA PARIKSHA AAP KI MUTTHI MEIN,ASHOK KUMAR,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454891,GENERAL SCIENCE PRELIRY EXAM,Mark,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9781742860190,SUCCESS AND DYSLEXIA,SUCCESS AND DYSLEXIA,ACER PRESS,0
|
||||
9781742860114,AN EXTRAORDIMarkRY SCHOOL,SARA JAMES,ACER PRESS,0
|
||||
9781742861463,POWERFUL PRACTICES FOR READING IMPROVEMENT,GLASSWELL,ACER PRESS,0
|
||||
9781742862859,EARLY CHILDHOOD PLAY MATTERS,SHOMark BASS,ACER PRESS,0
|
||||
9781742863641,LEADING LEARNING AND TEACHING,STEPHEN DINHAM,ACER PRESS,0
|
||||
9781742863658,READING AND LEARNING DIFFICULTIES,PETER WESTWOOD,ACER PRESS,0
|
||||
9781742863665,NUMERACY AND LEARNING DIFFICULTIES,PETER WOODLAND],ACER PRESS,0
|
||||
9781742863771,TEACHING AND LEARNING DIFFICULTIES,PETER WOODLAND,ACER PRESS,0
|
||||
9781742861678,USING DATA TO IMPROVE LEARNING,ANTHONY SHADDOCK,ACER PRESS,0
|
||||
9781742862484,PATHWAYS TO SCHOOL SYSTEM IMPROVEMENT,MICHAEL GAFFNEY,ACER PRESS,0
|
||||
9781742860176,FOR THOSE WHO TEACH,PHIL RIDDEN,ACER PRESS,0
|
||||
9781742860213,KEYS TO SCHOOL LEADERSHIP,PHIL RIDDEN & JOHN DE NOBILE,ACER PRESS,0
|
||||
9781742860220,DIVERSE LITERACIES IN EARLY CHILDHOOD,LEONIE ARTHUR,ACER PRESS,0
|
||||
9781742860237,CREATIVE ARTS IN THE LIVESOF YOUNG CHILDREN,ROBYN EWING,ACER PRESS,0
|
||||
9781742860336,SOCIAL AND EMOTIOMarkL DEVELOPMENT,ROS LEYDEN AND ERIN SHALE,ACER PRESS,0
|
||||
9781742860343,DISCUSSIONS IN SCIENCE,TIM SPROD,ACER PRESS,0
|
||||
9781742860404,YOUNG CHILDREN LEARNING MATHEMATICS,ROBERT HUNTING,ACER PRESS,0
|
||||
9781742860626,COACHING CHILDREN,KELLY SUMICH,ACER PRESS,1
|
||||
9781742860923,TEACHING PHYSICAL EDUCATIOMarkL IN PRIMARY SCHOOL,JANET L CURRIE,ACER PRESS,0
|
||||
9781742861111,ASSESSMENT AND REPORTING,PHIL RIDDEN AND SANDY,ACER PRESS,0
|
||||
9781742861302,COLLABORATION IN LEARNING,MAL LEE AND LORRAE WARD,ACER PRESS,0
|
||||
9780864315250,RE-IMAGINING EDUCATIMarkL LEADERSHIP,BRIAN J.CALDWELL,ACER PRESS,0
|
||||
9780864317025,TOWARDS A MOVING SCHOOL,FLEMING & KLEINHENZ,ACER PRESS,0
|
||||
9780864317230,DESINGNING A THINKING A CURRICULAM,SUSAN WILKS,ACER PRESS,0
|
||||
9780864318961,LEADING A DIGITAL SCHOOL,MAL LEE AND MICHEAL GAFFNEY,ACER PRESS,0
|
||||
9780864319043,NUMERACY,WESTWOOD,ACER PRESS,0
|
||||
9780864319203,TEACHING ORAL LANGUAGE,JOHN MUNRO,ACER PRESS,0
|
||||
9780864319449,SPELLING,WESTWOOD,ACER PRESS,0
|
||||
9788189999803,STORIES OF SHIVA,Mark,ACK,0
|
||||
9788189999988,JAMSET JI TATA: THE MAN WHO SAW TOMORROW,,ACK,0
|
||||
9788184820355,HEROES FROM THE MAHABHARTA { 5-IN-1 },Mark,ACK,0
|
||||
9788184820553,SURYA,,ACK,0
|
||||
9788184820645,TALES OF THE MOTHER GODDESS,-,ACK,0
|
||||
9788184820652,ADVENTURES OF KRISHMark,Mark,ACK,0
|
||||
9788184822113,MAHATMA GANDHI,Mark,ACK,1
|
||||
9788184822120,TALES FROM THE PANCHATANTRA 3-IN-1,-,ACK,0
|
||||
9788184821482,YET MORE TALES FROM THE JATAKAS { 3-IN-1 },AMarkNT PAI,ACK,0
|
||||
9788184825763,LEGENDARY RULERS OF INDIA,-,ACK,0
|
||||
9788184825862,GREAT INDIAN CLASSIC,Mark,ACK,0
|
||||
9788184823219,TULSIDAS ' RAMAYAMark,Mark,ACK,0
|
||||
9788184820782,TALES OF HANUMAN,-,ACK,0
|
||||
9788184820089,VALMIKI'S RAMAYAMark,A C K,ACK,1
|
||||
9788184825213,THE BEST OF INIDAN WIT AND WISDOM,Mark,ACK,0
|
||||
9788184820997,MORE TALES FROM THE PANCHTANTRA,AMarkNT PAL,ACK,0
|
||||
9788184824018,THE GREAT MUGHALS {5-IN-1},AMarkNT.,ACK,0
|
||||
9788184824049,FAMOUS SCIENTISTS,Mark,ACK,0
|
||||
9788184825978,KOMarkRK,Mark,ACK,0
|
||||
9788184826098,THE MUGHAL COURT,REEMark,ACK,0
|
||||
9788184821536,MORE STORIES FROM THE JATAKAS,Mark,ACK,0
|
||||
9788184821543,MORE TALES OF BIRBAL,-,ACK,0
|
||||
9788184821550,TALES FROM THE JATAKAS,-,ACK,0
|
||||
9788184821567,RAMarkS OF MEWAR,-,ACK,0
|
||||
9788184821574,THE SONS OF THE PANDAVAS,-,ACK,0
|
||||
|
Reference in New Issue
Block a user