djgentelella 0.3.23__py3-none-any.whl → 0.3.25__py3-none-any.whl
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.
- djgentelella/__init__.py +1 -1
- djgentelella/locale/es/LC_MESSAGES/django.mo +0 -0
- djgentelella/locale/es/LC_MESSAGES/django.po +33 -2
- djgentelella/locale/es/LC_MESSAGES/djangojs.po +2 -2
- djgentelella/management/commands/createbasejs.py +3 -1
- djgentelella/management/commands/loaddevstatic.py +9 -0
- djgentelella/objectmanagement.py +2 -2
- djgentelella/serializers/paginators.py +15 -0
- djgentelella/static/djgentelella.vendors.min.css +19 -0
- djgentelella/static/djgentelella.vendors.min.js +6 -0
- djgentelella/static/gentelella/css/custom.css +23 -0
- djgentelella/static/gentelella/css/modern.css +22 -0
- djgentelella/static/gentelella/css/modern_black_white.css +21 -0
- djgentelella/static/gentelella/css/style_black_and_white.css +21 -0
- djgentelella/static/gentelella/js/base/api_list.js +135 -0
- djgentelella/static/gentelella/js/base/form.common.js +142 -0
- djgentelella/static/gentelella/js/base.js +281 -0
- djgentelella/static/gentelella/js/obj_api_management.js +5 -147
- djgentelella/static/gentelella/js/widgets.js +3 -0
- djgentelella/static/vendors/htmlx/htmx.min.js +1 -0
- djgentelella/static/vendors/pdfjs/interact.min.js +4 -0
- djgentelella/static/vendors/pdfjs/pdf.min.mjs +21 -0
- djgentelella/static/vendors/pdfjs/pdf.worker.min.mjs +21 -0
- djgentelella/static/vendors/pdfjs/pdf_viewer.min.css +19 -0
- djgentelella/templates/gentelella/base.html +5 -1
- djgentelella/templates/gentelella/blocks/listcard_template.html +60 -0
- djgentelella/templates/gentelella/blocks/squirrelly_pagination.html +34 -0
- djgentelella/templates/gentelella/plain.html +75 -0
- djgentelella/templates/gentelella/registration/logout.html +35 -19
- djgentelella/templates/gentelella/statics/javascript.html +4 -0
- djgentelella/templates/gentelella/statics/stylesheets.html +1 -2
- djgentelella/urls.py +3 -7
- djgentelella/views/auth.py +7 -2
- djgentelella/views/listAreaViewset.py +74 -0
- {djgentelella-0.3.23.dist-info → djgentelella-0.3.25.dist-info}/METADATA +13 -3
- {djgentelella-0.3.23.dist-info → djgentelella-0.3.25.dist-info}/RECORD +40 -28
- {djgentelella-0.3.23.dist-info → djgentelella-0.3.25.dist-info}/WHEEL +1 -1
- {djgentelella-0.3.23.dist-info → djgentelella-0.3.25.dist-info}/AUTHORS +0 -0
- {djgentelella-0.3.23.dist-info → djgentelella-0.3.25.dist-info}/LICENSE.txt +0 -0
- {djgentelella-0.3.23.dist-info → djgentelella-0.3.25.dist-info}/top_level.txt +0 -0
|
@@ -4653,3 +4653,26 @@ input-group > .custom-file {
|
|
|
4653
4653
|
margin: 0em 1.2em;
|
|
4654
4654
|
font-size: 1.3em;
|
|
4655
4655
|
}
|
|
4656
|
+
|
|
4657
|
+
.plainfooter {
|
|
4658
|
+
width: 100%;
|
|
4659
|
+
margin-left: 0px;
|
|
4660
|
+
background: #F7F7F7;
|
|
4661
|
+
padding: 15px 20px;
|
|
4662
|
+
display: block;
|
|
4663
|
+
height: 15vh;
|
|
4664
|
+
}
|
|
4665
|
+
|
|
4666
|
+
.plain_main{
|
|
4667
|
+
height: 80vh;
|
|
4668
|
+
display: flex;
|
|
4669
|
+
justify-content: center; /* Centrar horizontalmente */
|
|
4670
|
+
align-items: center; /* Centrar verticalmente */
|
|
4671
|
+
}
|
|
4672
|
+
|
|
4673
|
+
.logout_content {
|
|
4674
|
+
padding: 20px;
|
|
4675
|
+
background-color: #fff; /* Color de fondo para el contenido */
|
|
4676
|
+
border: 1px solid #1ABB9C;; /* Bordes */
|
|
4677
|
+
border-radius: 5px; /* Esquinas redondeadas */
|
|
4678
|
+
}
|
|
@@ -5349,3 +5349,25 @@ div.form-group {
|
|
|
5349
5349
|
border: 0;
|
|
5350
5350
|
line-height: 30px;
|
|
5351
5351
|
}
|
|
5352
|
+
|
|
5353
|
+
.plainfooter {
|
|
5354
|
+
width: 100%;
|
|
5355
|
+
margin-left: 0px;
|
|
5356
|
+
background: #F7F7F7;
|
|
5357
|
+
padding: 15px 20px;
|
|
5358
|
+
display: block;
|
|
5359
|
+
height: 15vh;
|
|
5360
|
+
}
|
|
5361
|
+
.plain_main{
|
|
5362
|
+
height: 80vh;
|
|
5363
|
+
display: flex;
|
|
5364
|
+
justify-content: center; /* Centrar horizontalmente */
|
|
5365
|
+
align-items: center; /* Centrar verticalmente */
|
|
5366
|
+
}
|
|
5367
|
+
|
|
5368
|
+
.logout_content {
|
|
5369
|
+
padding: 20px;
|
|
5370
|
+
background-color: #fff; /* Color de fondo para el contenido */
|
|
5371
|
+
border: 1px solid #1ABB9C;; /* Bordes */
|
|
5372
|
+
border-radius: 5px; /* Esquinas redondeadas */
|
|
5373
|
+
}
|
|
@@ -5351,3 +5351,24 @@ div.form-group {
|
|
|
5351
5351
|
line-height: 30px;
|
|
5352
5352
|
}
|
|
5353
5353
|
|
|
5354
|
+
.plainfooter {
|
|
5355
|
+
width: 100%;
|
|
5356
|
+
margin-left: 0px;
|
|
5357
|
+
background: #F7F7F7;
|
|
5358
|
+
padding: 15px 20px;
|
|
5359
|
+
display: block;
|
|
5360
|
+
height: 15vh;
|
|
5361
|
+
}
|
|
5362
|
+
.plain_main{
|
|
5363
|
+
height: 80vh;
|
|
5364
|
+
display: flex;
|
|
5365
|
+
justify-content: center; /* Centrar horizontalmente */
|
|
5366
|
+
align-items: center; /* Centrar verticalmente */
|
|
5367
|
+
}
|
|
5368
|
+
|
|
5369
|
+
.logout_content {
|
|
5370
|
+
padding: 20px;
|
|
5371
|
+
background-color: #fff; /* Color de fondo para el contenido */
|
|
5372
|
+
border: 1px solid #1ABB9C;; /* Bordes */
|
|
5373
|
+
border-radius: 5px; /* Esquinas redondeadas */
|
|
5374
|
+
}
|
|
@@ -5334,3 +5334,24 @@ input-group>.chunkedupload {
|
|
|
5334
5334
|
opacity: 0;
|
|
5335
5335
|
}
|
|
5336
5336
|
|
|
5337
|
+
.plainfooter {
|
|
5338
|
+
width: 100%;
|
|
5339
|
+
margin-left: 0px;
|
|
5340
|
+
background: #F7F7F7;
|
|
5341
|
+
padding: 15px 20px;
|
|
5342
|
+
display: block;
|
|
5343
|
+
height: 15vh;
|
|
5344
|
+
}
|
|
5345
|
+
.plain_main{
|
|
5346
|
+
height: 80vh;
|
|
5347
|
+
display: flex;
|
|
5348
|
+
justify-content: center; /* Centrar horizontalmente */
|
|
5349
|
+
align-items: center; /* Centrar verticalmente */
|
|
5350
|
+
}
|
|
5351
|
+
|
|
5352
|
+
.logout_content {
|
|
5353
|
+
padding: 20px;
|
|
5354
|
+
background-color: #fff; /* Color de fondo para el contenido */
|
|
5355
|
+
border: 1px solid #1ABB9C;; /* Bordes */
|
|
5356
|
+
border-radius: 5px; /* Esquinas redondeadas */
|
|
5357
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
class CardList {
|
|
2
|
+
constructor(containerId, apiUrl, actions={}) {
|
|
3
|
+
this.container = document.getElementById(containerId);
|
|
4
|
+
this.apiUrl = apiUrl;
|
|
5
|
+
this.page = 1;
|
|
6
|
+
this.data=null;
|
|
7
|
+
this.page_size = 10;
|
|
8
|
+
this.totalPages = 1;
|
|
9
|
+
this.recordsTotal = 0;
|
|
10
|
+
this.template = '';
|
|
11
|
+
this.filters = {};
|
|
12
|
+
this.actions=actions;
|
|
13
|
+
this.fetchData();
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async fetchData() {
|
|
18
|
+
try {
|
|
19
|
+
const queryParams = new URLSearchParams({
|
|
20
|
+
page: this.page,
|
|
21
|
+
page_size: this.page_size,
|
|
22
|
+
...(this.filters || {}),
|
|
23
|
+
}).toString();
|
|
24
|
+
|
|
25
|
+
const url = `${this.apiUrl}?${queryParams}`;
|
|
26
|
+
const response = await fetch(url);
|
|
27
|
+
if (!response.ok) throw new Error(`Error HTTP: ${response.status}`);
|
|
28
|
+
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
this.template = data.template || this.template;
|
|
31
|
+
this.totalPages = data.totalPages || 1;
|
|
32
|
+
this.recordsTotal = data.recordsTotal || 0;
|
|
33
|
+
this.process_data(data);
|
|
34
|
+
this.render(data);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('Error fetching data:', error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
process_data(data){
|
|
41
|
+
this.data={};
|
|
42
|
+
data.data.forEach(item => {
|
|
43
|
+
this.data[item.id]=item;
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
render(data) {
|
|
48
|
+
if (!this.template) {
|
|
49
|
+
console.error("No template found!");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.container.innerHTML = Sqrl.render(this.template, data, Sqrl.getConfig({ tags: ["<%", "%>"] }));
|
|
53
|
+
gt_find_initialize_from_dom(this.container);
|
|
54
|
+
this.doPagination();
|
|
55
|
+
this.dofiltering();
|
|
56
|
+
this.doPageSizeOptions();
|
|
57
|
+
this.doObjActions()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async getFilters(){
|
|
61
|
+
const form = this.container.querySelectorAll('.filter_form');
|
|
62
|
+
|
|
63
|
+
const result = await convertToStringJson(form);
|
|
64
|
+
this.filters = JSON.parse(result);
|
|
65
|
+
this.fetchData();
|
|
66
|
+
}
|
|
67
|
+
dofiltering(){
|
|
68
|
+
/**
|
|
69
|
+
const forminput = this.container.querySelectorAll('.filter_form input, .filter_form select');
|
|
70
|
+
const parent=this;
|
|
71
|
+
forminput.forEach(input => {
|
|
72
|
+
input.onchange=function(event){
|
|
73
|
+
parent.getFilters();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
**/
|
|
77
|
+
}
|
|
78
|
+
doPageSizeOptions(){
|
|
79
|
+
const formselect = this.container.querySelectorAll('.page_size_select');
|
|
80
|
+
const parent=this;
|
|
81
|
+
parent.page_size=parseInt(formselect[0].value);
|
|
82
|
+
formselect.forEach(input => {
|
|
83
|
+
input.onchange=function(event){
|
|
84
|
+
parent.page_size=event.target.value
|
|
85
|
+
parent.getFilters();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
doPagination(){
|
|
91
|
+
const alink = this.container.querySelectorAll('.pagination a');
|
|
92
|
+
const parent=this;
|
|
93
|
+
alink.forEach(link => {
|
|
94
|
+
link.onclick = function(event) {
|
|
95
|
+
parent.page=event.target.dataset.page;
|
|
96
|
+
parent.fetchData();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
doObjActions(){
|
|
101
|
+
const actions = this.container.querySelectorAll('.obj_action');
|
|
102
|
+
const parent=this;
|
|
103
|
+
actions.forEach(action => {
|
|
104
|
+
action.onclick = function(event) {
|
|
105
|
+
event.preventDefault();
|
|
106
|
+
var pk = action.dataset.instance;
|
|
107
|
+
var name = action.dataset.action;
|
|
108
|
+
if (typeof parent.actions[name] === 'function') {
|
|
109
|
+
parent.actions[name](pk, parent.data[pk]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
const generalactions = this.container.querySelectorAll('.general_action');
|
|
114
|
+
generalactions.forEach(action => {
|
|
115
|
+
action.onclick = function(event) {
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
var name = action.dataset.action;
|
|
118
|
+
if (typeof parent.actions[name] === 'function') {
|
|
119
|
+
parent.actions[name]();
|
|
120
|
+
}else{
|
|
121
|
+
if (typeof parent[name] === 'function') parent[name]();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
search(){
|
|
127
|
+
this.getFilters();
|
|
128
|
+
}
|
|
129
|
+
clean(){
|
|
130
|
+
const form = this.container.querySelectorAll('.filter_form');
|
|
131
|
+
clear_action_form(form);
|
|
132
|
+
this.container.querySelectorAll('.filter_form input').forEach(i=>{i.value="";});
|
|
133
|
+
this.getFilters();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
function convertFileToBase64(file) {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
const reader = new FileReader();
|
|
4
|
+
|
|
5
|
+
reader.onload = () => {
|
|
6
|
+
const base64String = reader.result.split(',')[1];
|
|
7
|
+
resolve(base64String);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
reader.onerror = (error) => {
|
|
11
|
+
reject(error);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
reader.readAsDataURL(file);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function obtainFormAsJSON(form, prefix = '', extras={}) {
|
|
19
|
+
const fields = form.elements;
|
|
20
|
+
const formData = {};
|
|
21
|
+
// typeof variable === 'function'
|
|
22
|
+
for( let key in extras){
|
|
23
|
+
if(typeof extras[key] === 'function'){
|
|
24
|
+
formData[key]=extras[key](form, key, prefix);
|
|
25
|
+
}else{
|
|
26
|
+
formData[key]=extras[key];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < fields.length; i++) {
|
|
31
|
+
const field = fields[i];
|
|
32
|
+
|
|
33
|
+
if (field.type !== 'submit' && field.type !== 'button') {
|
|
34
|
+
const fieldName = field.name.replace(prefix, '');
|
|
35
|
+
if(field.type === 'textarea'){
|
|
36
|
+
formData[fieldName] = $(field).val();
|
|
37
|
+
}else if(field.type === 'checkbox'){
|
|
38
|
+
formData[fieldName] = field.checked;
|
|
39
|
+
}else if (field.type === 'radio') {
|
|
40
|
+
if(field.checked){
|
|
41
|
+
formData[fieldName] = $(field).val();
|
|
42
|
+
}
|
|
43
|
+
}else if (field.type === 'file') {
|
|
44
|
+
const files = Array.from(field.files);
|
|
45
|
+
const filesBase64 = [];
|
|
46
|
+
|
|
47
|
+
for (let j = 0; j < files.length; j++) {
|
|
48
|
+
const file = files[j];
|
|
49
|
+
try {
|
|
50
|
+
const base64String = await convertFileToBase64(file);
|
|
51
|
+
filesBase64.push({ name: file.name, value: base64String });
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Error converting file:', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
formData[fieldName] = filesBase64;
|
|
58
|
+
} else if (field.multiple) {
|
|
59
|
+
const selectedOptions = Array.from(field.selectedOptions);
|
|
60
|
+
const selectedValues = selectedOptions.map((option) => option.value);
|
|
61
|
+
formData[fieldName] = selectedValues;
|
|
62
|
+
} else {
|
|
63
|
+
formData[fieldName] = field.value;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return JSON.stringify(formData);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function convertToStringJson(form, prefix="", extras={}){
|
|
72
|
+
result=obtainFormAsJSON(form[0], prefix=prefix, extras=extras);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function load_errors(error_list, obj, parentdiv){
|
|
77
|
+
ul_obj = "<ul class='errorlist form_errors d-flex justify-content-center'>";
|
|
78
|
+
error_list.forEach((item)=>{
|
|
79
|
+
ul_obj += "<li>"+item+"</li>";
|
|
80
|
+
});
|
|
81
|
+
ul_obj += "</ul>"
|
|
82
|
+
$(obj).parents(parentdiv).prepend(ul_obj);
|
|
83
|
+
return ul_obj;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function form_field_errors(target_form, form_errors, prefix, parentdiv){
|
|
87
|
+
var item = "";
|
|
88
|
+
for (const [key, value] of Object.entries(form_errors)) {
|
|
89
|
+
item = " #id_" +prefix+key;
|
|
90
|
+
if(target_form.find(item).length > 0){
|
|
91
|
+
load_errors(form_errors[key], item, parentdiv);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function response_manage_type_data(instance, err_json_fn, error_text_fn){
|
|
97
|
+
return function(response) {
|
|
98
|
+
const contentType = response.headers.get("content-type");
|
|
99
|
+
if(response.ok){
|
|
100
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
101
|
+
return response.json();
|
|
102
|
+
}else{
|
|
103
|
+
return response.text();
|
|
104
|
+
}
|
|
105
|
+
}else{
|
|
106
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
107
|
+
response.json().then(data => err_json_fn(instance, data));
|
|
108
|
+
}else{
|
|
109
|
+
response.text().then(data => error_text_fn(instance, data));
|
|
110
|
+
}
|
|
111
|
+
return Promise.resolve(false);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return Promise.reject(response); // then it will go to the catch if it is an error code
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function clear_action_form(form){
|
|
119
|
+
// clear switchery before the form reset so the check status doesn't get changed before the validation
|
|
120
|
+
$(form).find("input[data-switchery=true]").each(function() {
|
|
121
|
+
if($(this).prop("checked")){ // only reset it if it is checked
|
|
122
|
+
$(this).trigger("click").prop("checked", false);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
$(form).find('[data-widget="TaggingInput"],[data-widget="EmailTaggingInput"]').each(function(i, e) {
|
|
126
|
+
var tg=$(e).data().tagify;
|
|
127
|
+
tg.removeAllTags();
|
|
128
|
+
});
|
|
129
|
+
$(form).find('[data-widget="FileChunkedUpload"],[data-widget="FileInput"]').each(function(i, e) {
|
|
130
|
+
var tg=$(e).data().fileUploadWidget;
|
|
131
|
+
tg.resetEmpty();
|
|
132
|
+
});
|
|
133
|
+
$(form).trigger('reset');
|
|
134
|
+
$(form).find("select option:selected").prop("selected", false);
|
|
135
|
+
$(form).find("select").val(null).trigger('change');
|
|
136
|
+
$(form).find("ul.form_errors").remove();
|
|
137
|
+
$(form).find(".file-link").remove();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var gt_form_modals = {}
|
|
141
|
+
var gt_detail_modals = {}
|
|
142
|
+
var gt_crud_objs = {};
|
|
@@ -699,6 +699,150 @@ $.fn.select2related = function(action, relatedobjs=[]) {
|
|
|
699
699
|
|
|
700
700
|
})(jQuery)
|
|
701
701
|
|
|
702
|
+
function convertFileToBase64(file) {
|
|
703
|
+
return new Promise((resolve, reject) => {
|
|
704
|
+
const reader = new FileReader();
|
|
705
|
+
|
|
706
|
+
reader.onload = () => {
|
|
707
|
+
const base64String = reader.result.split(',')[1];
|
|
708
|
+
resolve(base64String);
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
reader.onerror = (error) => {
|
|
712
|
+
reject(error);
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
reader.readAsDataURL(file);
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
async function obtainFormAsJSON(form, prefix = '', extras={}) {
|
|
720
|
+
const fields = form.elements;
|
|
721
|
+
const formData = {};
|
|
722
|
+
// typeof variable === 'function'
|
|
723
|
+
for( let key in extras){
|
|
724
|
+
if(typeof extras[key] === 'function'){
|
|
725
|
+
formData[key]=extras[key](form, key, prefix);
|
|
726
|
+
}else{
|
|
727
|
+
formData[key]=extras[key];
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
for (let i = 0; i < fields.length; i++) {
|
|
732
|
+
const field = fields[i];
|
|
733
|
+
|
|
734
|
+
if (field.type !== 'submit' && field.type !== 'button') {
|
|
735
|
+
const fieldName = field.name.replace(prefix, '');
|
|
736
|
+
if(field.type === 'textarea'){
|
|
737
|
+
formData[fieldName] = $(field).val();
|
|
738
|
+
}else if(field.type === 'checkbox'){
|
|
739
|
+
formData[fieldName] = field.checked;
|
|
740
|
+
}else if (field.type === 'radio') {
|
|
741
|
+
if(field.checked){
|
|
742
|
+
formData[fieldName] = $(field).val();
|
|
743
|
+
}
|
|
744
|
+
}else if (field.type === 'file') {
|
|
745
|
+
const files = Array.from(field.files);
|
|
746
|
+
const filesBase64 = [];
|
|
747
|
+
|
|
748
|
+
for (let j = 0; j < files.length; j++) {
|
|
749
|
+
const file = files[j];
|
|
750
|
+
try {
|
|
751
|
+
const base64String = await convertFileToBase64(file);
|
|
752
|
+
filesBase64.push({ name: file.name, value: base64String });
|
|
753
|
+
} catch (error) {
|
|
754
|
+
console.error('Error converting file:', error);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
formData[fieldName] = filesBase64;
|
|
759
|
+
} else if (field.multiple) {
|
|
760
|
+
const selectedOptions = Array.from(field.selectedOptions);
|
|
761
|
+
const selectedValues = selectedOptions.map((option) => option.value);
|
|
762
|
+
formData[fieldName] = selectedValues;
|
|
763
|
+
} else {
|
|
764
|
+
formData[fieldName] = field.value;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return JSON.stringify(formData);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
function convertToStringJson(form, prefix="", extras={}){
|
|
773
|
+
result=obtainFormAsJSON(form[0], prefix=prefix, extras=extras);
|
|
774
|
+
return result;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
function load_errors(error_list, obj, parentdiv){
|
|
778
|
+
ul_obj = "<ul class='errorlist form_errors d-flex justify-content-center'>";
|
|
779
|
+
error_list.forEach((item)=>{
|
|
780
|
+
ul_obj += "<li>"+item+"</li>";
|
|
781
|
+
});
|
|
782
|
+
ul_obj += "</ul>"
|
|
783
|
+
$(obj).parents(parentdiv).prepend(ul_obj);
|
|
784
|
+
return ul_obj;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function form_field_errors(target_form, form_errors, prefix, parentdiv){
|
|
788
|
+
var item = "";
|
|
789
|
+
for (const [key, value] of Object.entries(form_errors)) {
|
|
790
|
+
item = " #id_" +prefix+key;
|
|
791
|
+
if(target_form.find(item).length > 0){
|
|
792
|
+
load_errors(form_errors[key], item, parentdiv);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
function response_manage_type_data(instance, err_json_fn, error_text_fn){
|
|
798
|
+
return function(response) {
|
|
799
|
+
const contentType = response.headers.get("content-type");
|
|
800
|
+
if(response.ok){
|
|
801
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
802
|
+
return response.json();
|
|
803
|
+
}else{
|
|
804
|
+
return response.text();
|
|
805
|
+
}
|
|
806
|
+
}else{
|
|
807
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
808
|
+
response.json().then(data => err_json_fn(instance, data));
|
|
809
|
+
}else{
|
|
810
|
+
response.text().then(data => error_text_fn(instance, data));
|
|
811
|
+
}
|
|
812
|
+
return Promise.resolve(false);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return Promise.reject(response); // then it will go to the catch if it is an error code
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
function clear_action_form(form){
|
|
820
|
+
// clear switchery before the form reset so the check status doesn't get changed before the validation
|
|
821
|
+
$(form).find("input[data-switchery=true]").each(function() {
|
|
822
|
+
if($(this).prop("checked")){ // only reset it if it is checked
|
|
823
|
+
$(this).trigger("click").prop("checked", false);
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
$(form).find('[data-widget="TaggingInput"],[data-widget="EmailTaggingInput"]').each(function(i, e) {
|
|
827
|
+
var tg=$(e).data().tagify;
|
|
828
|
+
tg.removeAllTags();
|
|
829
|
+
});
|
|
830
|
+
$(form).find('[data-widget="FileChunkedUpload"],[data-widget="FileInput"]').each(function(i, e) {
|
|
831
|
+
var tg=$(e).data().fileUploadWidget;
|
|
832
|
+
tg.resetEmpty();
|
|
833
|
+
});
|
|
834
|
+
$(form).trigger('reset');
|
|
835
|
+
$(form).find("select option:selected").prop("selected", false);
|
|
836
|
+
$(form).find("select").val(null).trigger('change');
|
|
837
|
+
$(form).find("ul.form_errors").remove();
|
|
838
|
+
$(form).find(".file-link").remove();
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
var gt_form_modals = {}
|
|
842
|
+
var gt_detail_modals = {}
|
|
843
|
+
var gt_crud_objs = {};
|
|
844
|
+
|
|
845
|
+
|
|
702
846
|
function gtforms(index,manager, formList, extra=true) {
|
|
703
847
|
return {
|
|
704
848
|
index: index,
|
|
@@ -1970,3 +2114,140 @@ function getMediaRecord(element, mediatype){
|
|
|
1970
2114
|
}
|
|
1971
2115
|
}
|
|
1972
2116
|
|
|
2117
|
+
|
|
2118
|
+
class CardList {
|
|
2119
|
+
constructor(containerId, apiUrl, actions={}) {
|
|
2120
|
+
this.container = document.getElementById(containerId);
|
|
2121
|
+
this.apiUrl = apiUrl;
|
|
2122
|
+
this.page = 1;
|
|
2123
|
+
this.data=null;
|
|
2124
|
+
this.page_size = 10;
|
|
2125
|
+
this.totalPages = 1;
|
|
2126
|
+
this.recordsTotal = 0;
|
|
2127
|
+
this.template = '';
|
|
2128
|
+
this.filters = {};
|
|
2129
|
+
this.actions=actions;
|
|
2130
|
+
this.fetchData();
|
|
2131
|
+
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
async fetchData() {
|
|
2135
|
+
try {
|
|
2136
|
+
const queryParams = new URLSearchParams({
|
|
2137
|
+
page: this.page,
|
|
2138
|
+
page_size: this.page_size,
|
|
2139
|
+
...(this.filters || {}),
|
|
2140
|
+
}).toString();
|
|
2141
|
+
|
|
2142
|
+
const url = `${this.apiUrl}?${queryParams}`;
|
|
2143
|
+
const response = await fetch(url);
|
|
2144
|
+
if (!response.ok) throw new Error(`Error HTTP: ${response.status}`);
|
|
2145
|
+
|
|
2146
|
+
const data = await response.json();
|
|
2147
|
+
this.template = data.template || this.template;
|
|
2148
|
+
this.totalPages = data.totalPages || 1;
|
|
2149
|
+
this.recordsTotal = data.recordsTotal || 0;
|
|
2150
|
+
this.process_data(data);
|
|
2151
|
+
this.render(data);
|
|
2152
|
+
} catch (error) {
|
|
2153
|
+
console.error('Error fetching data:', error);
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
process_data(data){
|
|
2158
|
+
this.data={};
|
|
2159
|
+
data.data.forEach(item => {
|
|
2160
|
+
this.data[item.id]=item;
|
|
2161
|
+
})
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
render(data) {
|
|
2165
|
+
if (!this.template) {
|
|
2166
|
+
console.error("No template found!");
|
|
2167
|
+
return;
|
|
2168
|
+
}
|
|
2169
|
+
this.container.innerHTML = Sqrl.render(this.template, data, Sqrl.getConfig({ tags: ["<%", "%>"] }));
|
|
2170
|
+
gt_find_initialize_from_dom(this.container);
|
|
2171
|
+
this.doPagination();
|
|
2172
|
+
this.dofiltering();
|
|
2173
|
+
this.doPageSizeOptions();
|
|
2174
|
+
this.doObjActions()
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
async getFilters(){
|
|
2178
|
+
const form = this.container.querySelectorAll('.filter_form');
|
|
2179
|
+
|
|
2180
|
+
const result = await convertToStringJson(form);
|
|
2181
|
+
this.filters = JSON.parse(result);
|
|
2182
|
+
this.fetchData();
|
|
2183
|
+
}
|
|
2184
|
+
dofiltering(){
|
|
2185
|
+
/**
|
|
2186
|
+
const forminput = this.container.querySelectorAll('.filter_form input, .filter_form select');
|
|
2187
|
+
const parent=this;
|
|
2188
|
+
forminput.forEach(input => {
|
|
2189
|
+
input.onchange=function(event){
|
|
2190
|
+
parent.getFilters();
|
|
2191
|
+
}
|
|
2192
|
+
});
|
|
2193
|
+
**/
|
|
2194
|
+
}
|
|
2195
|
+
doPageSizeOptions(){
|
|
2196
|
+
const formselect = this.container.querySelectorAll('.page_size_select');
|
|
2197
|
+
const parent=this;
|
|
2198
|
+
parent.page_size=parseInt(formselect[0].value);
|
|
2199
|
+
formselect.forEach(input => {
|
|
2200
|
+
input.onchange=function(event){
|
|
2201
|
+
parent.page_size=event.target.value
|
|
2202
|
+
parent.getFilters();
|
|
2203
|
+
}
|
|
2204
|
+
});
|
|
2205
|
+
|
|
2206
|
+
}
|
|
2207
|
+
doPagination(){
|
|
2208
|
+
const alink = this.container.querySelectorAll('.pagination a');
|
|
2209
|
+
const parent=this;
|
|
2210
|
+
alink.forEach(link => {
|
|
2211
|
+
link.onclick = function(event) {
|
|
2212
|
+
parent.page=event.target.dataset.page;
|
|
2213
|
+
parent.fetchData();
|
|
2214
|
+
}
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
doObjActions(){
|
|
2218
|
+
const actions = this.container.querySelectorAll('.obj_action');
|
|
2219
|
+
const parent=this;
|
|
2220
|
+
actions.forEach(action => {
|
|
2221
|
+
action.onclick = function(event) {
|
|
2222
|
+
event.preventDefault();
|
|
2223
|
+
var pk = action.dataset.instance;
|
|
2224
|
+
var name = action.dataset.action;
|
|
2225
|
+
if (typeof parent.actions[name] === 'function') {
|
|
2226
|
+
parent.actions[name](pk, parent.data[pk]);
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
})
|
|
2230
|
+
const generalactions = this.container.querySelectorAll('.general_action');
|
|
2231
|
+
generalactions.forEach(action => {
|
|
2232
|
+
action.onclick = function(event) {
|
|
2233
|
+
event.preventDefault();
|
|
2234
|
+
var name = action.dataset.action;
|
|
2235
|
+
if (typeof parent.actions[name] === 'function') {
|
|
2236
|
+
parent.actions[name]();
|
|
2237
|
+
}else{
|
|
2238
|
+
if (typeof parent[name] === 'function') parent[name]();
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
})
|
|
2242
|
+
}
|
|
2243
|
+
search(){
|
|
2244
|
+
this.getFilters();
|
|
2245
|
+
}
|
|
2246
|
+
clean(){
|
|
2247
|
+
const form = this.container.querySelectorAll('.filter_form');
|
|
2248
|
+
clear_action_form(form);
|
|
2249
|
+
this.container.querySelectorAll('.filter_form input').forEach(i=>{i.value="";});
|
|
2250
|
+
this.getFilters();
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
|