@qikdev/vue-ui 0.0.3 → 0.1.1

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.
@@ -222,6 +222,14 @@ export default {
222
222
  return val;
223
223
  },
224
224
  cleanOutput(val) {
225
+
226
+ if (this.type == 'reference') {
227
+ if (!this.multiValue) {
228
+ if (Array.isArray(val) && val.length) {
229
+ return val[0]
230
+ }
231
+ }
232
+ }
225
233
  return val;
226
234
  }
227
235
  },
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="ux-multi-group" v-if="multiValue">
3
- <panel ref="row" :key="entry" v-for="(entry, index) in model">
4
- <panel-header>
3
+ <ux-panel ref="row" :key="entry" v-for="(entry, index) in model">
4
+ <ux-panel-header>
5
5
  <flex-row>
6
6
  <flex-cell vcenter>
7
7
  <div>
@@ -9,11 +9,11 @@
9
9
  </div>
10
10
  </flex-cell>
11
11
  </flex-row>
12
- </panel-header>
13
- <panel-body>
12
+ </ux-panel-header>
13
+ <ux-panel-body>
14
14
  <ux-render :fields="fields" :flex="sameLine" :parentModel="parentModel" v-model="model[index]" />
15
- </panel-body>
16
- </panel>
15
+ </ux-panel-body>
16
+ </ux-panel>
17
17
  </div>
18
18
  <template v-else>
19
19
  <ux-render :fields="fields" :flex="sameLine" :parentModel="parentModel" v-model="model" />
@@ -9,7 +9,8 @@
9
9
  </native-select> of the following rules
10
10
  </div>
11
11
  </div>
12
- <filter-rule :enableRemove="model.filters.length > 1" :key="`rule-${index}`" @remove="removeRule(index)" :definition="definition" v-model="model.filters[index]" :index="index" v-for="(rule, index) in model.filters" />
12
+ <!-- :enableRemove="model.filters.length > 1" -->
13
+ <filter-rule enableRemove :key="`rule-${index}`" @remove="removeRule(index)" :definition="definition" v-model="model.filters[index]" :index="index" v-for="(rule, index) in model.filters" />
13
14
  <ux-button @click="addRule()">Add Filter Rule</ux-button>
14
15
  </div>
15
16
  </flex-body>
@@ -9,7 +9,12 @@
9
9
  </flex-cell>
10
10
  <flex-cell v-if="model.comparator">
11
11
  <div v-if="inputType == 'array'">
12
- <text-field :field="arrayField" v-model="model.values" />
12
+ <template v-if="hasOptions">
13
+ <native-select v-model="model.values" :field="multiOptionsField" />
14
+ </template>
15
+ <template v-else>
16
+ <text-field :field="arrayField" v-model="model.values" />
17
+ </template>
13
18
  </div>
14
19
  <div v-if="inputType == 'range'">
15
20
  <text-field :field="normalField" v-model="model.value" />
@@ -50,16 +55,20 @@
50
55
  <text-field :field="normalField" v-model="model.value" />
51
56
  </div>
52
57
  <div v-if="inputType == 'normal'">
53
- <text-field :field="normalField" v-model="model.value" />
58
+ <template v-if="hasOptions">
59
+ <native-select v-model="model.value" :field="singleOptionsField" />
60
+ </template>
61
+ <template v-else>
62
+ <text-field :field="normalField" v-model="model.value" />
63
+ </template>
54
64
  </div>
55
- <!-- <pre>{{inputType}}</pre> -->
56
- <!-- <pre>{{comparator}}</pre>
57
- <native-select v-model="model.value" :field="comparatorField">
58
- {{model.comparator || 'Select Value'}}
59
- </native-select> -->
65
+
66
+
67
+ <!-- <pre>{{field}}</pre> -->
68
+
60
69
  </flex-cell>
61
70
  <flex-cell shrink v-if="enableRemove">
62
- <ux-button icon @click="$emit('remove')">
71
+ <ux-button size="sm" icon @click="$emit('remove')">
63
72
  <ux-icon icon="fa-times" />
64
73
  </ux-button>
65
74
  </flex-cell>
@@ -112,6 +121,9 @@ export default {
112
121
  }
113
122
  },
114
123
  computed: {
124
+ hasOptions() {
125
+ return !!(this.field.options && this.field.options.length);
126
+ },
115
127
  fieldHash() {
116
128
  return this.fields.reduce(function(set, field) {
117
129
 
@@ -282,13 +294,39 @@ export default {
282
294
  placeholder: this.field.title,
283
295
  }
284
296
  },
297
+ multiOptionsField() {
298
+ return {
299
+ // title:`Select ${this.field.title}`,
300
+ options: this.field.options,
301
+ widget: 'select',
302
+ type: this.fieldType,
303
+ maximum: 0,
304
+ minimum: 1,
305
+ placeholder: this.field.title,
306
+ }
307
+ },
308
+ singleOptionsField() {
309
+ return {
310
+ title:`Select ${this.field.title}`,
311
+ options: this.field.options,
312
+ widget: 'select',
313
+ type: this.fieldType,
314
+ maximum: 1,
315
+ minimum: 0,
316
+ placeholder: this.field.title,
317
+ }
318
+ },
285
319
  normalField() {
320
+
321
+
322
+
286
323
  return {
287
324
  type: this.fieldType,
288
325
  maximum: 1,
289
326
  minimum: 1,
290
327
  placeholder: this.field.title,
291
328
  }
329
+
292
330
  },
293
331
  arrayField() {
294
332
  return {
@@ -10,7 +10,7 @@
10
10
  </div>
11
11
  </flex-cell>
12
12
  <flex-cell @click="$emit('remove')" shrink v-if="enableRemove">
13
- <ux-button icon>
13
+ <ux-button size="sm" icon>
14
14
  <ux-icon icon="fa-trash" />
15
15
  </ux-button>
16
16
  </flex-cell>
@@ -109,6 +109,8 @@ export default {
109
109
  break;
110
110
  }
111
111
  },
112
+
113
+
112
114
  fields() {
113
115
  var allFields = [...this.definition.fields];
114
116
  var definedFields = this.definition.definedFields || [];
@@ -1,5 +1,8 @@
1
1
  <template>
2
2
  <div class="ux-field" @focusin="focus" @focusout="blur" v-if="visible" :class="classes">
3
+ <template v-if="widget == 'html'">
4
+ <custom-html @touched="touch" :field="actualField" v-model="fieldModel" />
5
+ </template>
3
6
  <template v-if="widget == 'checkbox'">
4
7
  <checkbox @touched="touch" :field="actualField" v-model="fieldModel" />
5
8
  </template>
@@ -35,6 +38,10 @@
35
38
  <template v-if="widget == 'content-select'">
36
39
  <content-select @touched="touch" :field="actualField" v-model="fieldModel" />
37
40
  </template>
41
+
42
+ <template v-if="widget == 'type-select'">
43
+ <type-select @touched="touch" :field="actualField" v-model="fieldModel" />
44
+ </template>
38
45
  <template v-if="widget == 'richtext'">
39
46
  <text-area @touched="touch" :field="actualField" v-model="fieldModel" />
40
47
  </template>
@@ -70,11 +77,13 @@
70
77
  import PhoneNumberInput from './inputs/phone-number-input.vue';
71
78
  import TimezoneSelect from './inputs/timezone.vue';
72
79
  import ContentSelect from './inputs/content-select.vue';
80
+ import TypeSelect from './inputs/type-select.vue';
73
81
  import CurrencyField from './inputs/currency.vue';
74
82
  import TextField from './inputs/textfield.vue';
75
83
  import TextArea from './inputs/textarea.vue';
76
84
  import DateField from './inputs/datefield.vue';
77
85
  import Checkbox from './inputs/checkbox.vue';
86
+ import CustomHTML from './inputs/html.vue';
78
87
  import Switch from './inputs/switch.vue';
79
88
  import Upload from './inputs/upload/upload.vue';
80
89
  import FieldGroup from './inputs/group.vue';
@@ -134,9 +143,11 @@ export default {
134
143
  CurrencyField,
135
144
  TextArea,
136
145
  Checkbox,
146
+ CustomHtml:CustomHTML,
137
147
  BooleanSwitch: Switch,
138
148
  FieldGroup,
139
149
  ContentSelect,
150
+ TypeSelect,
140
151
  TimezoneSelect,
141
152
  PhoneNumberInput,
142
153
  Upload,
@@ -529,6 +540,8 @@ export default {
529
540
  case 'upload':
530
541
  case 'options':
531
542
  case 'button':
543
+ case 'type-select':
544
+ case 'html':
532
545
  break;
533
546
  case 'password':
534
547
  return 'textfield';
@@ -141,6 +141,7 @@ export default function getDefaultValue(fieldData, currentValue) {
141
141
  }
142
142
  break;
143
143
  case 'group':
144
+
144
145
  if (fieldData.asObject) {
145
146
  var number = ask;
146
147
  if (multiValue) {
@@ -205,6 +206,7 @@ export default function getDefaultValue(fieldData, currentValue) {
205
206
  }
206
207
  break;
207
208
  default:
209
+
208
210
  if (multiValue) {
209
211
  if (defaultValues.length) {
210
212
  output = defaultValues.slice(0, maximum);
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
 
3
3
  <div class="ux-multi-group" v-if="multiValue">
4
- <panel ref="row" :key="entry" v-for="(entry, index) in model">
5
- <panel-header>
4
+ <ux-panel ref="row" :key="entry" v-for="(entry, index) in model">
5
+ <ux-panel-header>
6
6
  <flex-row>
7
7
  <flex-cell vcenter>
8
8
  <div>
@@ -15,11 +15,11 @@
15
15
  </ux-button>
16
16
  </flex-cell>
17
17
  </flex-row>
18
- </panel-header>
19
- <panel-body @keydown.enter="enterPress($event)">
18
+ </ux-panel-header>
19
+ <ux-panel-body @keydown.enter="enterPress($event)">
20
20
  <ux-form ref="form" @form:state="stateChange" :parentModel="parentModel" v-model="model[index]" :flex="sameLine" :fields="field.fields" />
21
- </panel-body>
22
- </panel>
21
+ </ux-panel-body>
22
+ </ux-panel>
23
23
  <ux-button v-if="canAddValue" @click="add()">{{addLabel}}
24
24
  <ux-icon icon="fa-plus" right />
25
25
  </ux-button>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <label class="ux-field-title" v-if="showLabel">{{label}} <span class="ux-required-marker" v-if="required">*</span></label>
3
+ <div class="ux-field-description" v-if="showDescription">{{description}}</div>
4
+ <div v-if="multiValue">
5
+ <flex-row class="ux-text-row">
6
+ <flex-cell>
7
+ <div v-html="field.template" :key="index" v-for="(entry, index) in model"></div>
8
+ </flex-cell>
9
+ <flex-cell shrink vcenter>
10
+ <ux-button tag="a" icon v-if="canRemoveValue" @click="remove(entry)">
11
+ <ux-icon icon="fa-times" />
12
+ </ux-button>
13
+ </flex-cell>
14
+ </flex-row>
15
+ <ux-button v-if="canAddValue" @click="add()">{{addLabel}}</ux-button>
16
+ </div>
17
+ <template v-else>
18
+ <div v-html="field.template"></div>
19
+ </template>
20
+ </template>
21
+ <script>
22
+ import InputMixin from './input-mixin';
23
+
24
+ export default {
25
+ props: {
26
+ modelValue: {
27
+ type: [String, Array],
28
+ },
29
+ },
30
+ mixins: [InputMixin],
31
+ methods: {
32
+ getNewDefaultEntry() {
33
+ return '';
34
+ },
35
+ },
36
+ }
37
+ </script>
38
+ <style lang="scss" scoped>
39
+ </style>
@@ -185,9 +185,27 @@ export default {
185
185
  position: relative;
186
186
  width:100%;
187
187
 
188
+
189
+
188
190
  & > .ux-btn {
189
191
  display: block;
192
+ position:relative;
190
193
  text-align: left;
194
+
195
+ &:after {
196
+ content:'▼';
197
+ position:absolute;
198
+ right:0;
199
+ line-height: 3.5em;
200
+ top:0;
201
+ bottom: 0;
202
+ height:100%;
203
+ font-size: 0.6em;
204
+ width:4em;
205
+ text-align: center;
206
+ opacity: 0.5;
207
+
208
+ }
191
209
  }
192
210
  }
193
211
 
@@ -0,0 +1,247 @@
1
+ <template>
2
+ <div class="native-select" :class="classes">
3
+ <label class="ux-field-title" v-if="showLabel">{{label}} <span class="ux-required-marker" v-if="required">*</span></label>
4
+ <div class="ux-field-description" v-if="showDescription">{{description}}</div>
5
+ <div class="ui-select-button" v-if="singleValue">
6
+ <slot>
7
+ <ux-button tag="div">
8
+ {{summary}}
9
+ </ux-button>
10
+ </slot>
11
+ </div>
12
+ <select @focus="touch" :multiple="multiValue" v-model="model">
13
+ <option value="" v-if="singleValue && !minimum">None</option>
14
+ <option :value="option.value" v-for="option in selectableOptions">{{option.title}}</option>
15
+ </select>
16
+ </div>
17
+ </template>
18
+ <script>
19
+ import InputMixin from './input-mixin';
20
+
21
+
22
+
23
+ function isUndefined(entry) {
24
+ return entry === undefined || typeof entry === 'undefined' || entry === null || String(entry) === 'null' || String(entry) === 'undefined';
25
+ }
26
+
27
+ //////////////////////////
28
+
29
+ export default {
30
+ props: {
31
+ title: {
32
+ type: String,
33
+ },
34
+ modelValue: {
35
+ // type: [Object, Array],
36
+ },
37
+ },
38
+ mixins: [InputMixin],
39
+ async created() {
40
+ this.model = this.model;
41
+
42
+ var glossary = await this.$qik.content.glossary();
43
+
44
+
45
+ var typeList = glossary;
46
+
47
+ if (this.field.basicTypes === false) {
48
+ typeList = typeList.filter(function(definition) {
49
+ return !!definition.definesType
50
+ })
51
+ }
52
+
53
+ if (this.field.definedTypes === false) {
54
+ typeList = typeList.filter(function(definition) {
55
+ return !definition.definesType
56
+ })
57
+ }
58
+
59
+ ////////////////////////////
60
+
61
+ typeList = typeList.map(function(definition) {
62
+ return {
63
+ title: definition.title,
64
+ value: definition.key,
65
+ }
66
+ })
67
+ .sort((a, b) => a.title > b.title ? 1 : -1);
68
+
69
+ ////////////////////////////
70
+
71
+ this.types = typeList;
72
+ },
73
+ data() {
74
+ return {
75
+ types: [],
76
+ }
77
+ },
78
+ methods: {
79
+ cleanOutput(val) {
80
+ var self = this;
81
+
82
+ if (isUndefined(val)) {
83
+ if (self.multiValue) {
84
+ val = [];
85
+ } else {
86
+ val = undefined;
87
+ }
88
+ } else {
89
+ if (self.multiValue) {
90
+ val = (val || []).filter(Boolean).map(function(i) {
91
+ return self.getValue(i);
92
+ })
93
+ } else {
94
+ val = self.getValue(val);
95
+ }
96
+ }
97
+
98
+ return val;
99
+ },
100
+ cleanInput(val) {
101
+
102
+ var self = this;
103
+
104
+ if (self.multiValue) {
105
+ if (!val) {
106
+ val = [];
107
+ }
108
+
109
+ if (!Array.isArray(val)) {
110
+ val = [val];
111
+ }
112
+
113
+ /////////////////////////////////
114
+
115
+ if (self.maximum) {
116
+ if (val.length > self.maximum) {
117
+ val.length = self.maximum;
118
+ }
119
+ }
120
+
121
+
122
+ val = val.filter(Boolean).map(function(v) {
123
+ var valueKey = self.getValue(v);
124
+ return self.returnObject ? self.optionLookup[valueKey] : valueKey;
125
+ })
126
+
127
+ } else {
128
+ var valueKey = self.getValue(val);
129
+ val = self.returnObject ? self.optionLookup[valueKey] : valueKey;
130
+ }
131
+
132
+ return val;
133
+ },
134
+ },
135
+ computed: {
136
+ returnObject() {
137
+ return false;
138
+ },
139
+ classes() {
140
+ var array = []
141
+
142
+ if (this.multiValue) {
143
+ array.push('multiple');
144
+ } else {
145
+ array.push('single');
146
+ }
147
+
148
+ return array;
149
+ },
150
+ // model: {
151
+ // get() {
152
+ // let val = this.cleanOutput(this.value);
153
+ // return val;
154
+ // },
155
+ // set(val) {
156
+ // val = this.cleanInput(val);
157
+ // // // var val = this.cleanOutput(newValue);
158
+ // // // var existing = this.cleanOutput(this.value);
159
+
160
+ // // if (newValue != existing) {
161
+ // // newValue = this.cleanInput(val);
162
+ // // this.value = newValue;
163
+ // // this.dispatch();
164
+ // // }
165
+
166
+ // this.value = val;
167
+ // this.dispatch();
168
+
169
+ // }
170
+ // },
171
+ optionLookup() {
172
+ var self = this;
173
+ return self.types.reduce(function(set, option) {
174
+ const key = self.getValue(option);
175
+ set[key] = option;
176
+ return set;
177
+ }, {})
178
+ },
179
+ summary() {
180
+ return this.model ? this.getLabel(this.optionLookup[this.model]) : this.title || 'Click to select';
181
+ },
182
+
183
+ selectableOptions() {
184
+
185
+ return this.types;
186
+ // return this.options
187
+ // .sort(function(option) {
188
+ // return option.title;
189
+ // });
190
+ // if(this.type == 'reference') {
191
+
192
+ // } else {
193
+
194
+ // }
195
+
196
+ },
197
+ }
198
+ }
199
+ </script>
200
+ <style lang="scss" scoped>
201
+ .native-select {
202
+
203
+ cursor: pointer;
204
+
205
+ &.multiple {
206
+ select {
207
+ width: 100%;
208
+ font-size: 1em;
209
+ border: 1px solid rgba(#000, 0.1);
210
+ appearance: none;
211
+
212
+ &:focus {
213
+ border: 1px solid $primary;
214
+ }
215
+ }
216
+ }
217
+
218
+ &.single {
219
+ position: relative;
220
+
221
+ .ui-select-button {
222
+ position: relative;
223
+ width: 100%;
224
+
225
+ &>.ux-btn {
226
+ display: block;
227
+ text-align: left;
228
+ }
229
+ }
230
+
231
+ select {
232
+ cursor: pointer;
233
+ opacity: 0;
234
+ appearance: none;
235
+ width: 100%;
236
+ height: 100%;
237
+ position: absolute;
238
+ top: 0;
239
+ left: 0;
240
+ bottom: 0;
241
+ right: 0;
242
+ }
243
+ }
244
+
245
+
246
+ }
247
+ </style>
@@ -30,7 +30,7 @@ export default {
30
30
  }
31
31
 
32
32
  &[gap] {
33
- gap: 0.2em;
33
+ gap: 0.4em;
34
34
  }
35
35
  }
36
36
 
@@ -10,6 +10,7 @@ export default {
10
10
  <style scoped lang="scss">
11
11
  .flex-spacer {
12
12
  padding:0.25em;
13
+ flex:1;
13
14
  }
14
15
 
15
16
 
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <flex-column>
3
+
4
+ <slot/>
5
+
6
+ </flex-column>
7
+ </template>
8
+ <script>
9
+ export default {
10
+ props:{
11
+ heading:{
12
+ type:String,
13
+ required:true,
14
+ }
15
+ },
16
+ data() {
17
+ return {
18
+ isActive:false,
19
+ }
20
+ },
21
+ computed:{
22
+ active:{
23
+ get() {
24
+ return this.isActive;
25
+ },
26
+ set(a) {
27
+ this.isActive = a;
28
+ }
29
+ }
30
+ }
31
+ }
32
+ </script>
33
+ <style lang="scss" scoped>
34
+ </style>