renusify 2.2.1 → 2.2.3

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
  <div ref="containerMessage"
3
- class="container-message-list" v-scroll="handle">
3
+ v-scroll.window="handle" class="container-message-list">
4
4
  <div v-for="message in messages" :key="message._id" class="message-container">
5
5
  <r-chat-message @see="$emit('see', $event)" :message="message" :is-me="message.user_id===myself.id"
6
6
  :user="message.user_id===myself.id?myself:participants[message.user_id]"></r-chat-message>
@@ -5,7 +5,7 @@
5
5
  v-for="(item, i) in allWPH"
6
6
  :key="i"
7
7
  :class="{ 'color-one-text': item === currentWPH }"
8
- class="me-1 mb-1 cursor-pointer"
8
+ class="ma-1 cursor-pointer"
9
9
  label
10
10
  outlined
11
11
  @click.prevent="changeWPH(item)"
@@ -2,10 +2,10 @@
2
2
  <r-select-input
3
3
  :label="$t('country','renusify')"
4
4
  v-model="country"
5
- v-if="!defaultCountry"
5
+ v-if="!hideCountry"
6
6
  @update:model-value="emit(true,true)"
7
7
  value="id"
8
- :searchLink="`https://codenus.com/api/apps/address?lang=${$r.lang}`"
8
+ :searchLink="`${baseUrl}?lang=${$r.lang}`"
9
9
  :rules="required?['required']:[]"
10
10
  :headers="{'Authorization':''}"
11
11
  :readonly="readonly"
@@ -15,9 +15,9 @@
15
15
  v-model="state"
16
16
  :disabled="!country"
17
17
  :key="country&&country['id']"
18
- v-if="!hideState"
18
+ v-if="show_state"
19
19
  @update:model-value="emit(false,true)"
20
- :searchLink="country&&`https://codenus.com/api/apps/address/${country['id']}?lang=${$r.lang}`"
20
+ :searchLink="country&&`${baseUrl}/${country['id']}?lang=${$r.lang}`"
21
21
  :rules="required?['required']:[]"
22
22
  value="id"
23
23
  :headers="{'Authorization':''}"
@@ -25,13 +25,13 @@
25
25
  :tile="tile">
26
26
 
27
27
  </r-select-input>
28
- <r-select-input v-if="!hideCity"
28
+ <r-select-input v-if="show_city"
29
29
  v-model="city"
30
30
  :disabled="!state"
31
31
  :key="state&&(country['id']+'-'+state['id'])"
32
32
  @update:model-value="emit(false,false)"
33
33
  :label="$t('city','renusify')"
34
- :searchLink="state&&`https://codenus.com/api/apps/address/${country['id']}/${state['id']}?lang=${$r.lang}`"
34
+ :searchLink="state&&`${baseUrl}/${country['id']}/${state['id']}?lang=${$r.lang}`"
35
35
  :rules="required?['required']:[]"
36
36
  value="id"
37
37
  :headers="{'Authorization':''}"
@@ -39,13 +39,13 @@
39
39
  :tile="tile">
40
40
 
41
41
  </r-select-input>
42
- <r-text-input v-if="!hideZipCode" @update:model-value="emit(false,false)"
42
+ <r-text-input v-if="show_zip" @update:model-value="emit(false,false)"
43
43
  :label="$t('zip_code','renusify')"
44
44
  v-model="zip_code"
45
45
  :tile="tile"
46
46
  :readonly="readonly"
47
47
  :rules="required?['required']:[]"></r-text-input>
48
- <r-text-area v-if="!hideStreet" @update:model-value="emit(false,false)"
48
+ <r-text-area v-if="show_street" @update:model-value="emit(false,false)"
49
49
  :label="$t('street','renusify')"
50
50
  v-model="street"
51
51
  :tile="tile"
@@ -59,13 +59,16 @@ export default {
59
59
  inheritAttrs: false,
60
60
  props: {
61
61
  required: Boolean,
62
+ stepShow: Boolean,
62
63
  allowCountries: Array,
64
+ hideCountry: Boolean,
63
65
  hideState: Boolean,
64
66
  hideCity: Boolean,
65
67
  hideZipCode: Boolean,
66
68
  hideStreet: Boolean,
67
69
  readonly: Boolean,
68
70
  tile: {type: Boolean, default: undefined},
71
+ baseUrl: {type: String, default: "https://codenus.com/api/apps/address"},
69
72
  defaultCountry: Object,
70
73
  modelValue: Object
71
74
  },
@@ -81,13 +84,43 @@ export default {
81
84
  },
82
85
  watch: {
83
86
  modelValue() {
84
- this.country = this.modelValue ? this.modelValue.country : null
87
+ this.country = this.modelValue ? this.modelValue.country : (this.defaultCountry ? this.defaultCountry : null)
85
88
  this.state = this.modelValue ? this.modelValue.state : null
86
89
  this.city = this.modelValue ? this.modelValue.city : null
87
90
  this.zip_code = this.modelValue ? this.modelValue.zip_code : null
88
91
  this.street = this.modelValue ? this.modelValue.street : null
89
92
  }
90
93
  },
94
+ computed: {
95
+ show_state() {
96
+ if (this.stepShow) {
97
+ return !this.hideState && this.country
98
+ } else {
99
+ return !this.hideState
100
+ }
101
+ },
102
+ show_city() {
103
+ if (this.stepShow) {
104
+ return !this.hideCity && this.state
105
+ } else {
106
+ return !this.hideCity
107
+ }
108
+ },
109
+ show_street() {
110
+ if (this.stepShow) {
111
+ return !this.hideStreet && this.city
112
+ } else {
113
+ return !this.hideStreet
114
+ }
115
+ },
116
+ show_zip() {
117
+ if (this.stepShow) {
118
+ return !this.hideZipCode && this.city
119
+ } else {
120
+ return !this.hideZipCode
121
+ }
122
+ }
123
+ },
91
124
  methods: {
92
125
  emit(clearState = false, clearCity = false) {
93
126
  setTimeout(() => {
@@ -1,147 +1,148 @@
1
1
  export default {
2
- props: {
3
- headers: Object
2
+ props: {
3
+ headers: Object
4
+ },
5
+ data() {
6
+ return {
7
+ imageStatus: 'inProgress',
8
+ CancelTokenSource: this.$axios.CancelToken.source(),
9
+ fileLink: '',
10
+ file: null,
11
+ uploadPercentage: 0,
12
+ }
13
+ },
14
+ methods: {
15
+ addFile() {
16
+ this.CancelTokenSource = this.$axios.CancelToken.source()
17
+ this.file = this.$refs.file.files[0]
18
+ if (!this.wPH) {
19
+ this.checkSave()
20
+ } else {
21
+ this.showCrop = true
22
+ }
23
+ this.showAdd = false
4
24
  },
5
- data() {
6
- return {
7
- imageStatus: 'inProgress',
8
- CancelTokenSource: this.$axios.CancelToken.source(),
9
- fileLink: '',
10
- file: null,
11
- uploadPercentage: 0,
12
- }
25
+ pickFile() {
26
+ this.$refs.file.click()
13
27
  },
14
- methods: {
15
- addFile() {
16
- this.CancelTokenSource = this.$axios.CancelToken.source()
17
- this.file = this.$refs.file.files[0]
18
- if (!this.wPH) {
19
- this.checkSave()
20
- } else {
21
- this.showCrop = true
22
- }
23
- this.showAdd = false
24
- },
25
- pickFile() {
26
- this.$refs.file.click()
27
- },
28
- fileDelete() {
29
- this.CancelTokenSource.cancel()
30
- this.deleteImage()
31
- this.showFile = false
32
- this.$nextTick(() => {
33
- this.showFile = true
34
- })
35
- this.file = null
36
- this.metaList = {}
37
- this.uploadPercentage = 0
38
- this.showAdd = true
39
- this.$emit('delete', true)
40
- this.$emit('file-link', null)
41
- },
42
- checkSave() {
43
- if (this.maxFileSize && this.file.size > this.maxFileSize) {
44
- this.CancelTokenSource.cancel()
45
- console.error('max file size must be:' + this.maxFileSize);
46
- console.error('current file size is:' + this.file.size);
47
- this.$toast(this.$t(['max_allow_size', [this.maxFileSize / 1024]], 'renusify'))
48
- return
49
- }
28
+ fileDelete() {
29
+ this.CancelTokenSource.cancel()
30
+ this.deleteImage().then(() => {
31
+ this.showFile = false
32
+ this.$nextTick(() => {
33
+ this.showFile = true
34
+ })
35
+ this.file = null
36
+ this.metaList = {}
37
+ this.uploadPercentage = 0
38
+ this.showAdd = true
39
+ this.$emit('delete', true)
40
+ this.$emit('file-link', null)
41
+ })
42
+ },
43
+ checkSave() {
44
+ if (this.maxFileSize && this.file.size > this.maxFileSize) {
45
+ this.CancelTokenSource.cancel()
46
+ console.error('max file size must be:' + this.maxFileSize);
47
+ console.error('current file size is:' + this.file.size);
48
+ this.$toast(this.$t(['max_allow_size', [this.maxFileSize / 1024]], 'renusify'))
49
+ return
50
+ }
50
51
 
51
- if (this.wPH) {
52
- let img = new Image();
53
- let objectUrl = URL.createObjectURL(this.file);
54
- let that = this
55
- const is_array = Array.isArray(this.wPH)
56
- let wPH = []
57
- if (is_array) {
58
- this.wPH.forEach((item) => {
59
- item = item.split('/')
60
- if (item.length === 2) {
61
- wPH.push(parseFloat(item[0]) / parseFloat(item[1]))
52
+ if (this.wPH) {
53
+ let img = new Image();
54
+ let objectUrl = URL.createObjectURL(this.file);
55
+ let that = this
56
+ const is_array = Array.isArray(this.wPH)
57
+ let wPH = []
58
+ if (is_array) {
59
+ this.wPH.forEach((item) => {
60
+ item = item.toString().split('/')
61
+ if (item.length === 2) {
62
+ wPH.push(parseFloat(item[0]) / parseFloat(item[1]))
62
63
 
63
- } else {
64
- wPH.push(parseFloat(item[0]))
64
+ } else {
65
+ wPH.push(parseFloat(item[0]))
65
66
 
66
- }
67
- })
68
- } else {
69
- if (typeof this.wPH === 'string') {
70
- let item = this.wPH
71
- item = item.split('/')
72
- if (item.length === 2) {
73
- wPH.push(parseFloat((parseFloat(item[0]) / parseFloat(item[1])).toFixed(4)))
67
+ }
68
+ })
69
+ } else {
70
+ if (typeof this.wPH === 'string') {
71
+ let item = this.wPH
72
+ item = item.split('/')
73
+ if (item.length === 2) {
74
+ wPH.push(parseFloat((parseFloat(item[0]) / parseFloat(item[1])).toFixed(4)))
74
75
 
75
- } else {
76
- wPH.push(parseFloat(item[0]))
76
+ } else {
77
+ wPH.push(parseFloat(item[0]))
77
78
 
78
- }
79
- } else {
80
- wPH.push(this.wPH)
81
- }
79
+ }
80
+ } else {
81
+ wPH.push(this.wPH)
82
+ }
82
83
 
83
- }
84
- img.onload = function () {
85
- const wph = parseFloat((this.width / this.height).toFixed(4))
86
- if (!wPH.includes(wph)) {
87
- that.CancelTokenSource.cancel()
88
- that.$toast(that.$t(['image_w_p_h', [that.wPH]], 'renusify'))
89
- console.error('width per height must be:' + that.wPH, wPH);
90
- console.error('current width per height is:' + wph);
91
- }
84
+ }
85
+ img.onload = function () {
86
+ const wph = parseFloat((this.width / this.height).toFixed(4))
87
+ if (!wPH.includes(wph)) {
88
+ that.CancelTokenSource.cancel()
89
+ that.$toast(that.$t(['image_w_p_h', [that.wPH]], 'renusify'))
90
+ console.error('width per height must be:' + that.wPH, wPH);
91
+ console.error('current width per height is:' + wph);
92
+ }
92
93
 
93
- URL.revokeObjectURL(objectUrl);
94
- that.saveImage()
95
- };
96
- img.src = objectUrl;
97
- return;
98
- }
99
- this.saveImage()
100
- },
101
- saveImage() {
102
- this.imageStatus = 'inProgress'
103
- let fileData = new FormData()
104
- fileData.append('file', this.file, this.file.name)
105
- let headers = this.headers
106
- if (!headers) {
107
- headers = {}
108
- }
109
- headers['Content-Type'] = 'multipart/form-data'
110
- let link = this.uploadLink
111
- if (this.maxFileSize) {
112
- if (link.indexOf('?') === -1) {
113
- link += '?'
114
- } else {
115
- link += '&'
116
- }
117
- link += 'max_size=' + this.maxFileSize
118
- }
119
- this.$axios.post(link, fileData,
120
- {
121
- headers: headers,
122
- onUploadProgress: function (progressEvent) {
123
- this.uploadPercentage = Math.min(parseInt(Math.floor((progressEvent.loaded * 100) / progressEvent.total)), 98)
124
- }.bind(this),
125
- cancelToken: this.CancelTokenSource.token
126
- }
127
- )
128
- .then((res) => {
129
- this.fileLink = res.data.link
130
- this.uploadPercentage = 100
131
- this.emit()
132
- this.imageStatus = 'finished'
133
- }, () => {
134
- this.imageStatus = 'fails'
135
- this.uploadPercentage = 0
136
- })
137
- },
138
- deleteImage() {
139
- this.$axios.delete(this.uploadLink,
140
- {
141
- data: {link: this.fileLink},
142
- headers: this.headers
143
- }
144
- )
145
- },
146
- }
94
+ URL.revokeObjectURL(objectUrl);
95
+ that.saveImage()
96
+ };
97
+ img.src = objectUrl;
98
+ return;
99
+ }
100
+ this.saveImage()
101
+ },
102
+ saveImage() {
103
+ this.imageStatus = 'inProgress'
104
+ let fileData = new FormData()
105
+ fileData.append('file', this.file, this.file.name)
106
+ let headers = this.headers
107
+ if (!headers) {
108
+ headers = {}
109
+ }
110
+ headers['Content-Type'] = 'multipart/form-data'
111
+ let link = this.uploadLink
112
+ if (this.maxFileSize) {
113
+ if (link.indexOf('?') === -1) {
114
+ link += '?'
115
+ } else {
116
+ link += '&'
117
+ }
118
+ link += 'max_size=' + this.maxFileSize
119
+ }
120
+ this.$axios.post(link, fileData,
121
+ {
122
+ headers: headers,
123
+ onUploadProgress: function (progressEvent) {
124
+ this.uploadPercentage = Math.min(parseInt(Math.floor((progressEvent.loaded * 100) / progressEvent.total)), 98)
125
+ }.bind(this),
126
+ cancelToken: this.CancelTokenSource.token
127
+ }
128
+ )
129
+ .then((res) => {
130
+ this.fileLink = res.data.link
131
+ this.uploadPercentage = 100
132
+ this.emit()
133
+ this.imageStatus = 'finished'
134
+ }, () => {
135
+ this.imageStatus = 'fails'
136
+ this.uploadPercentage = 0
137
+ })
138
+ },
139
+ deleteImage() {
140
+ return this.$axios.delete(this.uploadLink,
141
+ {
142
+ data: {link: this.fileLink},
143
+ headers: this.headers
144
+ }
145
+ )
146
+ },
147
+ }
147
148
  }
@@ -14,7 +14,7 @@
14
14
  >
15
15
  {{ `% ${uploadPercentage}` }}
16
16
  </r-progress-circle>
17
- <r-btn :href="'/'+fileLink" class="image-copy" icon target="_blank">
17
+ <r-btn :href="fileLink" class="image-copy" icon target="_blank">
18
18
  <r-icon v-html="$r.icons.eye"></r-icon>
19
19
  </r-btn>
20
20
  <img v-if="isImg()" :class="`image ${imageStatus} `" :src="getUrl(file)">
@@ -89,7 +89,7 @@ export default {
89
89
  methods: {
90
90
  setValue() {
91
91
  if (this.modelValue) {
92
- this.fileLink = this.meta ? this.modelValue['url'] : this.modelValue
92
+ this.fileLink = this.$helper.fix_url(this.meta ? this.modelValue['url'] : this.modelValue)
93
93
  this.metaList = this.meta ? this.modelValue['meta'] : {}
94
94
  this.showAdd = false
95
95
  this.imageStatus = 'finished'
@@ -99,7 +99,7 @@ export default {
99
99
  },
100
100
  getUrl(value) {
101
101
  if (this.modelValue) {
102
- return '/' + this.fileLink
102
+ return this.fileLink
103
103
  } else {
104
104
  return URL.createObjectURL(value)
105
105
  }
@@ -21,7 +21,8 @@
21
21
  @click.prevent="open">
22
22
  <r-icon v-html="$r.icons.plus"></r-icon>
23
23
  </r-btn>
24
- <div v-else-if="show" class="d-flex v-baseline">
24
+ <div v-else-if="show" class="d-flex v-baseline flex-wrap">
25
+ <slot :add="add" :info="info">
25
26
  <r-text-input
26
27
  v-if="!is_array"
27
28
  v-model="info.key"
@@ -50,6 +51,7 @@
50
51
  :tile="tile"
51
52
  v-model="info.value" :label="valueLabel||$t('value','renusify')"></r-switch-input>
52
53
  <r-btn :rounded="!c_tile" class="ms-1 color-success" @click.prevent="add">{{ $t('add', 'renusify') }}</r-btn>
54
+ </slot>
53
55
  </div>
54
56
  </div>
55
57
  <div v-else :class="{'state-error':error}" class="json-highlight ltr">
@@ -46,7 +46,7 @@
46
46
  width:$refs.select&&$refs.select.getBoundingClientRect().width+'px'
47
47
  }"
48
48
  >
49
- <r-list :filter="inputVal&&inputVal.trim()"
49
+ <r-list :filter="!searchLink?(inputVal&&inputVal.trim()):''"
50
50
  :items="genItems"
51
51
  :multiple="multiple"
52
52
  :modelValue="chips"
@@ -1,5 +1,19 @@
1
1
  <template>
2
2
  <div :class="`${$r.prefix}input-tel`">
3
+ <r-btn :disabled="!select||readonly"
4
+ :rounded="!c_tile" class="btn-country ltr ms-1" outlined @click.stop="toggleDropdown">
5
+ <div :class="activeCountry.iso2.toLowerCase()" class="iti-flag"></div>
6
+ <span class="country-code pa-1"> +{{ activeCountry.dialCode }} </span>
7
+ <span class="dropdown-arrow">{{ open ? "▲" : "▼" }}</span>
8
+ </r-btn>
9
+ <r-text-input v-model="tel.phone" :label="label?label:$t('phone','renusify')"
10
+ :readonly="readonly"
11
+ :rules="required?['required','number']:['number']"
12
+ :tile="c_tile"
13
+ class="input-phone"
14
+ @update:model-value="emit"
15
+ >
16
+ </r-text-input>
3
17
  <r-modal
4
18
  v-model="open"
5
19
  >
@@ -20,21 +34,6 @@
20
34
  </r-list>
21
35
  </div>
22
36
  </r-modal>
23
- <r-btn class="btn-country ltr ms-1"
24
- :rounded="!c_tile" :disabled="!select||readonly" @click.stop="toggleDropdown" outlined>
25
- <div :class="activeCountry.iso2.toLowerCase()" class="iti-flag"></div>
26
- <span class="country-code pa-1"> +{{ activeCountry.dialCode }} </span>
27
- <span class="dropdown-arrow">{{ open ? "▲" : "▼" }}</span>
28
- </r-btn>
29
- <r-text-input class="input-phone" :label="label?label:$t('phone','renusify')"
30
- @update:model-value="emit"
31
- :tile="c_tile"
32
- :readonly="readonly"
33
- :rules="required?['required','number']:['number']"
34
- v-model="tel.phone"
35
- >
36
- </r-text-input>
37
-
38
37
  </div>
39
38
  </template>
40
39
 
@@ -62,7 +61,7 @@ export default {
62
61
  }
63
62
 
64
63
  },
65
- emits:['update:modelValue'],
64
+ emits: ['update:modelValue'],
66
65
  data() {
67
66
  return {
68
67
  tel: {
@@ -75,19 +74,19 @@ export default {
75
74
  open: false
76
75
  }
77
76
  },
78
- mounted() {
79
- import('./assets/all-countries.js').then((d)=>{
77
+ created() {
78
+ import('./assets/all-countries.js').then((d) => {
80
79
  this.countries = d.default;
81
- this.initializeCountry()
80
+ if (this.modelValue) {
81
+ let a = this.modelValue.split(' ')
82
+ this.tel.country_code = a[0]
83
+ this.tel.phone = a[1]
84
+ this.activeCountry = this.findCountryByCode(this.tel.country_code)
85
+ } else {
86
+ this.initializeCountry()
87
+ }
82
88
  })
83
- },
84
- created() {
85
- if (this.modelValue) {
86
- let a = this.modelValue.split(' ')
87
- this.tel.country_code = a[0]
88
- this.tel.phone = a[1]
89
- this.activeCountry.dialCode = this.tel.country_code
90
- }
89
+
91
90
  },
92
91
  computed: {
93
92
  c_tile() {
@@ -109,6 +108,9 @@ export default {
109
108
  findCountry(iso = '') {
110
109
  return this.countries.find(country => country.iso2 === iso)
111
110
  },
111
+ findCountryByCode(code = '') {
112
+ return this.countries.find(country => country.dialCode === code)
113
+ },
112
114
 
113
115
  choose(country) {
114
116
  this.activeCountry = country
@@ -152,15 +154,16 @@ export default {
152
154
  display: flex;
153
155
  align-items: baseline;
154
156
  direction: ltr;
155
-
157
+ flex-wrap: wrap;
156
158
  .btn-country {
157
- width: 120px;
159
+ width: 100px;
158
160
  border-color: var(--color-sheet-low)
159
161
 
160
162
  }
161
163
 
162
164
  .input-phone {
163
- width: calc(100% - 120px);
165
+ width: calc(100% - 104px);
166
+ min-width: 150px;
164
167
  }
165
168
  }
166
169
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div v-intersect[modifier]="check" :class="{
2
+ <div v-intersect.[modifier]="check" :class="{
3
3
  [$r.prefix+'img']:true,
4
4
  'img-hoverZoom':hoverZoom,'img-hoverDark':hoverDark,'img-hoverTitle':hoverTitle}"
5
5
  ref="rImg">
@@ -94,7 +94,7 @@ export default {
94
94
  res += this.query
95
95
  }
96
96
  if (this.isSvg && this.svgCache) {
97
- res += 'c=' + this.svgCache
97
+ res += '&c=' + this.svgCache
98
98
  }
99
99
  if (!this.isSvg && ((this.autoSize && this.size.width > 0) || this.width)) {
100
100
  res += `&w=${this.size.width}`
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="infinite-page">
3
- <div class="infinite-page-container" v-scroll="onScroll">
3
+ <div v-scroll.window="onScroll" class="infinite-page-container">
4
4
  <slot :items="datacollection" :total="total"></slot>
5
5
  </div>
6
6
  <r-progress-line color="color-two"
@@ -34,7 +34,7 @@
34
34
  @focusout="active = false"
35
35
  @input="handle"
36
36
  />
37
- <r-icon v-html="$r.icons.search"></r-icon>
37
+ <r-icon class="mx-1" v-html="$r.icons.search"></r-icon>
38
38
  </span>
39
39
  </div>
40
40
  <r-card
@@ -305,6 +305,8 @@ export default {
305
305
  list-style: none;
306
306
  padding: 0;
307
307
  white-space: nowrap;
308
+ max-width: 100%;
309
+ overflow: auto;
308
310
  }
309
311
 
310
312
  .slider-dot {
@@ -1,252 +1,158 @@
1
1
  <template>
2
- <div>
3
- <r-container class="container-fluid">
4
- <r-row class="h-start h-space-between">
5
- <r-col class="col-auto">
6
- <r-btn @click.prevent="newItem"
7
- v-if="!disableAdd"
8
- class="color-success-text"
9
- outlined
10
- rounded>{{ $t('new', 'renusify') }}
2
+ <div>
3
+ <r-container class="container-fluid pa-0 mb-3">
4
+ <r-row class="h-start h-space-between" no-gutter>
5
+ <r-col class="col-auto">
6
+ <r-btn v-if="!disableAdd"
7
+ class="color-success-text"
8
+ outlined
9
+ rounded
10
+ @click.prevent="newItem">{{ $t('new', 'renusify') }}
11
+ </r-btn>
12
+ </r-col>
13
+ <r-col class="col-auto">
14
+ <template v-if="mcud">
15
+ <r-btn class="color-error mx-1" icon @click.prevent="showConfirm=true">
16
+ <r-icon v-html="$r.icons.delete"></r-icon>
11
17
  </r-btn>
12
- </r-col>
13
- <r-col class="col-auto">
14
- <template v-if="mcud">
15
- <r-btn class="color-error mx-1" icon @click.prevent="showConfirm=true">
16
- <r-icon v-html="$r.icons.delete"></r-icon>
17
- </r-btn>
18
- <r-btn icon class="color-success mx-1" @click.prevent="$emit('copy',true)">
19
- <r-icon v-html="$r.icons.copy"></r-icon>
20
- </r-btn>
21
- <r-btn icon class="color-info mx-1" @click.prevent="$emit('edit',true)">
22
- <r-icon v-html="$r.icons.edit"></r-icon>
23
- </r-btn>
24
- </template>
25
- <r-btn @click.prevent="open"
26
- v-if="advanceSearch"
27
- :class="{'color-info':!show,'color-error':show}"
28
- rounded>{{$t(!show?'advance_search':'search','renusify')}}
29
- </r-btn>
30
- </r-col>
31
- <r-col v-if="!show" class="col-12">
32
- <r-text-input :label="$t('search','renusify')"
33
- @update:modelValue="$emit('update:modelValue',$event)"
34
- :model-value="search"></r-text-input>
35
- </r-col>
36
- <r-col v-else class="col-12">
37
- <r-container class="pa-0" full-width>
38
- <r-select-input :model-value="select" :items="header" text="text" disableSearch
39
- :label="$t('add','renusify')" @update:model-value="add"></r-select-input>
40
- <r-divider class="my-3"></r-divider>
41
- <template v-for="(item,i) in inputs" :key="i">
42
- <r-row v-if="['r-text-input','r-text-area'].includes(item.option.type)" class="v-baseline">
43
- <r-col class="col-5 md-3">
44
- <r-select-input v-model="item.advance.action"
45
- :items="[
46
- {name:$t('advance_search_like','renusify'),value:'r'},
47
- {name:$t('advance_search_not_like','renusify'),value:'nr'},
48
- {name:$t('advance_search_equal','renusify'),value:'e'},
49
- {name:$t('advance_search_not_equal','renusify'),value:'ne'},
50
- {name:$t('advance_search_id','renusify'),value:'_id'}
51
- ]"
52
- justValue
53
- disableSearch
54
- firstSelect
55
- :label="$t('advance_search_operator','renusify')"></r-select-input>
56
- </r-col>
57
- <r-col class="col-6 md-8">
58
- <r-text-input v-model="item.advance.search" :label="item.text"></r-text-input>
59
- </r-col>
60
- <r-col class="col-1">
61
- <r-btn class="color-error" icon @click.prevent="del(i)">
62
- <r-icon v-html="$r.icons.delete"></r-icon>
63
- </r-btn>
64
- </r-col>
65
- </r-row>
66
- <r-row v-else-if="'r-number-input'===item.option.type" class="v-baseline">
67
- <r-col class="col-6 md-3">
68
- <r-select-input v-model="item.advance.action"
69
- :items="[
18
+ <r-btn class="color-success mx-1" icon @click.prevent="$emit('copy',true)">
19
+ <r-icon v-html="$r.icons.copy"></r-icon>
20
+ </r-btn>
21
+ <r-btn class="color-info mx-1" icon @click.prevent="$emit('edit',true)">
22
+ <r-icon v-html="$r.icons.edit"></r-icon>
23
+ </r-btn>
24
+ </template>
25
+ <r-btn v-if="advanceSearch"
26
+ :class="{'color-info':!show,'color-error':show}"
27
+ rounded
28
+ @click.prevent="open">{{ $t(!show ? 'advance_search' : 'search', 'renusify') }}
29
+ </r-btn>
30
+ </r-col>
31
+ <r-col v-if="!show" class="col-12">
32
+ <r-text-input :label="$t('search','renusify')"
33
+ :model-value="modelValue"
34
+ @update:modelValue="$emit('update:modelValue',$event)"></r-text-input>
35
+ </r-col>
36
+ <r-col v-else class="col-12">
37
+ <r-container class="pa-0" full-width>
38
+ <r-json-input v-model="advance"
39
+ :label="$t('search','renusify')">
40
+ <template v-slot="{info,add}">
41
+ <r-select-input v-model="info.key"
42
+ :items="headers[0]"
43
+ :label="$t('name','renusify')"
44
+ just-value></r-select-input>
45
+
46
+ <r-select-input v-if="info.key" :key="info.key" v-model="info.action"
47
+ :items="[
70
48
  {name:$t('advance_search_equal','renusify'),value:'e'},
71
49
  {name:$t('advance_search_not_equal','renusify'),value:'ne'},
72
50
  {name:$t('advance_search_gt','renusify'),value:'gt'},
73
- {name:$t('advance_search_gte','renusify'),value:'gte'},
74
- {name:$t('advance_search_lt','renusify'),value:'lt'},
75
- {name:$t('advance_search_lte','renusify'),value:'lte'}]"
76
- firstSelect
77
- justValue
78
- disableSearch
79
- :label="$t('advance_search_operator','renusify')"></r-select-input>
80
- </r-col>
81
- <r-col class="col-6 md-8">
82
- <r-number-input v-model="item.advance.search" :label="item.text"></r-number-input>
83
- </r-col>
84
- <r-col class="col-1">
85
- <r-btn class="color-error" icon @click.prevent="del(i)">
86
- <r-icon v-html="$r.icons.delete"></r-icon>
87
- </r-btn>
88
- </r-col>
89
- </r-row>
90
- <r-row v-else-if="'r-switch-input'===item.option.type" class="v-baseline">
91
- <r-col class="col-5 md-3">
92
- <r-select-input v-model="item.advance.action"
93
- :items="[
94
- {name:$t('advance_search_equal','renusify'),value:'e'}
95
- ]"
96
- justValue
97
- firstSelect
98
- disableSearch
99
- :label="$t('advance_search_operator','renusify')"></r-select-input>
100
- </r-col>
101
- <r-col class="col-6 md-8">
102
- <r-switch-input v-model="item.advance.search" :label="item.text"></r-switch-input>
103
- </r-col>
104
- <r-col class="col-1">
105
- <r-btn class="color-error" icon @click.prevent="del(i)">
106
- <r-icon v-html="$r.icons.delete"></r-icon>
107
- </r-btn>
108
- </r-col>
109
- </r-row>
110
- <r-row v-else-if="'r-select-input'===item.option.type" class="v-baseline">
111
- <r-col class="col-5 md-3">
112
- <r-select-input v-model="item.advance.action"
113
- :items="[
114
- {name:$t('advance_search_in','renusify'),value:'in'},
115
- {name:$t('advance_search_not_in','renusify'),value:'nin'}
116
- ]"
117
- justValue
118
- firstSelect
119
- disableSearch
120
- :label="$t('advance_search_operator','renusify')"></r-select-input>
121
- </r-col>
122
- <r-col class="col-6 md-8">
123
- <r-select-input v-model="item.advance.search" :label="item.text" :items="item.option.items"
124
- justValue multiple tags></r-select-input>
125
- </r-col>
126
- <r-col class="col-1">
127
- <r-btn class="color-error" icon @click.prevent="del(i)">
128
- <r-icon v-html="$r.icons.delete"></r-icon>
129
- </r-btn>
130
- </r-col>
131
- </r-row>
132
- <r-row v-else-if="'r-json-input'===item.option.type" class="v-baseline">
133
- <r-col class="col-5 md-3">
134
- <r-select-input v-model="item.advance.action"
135
- :items="[
136
- {name:$t('advance_search_equal','renusify'),value:'e'},
137
- {name:$t('advance_search_not_equal','renusify'),value:'ne'}
138
- ]"
139
- :label="$t('advance_search_operator','renusify')"
140
- disableSearch
141
- firstSelect
142
- justValue></r-select-input>
143
- </r-col>
144
- <r-col class="col-6 md-8">
145
- <r-json-input v-model="item.advance.search" :label="item.text"></r-json-input>
146
- </r-col>
147
- <r-col class="col-1">
148
- <r-btn class="color-error" icon @click.prevent="del(i)">
149
- <r-icon v-html="$r.icons.delete"></r-icon>
150
- </r-btn>
151
- </r-col>
152
- </r-row>
153
- <r-row v-else-if="['r-date-input','r-time-ago'].includes(item.option.type)" class="v-baseline">
154
- <r-col class="col-5 md-3" :a="item.advance.t='date'">
155
- <r-select-input v-model="item.advance.action"
156
- :items="[
157
- {name:$t('advance_search_gt','renusify'),value:'gt'},
158
- {name:$t('advance_search_gte','renusify'),value:'gte'},
159
- {name:$t('advance_search_lt','renusify'),value:'lt'},
160
- {name:$t('advance_search_lte','renusify'),value:'lte'}
161
- ]"
162
- justValue
163
- disableSearch
164
- firstSelect
165
- :label="$t('advance_search_operator','renusify')"></r-select-input>
166
- </r-col>
167
- <r-col class="col-6 md-8">
168
- <r-date-input with-time v-model="item.advance.search" :label="item.text"></r-date-input>
169
- </r-col>
170
- <r-col class="col-1">
171
- <r-btn class="color-error" icon @click.prevent="del(i)">
172
- <r-icon v-html="$r.icons.delete"></r-icon>
173
- </r-btn>
174
- </r-col>
175
- </r-row>
176
- </template>
177
- <r-btn block rounded class="color-info" :loading="loading" @click.prevent="send">{{$t('search','renusify')}}</r-btn>
178
- </r-container>
179
- </r-col>
180
- </r-row>
181
- </r-container>
182
- <r-progress-line v-if="loading" color="color-one"></r-progress-line>
183
- <r-confirm
184
- hard
185
- v-model="showConfirm"
186
- v-on:accept="accept"
187
- v-on:cancel="showConfirm = false"
188
- />
189
- </div>
51
+ {name:$t('advance_search_lt','renusify'),value:'lt'}]"
52
+ :label="$t('advance_search_operator','renusify')"
53
+ disableSearch
54
+ firstSelect
55
+ justValue></r-select-input>
56
+
57
+ <div v-if="info.key" :key="info.key">
58
+ <component :is="headers[1][info.key].type" v-if="headers[1][info.key].type"
59
+ v-model="info.value"
60
+ :label="$t('search','renusify')"
61
+ v-bind="headers[1][info.key].props"></component>
62
+ </div>
63
+ <r-btn :rounded="!$r.inputs.tile" class="ms-1 color-success" @click.prevent="added(info,add)">
64
+ {{ $t('add', 'renusify') }}
65
+ </r-btn>
66
+ </template>
67
+ </r-json-input>
68
+
69
+ <r-btn :loading="loading" block class="color-info mt-2" rounded @click.prevent="send">
70
+ {{ $t('search', 'renusify') }}
71
+ </r-btn>
72
+ </r-container>
73
+ </r-col>
74
+ </r-row>
75
+ </r-container>
76
+ <r-progress-line v-if="loading" color="color-one"></r-progress-line>
77
+ <r-confirm
78
+ v-model="showConfirm"
79
+ hard
80
+ v-on:accept="accept"
81
+ v-on:cancel="showConfirm = false"
82
+ />
83
+ </div>
190
84
  </template>
191
85
  <script>
192
- export default {
193
- name: 'manageHeader',
194
- props: {
195
- headerTable: Object,
196
- loading: Boolean,
197
- disableAdd: Boolean,
198
- advanceSearch: Boolean,
199
- mcud: Boolean,
200
- newItem: Function,
201
- search: String
202
- },
203
- emits:['update:modelValue','copy','edit','delete','a-search'],
204
- data() {
205
- return {
206
- show: false,
207
- showConfirm: false,
208
- select: [],
209
- inputs: []
210
- }
211
- },
212
- methods: {
213
- accept(){
214
- this.$emit('delete',true)
215
- this.showConfirm=false
216
- },
217
- send() {
218
- this.$emit('update:modelValue', '')
219
- let r = []
220
- this.inputs.forEach((item) => {
221
- r.push({'name': item.value, 'advance': item.advance})
222
- })
223
- this.$emit('a-search', r)
224
- },
225
- del(i){
226
- this.inputs.splice(i,1)
227
- },
228
- open(){
229
- this.show=!this.show
230
- },
231
- add($event) {
232
- this.inputs.push($event)
233
- $event.advance = {}
234
- if ($event.option.type === 'r-switch-input') {
235
- $event.advance.search = false
236
- }
237
- this.select = []
238
- }
239
- },
240
- computed: {
241
- header() {
242
- let res = []
243
- this.headerTable.forEach((item) => {
244
- if (['r-text-input', 'r-text-area', 'r-number-input', 'r-switch-input', 'r-select-input', 'r-json-input', 'r-date-input', 'r-time-ago'].includes(item.option.type)) {
245
- res.push(item)
246
- }
247
- })
248
- return res
249
- }
86
+ export default {
87
+ name: 'manageHeader',
88
+ props: {
89
+ headerTable: Object,
90
+ loading: Boolean,
91
+ disableAdd: Boolean,
92
+ advanceSearch: Boolean,
93
+ mcud: Boolean,
94
+ newItem: Function,
95
+ modelValue: String
96
+ },
97
+ emits: ['update:modelValue', 'copy', 'edit', 'delete', 'a-search'],
98
+ data() {
99
+ return {
100
+ show: false,
101
+ showConfirm: false,
102
+ advance: null
103
+ }
104
+ },
105
+ computed: {
106
+ headers() {
107
+ let r = []
108
+ let r2 = {}
109
+ for (let i = 0; i < this.headerTable.length; i++) {
110
+ r.push({'name': this.$t(this.headerTable[i].text), 'value': this.headerTable[i].value})
111
+ r2[this.headerTable[i].value] = this.headerTable[i].option
112
+ if (this.headerTable[i].option.type === 'r-date-input' || this.headerTable[i].option.type === 'r-time-ago') {
113
+ r2[this.headerTable[i].value]['withTime'] = true
250
114
  }
115
+ }
116
+ return [r, r2]
251
117
  }
118
+ },
119
+ methods: {
120
+ added(info, add) {
121
+ let item = this.headers[1][info.key]
122
+ if (info.key === '_id' || item.is_object_id) {
123
+ info.value = {'$oid': info.value}
124
+ } else if (item.type === 'r-date-input' || item.type === 'r-time-ago') {
125
+ if (info.action === 'eq') {
126
+ info.value = {'$date': info.value}
127
+ } else if (info.action === 'ne') {
128
+ info.value = {'$ne': {'$date': info.value}}
129
+ } else if (info.action === 'gt') {
130
+ info.value = {'$gt': {'$date': info.value}}
131
+ } else if (info.action === 'lt') {
132
+ info.value = {'$lt': {'$date': info.value}}
133
+ }
134
+ } else {
135
+ if (info.action === 'ne') {
136
+ info.value = {'$ne': info.value}
137
+ } else if (info.action === 'gt') {
138
+ info.value = {'$gt': info.value}
139
+ } else if (info.action === 'lt') {
140
+ info.value = {'$lt': info.value}
141
+ }
142
+ }
143
+ add()
144
+ },
145
+ accept() {
146
+ this.$emit('delete', true)
147
+ this.showConfirm = false
148
+ },
149
+ send() {
150
+ this.$emit('update:modelValue', '')
151
+ this.$emit('a-search', this.advance)
152
+ },
153
+ open() {
154
+ this.show = !this.show
155
+ },
156
+ }
157
+ }
252
158
  </script>
@@ -14,7 +14,4 @@ export * as l_col from '../../container/col.js'
14
14
  export * as l_divider from '../../container/divider.js'
15
15
  export * as l_json from '../../form/jsonInput/index.js'
16
16
  export * as l_text from '../../form/textInput/index.js'
17
- export * as l_select from '../../form/selectInput/index.js'
18
- export * as l_date from '../../form/dateInput/index.js'
19
- export * as l_number from '../../form/numberInput/index.js'
20
17
  export * as l_switch from '../../form/switchInput/index.js'
@@ -58,7 +58,60 @@
58
58
  @edit="copyHandle('edit')"
59
59
  @update:modelValue="searching()"
60
60
  @a-search="(a_search=$event),(searching())"></manage-header>
61
- <r-table :headers="headerTable" :items="table.data" :key-item="itemId" :responsive="responsive"
61
+ <div v-if="card" class="d-flex overflow-x-auto">
62
+ <div class="d-flex">
63
+ <r-card v-for="(item,i) in table.data" :key="i" :class="{'br-lg':!$r.inputs.tile}" class="pa-3 me-3"
64
+ style="width: 300px">
65
+ <div v-for="(h,j) in headerTable" :key="i+'-'+j" class="d-flex text-no-wrap overflow-x-auto">
66
+ <slot :data="item" :header="h" name="card">
67
+ <div v-if="h['option']['type']==='r-date-input' && item[h['value']]!==undefined" class="py-2">
68
+ {{ h['text'] }}: {{ $d(new Date(item[h['value']]), h['option']['format'] || 'short') }}
69
+ </div>
70
+ <div
71
+ v-else-if="h['option']['type']==='r-time-ago' && item[h['value']]!==undefined" class="py-2">
72
+ {{ h['text'] }}:
73
+ <r-time-ago :time="item[h['value']]"></r-time-ago>
74
+ </div>
75
+ <div v-else-if="h['option']['type']==='r-switch-input'" class="d-flex py-2">
76
+ {{ h['text'] }}:
77
+ <r-switch-input
78
+ :modelValue="item[h['value']]"
79
+ :readonly="h['option']['formInput']===false"
80
+ class="mt-0"
81
+ @update:modelValue="h['option']['formInput']!==false?editItem(item,true,h['value']):''"
82
+ ></r-switch-input>
83
+ </div>
84
+ <div v-else-if="h['option']['type'] === 'r-number-input'" class="py-2">
85
+ {{ h['text'] }}: {{ $n(item[h["value"]]) }}
86
+ </div>
87
+ <div v-else-if="h['option']['type']!=='action'" class="py-2">
88
+ {{ h['text'] }}: {{
89
+ h['value'] in cast ?
90
+ $helper.ifHas(item, '', h['value'], cast[h['value']])
91
+ : item[h['value']]
92
+ }}
93
+ </div>
94
+ </slot>
95
+ <div v-if="h['option']['type']==='action'" class="w-full text-end">
96
+ <r-divider class="mt-3"></r-divider>
97
+ <r-btn v-if="!disableUpdate" class="mx-0 color-success-text"
98
+ icon text @click.prevent="editItem(item)">
99
+ <r-icon exact v-html="$r.icons.edit"></r-icon>
100
+ </r-btn>
101
+ <r-btn v-if="!disableDelete" class="mx-0 color-error-text"
102
+ icon text @click.prevent="deleteItem(item)">
103
+ <r-icon v-html="$r.icons.delete"></r-icon>
104
+ </r-btn>
105
+ <r-btn v-for="(val,index) in actions" :key="index" :class="`color-${val.color}-text`" class="mx-0" icon
106
+ text @click.prevent="$emit(val.name,item)">
107
+ <r-icon exact v-html="val.icon"></r-icon>
108
+ </r-btn>
109
+ </div>
110
+ </div>
111
+ </r-card>
112
+ </div>
113
+ </div>
114
+ <r-table v-else :headers="headerTable" :items="table.data" :key-item="itemId" :responsive="responsive"
62
115
  transition="table-row">
63
116
  <template v-slot:header="{header}">
64
117
  <th v-for="(item,key) in header"
@@ -201,6 +254,7 @@ export default {
201
254
  default: true
202
255
  },
203
256
 
257
+ card: Boolean,
204
258
  disableAdd: Boolean,
205
259
  advanceSearch: {type: Boolean, default: true},
206
260
  disableDelete: Boolean,
@@ -400,7 +454,7 @@ export default {
400
454
  params.a_search = JSON.stringify(this.a_search)
401
455
  }
402
456
 
403
- this.setup('/' + this.link, params)
457
+ this.setup(this.link, params)
404
458
  },
405
459
  searching() {
406
460
  clearTimeout(this.time_out_id)
@@ -286,7 +286,9 @@ $data-table-regular-header-height: 38px !default;
286
286
 
287
287
  .manage-footer {
288
288
  .btn-page {
289
- border: solid 1px var(--color-border);
289
+ color: var(--color-on-sheet);
290
+ border: solid 1px var(--color-sheet-low);
291
+ background-color: var(--color-sheet-container);
290
292
  }
291
293
  }
292
294
 
@@ -3,7 +3,12 @@ function mounted (el, binding) {
3
3
  const options = binding.options || {
4
4
  passive: true
5
5
  }
6
- const target = binding.arg ? document.querySelector(binding.arg) : window
6
+ let target = el
7
+ if (binding.modifiers.window) {
8
+ target = window
9
+ } else if (binding.arg) {
10
+ target = document.querySelector(binding.arg)
11
+ }
7
12
  if (!target) return
8
13
  target.addEventListener('scroll', callback, options)
9
14
  el._onScroll = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "renusify",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "description": "Vue3 Framework",
5
5
  "keywords": [
6
6
  "vuejs",
@@ -155,7 +155,9 @@ export default class Translate {
155
155
  this.local = locale;
156
156
  this.setMessages({});
157
157
  }
158
+ setTimeout(() => {
158
159
  this.$r.store['langs_loaded'][pack] = true;
160
+ }, 50)
159
161
  } else {
160
162
  this.$r.store['langs_loaded'][pack] = true;
161
163
  }
package/tools/helper.js CHANGED
@@ -399,3 +399,10 @@ export function changeColor(vars) {
399
399
  css += '}'
400
400
  style.appendChild(document.createTextNode(css));
401
401
  }
402
+
403
+ export function fix_url(url) {
404
+ if (url.startsWith("/") || url.startsWith("http:") || url.startsWith("https:")) {
405
+ return url
406
+ }
407
+ return "/" + url
408
+ }