@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 });
|
|
@@ -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
|
-
|
|
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
|
-
|
|
1398
|
-
this.getEntriesWithUrl(response.next);
|
|
1399
|
-
}
|
|
1400
|
-
else {
|
|
1401
|
-
this.organizeEntries();
|
|
1402
|
-
}
|
|
1419
|
+
this.organizeEntries(wipe);
|
|
1403
1420
|
});
|
|
1404
1421
|
}
|
|
1405
|
-
organizeEntries() {
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
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
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
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
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
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
|
-
|
|
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
|
|
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',
|
|
1515
|
-
|
|
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,
|