glib-web 3.15.3 → 3.16.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.
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <pie-chart :style="genericStyles()" :class="$classes()" :data="series" :colors="color" :suffix="spec.suffix"
3
- :prefix="spec.prefix" :min=spec.min :max=spec.max :legend=spec.legend></pie-chart>
3
+ :prefix="spec.prefix" :min="spec.min" :max="spec.max" :legend="spec.legend" :donut="isDonut($classes())"></pie-chart>
4
4
  </template>
5
5
 
6
6
  <script setup>
@@ -9,8 +9,8 @@ const { singleDataSeries } = await import('./series');
9
9
 
10
10
  const { spec } = defineProps({ spec: Object });
11
11
  const color = spec.colors == null ? '' : spec.colors;
12
- const series = computed(() => singleDataSeries(spec.dataSeries))
13
-
12
+ const series = computed(() => singleDataSeries(spec.dataSeries));
13
+ const isDonut = (classes) => [classes].flat().includes('donut');
14
14
  </script>
15
15
 
16
16
  <style scoped></style>
@@ -71,7 +71,7 @@ import TextAreaField from "./fields/textarea.vue";
71
71
  const RichTextField = defineAsyncComponent(() => import("./fields/richText.vue"));
72
72
  // import NewRichTextField from "./fields/newRichText.vue";
73
73
  const FileField = defineAsyncComponent(() => import("./fields/file.vue"));
74
- const MultipleUploadField = defineAsyncComponent(() => import("./fields/multipleUpload.vue"));
74
+ const MultiUploadField = defineAsyncComponent(() => import("./fields/multiUpload.vue"));
75
75
  import AutocompleteField from "./fields/autocomplete.vue";
76
76
  import SelectField from "./fields/select.vue";
77
77
  import TimeZoneField from "./fields/timeZone.vue";
@@ -164,7 +164,7 @@ export default {
164
164
  "fields-richText": RichTextField,
165
165
  // "fields-newRichText": NewRichTextField,
166
166
  "fields-file": FileField,
167
- "fields-multipleUpload": MultipleUploadField,
167
+ "fields-multiUpload": MultiUploadField,
168
168
  "fields-autocomplete": AutocompleteField,
169
169
  "fields-select": SelectField,
170
170
  "fields-timeZone": TimeZoneField,
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <div :style="$styles()" :class="classes()">
3
- <v-autocomplete v-model="fieldModel" :label="spec.label" :items="options || []" :chips="spec.multiple"
4
- :multiple="spec.multiple" :readonly="spec.readOnly" :clearable="!spec.readOnly" :hint="spec.hint"
3
+ <v-autocomplete v-model="fieldModel" :label="label" :items="options || []" :chips="spec.multiple"
4
+ :multiple="spec.multiple" :readonly="spec.readOnly" :clearable="!spec.readOnly"
5
5
  :placeholder="spec.placeholder" :rules="rules" persistent-hint :append-icon="append.icon" validate-on="blur"
6
6
  item-title='text' :variant="variant" :closable-chips="spec.multiple" :density="density" persistent-placeholder
7
- @update:modelValue="onChange">
7
+ @update:modelValue="onChange" @focus="focused = true" @blur="focused = false">
8
8
 
9
9
  <template #item="{props, item}">
10
10
  <v-list-subheader v-if="item.raw.header">
@@ -41,7 +41,8 @@ export default {
41
41
  return {
42
42
  options: null,
43
43
  append: {},
44
- rules: []
44
+ rules: [],
45
+ focused: false
45
46
  };
46
47
  },
47
48
  computed: {
@@ -60,6 +61,12 @@ export default {
60
61
  },
61
62
  density() {
62
63
  return determineDensity(this.spec.styleClasses);
64
+ },
65
+ label() {
66
+ if (this.focused) {
67
+ return `${this.spec.label} ${this.spec.hint}`
68
+ }
69
+ return this.spec.label
63
70
  }
64
71
  },
65
72
  methods: {
@@ -9,28 +9,18 @@
9
9
  :src="fileImage || placeholder.url" />
10
10
 
11
11
  <v-text-field v-else-if="placeholder.type == 'input'" :value="fileTitle" variant="outlined"
12
- placholder="Upload your file" disabled />
12
+ :placeholder="placeholder.inputPlaceholder" disabled />
13
13
 
14
- <!-- See https://www.freecodecamp.org/news/how-to-use-html-to-open-link-in-new-tab/ -->
14
+ <!-- See https://www.freecodecamp.org/news/how-to-use-html-to-open-link-in-new-tab/ -->
15
15
  <a href="" @click="showPreview" v-else>{{ fileTitle }}</a>
16
16
 
17
- <span v-if="spec.uploadText">
18
- <v-btn @click="triggerUpload">
19
- <v-icon> {{ spec.uploadIcon || "upload" }} </v-icon>
20
- {{ spec.uploadText }}
21
- </v-btn>
22
-
23
- <v-btn v-if="fileImage" icon @click="removeImage">
24
- <v-icon>close</v-icon>
25
- </v-btn>
26
- </span>
27
- <div v-else class="action-container">
17
+ <div class="action-container">
28
18
  <v-btn @click="triggerUpload" class="upload-btn">
29
- {{ fileImage ? 'Change' : 'Upload' }}
19
+ {{ fileImage ? buttonLabels.change : buttonLabels.upload }}
30
20
  </v-btn>
31
21
 
32
22
  <v-btn variant="flat" v-if="fileImage" @click="removeImage" class="remove-btn">
33
- Delete
23
+ {{ buttonLabels.delete }}
34
24
  </v-btn>
35
25
 
36
26
 
@@ -39,28 +29,13 @@
39
29
  </div>
40
30
  </div>
41
31
  <input ref="directUploadFile" style="display: none" type="file" @change="uploadFiles" />
42
-
43
- <!-- <input type="file" :name="spec.name" ref='directUploadFile' @change='uploadFiles' v-show='!uploaded'/> -->
44
32
  <v-progress-linear class="mt-1" v-if="showProgress" v-model="progress.value" />
45
- <!-- <div v-show='uploaded'>
46
- <v-layout align-center justify-space-between row>
47
- <v-chip @click='removeImage' class='mr-2' color='red' text-color="white">X</v-chip>
48
- <span ref='fileName' class='w-full mr-2'></span>
49
- <img ref='fileImage' class='place-image-preview' />
50
- </v-layout>
51
- </div> -->
52
33
  <input type="hidden" :name="spec.name" :value="fileValue" :disabled="inputDisabled" />
53
34
  </div>
54
35
  </template>
55
36
 
56
37
  <script>
57
- // import * as ActiveStorage from "@rails/activestorage"
58
38
  import Uploader from "../../utils/uploader";
59
- // import EventController, {
60
- // DISABLE_SUBMIT_BUTTON
61
- // } from "../../utils/global-event-controller";
62
-
63
- // ActiveStorage.start()
64
39
 
65
40
  export default {
66
41
  props: {
@@ -75,6 +50,7 @@ export default {
75
50
  fileValue: null,
76
51
  inputElement: null,
77
52
  placeholder: {},
53
+ buttonLabels: { delete: 'Delete', upload: 'Upload', change: 'Change' }
78
54
  };
79
55
  },
80
56
  computed: {
@@ -91,8 +67,9 @@ export default {
91
67
  this.fileValue = this.spec.value;
92
68
  }
93
69
 
94
- this.placeholder = this.spec.placeholderView || {};
70
+ this.placeholder = this.spec.placeholderView || { inputPlaceholder: 'Upload your file' };
95
71
  this.inputElement = this.$refs.directUploadFile;
72
+ this.buttonLabels = Object.assign(this.buttonLabels, this.spec.buttonLabels);
96
73
  },
97
74
  triggerUpload() {
98
75
  this.inputElement.click();
@@ -122,7 +99,7 @@ export default {
122
99
  const previewWindow = window.open("");
123
100
  previewWindow?.document.write(
124
101
  `<iframe width='100%' height='100%' src='${this.fileImage}'></iframe>`
125
- )
102
+ );
126
103
  },
127
104
  uploadFile(file) {
128
105
  const upload = new Uploader(
@@ -182,6 +159,7 @@ export default {
182
159
  display: flex;
183
160
  align-items: center;
184
161
  flex-wrap: wrap;
162
+ gap: 8px;
185
163
 
186
164
  &.uploaded {
187
165
  gap: 16px;
@@ -6,8 +6,8 @@
6
6
 
7
7
  <div class="cloud" style="pointer-events: none;">
8
8
  <v-icon ref="icon" size="48" class="icon">cloud_upload</v-icon>
9
- <h4 v-if="spec.title" class="title">{{ spec.title }}</h4>
10
- <p v-if="spec.subtitle" class="subtitle">{{ spec.subtitle }}</p>
9
+ <h4 v-if="spec.placeholder" class="title">{{ spec.placeholder }}</h4>
10
+ <p v-if="spec.hint" class="subtitle">{{ spec.hint }}</p>
11
11
  </div>
12
12
 
13
13
  <input v-for="(file, index) in Object.values(files)" type="hidden" :name="spec.name" :value="file.signedId"
@@ -239,8 +239,8 @@ export default defineComponent({
239
239
  const container = ref(null);
240
240
  const icon = ref(null);
241
241
 
242
- let files = null;
243
- if (spec.files) {
242
+ let files = ref({});
243
+ if (spec.files && spec.files.length > 0) {
244
244
  files = ref(spec.files.reduce((prev, curr) => {
245
245
  const key = makeKey();
246
246
 
@@ -255,8 +255,6 @@ export default defineComponent({
255
255
 
256
256
  return prev;
257
257
  }, {}));
258
- } else {
259
- files = ref([]);
260
258
  }
261
259
 
262
260
  const setBusy = (value) => {
@@ -1,24 +1,41 @@
1
1
  <template>
2
- <fields-otp :spec="spec" />
2
+ <div :style="$styles()" :class="$classes()">
3
+ <v-otp-input ref="field" v-model="fieldModel" :name="fieldName" :disabled="inputDisabled" :rounded="4"
4
+ :max-width="maxWidth" type="spec.type || 'number'" :length="length" :variant="variant" />
5
+ <label class="hint" v-if="spec.hint">{{ spec.hint }}</label>
6
+ </div>
3
7
  </template>
4
8
 
5
9
  <script>
6
- import OtpField from "./_otp.vue";
10
+ import inputVariant from "../mixins/inputVariant";
7
11
 
8
12
  export default {
9
- components: {
10
- // Need to start with `fields-` to enable jsonlogic in `styles.js#_linkFieldModels`
11
- "fields-otp": OtpField,
12
- },
13
+ expose: ['fieldModel'],
14
+ mixins: [inputVariant],
13
15
  props: {
14
16
  spec: { type: Object, required: true },
15
17
  },
16
- data() {
17
- return {
18
- value: null,
19
- };
18
+ computed: {
19
+ length() {
20
+ return this.spec.length || 6;
21
+ },
22
+ maxWidth() {
23
+ const width = 50;
24
+ const pad = 8;
25
+ return this.length * width + this.length * pad;
26
+ }
20
27
  },
28
+ methods: {
29
+ $sanitizeValue(val) {
30
+ if (!val) return '';
31
+
32
+ let value = val + '';
33
+ if (this.length > value.length) {
34
+ value = '0'.repeat(this.length - value.length) + value;
35
+ }
36
+
37
+ return value;
38
+ }
39
+ }
21
40
  };
22
41
  </script>
23
-
24
- <style scoped></style>
@@ -94,7 +94,9 @@ export default {
94
94
  return;
95
95
  }
96
96
 
97
- this.fieldModel = this.$sanitizeValue(this.$externalizeValue(value));
97
+ if (this.spec.valueIf) {
98
+ this.fieldModel = this.$sanitizeValue(this.$externalizeValue(value));
99
+ }
98
100
  });
99
101
  this._watchers.push(watcher1);
100
102
  }
@@ -253,12 +255,12 @@ export default {
253
255
 
254
256
  // Avoid user input getting removed when updating certain parts of the page.
255
257
  if (valueChanged) {
256
- this.fieldModel = this._sanitizeValue(this.spec.value);
258
+ this.fieldModel = this.$sanitizeValue(this.$externalizeValue(this.spec.value));
257
259
  }
258
260
  }
259
261
  },
260
262
  action_resetValue() {
261
- this.fieldModel = this._sanitizeValue(this.spec.value);
263
+ this.fieldModel = this.$sanitizeValue(this.$externalizeValue(this.spec.value));
262
264
  },
263
265
  $classes(spec, defaultViewName) {
264
266
  const properties = Object.assign(
@@ -49,12 +49,14 @@
49
49
  <tr :class="row.onClick ? 'clickable' : ''">
50
50
  <td v-for="(cell, cellIndex) in row.cellViews" :key="`cell_${cellIndex}`" :colSpan="colSpan(row, cellIndex)"
51
51
  :style="colStyles(row, cellIndex)">
52
- <!-- Prevent double links -->
53
- <glib-component v-if="$href(cell)" :spec="cell" />
54
- <!-- without "|| null" the browser will reload strangely -->
55
- <a v-else :href="$href(row) || null" @click="$onClick($event, row)">
56
- <glib-component :spec="cell" />
57
- </a>
52
+ <span>
53
+ <!-- Prevent double links -->
54
+ <glib-component v-if="$href(cell)" :spec="cell" />
55
+ <!-- without "|| null" the browser will reload strangely -->
56
+ <a v-else :href="$href(row) || null" @click="$onClick($event, row)">
57
+ <glib-component :spec="cell" />
58
+ </a>
59
+ </span>
58
60
  </td>
59
61
  </tr>
60
62
  </template>
@@ -175,9 +177,8 @@ tbody {
175
177
 
176
178
  td {
177
179
  border-top: 1px solid rgba(0, 0, 0, 0.12);
178
- // border-left: 1px solid rgba(0, 0, 0, 0.12);
179
180
 
180
- a {
181
+ span {
181
182
  padding: 10px 24px;
182
183
  display: block;
183
184
  color: inherit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "3.15.3",
3
+ "version": "3.16.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {