toggle-components-library 1.35.0 → 1.36.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/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toggle-components-library",
3
- "version": "1.35.0",
3
+ "version": "1.36.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toggle-components-library",
3
- "version": "1.35.0",
3
+ "version": "1.36.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -1,18 +1,18 @@
1
1
  <template>
2
2
 
3
3
  <div class="toggle-input-container" :class="{'toggle-input-is-invalid':isInvalid, 'toggle-input-is-disabled':disabled}" v-on:click="focusClosestInput">
4
- <label
4
+ <label
5
5
  v-if="label"
6
- :for="name ? name : 'ToggleInputSelect' "
6
+ :for="name ? name : 'ToggleInputSelect' "
7
7
  class="toggle-input-label"
8
- > {{ label }}
8
+ > {{ label }}
9
9
  </label>
10
10
 
11
11
  <div class="toggle-input-select-container">
12
- <select
13
- :name="name ? name : 'ToggleInputSelect' "
12
+ <select
13
+ :name="name ? name : 'ToggleInputSelect' "
14
14
  :class="[ 'toggle-input-select', size]"
15
- v-model="inputVal"
15
+ v-model="inputVal"
16
16
  :autocomplete="autocomplete ? 'on' : 'off' "
17
17
  :required="required"
18
18
  :disabled="disabled"
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  <label
27
- class="toggle-input-label-error"
27
+ class="toggle-input-label-error"
28
28
  v-if="isInvalid"
29
29
  :for="name ? name : 'ToggleInputText' "
30
30
  >
@@ -39,6 +39,11 @@ import { mixins } from '../mixins/mixins'
39
39
 
40
40
  export default {
41
41
  mixins:[mixins],
42
+ data() {
43
+ return {
44
+ show: false
45
+ }
46
+ },
42
47
  props: {
43
48
  value: {},
44
49
  name: {
@@ -87,6 +92,7 @@ export default {
87
92
  },
88
93
 
89
94
  created : function(){
95
+
90
96
  },
91
97
  computed: {
92
98
  inputVal: {
@@ -1,16 +1,16 @@
1
1
  <template>
2
2
 
3
3
  <div class="toggle-input-container" :class="{'toggle-input-is-invalid':isInvalid, 'toggle-input-is-disabled':disabled}" v-on:click="focusClosestInput">
4
- <label
4
+ <label
5
5
  v-if="label"
6
- :for="name ? name : 'InputText' "
6
+ :for="name ? name : 'InputText' "
7
7
  class="toggle-input-label"
8
- > {{ label }}
8
+ > {{ label }}
9
9
  </label>
10
10
  <span class="toggle-input-counter" v-if="maxLength">{{messageLength(inputVal, maxLength)}}</span>
11
11
  <input
12
12
  :type="type"
13
- :name="name ? name : 'ToggleInputText' "
13
+ :name="name ? name : 'ToggleInputText' "
14
14
  :class="[ 'toggle-input', size]"
15
15
  :placeholder="placeholder ? placeholder : '' "
16
16
  :autocomplete="autocomplete ? 'on' : 'off' "
@@ -19,9 +19,11 @@
19
19
  :maxlength="maxLength"
20
20
  :disabled="disabled"
21
21
  :readonly="readonly"
22
+ :ref="'input_ele'"
23
+ @keyup.esc="handleEscPress"
22
24
  />
23
25
  <label
24
- class="toggle-input-label-error"
26
+ class="toggle-input-label-error"
25
27
  v-if="isInvalid"
26
28
  :for="name ? name : 'ToggleInputText' "
27
29
  >
@@ -103,7 +105,9 @@ export default {
103
105
  }
104
106
  },
105
107
 
106
- created : function(){
108
+ created : function()
109
+ {
110
+ this.$nextTick(() => this.$refs['input_ele'].focus());
107
111
  },
108
112
  computed: {
109
113
  inputVal: {
@@ -118,6 +122,11 @@ export default {
118
122
  },
119
123
  methods: {
120
124
 
125
+ handleEscPress()
126
+ {
127
+ this.$emit('bail');
128
+ },
129
+
121
130
  /*
122
131
  * Concat message for count characters
123
132
  * @return string
@@ -3,29 +3,56 @@
3
3
  <div>
4
4
 
5
5
  <table class="toggle-table">
6
- <thead :class="{'toggle-table-any-search-active': searchActive}">
6
+ <thead :class="{'toggle-table-any-search-active': anySearchActive}">
7
7
  <tr class="toggle-tablee-tr">
8
- <th
9
- scope="col"
10
- :class="['toggle-table-th', {'toggle-table-search-active': tableSearchActive(field), 'toggle-table-searchable':field.filterable}]"
11
- v-for="(field, index) in headers"
8
+ <th
9
+ scope="col"
10
+ :class="['toggle-table-th', {'toggle-table-search-active': tableSearchActive(field), 'toggle-table-searchable':field.filterable}]"
11
+ v-for="(field, index) in headers"
12
+ :colspan="field.colspan"
12
13
  :key="index"
13
14
  :style="'width:'+field.width"
14
15
  @click="activateSearch(field)"
15
16
  >
16
- <div class="toggle-table-th-inner">
17
+ <div class="toggle-table-th-inner" @transitionend="handleTransitionEnd">
18
+
17
19
  <span class="toggle-table-th-title">{{field.label}}</span>
18
20
  <span class="toggle-table-close-search" v-on:click.stop @click="closeSearch(field)"></span>
19
- <ToggleInputText type="text" :ref="field.key+'-input'" v-model="searchModels[field.key]" @input="searchChange(field)"
20
- v-if="field.type == 'text' && (searchModels[field.key] || editingInput == field.key)" />
21
- <ToggleInputSelect style="margin-top:2px;" size="small" v-if="field.type == 'select' && (searchModels[field.key] || editingInput == field.key)" :options="field.select_options" v-model="searchModels[field.key]" @input="val=>searchChange(val, field)"/>
22
21
 
23
- <ToggleDateRangePicker v-if="field.type == 'date' && (searchModels[field.key].start || searchModels[field.key].end || editingInput == field.key)" name="date" v-model="searchModels[field.key]" @input="val=>searchChange(val, field)" />
22
+ <ToggleInputText
23
+ v-if="field.type === 'text' && (searchModels[field.key] || editingInput === field.key) && applyFocus"
24
+ type="text"
25
+ :ref="field.key+'-input'"
26
+ v-model="searchModels[field.key]"
27
+ @input="searchChange()"
28
+ @bail="closeSearch(field)"
29
+ />
30
+ <ToggleInputSelect
31
+ style="margin-top:2px;"
32
+ :size="'small'"
33
+ v-if="field.type === 'select' && (searchModels[field.key] || editingInput === field.key) && applyFocus"
34
+ :options="field.select_options"
35
+ v-model="searchModels[field.key]"
36
+ @input="searchChange()"
37
+ />
38
+ <ToggleDateRangePicker
39
+ v-if="field.type === 'date_range' && (searchModels[field.key].start || searchModels[field.key].end || editingInput === field.key)"
40
+ name="date_range"
41
+ v-model="searchModels[field.key]"
42
+ @input="searchChange()"
43
+ />
24
44
  </div>
25
45
  </th>
26
-
46
+
27
47
  </tr>
28
48
  </thead>
49
+ <tr class="empty-table" v-if="(items && items.length === 0) && !loading">
50
+ <td :colspan="headers.length">
51
+ <div class="full">
52
+ <div class="empty-area"><p>{{ emptyTableMessage }}</p></div>
53
+ </div>
54
+ </td>
55
+ </tr>
29
56
  <tbody v-if="!$slots.default || !$slots.default.length">
30
57
  <ToggleTableRow v-for="(item, index) in items" :key="index" >
31
58
  <ToggleTableColumn v-for="(column, column_index) in item" :key="column_index">{{column}}</ToggleTableColumn>
@@ -62,20 +89,34 @@ export default {
62
89
  type: [Array]
63
90
  },
64
91
  total:{
65
- type: [Number]
92
+ type: [Number]
66
93
  },
67
94
  per_page:{
68
- type: [Number]
95
+ type: [Number]
69
96
  },
70
97
  page:{
71
98
  type: [Number],
72
99
  default:1
100
+ },
101
+ loading: {
102
+ type: Boolean
103
+ },
104
+ emptyTableMessage: {
105
+ type: String,
106
+ default: "No rows returned."
107
+ },
108
+ searchDebounce: {
109
+ type: [Number],
110
+ default: 500
73
111
  }
74
- },
112
+ },
75
113
  data : function(){
76
114
  return {
77
115
  editingInput:false,
78
- searchModels:{}
116
+ searchModels:{},
117
+ anySearchActive: false,
118
+ applyFocus: false,
119
+ searchTimeout: null
79
120
  };
80
121
  },
81
122
  computed: {
@@ -97,36 +138,23 @@ export default {
97
138
 
98
139
  headers() {
99
140
  if(!this.fields){
100
- return Object.keys(this.items[0]);
141
+ return Object.keys(this.items[0]);
101
142
  }
102
143
  return this.fields;
103
144
  },
104
145
 
105
- searchActive() {
106
- if(this.editingInput) {
107
- return true;
108
- }
109
- for(let col in this.searchModels){
110
- if(!this.searchModels[col])
111
- return false;
112
- if (this.searchModels[col].start !== undefined) {
113
- return true;
114
- }
115
- else if(this.searchModels[col]) return true;
116
- }
117
- return false;
118
- },
119
-
120
-
121
146
  },
122
147
  created : function(){
123
148
 
124
149
  if(this.fields){
150
+
125
151
  for (let i = 0; i < this.fields.length; i++) {
126
- let value = this.fields[i].type == 'date' ? this.setInitialDate(i) : this.fields[i].value;
152
+ let value = this.fields[i].type == 'date_range' ? this.setInitialDate(i) : (this.fields[i].value ?? '');
153
+
127
154
  let field_name = this.fields[i].key;
128
155
  this.$set( this.searchModels, field_name, value )
129
156
  if(value){
157
+ this.applyFocus = true;
130
158
  // if date has an initial value set, show it.
131
159
  if(typeof value.start !== 'undefined'){
132
160
  if(value.start.length) this.activateSearch(this.fields[i]);
@@ -137,20 +165,29 @@ export default {
137
165
  this.searchChange();
138
166
  }
139
167
  }
140
-
168
+
141
169
  },
142
170
 
143
171
  beforeDestroy: function () {
144
- },
145
- watch:{
146
-
147
172
  },
148
173
  mounted : function ()
149
174
  {
150
175
 
151
176
  },
152
-
177
+
153
178
  methods:{
179
+
180
+ handleTransitionEnd(event){
181
+ if(event.propertyName === 'height'){
182
+ if(this.anySearchActive && !this.applyFocus){
183
+ this.applyFocus = true;
184
+ }
185
+ if(!this.anySearchActive && this.applyFocus){
186
+ this.applyFocus = false;
187
+ }
188
+ }
189
+ },
190
+
154
191
  // set initial date
155
192
  setInitialDate(index){
156
193
  let value = this.fields[index].value;
@@ -160,36 +197,64 @@ export default {
160
197
 
161
198
  tableSearchActive(field)
162
199
  {
163
- if(field.type == 'date'){
164
- return (this.searchModels[field.key].start || this.searchModels[field.key].end || this.editingInput == field.key);
200
+ if(field.type === 'date_range'){
201
+ return (this.searchModels[field.key].start || this.searchModels[field.key].end || this.editingInput === field.key);
165
202
  }
166
- return (this.searchModels[field.key] || this.editingInput == field.key);
203
+ return (this.searchModels[field.key] || this.editingInput === field.key);
167
204
 
168
205
  },
169
206
 
207
+
208
+ getSearchModelTypeFromKey(key){
209
+ for(let i=0; i<this.fields.length; i++){
210
+ if(this.fields[i].key === key){
211
+ return this.fields[i].type;
212
+ }
213
+ }
214
+ return null;
215
+ },
216
+
170
217
  closeSearch(field){
218
+
171
219
  this.editingInput = false;
172
- this.searchModels[field.key] = field.type == 'date' ? { start: false, end: false} : '' ;
220
+ this.searchModels[field.key] = field.type === 'date_range' ? { start: false, end: false} : '' ;
221
+
222
+ // check if any search is active; if not, close/shrink header
223
+ let is_active = false;
224
+ for(const key in this.searchModels){
225
+
226
+ if(this.getSearchModelTypeFromKey(key) === 'date_range'){
227
+ if (this.searchModels[key].start || this.searchModels[key].end){
228
+ is_active = true;
229
+ break;
230
+ }
231
+ }else if(this.searchModels[key] && this.searchModels[key] !== ''){
232
+ is_active = true;
233
+ break;
234
+ }
235
+ }
236
+ this.anySearchActive = is_active;
173
237
  this.searchChange();
174
238
  },
175
239
 
176
240
  searchChange(){
177
- this.$emit('search', this.fieldsWithSearch);
241
+ clearTimeout(this.searchTimeout);
242
+ this.searchTimeout = setTimeout(()=>{
243
+ this.$emit('search', this.fieldsWithSearch);
244
+ },this.searchDebounce);
245
+
178
246
  },
179
247
 
180
248
  /* activateSearch
181
249
  * When a user clicks a searchable column name, show it as active, and focus the child input field (unless it's already active)
182
250
  */
183
251
  activateSearch(field){
184
- if(!field.filterable) return;
185
- if(field.type === 'date'){
186
- this.datePickerOpen = true;
187
- }
252
+ if(!field.filterable || field.readonly) return;
188
253
  this.editingInput = field.key;
189
- //this.$nextTick(() => this.$refs[this.editingInput + '-input'].focus())
254
+ this.anySearchActive = true;
190
255
  },
191
256
 
192
-
257
+
193
258
 
194
259
  }
195
260
  }