@edgedev/create-edge-app 1.2.34 → 1.2.35

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.
@@ -2,19 +2,7 @@
2
2
  class="relative cms-block cms-block-contact-form-placeholder rounded-2xl border border-dashed border-slate-300 bg-slate-50/70 px-4 py-6 sm:px-6 sm:py-8"
3
3
  data-block-type="contact-form-placeholder"
4
4
  >
5
- <!-- OVERLAY BADGE -->
6
- <div class="pointer-events-none absolute inset-x-0 top-0 z-20 flex justify-center pt-3">
7
- <div
8
- class="rounded-full border border-slate-300 bg-white/95 px-4 py-1 text-[11px] font-semibold uppercase tracking-wide text-slate-600 shadow-sm"
9
- >
10
- Contact Form Placeholder
11
- </div>
12
- </div>
13
-
14
5
  <div class="mx-auto max-w-3xl pt-6">
15
- <!-- Hidden config field: emailTo -->
16
-
17
- <!-- Header -->
18
6
  <div class="mb-6 space-y-2 text-center sm:text-left">
19
7
  <h2 class="text-xl font-semibold text-slate-900">
20
8
  {{{#text {"field":"formHeader","title":"Form Header","value":"Contact Us"}}}}
@@ -24,46 +12,66 @@
24
12
  </p>
25
13
  </div>
26
14
 
27
- <!-- Fields driven by CMS array (fieldName + fieldType as option) -->
28
- <div class="space-y-4">
29
- {{{#array {"field":"formFields","schema":[{"field":"fieldName","type":"text","title":"Field Label"},{"field":"fieldType","type":"option","option":{"optionsKey":"title","optionsValue":"value","options":[{"title":"Text","value":"text"},{"title":"Email","value":"email"},{"title":"Phone","value":"tel"},{"title":"Textarea","value":"textarea"}]},"value":"text"}],"value":[{"fieldName":"Name","fieldType":"text"},{"fieldName":"Email","fieldType":"email"},{"fieldName":"Message","fieldType":"textarea"}]}}}}
30
- <div class="space-y-1">
31
- <!-- Label preview -->
32
- <p class="text-xs font-medium uppercase tracking-wide text-slate-600">
33
- {{item.fieldName}}
15
+ <form
16
+ class="cms-form space-y-4"
17
+ data-cms-form
18
+ data-cms-required-message="Please complete all required fields."
19
+ data-cms-success-message="Thanks! Your message has been sent."
20
+ data-cms-error-message="Sorry, we could not send your message. Please try again."
21
+ data-cms-success-class="cms-form-message cms-form-message-success"
22
+ data-cms-error-class="cms-form-message cms-form-message-error"
23
+ data-cms-invalid-class="cms-form-field-invalid"
24
+ data-cms-working-class="cms-form-submitting"
25
+ >
26
+ <!-- Honeypot (optional, used by helper if present) -->
27
+ <div class="pointer-events-none absolute -left-[9999px] top-auto h-px w-px overflow-hidden opacity-0" aria-hidden="true">
28
+ <label for="cms-company">Company</label>
29
+ <input id="cms-company" name="company" type="text" tabindex="-1" autocomplete="off" />
30
+ </div>
31
+
32
+ <div class="space-y-4">
33
+ {{{#array {"field":"formFields","schema":[{"field":"fieldName","type":"text","title":"Field Label"},{"field":"fieldType","type":"option","title":"Field Type","option":{"optionsKey":"title","optionsValue":"value","options":[{"title":"Text","value":"text"},{"title":"Email","value":"email"},{"title":"Phone","value":"tel"},{"title":"Textarea","value":"textarea"}]},"value":"text"},{"field":"fieldRequired","type":"option","title":"Required","option":{"optionsKey":"title","optionsValue":"value","options":[{"title":"Yes","value":"true"},{"title":"No","value":"false"}]},"value":"true"}],"value":[{"fieldName":"Name","fieldType":"text","fieldRequired":"true"},{"fieldName":"Email","fieldType":"email","fieldRequired":"true"},{"fieldName":"Message","fieldType":"textarea","fieldRequired":"true"}]}}}}
34
+ <div class="space-y-1">
35
+ <label class="text-xs font-medium uppercase tracking-wide text-slate-600">
36
+ {{item.fieldName}}
37
+ </label>
38
+
34
39
  {{{#if {"cond":"item.fieldType == 'textarea'"}}}}
35
- <span class="ml-1 text-[10px] h-[300px] font-normal text-slate-400">
36
- ({{item.fieldType}})
37
- </span>
38
- <div class="w-full rounded-lg bg-slate-100 h-20"></div>
40
+ <textarea
41
+ class="w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900"
42
+ data-cms-required="{{item.fieldRequired}}"
43
+ name="{{item.fieldName}}"
44
+ placeholder="{{item.fieldName}}"
45
+ rows="6"
46
+ ></textarea>
39
47
  {{{#else}}}
40
- <span class="ml-1 text-[10px] font-normal text-slate-400">
41
- ({{item.fieldType}})
42
- </span>
43
- <div class="w-full rounded-lg bg-slate-100 h-10"></div>
48
+ <input
49
+ class="w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900"
50
+ data-cms-required="{{item.fieldRequired}}"
51
+ type="{{item.fieldType}}"
52
+ name="{{item.fieldName}}"
53
+ placeholder="{{item.fieldName}}"
54
+ />
44
55
  {{{/if}}}
45
- </p>
56
+ </div>
57
+ {{{/array}}}
58
+ </div>
46
59
 
47
- <!-- Input preview skeleton (visual only) -->
48
-
49
- </div>
50
- {{{/array}}}
51
- </div>
60
+ <div class="mt-6">
61
+ <button
62
+ type="submit"
63
+ class="cms-form-submit inline-flex w-full items-center justify-center rounded-lg bg-slate-900 px-4 py-2.5 text-sm font-semibold text-white shadow-sm disabled:cursor-not-allowed disabled:opacity-60 sm:w-auto"
64
+ data-cms-form-submit
65
+ >
66
+ {{{#text {"field":"buttonText","title":"Button Text","value":"Send Message"}}}}
67
+ </button>
68
+ </div>
52
69
 
53
- <!-- Submit button preview -->
54
- <div class="mt-6">
55
- <button
56
- type="button"
57
- class="inline-flex w-full items-center justify-center rounded-lg bg-slate-900 px-4 py-2.5 text-sm font-semibold text-white shadow-sm disabled:cursor-not-allowed disabled:opacity-60 sm:w-auto"
58
- disabled
59
- >
60
- {{{#text {"field":"buttonText","title":"Button Text","value":"Send Message"}}}}
61
- </button>
62
- </div>
70
+ <p class="cms-form-message hidden text-sm" data-cms-form-message></p>
71
+ </form>
63
72
 
64
- <!-- Tiny note -->
65
- <p class="mt-3 text-xs text-slate-400">
66
- The CMS uses <code>emailTo</code> <span class="font-bold underline">({{{#text {"field":"emailTo","title":"Email To","value":"test@testing.com"}}}})</span> and <code>formFields</code> (with fieldType options) to build the real form on the live site.
67
- </p>
73
+ <div class="hidden">
74
+ {{{#text {"field":"emailTo","title":"Email To","value":"test@testing.com"}}}}
75
+ </div>
68
76
  </div>
69
77
  </section>
@@ -2,20 +2,7 @@
2
2
  class="relative cms-block cms-block-newsletter-placeholder rounded-2xl border border-dashed border-slate-300 bg-slate-50/70 px-4 py-6 sm:px-6 sm:py-8"
3
3
  data-block-type="newsletter-placeholder"
4
4
  >
5
- <!-- OVERLAY BADGE -->
6
- <div
7
- class="pointer-events-none absolute inset-x-0 top-0 z-20 flex justify-center pt-3"
8
- >
9
- <div
10
- class="rounded-full border border-slate-300 bg-white/95 px-4 py-1 text-[11px] font-semibold uppercase tracking-wide text-slate-600 shadow-sm"
11
- >
12
- Newsletter Placeholder
13
- </div>
14
- </div>
15
-
16
5
  <div class="mx-auto max-w-2xl pt-6">
17
- <!-- Hidden config field: emailTo -->
18
-
19
6
  <!-- Header -->
20
7
  <div class="mb-6 space-y-2 text-center sm:text-left">
21
8
  <h2 class="text-xl font-semibold text-slate-900">
@@ -26,92 +13,65 @@
26
13
  </p>
27
14
  </div>
28
15
 
29
- <!-- Fields driven by CMS array (fieldName + fieldType as option) -->
30
- <div class="space-y-4">
31
- {{{#array {
32
- "field":"newsletterFields",
33
- "title":"Form Fields",
34
- "schema":[
35
- {
36
- "field":"fieldName",
37
- "type":"text",
38
- "title":"Field Label"
39
- },
40
- {
41
- "field":"fieldType",
42
- "type":"option",
43
- "title":"Field Type",
44
- "option":{
45
- "optionsKey":"title",
46
- "optionsValue":"value",
47
- "options":[
48
- {
49
- "title":"Text",
50
- "value":"text"
51
- },
52
- {
53
- "title":"Email",
54
- "value":"email"
55
- },
56
- {
57
- "title":"Phone",
58
- "value":"tel"
59
- },
60
- {
61
- "title":"Textarea",
62
- "value":"textarea"
63
- }
64
- ]
65
- },
66
- "value":"text"
67
- }
68
- ],
69
- "value":[
70
- {
71
- "fieldName":"Name",
72
- "fieldType":"text"
73
- },
74
- {
75
- "fieldName":"Email",
76
- "fieldType":"email"
77
- }
78
- ]
79
- }}}}
80
- <div class="space-y-1">
81
- <!-- Label preview -->
82
- <p class="text-xs font-medium uppercase tracking-wide text-slate-600">
83
- {{item.fieldName}}
16
+ <form
17
+ class="cms-form space-y-4"
18
+ data-cms-form
19
+ data-cms-required-message="Please complete all required fields."
20
+ data-cms-success-message="Thanks! You’re subscribed."
21
+ data-cms-error-message="Sorry, we could not submit this right now."
22
+ data-cms-success-class="cms-form-message cms-form-message-success"
23
+ data-cms-error-class="cms-form-message cms-form-message-error"
24
+ data-cms-invalid-class="cms-form-field-invalid"
25
+ data-cms-working-class="cms-form-submitting"
26
+ >
27
+ <div class="space-y-4">
28
+ {{{#array {
29
+ "field":"newsletterFields",
30
+ "title":"Form Fields",
31
+ "schema":[
32
+ {"field":"fieldName","type":"text","title":"Field Label"},
33
+ {"field":"fieldType","type":"option","title":"Field Type","option":{"optionsKey":"title","optionsValue":"value","options":[{"title":"Text","value":"text"},{"title":"Email","value":"email"},{"title":"Phone","value":"tel"},{"title":"Textarea","value":"textarea"}]},"value":"text"}
34
+ ],
35
+ "value":[
36
+ {"fieldName":"Name","fieldType":"text"},
37
+ {"fieldName":"Email","fieldType":"email"}
38
+ ]
39
+ }}}}
40
+ <div class="space-y-1 cms-form-required" data-cms-required="true">
41
+ <label class="block text-xs font-medium uppercase tracking-wide text-slate-600">
42
+ {{item.fieldName}}
43
+ </label>
44
+
84
45
  {{{#if {"cond":"item.fieldType == 'textarea'"}}}}
85
- <span class="ml-1 text-[10px] font-normal text-slate-400">
86
- ({{item.fieldType}})
87
- </span>
88
- <div class="w-full rounded-lg bg-slate-100 h-20"></div>
46
+ <textarea
47
+ name="{{item.fieldName}}"
48
+ placeholder="{{item.fieldName}}"
49
+ rows="5"
50
+ class="w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 focus:outline-none focus:ring-2 focus:ring-brand/30 focus:border-brand"
51
+ ></textarea>
89
52
  {{{#else}}}
90
- <span class="ml-1 text-[10px] font-normal text-slate-400">
91
- ({{item.fieldType}})
92
- </span>
93
- <div class="w-full rounded-lg bg-slate-100 h-10"></div>
53
+ <input
54
+ type="{{item.fieldType}}"
55
+ name="{{item.fieldName}}"
56
+ placeholder="{{item.fieldName}}"
57
+ class="h-10 w-full rounded-lg border border-slate-300 bg-white px-3 text-sm text-slate-900 focus:outline-none focus:ring-2 focus:ring-brand/30 focus:border-brand"
58
+ />
94
59
  {{{/if}}}
95
- </p>
96
- </div>
97
- {{{/array}}}
98
- </div>
60
+ </div>
61
+ {{{/array}}}
62
+ </div>
99
63
 
100
- <!-- Submit button preview -->
101
- <div class="mt-6">
102
- <button
103
- type="button"
104
- class="inline-flex w-full items-center justify-center rounded-lg bg-slate-900 px-4 py-2.5 text-sm font-semibold text-white shadow-sm disabled:cursor-not-allowed disabled:opacity-60 sm:w-auto"
105
- disabled
106
- >
107
- {{{#text {"field":"buttonText","title":"Button Text","value":"Subscribe"}}}}
108
- </button>
109
- </div>
64
+ <div class="mt-6">
65
+ <button
66
+ type="submit"
67
+ data-cms-form-submit
68
+ class="cms-form-submit inline-flex w-full items-center justify-center rounded-lg bg-slate-900 px-4 py-2.5 text-sm font-semibold text-white shadow-sm disabled:cursor-not-allowed disabled:opacity-60 sm:w-auto"
69
+ >
70
+ {{{#text {"field":"buttonText","title":"Button Text","value":"Subscribe"}}}}
71
+ </button>
72
+ </div>
110
73
 
111
- <!-- Tiny note -->
112
- <p class="mt-3 text-xs text-slate-400">
113
- The CMS uses <code>emailTo</code> and <code>newsletterFields</code> (array of fieldName + fieldType)
114
- to build the real newsletter signup form on the live site.
115
- </p>
74
+ <p class="cms-form-message hidden text-sm" data-cms-form-message></p>
75
+ </form>
116
76
  </div>
117
- </section>
77
+ </section>
@@ -60,6 +60,53 @@ const isDeleteDisabled = entry => isPageEntry(entry) && !!entry?.disableDelete
60
60
  const isLinkUrlSpecial = url => /^tel:|^mailto:/i.test(String(url || '').trim())
61
61
  const linkTarget = url => (isLinkUrlSpecial(url) ? null : '_blank')
62
62
  const linkRel = url => (isLinkUrlSpecial(url) ? null : 'noopener noreferrer')
63
+ const titleFromSlug = (slug) => {
64
+ if (!slug)
65
+ return ''
66
+ return slug.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())
67
+ }
68
+ const displayEntryName = (entry) => {
69
+ if (!entry)
70
+ return ''
71
+ if (entry?.name === 'Deleting...')
72
+ return 'Deleting...'
73
+ if (isExternalLinkEntry(entry))
74
+ return String(entry?.name || '').trim()
75
+ const menuTitle = String(entry?.menuTitle || '').trim()
76
+ if (menuTitle)
77
+ return menuTitle
78
+ const slug = String(entry?.name || '').trim()
79
+ if (!slug)
80
+ return ''
81
+ return slug
82
+ }
83
+ const folderEntryForMenu = (menuName) => {
84
+ if (!props.prevMenu || !Number.isInteger(props.prevIndex) || props.prevIndex < 0)
85
+ return null
86
+ const parentList = props.prevModelValue?.[props.prevMenu]
87
+ if (!Array.isArray(parentList))
88
+ return null
89
+ const parentEntry = parentList[props.prevIndex]
90
+ if (!parentEntry || typeof parentEntry !== 'object' || isExternalLinkEntry(parentEntry))
91
+ return null
92
+ if (!parentEntry.item || typeof parentEntry.item !== 'object')
93
+ return null
94
+ const folderSlug = Object.keys(parentEntry.item || {})[0]
95
+ if (!folderSlug || folderSlug !== menuName)
96
+ return null
97
+ return parentEntry
98
+ }
99
+ const displayMenuName = (menuName) => {
100
+ if (menuName === 'Site Root')
101
+ return 'Site Menu'
102
+ const folderEntry = folderEntryForMenu(menuName)
103
+ if (folderEntry) {
104
+ const title = String(folderEntry?.menuTitle || folderEntry?.folderTitle || '').trim()
105
+ if (title)
106
+ return title
107
+ }
108
+ return menuName
109
+ }
63
110
 
64
111
  const normalizeForCompare = (value) => {
65
112
  if (Array.isArray(value))
@@ -466,6 +513,11 @@ const renameFolderOrPageShow = (item) => {
466
513
  // Work on a copy so edits in the dialog do not mutate the live menu entry.
467
514
  state.renameItem = edgeGlobal.dupObject(item || {})
468
515
  state.renameItem.previousName = item?.name
516
+ state.renameItem.previousMenuTitle = displayEntryName(item)
517
+ if (state.renameItem.item === '')
518
+ state.renameItem.name = String(item?.menuTitle || item?.folderTitle || item?.name || '').trim()
519
+ if (state.renameItem.item !== '' && !isExternalLinkEntry(state.renameItem))
520
+ state.renameItem.name = state.renameItem.previousMenuTitle
469
521
  state.renameFolderOrPageDialog = true
470
522
  }
471
523
 
@@ -558,10 +610,11 @@ const slugGenerator = (name, excludeName = '') => {
558
610
  console.log('Existing slugs:', existing)
559
611
 
560
612
  const base = name ? name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)+/g, '') : ''
561
- let unique = base
613
+ const baseSlug = base || 'page'
614
+ let unique = baseSlug
562
615
  let suffix = 1
563
616
  while (existing.has(unique)) {
564
- unique = `${base}-${suffix}`
617
+ unique = `${baseSlug}-${suffix}`
565
618
  suffix += 1
566
619
  }
567
620
  return unique
@@ -686,20 +739,21 @@ const renameFolderOrPageAction = async () => {
686
739
  state.renameItem = {}
687
740
  return
688
741
  }
689
- const newSlug = slugGenerator(state.renameItem.name, state.renameItem.previousName || '')
690
-
691
- if (state.renameItem.name === state.renameItem.previousName) {
692
- state.renameFolderOrPageDialog = false
693
- state.renameItem = {}
694
- return
695
- }
696
-
697
742
  // If the item is an empty string, we are renaming a top-level folder (handled here)
698
743
  if (state.renameItem.item === '') {
699
- const original = edgeGlobal.dupObject(modelValue.value)
744
+ const nextFolderTitle = String(state.renameItem.name || '').trim()
745
+ const newSlug = slugGenerator(nextFolderTitle, state.renameItem.previousName || '')
746
+ const folderEntry = folderEntryForMenu(state.renameItem.previousName || '')
747
+ const previousFolderTitle = String(folderEntry?.menuTitle || folderEntry?.folderTitle || '').trim()
748
+ const resolvedFolderTitle = nextFolderTitle || titleFromSlug(newSlug)
749
+ if (newSlug === state.renameItem.previousName && resolvedFolderTitle === previousFolderTitle) {
750
+ state.renameFolderOrPageDialog = false
751
+ state.renameItem = {}
752
+ return
753
+ }
700
754
  const originalItem = edgeGlobal.dupObject(modelValue.value[state.renameItem.previousName])
701
755
  // Renaming a folder: if the new name is empty, abort and reset dialog state
702
- if (!state.renameItem.name) {
756
+ if (!nextFolderTitle) {
703
757
  state.renameFolderOrPageDialog = false
704
758
  state.renameItem = {}
705
759
  return
@@ -708,6 +762,11 @@ const renameFolderOrPageAction = async () => {
708
762
  modelValue.value[newSlug] = originalItem
709
763
  console.log('updated modelValue:', modelValue.value)
710
764
  delete modelValue.value[state.renameItem.previousName]
765
+ if (folderEntry) {
766
+ folderEntry.menuTitle = resolvedFolderTitle
767
+ if (Object.prototype.hasOwnProperty.call(folderEntry, 'folderTitle'))
768
+ delete folderEntry.folderTitle
769
+ }
711
770
  state.renameFolderOrPageDialog = false
712
771
  state.renameItem = {}
713
772
  return
@@ -716,7 +775,14 @@ const renameFolderOrPageAction = async () => {
716
775
  // Renaming a page: the page is uniquely identified by its docId in `state.renameItem.item`.
717
776
  // Traverse all menus and submenus; update the `name` where the `item` matches that docId (strings only).
718
777
  const targetDocId = state.renameItem.item
719
- // const newName = state.renameItem.name || ''
778
+ const nextMenuTitle = String(state.renameItem.name || '').trim()
779
+ const previousMenuTitle = String(state.renameItem.previousMenuTitle || '').trim()
780
+ const newSlug = slugGenerator(nextMenuTitle, state.renameItem.previousName || '')
781
+ if (nextMenuTitle === previousMenuTitle && newSlug === state.renameItem.previousName) {
782
+ state.renameFolderOrPageDialog = false
783
+ state.renameItem = {}
784
+ return
785
+ }
720
786
 
721
787
  let renamed = false
722
788
  for (const [menuName, items] of Object.entries(modelValue.value)) {
@@ -725,6 +791,7 @@ const renameFolderOrPageAction = async () => {
725
791
  const results = await edgeFirebase.changeDoc(`${edgeGlobal.edgeState.organizationDocPath}/sites/${props.site}/pages`, targetDocId, { name: newSlug })
726
792
  if (results.success) {
727
793
  item.name = newSlug
794
+ item.menuTitle = nextMenuTitle || titleFromSlug(newSlug)
728
795
  renamed = true
729
796
  }
730
797
  break
@@ -755,7 +822,7 @@ const addPageAction = async () => {
755
822
  modelValue.value[state.menuName] = []
756
823
 
757
824
  if (state.addMenu) {
758
- modelValue.value[state.menuName].push({ item: { [slug]: [] } })
825
+ modelValue.value[state.menuName].push({ menuTitle: state.newPageName, item: { [slug]: [] } })
759
826
  }
760
827
  else {
761
828
  const templateDoc = getTemplateDoc(state.selectedTemplateId)
@@ -766,7 +833,7 @@ const addPageAction = async () => {
766
833
  const targetMenu = modelValue.value[state.menuName]
767
834
  const alreadyExists = Array.isArray(targetMenu) && targetMenu.some(entry => entry?.item === docId)
768
835
  if (!alreadyExists)
769
- targetMenu.push({ name: slug, item: docId })
836
+ targetMenu.push({ name: slug, menuTitle: state.newPageName, item: docId })
770
837
  }
771
838
  }
772
839
 
@@ -936,12 +1003,6 @@ const onSubmit = () => {
936
1003
  state.pageSettings = false
937
1004
  }
938
1005
  }
939
- const titleFromSlug = (slug) => {
940
- if (!slug)
941
- return ''
942
- return slug.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())
943
- }
944
-
945
1006
  const theme = computed(() => {
946
1007
  const theme = edgeFirebase.data?.[`${edgeGlobal.edgeState.organizationDocPath}/sites`]?.[props.site]?.theme || ''
947
1008
  console.log(`${edgeGlobal.edgeState.organizationDocPath}/sites/${props.site}`)
@@ -962,7 +1023,7 @@ const theme = computed(() => {
962
1023
  <FolderOpen
963
1024
  class="mr-2 group-hover:text-foreground"
964
1025
  />
965
- <span v-if="!props.isTemplateSite" class="!text-foreground">{{ menuName === 'Site Root' ? 'Site Menu' : menuName }}</span>
1026
+ <span v-if="!props.isTemplateSite" class="!text-foreground">{{ displayMenuName(menuName) }}</span>
966
1027
  <SidebarGroupAction class="absolute right-2 top-0 hover:!bg-transparent">
967
1028
  <DropdownMenu>
968
1029
  <DropdownMenuTrigger as-child>
@@ -990,7 +1051,7 @@ const theme = computed(() => {
990
1051
  <FolderPlus />
991
1052
  <span>New Folder</span>
992
1053
  </DropdownMenuItem>
993
- <DropdownMenuItem v-if="canRename(menuName)" @click="renameFolderOrPageShow({ name: menuName, item: '' })">
1054
+ <DropdownMenuItem v-if="canRename(menuName)" @click="renameFolderOrPageShow({ name: menuName, menuTitle: displayMenuName(menuName), item: '' })">
994
1055
  <FolderPen />
995
1056
  <span>Rename Folder</span>
996
1057
  </DropdownMenuItem>
@@ -1041,7 +1102,7 @@ const theme = computed(() => {
1041
1102
  <Loader2 v-if="element.item === '' || element.name === 'Deleting...'" :class="{ '!text-red-500': element.name === 'Deleting...' }" class="w-4 h-4 animate-spin" />
1042
1103
  <FileWarning v-else-if="isPublishedPageDiff(element.item) && !props.isTemplateSite" class="!text-yellow-600" />
1043
1104
  <FileCheck v-else class="text-xs !text-green-700 font-normal" />
1044
- <span>{{ element.name }}</span>
1105
+ <span>{{ displayEntryName(element) }}</span>
1045
1106
  </NuxtLink>
1046
1107
  <a
1047
1108
  v-else
@@ -1051,7 +1112,7 @@ const theme = computed(() => {
1051
1112
  :rel="linkRel(element.item?.url)"
1052
1113
  >
1053
1114
  <Link class="w-4 h-4 text-muted-foreground" />
1054
- <span>{{ element.name }}</span>
1115
+ <span>{{ displayEntryName(element) }}</span>
1055
1116
  </a>
1056
1117
  </SidebarMenuSubButton>
1057
1118
  <div class="absolute right-0 -top-0.5">
@@ -1063,10 +1124,10 @@ const theme = computed(() => {
1063
1124
  </DropdownMenuTrigger>
1064
1125
  <DropdownMenuContent side="right" align="start">
1065
1126
  <DropdownMenuLabel v-if="props.prevMenu" class="flex items-center gap-2">
1066
- <File class="w-5 h-5" /> {{ ROOT_MENUS.includes(props.prevMenu) ? '' : props.prevMenu }}/{{ menuName }}/{{ element.name }}
1127
+ <File class="w-5 h-5" /> {{ ROOT_MENUS.includes(props.prevMenu) ? '' : props.prevMenu }}/{{ menuName }}/{{ displayEntryName(element) }}
1067
1128
  </DropdownMenuLabel>
1068
1129
  <DropdownMenuLabel v-else class="flex items-center gap-2">
1069
- <File class="w-5 h-5" /> {{ ROOT_MENUS.includes(menuName) ? '' : menuName }}/{{ element.name }}
1130
+ <File class="w-5 h-5" /> {{ ROOT_MENUS.includes(menuName) ? '' : menuName }}/{{ displayEntryName(element) }}
1070
1131
  </DropdownMenuLabel>
1071
1132
  <DropdownMenuSeparator />
1072
1133
  <template v-if="!isExternalLinkEntry(element)">
@@ -1130,13 +1191,13 @@ const theme = computed(() => {
1130
1191
  <DialogHeader>
1131
1192
  <DialogTitle class="text-left">
1132
1193
  <span v-if="state.deletePage.item === ''">Delete Folder "{{ state.deletePage.name }}"</span>
1133
- <span v-else-if="isExternalLinkEntry(state.deletePage)">Delete Link "{{ state.deletePage.name }}"</span>
1134
- <span v-else>Delete Page "{{ state.deletePage.name }}"</span>
1194
+ <span v-else-if="isExternalLinkEntry(state.deletePage)">Delete Link "{{ displayEntryName(state.deletePage) }}"</span>
1195
+ <span v-else>Delete Page "{{ displayEntryName(state.deletePage) }}"</span>
1135
1196
  </DialogTitle>
1136
1197
  <DialogDescription />
1137
1198
  </DialogHeader>
1138
1199
  <div class="text-left px-1">
1139
- Are you sure you want to delete "{{ state.deletePage.name }}"? This action cannot be undone.
1200
+ Are you sure you want to delete "{{ state.deletePage.item === '' ? state.deletePage.name : displayEntryName(state.deletePage) }}"? This action cannot be undone.
1140
1201
  </div>
1141
1202
  <DialogFooter class="pt-2 flex justify-between">
1142
1203
  <edge-shad-button
@@ -1338,7 +1399,7 @@ const theme = computed(() => {
1338
1399
  <Sheet v-model:open="state.pageSettings">
1339
1400
  <SheetContent side="left" class="w-full md:w-1/2 max-w-none sm:max-w-none max-w-2xl">
1340
1401
  <SheetHeader>
1341
- <SheetTitle>{{ state.pageData.name || 'Site' }}</SheetTitle>
1402
+ <SheetTitle>{{ displayEntryName(state.pageData) || 'Site' }}</SheetTitle>
1342
1403
  <SheetDescription />
1343
1404
  </SheetHeader>
1344
1405
  <edge-editor