@thecodeblogs/blog 0.15.3 → 0.15.5

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.
@@ -34,7 +34,7 @@ import { FileUploader, FileUploadModule } from 'ng2-file-upload';
34
34
  import * as i1$3 from '@fortawesome/angular-fontawesome';
35
35
  import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
36
36
  import * as i6$1 from '@angular/forms';
37
- import { UntypedFormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
37
+ import { UntypedFormControl, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
38
38
  import * as i8 from '@angular/material/card';
39
39
  import { MatCardModule } from '@angular/material/card';
40
40
  import * as i9 from '@angular/material/input';
@@ -59,8 +59,11 @@ import * as i1$4 from '@angular/router';
59
59
  import { NavigationEnd, RouterModule } from '@angular/router';
60
60
  import * as i3 from '@angular/cdk/drag-drop';
61
61
  import { DragDropModule } from '@angular/cdk/drag-drop';
62
- import * as i5$1 from '@angular/material/list';
62
+ import { trigger, state, style, transition, animate } from '@angular/animations';
63
+ import * as i8$1 from '@angular/material/list';
63
64
  import { MatListModule } from '@angular/material/list';
65
+ import * as i9$1 from '@angular/material/progress-spinner';
66
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
64
67
  import * as i3$1 from '@angular/material/sidenav';
65
68
  import { MatSidenavModule } from '@angular/material/sidenav';
66
69
  import Autolinker from 'autolinker';
@@ -314,6 +317,9 @@ class EntryService extends DjangoRestFrameworkEndpointService {
314
317
  get() {
315
318
  return this.http.get(this.endpoint).pipe(map(this.handleListResponse.bind(this)));
316
319
  }
320
+ search(searchTerm) {
321
+ return this.http.get(this.endpoint + "?search=" + searchTerm).pipe(map(this.handleListResponse.bind(this)));
322
+ }
317
323
  getUnpublishedEntries() {
318
324
  const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
319
325
  return this.http.get(this.adminEndpoint, { params });
@@ -1378,14 +1384,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1378
1384
  }], ctorParameters: function () { return [{ type: EntryService }]; } });
1379
1385
 
1380
1386
  class SideNavigationComponent {
1381
- constructor(entryService, router, identityService) {
1387
+ constructor(entryService, router, identityService, renderer) {
1382
1388
  this.entryService = entryService;
1383
1389
  this.router = router;
1384
1390
  this.identityService = identityService;
1391
+ this.renderer = renderer;
1392
+ this.state = 'out';
1393
+ this.response = null;
1394
+ this.debounceTimeout = 200;
1395
+ this.loading = true;
1385
1396
  this.entries = [];
1386
1397
  this.entriesByMonthAndYear = [];
1398
+ this.searchTerm = "";
1399
+ this.doSearch = new EventEmitter();
1400
+ this.searchControl = new FormControl('');
1387
1401
  }
1388
1402
  ngOnInit() {
1403
+ this.doSearch.pipe(debounceTime(this.debounceTimeout)).subscribe((result) => {
1404
+ this.searchEntries(result);
1405
+ });
1389
1406
  this.identityService.getMe().subscribe((identity) => {
1390
1407
  this.identity = identity;
1391
1408
  }, (err) => {
@@ -1393,58 +1410,91 @@ class SideNavigationComponent {
1393
1410
  });
1394
1411
  this.getEntries();
1395
1412
  }
1396
- getEntriesWithUrl(url) {
1413
+ getMore() {
1414
+ this.getEntriesWithUrl(this.response.next, false);
1415
+ }
1416
+ getEntriesWithUrl(url, wipe = true) {
1417
+ this.loading = true;
1397
1418
  this.entryService.getListByUrl(url).subscribe((response) => {
1419
+ this.response = response;
1398
1420
  this.entries = this.entries.concat(map$1(response.results, (result) => {
1399
1421
  return { id: result.id, entry: new Entry(result) };
1400
1422
  }));
1401
- if (response.next) {
1402
- this.getEntriesWithUrl(response.next);
1403
- }
1404
- else {
1405
- this.organizeEntries();
1406
- }
1423
+ this.organizeEntries(wipe);
1407
1424
  });
1408
1425
  }
1409
- organizeEntries() {
1410
- for (const entryWrapper of this.entries) {
1411
- const entry = entryWrapper.entry;
1412
- const create_date = new Date(entry.create_date);
1413
- const month = create_date.getMonth();
1414
- const year = create_date.getFullYear();
1415
- const key = month + '/' + year;
1416
- const sort_index = (year * 100) + month;
1417
- const containers = filter(this.entriesByMonthAndYear, (entryContainer) => entryContainer.month_year === key);
1418
- if (containers.length > 0) {
1419
- const container = containers[0];
1420
- const entriesWithId = filter(container.entries, (e) => e.id === entryWrapper.entry.id);
1421
- if (entriesWithId.length === 0) {
1422
- container.entries.push(entry);
1423
- }
1426
+ organizeEntries(wipe = true) {
1427
+ if (wipe) {
1428
+ this.state = 'out';
1429
+ }
1430
+ let organizeEntriesFn = () => {
1431
+ if (wipe) {
1432
+ this.entriesByMonthAndYear = [];
1424
1433
  }
1425
- else {
1426
- const newContainer = { month_year: key, month_year_number: sort_index, entries: [entry] };
1427
- this.entriesByMonthAndYear.push(newContainer);
1434
+ let newEntries = JSON.parse(JSON.stringify(this.entriesByMonthAndYear));
1435
+ for (const entryWrapper of this.entries) {
1436
+ const entry = entryWrapper.entry;
1437
+ const create_date = new Date(entry.create_date);
1438
+ const month = create_date.getMonth();
1439
+ const year = create_date.getFullYear();
1440
+ const key = month + '/' + year;
1441
+ const sort_index = (year * 100) + month;
1442
+ const containers = filter(newEntries, (entryContainer) => entryContainer.month_year === key);
1443
+ if (containers.length > 0) {
1444
+ const container = containers[0];
1445
+ const entriesWithId = filter(container.entries, (e) => e.id === entryWrapper.entry.id);
1446
+ if (entriesWithId.length === 0) {
1447
+ container.entries.push(entry);
1448
+ }
1449
+ }
1450
+ else {
1451
+ const newContainer = { month_year: key, month_year_number: sort_index, entries: [entry] };
1452
+ newEntries.push(newContainer);
1453
+ }
1428
1454
  }
1429
- }
1430
- this.entriesByMonthAndYear.sort((entry_a, entry_b) => {
1431
- return entry_a.month_year_number - entry_b.month_year_number;
1432
- });
1433
- this.entriesByMonthAndYear.reverse();
1455
+ newEntries.sort((entry_a, entry_b) => {
1456
+ return entry_a.month_year_number - entry_b.month_year_number;
1457
+ });
1458
+ newEntries.reverse();
1459
+ let setEntriesFn = () => {
1460
+ this.entriesByMonthAndYear = newEntries;
1461
+ this.loading = false;
1462
+ if (wipe) {
1463
+ this.state = 'in';
1464
+ }
1465
+ };
1466
+ setTimeout(setEntriesFn.bind(this), 400);
1467
+ };
1468
+ setTimeout(organizeEntriesFn.bind(this), 400);
1434
1469
  }
1435
1470
  getEntries() {
1471
+ this.loading = true;
1436
1472
  this.entryService.get().subscribe((response) => {
1473
+ this.response = response;
1437
1474
  this.entries = map$1(response.results, (result) => {
1438
1475
  return { id: result.id, entry: new Entry(result) };
1439
1476
  });
1440
- if (response.next) {
1441
- this.getEntriesWithUrl(response.next);
1442
- }
1443
- else {
1444
- this.organizeEntries();
1445
- }
1477
+ this.organizeEntries();
1446
1478
  });
1447
1479
  }
1480
+ searchEntries(searchTerm) {
1481
+ let turnOnLoading = () => {
1482
+ this.loading = true;
1483
+ };
1484
+ setTimeout(turnOnLoading.bind(this), this.debounceTimeout + 100);
1485
+ if (searchTerm !== "") {
1486
+ this.entryService.search(searchTerm).subscribe((response) => {
1487
+ this.response = response;
1488
+ this.entries = map$1(response.results, (result) => {
1489
+ return { id: result.id, entry: new Entry(result) };
1490
+ });
1491
+ this.organizeEntries();
1492
+ });
1493
+ }
1494
+ else {
1495
+ this.getEntries();
1496
+ }
1497
+ }
1448
1498
  render() {
1449
1499
  }
1450
1500
  routeTo(entry) {
@@ -1510,13 +1560,41 @@ class SideNavigationComponent {
1510
1560
  this.sourceSub = null;
1511
1561
  }
1512
1562
  }
1563
+ onSearchChange(searchValue) {
1564
+ this.doSearch.emit(searchValue);
1565
+ }
1513
1566
  }
1514
- SideNavigationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SideNavigationComponent, deps: [{ token: EntryService }, { token: i1$4.Router }, { token: IdentityService }], target: i0.ɵɵFactoryTarget.Component });
1515
- SideNavigationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: SideNavigationComponent, selector: "app-side-navigation", ngImport: i0, template: "<div class=\"sidenav no-scrollbar\">\n <mat-nav-list *ngFor=\"let container of entriesByMonthAndYear\">\n <h3>{{getMonthAndYearFromKey(container.month_year)}}</h3>\n <a mat-list-item *ngFor=\"let entry of container.entries\" href=\"javascript:void(0)\" (click)=\"routeTo(entry)\">{{entry.title}}</a>\n </mat-nav-list>\n\n <ng-container *ngIf=\"identity?.id === 1\">\n <h2>Misc</h2>\n\n <mat-nav-list>\n <a mat-list-item href=\"javascript:void(0);\" (click)=\"routeTo(null)\">Create</a>\n </mat-nav-list>\n </ng-container>\n <h3 *ngIf=\"identity\">Logged in as {{identity?.email}}</h3>\n</div>\n\n", styles: [".sidenav{max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.sidenav{max-height:100vh}}h2,h3{margin-left:10px;justify-content:right}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5$1.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i5$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }] });
1567
+ SideNavigationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SideNavigationComponent, deps: [{ token: EntryService }, { token: i1$4.Router }, { token: IdentityService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
1568
+ SideNavigationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: SideNavigationComponent, selector: "app-side-navigation", viewQueries: [{ propertyName: "divNav", first: true, predicate: ["navcontainer"], descendants: true }], ngImport: i0, template: "<div class=\"sidenav no-scrollbar\">\n <div style=\"margin-top: 20px;\">\n <mat-form-field style=\"width: 100%\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchControl\" (ngModelChange)=\"onSearchChange($event)\">\n </mat-form-field>\n </div>\n\n <div\n class=\"progress\"\n [hidden]=\"!loading\"\n >\n <mat-progress-spinner\n style=\"margin-left: 16px;\"\n [diameter]=20\n mode=\"indeterminate\"\n >\n </mat-progress-spinner>\n </div>\n\n <div #navcontainer class=\"navcontainer\"\n [@sideNavAnimation]=\"state\"\n >\n <mat-nav-list\n *ngFor=\"let container of entriesByMonthAndYear\"\n >\n <h3>{{getMonthAndYearFromKey(container.month_year)}}</h3>\n <a mat-list-item *ngFor=\"let entry of container.entries\" href=\"javascript:void(0)\" (click)=\"routeTo(entry)\">{{entry.title}}</a>\n </mat-nav-list>\n\n <a\n class=\"sidelink\"\n *ngIf=\"this?.response?.next && !loading\"\n (click)=\"getMore()\"\n href=\"javascript:void(0);\">More...</a>\n </div>\n <ng-container *ngIf=\"identity?.id === 1\">\n <h2>Misc</h2>\n\n <mat-nav-list>\n <a mat-list-item href=\"javascript:void(0);\" (click)=\"routeTo(null)\">Create</a>\n </mat-nav-list>\n </ng-container>\n <h3 *ngIf=\"identity\">Logged in as {{identity?.email}}</h3>\n</div>\n\n", styles: [".progress{position:absolute;top:100px;left:0}.sidelink{padding-left:16px}.sidenav{position:relative;max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.sidenav{max-height:100vh}}h2,h3{margin-left:10px;justify-content:right}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "component", type: i8$1.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i8$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i9$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], animations: [
1569
+ trigger('sideNavAnimation', [
1570
+ state('in', style({ transform: 'translateX(0%)' })),
1571
+ state('out', style({ transform: 'translateX(110%)' })),
1572
+ transition('in => out', [
1573
+ animate('100ms ease-out', style({ transform: 'translateX(110%)' }))
1574
+ ]),
1575
+ transition('out => in', [
1576
+ animate('100ms ease-in', style({ transform: 'translateX(0%)' }))
1577
+ ])
1578
+ ]),
1579
+ ] });
1516
1580
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SideNavigationComponent, decorators: [{
1517
1581
  type: Component,
1518
- args: [{ selector: 'app-side-navigation', template: "<div class=\"sidenav no-scrollbar\">\n <mat-nav-list *ngFor=\"let container of entriesByMonthAndYear\">\n <h3>{{getMonthAndYearFromKey(container.month_year)}}</h3>\n <a mat-list-item *ngFor=\"let entry of container.entries\" href=\"javascript:void(0)\" (click)=\"routeTo(entry)\">{{entry.title}}</a>\n </mat-nav-list>\n\n <ng-container *ngIf=\"identity?.id === 1\">\n <h2>Misc</h2>\n\n <mat-nav-list>\n <a mat-list-item href=\"javascript:void(0);\" (click)=\"routeTo(null)\">Create</a>\n </mat-nav-list>\n </ng-container>\n <h3 *ngIf=\"identity\">Logged in as {{identity?.email}}</h3>\n</div>\n\n", styles: [".sidenav{max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.sidenav{max-height:100vh}}h2,h3{margin-left:10px;justify-content:right}\n"] }]
1519
- }], ctorParameters: function () { return [{ type: EntryService }, { type: i1$4.Router }, { type: IdentityService }]; } });
1582
+ args: [{ selector: 'app-side-navigation', animations: [
1583
+ trigger('sideNavAnimation', [
1584
+ state('in', style({ transform: 'translateX(0%)' })),
1585
+ state('out', style({ transform: 'translateX(110%)' })),
1586
+ transition('in => out', [
1587
+ animate('100ms ease-out', style({ transform: 'translateX(110%)' }))
1588
+ ]),
1589
+ transition('out => in', [
1590
+ animate('100ms ease-in', style({ transform: 'translateX(0%)' }))
1591
+ ])
1592
+ ]),
1593
+ ], template: "<div class=\"sidenav no-scrollbar\">\n <div style=\"margin-top: 20px;\">\n <mat-form-field style=\"width: 100%\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchControl\" (ngModelChange)=\"onSearchChange($event)\">\n </mat-form-field>\n </div>\n\n <div\n class=\"progress\"\n [hidden]=\"!loading\"\n >\n <mat-progress-spinner\n style=\"margin-left: 16px;\"\n [diameter]=20\n mode=\"indeterminate\"\n >\n </mat-progress-spinner>\n </div>\n\n <div #navcontainer class=\"navcontainer\"\n [@sideNavAnimation]=\"state\"\n >\n <mat-nav-list\n *ngFor=\"let container of entriesByMonthAndYear\"\n >\n <h3>{{getMonthAndYearFromKey(container.month_year)}}</h3>\n <a mat-list-item *ngFor=\"let entry of container.entries\" href=\"javascript:void(0)\" (click)=\"routeTo(entry)\">{{entry.title}}</a>\n </mat-nav-list>\n\n <a\n class=\"sidelink\"\n *ngIf=\"this?.response?.next && !loading\"\n (click)=\"getMore()\"\n href=\"javascript:void(0);\">More...</a>\n </div>\n <ng-container *ngIf=\"identity?.id === 1\">\n <h2>Misc</h2>\n\n <mat-nav-list>\n <a mat-list-item href=\"javascript:void(0);\" (click)=\"routeTo(null)\">Create</a>\n </mat-nav-list>\n </ng-container>\n <h3 *ngIf=\"identity\">Logged in as {{identity?.email}}</h3>\n</div>\n\n", styles: [".progress{position:absolute;top:100px;left:0}.sidelink{padding-left:16px}.sidenav{position:relative;max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.sidenav{max-height:100vh}}h2,h3{margin-left:10px;justify-content:right}\n"] }]
1594
+ }], ctorParameters: function () { return [{ type: EntryService }, { type: i1$4.Router }, { type: IdentityService }, { type: i0.Renderer2 }]; }, propDecorators: { divNav: [{
1595
+ type: ViewChild,
1596
+ args: ['navcontainer', { static: false }]
1597
+ }] } });
1520
1598
 
1521
1599
  class MainComponent {
1522
1600
  constructor(router) {
@@ -1729,6 +1807,7 @@ CoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15
1729
1807
  MatDatepickerModule,
1730
1808
  MatNativeDateModule,
1731
1809
  MatTableModule,
1810
+ MatProgressSpinnerModule,
1732
1811
  FontAwesomeModule,
1733
1812
  FileUploadModule,
1734
1813
  NgxMaterialTimepickerModule], exports: [EntryRendererComponent,
@@ -1773,6 +1852,7 @@ CoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15
1773
1852
  MatDatepickerModule,
1774
1853
  MatNativeDateModule,
1775
1854
  MatTableModule,
1855
+ MatProgressSpinnerModule,
1776
1856
  FontAwesomeModule,
1777
1857
  FileUploadModule,
1778
1858
  NgxMaterialTimepickerModule] });
@@ -1817,6 +1897,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1817
1897
  MatDatepickerModule,
1818
1898
  MatNativeDateModule,
1819
1899
  MatTableModule,
1900
+ MatProgressSpinnerModule,
1820
1901
  FontAwesomeModule,
1821
1902
  FileUploadModule,
1822
1903
  NgxMaterialTimepickerModule,