@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 });
@@ -1374,14 +1380,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1374
1380
  }], ctorParameters: function () { return [{ type: EntryService }]; } });
1375
1381
 
1376
1382
  class SideNavigationComponent {
1377
- constructor(entryService, router, identityService) {
1383
+ constructor(entryService, router, identityService, renderer) {
1378
1384
  this.entryService = entryService;
1379
1385
  this.router = router;
1380
1386
  this.identityService = identityService;
1387
+ this.renderer = renderer;
1388
+ this.state = 'out';
1389
+ this.response = null;
1390
+ this.debounceTimeout = 200;
1391
+ this.loading = true;
1381
1392
  this.entries = [];
1382
1393
  this.entriesByMonthAndYear = [];
1394
+ this.searchTerm = "";
1395
+ this.doSearch = new EventEmitter();
1396
+ this.searchControl = new FormControl('');
1383
1397
  }
1384
1398
  ngOnInit() {
1399
+ this.doSearch.pipe(debounceTime(this.debounceTimeout)).subscribe((result) => {
1400
+ this.searchEntries(result);
1401
+ });
1385
1402
  this.identityService.getMe().subscribe((identity) => {
1386
1403
  this.identity = identity;
1387
1404
  }, (err) => {
@@ -1389,58 +1406,91 @@ class SideNavigationComponent {
1389
1406
  });
1390
1407
  this.getEntries();
1391
1408
  }
1392
- getEntriesWithUrl(url) {
1409
+ getMore() {
1410
+ this.getEntriesWithUrl(this.response.next, false);
1411
+ }
1412
+ getEntriesWithUrl(url, wipe = true) {
1413
+ this.loading = true;
1393
1414
  this.entryService.getListByUrl(url).subscribe((response) => {
1415
+ this.response = response;
1394
1416
  this.entries = this.entries.concat(map$1(response.results, (result) => {
1395
1417
  return { id: result.id, entry: new Entry(result) };
1396
1418
  }));
1397
- if (response.next) {
1398
- this.getEntriesWithUrl(response.next);
1399
- }
1400
- else {
1401
- this.organizeEntries();
1402
- }
1419
+ this.organizeEntries(wipe);
1403
1420
  });
1404
1421
  }
1405
- organizeEntries() {
1406
- for (const entryWrapper of this.entries) {
1407
- const entry = entryWrapper.entry;
1408
- const create_date = new Date(entry.create_date);
1409
- const month = create_date.getMonth();
1410
- const year = create_date.getFullYear();
1411
- const key = month + '/' + year;
1412
- const sort_index = (year * 100) + month;
1413
- const containers = filter(this.entriesByMonthAndYear, (entryContainer) => entryContainer.month_year === key);
1414
- if (containers.length > 0) {
1415
- const container = containers[0];
1416
- const entriesWithId = filter(container.entries, (e) => e.id === entryWrapper.entry.id);
1417
- if (entriesWithId.length === 0) {
1418
- container.entries.push(entry);
1419
- }
1422
+ organizeEntries(wipe = true) {
1423
+ if (wipe) {
1424
+ this.state = 'out';
1425
+ }
1426
+ let organizeEntriesFn = () => {
1427
+ if (wipe) {
1428
+ this.entriesByMonthAndYear = [];
1420
1429
  }
1421
- else {
1422
- const newContainer = { month_year: key, month_year_number: sort_index, entries: [entry] };
1423
- this.entriesByMonthAndYear.push(newContainer);
1430
+ let newEntries = JSON.parse(JSON.stringify(this.entriesByMonthAndYear));
1431
+ for (const entryWrapper of this.entries) {
1432
+ const entry = entryWrapper.entry;
1433
+ const create_date = new Date(entry.create_date);
1434
+ const month = create_date.getMonth();
1435
+ const year = create_date.getFullYear();
1436
+ const key = month + '/' + year;
1437
+ const sort_index = (year * 100) + month;
1438
+ const containers = filter(newEntries, (entryContainer) => entryContainer.month_year === key);
1439
+ if (containers.length > 0) {
1440
+ const container = containers[0];
1441
+ const entriesWithId = filter(container.entries, (e) => e.id === entryWrapper.entry.id);
1442
+ if (entriesWithId.length === 0) {
1443
+ container.entries.push(entry);
1444
+ }
1445
+ }
1446
+ else {
1447
+ const newContainer = { month_year: key, month_year_number: sort_index, entries: [entry] };
1448
+ newEntries.push(newContainer);
1449
+ }
1424
1450
  }
1425
- }
1426
- this.entriesByMonthAndYear.sort((entry_a, entry_b) => {
1427
- return entry_a.month_year_number - entry_b.month_year_number;
1428
- });
1429
- this.entriesByMonthAndYear.reverse();
1451
+ newEntries.sort((entry_a, entry_b) => {
1452
+ return entry_a.month_year_number - entry_b.month_year_number;
1453
+ });
1454
+ newEntries.reverse();
1455
+ let setEntriesFn = () => {
1456
+ this.entriesByMonthAndYear = newEntries;
1457
+ this.loading = false;
1458
+ if (wipe) {
1459
+ this.state = 'in';
1460
+ }
1461
+ };
1462
+ setTimeout(setEntriesFn.bind(this), 400);
1463
+ };
1464
+ setTimeout(organizeEntriesFn.bind(this), 400);
1430
1465
  }
1431
1466
  getEntries() {
1467
+ this.loading = true;
1432
1468
  this.entryService.get().subscribe((response) => {
1469
+ this.response = response;
1433
1470
  this.entries = map$1(response.results, (result) => {
1434
1471
  return { id: result.id, entry: new Entry(result) };
1435
1472
  });
1436
- if (response.next) {
1437
- this.getEntriesWithUrl(response.next);
1438
- }
1439
- else {
1440
- this.organizeEntries();
1441
- }
1473
+ this.organizeEntries();
1442
1474
  });
1443
1475
  }
1476
+ searchEntries(searchTerm) {
1477
+ let turnOnLoading = () => {
1478
+ this.loading = true;
1479
+ };
1480
+ setTimeout(turnOnLoading.bind(this), this.debounceTimeout + 100);
1481
+ if (searchTerm !== "") {
1482
+ this.entryService.search(searchTerm).subscribe((response) => {
1483
+ this.response = response;
1484
+ this.entries = map$1(response.results, (result) => {
1485
+ return { id: result.id, entry: new Entry(result) };
1486
+ });
1487
+ this.organizeEntries();
1488
+ });
1489
+ }
1490
+ else {
1491
+ this.getEntries();
1492
+ }
1493
+ }
1444
1494
  render() {
1445
1495
  }
1446
1496
  routeTo(entry) {
@@ -1506,13 +1556,41 @@ class SideNavigationComponent {
1506
1556
  this.sourceSub = null;
1507
1557
  }
1508
1558
  }
1559
+ onSearchChange(searchValue) {
1560
+ this.doSearch.emit(searchValue);
1561
+ }
1509
1562
  }
1510
- 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 });
1511
- 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"] }] });
1563
+ 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 });
1564
+ 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: [
1565
+ trigger('sideNavAnimation', [
1566
+ state('in', style({ transform: 'translateX(0%)' })),
1567
+ state('out', style({ transform: 'translateX(110%)' })),
1568
+ transition('in => out', [
1569
+ animate('100ms ease-out', style({ transform: 'translateX(110%)' }))
1570
+ ]),
1571
+ transition('out => in', [
1572
+ animate('100ms ease-in', style({ transform: 'translateX(0%)' }))
1573
+ ])
1574
+ ]),
1575
+ ] });
1512
1576
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SideNavigationComponent, decorators: [{
1513
1577
  type: Component,
1514
- 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"] }]
1515
- }], ctorParameters: function () { return [{ type: EntryService }, { type: i1$4.Router }, { type: IdentityService }]; } });
1578
+ args: [{ selector: 'app-side-navigation', animations: [
1579
+ trigger('sideNavAnimation', [
1580
+ state('in', style({ transform: 'translateX(0%)' })),
1581
+ state('out', style({ transform: 'translateX(110%)' })),
1582
+ transition('in => out', [
1583
+ animate('100ms ease-out', style({ transform: 'translateX(110%)' }))
1584
+ ]),
1585
+ transition('out => in', [
1586
+ animate('100ms ease-in', style({ transform: 'translateX(0%)' }))
1587
+ ])
1588
+ ]),
1589
+ ], 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"] }]
1590
+ }], ctorParameters: function () { return [{ type: EntryService }, { type: i1$4.Router }, { type: IdentityService }, { type: i0.Renderer2 }]; }, propDecorators: { divNav: [{
1591
+ type: ViewChild,
1592
+ args: ['navcontainer', { static: false }]
1593
+ }] } });
1516
1594
 
1517
1595
  class MainComponent {
1518
1596
  constructor(router) {
@@ -1723,6 +1801,7 @@ CoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15
1723
1801
  MatDatepickerModule,
1724
1802
  MatNativeDateModule,
1725
1803
  MatTableModule,
1804
+ MatProgressSpinnerModule,
1726
1805
  FontAwesomeModule,
1727
1806
  FileUploadModule,
1728
1807
  NgxMaterialTimepickerModule], exports: [EntryRendererComponent,
@@ -1767,6 +1846,7 @@ CoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15
1767
1846
  MatDatepickerModule,
1768
1847
  MatNativeDateModule,
1769
1848
  MatTableModule,
1849
+ MatProgressSpinnerModule,
1770
1850
  FontAwesomeModule,
1771
1851
  FileUploadModule,
1772
1852
  NgxMaterialTimepickerModule] });
@@ -1811,6 +1891,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1811
1891
  MatDatepickerModule,
1812
1892
  MatNativeDateModule,
1813
1893
  MatTableModule,
1894
+ MatProgressSpinnerModule,
1814
1895
  FontAwesomeModule,
1815
1896
  FileUploadModule,
1816
1897
  NgxMaterialTimepickerModule,