@myissue/vue-website-page-builder 3.1.13 → 3.1.15

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 (43) hide show
  1. package/dist/vue-website-page-builder.css +1 -1
  2. package/dist/vue-website-page-builder.js +5161 -5194
  3. package/dist/vue-website-page-builder.umd.cjs +38 -38
  4. package/package.json +1 -1
  5. package/src/App.vue +2 -2
  6. package/src/Components/Homepage/HomeSection.vue +18 -7
  7. package/src/Components/Modals/{DynamicModal.vue → DynamicModalBuilder.vue} +38 -31
  8. package/src/Components/Modals/MediaLibraryModal.vue +1 -1
  9. package/src/Components/Modals/{Modal.vue → ModalBuilder.vue} +9 -15
  10. package/src/Components/Modals/PageBuilderPreviewModal.vue +13 -6
  11. package/src/Components/PageBuilder/DemoContent/NoneCustomSearchComponent.vue +0 -17
  12. package/src/Components/PageBuilder/DropdownsPlusToggles/OptionsDropdown.vue +113 -87
  13. package/src/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue +2 -2
  14. package/src/Components/PageBuilder/EditorMenu/Editables/BorderRadius.vue +2 -2
  15. package/src/Components/PageBuilder/EditorMenu/Editables/Borders.vue +3 -3
  16. package/src/Components/PageBuilder/EditorMenu/Editables/ClassEditor.vue +1 -1
  17. package/src/Components/PageBuilder/EditorMenu/Editables/ComponentTopMenu.vue +13 -13
  18. package/src/Components/PageBuilder/EditorMenu/Editables/DeleteElement.vue +1 -1
  19. package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +25 -25
  20. package/src/Components/PageBuilder/EditorMenu/Editables/ElementEditor.vue +2 -2
  21. package/src/Components/PageBuilder/EditorMenu/Editables/ImageEditor.vue +3 -3
  22. package/src/Components/PageBuilder/EditorMenu/Editables/LinkEditor.vue +1 -1
  23. package/src/Components/PageBuilder/EditorMenu/Editables/ManageBackgroundOpacity.vue +2 -2
  24. package/src/Components/PageBuilder/EditorMenu/Editables/ManageOpacity.vue +2 -2
  25. package/src/Components/PageBuilder/EditorMenu/Editables/OpacityEditor.vue +3 -3
  26. package/src/Components/PageBuilder/EditorMenu/Editables/PaddingPlusMargin.vue +2 -2
  27. package/src/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue +2 -2
  28. package/src/Components/PageBuilder/EditorMenu/Editables/Typography.vue +3 -3
  29. package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +13 -13
  30. package/src/Components/PageBuilder/Settings/AdvancedPageBuilderSettings.vue +9 -1
  31. package/src/Components/PageBuilder/Settings/PageBuilderSettings.vue +306 -15
  32. package/src/Components/Search/SearchComponents.vue +14 -8
  33. package/src/Components/TipTap/TipTap.vue +1 -1
  34. package/src/Components/TipTap/TipTapInput.vue +15 -17
  35. package/src/PageBuilder/PageBuilder.vue +37 -131
  36. package/src/composables/PageBuilderClass.ts +90 -80
  37. package/src/stores/page-builder-state.ts +9 -192
  38. package/src/types/index.ts +13 -10
  39. package/src/utils/builder/html-doc-declaration-with-components.ts +1 -1
  40. package/src/utils/html-elements/componentHelpers.ts +3 -3
  41. package/src/composables/isObject.ts +0 -6
  42. package/src/composables/usePromise.ts +0 -10
  43. package/src/composables/vueFetch.ts +0 -278
@@ -1,35 +1,14 @@
1
1
  import { defineStore } from 'pinia'
2
2
  import { nextTick } from 'vue'
3
- import { vueFetch } from '@/composables/vueFetch'
4
3
  import type {
5
4
  ComponentObject,
6
- FetchedComponentsResponse,
7
5
  SetPushComponentsPayload,
8
- LoadComponentsData,
9
6
  ImageObject,
10
- UserSettings,
11
- User,
12
- } from '@/types'
13
-
14
- // Media Library interfaces
15
- interface UnsplashImagesData {
16
- fetchedMedia: unknown
17
- isError: boolean | null
18
- error: unknown
19
- errors: unknown
20
- isLoading: boolean | null
21
- isSuccess: boolean | null
22
- }
23
-
24
- interface LoadUnsplashImagesPayload {
25
- orientation?: string
26
- currentPage: number
27
- searchTerm?: string
28
- }
7
+ PageBuilderConfig,
8
+ } from '../types'
29
9
 
30
10
  interface PageBuilderState {
31
11
  // Core Page Builder State
32
- pageBuilderLogo: string | null
33
12
  componentArrayAddMethod: string | null
34
13
  localStorageItemName: string | null
35
14
  showModalTipTap: boolean
@@ -73,9 +52,7 @@ interface PageBuilderState {
73
52
  component: ComponentObject | null
74
53
  components: ComponentObject[]
75
54
  basePrimaryImage: string | null
76
- fetchedComponents: FetchedComponentsResponse | null
77
- currentResourceData: { title: string; id: number } | null
78
- updateOrCreate: string
55
+ configPageBuilder: PageBuilderConfig | null
79
56
 
80
57
  // Media Library State
81
58
  currentImage: ImageObject
@@ -83,40 +60,11 @@ interface PageBuilderState {
83
60
 
84
61
  // User State
85
62
  isLoading: boolean
86
- userSettings: UserSettings | null
87
- currentUser: User | null
88
-
89
- // Unsplash State
90
- unsplashImages: UnsplashImagesData | null
91
- searchTerm: string
92
- currentPageNumber: number
93
- orientationValue: string | null
94
63
  }
95
64
 
96
- // get components
97
- const {
98
- handleData: handlefetchComponents,
99
- fetchedData: fetchedComponents,
100
- isLoading,
101
- isError,
102
- error,
103
- } = vueFetch()
104
-
105
- // get unsplash images
106
- const {
107
- handleData: handleGetImages,
108
- fetchedData: fetchedMedia,
109
- isError: isErrorImages,
110
- error: errorImages,
111
- errors: errorsImages,
112
- isLoading: isLoadingImages,
113
- isSuccess: isSuccessImages,
114
- } = vueFetch()
115
-
116
65
  export const usePageBuilderStateStore = defineStore('pageBuilderState', {
117
66
  state: (): PageBuilderState => ({
118
67
  // Core Page Builder State
119
- pageBuilderLogo: null,
120
68
  componentArrayAddMethod: null,
121
69
  localStorageItemName: null,
122
70
  showModalTipTap: false,
@@ -160,9 +108,7 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
160
108
  component: null,
161
109
  components: [],
162
110
  basePrimaryImage: null,
163
- fetchedComponents: null,
164
- currentResourceData: null,
165
- updateOrCreate: '',
111
+ configPageBuilder: null,
166
112
 
167
113
  // Media Library State
168
114
  currentImage: { src: '' },
@@ -170,20 +116,9 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
170
116
 
171
117
  // User State
172
118
  isLoading: false,
173
- userSettings: null,
174
- currentUser: null,
175
-
176
- // Unsplash State
177
- unsplashImages: null,
178
- searchTerm: '',
179
- currentPageNumber: 1,
180
- orientationValue: null,
181
119
  }),
182
120
  getters: {
183
121
  // Core Page Builder Getters
184
- getPageBuilderLogo(state: PageBuilderState): string | null {
185
- return state.pageBuilderLogo
186
- },
187
122
  getComponentArrayAddMethod(state: PageBuilderState): string | null {
188
123
  return state.componentArrayAddMethod
189
124
  },
@@ -313,27 +248,9 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
313
248
  getBasePrimaryImage(state: PageBuilderState): string | null {
314
249
  return state.basePrimaryImage
315
250
  },
316
- getFetchedComponents(): {
317
- isLoading: boolean
318
- isError: boolean
319
- error: string | null
320
- fetchedData: unknown
321
- } {
322
- return {
323
- isLoading: isLoading.value,
324
- isError: isError.value,
325
- error: error.value,
326
- fetchedData: fetchedComponents.value,
327
- }
328
- },
329
- getFetchedComponentsData(state: PageBuilderState): FetchedComponentsResponse | null {
330
- return state.fetchedComponents
331
- },
332
- getCurrentResourceData(state: PageBuilderState): { title: string; id: number } | null {
333
- return state.currentResourceData
334
- },
335
- getUpdateOrCreate(state: PageBuilderState): string {
336
- return state.updateOrCreate
251
+
252
+ getConfigPageBuilder(state: PageBuilderState): PageBuilderConfig | null {
253
+ return state.configPageBuilder
337
254
  },
338
255
 
339
256
  // Media Library Getters
@@ -346,22 +263,8 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
346
263
 
347
264
  // User Getters
348
265
  getIsLoading: (state: PageBuilderState): boolean => state.isLoading,
349
- getUserSettings: (state: PageBuilderState): UserSettings | null => state.userSettings,
350
- getCurrentUser: (state: PageBuilderState): User | null => state.currentUser,
351
-
352
- // Unsplash Getters
353
- getUnsplashImages: (state: PageBuilderState): UnsplashImagesData | null => {
354
- return state.unsplashImages
355
- },
356
- getSearchTerm: (state: PageBuilderState): string => state.searchTerm,
357
- getCurrentPageNumber: (state: PageBuilderState): number => state.currentPageNumber,
358
- getOrientationValue: (state: PageBuilderState): string | null => state.orientationValue,
359
266
  },
360
267
  actions: {
361
- // Core Page Builder Actions
362
- setPageBuilderLogo(payload: string | null): void {
363
- this.pageBuilderLogo = payload
364
- },
365
268
  setComponentArrayAddMethod(payload: string | null): void {
366
269
  this.componentArrayAddMethod = payload
367
270
  },
@@ -531,34 +434,9 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
531
434
  setCurrentLayoutPreview(payload: string): void {
532
435
  localStorage.setItem('preview', payload)
533
436
  },
534
- setFetchedComponents(payload: FetchedComponentsResponse | null): void {
535
- this.fetchedComponents = payload
536
- },
537
-
538
- async setLoadComponents(_data: LoadComponentsData): Promise<void> {
539
- this.setFetchedComponents(null)
540
437
 
541
- try {
542
- await handlefetchComponents('/components.json', {}, { additionalCallTime: 500 })
543
- } catch (err) {
544
- console.log(`Error: ${err}`)
545
- }
546
-
547
- // fetchedComponents.value is an object containing a components property
548
- this.setFetchedComponents(
549
- fetchedComponents &&
550
- fetchedComponents.value &&
551
- typeof fetchedComponents.value === 'object' &&
552
- 'components' in fetchedComponents.value
553
- ? (fetchedComponents.value as FetchedComponentsResponse)
554
- : null,
555
- )
556
- },
557
- setCurrentResourceData(payload: { title: string; id: number } | null): void {
558
- this.currentResourceData = payload
559
- },
560
- setUpdateOrCreate(payload: string): void {
561
- this.updateOrCreate = payload
438
+ setConfigPageBuilder(payload: PageBuilderConfig | null): void {
439
+ this.configPageBuilder = payload
562
440
  },
563
441
 
564
442
  // Media Library Actions
@@ -573,66 +451,5 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
573
451
  setIsLoading(payload: boolean): void {
574
452
  this.isLoading = payload
575
453
  },
576
- setUserSettings(payload: UserSettings | null): void {
577
- this.userSettings = payload
578
- },
579
- setCurrentUser(payload: User | null): void {
580
- this.currentUser = payload
581
- },
582
-
583
- // Unsplash Actions
584
- setUnsplashImages(payload: UnsplashImagesData | null): void {
585
- this.unsplashImages = payload
586
- },
587
- setSearchTerm(payload: string): void {
588
- this.searchTerm = payload
589
- },
590
- setCurrentPageNumber(payload: number): void {
591
- this.currentPageNumber = payload
592
- },
593
- setOrientationValue(payload: string | null): void {
594
- this.orientationValue = payload
595
- },
596
-
597
- // Load Unsplash images
598
- async setLoadUnsplashImages(payload: LoadUnsplashImagesPayload): Promise<void> {
599
- this.setUnsplashImages({
600
- fetchedMedia: null,
601
- isError: null,
602
- error: null,
603
- errors: null,
604
- isLoading: true,
605
- isSuccess: null,
606
- })
607
-
608
- const orientationType = payload.orientation ? `&orientation=${payload.orientation}` : ''
609
-
610
- const unsplashKey = import.meta.env.VITE_UNSPLASH_KEY as string
611
-
612
- try {
613
- await handleGetImages(
614
- `https://api.unsplash.com/search/photos?page=${payload.currentPage}&per_page=24&query=${payload.searchTerm || 'a'}${orientationType}`,
615
- {
616
- headers: {
617
- 'Accept-Version': 'v1',
618
- Authorization: unsplashKey,
619
- },
620
- },
621
- { additionalCallTime: 500 },
622
- )
623
- } catch (err) {
624
- console.log(`Error: ${err}`)
625
- }
626
-
627
- // Update state directly instead of committing mutations
628
- this.setUnsplashImages({
629
- fetchedMedia: fetchedMedia.value,
630
- isError: isErrorImages.value,
631
- error: errorImages.value,
632
- errors: errorsImages.value,
633
- isLoading: isLoadingImages.value,
634
- isSuccess: isSuccessImages.value,
635
- })
636
- },
637
454
  },
638
455
  })
@@ -27,8 +27,6 @@ export interface PageBuilderStateStore {
27
27
  getFontDesktop: string | null
28
28
  getFontTablet: string | null
29
29
  getFontMobile: string | null
30
- getUpdateOrCreate: string
31
- getCurrentResourceData: { title: string; id: number } | null
32
30
  setElement: (element: HTMLElement | null) => void
33
31
  setMenuRight: (value: boolean) => void
34
32
  setComponent: (component: ComponentObject | null) => void
@@ -57,7 +55,6 @@ export interface PageBuilderStateStore {
57
55
  setPushComponents: (payload: SetPushComponentsPayload) => void
58
56
  setLocalStorageItemName: (name: string | null) => void
59
57
  setUpdateOrCreate: (mode: string) => void
60
- setCurrentResourceData: (data: { title: string; id: number } | null) => void
61
58
  setFontWeight: (weight: string) => void
62
59
  setFontFamily: (family: string) => void
63
60
  setFontStyle: (style: string) => void
@@ -94,15 +91,21 @@ export interface PageBuilderUser {
94
91
  name: string
95
92
  }
96
93
 
97
- // User settings interface
98
- export interface UserSettings {
99
- theme: 'light' | 'dark' | 'auto'
100
- language: string
101
- notifications?: boolean
102
- autoSave: boolean
94
+ // Page Builder Configuration interface
95
+ export interface PageBuilderConfig {
96
+ updateOrCreate?: 'create' | 'update'
97
+ pageBuilderLogo?: string
98
+ resourceData?: { title: string; id: number } | null
99
+ userForPageBuilder?: { name: string } | null
103
100
  [key: string]: unknown
101
+ userSettings: {
102
+ theme: 'light' | 'dark' | 'auto'
103
+ language: string
104
+ notifications?: boolean
105
+ autoSave: boolean
106
+ [key: string]: unknown
107
+ }
104
108
  }
105
-
106
109
  // Tailwind utility interfaces
107
110
  export interface TailwindColors {
108
111
  backgroundColorVariables: string[]
@@ -1,4 +1,4 @@
1
- import tailwindCSS from '@/css/app.css?inline'
1
+ import tailwindCSS from '../../css/app.css?inline'
2
2
 
3
3
  const fullHTMLContent = function (HTML: string): string {
4
4
  return `<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>${tailwindCSS}</style></head><body>${HTML}</body></html>`
@@ -16,7 +16,7 @@ const componentHelpers: ComponentHelper[] = [
16
16
  Turpis tincidunt id aliquet risus feugiat in ante. Tincidunt dui ut ornare lectus sit. Ipsum dolor sit amet consectetur. Viverra ipsum nunc aliquet bibendum enim facilisis gravida neque convallis.<br><br>Dignissim sodales ut eu sem integer vitae justo eget magna.
17
17
  Ac turpis egestas maecenas pharetra convallis. Mauris sit amet massa vitae. Ut tellus elementum sagittis vitae et. Sed risus ultricies tristique nulla aliquet enim tortor. Nunc mattis enim ut tellus elementum sagittis vitae et leo. Quis vel eros donec ac odio tempor.
18
18
  Faucibus scelerisque eleifend donec pretium. <br><br>Adipiscing bibendum est ultricies integer quis auctor elit. Vestibulum morbi blandit cursus risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget. Gravida dictum fusce ut placerat orci nulla.
19
- Consequat mauris nunc congue nisi vitae suscipit tellus mauris. <br><br></p><p><strong>List</strong></p><ul><li><p>Integer enim neque volutpat ac tincidunt vitae semper quis. Sit amet consectetur adipiscing elit pellentesque.</p></li><li><p>Urna cursus eget nunc scelerisque viverra.
19
+ Sunt in culpa qui officia deserunt nisi vitae suscipit tellus mauris. <br><br></p><p><strong>List</strong></p><ul><li><p>Integer enim neque volutpat ac tincidunt vitae semper quis. Sit amet consectetur adipiscing elit pellentesque.</p></li><li><p>Urna cursus eget nunc scelerisque viverra.
20
20
  Cursus metus aliquam eleifend mi in nulla posuere. Lobortis elementum nibh tellus molestie nunc non blandit massa.</p></li><li><p>Sodales ut eu sem integer vitae justo eget magna. Scelerisque felis imperdiet proin fermentum leo vel orci. Nunc id cursus metus aliquam eleifend.</p></li></ul>
21
21
  </div>
22
22
  </div>
@@ -31,7 +31,7 @@ const componentHelpers: ComponentHelper[] = [
31
31
  `,
32
32
  },
33
33
  {
34
- html_code: `<section><div class="relative py-4"><div class="mx-auto max-w-7xl lg:px-4 px-2"><div class="break-words"><h2>Consequat mauris nunc congue</h2></div></div></div></section>`,
34
+ html_code: `<section><div class="relative py-4"><div class="mx-auto max-w-7xl lg:px-4 px-2"><div class="break-words"><h2>Sunt in culpa qui officia deserunt</h2></div></div></div></section>`,
35
35
  id: null,
36
36
  title: 'Header H2',
37
37
  icon: `
@@ -41,7 +41,7 @@ const componentHelpers: ComponentHelper[] = [
41
41
  `,
42
42
  },
43
43
  {
44
- html_code: `<section><div class="relative py-4"><div class="mx-auto max-w-7xl lg:px-4 px-2"><div class="break-words"><h3>Consequat mauris nunc congue</h3></div></div></div></section>`,
44
+ html_code: `<section><div class="relative py-4"><div class="mx-auto max-w-7xl lg:px-4 px-2"><div class="break-words"><h3>Sunt in culpa qui officia deserunt</h3></div></div></div></section>`,
45
45
  id: null,
46
46
  title: 'Header H3',
47
47
  icon: `
@@ -1,6 +0,0 @@
1
- export const isObject = function (data: unknown): data is Record<string, unknown> {
2
- if (typeof data === 'object' && !Array.isArray(data) && data !== null) {
3
- return true
4
- }
5
- return false
6
- }
@@ -1,10 +0,0 @@
1
- export const usePromise = function (time: number): Promise<() => void> {
2
- // new promise
3
- return new Promise((resolve) => {
4
- return setTimeout(() => {
5
- resolve(() => {
6
- return
7
- })
8
- }, time)
9
- })
10
- }
@@ -1,278 +0,0 @@
1
- import { ref } from 'vue'
2
- import type { Ref } from 'vue'
3
- import { usePromise } from '@/composables/usePromise'
4
- import { isObject } from '@/composables/isObject'
5
-
6
- // Type definitions
7
- interface CustomFetchOptions {
8
- abortTimeoutTime?: number
9
- additionalCallTime?: number
10
- }
11
-
12
- interface VueFetchReturn {
13
- isSuccess: Ref<boolean>
14
- isLoading: Ref<boolean>
15
- isError: Ref<boolean>
16
- error: Ref<string | null>
17
- errors: Ref<unknown>
18
- handleData: (
19
- url: string,
20
- fetchOptions?: RequestInit,
21
- customFetchOptions?: CustomFetchOptions,
22
- ) => Promise<unknown>
23
- fetchedData: Ref<unknown>
24
- }
25
-
26
- export const vueFetch = function vueFetch(): VueFetchReturn {
27
- // Initializing state management references
28
- const isSuccess: Ref<boolean> = ref(false)
29
- const isLoading: Ref<boolean> = ref(false)
30
- const isError: Ref<boolean> = ref(false)
31
- const error: Ref<string | null> = ref(null)
32
- const errors: Ref<unknown> = ref(null)
33
- const goDirectToError: Ref<boolean> = ref(false)
34
- const fetchedData: Ref<unknown> = ref(null)
35
- const streamAlreadyRead: Ref<boolean | null> = ref(null)
36
- const response: Ref<Response | null> = ref(null)
37
-
38
- const additionalTime: Ref<number | null> = ref(null)
39
- const abortTimeout: Ref<number | null> = ref(null)
40
-
41
- // Function to handle data fetching and state updates
42
- const handleData = async function (
43
- url: string,
44
- fetchOptions: RequestInit = {},
45
- customFetchOptions: CustomFetchOptions = {},
46
- ): Promise<unknown> {
47
- isSuccess.value = false
48
- isLoading.value = false
49
- isError.value = false
50
- error.value = null
51
- errors.value = null
52
- goDirectToError.value = false
53
- fetchedData.value = null
54
- streamAlreadyRead.value = null
55
- response.value = null
56
-
57
- // Initialize or set timeout and additional time values
58
- abortTimeout.value = customFetchOptions.abortTimeoutTime ?? 4000
59
- additionalTime.value = customFetchOptions.additionalCallTime ?? 0
60
-
61
- // Initializing fetch operation control parameters
62
- const controller = new AbortController()
63
-
64
- // Abort fetch operation after the specified timeout
65
- const timer = setTimeout(() => {
66
- controller.abort()
67
- }, abortTimeout.value)
68
-
69
- try {
70
- // Begin fetch operation
71
- isLoading.value = true
72
- const promise = usePromise(additionalTime.value)
73
- await promise
74
-
75
- // Check for abort signal and handle accordingly
76
- if (controller.signal.aborted) {
77
- clearTimeout(timer)
78
- isLoading.value = false
79
- isError.value = false
80
- goDirectToError.value = true
81
-
82
- throw new Error('Error 500. Loading time exceeded.')
83
- }
84
-
85
- // Fetch and handle response
86
- response.value = await fetch(url, {
87
- ...fetchOptions,
88
- signal: controller.signal,
89
- })
90
-
91
- // Check if the fetch request was successful. If not, throw an error
92
- if (response.value.status !== 200 && response.value.status !== 201) {
93
- throw new Error(`${response.value.status}. ${response.value.statusText}`)
94
- }
95
-
96
- // Parse JSON response when content-type is 'application/json'
97
- const contentType = response.value.headers.get('content-type') || ''
98
-
99
- // Content-Type 'application/json'
100
- if (contentType.includes('application/json')) {
101
- streamAlreadyRead.value = true
102
- clearTimeout(timer)
103
- isSuccess.value = true
104
- isLoading.value = false
105
- isError.value = false
106
-
107
- fetchedData.value = await response.value.json()
108
- return fetchedData.value
109
- }
110
-
111
- // Content-Type 'text/plain' or 'text/html'
112
- if (contentType.includes('text/plain') || contentType.includes('text/html')) {
113
- streamAlreadyRead.value = true
114
- clearTimeout(timer)
115
- isSuccess.value = true
116
- isLoading.value = false
117
- isError.value = false
118
-
119
- fetchedData.value = await response.value.text()
120
- return fetchedData.value
121
- }
122
-
123
- // Handle non-GET requests without 'application/json', 'text/plain' or 'text/html'
124
- if (
125
- fetchOptions?.method !== 'GET' &&
126
- fetchOptions?.method !== 'get' &&
127
- fetchOptions?.method !== undefined
128
- ) {
129
- clearTimeout(timer)
130
- isSuccess.value = true
131
- isLoading.value = false
132
- isError.value = false
133
- fetchedData.value = 'Your request was processed successfully.'
134
- return 'Your request was processed successfully.'
135
- }
136
-
137
- // Handle GET requests without 'application/json' content-type
138
- clearTimeout(timer)
139
- isSuccess.value = true
140
- isLoading.value = false
141
- isError.value = false
142
- goDirectToError.value = true
143
- throw new Error(
144
- "Error 500. The request header must contain 'application/json', 'text/plain' or 'text/html'",
145
- )
146
- } catch (err: unknown) {
147
- clearTimeout(timer)
148
- isSuccess.value = false
149
- isLoading.value = false
150
-
151
- // Set default error message
152
- isError.value = true
153
- const errorMessage = err instanceof Error ? err.message : String(err)
154
- error.value = `Not able to fetch data. Error status: ${errorMessage}.`
155
-
156
- if (response.value) {
157
- // Get content type of the response
158
- const contentType = response.value.headers.get('content-type') || ''
159
-
160
- if (contentType.includes('application/json') && !streamAlreadyRead.value) {
161
- // Handle errors when content type is 'application/json'
162
- if (goDirectToError.value !== true) {
163
- try {
164
- // Parse the response body as JSON
165
- const collectingErrorsJson = await response.value.json()
166
-
167
- // Collect backend form validation errors
168
- errors.value = collectingErrorsJson
169
-
170
- // Handle different types of error messages
171
-
172
- // If the error message is a string, handle it accordingly
173
- if (typeof collectingErrorsJson === 'string') {
174
- // Set error message when error body is a string
175
- isError.value = true
176
- error.value = `Not able to fetch data. Error status: ${errorMessage}. ${collectingErrorsJson}`
177
- }
178
- // If the error message is an array, handle it accordingly
179
- else if (Array.isArray(collectingErrorsJson)) {
180
- // Set error message when error body is an array
181
- isError.value = true
182
- error.value = `Not able to fetch data. Error status: ${errorMessage}. ${collectingErrorsJson.join(' ')}`
183
- }
184
- // If the error message is an object, handle it accordingly
185
- else if (isObject(collectingErrorsJson)) {
186
- const errorsKeys = Object.keys(collectingErrorsJson)
187
- const errorsValues = Object.values(collectingErrorsJson)
188
-
189
- // If there are no errors, handle it accordingly
190
- if (errorsKeys.length === 0) {
191
- // Set error message when error body is an empty object
192
- isError.value = true
193
- error.value = `Not able to fetch data. Error status: ${response.value.status}.`
194
- }
195
-
196
- // If there are errors, handle them accordingly
197
- if (errorsKeys.length > 0) {
198
- for (let i = 0; i < errorsKeys.length; i++) {
199
- if (Array.isArray(errorsValues[i]) || isObject(errorsValues[i])) {
200
- // Set error message when encountering a nested object or array
201
- isError.value = true
202
- error.value = `Not able to fetch data. Error status: ${errorMessage}`
203
- break
204
- }
205
-
206
- // If the error is neither an array nor an object, handle it accordingly
207
- if (!Array.isArray(errorsValues[i]) && !isObject(errorsValues[i])) {
208
- const errorObjToString = Object.values(collectingErrorsJson).join(' ')
209
- // Set error message when error body is a flat object
210
- isError.value = true
211
- error.value = `Not able to fetch data. Error status: ${errorMessage}. ${errorObjToString}`
212
- }
213
- }
214
- }
215
- }
216
- } catch {
217
- // Handle JSON parsing error
218
- error.value = `Not able to fetch data. Error status: ${errorMessage}`
219
- }
220
- }
221
- }
222
-
223
- // If the response's Content-Type text/plain, handle it accordingly
224
- if (contentType.includes('text/plain') && !streamAlreadyRead.value) {
225
- try {
226
- const plainText = await response.value.text()
227
- // Remove HTML tags using a regular expression
228
- const cleanedText = plainText.replace(/<\/?[^>]+(>|$)/g, '')
229
- error.value = `Error: ${cleanedText}`
230
- } catch {
231
- // Handle text parsing error
232
- error.value = `Not able to fetch data. Error status: ${errorMessage}`
233
- }
234
- }
235
-
236
- // If the response's Content-Type text/html, handle it accordingly
237
- if (contentType.includes('text/html') && !streamAlreadyRead.value) {
238
- try {
239
- const htmlContent = await response.value.text()
240
- // Remove HTML tags using a regular expression
241
- const cleanedText = htmlContent.replace(/<\/?[^>]+(>|$)/g, '')
242
- error.value = `Error: ${cleanedText}`
243
- } catch {
244
- // Handle HTML parsing error
245
- error.value = `Not able to fetch data. Error status: ${errorMessage}`
246
- }
247
- }
248
-
249
- if (
250
- (!contentType.includes('application/json') &&
251
- !contentType.includes('text/plain') &&
252
- !contentType.includes('text/html')) ||
253
- goDirectToError.value
254
- ) {
255
- isError.value = true
256
- error.value = `Not able to fetch data. Error status: ${errorMessage}`
257
- }
258
-
259
- // Rethrow the error for further handling
260
- throw err
261
- }
262
-
263
- // Rethrow the error if no response
264
- throw err
265
- }
266
- }
267
-
268
- // Return the state variables and the fetch function
269
- return {
270
- isSuccess,
271
- isLoading,
272
- isError,
273
- error,
274
- errors,
275
- handleData,
276
- fetchedData,
277
- }
278
- }