@edgedev/create-edge-app 1.1.25 → 1.1.26
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.
- package/README.md +55 -20
- package/{agent.md → agents.md} +2 -0
- package/bin/cli.js +6 -6
- package/edge/components/auth/login.vue +384 -0
- package/edge/components/auth/register.vue +396 -0
- package/edge/components/auth.vue +108 -0
- package/edge/components/autoFileUpload.vue +215 -0
- package/edge/components/billing.vue +8 -0
- package/edge/components/buttonDivider.vue +14 -0
- package/edge/components/chip.vue +34 -0
- package/edge/components/clipboardButton.vue +42 -0
- package/edge/components/cms/block.vue +529 -0
- package/edge/components/cms/blockApi.vue +212 -0
- package/edge/components/cms/blockEditor.vue +725 -0
- package/edge/components/cms/blockInput.vue +66 -0
- package/edge/components/cms/blockPicker.vue +486 -0
- package/edge/components/cms/blockRender.vue +78 -0
- package/edge/components/cms/blockSheetContent.vue +28 -0
- package/edge/components/cms/codeEditor.vue +466 -0
- package/edge/components/cms/fontUpload.vue +327 -0
- package/edge/components/cms/htmlContent.vue +807 -0
- package/edge/components/cms/init_blocks/api_with_subarrays.html +17 -0
- package/edge/components/cms/init_blocks/array_with_collection.html +7 -0
- package/edge/components/cms/init_blocks/array_with_objects.html +7 -0
- package/edge/components/cms/init_blocks/carousel.html +103 -0
- package/edge/components/cms/init_blocks/contact_us.html +69 -0
- package/edge/components/cms/init_blocks/content_with_left_image.html +27 -0
- package/edge/components/cms/init_blocks/footer.html +24 -0
- package/edge/components/cms/init_blocks/header_divider.html +7 -0
- package/edge/components/cms/init_blocks/hero.html +35 -0
- package/edge/components/cms/init_blocks/hero_carousel.html +52 -0
- package/edge/components/cms/init_blocks/newsletter.html +117 -0
- package/edge/components/cms/init_blocks/post_content.html +7 -0
- package/edge/components/cms/init_blocks/post_title_header.html +21 -0
- package/edge/components/cms/init_blocks/posts_list.html +20 -0
- package/edge/components/cms/init_blocks/properties_showcase.html +100 -0
- package/edge/components/cms/init_blocks/property_carousel.html +59 -0
- package/edge/components/cms/init_blocks/property_detail.html +112 -0
- package/edge/components/cms/init_blocks/property_detail_header.html +34 -0
- package/edge/components/cms/init_blocks/property_results.html +137 -0
- package/edge/components/cms/init_blocks/property_search.html +75 -0
- package/edge/components/cms/init_blocks/simple_array.html +7 -0
- package/edge/components/cms/mediaCard.vue +116 -0
- package/edge/components/cms/mediaManager.vue +386 -0
- package/edge/components/cms/menu.vue +1103 -0
- package/edge/components/cms/optionsSelect.vue +107 -0
- package/edge/components/cms/page.vue +1785 -0
- package/edge/components/cms/posts.vue +1083 -0
- package/edge/components/cms/site.vue +1298 -0
- package/edge/components/cms/themeDefaultMenu.vue +548 -0
- package/edge/components/cms/themeEditor.vue +426 -0
- package/edge/components/dashboard.vue +776 -0
- package/edge/components/editor.vue +671 -0
- package/edge/components/fileTree.vue +72 -0
- package/edge/components/files.vue +89 -0
- package/edge/components/formSubtypes/myOrgs.vue +214 -0
- package/edge/components/formSubtypes/users.vue +336 -0
- package/edge/components/functionChips.vue +57 -0
- package/edge/components/gError.vue +98 -0
- package/edge/components/gHelper.vue +67 -0
- package/edge/components/gInput.vue +1331 -0
- package/edge/components/loggingIn.vue +41 -0
- package/edge/components/menu.vue +137 -0
- package/edge/components/menuContent.vue +132 -0
- package/edge/components/myAccount.vue +317 -0
- package/edge/components/myOrganizations.vue +75 -0
- package/edge/components/myProfile.vue +122 -0
- package/edge/components/orgSwitcher.vue +25 -0
- package/edge/components/organizationMembers.vue +522 -0
- package/edge/components/organizationSettings.vue +271 -0
- package/edge/components/shad/breadcrumbs.vue +35 -0
- package/edge/components/shad/button.vue +43 -0
- package/edge/components/shad/checkbox.vue +73 -0
- package/edge/components/shad/combobox.vue +238 -0
- package/edge/components/shad/datepicker.vue +184 -0
- package/edge/components/shad/dialog.vue +32 -0
- package/edge/components/shad/dropdownMenu.vue +54 -0
- package/edge/components/shad/dropdownMenuItem.vue +21 -0
- package/edge/components/shad/form.vue +59 -0
- package/edge/components/shad/html.vue +877 -0
- package/edge/components/shad/input.vue +139 -0
- package/edge/components/shad/number.vue +109 -0
- package/edge/components/shad/select.vue +151 -0
- package/edge/components/shad/selectTags.vue +278 -0
- package/edge/components/shad/switch.vue +67 -0
- package/edge/components/shad/tags.vue +137 -0
- package/edge/components/shad/textarea.vue +102 -0
- package/edge/components/shad/typeMoney.vue +167 -0
- package/edge/components/sideBar.vue +288 -0
- package/edge/components/sideBarContent.vue +268 -0
- package/edge/components/sidebarProvider.vue +33 -0
- package/edge/components/tooltip.vue +16 -0
- package/edge/components/userMenu.vue +148 -0
- package/edge/components/v/alert.vue +59 -0
- package/edge/components/v/alertTitle.vue +18 -0
- package/edge/components/v/card.vue +53 -0
- package/edge/components/v/cardActions.vue +18 -0
- package/edge/components/v/cardText.vue +18 -0
- package/edge/components/v/cardTitle.vue +20 -0
- package/edge/components/v/col.vue +56 -0
- package/edge/components/v/list.vue +46 -0
- package/edge/components/v/listItem.vue +26 -0
- package/edge/components/v/listItemTitle.vue +18 -0
- package/edge/components/v/row.vue +42 -0
- package/edge/components/v/toolbar.vue +24 -0
- package/edge/composables/global.ts +519 -0
- package/edge-pull.sh +2 -0
- package/edge-push.sh +1 -0
- package/edge-status.sh +14 -0
- package/package.json +1 -1
- package/edge-components-install.sh +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
/**
|
|
3
|
+
* SSR-friendly array loading for block APIs using useAsyncData
|
|
4
|
+
* - Fetches all configured API arrays on the server when possible
|
|
5
|
+
* - Refetches when meta/values change on the client
|
|
6
|
+
* - Preserves original behavior: API fields override same-named props.values fields
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { computedAsync } from '@vueuse/core'
|
|
10
|
+
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
content: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
values: {
|
|
17
|
+
type: Object,
|
|
18
|
+
required: true,
|
|
19
|
+
},
|
|
20
|
+
meta: {
|
|
21
|
+
type: Object,
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
theme: {
|
|
25
|
+
type: Object,
|
|
26
|
+
default: null,
|
|
27
|
+
},
|
|
28
|
+
siteId: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: '',
|
|
31
|
+
},
|
|
32
|
+
viewportMode: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: 'auto',
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
const emit = defineEmits(['pending'])
|
|
38
|
+
const edgeFirebase = inject('edgeFirebase')
|
|
39
|
+
/* ---------------- helpers ---------------- */
|
|
40
|
+
|
|
41
|
+
// Safe dot-path getter
|
|
42
|
+
const getByPath = (obj, path) => {
|
|
43
|
+
if (!path || typeof path !== 'string')
|
|
44
|
+
return obj
|
|
45
|
+
return path.split('.').reduce((acc, key) => ((acc && acc[key] !== undefined) ? acc[key] : undefined), obj)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Build URL combining existing query string, template query, and runtime overrides
|
|
49
|
+
const buildUrlWithQuery = (base, query, queryItems = {}) => {
|
|
50
|
+
const safeBase = String(base || '')
|
|
51
|
+
const queryOverrides = (queryItems && typeof queryItems === 'object') ? queryItems : {}
|
|
52
|
+
|
|
53
|
+
// Separate hash fragment to re-attach later
|
|
54
|
+
const hashIndex = safeBase.indexOf('#')
|
|
55
|
+
const hash = hashIndex !== -1 ? safeBase.slice(hashIndex) : ''
|
|
56
|
+
const baseWithoutHash = hashIndex !== -1 ? safeBase.slice(0, hashIndex) : safeBase
|
|
57
|
+
|
|
58
|
+
const questionIndex = baseWithoutHash.indexOf('?')
|
|
59
|
+
const basePath = questionIndex === -1 ? baseWithoutHash : baseWithoutHash.slice(0, questionIndex)
|
|
60
|
+
const baseQuery = questionIndex === -1 ? '' : baseWithoutHash.slice(questionIndex + 1)
|
|
61
|
+
|
|
62
|
+
const params = new URLSearchParams(baseQuery)
|
|
63
|
+
|
|
64
|
+
const templateQuery = typeof query === 'string' ? query.trim() : ''
|
|
65
|
+
if (templateQuery) {
|
|
66
|
+
const cleaned = templateQuery.startsWith('?') ? templateQuery.slice(1) : templateQuery
|
|
67
|
+
if (cleaned) {
|
|
68
|
+
const templateParams = new URLSearchParams(cleaned)
|
|
69
|
+
for (const [key, value] of templateParams.entries())
|
|
70
|
+
params.set(key, value)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (const [key, value] of Object.entries(queryOverrides)) {
|
|
75
|
+
if (value == null) {
|
|
76
|
+
params.delete(key)
|
|
77
|
+
continue
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
params.delete(key)
|
|
82
|
+
value.forEach((val) => {
|
|
83
|
+
if (val != null)
|
|
84
|
+
params.append(key, String(val))
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
params.set(key, String(value))
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const paramString = params.toString()
|
|
93
|
+
return `${basePath}${paramString ? `?${paramString}` : ''}${hash}`
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Core fetcher that resolves all API-backed arrays from meta
|
|
97
|
+
const fetchAllArrays = async (meta, baseValues) => {
|
|
98
|
+
const out = {}
|
|
99
|
+
const entries = Object.entries(meta || {})
|
|
100
|
+
await Promise.all(entries.map(async ([field, cfg]) => {
|
|
101
|
+
try {
|
|
102
|
+
if (!cfg || cfg.type !== 'array' || !cfg.api)
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
const url = buildUrlWithQuery(String(cfg.api), String(cfg.apiQuery || ''), cfg.queryItems || {})
|
|
106
|
+
// use $fetch for SSR-friendly HTTP
|
|
107
|
+
const json = await $fetch(url, { method: 'GET' })
|
|
108
|
+
|
|
109
|
+
let data = getByPath(json, cfg.apiField || '')
|
|
110
|
+
if (!Array.isArray(data)) {
|
|
111
|
+
data = (data && typeof data === 'object') ? Object.values(data) : []
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const limit = Number(cfg.limit)
|
|
115
|
+
if (Number.isFinite(limit) && limit > 0) {
|
|
116
|
+
data = data.slice(0, limit)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
out[field] = data
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
// On error, preserve any existing prop value for that field or fallback to []
|
|
123
|
+
const existing = (baseValues || {})[field]
|
|
124
|
+
out[field] = Array.isArray(existing) ? existing : []
|
|
125
|
+
// Optional: console.warn('blockApi useAsyncData error for', field, e)
|
|
126
|
+
}
|
|
127
|
+
}))
|
|
128
|
+
return out
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* ---------------- async data (SSR + client) ---------------- */
|
|
132
|
+
|
|
133
|
+
// Stable, SSR-safe cache key so multiple block instances don't collide
|
|
134
|
+
const route = useRoute()
|
|
135
|
+
const asyncKey = computed(() => `blockApi:${route.fullPath}:${JSON.stringify(props.meta ?? {})}`)
|
|
136
|
+
|
|
137
|
+
const { data: apiResolved, pending } = await useAsyncData(
|
|
138
|
+
asyncKey.value,
|
|
139
|
+
() => {
|
|
140
|
+
// Always compute from latest props
|
|
141
|
+
return fetchAllArrays(props.meta, props.values)
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
server: true,
|
|
145
|
+
default: () => ({}),
|
|
146
|
+
// Re-run when inputs change on client side
|
|
147
|
+
watch: [() => props.meta, () => props.values],
|
|
148
|
+
},
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
/* ---------------- state & derived values ---------------- */
|
|
152
|
+
|
|
153
|
+
// Merge props.values (base) + apiResolved (overrides for API-backed fields)
|
|
154
|
+
const mergedValues = computed(() => {
|
|
155
|
+
return {
|
|
156
|
+
...(props.values || {}),
|
|
157
|
+
...(apiResolved.value || {}),
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
// Map original loading flags into class toggles
|
|
162
|
+
const loadingRender = (content) => {
|
|
163
|
+
const isLoading = pending.value
|
|
164
|
+
if (isLoading) {
|
|
165
|
+
content = content.replaceAll('{{loading}}', '')
|
|
166
|
+
content = content.replaceAll('{{loaded}}', 'hidden')
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
content = content.replaceAll('{{loading}}', 'hidden')
|
|
170
|
+
content = content.replaceAll('{{loaded}}', '')
|
|
171
|
+
}
|
|
172
|
+
return content
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Emit pending state to parent (client-side)
|
|
176
|
+
if (import.meta.client) {
|
|
177
|
+
watch(pending, val => emit('pending', val), { immediate: true })
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const collectionValues = computedAsync(
|
|
181
|
+
async () => {
|
|
182
|
+
const collectionData = await edgeGlobal.cmsCollectionData(
|
|
183
|
+
edgeFirebase,
|
|
184
|
+
mergedValues.value,
|
|
185
|
+
props.meta,
|
|
186
|
+
props.siteId,
|
|
187
|
+
)
|
|
188
|
+
return collectionData
|
|
189
|
+
},
|
|
190
|
+
{},
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
const finalValues = computed(() => {
|
|
194
|
+
return {
|
|
195
|
+
...(mergedValues.value || {}),
|
|
196
|
+
...(collectionValues.value || {}),
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
</script>
|
|
200
|
+
|
|
201
|
+
<template>
|
|
202
|
+
<edge-cms-block-render
|
|
203
|
+
:theme="props.theme"
|
|
204
|
+
:content="loadingRender(props.content)"
|
|
205
|
+
:values="finalValues"
|
|
206
|
+
:meta="props.meta"
|
|
207
|
+
:viewport-mode="props.viewportMode"
|
|
208
|
+
/>
|
|
209
|
+
</template>
|
|
210
|
+
|
|
211
|
+
<style scoped>
|
|
212
|
+
</style>
|