@signal24/vue-foundation 3.3.2 → 3.6.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.
Files changed (39) hide show
  1. package/.eslintrc.js +16 -0
  2. package/.prettierrc.json +7 -0
  3. package/CHANGES.md +6 -3
  4. package/package.json +26 -13
  5. package/postcss.config.js +1 -1
  6. package/src/app.js +2 -2
  7. package/src/components/ajax-select.vue +10 -6
  8. package/src/components/alert.vue +28 -28
  9. package/src/components/index.js +6 -11
  10. package/src/components/modal.vue +18 -10
  11. package/src/components/smart-select.vue +57 -34
  12. package/src/config.js +1 -1
  13. package/src/directives/autofocus.js +4 -3
  14. package/src/directives/confirm-button.js +2 -2
  15. package/src/directives/date-input.js +7 -9
  16. package/src/directives/datetime.js +11 -9
  17. package/src/directives/disabled.js +4 -5
  18. package/src/directives/duration.js +7 -8
  19. package/src/directives/index.js +1 -1
  20. package/src/directives/infinite-scroll.js +1 -1
  21. package/src/directives/readonly.js +5 -6
  22. package/src/directives/tooltip.js +58 -61
  23. package/src/directives/user-text.js +1 -1
  24. package/src/filters/index.js +9 -6
  25. package/src/helpers/array.js +13 -14
  26. package/src/helpers/context-menu.js +16 -18
  27. package/src/helpers/delay.js +1 -1
  28. package/src/helpers/error.js +6 -9
  29. package/src/helpers/http.js +27 -25
  30. package/src/helpers/index.js +1 -1
  31. package/src/helpers/mask.js +27 -20
  32. package/src/helpers/number.js +2 -2
  33. package/src/helpers/string.js +17 -17
  34. package/src/helpers/vue.js +2 -2
  35. package/src/index.js +5 -5
  36. package/src/plugins/index.js +6 -6
  37. package/src/plugins/infinite-scroll/hook.js +2 -2
  38. package/src/plugins/infinite-scroll.js +20 -10
  39. package/src/plugins/resize-watcher.js +2 -4
package/.eslintrc.js ADDED
@@ -0,0 +1,16 @@
1
+ module.exports = {
2
+ root: true,
3
+ env: {
4
+ node: true
5
+ },
6
+ extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier'],
7
+ rules: {
8
+ 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
9
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
10
+ 'simple-import-sort/imports': 'error',
11
+ 'simple-import-sort/exports': 'error',
12
+ 'prettier/prettier': 'warn',
13
+ 'no-unused-vars': 'warn'
14
+ },
15
+ plugins: ['simple-import-sort']
16
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "arrowParens": "avoid",
3
+ "printWidth": 120,
4
+ "singleQuote": true,
5
+ "tabWidth": 4,
6
+ "trailingComma": "none"
7
+ }
package/CHANGES.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Release notes
2
+
2
3
  All notable changes to this project will be documented in this file.
3
4
  This project adheres to [Semantic Versioning](http://semver.org/).
4
5
 
5
6
  ## 1.0.1
6
- - Update dependencies
7
- - Fix $confirmDestroy
7
+
8
+ - Update dependencies
9
+ - Fix $confirmDestroy
8
10
 
9
11
  ## 1.0.0
10
- - Initial public release
12
+
13
+ - Initial public release
package/package.json CHANGED
@@ -1,15 +1,28 @@
1
1
  {
2
- "name": "@signal24/vue-foundation",
3
- "version": "3.3.2",
4
- "description": "Common components, directives, and helpers for Vue 3 apps",
5
- "main": "src/index.js",
6
- "license": "MIT",
7
- "dependencies": {
8
- "axios": "^0.21.1",
9
- "jquery": "^3.6.0",
10
- "lodash": "^4.17.21",
11
- "moment": "^2.29.1",
12
- "vue": "^3.1.2",
13
- "vue-stash-nested": "fergusean/vue-stash-nested#vue-foundation-3"
14
- }
2
+ "name": "@signal24/vue-foundation",
3
+ "version": "3.6.0",
4
+ "description": "Common components, directives, and helpers for Vue 3 apps",
5
+ "main": "src/index.js",
6
+ "scripts": {
7
+ "format": "prettier --write . && eslint src --fix"
8
+ },
9
+ "license": "MIT",
10
+ "dependencies": {
11
+ "axios": "^0.26.0",
12
+ "jquery": "^3.6.0",
13
+ "lodash": "^4.17.21",
14
+ "moment": "^2.29.1",
15
+ "vue-stash-nested": "fergusean/vue-stash-nested#vue-foundation-3"
16
+ },
17
+ "devDependencies": {
18
+ "@vue/eslint-config-prettier": "^7.0.0",
19
+ "eslint": "^8.10.0",
20
+ "eslint-plugin-prettier": "^4.0.0",
21
+ "eslint-plugin-simple-import-sort": "^7.0.0",
22
+ "eslint-plugin-vue": "^8.5.0",
23
+ "prettier": "^2.5.1",
24
+ "sass": "^1.49.9",
25
+ "sass-loader": "^12",
26
+ "vue": "^3.2.31"
27
+ }
15
28
  }
package/postcss.config.js CHANGED
@@ -2,4 +2,4 @@ module.exports = {
2
2
  plugins: {
3
3
  autoprefixer: {}
4
4
  }
5
- }
5
+ };
package/src/app.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createApp, h } from 'vue'
1
+ import { createApp, h } from 'vue';
2
2
 
3
3
  let rootComponent;
4
4
  function setRootComponent(inComponent) {
@@ -17,7 +17,7 @@ const app = createApp({
17
17
  },
18
18
 
19
19
  render() {
20
- return h(rootComponent)
20
+ return h(rootComponent);
21
21
  }
22
22
  });
23
23
 
@@ -1,8 +1,12 @@
1
1
  <template>
2
- <select v-if="!options" disabled><option>{{ loadingText || 'Loading...' }}</option></select>
2
+ <select v-if="!options" disabled>
3
+ <option>{{ loadingText || 'Loading...' }}</option>
4
+ </select>
3
5
  <select v-else v-model="selectedItem">
4
6
  <option v-if="nullText" :value="null">{{ nullText }}</option>
5
- <option v-for="option in options" :key="option.id" :value="option">{{ textKey ? option[textKey] : option }}</option>
7
+ <option v-for="option in options" :key="option.id" :value="option">
8
+ {{ textKey ? option[textKey] : option }}
9
+ </option>
6
10
  </select>
7
11
  </template>
8
12
 
@@ -14,7 +18,7 @@ export default {
14
18
  return {
15
19
  options: null,
16
20
  selectedItem: null
17
- }
21
+ };
18
22
  },
19
23
 
20
24
  watch: {
@@ -38,7 +42,7 @@ export default {
38
42
  methods: {
39
43
  async load() {
40
44
  this.options = null;
41
- let params = this.params ? { params: this.params } : undefined
45
+ let params = this.params ? { params: this.params } : undefined;
42
46
  let result = await this.$http.get(this.url, params);
43
47
  let options = this.itemsKey ? result.data[this.itemsKey] : result.data;
44
48
  this.preprocessor && this.preprocessor(options);
@@ -46,5 +50,5 @@ export default {
46
50
  this.selectedItem = this.modelValue;
47
51
  }
48
52
  }
49
- }
50
- </script>
53
+ };
54
+ </script>
@@ -1,6 +1,8 @@
1
1
  <template>
2
- <modal class="vf-alert" :class="classes">
3
- <h1 v-if="!this.isBare" v-slot:header>{{ title }}</h1>
2
+ <Modal class="vf-alert" :class="classes">
3
+ <template v-if="!this.isBare" v-slot:header>
4
+ <h1>{{ title }}</h1>
5
+ </template>
4
6
 
5
7
  <div v-if="isHtml" v-html="message" class="user-message"></div>
6
8
  <div v-else v-user-text="message"></div>
@@ -12,13 +14,18 @@
12
14
  </template>
13
15
  <button v-else class="default" @click="ok" v-autofocus>OK</button>
14
16
  </template>
15
- </modal>
17
+ </Modal>
16
18
  </template>
17
19
 
18
20
  <script>
19
21
  import app from '../app';
22
+ import Modal from './modal';
20
23
 
21
24
  const classDef = {
25
+ components: {
26
+ Modal
27
+ },
28
+
22
29
  data() {
23
30
  return {
24
31
  isBare: false,
@@ -27,17 +34,15 @@ const classDef = {
27
34
  title: null,
28
35
  message: null,
29
36
  shouldConfirm: false
30
- }
37
+ };
31
38
  },
32
39
 
33
40
  created() {
34
- if (typeof(this.message) == 'object') {
41
+ if (typeof this.message == 'object') {
35
42
  if (this.message.html) {
36
43
  this.isHtml = true;
37
44
  this.message = this.message.html;
38
- }
39
-
40
- else if (this.message instanceof Error) {
45
+ } else if (this.message instanceof Error) {
41
46
  let err = this.message;
42
47
  err.handle();
43
48
 
@@ -58,51 +63,46 @@ export default classDef;
58
63
  async function launchModal(context, classDef, ...args) {
59
64
  classDef = { ...classDef, __modalId: Math.random().toString(36).substring(2, 10) };
60
65
  return await context.$modal.apply(context, [classDef, ...args]);
61
- };
66
+ }
62
67
 
63
- app.config.globalProperties.$alert = async function(title, message) {
68
+ app.config.globalProperties.$alert = async function (title, message) {
64
69
  return await launchModal(this, classDef, { title, message });
65
- }
70
+ };
66
71
 
67
- app.config.globalProperties.$confirm = async function(title, message, options) {
72
+ app.config.globalProperties.$confirm = async function (title, message, options) {
68
73
  options = options || {};
69
74
  const result = await launchModal(this, classDef, { title, message, shouldConfirm: true, ...options });
70
75
  return !!result;
71
- }
76
+ };
72
77
 
73
- app.config.globalProperties.$confirmDestroy = function(title, message, options) {
78
+ app.config.globalProperties.$confirmDestroy = function (title, message, options) {
74
79
  options = options || {};
75
80
  options.classes = options.classes || [];
76
81
  options.classes.push('destructive');
77
82
  return this.$confirm(title, message, options);
78
- }
83
+ };
79
84
 
80
- app.config.globalProperties.$wait = function(title, message) {
85
+ app.config.globalProperties.$wait = function (title, message) {
81
86
  if (title && !message) {
82
87
  message = title;
83
88
  title = undefined;
84
- }
85
- else if (!title && !message) {
89
+ } else if (!title && !message) {
86
90
  message = 'Please wait...';
87
91
  }
88
92
 
89
93
  let resolved = null;
90
94
  let promise = new Promise((resolve, reject) => {
91
95
  launchModal(this, classDef, { title, message, isBare: true, classes: ['wait'] }, resolve);
92
- })
93
- .then(inResolved => resolved = inResolved);
96
+ }).then(inResolved => (resolved = inResolved));
94
97
 
95
98
  this.$endWait = async () => {
96
99
  delete this.$endWait;
97
- if (resolved)
98
- await resolved.$dismiss();
99
- else
100
- await promise.then(() => resolved.$dismiss());
101
- }
100
+ if (resolved) await resolved.$dismiss();
101
+ else await promise.then(() => resolved.$dismiss());
102
+ };
102
103
 
103
104
  return this.$endWait;
104
- }
105
-
105
+ };
106
106
  </script>
107
107
 
108
108
  <style lang="scss">
@@ -127,4 +127,4 @@ app.config.globalProperties.$wait = function(title, message) {
127
127
  }
128
128
  }
129
129
  }
130
- </style>
130
+ </style>
@@ -1,17 +1,12 @@
1
1
  import app from '../app';
2
-
3
- import AjaxSelect from './ajax-select'
2
+ import AjaxSelect from './ajax-select';
4
3
  app.component('AjaxSelect', AjaxSelect);
5
4
 
6
- // do not register Alert with Vue or our customizations to
7
- // on-the-fly alerts won't take effect, as Vue will use
8
- // the already-cached 'Alert' component instead of recompiling
9
- // TODO: ^ is this for mutating Alert during dev, or...?
10
- import Alert from './alert'
11
- Alert;
5
+ import Alert from './alert';
6
+ app.component('Alert', Alert);
12
7
 
13
- import Modal from './modal'
8
+ import Modal from './modal';
14
9
  app.component('Modal', Modal);
15
10
 
16
- import SmartSelect from './smart-select'
17
- app.component('SmartSelect', SmartSelect);
11
+ import SmartSelect from './smart-select';
12
+ app.component('SmartSelect', SmartSelect);
@@ -1,6 +1,11 @@
1
1
  <template>
2
2
  <div class="vf-overlay vf-modal-wrap">
3
- <form action="." class="vf-modal" :class="{ scrolls: $isPropTruthy(this.scrolls) }" @submit.prevent="$emit('formSubmit')">
3
+ <form
4
+ action="."
5
+ class="vf-modal"
6
+ :class="{ scrolls: $isPropTruthy(this.scrolls) }"
7
+ @submit.prevent="$emit('formSubmit')"
8
+ >
4
9
  <div v-if="$slots.header" class="vf-modal-header">
5
10
  <slot name="header" />
6
11
  <i v-if="$isPropTruthy(this.closeX)" class="close" @click="$parent.$dismiss()"></i>
@@ -26,8 +31,7 @@ export default {
26
31
 
27
32
  if (this.$isPropTruthy(this.closeOnMaskClick)) {
28
33
  this.$el.addEventListener('click', e => {
29
- if (e.target == this.$el)
30
- this.$parent.$dismiss();
34
+ if (e.target == this.$el) this.$parent.$dismiss();
31
35
  });
32
36
  }
33
37
  },
@@ -49,7 +53,7 @@ export default {
49
53
  }
50
54
  }
51
55
  }
52
- }
56
+ };
53
57
 
54
58
  import app from '../app';
55
59
  import { markRaw } from 'vue';
@@ -66,14 +70,18 @@ function bootModal(modalId) {
66
70
  this.$options.storeParent = this.$modalOpener;
67
71
 
68
72
  let originalDataFn = this.$options.data;
69
- this.$options.data = function() {
73
+ this.$options.data = function () {
70
74
  const injectedData = config.injectedData || {};
71
75
  const keepOriginalKeys = this.$options.keepOriginal || [];
72
76
  let data = originalDataFn ? originalDataFn.apply(this) : {};
73
77
 
74
78
  for (let key in injectedData) {
75
79
  if (!keepOriginalKeys.includes(key)) {
76
- if (injectedData[key] !== null && typeof(injectedData[key]) == 'object' && injectedData[key].constructor === Object) {
80
+ if (
81
+ injectedData[key] !== null &&
82
+ typeof injectedData[key] == 'object' &&
83
+ injectedData[key].constructor === Object
84
+ ) {
77
85
  data[key] = cloneDeep(injectedData[key]);
78
86
  } else {
79
87
  data[key] = injectedData[key];
@@ -116,7 +124,7 @@ app.mixin({
116
124
  }
117
125
  });
118
126
 
119
- app.config.globalProperties.$modal = function(classDef, injectedData, instanceCreationCallback) {
127
+ app.config.globalProperties.$modal = function (classDef, injectedData, instanceCreationCallback) {
120
128
  return new Promise((resolve, reject) => {
121
129
  const modalId = classDef.__modalId || classDef.__file || Math.random().toString(36).substring(2, 10);
122
130
  classDef.__modalId = modalId;
@@ -132,7 +140,7 @@ app.config.globalProperties.$modal = function(classDef, injectedData, instanceCr
132
140
  app.vm.store.rootInjections.push(markRaw(classDef));
133
141
  });
134
142
  });
135
- }
143
+ };
136
144
 
137
145
  // TODO: see about a injecting a root modal container & HMR inside it
138
146
  // modals, on render, can hot move themselves to body end
@@ -163,7 +171,7 @@ app.config.globalProperties.$modal = function(classDef, injectedData, instanceCr
163
171
 
164
172
  .vf-modal {
165
173
  background: white;
166
- box-shadow: 0px 3px 6px 0px rgba(0,0,0,.15);
174
+ box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.15);
167
175
  min-width: 200px;
168
176
  max-width: 95%;
169
177
  max-height: 95%;
@@ -187,4 +195,4 @@ app.config.globalProperties.$modal = function(classDef, injectedData, instanceCr
187
195
  flex-shrink: 1;
188
196
  flex-basis: 0%;
189
197
  }
190
- </style>
198
+ </style>
@@ -41,10 +41,10 @@ import debounce from 'lodash/debounce';
41
41
  const nullSymbol = Symbol(null);
42
42
  const createSymbol = Symbol('create');
43
43
 
44
- const VALID_KEYS = `\`1234567890-=[]\;',./~!@#$%^&*()_+{}|:"<>?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM`;
44
+ const VALID_KEYS = `\`1234567890-=[]\\;',./~!@#$%^&*()_+{}|:"<>?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM`;
45
45
 
46
46
  export default {
47
- emits: ['optionsLoaded', 'createItem'],
47
+ emits: ['optionsLoaded', 'createItem', 'update:modelValue'],
48
48
 
49
49
  props: [
50
50
  'modelValue',
@@ -72,7 +72,6 @@ export default {
72
72
  return {
73
73
  isLoaded: false,
74
74
  resolvedOptions: [],
75
- decoratedOptions: [],
76
75
  isSearching: false,
77
76
  searchText: '',
78
77
  selectedOption: null,
@@ -84,6 +83,10 @@ export default {
84
83
  },
85
84
 
86
85
  computed: {
86
+ hasManualOptionsObject() {
87
+ return this.options && typeof this.options === 'object' && !Array.isArray(this.options);
88
+ },
89
+
87
90
  effectiveDisabled() {
88
91
  return this.disabled || !this.resolvedOptions;
89
92
  },
@@ -115,7 +118,8 @@ export default {
115
118
  });
116
119
 
117
120
  if (this.shouldShowCreateOption) {
118
- const hasExactMatch = options.find(option => option.searchContent === strippedSearchText) !== undefined;
121
+ const hasExactMatch =
122
+ options.find(option => option.searchContent === strippedSearchText) !== undefined;
119
123
  if (!hasExactMatch) {
120
124
  options.push({
121
125
  key: createSymbol,
@@ -124,9 +128,7 @@ export default {
124
128
  }
125
129
  }
126
130
  }
127
- }
128
-
129
- else if (this.nullTitle) {
131
+ } else if (this.nullTitle) {
130
132
  options.unshift({
131
133
  key: nullSymbol,
132
134
  titleHtml: this.nullTitle
@@ -144,34 +146,27 @@ export default {
144
146
  return this.titleKey || 'name';
145
147
  },
146
148
 
147
- effectiveNoResultsText() {
148
- return this.noResultsText || 'No options match your search.';
149
- }
150
- },
151
-
152
- watch: {
153
- // props
154
-
155
- modelValue() {
156
- this.handleValueChanged();
157
- },
158
-
159
- options() {
160
- this.resolvedOptions = this.options;
149
+ effectiveValueKey() {
150
+ if (this.valueKey) return this.valueKey;
151
+ if (this.hasManualOptionsObject) return this.effectiveIdKey;
152
+ return undefined;
161
153
  },
162
154
 
163
- url() {
164
- this.handleSourceUpdate();
155
+ effectiveNoResultsText() {
156
+ return this.noResultsText || 'No options match your search.';
165
157
  },
166
158
 
167
- urlParams() {
168
- this.handleSourceUpdate();
159
+ resolvedOptionsArray() {
160
+ return this.hasManualOptionsObject
161
+ ? Object.entries(this.resolvedOptions).map(entry => ({
162
+ [this.effectiveIdKey]: entry[0],
163
+ [this.effectiveTitleKey]: entry[1]
164
+ }))
165
+ : this.resolvedOptions;
169
166
  },
170
167
 
171
- // data
172
-
173
- resolvedOptions() {
174
- this.decoratedOptions = this.resolvedOptions.map((option, index) => {
168
+ decoratedOptions() {
169
+ return this.resolvedOptionsArray.map((option, index) => {
175
170
  const title = this.getOptionTitle(option);
176
171
  const subtitle = this.getOptionSubtitle(option);
177
172
  const strippedTitle = title ? title.text.trim().toLowerCase() : '';
@@ -195,7 +190,31 @@ export default {
195
190
  ref: option
196
191
  };
197
192
  });
193
+ }
194
+ },
195
+
196
+ watch: {
197
+ // props
198
+
199
+ modelValue() {
200
+ this.handleValueChanged();
201
+ },
202
+
203
+ options() {
204
+ this.resolvedOptions = this.options;
205
+ },
206
+
207
+ url() {
208
+ this.handleSourceUpdate();
209
+ },
210
+
211
+ urlParams() {
212
+ this.handleSourceUpdate();
213
+ },
214
+
215
+ // data
198
216
 
217
+ decoratedOptions() {
199
218
  this.shouldDisplayOptions && setTimeout(this.highlightInitialOption, 0);
200
219
  },
201
220
 
@@ -227,6 +246,7 @@ export default {
227
246
 
228
247
  if (this.options) {
229
248
  this.resolvedOptions = this.options;
249
+ // this.buildDecoratedOptions();
230
250
  this.isLoaded = true;
231
251
  } else if (this.$isPropTruthy(this.preload)) {
232
252
  this.performInitialLoad();
@@ -235,7 +255,8 @@ export default {
235
255
  this.handleValueChanged();
236
256
 
237
257
  this.$watch('selectedOption', () => {
238
- const newValue = this.selectedOption && this.valueKey ? this.selectedOption[this.valueKey] : this.selectedOption;
258
+ const newValue =
259
+ this.selectedOption && this.effectiveValueKey ? this.selectedOption[this.effectiveValueKey] : this.selectedOption;
239
260
  newValue === this.modelValue || this.$emit('update:modelValue', newValue);
240
261
  });
241
262
  },
@@ -429,10 +450,10 @@ export default {
429
450
  this.selectedOptionTitle = null;
430
451
  this.$emit('createItem', createText);
431
452
  } else {
432
- const optionIndex = this.decoratedOptions.findIndex(
453
+ const selectedDecoratedOption = this.decoratedOptions.find(
433
454
  decoratedOption => decoratedOption.key == option.key
434
455
  );
435
- const realOption = this.resolvedOptions[optionIndex];
456
+ const realOption = selectedDecoratedOption.ref;
436
457
  this.selectedOption = realOption;
437
458
  this.selectedOptionTitle = this.getOptionTitle(this.selectedOption).text;
438
459
  this.searchText = this.selectedOptionTitle || '';
@@ -443,8 +464,10 @@ export default {
443
464
 
444
465
  handleValueChanged() {
445
466
  if (this.modelValue) {
446
- if (this.valueKey) {
447
- this.selectedOption = this.resolvedOptions.find(option => option[this.valueKey] === this.modelValue);
467
+ if (this.effectiveValueKey) {
468
+ this.selectedOption = this.resolvedOptionsArray.find(
469
+ option => option[this.effectiveValueKey] === this.modelValue
470
+ );
448
471
  } else {
449
472
  this.selectedOption = this.modelValue;
450
473
  }
package/src/config.js CHANGED
@@ -8,4 +8,4 @@ function applyConfiguration(inOptions) {
8
8
 
9
9
  Object.defineProperty(options, 'set', { value: applyConfiguration, enumerable: false });
10
10
 
11
- export default options;
11
+ export default options;
@@ -1,6 +1,7 @@
1
- import app from '../app';
2
1
  import $ from 'jquery';
3
2
 
3
+ import app from '../app';
4
+
4
5
  app.directive('autofocus', {
5
6
  mounted: fn,
6
7
  updated: fn
@@ -11,6 +12,6 @@ function fn(el, binding) {
11
12
  if (binding.value !== undefined && !binding.value) return;
12
13
  if (binding.oldValue !== undefined && binding.value == binding.oldValue) return;
13
14
  el.hasAutoFocused = true;
14
- el = ['BUTTON','INPUT','TEXTAREA','SELECT'].indexOf(el.tagName) > -1 ? el : $(el).find('input:first')[0];
15
+ el = ['BUTTON', 'INPUT', 'TEXTAREA', 'SELECT'].indexOf(el.tagName) > -1 ? el : $(el).find('input:first')[0];
15
16
  setTimeout(() => el.focus(), 10);
16
- }
17
+ }
@@ -1,4 +1,4 @@
1
- import app from '../app'
1
+ import app from '../app';
2
2
 
3
3
  app.directive('confirm-button', {
4
4
  mounted(el) {
@@ -37,4 +37,4 @@ app.directive('confirm-button', {
37
37
  el.addEventListener('mouseout', el._resetHandler);
38
38
  });
39
39
  }
40
- });
40
+ });
@@ -1,20 +1,18 @@
1
- import app from '../app';
2
1
  import moment from 'moment';
3
2
 
3
+ import app from '../app';
4
+
4
5
  app.directive('date-input', {
5
6
  beforeMount: fn
6
7
  });
7
8
 
8
- function fn(el, binding) {
9
+ function fn(el) {
9
10
  el.addEventListener('blur', () => {
10
11
  let val = el.value;
11
- if (/^[0-9]{1,2}\/[0-9]{1,2}$/.test(val))
12
- val += '/' + moment().format('YY');
12
+ if (/^[0-9]{1,2}\/[0-9]{1,2}$/.test(val)) val += '/' + moment().format('YY');
13
13
  let ts = Date.parse(val);
14
- if (isNaN(ts))
15
- el.value = '';
16
- else
17
- el.value = moment(ts).format('MM/DD/YYYY');
14
+ if (isNaN(ts)) el.value = '';
15
+ else el.value = moment(ts).format('MM/DD/YYYY');
18
16
  el.dispatchEvent(new Event('input'));
19
17
  });
20
- }
18
+ }
@@ -1,6 +1,7 @@
1
- import app from '../app';
2
1
  import moment from 'moment';
3
2
 
3
+ import app from '../app';
4
+
4
5
  app.directive('datetime', {
5
6
  beforeMount: applyDateTime,
6
7
  updated: applyDateTime
@@ -19,26 +20,27 @@ function getDateTimeValue(el, binding) {
19
20
  let prefix = '';
20
21
  let thatMoment = el.attributes.local ? moment(binding.value) : moment.utc(binding.value);
21
22
 
22
- if (!el.attributes['display-utc'])
23
- thatMoment.local();
23
+ if (!el.attributes['display-utc']) thatMoment.local();
24
24
 
25
25
  let format = el.attributes.format ? el.attributes.format.value : null;
26
26
 
27
27
  if (!format && el.attributes['relative-date']) {
28
28
  let thisMoment = moment();
29
- if (thisMoment.year() == thatMoment.year() && thisMoment.month() == thatMoment.month() && thisMoment.date() == thatMoment.date()) {
29
+ if (
30
+ thisMoment.year() == thatMoment.year() &&
31
+ thisMoment.month() == thatMoment.month() &&
32
+ thisMoment.date() == thatMoment.date()
33
+ ) {
30
34
  prefix = 'at';
31
35
  format = 'HH:mm';
32
36
  }
33
37
  }
34
38
 
35
- if (!format)
36
- format = 'MM/DD/YY HH:mm';
39
+ if (!format) format = 'MM/DD/YY HH:mm';
37
40
 
38
41
  let result = thatMoment.format(format);
39
42
 
40
- if (prefix)
41
- result = prefix + ' ' + result;
43
+ if (prefix) result = prefix + ' ' + result;
42
44
 
43
45
  return result;
44
- }
46
+ }