@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.
- package/esm2020/lib/components/side-navigation/side-navigation.component.mjs +123 -44
- package/esm2020/lib/core.module.mjs +5 -1
- package/esm2020/lib/services/entry.service.mjs +4 -1
- package/fesm2015/thecodeblogs-blog.mjs +124 -43
- package/fesm2015/thecodeblogs-blog.mjs.map +1 -1
- package/fesm2020/thecodeblogs-blog.mjs +124 -43
- package/fesm2020/thecodeblogs-blog.mjs.map +1 -1
- package/lib/components/side-navigation/side-navigation.component.d.ts +18 -4
- package/lib/core.module.d.ts +5 -4
- package/lib/services/entry.service.d.ts +1 -0
- package/package.json +1 -1
- package/version.json +0 -1
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
1402
|
-
this.getEntriesWithUrl(response.next);
|
|
1403
|
-
}
|
|
1404
|
-
else {
|
|
1405
|
-
this.organizeEntries();
|
|
1406
|
-
}
|
|
1423
|
+
this.organizeEntries(wipe);
|
|
1407
1424
|
});
|
|
1408
1425
|
}
|
|
1409
|
-
organizeEntries() {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
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
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
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
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
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
|
-
|
|
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
|
|
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',
|
|
1519
|
-
|
|
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,
|