@dogiloki/artha-js 1.2.0 → 1.3.0
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/README.md +818 -1
- package/dist/artha.min.css +1 -1
- package/dist/artha.min.css.map +1 -1
- package/dist/artha.min.js +6 -1
- package/dist/assets/icons/refresh.svg +1 -0
- package/dist/assets/icons/search.svg +1 -0
- package/package.json +1 -1
- package/src/abstract/BaseComponent.js +72 -15
- package/src/components/artha-container.js +101 -20
- package/src/components/artha-form.js +17 -8
- package/src/components/input-search.js +104 -0
- package/src/core/TaskQueue.js +0 -5
- package/src/scss/colors.scss +30 -1
- package/src/scss/icons.scss +20 -0
- package/src/scss/main.scss +1 -0
package/dist/artha.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
artha-message{width:100%;padding:10px;text-align:left;font-size:1em;cursor:default}artha-message[type=error]{background-color:#f2dede;color:#b94a48}artha-message[type=success]{background-color:#dff0d8;color:#468847}artha-message[type=warning]{background-color:#fcf8e3;color:#c09853}artha-message[type=info]{background-color:#d9edf7;color:#3a87ad}artha-loader{display:inline-flex;flex-direction:column;align-items:center}artha-loader .loader-content{display:flex;justify-content:center;align-items:center;gap:10px}artha-loader[type=dots] .loader-content>div{width:10px;height:10px;background-color:#3b82f6;border-radius:50%;animation:dot 1.2s infinite ease-in-out}artha-loader[type=dots] .loader-content>div:nth-of-type(1){animation-delay:0s}artha-loader[type=dots] .loader-content>div:nth-of-type(2){animation-delay:.2s}artha-loader[type=dots] .loader-content>div:nth-of-type(3){animation-delay:.4s}artha-loader[type=ring] .loader-content>div{width:32px;height:32px;border:3px solid #93c5fd;border-top-color:#3b82f6;border-radius:50%;animation:ring .8s linear infinite}artha-loader span{font-size:1rem;color:#5b6e8c}@keyframes dot{0%,100%{transform:scale(0.8);opacity:.4}50%{transform:scale(1.2);opacity:1}}@keyframes ring{to{transform:rotate(360deg)}}/*# sourceMappingURL=artha.min.css.map */
|
|
1
|
+
.icon{width:1.2rem;height:1.2rem;display:inline-block;vertical-align:middle;background-color:#000;mask-repeat:no-repeat;mask-position:center;mask-size:contain;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;-webkit-mask-size:contain}.icon.search{mask-image:url("./assets/icons/search.svg");-webkit-mask-image:url("./assets/icons/search.svg")}artha-message{width:100%;padding:10px;text-align:left;font-size:1em;cursor:default}artha-message[type=error]{background-color:#f2dede;color:#b94a48}artha-message[type=success]{background-color:#dff0d8;color:#468847}artha-message[type=warning]{background-color:#fcf8e3;color:#c09853}artha-message[type=info]{background-color:#d9edf7;color:#3a87ad}artha-loader{display:inline-flex;flex-direction:column;align-items:center}artha-loader .loader-content{display:flex;justify-content:center;align-items:center;gap:10px}artha-loader[type=dots] .loader-content>div{width:10px;height:10px;background-color:#3b82f6;border-radius:50%;animation:dot 1.2s infinite ease-in-out}artha-loader[type=dots] .loader-content>div:nth-of-type(1){animation-delay:0s}artha-loader[type=dots] .loader-content>div:nth-of-type(2){animation-delay:.2s}artha-loader[type=dots] .loader-content>div:nth-of-type(3){animation-delay:.4s}artha-loader[type=ring] .loader-content>div{width:32px;height:32px;border:3px solid #93c5fd;border-top-color:#3b82f6;border-radius:50%;animation:ring .8s linear infinite}artha-loader span{font-size:1rem;color:#5b6e8c}@keyframes dot{0%,100%{transform:scale(0.8);opacity:.4}50%{transform:scale(1.2);opacity:1}}@keyframes ring{to{transform:rotate(360deg)}}/*# sourceMappingURL=artha.min.css.map */
|
package/dist/artha.min.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../src/scss/
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../src/scss/icons.scss","../src/scss/colors.scss","../src/scss/message.scss","../src/scss/loader.scss"],"names":[],"mappings":"AAEA,MACI,aACA,cACA,qBACA,sBACA,iBCFK,KDGL,sBACA,qBACA,kBACA,8BACA,6BACA,0BAEA,aACI,4CACA,oDEfR,cACI,WACA,aACA,gBACA,cACA,eAEA,0BACI,iBDcqB,QCbrB,MDSe,QCPnB,4BACI,iBDWuB,QCVvB,MDMiB,QCJrB,4BACI,iBDQuB,QCPvB,MDGiB,QCDrB,yBACI,iBDKoB,QCJpB,cCrBR,aACI,oBACA,sBACA,mBAEA,6BACI,aACA,uBACA,mBACA,SAKI,4CACI,WACA,YACA,iBFWO,QEVP,kBACA,wCAEA,2DACI,mBAEJ,2DACI,oBAEJ,2DACI,oBAQR,4CACI,WACA,YACA,yBACA,iBFZO,QEaP,kBACA,mCAIZ,kBACI,eACA,MFlBa,QEsBrB,eACI,QACI,qBACA,WAEJ,IACI,qBACA,WAIR,gBACI,GACI","file":"artha.min.css"}
|
package/dist/artha.min.js
CHANGED
|
@@ -6,6 +6,7 @@ import ArthaMessage from '../src/components/artha-message.js';
|
|
|
6
6
|
import ArthaLoader from '../src/components/artha-loader.js';
|
|
7
7
|
import ArthaContainer from '../src/components/artha-container.js';
|
|
8
8
|
import ArthaForm from '../src/components/artha-form.js';
|
|
9
|
+
import InputSearch from '../src/components/input-search.js';
|
|
9
10
|
|
|
10
11
|
export {
|
|
11
12
|
Util,
|
|
@@ -15,7 +16,8 @@ export {
|
|
|
15
16
|
ArthaMessage,
|
|
16
17
|
ArthaLoader,
|
|
17
18
|
ArthaContainer,
|
|
18
|
-
ArthaForm
|
|
19
|
+
ArthaForm,
|
|
20
|
+
InputSearch
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
Promise.resolve().then(()=>{
|
|
@@ -37,4 +39,7 @@ function registerComponents(){
|
|
|
37
39
|
if(!customElements.get('artha-loader')){
|
|
38
40
|
customElements.define('artha-loader',ArthaLoader);
|
|
39
41
|
}
|
|
42
|
+
if(!customElements.get('input-search')){
|
|
43
|
+
customElements.define('input-search',InputSearch);
|
|
44
|
+
}
|
|
40
45
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M482-160q-134 0-228-93t-94-227v-7l-64 64-56-56 160-160 160 160-56 56-64-64v7q0 100 70.5 170T482-240q26 0 51-6t49-18l60 60q-38 22-78 33t-82 11Zm278-161L600-481l56-56 64 64v-7q0-100-70.5-170T478-720q-26 0-51 6t-49 18l-60-60q38-22 78-33t82-11q134 0 228 93t94 227v7l64-64 56 56-160 160Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>
|
package/package.json
CHANGED
|
@@ -16,12 +16,15 @@ export default class BaseComponent extends HTMLElement{
|
|
|
16
16
|
this._updating=false;
|
|
17
17
|
// Mapeo de atributos
|
|
18
18
|
this._props=[];
|
|
19
|
+
// Mapeo de propiedade no reflejadas como atributos
|
|
20
|
+
this._memory={};
|
|
19
21
|
// Mapeo para indicar comportamiento especiales en el mapeo de atributos
|
|
20
22
|
this._special_props={
|
|
21
23
|
booleans:[], // Propiedades booleanas
|
|
22
24
|
element_refs:[], // Propiedades de referencian elementos por ID
|
|
23
25
|
defaults:{}, // Propiedades con valor por defecto
|
|
24
|
-
resolvers:{} // Propiedades con un callback
|
|
26
|
+
resolvers:{}, // Propiedades con un callback
|
|
27
|
+
reflect:{} // Guardar en memoria y no llamar a setAttribute y getAttribute
|
|
25
28
|
};
|
|
26
29
|
this.configureProperties(props,options);
|
|
27
30
|
}
|
|
@@ -43,12 +46,13 @@ export default class BaseComponent extends HTMLElement{
|
|
|
43
46
|
|
|
44
47
|
attributeChangedCallback(name,old_value,new_value){
|
|
45
48
|
if(old_value===new_value) return;
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
const attr=this._valueToAttr(name);
|
|
50
|
+
if(this._props.includes(attr)){
|
|
51
|
+
this._triggerUpdate(attr,this._getPropertyValue(attr));
|
|
48
52
|
}
|
|
49
|
-
this.onAttributeChanged(
|
|
53
|
+
this.onAttributeChanged(attr,old_value,new_value);
|
|
50
54
|
}
|
|
51
|
-
onAttributeChanged(
|
|
55
|
+
onAttributeChanged(prop,old_value,new_value){}
|
|
52
56
|
|
|
53
57
|
configureProperties(props,options={}){
|
|
54
58
|
if(props==null) return;
|
|
@@ -57,11 +61,40 @@ export default class BaseComponent extends HTMLElement{
|
|
|
57
61
|
booleans:options.booleans||[],
|
|
58
62
|
element_refs:options.element_refs||[],
|
|
59
63
|
defaults:options.defaults||{},
|
|
60
|
-
resolvers:options.resolvers||{}
|
|
64
|
+
resolvers:options.resolvers||{},
|
|
65
|
+
reflect:options.reflect||{}
|
|
61
66
|
};
|
|
62
67
|
this._setupProperties();
|
|
63
68
|
}
|
|
64
69
|
|
|
70
|
+
_isReflected(prop){
|
|
71
|
+
return this._special_props.reflect[prop]!==false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_getAttribute(attr){
|
|
75
|
+
return this.getAttribute(this._valueToAttr(attr));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
_setAttribute(attr,value){
|
|
79
|
+
return this.setAttribute(this._valueToAttr(attr),value);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_removeAttribute(attr){
|
|
83
|
+
return this.removeAttribute(this._valueToAttr(attr));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
_hasAttribute(attr){
|
|
87
|
+
return this.hasAttribute(this._valueToAttr(attr));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_valueToAttr(value){
|
|
91
|
+
return value.replace(/_/g,'-');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_attrToValue(value){
|
|
95
|
+
return value.replace(/-/g,'_');
|
|
96
|
+
}
|
|
97
|
+
|
|
65
98
|
_setupProperties(){
|
|
66
99
|
this._props.forEach((prop)=>{
|
|
67
100
|
Object.defineProperty(this,prop,{
|
|
@@ -76,10 +109,22 @@ export default class BaseComponent extends HTMLElement{
|
|
|
76
109
|
}
|
|
77
110
|
|
|
78
111
|
_getPropertyValue(prop){
|
|
112
|
+
// Propiedades que son se refleja como atributos
|
|
113
|
+
if(!this._isReflected(prop)){
|
|
114
|
+
if(prop in this._memory){
|
|
115
|
+
return this._memory[prop];
|
|
116
|
+
}
|
|
117
|
+
if(this._special_props.defaults[prop]!==undefined){
|
|
118
|
+
return this._special_props.defaults[prop];
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
79
122
|
// Propiedade que referencia un elemento por ID
|
|
80
123
|
if(this._special_props.element_refs.includes(prop)){
|
|
81
|
-
const element_id=this.
|
|
82
|
-
if(!element_id)
|
|
124
|
+
const element_id=this._getAttribute(prop);
|
|
125
|
+
if(!element_id){
|
|
126
|
+
return this._elements[prop]??null;
|
|
127
|
+
}
|
|
83
128
|
// Cache para evitar múltiples búsquedas en el DOM
|
|
84
129
|
if(!this._elements[prop] || this._elements[prop].id!==element_id){
|
|
85
130
|
this._elements[prop]=document.getElementById(element_id);
|
|
@@ -88,15 +133,15 @@ export default class BaseComponent extends HTMLElement{
|
|
|
88
133
|
}
|
|
89
134
|
// Propiedades con callback
|
|
90
135
|
if(this._special_props.resolvers[prop]){
|
|
91
|
-
const raw_value=this.
|
|
136
|
+
const raw_value=this._getAttribute(prop);
|
|
92
137
|
return this._special_props.resolvers[prop].get(raw_value,this);
|
|
93
138
|
}
|
|
94
139
|
// Propiedad booleana
|
|
95
140
|
if(this._special_props.booleans.includes(prop)){
|
|
96
|
-
return this.
|
|
141
|
+
return this._hasAttribute(prop) && this._getAttribute(prop)!=='false';
|
|
97
142
|
}
|
|
98
143
|
// Propiedad con valor por defecto
|
|
99
|
-
const value=this.
|
|
144
|
+
const value=this._getAttribute(prop);
|
|
100
145
|
if(value===null && this._special_props.defaults[prop]!==undefined){
|
|
101
146
|
return this._special_props.defaults[prop];
|
|
102
147
|
}
|
|
@@ -105,7 +150,13 @@ export default class BaseComponent extends HTMLElement{
|
|
|
105
150
|
|
|
106
151
|
_setPropertyValue(prop,value){
|
|
107
152
|
if(this._updating) return;
|
|
108
|
-
|
|
153
|
+
// Propiedades que son se refleja como atributos
|
|
154
|
+
if(this._isReflected(prop)===false){
|
|
155
|
+
this._memory[prop]=value;
|
|
156
|
+
this._triggerUpdate(prop,value);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const current_value=this._getAttribute(prop);
|
|
109
160
|
let new_value=value;
|
|
110
161
|
// Convertir a string para atributos
|
|
111
162
|
if(value===null || value===undefined){
|
|
@@ -126,9 +177,9 @@ export default class BaseComponent extends HTMLElement{
|
|
|
126
177
|
// Solo actualizar si cambió
|
|
127
178
|
if(current_value!==new_value){
|
|
128
179
|
if(new_value===null){
|
|
129
|
-
this.
|
|
180
|
+
this._removeAttribute(prop);
|
|
130
181
|
}else{
|
|
131
|
-
this.
|
|
182
|
+
this._setAttribute(prop,new_value);
|
|
132
183
|
}
|
|
133
184
|
this._triggerUpdate(prop,value);
|
|
134
185
|
}
|
|
@@ -136,7 +187,13 @@ export default class BaseComponent extends HTMLElement{
|
|
|
136
187
|
|
|
137
188
|
_initializeProperties(){
|
|
138
189
|
this._props.forEach((prop)=>{
|
|
139
|
-
|
|
190
|
+
if(this._isReflected(prop)===false){
|
|
191
|
+
if(this._special_props.defaults[prop]!==undefined){
|
|
192
|
+
this._memory[prop]=this._special_props.defaults[prop];
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const attrib_value=this._getAttribute(prop);
|
|
140
197
|
if(attrib_value!==null){
|
|
141
198
|
this[prop]=this._getPropertyValue(prop);
|
|
142
199
|
}else if(this._special_props.defaults[prop]!==undefined){
|
|
@@ -3,20 +3,29 @@ import Util from '../core/Util.js';
|
|
|
3
3
|
import EventBus from '../core/EventBus.js';
|
|
4
4
|
import XHR from '../core/XHR.js';
|
|
5
5
|
import TaskQueue from '../core/TaskQueue.js';
|
|
6
|
-
import ArthaMessage from './artha-message.js';
|
|
7
6
|
|
|
8
7
|
export default class ArthaContainer extends BaseComponent{
|
|
9
8
|
|
|
9
|
+
static defaults={
|
|
10
|
+
method:'GET',
|
|
11
|
+
pagination:10,
|
|
12
|
+
page:1,
|
|
13
|
+
response_type:'json'
|
|
14
|
+
};
|
|
15
|
+
|
|
10
16
|
constructor(){
|
|
11
17
|
super(
|
|
12
|
-
["template","action","action_router","method",
|
|
13
|
-
"pagination","message","searcher","selectable","multiple"],
|
|
18
|
+
["template","action","action_router","method","page","search",
|
|
19
|
+
"pagination","message","searcher","selectable","multiple","response_type"],
|
|
14
20
|
{
|
|
15
21
|
booleans:['searcher','selectable','multiple'],
|
|
16
|
-
element_refs:['template','
|
|
22
|
+
element_refs:['template','message'],
|
|
17
23
|
defaults:{
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
response_type:ArthaContainer.defaults.response_type
|
|
25
|
+
},
|
|
26
|
+
reflect:{
|
|
27
|
+
search:false,
|
|
28
|
+
response_type:false
|
|
20
29
|
}
|
|
21
30
|
}
|
|
22
31
|
);
|
|
@@ -26,26 +35,40 @@ export default class ArthaContainer extends BaseComponent{
|
|
|
26
35
|
this.onRenderItemIter=(element,data,iter_element,iter_data)=>{};
|
|
27
36
|
|
|
28
37
|
this.task_queue=TaskQueue.singleton();
|
|
38
|
+
this._current_xhr=null;
|
|
29
39
|
this.items={};
|
|
30
40
|
this.selection_store=new SelectionStore();
|
|
31
|
-
this.response_type='json';
|
|
32
41
|
this.message??=this.querySelector('artha-message')??this.querySelector(this.getAttribute('message-target'))??null;
|
|
33
42
|
this.id=this.getAttribute('id')??'container-'+BaseComponent.counter;
|
|
43
|
+
if(this.hasPagination()){
|
|
44
|
+
this.pagination=this.pagination||ArthaContainer.defaults.pagination;
|
|
45
|
+
this.page=this.page||ArthaContainer.defaults.page;
|
|
46
|
+
}
|
|
47
|
+
if(this.hasAction()){
|
|
48
|
+
this.method=this.method||ArthaContainer.defaults.method;
|
|
49
|
+
}
|
|
34
50
|
|
|
35
51
|
// Loader
|
|
36
52
|
this.loader_container=this._createLoader();
|
|
37
53
|
|
|
54
|
+
// Input de búsqueda
|
|
55
|
+
if(this.searcher){
|
|
56
|
+
this.searcher_input=Util.createElement('input-search');
|
|
57
|
+
this.appendChild(this.searcher_input);
|
|
58
|
+
this.searcher_input.addEventListener('search',(evt)=>this._handleSearch(evt));
|
|
59
|
+
this.searcher_input.addEventListener('cancel-search',(evt)=>this._cancelSearch(evt));
|
|
60
|
+
}
|
|
61
|
+
|
|
38
62
|
// Contenido
|
|
39
63
|
this.content=this.querySelector(':scope > dynamic-content') || this.appendChild(document.createElement('dynamic-content'));
|
|
40
64
|
this._content=this.content.children[0];
|
|
41
65
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.refresh();
|
|
66
|
+
if(this.hasAction()){
|
|
67
|
+
if(this.searcher){
|
|
68
|
+
this.refresh(this.searcher_input.value);
|
|
69
|
+
}else{
|
|
70
|
+
this.refresh();
|
|
71
|
+
}
|
|
49
72
|
}
|
|
50
73
|
}
|
|
51
74
|
|
|
@@ -54,16 +77,23 @@ export default class ArthaContainer extends BaseComponent{
|
|
|
54
77
|
}
|
|
55
78
|
|
|
56
79
|
_handleSearch(evt){
|
|
80
|
+
this.page=1;
|
|
57
81
|
if(this.action){
|
|
58
|
-
this.
|
|
82
|
+
this.search=evt.detail.query;
|
|
83
|
+
return this.refresh();
|
|
59
84
|
}else{
|
|
60
85
|
const search=evt.detail.query?.toLowerCase()??'';
|
|
61
|
-
for(const item of this.items
|
|
86
|
+
for(const item of this.items){
|
|
62
87
|
Util.modal(item,item.textContent.toLowerCase().includes(search));
|
|
63
88
|
}
|
|
64
89
|
}
|
|
65
90
|
}
|
|
66
91
|
|
|
92
|
+
_cancelSearch(evt){
|
|
93
|
+
this._current_xhr?.abort();
|
|
94
|
+
this._current_xhr=null;
|
|
95
|
+
}
|
|
96
|
+
|
|
67
97
|
// value - getter/setter
|
|
68
98
|
get value(){
|
|
69
99
|
if(!this.selectable) return null;
|
|
@@ -105,10 +135,20 @@ export default class ArthaContainer extends BaseComponent{
|
|
|
105
135
|
}
|
|
106
136
|
|
|
107
137
|
getData(search=null){
|
|
138
|
+
search??=this.search;
|
|
108
139
|
if(!this.action) return;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
140
|
+
let query={};
|
|
141
|
+
if(this.hasPagination()){
|
|
142
|
+
query={
|
|
143
|
+
pagination:this.pagination,
|
|
144
|
+
page:this.page
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if(search){
|
|
148
|
+
query['search']=search;
|
|
149
|
+
}
|
|
150
|
+
return this.task_queue.loadTask(`container-${this.id}`,null,(task)=>{
|
|
151
|
+
this._current_xhr=XHR.request({
|
|
112
152
|
url:this.action,
|
|
113
153
|
method:this.method,
|
|
114
154
|
headers:{
|
|
@@ -120,6 +160,7 @@ export default class ArthaContainer extends BaseComponent{
|
|
|
120
160
|
this.dispatchEvent(new CustomEvent('load',{detail:xhr}));
|
|
121
161
|
},
|
|
122
162
|
onData:(xhr,json)=>{
|
|
163
|
+
this._current_xhr=null;
|
|
123
164
|
// Respuesta procesada en en formato json
|
|
124
165
|
task.resolve(xhr,()=>{
|
|
125
166
|
this.dispatchEvent(new CustomEvent('resolve',{detail:json}));
|
|
@@ -132,6 +173,11 @@ export default class ArthaContainer extends BaseComponent{
|
|
|
132
173
|
onError:(err)=>{
|
|
133
174
|
this.message?.error(err??"Error de conexión");
|
|
134
175
|
task.onFinalize();
|
|
176
|
+
this._cancelSearch();
|
|
177
|
+
},
|
|
178
|
+
onAbort:(err)=>{
|
|
179
|
+
task.onFinalize();
|
|
180
|
+
this._cancelSearch();
|
|
135
181
|
}
|
|
136
182
|
});
|
|
137
183
|
},{
|
|
@@ -139,14 +185,49 @@ export default class ArthaContainer extends BaseComponent{
|
|
|
139
185
|
});
|
|
140
186
|
}
|
|
141
187
|
|
|
188
|
+
hasAction(){
|
|
189
|
+
return this.hasAttribute('action');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
hasPagination(){
|
|
193
|
+
return this.hasAttribute('pagination');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
nextPage(){
|
|
197
|
+
if(!this.hasPagination()) return;
|
|
198
|
+
this.page+=1;
|
|
199
|
+
return this.refresh(this.search);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
prevPage(){
|
|
203
|
+
if(!this.hasPagination()) return;
|
|
204
|
+
if(this.page>1){
|
|
205
|
+
this.page-=1;
|
|
206
|
+
}
|
|
207
|
+
return this.refresh(this.search);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
goToPage(page){
|
|
211
|
+
page=Number(page);
|
|
212
|
+
if(!this.hasPagination() || !Number.isInteger(page) || page<1) return;
|
|
213
|
+
this.page=page;
|
|
214
|
+
return this.refresh(this.search);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
resetPagination(refresh=false){
|
|
218
|
+
this.page=1;
|
|
219
|
+
if(refresh) return this.refresh(this.search);
|
|
220
|
+
}
|
|
221
|
+
|
|
142
222
|
refresh(search=null){
|
|
223
|
+
search??=this.search;
|
|
143
224
|
this.loader_container.remove();
|
|
144
225
|
if(this.template){
|
|
145
226
|
this.content.innerHTML="";
|
|
146
227
|
if(this._content) this.content.appendChild(this._content);
|
|
147
228
|
this.content.appendChild(this.loader_container);
|
|
148
229
|
}
|
|
149
|
-
this.getData(search);
|
|
230
|
+
return this.getData(search);
|
|
150
231
|
}
|
|
151
232
|
|
|
152
233
|
refreshWithData(data){
|
|
@@ -2,15 +2,26 @@ import BaseComponent from '../abstract/BaseComponent.js';
|
|
|
2
2
|
import Util from '../core/Util.js';
|
|
3
3
|
import XHR from '../core/XHR.js';
|
|
4
4
|
import TaskQueue from '../core/TaskQueue.js';
|
|
5
|
-
import ArthaMessage from './artha-message.js';
|
|
6
5
|
|
|
7
6
|
export default class ArthaForm extends BaseComponent{
|
|
8
7
|
|
|
8
|
+
static defaults={
|
|
9
|
+
response_type:'json'
|
|
10
|
+
};
|
|
11
|
+
|
|
9
12
|
constructor(){
|
|
10
|
-
super(
|
|
13
|
+
super([
|
|
14
|
+
'action','method','response_type','disable_submit'
|
|
15
|
+
],{
|
|
16
|
+
booleans:['disable_submit'],
|
|
17
|
+
defaults:{
|
|
18
|
+
'response_type':ArthaForm.defaults.response_type
|
|
19
|
+
},
|
|
20
|
+
reflect:{
|
|
21
|
+
response_type:false
|
|
22
|
+
}
|
|
23
|
+
});
|
|
11
24
|
this.task_queue=TaskQueue.singleton();
|
|
12
|
-
this.response_type=this.getAttribute('response-type')??'json';
|
|
13
|
-
this.disable_submit=this.hasAttribute('disable-submit');
|
|
14
25
|
this.message=this.querySelector('artha-message')??this.querySelector(this.getAttribute('message-target'))??null;
|
|
15
26
|
if(!this.message){
|
|
16
27
|
this.message=Util.createElement('artha-message');
|
|
@@ -112,13 +123,11 @@ export default class ArthaForm extends BaseComponent{
|
|
|
112
123
|
this.element_inputs.forEach((element)=>{
|
|
113
124
|
form_data[element.name]=element.type==='checkbox'?(element.checked?1:0):element.value;
|
|
114
125
|
});
|
|
115
|
-
const action=this.getAttribute('action')??'';
|
|
116
|
-
const method=this.getAttribute('method')??'GET';
|
|
117
126
|
const id=this.getAttribute('id');
|
|
118
127
|
this.task_queue.loadTask(`form-${id}`,null,(task)=>{
|
|
119
128
|
XHR.request({
|
|
120
|
-
url:action,
|
|
121
|
-
method:method,
|
|
129
|
+
url:this.action,
|
|
130
|
+
method:this.method,
|
|
122
131
|
data:form_data,
|
|
123
132
|
response_type:this.response_type,
|
|
124
133
|
onLoad:(xhr)=>{
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import BaseComponent from '../abstract/BaseComponent.js';
|
|
2
|
+
import Util from "../core/Util.js";
|
|
3
|
+
|
|
4
|
+
export default class InputSearch extends BaseComponent{
|
|
5
|
+
|
|
6
|
+
static defaults={
|
|
7
|
+
delay:300,
|
|
8
|
+
text:'Búscar',
|
|
9
|
+
icon:'../dist/assets/icons/search.svg'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
constructor(){
|
|
13
|
+
super([
|
|
14
|
+
'delay','text','value','input','button'
|
|
15
|
+
],{
|
|
16
|
+
element_refs:['input','button'],
|
|
17
|
+
resolvers:{
|
|
18
|
+
'value':{
|
|
19
|
+
set:(raw)=>{
|
|
20
|
+
return this.input.value=raw;
|
|
21
|
+
},
|
|
22
|
+
get:(raw)=>{
|
|
23
|
+
return this.input?.value??null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
defaults:{
|
|
28
|
+
delay:InputSearch.defaults.delay,
|
|
29
|
+
text:InputSearch.defaults.text
|
|
30
|
+
},
|
|
31
|
+
reflect:{
|
|
32
|
+
text:false
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
this._search_timer=null;
|
|
36
|
+
this._ensureStructure();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_ensureStructure(){
|
|
40
|
+
this.icon=InputSearch.defaults.icon;
|
|
41
|
+
this.style.display="flex";
|
|
42
|
+
this.input=this.appendChild(Util.createElement('input',(input)=>{
|
|
43
|
+
input.classList.add('input-field');
|
|
44
|
+
input.type="search";
|
|
45
|
+
input.placeholder=this.text;
|
|
46
|
+
}));
|
|
47
|
+
this.button=this.appendChild(Util.createElement('button',async(button)=>{
|
|
48
|
+
button.classList.add('button-search');
|
|
49
|
+
button.appendChild(Util.createElement('span',(span)=>{
|
|
50
|
+
span.classList.add('icon','search');
|
|
51
|
+
}));
|
|
52
|
+
}));
|
|
53
|
+
this._bindEvents();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_bindEvents(){
|
|
57
|
+
this.input.addEventListener('input',(evt)=>{
|
|
58
|
+
this._queueSearch();
|
|
59
|
+
});
|
|
60
|
+
this.input.addEventListener('keydown',(evt)=>{
|
|
61
|
+
if(evt.key==='Enter'){
|
|
62
|
+
evt.preventDefault();
|
|
63
|
+
this._cancelQueuedSearch();
|
|
64
|
+
this.search();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this.button.addEventListener('click',(evt)=>{
|
|
68
|
+
evt.preventDefault();
|
|
69
|
+
this._cancelQueuedSearch();
|
|
70
|
+
this.search();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_queueSearch(){
|
|
75
|
+
this._cancelQueuedSearch();
|
|
76
|
+
this._search_timer=setTimeout(()=>{
|
|
77
|
+
this.search();
|
|
78
|
+
this._search_timer=null;
|
|
79
|
+
},Number(this.delay));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_cancelQueuedSearch(){
|
|
83
|
+
this.dispatchEvent(new CustomEvent('cancel-search',{
|
|
84
|
+
detail:{
|
|
85
|
+
query:this.value
|
|
86
|
+
},
|
|
87
|
+
bubbles:true
|
|
88
|
+
}));
|
|
89
|
+
if(this._search_timer){
|
|
90
|
+
clearTimeout(this._search_timer);
|
|
91
|
+
this._search_timer=null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
search(){
|
|
96
|
+
this.dispatchEvent(new CustomEvent('search',{
|
|
97
|
+
detail:{
|
|
98
|
+
query:this.value
|
|
99
|
+
},
|
|
100
|
+
bubbles:true
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
}
|
package/src/core/TaskQueue.js
CHANGED
package/src/scss/colors.scss
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
// Colores generales
|
|
2
|
+
$primary-color: #06c;
|
|
3
|
+
$secondary-color: #2c3e50;
|
|
4
|
+
$primary-color-hover: #007bff;
|
|
5
|
+
$secondary-color-hover: #2c3e50;
|
|
6
|
+
$black1: #000000;
|
|
7
|
+
$black2: #202020;
|
|
8
|
+
$black3: #404040;
|
|
9
|
+
$black4: #808080;
|
|
10
|
+
$black: $black1;
|
|
11
|
+
$white1: #ffffff;
|
|
12
|
+
$white2: #f5f5f5;
|
|
13
|
+
$white3: #e0e0e0;
|
|
14
|
+
$white4: #bfbfbf;
|
|
15
|
+
$white: $white1;
|
|
16
|
+
$valid-color: #008000;
|
|
17
|
+
$invalid-color: #FF0000;
|
|
18
|
+
$neutral-color: #353535;
|
|
19
|
+
|
|
1
20
|
// Colores de ventanas de mensajes
|
|
2
21
|
$msg-text-error-color: #b94a48;
|
|
3
22
|
$msg-text-success-color: #468847;
|
|
@@ -8,6 +27,16 @@ $msg-background-success-color: #dff0d8;
|
|
|
8
27
|
$msg-background-warning-color: #fcf8e3;
|
|
9
28
|
$msg-background-info-color: #d9edf7;
|
|
10
29
|
|
|
30
|
+
// Colores para carga
|
|
11
31
|
$loader-primary-color: #3b82f6;
|
|
12
32
|
$loader-secondary-color: #93c5fd;
|
|
13
|
-
$loader-muted-color: #5b6e8c;
|
|
33
|
+
$loader-muted-color: #5b6e8c;
|
|
34
|
+
|
|
35
|
+
// Colores para botones
|
|
36
|
+
$add-button-background: #006400;
|
|
37
|
+
$add-button-background-hover: #004b00;
|
|
38
|
+
$edit-button-background: #004080;
|
|
39
|
+
$edit-button-background-hover: #003060;
|
|
40
|
+
$delete-button-background: #8b0000;
|
|
41
|
+
$delete-button-background-hover: #6b0000;
|
|
42
|
+
$disabled-button-background: #dddddd;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@use './colors.scss' as *;
|
|
2
|
+
|
|
3
|
+
.icon{
|
|
4
|
+
width: 1.2rem;
|
|
5
|
+
height: 1.2rem;
|
|
6
|
+
display: inline-block;
|
|
7
|
+
vertical-align: middle;
|
|
8
|
+
background-color: $black;
|
|
9
|
+
mask-repeat: no-repeat;
|
|
10
|
+
mask-position: center;
|
|
11
|
+
mask-size: contain;
|
|
12
|
+
-webkit-mask-repeat: no-repeat;
|
|
13
|
+
-webkit-mask-position: center;
|
|
14
|
+
-webkit-mask-size: contain;
|
|
15
|
+
|
|
16
|
+
&.search{
|
|
17
|
+
mask-image: url("./assets/icons/search.svg");
|
|
18
|
+
-webkit-mask-image: url("./assets/icons/search.svg");
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/scss/main.scss
CHANGED