hoodcms 5.0.15 → 6.0.2
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/dist/css/login.css +1 -1
- package/dist/js/admin/ContentController.d.ts +30 -0
- package/dist/js/admin/ContentController.js +188 -0
- package/dist/js/admin/ContentTypeController.d.ts +15 -0
- package/dist/js/admin/ContentTypeController.js +140 -0
- package/dist/js/admin/HomeController.d.ts +17 -0
- package/dist/js/admin/HomeController.js +111 -0
- package/dist/js/admin/LogsController.d.ts +6 -0
- package/dist/js/admin/LogsController.js +14 -0
- package/dist/js/admin/MediaController.d.ts +7 -0
- package/dist/js/admin/MediaController.js +29 -0
- package/dist/js/admin/PropertyController.d.ts +18 -0
- package/dist/js/admin/PropertyController.js +118 -0
- package/dist/js/admin/PropertyImporter.d.ts +31 -0
- package/dist/js/admin/PropertyImporter.js +95 -0
- package/dist/js/admin/ThemesController.d.ts +8 -0
- package/dist/js/admin/ThemesController.js +37 -0
- package/dist/js/admin/UsersController.d.ts +17 -0
- package/dist/js/admin/UsersController.js +176 -0
- package/dist/js/admin.js +7 -7
- package/dist/js/app/PropertyService.d.ts +46 -0
- package/{src/ts/app/PropertyController.ts → dist/js/app/PropertyService.js} +44 -76
- package/dist/js/app.js +16 -4
- package/dist/js/app.property.js +5 -5
- package/dist/js/core/DataList.js +25 -3
- package/dist/js/index.d.ts +10 -0
- package/dist/js/index.js +12 -0
- package/dist/js/login.js +1 -1
- package/images/hood-small.png +0 -0
- package/images/hood.png +0 -0
- package/package.json +108 -108
- package/src/css/admin.css +0 -3
- package/src/css/admin.css.map +1 -1
- package/src/css/app.css +0 -3
- package/src/css/app.css.map +1 -1
- package/src/css/login.css +165 -0
- package/src/css/login.css.map +1 -1
- package/src/html/auth0/login.html +100 -0
- package/src/html/auth0/passwordless-email.html +184 -0
- package/src/js/admin.js +835 -664
- package/src/js/admin.js.map +1 -1
- package/src/js/app.js +11546 -5
- package/src/js/app.js.map +1 -1
- package/src/js/app.property.js +175 -129
- package/src/js/app.property.js.map +1 -1
- package/src/js/login.js +1 -1
- package/src/scss/core/_images.scss +48 -48
- package/src/scss/login.scss +1 -0
- package/src/ts/app/PropertyService.ts +202 -0
- package/src/ts/app.property.ts +4 -5
- package/src/ts/core/DataList.ts +27 -4
- package/src/ts/index.ts +14 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/// <reference types="jquery" />
|
|
2
|
+
import { DataList } from "../core/DataList";
|
|
3
|
+
export declare class ContentController {
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Content list element, #content-list
|
|
7
|
+
*/
|
|
8
|
+
element: HTMLElement;
|
|
9
|
+
/**
|
|
10
|
+
* Content DataList object.
|
|
11
|
+
*/
|
|
12
|
+
list: DataList;
|
|
13
|
+
/**
|
|
14
|
+
* Content list element, #content-list
|
|
15
|
+
*/
|
|
16
|
+
categoryElement: HTMLElement;
|
|
17
|
+
/**
|
|
18
|
+
* Content DataList object.
|
|
19
|
+
*/
|
|
20
|
+
categoryList: DataList;
|
|
21
|
+
manage(this: ContentController): void;
|
|
22
|
+
create(this: ContentController, e: JQuery.ClickEvent): void;
|
|
23
|
+
delete(this: ContentController, e: JQuery.ClickEvent): void;
|
|
24
|
+
setStatus(this: ContentController, e: JQuery.ClickEvent): void;
|
|
25
|
+
clone(this: ContentController, e: JQuery.ClickEvent): void;
|
|
26
|
+
createOrEditCategory(this: ContentController, e: JQuery.ClickEvent): void;
|
|
27
|
+
deleteCategory(this: ContentController, e: JQuery.ClickEvent): void;
|
|
28
|
+
toggleCategory(this: ContentController, e: JQuery.ClickEvent): void;
|
|
29
|
+
removeMedia(this: ContentController, e: JQuery.ClickEvent): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Alerts } from "../core/Alerts";
|
|
2
|
+
import { DataList } from "../core/DataList";
|
|
3
|
+
import { Inline } from "../core/Inline";
|
|
4
|
+
import { ModalController } from "../core/Modal";
|
|
5
|
+
import { Response } from "../core/Response";
|
|
6
|
+
import { Validator } from "../core/Validator";
|
|
7
|
+
export class ContentController {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.manage();
|
|
10
|
+
$('body').on('click', '.content-create', this.create.bind(this));
|
|
11
|
+
$('body').on('click', '.content-delete', this.delete.bind(this));
|
|
12
|
+
$('body').on('click', '.content-set-status', this.setStatus.bind(this));
|
|
13
|
+
$('body').on('click', '.content-categories-delete', this.deleteCategory.bind(this));
|
|
14
|
+
$('body').on('click', '.content-categories-create,.content-categories-edit', this.createOrEditCategory.bind(this));
|
|
15
|
+
$('body').on('change', '.content-categories-check', this.toggleCategory.bind(this));
|
|
16
|
+
$('body').on('click', '.content-media-delete', this.removeMedia.bind(this));
|
|
17
|
+
$('body').on('keyup', '#Slug', function () {
|
|
18
|
+
let slugValue = $(this).val();
|
|
19
|
+
$('.slug-display').html(slugValue);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
manage() {
|
|
23
|
+
this.element = document.getElementById('content-list');
|
|
24
|
+
if (this.element) {
|
|
25
|
+
this.list = new DataList(this.element, {
|
|
26
|
+
onComplete: function (data, sender = null) {
|
|
27
|
+
Alerts.log('Finished loading content list.', 'info');
|
|
28
|
+
}.bind(this)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
this.categoryElement = document.getElementById('content-categories-list');
|
|
32
|
+
if (this.categoryElement) {
|
|
33
|
+
this.categoryList = new DataList(this.categoryElement, {
|
|
34
|
+
onComplete: function (data, sender = null) {
|
|
35
|
+
Alerts.log('Finished loading category list.', 'info');
|
|
36
|
+
}.bind(this)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
create(e) {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
e.stopPropagation();
|
|
43
|
+
let createContentModal = new ModalController({
|
|
44
|
+
onComplete: function () {
|
|
45
|
+
let form = document.getElementById('content-create-form');
|
|
46
|
+
new Validator(form, {
|
|
47
|
+
onComplete: function (response) {
|
|
48
|
+
Response.process(response, 5000);
|
|
49
|
+
if (this.list) {
|
|
50
|
+
this.list.reload();
|
|
51
|
+
}
|
|
52
|
+
if (response.success) {
|
|
53
|
+
createContentModal.close();
|
|
54
|
+
}
|
|
55
|
+
}.bind(this)
|
|
56
|
+
});
|
|
57
|
+
}.bind(this)
|
|
58
|
+
});
|
|
59
|
+
createContentModal.show($(e.currentTarget).attr('href'), this.element);
|
|
60
|
+
}
|
|
61
|
+
delete(e) {
|
|
62
|
+
e.preventDefault();
|
|
63
|
+
e.stopPropagation();
|
|
64
|
+
Alerts.confirm({
|
|
65
|
+
// Confirm options...
|
|
66
|
+
title: "Are you sure?",
|
|
67
|
+
html: "The content will be permanently removed."
|
|
68
|
+
}, function (result) {
|
|
69
|
+
if (result.isConfirmed) {
|
|
70
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
71
|
+
Response.process(data, 5000);
|
|
72
|
+
if (this.list) {
|
|
73
|
+
this.list.reload();
|
|
74
|
+
}
|
|
75
|
+
if (e.currentTarget.dataset.redirect) {
|
|
76
|
+
Alerts.message('Just taking you back to the content list.', 'Redirecting...');
|
|
77
|
+
setTimeout(function () {
|
|
78
|
+
window.location = e.currentTarget.dataset.redirect;
|
|
79
|
+
}, 1500);
|
|
80
|
+
}
|
|
81
|
+
}.bind(this));
|
|
82
|
+
}
|
|
83
|
+
}.bind(this));
|
|
84
|
+
}
|
|
85
|
+
setStatus(e) {
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
e.stopPropagation();
|
|
88
|
+
Alerts.confirm({
|
|
89
|
+
// Confirm options...
|
|
90
|
+
title: "Are you sure?",
|
|
91
|
+
html: "The change will happen immediately."
|
|
92
|
+
}, function (result) {
|
|
93
|
+
if (result.isConfirmed) {
|
|
94
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
95
|
+
Response.process(data, 5000);
|
|
96
|
+
if (this.list) {
|
|
97
|
+
this.list.reload();
|
|
98
|
+
}
|
|
99
|
+
}.bind(this));
|
|
100
|
+
}
|
|
101
|
+
}.bind(this));
|
|
102
|
+
}
|
|
103
|
+
clone(e) {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
Alerts.confirm({
|
|
107
|
+
// Confirm options...
|
|
108
|
+
title: "Are you sure?",
|
|
109
|
+
html: "This will duplicate the content and everything inside it."
|
|
110
|
+
}, function (result) {
|
|
111
|
+
if (result.isConfirmed) {
|
|
112
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
113
|
+
Response.process(data, 5000);
|
|
114
|
+
if (this.list) {
|
|
115
|
+
this.list.reload();
|
|
116
|
+
}
|
|
117
|
+
}.bind(this));
|
|
118
|
+
}
|
|
119
|
+
}.bind(this));
|
|
120
|
+
}
|
|
121
|
+
createOrEditCategory(e) {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
e.stopPropagation();
|
|
124
|
+
let createCategoryModal = new ModalController({
|
|
125
|
+
onComplete: function () {
|
|
126
|
+
let form = document.getElementById('content-categories-edit-form');
|
|
127
|
+
new Validator(form, {
|
|
128
|
+
onComplete: function (response) {
|
|
129
|
+
Response.process(response, 5000);
|
|
130
|
+
if (this.list) {
|
|
131
|
+
this.list.reload();
|
|
132
|
+
}
|
|
133
|
+
if (response.success) {
|
|
134
|
+
this.categoryList.reload();
|
|
135
|
+
createCategoryModal.close();
|
|
136
|
+
}
|
|
137
|
+
}.bind(this)
|
|
138
|
+
});
|
|
139
|
+
}.bind(this)
|
|
140
|
+
});
|
|
141
|
+
createCategoryModal.show($(e.currentTarget).attr('href'), this.element);
|
|
142
|
+
}
|
|
143
|
+
deleteCategory(e) {
|
|
144
|
+
e.preventDefault();
|
|
145
|
+
e.stopPropagation();
|
|
146
|
+
Alerts.confirm({
|
|
147
|
+
// Confirm options...
|
|
148
|
+
}, function (result) {
|
|
149
|
+
if (result.isConfirmed) {
|
|
150
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
151
|
+
// category deleted...
|
|
152
|
+
Response.process(data, 5000);
|
|
153
|
+
this.categoryList.reload();
|
|
154
|
+
}.bind(this));
|
|
155
|
+
}
|
|
156
|
+
}.bind(this));
|
|
157
|
+
}
|
|
158
|
+
toggleCategory(e) {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
e.stopPropagation();
|
|
161
|
+
$.post($(e.currentTarget).data('url'), { categoryId: $(e.currentTarget).val(), add: $(e.currentTarget).is(':checked') }, function (response) {
|
|
162
|
+
Response.process(response, 5000);
|
|
163
|
+
if (this.categoryList) {
|
|
164
|
+
this.categoryList.reload();
|
|
165
|
+
}
|
|
166
|
+
}.bind(this));
|
|
167
|
+
}
|
|
168
|
+
removeMedia(e) {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
e.stopPropagation();
|
|
171
|
+
Alerts.confirm({
|
|
172
|
+
// Confirm options...
|
|
173
|
+
title: "Are you sure?",
|
|
174
|
+
html: "The media will be removed from the property, but will still be in the media collection."
|
|
175
|
+
}, function (result) {
|
|
176
|
+
if (result.isConfirmed) {
|
|
177
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
178
|
+
Response.process(data, 5000);
|
|
179
|
+
// reload the property media gallery, should be attached to #property-gallery-list
|
|
180
|
+
let mediaGalleryEl = document.getElementById('content-gallery-list');
|
|
181
|
+
if (mediaGalleryEl.hoodDataList) {
|
|
182
|
+
mediaGalleryEl.hoodDataList.reload();
|
|
183
|
+
}
|
|
184
|
+
}.bind(this));
|
|
185
|
+
}
|
|
186
|
+
}.bind(this));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="jquery" />
|
|
2
|
+
import { DataList } from "../core/DataList";
|
|
3
|
+
export declare class ContentTypeController {
|
|
4
|
+
constructor();
|
|
5
|
+
element: HTMLElement;
|
|
6
|
+
list: DataList;
|
|
7
|
+
fieldsElement: HTMLElement;
|
|
8
|
+
fieldsList: DataList;
|
|
9
|
+
manage(this: ContentTypeController): void;
|
|
10
|
+
create(this: ContentTypeController, e: JQuery.ClickEvent): void;
|
|
11
|
+
delete(this: ContentTypeController, e: JQuery.ClickEvent): void;
|
|
12
|
+
setStatus(this: ContentTypeController, e: JQuery.ClickEvent): void;
|
|
13
|
+
createField(this: ContentTypeController, e: JQuery.ClickEvent): void;
|
|
14
|
+
deleteField(this: ContentTypeController, e: JQuery.ClickEvent): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Alerts } from "../core/Alerts";
|
|
2
|
+
import { DataList } from "../core/DataList";
|
|
3
|
+
import { Inline } from "../core/Inline";
|
|
4
|
+
import { ModalController } from "../core/Modal";
|
|
5
|
+
import { Response } from "../core/Response";
|
|
6
|
+
import { Validator } from "../core/Validator";
|
|
7
|
+
export class ContentTypeController {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.manage();
|
|
10
|
+
$('body').on('click', '.content-type-create', this.create.bind(this));
|
|
11
|
+
$('body').on('click', '.content-type-delete', this.delete.bind(this));
|
|
12
|
+
$('body').on('click', '.content-type-set-status', this.setStatus.bind(this));
|
|
13
|
+
$('body').on('click', '.content-custom-field-create', this.createField.bind(this));
|
|
14
|
+
$('body').on('click', '.content-custom-field-delete', this.deleteField.bind(this));
|
|
15
|
+
$('body').on('keyup', '#Slug', function () {
|
|
16
|
+
let slugValue = $(this).val();
|
|
17
|
+
$('.slug-display').html(slugValue);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
manage() {
|
|
21
|
+
this.element = document.getElementById('content-type-list');
|
|
22
|
+
if (this.element) {
|
|
23
|
+
this.list = new DataList(this.element, {
|
|
24
|
+
onComplete: function (data, sender = null) {
|
|
25
|
+
Alerts.log('Finished loading content type list.', 'info');
|
|
26
|
+
}.bind(this)
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
this.fieldsElement = document.getElementById('content-custom-field-list');
|
|
30
|
+
if (this.fieldsElement) {
|
|
31
|
+
this.fieldsList = new DataList(this.fieldsElement, {
|
|
32
|
+
onComplete: function (data, sender = null) {
|
|
33
|
+
Alerts.log('Finished loading content type list.', 'info');
|
|
34
|
+
}.bind(this)
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
create(e) {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
e.stopPropagation();
|
|
41
|
+
let createContentModal = new ModalController({
|
|
42
|
+
onComplete: function () {
|
|
43
|
+
let form = document.getElementById('content-type-create-form');
|
|
44
|
+
new Validator(form, {
|
|
45
|
+
onComplete: function (response) {
|
|
46
|
+
Response.process(response, 5000);
|
|
47
|
+
if (this.list) {
|
|
48
|
+
this.list.reload();
|
|
49
|
+
}
|
|
50
|
+
if (response.success) {
|
|
51
|
+
createContentModal.close();
|
|
52
|
+
}
|
|
53
|
+
}.bind(this)
|
|
54
|
+
});
|
|
55
|
+
}.bind(this)
|
|
56
|
+
});
|
|
57
|
+
createContentModal.show($(e.currentTarget).attr('href'), this.element);
|
|
58
|
+
}
|
|
59
|
+
delete(e) {
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
e.stopPropagation();
|
|
62
|
+
Alerts.confirm({
|
|
63
|
+
// Confirm options...
|
|
64
|
+
title: "Are you sure?",
|
|
65
|
+
html: "The content type will be permanently removed. Content will remain, but will be unusable and marked as the old content type."
|
|
66
|
+
}, function (result) {
|
|
67
|
+
if (result.isConfirmed) {
|
|
68
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
69
|
+
Response.process(data, 5000);
|
|
70
|
+
if (this.list) {
|
|
71
|
+
this.list.reload();
|
|
72
|
+
}
|
|
73
|
+
if (e.currentTarget.dataset.redirect) {
|
|
74
|
+
Alerts.message('Just taking you back to the content list.', 'Redirecting...');
|
|
75
|
+
setTimeout(function () {
|
|
76
|
+
window.location = e.currentTarget.dataset.redirect;
|
|
77
|
+
}, 1500);
|
|
78
|
+
}
|
|
79
|
+
}.bind(this));
|
|
80
|
+
}
|
|
81
|
+
}.bind(this));
|
|
82
|
+
}
|
|
83
|
+
setStatus(e) {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
Alerts.confirm({
|
|
87
|
+
// Confirm options...
|
|
88
|
+
title: "Are you sure?",
|
|
89
|
+
html: "The change will happen immediately."
|
|
90
|
+
}, function (result) {
|
|
91
|
+
if (result.isConfirmed) {
|
|
92
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
93
|
+
Response.process(data, 5000);
|
|
94
|
+
if (this.list) {
|
|
95
|
+
this.list.reload();
|
|
96
|
+
}
|
|
97
|
+
}.bind(this));
|
|
98
|
+
}
|
|
99
|
+
}.bind(this));
|
|
100
|
+
}
|
|
101
|
+
createField(e) {
|
|
102
|
+
e.preventDefault();
|
|
103
|
+
e.stopPropagation();
|
|
104
|
+
let createContentModal = new ModalController({
|
|
105
|
+
onComplete: function () {
|
|
106
|
+
let form = document.getElementById('content-custom-field-create-form');
|
|
107
|
+
new Validator(form, {
|
|
108
|
+
onComplete: function (response) {
|
|
109
|
+
Response.process(response, 5000);
|
|
110
|
+
if (this.fieldsList) {
|
|
111
|
+
this.fieldsList.reload();
|
|
112
|
+
}
|
|
113
|
+
if (response.success) {
|
|
114
|
+
createContentModal.close();
|
|
115
|
+
}
|
|
116
|
+
}.bind(this)
|
|
117
|
+
});
|
|
118
|
+
}.bind(this)
|
|
119
|
+
});
|
|
120
|
+
createContentModal.show($(e.currentTarget).attr('href'), this.element);
|
|
121
|
+
}
|
|
122
|
+
deleteField(e) {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
e.stopPropagation();
|
|
125
|
+
Alerts.confirm({
|
|
126
|
+
// Confirm options...
|
|
127
|
+
title: "Are you sure?",
|
|
128
|
+
html: "The field will be permanently removed. However fields will still be attached to content."
|
|
129
|
+
}, function (result) {
|
|
130
|
+
if (result.isConfirmed) {
|
|
131
|
+
Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
|
|
132
|
+
Response.process(data, 5000);
|
|
133
|
+
if (this.fieldsList) {
|
|
134
|
+
this.fieldsList.reload();
|
|
135
|
+
}
|
|
136
|
+
}.bind(this));
|
|
137
|
+
}
|
|
138
|
+
}.bind(this));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ContentStatistics } from "../models/Content";
|
|
2
|
+
import { PropertyStatistics } from "../models/Property";
|
|
3
|
+
import { UserStatistics } from "../models/Users";
|
|
4
|
+
export declare class HomeController {
|
|
5
|
+
canvas: HTMLCanvasElement;
|
|
6
|
+
ctx: CanvasRenderingContext2D;
|
|
7
|
+
chart: any;
|
|
8
|
+
constructor();
|
|
9
|
+
LoadChart(): void;
|
|
10
|
+
DrawChart(data: Statistics): void;
|
|
11
|
+
LoadStats(data: Statistics): void;
|
|
12
|
+
}
|
|
13
|
+
export declare class Statistics {
|
|
14
|
+
content: ContentStatistics;
|
|
15
|
+
users: UserStatistics;
|
|
16
|
+
properties: PropertyStatistics;
|
|
17
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Chart } from 'chart.js';
|
|
2
|
+
export class HomeController {
|
|
3
|
+
constructor() {
|
|
4
|
+
if ($('#admin-chart-area').length) {
|
|
5
|
+
let $this = this;
|
|
6
|
+
$this.LoadChart();
|
|
7
|
+
$('body').on('change', '#history', function () {
|
|
8
|
+
$this.LoadChart();
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
LoadChart() {
|
|
13
|
+
let $this = this;
|
|
14
|
+
$.get('/admin/stats/', function (data) {
|
|
15
|
+
$('#admin-chart-area').empty();
|
|
16
|
+
;
|
|
17
|
+
$('#admin-chart-area').html('<canvas id="admin-stats-chart"></canvas>');
|
|
18
|
+
$this.LoadStats(data);
|
|
19
|
+
$this.DrawChart(data);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
DrawChart(data) {
|
|
23
|
+
let datasets = [];
|
|
24
|
+
let dataLabels = [];
|
|
25
|
+
let contentColour = '#fabd07';
|
|
26
|
+
let propertyColour = '#20c997';
|
|
27
|
+
let userColour = '#fd7e14';
|
|
28
|
+
// 12 months
|
|
29
|
+
let labels = [];
|
|
30
|
+
// Content by day
|
|
31
|
+
let contentSet = [];
|
|
32
|
+
data.content.months.forEach(function (element) {
|
|
33
|
+
contentSet.push(element.value);
|
|
34
|
+
labels.push(element.key);
|
|
35
|
+
});
|
|
36
|
+
datasets.push({
|
|
37
|
+
label: 'New Content',
|
|
38
|
+
data: contentSet,
|
|
39
|
+
borderColor: contentColour,
|
|
40
|
+
backgroundColor: contentColour,
|
|
41
|
+
pointBackgroundColor: contentColour,
|
|
42
|
+
pointBorderColor: '#ffffff'
|
|
43
|
+
});
|
|
44
|
+
// users by day
|
|
45
|
+
contentSet = [];
|
|
46
|
+
data.users.months.forEach(function (element) {
|
|
47
|
+
contentSet.push(element.value);
|
|
48
|
+
});
|
|
49
|
+
datasets.push({
|
|
50
|
+
label: 'New Users',
|
|
51
|
+
data: contentSet,
|
|
52
|
+
borderColor: userColour,
|
|
53
|
+
backgroundColor: userColour,
|
|
54
|
+
pointBackgroundColor: userColour,
|
|
55
|
+
pointBorderColor: '#ffffff'
|
|
56
|
+
});
|
|
57
|
+
// Properties by day
|
|
58
|
+
contentSet = [];
|
|
59
|
+
data.properties.months.forEach(function (element) {
|
|
60
|
+
contentSet.push(element.value);
|
|
61
|
+
});
|
|
62
|
+
datasets.push({
|
|
63
|
+
label: 'New Properties',
|
|
64
|
+
data: contentSet,
|
|
65
|
+
borderColor: propertyColour,
|
|
66
|
+
backgroundColor: propertyColour,
|
|
67
|
+
pointBackgroundColor: propertyColour,
|
|
68
|
+
pointBorderColor: '#ffffff'
|
|
69
|
+
});
|
|
70
|
+
dataLabels = labels;
|
|
71
|
+
this.canvas = document.getElementById("admin-stats-chart");
|
|
72
|
+
this.ctx = this.canvas.getContext('2d');
|
|
73
|
+
this.chart = new Chart(this.ctx, {
|
|
74
|
+
type: 'bar',
|
|
75
|
+
data: {
|
|
76
|
+
labels: dataLabels,
|
|
77
|
+
datasets: datasets
|
|
78
|
+
},
|
|
79
|
+
options: {
|
|
80
|
+
responsive: true,
|
|
81
|
+
maintainAspectRatio: false,
|
|
82
|
+
scales: {
|
|
83
|
+
ticks: {
|
|
84
|
+
beginAtZero: true
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
LoadStats(data) {
|
|
91
|
+
if (data.content) {
|
|
92
|
+
$('.content-totalPosts').text(data.content.totalPosts);
|
|
93
|
+
$('.content-totalPublished').text(data.content.totalPublished);
|
|
94
|
+
if (data.content.byType) {
|
|
95
|
+
for (let i = 0; i < data.content.byType.length; i++) {
|
|
96
|
+
$('.content-' + data.content.byType[i].name + '-total').text(data.content.byType[i].total);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (data.users) {
|
|
101
|
+
$('.users-totalUsers').text(data.users.totalUsers);
|
|
102
|
+
$('.users-totalAdmins').text(data.users.totalAdmins);
|
|
103
|
+
}
|
|
104
|
+
if (data.properties) {
|
|
105
|
+
$('.properties-totalPosts').text(data.properties.totalProperties);
|
|
106
|
+
$('.properties-totalPublished').text(data.properties.totalPublished);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export class Statistics {
|
|
111
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Alerts } from "../core/Alerts";
|
|
2
|
+
import { DataList } from "../core/DataList";
|
|
3
|
+
export class LogsController {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.element = document.getElementById('log-list');
|
|
6
|
+
if (this.element) {
|
|
7
|
+
this.list = new DataList(this.element, {
|
|
8
|
+
onComplete: function (data, sender = null) {
|
|
9
|
+
Alerts.log('Finished loading logs list.', 'info');
|
|
10
|
+
}.bind(this)
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MediaService } from "../core/Media";
|
|
2
|
+
import { Alerts } from "../core/Alerts";
|
|
3
|
+
export class MediaController {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.manage();
|
|
6
|
+
}
|
|
7
|
+
manage() {
|
|
8
|
+
this.list = document.getElementById('media-list');
|
|
9
|
+
this.service = new MediaService(this.list, {
|
|
10
|
+
action: 'show',
|
|
11
|
+
onAction: function (mediaObject) {
|
|
12
|
+
Alerts.log(`Showing media object id ${mediaObject.id} - ${mediaObject.filename}`);
|
|
13
|
+
}.bind(this),
|
|
14
|
+
onListLoad: function () {
|
|
15
|
+
Alerts.log('Commencing media list fetch.');
|
|
16
|
+
},
|
|
17
|
+
onError: function (jqXHR, textStatus, errorThrown) {
|
|
18
|
+
Alerts.log(`Error loading media list: ${textStatus}`);
|
|
19
|
+
},
|
|
20
|
+
onListRender: function (data) {
|
|
21
|
+
Alerts.log('Fetched media list data.');
|
|
22
|
+
return data;
|
|
23
|
+
},
|
|
24
|
+
onListComplete: function () {
|
|
25
|
+
Alerts.log('Finished loading media list...', 'info');
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="jquery" />
|
|
2
|
+
import { DataList } from "../core/DataList";
|
|
3
|
+
export declare class PropertyController {
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Property list element, #property-list
|
|
7
|
+
*/
|
|
8
|
+
element: HTMLElement;
|
|
9
|
+
/**
|
|
10
|
+
* Property DataList object.
|
|
11
|
+
*/
|
|
12
|
+
list: DataList;
|
|
13
|
+
manage(this: PropertyController): void;
|
|
14
|
+
create(this: PropertyController, e: JQuery.ClickEvent): void;
|
|
15
|
+
delete(this: PropertyController, e: JQuery.ClickEvent): void;
|
|
16
|
+
setStatus(this: PropertyController, e: JQuery.ClickEvent): void;
|
|
17
|
+
removeMedia(this: PropertyController, e: JQuery.ClickEvent): void;
|
|
18
|
+
}
|