Skip to content

Commit 91911bc

Browse files
committed
Multiple bug fixing
1 parent f2916b9 commit 91911bc

File tree

16 files changed

+51
-51
lines changed

16 files changed

+51
-51
lines changed

client/components/global/ScrollShadow.vue

+11-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
ref="scrollContainer"
55
:class="[$style['scroll-container'],{'no-scrollbar':hideScrollbar}]"
66
:style="{ width: width?width:'auto', height }"
7-
@scroll.passive="toggleShadow"
7+
@scroll.passive="throttled.toggleShadow"
88
>
99
<slot />
1010
<span :class="[$style['shadow-top'], shadow.top && $style['is-active']]" :style="{
@@ -19,6 +19,7 @@
1919
</template>
2020

2121
<script>
22+
import throttle from 'lodash.throttle'
2223
function newResizeObserver (callback) {
2324
// Skip this feature for browsers which
2425
// do not support ResizeObserver.
@@ -50,28 +51,31 @@ export default {
5051
bottom: false,
5152
left: false
5253
},
53-
debounceTimeout: null,
5454
scrollContainerObserver: null,
55-
wrapObserver: null
55+
wrapObserver: null,
56+
throttled: {}
5657
}
5758
},
5859
mounted () {
59-
window.addEventListener('resize', this.calcDimensions)
60+
this.throttled.toggleShadow = throttle(this.toggleShadow, 100);
61+
this.throttled.calcDimensions = throttle(this.calcDimensions, 100);
62+
63+
window.addEventListener('resize', this.throttled.calcDimensions)
6064
6165
// Check if shadows are necessary after the element is resized.
62-
const scrollContainerObserver = newResizeObserver(this.toggleShadow)
66+
const scrollContainerObserver = newResizeObserver(this.throttled.toggleShadow)
6367
if (scrollContainerObserver) {
6468
scrollContainerObserver.observe(this.$refs.scrollContainer)
6569
}
6670
6771
// Recalculate the container dimensions when the wrapper is resized.
68-
this.wrapObserver = newResizeObserver(this.calcDimensions)
72+
this.wrapObserver = newResizeObserver(this.throttled.calcDimensions)
6973
if (this.wrapObserver) {
7074
this.wrapObserver.observe(this.$el)
7175
}
7276
},
7377
unmounted () {
74-
window.removeEventListener('resize', this.calcDimensions)
78+
window.removeEventListener('resize', this.throttled.calcDimensions)
7579
// Cleanup when the component is unmounted.
7680
this.wrapObserver.disconnect()
7781
if (this.scrollContainerObserver) {

client/components/open/forms/OpenForm.vue

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export default {
173173
*/
174174
currentFieldsPageBreak () {
175175
// Last block from current group
176+
if (!this.currentFields?.length) return null
176177
const block = this.currentFields[this.currentFields.length - 1]
177178
if (block && block.type === 'nf-page-break') return block
178179
return null

client/components/open/forms/components/FormEditor.vue

+9-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ import FormCustomSeo from './form-components/FormCustomSeo.vue'
9797
import FormAccess from './form-components/FormAccess.vue'
9898
import {validatePropertiesLogic} from "~/composables/forms/validatePropertiesLogic.js"
9999
import opnformConfig from "~/opnform.config.js";
100+
import {captureException} from "@sentry/vue";
100101
101102
export default {
102103
name: 'FormEditor',
@@ -255,9 +256,12 @@ export default {
255256
this.amplitude.logEvent('form_saved', { form_id: this.form.id, form_slug: this.form.slug })
256257
this.displayFormModificationAlert(data)
257258
}).catch((error) => {
258-
if (error.response.status === 422) {
259+
if (error?.response.status === 422) {
259260
this.validationErrorResponse = error.response.data
260261
this.showValidationErrors()
262+
} else {
263+
useAlert().error('An error occurred while saving the form, please try again.')
264+
captureException(error)
261265
}
262266
}).finally(() => {
263267
this.updateFormLoading = false
@@ -282,10 +286,12 @@ export default {
282286
this.displayFormModificationAlert(response)
283287
useRouter().push({ name: 'forms-slug-show-share', params: { slug: this.createdFormSlug, new_form: response.users_first_form } })
284288
}).catch((error) => {
285-
console.error(error)
286-
if (error.response && error.response.status === 422) {
289+
if (error?.response?.status === 422) {
287290
this.validationErrorResponse = error.response
288291
this.showValidationErrors()
292+
} else {
293+
useAlert().error('An error occurred while saving the form, please try again.')
294+
captureException(error)
289295
}
290296
}).finally(() => {
291297
this.updateFormLoading = false

client/components/open/forms/components/form-components/FormCustomization.vue

-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@
1717
]"
1818
:form="form" label="Form Theme"
1919
/>
20-
<div class="-mt-3 mb-3 text-gray-400 dark:text-gray-500">
21-
<small>
22-
Need another theme? <a href="#" @click.prevent="crisp.openAndShowChat">Send us some suggestions!</a>
23-
</small>
24-
</div>
2520

2621
<select-input name="dark_mode" class="mt-4"
2722
help="To see changes, save your form and open it"

client/components/open/forms/fields/components/FieldOptions.vue

+1
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ export default {
468468
return true
469469
},
470470
optionsText () {
471+
if (this.field[this.field.type]) return []
471472
return this.field[this.field.type].options.map(option => {
472473
return option.name
473474
}).join('\n')

client/components/open/tables/OpenTable.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
<td v-if="hasActions" class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 border-b"
5454
style="width: 100px"
5555
>
56-
<record-operations :form="form" :structure="columns" :submission="row"
57-
@deleted="(submission)=>$emit('deleted',submission)"
56+
<record-operations :form="form" :structure="columns" :submission="row"
57+
@deleted="(submission)=>$emit('deleted',submission)"
5858
@updated="(submission)=>$emit('updated', submission)"/>
5959
</td>
6060
</tr>
@@ -91,7 +91,7 @@ import {hash} from "~/lib/utils.js";
9191
9292
export default {
9393
components: {ResizableTh, RecordOperations},
94-
emits: ["updated", "deleted"],
94+
emits: ["updated", "deleted", "resize"],
9595
props: {
9696
columns: {
9797
type: Array,

client/components/pages/forms/create/CreateFormBaseModal.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ export default {
145145
this.fetchGeneratedForm(generationId)
146146
}
147147
}).catch(error => {
148-
this.useAlert.error(error.data.message)
148+
if (error?.data?.message){
149+
this.useAlert.error(error.data.message)
150+
}
149151
this.state = 'default'
150152
this.loading = false
151153
})

client/composables/useCrisp.js

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export const useCrisp = () => {
2525

2626
function openAndShowChat(message = null) {
2727
if (!crisp) return
28-
showChat()
2928
openChat()
3029
if (message) sendTextMessage(message)
3130
}

client/lib/forms/FormLogicConditionChecker.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function checkContains (condition, fieldValue) {
6565

6666
function checkListContains (condition, fieldValue) {
6767
if (!fieldValue) return false
68-
68+
6969
if (Array.isArray(condition.value)) {
7070
return condition.value.every(r => fieldValue.includes(r))
7171
} else {
@@ -74,11 +74,11 @@ function checkListContains (condition, fieldValue) {
7474
}
7575

7676
function checkStartsWith (condition, fieldValue) {
77-
return fieldValue.startsWith(condition.value)
77+
return fieldValue?.startsWith(condition.value)
7878
}
7979

8080
function checkendsWith (condition, fieldValue) {
81-
return fieldValue && fieldValue.endsWith(condition.value)
81+
return fieldValue?.endsWith(condition.value)
8282
}
8383

8484
function checkIsEmpty (condition, fieldValue) {

client/package-lock.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"fuse.js": "^6.4.6",
4444
"js-sha256": "^0.10.0",
4545
"libphonenumber-js": "^1.10.44",
46+
"lodash.throttle": "^4.1.1",
4647
"nuxt3-notifications": "^1.1.9",
4748
"object-to-formdata": "^4.5.1",
4849
"pinia": "^2.1.7",

client/pages/forms/[slug]/edit.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ const error = ref(null)
3333
const formInitialHash = ref(null)
3434
3535
function isDirty() {
36-
return formInitialHash.value && updatedForm.value && formInitialHash.value !== hash(JSON.stringify(updatedForm.value.data() ?? null))
36+
return formInitialHash.value &&
37+
updatedForm.value &&
38+
formInitialHash.value !== hash(JSON.stringify(updatedForm?.value?.data() ?? null))
3739
}
3840
3941
function initUpdatedForm() {

client/pages/settings.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@
7171
}
7272
]
7373
74-
if (user.value.is_subscribed) {
74+
if (user?.value?.is_subscribed) {
7575
tabs.splice(1, 0, {
7676
name: 'Billing',
7777
route: 'settings-billing'
7878
})
7979
}
8080
81-
if (user.value.admin) {
81+
if (user?.value?.admin) {
8282
tabs.push({
8383
name: 'Admin',
8484
route: 'settings-admin'

client/plugins/sentry.js

-14
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
import * as Sentry from "@sentry/vue";
22

3-
async function lazyLoadSentryIntegrations() {
4-
// don't load on server
5-
if (!process.client) return;
6-
7-
const {Replay} = await import("@sentry/vue");
8-
Sentry.addIntegration(new Replay({
9-
maskAllText: false,
10-
blockAllMedia: false,
11-
}));
12-
}
13-
143
function getSentryIntegrations() {
154
// don't load on server
165
if (!process.client) return [];
@@ -65,8 +54,5 @@ export default defineNuxtPlugin({
6554
return event;
6655
},
6756
})
68-
69-
// Lazy-load the replay integration to reduce bundle size
70-
lazyLoadSentryIntegrations()
7157
}
7258
});

client/stores/auth.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {defineStore} from 'pinia'
2+
import {setUser as sentrySetUser} from "@sentry/vue";
23

34
export const useAuthStore = defineStore('auth', {
45
state: () => {
@@ -65,18 +66,16 @@ export const useAuthStore = defineStore('auth', {
6566
useCrisp().setUser(this.user)
6667

6768
// Init sentry
68-
// console.log(process)
69-
// $sentry.configureScope((scope) => {
70-
// scope.setUser({
71-
// id: this.user.id,
72-
// email: this.user.email,
73-
// subscription: this.user?.is_subscribed
74-
// })
75-
// })
69+
sentrySetUser({
70+
id: this.user.id,
71+
email: this.user.email,
72+
subscription: this.user?.is_subscribed
73+
})
7674
},
7775

7876
logout() {
79-
opnFetch('logout', {method: 'POST'}).catch((error) => {})
77+
opnFetch('logout', {method: 'POST'}).catch((error) => {
78+
})
8079

8180
this.user = null
8281
this.setToken(null)

client/stores/working_form.js

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { defineStore } from 'pinia'
22

3-
4-
53
export const useWorkingFormStore = defineStore('working_form', {
64
state: () => ({
75
content: null,

0 commit comments

Comments
 (0)