@edgedev/create-edge-app 1.1.27 → 1.1.28

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,8 +1,9 @@
1
1
  <script setup lang="js">
2
2
  import { useVModel } from '@vueuse/core'
3
- import { File, FileCheck, FileCog, FileDown, FileMinus2, FilePen, FilePlus2, FileUp, FileWarning, FileX, Folder, FolderMinus, FolderOpen, FolderPen, FolderPlus } from 'lucide-vue-next'
3
+ import { File, FileCheck, FileCog, FileDown, FileMinus2, FilePen, FilePlus2, FileUp, FileWarning, FileX, Folder, FolderMinus, FolderOpen, FolderPen, FolderPlus, Link } from 'lucide-vue-next'
4
4
  import { toTypedSchema } from '@vee-validate/zod'
5
5
  import * as z from 'zod'
6
+ import { useStructuredDataTemplates } from '@/edge/composables/structuredDataTemplates'
6
7
 
7
8
  const props = defineProps({
8
9
  prevModelValue: {
@@ -50,6 +51,15 @@ const router = useRouter()
50
51
  const modelValue = useVModel(props, 'modelValue', emit)
51
52
  const route = useRoute()
52
53
  const edgeFirebase = inject('edgeFirebase')
54
+ const { buildPageStructuredData } = useStructuredDataTemplates()
55
+
56
+ const isExternalLinkEntry = entry => entry?.item && typeof entry.item === 'object' && entry.item.type === 'external'
57
+ const isPageEntry = entry => typeof entry?.item === 'string'
58
+ const isRenameDisabled = entry => isPageEntry(entry) && !!entry?.disableRename
59
+ const isDeleteDisabled = entry => isPageEntry(entry) && !!entry?.disableDelete
60
+ const isLinkUrlSpecial = url => /^tel:|^mailto:/i.test(String(url || '').trim())
61
+ const linkTarget = url => (isLinkUrlSpecial(url) ? null : '_blank')
62
+ const linkRel = url => (isLinkUrlSpecial(url) ? null : 'noopener noreferrer')
53
63
 
54
64
  const normalizeForCompare = (value) => {
55
65
  if (Array.isArray(value))
@@ -142,17 +152,26 @@ const state = reactive({
142
152
  newPageName: '',
143
153
  indexPath: '',
144
154
  addMenu: false,
155
+ addLinkDialog: false,
145
156
  deletePage: {},
146
157
  renameItem: {},
147
158
  renameFolderOrPageDialog: false,
148
159
  deletePageDialog: false,
149
160
  pageSettings: false,
150
161
  pageData: {},
162
+ linkDialogMode: 'add',
163
+ linkName: '',
164
+ linkUrl: '',
165
+ linkTargetMenu: '',
166
+ linkTargetIndex: -1,
151
167
  newDocs: {
152
168
  pages: {
153
169
  name: { value: '' },
154
170
  content: { value: [] },
155
171
  blockIds: { value: [] },
172
+ metaTitle: { value: '' },
173
+ metaDescription: { value: '' },
174
+ structuredData: { value: buildPageStructuredData() },
156
175
  tags: { value: [] },
157
176
  allowedThemes: { value: [] },
158
177
  },
@@ -182,6 +201,8 @@ const templateTagItems = computed(() => {
182
201
  return [{ name: 'Quick Picks', title: 'Quick Picks' }, ...tagList]
183
202
  })
184
203
 
204
+ const BLANK_TEMPLATE_ID = 'blank'
205
+
185
206
  const resetAddPageDialogState = () => {
186
207
  state.newPageName = ''
187
208
  state.templateFilter = 'quick-picks'
@@ -194,6 +215,21 @@ watch(() => state.addPageDialog, (open) => {
194
215
  resetAddPageDialogState()
195
216
  })
196
217
 
218
+ const resetLinkDialogState = () => {
219
+ state.linkDialogMode = 'add'
220
+ state.linkName = ''
221
+ state.linkUrl = ''
222
+ state.linkTargetMenu = ''
223
+ state.linkTargetIndex = -1
224
+ }
225
+
226
+ watch(() => state.addLinkDialog, (open) => {
227
+ if (!open)
228
+ resetLinkDialogState()
229
+ })
230
+
231
+ const TEMPLATE_COLLECTION_PATH = computed(() => `${edgeGlobal.edgeState.organizationDocPath}/sites/templates/pages`)
232
+
197
233
  onMounted(async () => {
198
234
  if (!edgeGlobal.edgeState.organizationDocPath)
199
235
  return
@@ -202,8 +238,6 @@ onMounted(async () => {
202
238
  await edgeFirebase.startSnapshot(path)
203
239
  })
204
240
 
205
- const TEMPLATE_COLLECTION_PATH = computed(() => `${edgeGlobal.edgeState.organizationDocPath}/sites/templates/pages`)
206
-
207
241
  const templatePagesCollection = computed(() => {
208
242
  return edgeFirebase.data?.[TEMPLATE_COLLECTION_PATH.value] || {}
209
243
  })
@@ -265,8 +299,6 @@ watch(filteredTemplates, (templates) => {
265
299
  state.selectedTemplateId = BLANK_TEMPLATE_ID
266
300
  })
267
301
 
268
- const BLANK_TEMPLATE_ID = 'blank'
269
-
270
302
  const blankTemplateTile = {
271
303
  docId: BLANK_TEMPLATE_ID,
272
304
  name: 'Blank Page',
@@ -314,6 +346,8 @@ const templatePreviewBlocks = (template) => {
314
346
  }
315
347
 
316
348
  const renameFolderOrPageShow = (item) => {
349
+ if (isRenameDisabled(item))
350
+ return
317
351
  // Work on a copy so edits in the dialog do not mutate the live menu entry.
318
352
  state.renameItem = edgeGlobal.dupObject(item || {})
319
353
  state.renameItem.previousName = item?.name
@@ -328,6 +362,8 @@ const addPageShow = (menuName, isMenu = false) => {
328
362
  }
329
363
 
330
364
  const deletePageShow = (page) => {
365
+ if (isDeleteDisabled(page))
366
+ return
331
367
  state.deletePage = page
332
368
  state.deletePageDialog = true
333
369
  }
@@ -343,6 +379,9 @@ const collectRootLevelSlugs = (excludeName = '') => {
343
379
  if (entry.name && entry.name !== excludeName)
344
380
  slugs.add(entry.name)
345
381
  }
382
+ else if (isExternalLinkEntry(entry)) {
383
+ continue
384
+ }
346
385
  // Top-level folder at "/<folder>/*"
347
386
  else if (entry && typeof entry.item === 'object') {
348
387
  const key = Object.keys(entry.item)[0]
@@ -362,6 +401,9 @@ const collectRootLevelSlugs = (excludeName = '') => {
362
401
  if (entry.name && entry.name !== excludeName)
363
402
  slugs.add(entry.name)
364
403
  }
404
+ else if (isExternalLinkEntry(entry)) {
405
+ continue
406
+ }
365
407
  // Top-level folder at "/<folder>/*"
366
408
  else if (entry && typeof entry.item === 'object') {
367
409
  const key = Object.keys(entry.item)[0]
@@ -380,6 +422,9 @@ const collectRootLevelSlugs = (excludeName = '') => {
380
422
  if (entry.name && entry.name !== excludeName)
381
423
  slugs.add(entry.name)
382
424
  }
425
+ else if (isExternalLinkEntry(entry)) {
426
+ continue
427
+ }
383
428
  // Top-level folder at "/<folder>/*"
384
429
  else if (entry && typeof entry.item === 'object') {
385
430
  const key = Object.keys(entry.item)[0]
@@ -471,6 +516,8 @@ const hydrateSyncedBlocksFromSite = (blocks = []) => {
471
516
 
472
517
  const buildPagePayloadFromTemplate = (templateDoc, slug) => {
473
518
  const timestamp = Date.now()
519
+ const templateStructuredData = typeof templateDoc?.structuredData === 'string' ? templateDoc.structuredData.trim() : ''
520
+ const structuredData = templateDoc ? (templateStructuredData || buildPageStructuredData()) : buildPageStructuredData()
474
521
  const basePayload = {
475
522
  name: slug,
476
523
  content: [],
@@ -478,7 +525,7 @@ const buildPagePayloadFromTemplate = (templateDoc, slug) => {
478
525
  blockIds: [],
479
526
  metaTitle: '',
480
527
  metaDescription: '',
481
- structuredData: '',
528
+ structuredData,
482
529
  doc_created_at: timestamp,
483
530
  last_updated: timestamp,
484
531
  }
@@ -492,10 +539,35 @@ const buildPagePayloadFromTemplate = (templateDoc, slug) => {
492
539
  copy.content = Array.isArray(copy.content) ? hydrateSyncedBlocksFromSite(copy.content) : []
493
540
  copy.postContent = Array.isArray(copy.postContent) ? hydrateSyncedBlocksFromSite(copy.postContent) : []
494
541
  copy.blockIds = deriveBlockIds(copy)
542
+ if (!String(copy.structuredData || '').trim())
543
+ copy.structuredData = structuredData
495
544
  return { ...basePayload, ...copy }
496
545
  }
497
546
 
498
547
  const renameFolderOrPageAction = async () => {
548
+ if (isRenameDisabled(state.renameItem)) {
549
+ state.renameFolderOrPageDialog = false
550
+ state.renameItem = {}
551
+ return
552
+ }
553
+ if (isExternalLinkEntry(state.renameItem)) {
554
+ const nextName = state.renameItem.name?.trim() || ''
555
+ if (!nextName) {
556
+ state.renameFolderOrPageDialog = false
557
+ state.renameItem = {}
558
+ return
559
+ }
560
+ const menuName = state.renameItem.menuName
561
+ const index = state.renameItem.index
562
+ if (menuName && Number.isInteger(index) && Array.isArray(modelValue.value[menuName])) {
563
+ const target = modelValue.value[menuName][index]
564
+ if (target)
565
+ target.name = nextName
566
+ }
567
+ state.renameFolderOrPageDialog = false
568
+ state.renameItem = {}
569
+ return
570
+ }
499
571
  const newSlug = slugGenerator(state.renameItem.name, state.renameItem.previousName || '')
500
572
 
501
573
  if (state.renameItem.name === state.renameItem.previousName) {
@@ -582,7 +654,70 @@ const addPageAction = async () => {
582
654
 
583
655
  state.addPageDialog = false
584
656
  }
657
+
658
+ const addLinkShow = (menuName) => {
659
+ state.linkDialogMode = 'add'
660
+ state.linkTargetMenu = menuName
661
+ state.addLinkDialog = true
662
+ }
663
+
664
+ const editLinkShow = (menuName, index, entry) => {
665
+ state.linkDialogMode = 'edit'
666
+ state.linkTargetMenu = menuName
667
+ state.linkTargetIndex = index
668
+ state.linkName = entry?.name || ''
669
+ state.linkUrl = entry?.item?.url || ''
670
+ state.addLinkDialog = true
671
+ }
672
+
673
+ const linkDialogSchema = toTypedSchema(z.object({
674
+ name: z.string({
675
+ required_error: 'Name is required',
676
+ }).min(1, { message: 'Name is required' }),
677
+ url: z.string({
678
+ required_error: 'URL is required',
679
+ }).min(1, { message: 'URL is required' }),
680
+ }))
681
+
682
+ const submitLinkDialog = () => {
683
+ const name = state.linkName?.trim() || ''
684
+ const url = state.linkUrl?.trim() || ''
685
+ if (!name || !url)
686
+ return
687
+ const payload = { name, item: { type: 'external', url } }
688
+ if (!Array.isArray(modelValue.value[state.linkTargetMenu]))
689
+ modelValue.value[state.linkTargetMenu] = []
690
+ if (state.linkDialogMode === 'edit') {
691
+ const target = modelValue.value[state.linkTargetMenu]?.[state.linkTargetIndex]
692
+ if (target) {
693
+ target.name = name
694
+ target.item = { type: 'external', url }
695
+ }
696
+ else {
697
+ modelValue.value[state.linkTargetMenu].push(payload)
698
+ }
699
+ }
700
+ else {
701
+ modelValue.value[state.linkTargetMenu].push(payload)
702
+ }
703
+ state.addLinkDialog = false
704
+ }
585
705
  const deletePageAction = async () => {
706
+ if (isDeleteDisabled(state.deletePage)) {
707
+ state.deletePageDialog = false
708
+ state.deletePage = {}
709
+ return
710
+ }
711
+ if (isExternalLinkEntry(state.deletePage)) {
712
+ const menuName = state.deletePage.menuName
713
+ const index = state.deletePage.index
714
+ if (menuName && Number.isInteger(index) && Array.isArray(modelValue.value[menuName])) {
715
+ modelValue.value[menuName].splice(index, 1)
716
+ }
717
+ state.deletePageDialog = false
718
+ state.deletePage = {}
719
+ return
720
+ }
586
721
  if (state.deletePage.item === '') {
587
722
  // deleting a folder
588
723
  delete modelValue.value[state.deletePage.name]
@@ -701,11 +836,11 @@ const theme = computed(() => {
701
836
 
702
837
  <template>
703
838
  <SidebarMenuItem v-for="({ menu, name: menuName }) in orderedMenus" :key="menuName">
704
- <SidebarMenuButton class="!px-0 hover:!bg-transparent">
839
+ <SidebarMenuButton class="group !px-0 hover:!bg-transparent">
705
840
  <FolderOpen
706
- class="mr-2"
841
+ class="mr-2 group-hover:text-black"
707
842
  />
708
- <span v-if="!props.isTemplateSite">{{ menuName === 'Site Root' ? 'Site Menu' : menuName }}</span>
843
+ <span v-if="!props.isTemplateSite" class="hover:text-black !text-black">{{ menuName === 'Site Root' ? 'Site Menu' : menuName }}</span>
709
844
  <SidebarGroupAction class="absolute right-2 top-0 hover:!bg-transparent">
710
845
  <DropdownMenu>
711
846
  <DropdownMenuTrigger as-child>
@@ -725,6 +860,10 @@ const theme = computed(() => {
725
860
  <FilePlus2 />
726
861
  <span>New Page</span>
727
862
  </DropdownMenuItem>
863
+ <DropdownMenuItem v-if="!props.isTemplateSite" @click="addLinkShow(menuName)">
864
+ <Link />
865
+ <span>New Link</span>
866
+ </DropdownMenuItem>
728
867
  <DropdownMenuItem v-if="!props.prevMenu && !props.isTemplateSite" @click="addPageShow(menuName, true)">
729
868
  <FolderPlus />
730
869
  <span>New Folder</span>
@@ -754,7 +893,7 @@ const theme = computed(() => {
754
893
  <template #item="{ element, index }">
755
894
  <div class="handle list-group-item">
756
895
  <edge-cms-menu
757
- v-if="typeof element.item === 'object'"
896
+ v-if="typeof element.item === 'object' && !isExternalLinkEntry(element)"
758
897
  v-model="modelValue[menuName][index].item"
759
898
  :prev-menu="menuName"
760
899
  :prev-model-value="modelValue"
@@ -764,13 +903,33 @@ const theme = computed(() => {
764
903
  :is-template-site="props.isTemplateSite"
765
904
  />
766
905
  <SidebarMenuSubItem v-else class="relative">
767
- <SidebarMenuSubButton :class="{ 'text-gray-400': element.item === '' }" as-child :is-active="element.item === props.page">
768
- <NuxtLink :disabled="element.item === ''" :class="{ '!text-red-500': element.name === 'Deleting...' }" class="text-xs" :to="`${pageRouteBase}/${element.item}`">
906
+ <SidebarMenuSubButton
907
+ :class="{ 'text-gray-400': element.item === '' }"
908
+ as-child
909
+ :is-active="!isExternalLinkEntry(element) && element.item === props.page"
910
+ >
911
+ <NuxtLink
912
+ v-if="!isExternalLinkEntry(element)"
913
+ :disabled="element.item === ''"
914
+ :class="{ '!text-red-500': element.name === 'Deleting...' }"
915
+ class="text-xs"
916
+ :to="`${pageRouteBase}/${element.item}`"
917
+ >
769
918
  <Loader2 v-if="element.item === '' || element.name === 'Deleting...'" :class="{ '!text-red-500': element.name === 'Deleting...' }" class="w-4 h-4 animate-spin" />
770
919
  <FileWarning v-else-if="isPublishedPageDiff(element.item) && !props.isTemplateSite" class="!text-yellow-600" />
771
920
  <FileCheck v-else class="text-xs !text-green-700 font-normal" />
772
921
  <span>{{ element.name }}</span>
773
922
  </NuxtLink>
923
+ <a
924
+ v-else
925
+ :href="element.item?.url || '#'"
926
+ class="text-xs inline-flex items-center gap-2"
927
+ :target="linkTarget(element.item?.url)"
928
+ :rel="linkRel(element.item?.url)"
929
+ >
930
+ <Link class="w-4 h-4 text-muted-foreground" />
931
+ <span>{{ element.name }}</span>
932
+ </a>
774
933
  </SidebarMenuSubButton>
775
934
  <div class="absolute right-0 -top-0.5">
776
935
  <DropdownMenu>
@@ -787,34 +946,51 @@ const theme = computed(() => {
787
946
  <File class="w-5 h-5" /> {{ ROOT_MENUS.includes(menuName) ? '' : menuName }}/{{ element.name }}
788
947
  </DropdownMenuLabel>
789
948
  <DropdownMenuSeparator />
790
- <DropdownMenuItem :disabled="edgeGlobal.edgeState.cmsPageWithUnsavedChanges === element.item" @click="showPageSettings(element)">
791
- <FileCog />
792
- <div class="flex flex-col">
793
- <span>Settings</span>
794
- <span v-if="edgeGlobal.edgeState.cmsPageWithUnsavedChanges === element.item" class="text-xs text-red-500">(Unsaved Changes)</span>
795
- </div>
796
- </DropdownMenuItem>
797
- <DropdownMenuItem v-if="!props.isTemplateSite && isPublishedPageDiff(element.item)" @click="publishPage(element.item)">
798
- <FileUp />
799
- Publish
800
- </DropdownMenuItem>
801
- <DropdownMenuItem @click="renameFolderOrPageShow(element)">
802
- <FilePen />
803
- <span>Rename</span>
804
- </DropdownMenuItem>
805
- <DropdownMenuSeparator />
806
- <DropdownMenuItem v-if="!props.isTemplateSite && isPublishedPageDiff(element.item) && isPublished(element.item)" @click="discardPageChanges(element.item)">
807
- <FileX />
808
- Discard Changes
809
- </DropdownMenuItem>
810
- <DropdownMenuItem v-if="!props.isTemplateSite && isPublished(element.item)" @click="unPublishPage(element.item)">
811
- <FileDown />
812
- Unpublish
813
- </DropdownMenuItem>
814
- <DropdownMenuItem class="text-destructive" @click="deletePageShow(element)">
815
- <FileMinus2 />
816
- <span>Delete</span>
817
- </DropdownMenuItem>
949
+ <template v-if="!isExternalLinkEntry(element)">
950
+ <DropdownMenuItem :disabled="edgeGlobal.edgeState.cmsPageWithUnsavedChanges === element.item" @click="showPageSettings(element)">
951
+ <FileCog />
952
+ <div class="flex flex-col">
953
+ <span>Settings</span>
954
+ <span v-if="edgeGlobal.edgeState.cmsPageWithUnsavedChanges === element.item" class="text-xs text-red-500">(Unsaved Changes)</span>
955
+ </div>
956
+ </DropdownMenuItem>
957
+ <DropdownMenuItem v-if="!props.isTemplateSite && isPublishedPageDiff(element.item)" @click="publishPage(element.item)">
958
+ <FileUp />
959
+ Publish
960
+ </DropdownMenuItem>
961
+ <DropdownMenuItem :disabled="isRenameDisabled(element)" @click="renameFolderOrPageShow({ ...element, menuName, index })">
962
+ <FilePen />
963
+ <span>Rename</span>
964
+ </DropdownMenuItem>
965
+ <DropdownMenuSeparator />
966
+ <DropdownMenuItem v-if="!props.isTemplateSite && isPublishedPageDiff(element.item) && isPublished(element.item)" @click="discardPageChanges(element.item)">
967
+ <FileX />
968
+ Discard Changes
969
+ </DropdownMenuItem>
970
+ <DropdownMenuItem v-if="!props.isTemplateSite && isPublished(element.item)" @click="unPublishPage(element.item)">
971
+ <FileDown />
972
+ Unpublish
973
+ </DropdownMenuItem>
974
+ <DropdownMenuItem class="text-destructive" :disabled="isDeleteDisabled(element)" @click="deletePageShow({ ...element, menuName, index })">
975
+ <FileMinus2 />
976
+ <span>Delete</span>
977
+ </DropdownMenuItem>
978
+ </template>
979
+ <template v-else>
980
+ <DropdownMenuItem @click="editLinkShow(menuName, index, element)">
981
+ <Link />
982
+ <span>Edit Link</span>
983
+ </DropdownMenuItem>
984
+ <DropdownMenuItem @click="renameFolderOrPageShow({ ...element, menuName, index })">
985
+ <FilePen />
986
+ <span>Rename</span>
987
+ </DropdownMenuItem>
988
+ <DropdownMenuSeparator />
989
+ <DropdownMenuItem class="text-destructive" @click="deletePageShow({ ...element, menuName, index })">
990
+ <FileMinus2 />
991
+ <span>Delete</span>
992
+ </DropdownMenuItem>
993
+ </template>
818
994
  </DropdownMenuContent>
819
995
  </DropdownMenu>
820
996
  </div>
@@ -831,6 +1007,7 @@ const theme = computed(() => {
831
1007
  <DialogHeader>
832
1008
  <DialogTitle class="text-left">
833
1009
  <span v-if="state.deletePage.item === ''">Delete Folder "{{ state.deletePage.name }}"</span>
1010
+ <span v-else-if="isExternalLinkEntry(state.deletePage)">Delete Link "{{ state.deletePage.name }}"</span>
834
1011
  <span v-else>Delete Page "{{ state.deletePage.name }}"</span>
835
1012
  </DialogTitle>
836
1013
  <DialogDescription />
@@ -847,7 +1024,9 @@ const theme = computed(() => {
847
1024
  <edge-shad-button
848
1025
  variant="destructive" class="text-white w-full" @click="deletePageAction()"
849
1026
  >
850
- Delete Page
1027
+ <span v-if="state.deletePage.item === ''">Delete Folder</span>
1028
+ <span v-else-if="isExternalLinkEntry(state.deletePage)">Delete Link</span>
1029
+ <span v-else>Delete Page</span>
851
1030
  </edge-shad-button>
852
1031
  </DialogFooter>
853
1032
  </DialogContent>
@@ -962,6 +1141,32 @@ const theme = computed(() => {
962
1141
  </edge-shad-form>
963
1142
  </DialogContent>
964
1143
  </edge-shad-dialog>
1144
+ <edge-shad-dialog v-model="state.addLinkDialog">
1145
+ <DialogContent class="pt-10">
1146
+ <edge-shad-form :schema="linkDialogSchema" @submit="submitLinkDialog">
1147
+ <DialogHeader>
1148
+ <DialogTitle class="text-left">
1149
+ <span v-if="state.linkDialogMode === 'edit'">Edit Link</span>
1150
+ <span v-else>Add link to "{{ state.linkTargetMenu }}"</span>
1151
+ </DialogTitle>
1152
+ <DialogDescription />
1153
+ </DialogHeader>
1154
+ <div class="space-y-4">
1155
+ <edge-shad-input v-model="state.linkName" name="name" label="Label" placeholder="Link label" />
1156
+ <edge-shad-input v-model="state.linkUrl" name="url" label="URL" placeholder="https://example.com or tel:123-456-7890" />
1157
+ </div>
1158
+ <DialogFooter class="pt-2 flex justify-between">
1159
+ <edge-shad-button type="button" variant="destructive" @click="state.addLinkDialog = false">
1160
+ Cancel
1161
+ </edge-shad-button>
1162
+ <edge-shad-button type="submit" class="text-white bg-slate-800 hover:bg-slate-400 w-full">
1163
+ <span v-if="state.linkDialogMode === 'edit'">Update Link</span>
1164
+ <span v-else>Add Link</span>
1165
+ </edge-shad-button>
1166
+ </DialogFooter>
1167
+ </edge-shad-form>
1168
+ </DialogContent>
1169
+ </edge-shad-dialog>
965
1170
  <edge-shad-dialog
966
1171
  v-model="state.renameFolderOrPageDialog"
967
1172
  >
@@ -975,6 +1180,12 @@ const theme = computed(() => {
975
1180
  <DialogDescription />
976
1181
  </DialogHeader>
977
1182
  <edge-shad-input v-model="state.renameItem.name" name="name" placeholder="New Name" />
1183
+ <p
1184
+ v-if="state.renameItem.item !== ''"
1185
+ class="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs font-medium text-red-700"
1186
+ >
1187
+ Renaming a page changes its URL. If search engines already indexed the old URL, rankings may drop temporarily.
1188
+ </p>
978
1189
  <DialogFooter class="pt-2 flex justify-between">
979
1190
  <edge-shad-button variant="destructive" @click="state.renameFolderOrPageDialog = false">
980
1191
  Cancel
@@ -1024,7 +1235,7 @@ const theme = computed(() => {
1024
1235
  :allow-additions="true"
1025
1236
  />
1026
1237
  <edge-shad-select-tags
1027
- v-if="props.themeOptions.length"
1238
+ v-if="props.isTemplateSite && props.themeOptions.length"
1028
1239
  :model-value="Array.isArray(slotProps.workingDoc.allowedThemes) ? slotProps.workingDoc.allowedThemes : []"
1029
1240
  name="allowedThemes"
1030
1241
  label="Allowed Themes"