Skip to content

Commit aed8a2d

Browse files
authored
feat(context): duplicate and rename (#23)
1 parent 17e13d8 commit aed8a2d

32 files changed

+1250
-586
lines changed

src/app/src/components/content/ContentEditor.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { computed, type PropType, toRaw } from 'vue'
33
import { decompressTree } from '@nuxt/content/runtime'
44
import type { MarkdownRoot } from '@nuxt/content'
5-
import type { DatabasePageItem, DraftItem } from '../../types'
5+
import { DraftStatus, type DatabasePageItem, type DraftItem } from '../../types'
66
import { useStudio } from '../../composables/useStudio'
77
88
const props = defineProps({
@@ -25,10 +25,13 @@ const document = computed<DatabasePageItem>({
2525
return {} as DatabasePageItem
2626
}
2727
28+
if (props.draftItem.status === DraftStatus.Deleted) {
29+
return props.draftItem.original as DatabasePageItem
30+
}
31+
2832
const dbItem = props.draftItem.modified as DatabasePageItem
2933
3034
let result: DatabasePageItem
31-
// TODO: check mdcRoot and markdownRoot types with Ahad
3235
if (dbItem.body?.type === 'minimark') {
3336
result = {
3437
...props.draftItem.modified as DatabasePageItem,

src/app/src/components/shared/item/ItemActionsDropdown.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { computeActionItems, computeActionParams } from '../../../utils/context'
2+
import { computeActionItems } from '../../../utils/context'
33
import { computed, type PropType } from 'vue'
44
import type { TreeItem } from '../../../types'
55
import { useStudio } from '../../../composables/useStudio'
@@ -17,7 +17,7 @@ const props = defineProps({
1717
const actions = computed<DropdownMenuItem[]>(() => {
1818
return computeActionItems(context.itemActions.value, props.item).map(action => ({
1919
...action,
20-
onSelect: () => action.handler?.(computeActionParams(action.id, { item: props.item })),
20+
onSelect: () => action.handler!(props.item),
2121
}))
2222
})
2323
</script>

src/app/src/components/shared/item/ItemActionsToolbar.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useStudio } from '../../../composables/useStudio'
55
66
const { context } = useStudio()
77
8-
const item = computed(() => context.featureTree.value.currentItem.value)
8+
const item = computed(() => context.activeTree.value.currentItem.value)
99
const actions = computed(() => {
1010
return computeActionItems(context.itemActions.value, item.value)
1111
})
@@ -24,7 +24,7 @@ const actions = computed(() => {
2424
size="sm"
2525
color="neutral"
2626
variant="ghost"
27-
@click="action.handler!(item.id)"
27+
@click="action.handler!(item)"
2828
/>
2929
</UTooltip>
3030
</div>

src/app/src/components/shared/item/ItemBadge.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<script setup lang="ts">
2-
import { COLOR_UI_STATUS_MAP } from '../../../utils/draft'
3-
import type { DraftStatus } from '../../../types/draft'
2+
import { COLOR_UI_STATUS_MAP } from '../../../utils/tree'
3+
import type { TreeStatus } from '../../../types'
44
import type { PropType } from 'vue'
55
66
defineProps({
77
status: {
8-
type: String as PropType<DraftStatus>,
8+
type: String as PropType<TreeStatus>,
99
required: true,
1010
},
1111
})

src/app/src/components/shared/item/ItemBreadcrumb.vue

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@
22
import type { BreadcrumbItem } from '@nuxt/ui/components/Breadcrumb.vue.d.ts'
33
import type { DropdownMenuItem } from '@nuxt/ui/components/DropdownMenu.vue.d.ts'
44
import { computed, unref } from 'vue'
5-
import type { TreeItem } from '../../../types'
5+
import { type TreeItem, TreeStatus } from '../../../types'
66
import { useStudio } from '../../../composables/useStudio'
77
import { findParentFromId, ROOT_ITEM } from '../../../utils/tree'
8-
import { DraftStatus } from '../../../types/draft'
98
109
const { context } = useStudio()
1110
12-
const currentItem = computed(() => context.featureTree.value.currentItem.value)
13-
const tree = computed(() => context.featureTree.value.root.value)
11+
const currentItem = computed(() => context.activeTree.value.currentItem.value)
12+
const tree = computed(() => context.activeTree.value.root.value)
1413
1514
const items = computed<BreadcrumbItem[]>(() => {
1615
const rootItem = {
1716
icon: 'i-lucide-folder-git',
1817
onClick: () => {
1918
// TODO: update for ROOT_DOCUMENT_ITEM and ROOT_MEDIA_ITEM
20-
context.featureTree.value.select(ROOT_ITEM)
19+
context.activeTree.value.select(ROOT_ITEM)
2120
},
2221
}
2322
@@ -33,7 +32,7 @@ const items = computed<BreadcrumbItem[]>(() => {
3332
breadcrumbItems.unshift({
3433
label: currentTreeItem.name,
3534
onClick: async () => {
36-
await context.featureTree.value.select(itemToSelect)
35+
await context.activeTree.value.select(itemToSelect)
3736
},
3837
})
3938
@@ -87,7 +86,7 @@ const items = computed<BreadcrumbItem[]>(() => {
8786
</template>
8887
</UBreadcrumb>
8988
<ItemBadge
90-
v-if="currentItem.status && currentItem.status !== DraftStatus.Opened"
89+
v-if="currentItem.status && currentItem.status !== TreeStatus.Opened"
9190
:status="currentItem.status"
9291
/>
9392
</div>

src/app/src/components/shared/item/ItemCard.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<script setup lang="ts">
2-
import type { TreeItem } from '../../../types'
2+
import { TreeStatus, type TreeItem } from '../../../types'
33
import type { PropType } from 'vue'
44
import { computed } from 'vue'
55
import { Image } from '@unpic/vue'
66
import { titleCase } from 'scule'
7-
import { COLOR_UI_STATUS_MAP } from '../../../utils/draft'
7+
import { COLOR_UI_STATUS_MAP } from '../../../utils/tree'
88
import { DraftStatus } from '../../../types/draft'
99
1010
const props = defineProps({

src/app/src/components/shared/item/ItemCardForm.vue

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { computed, reactive, type PropType } from 'vue'
33
import { Image } from '@unpic/vue'
44
import * as z from 'zod'
55
import type { FormSubmitEvent } from '@nuxt/ui'
6-
import { type StudioAction, type TreeItem, ContentFileExtension } from '../../../types'
6+
import { type CreateFileParams, type CreateFolderParams, type RenameFileParams, type StudioAction, type TreeItem, ContentFileExtension } from '../../../types'
77
import { joinURL, withLeadingSlash } from 'ufo'
88
import { contentFileExtensions } from '../../../utils/content'
99
import { useStudio } from '../../../composables/useStudio'
@@ -14,15 +14,22 @@ const { context } = useStudio()
1414
1515
const props = defineProps({
1616
actionId: {
17-
type: String as PropType<StudioItemActionId>,
17+
type: String as PropType<StudioItemActionId.CreateDocument | StudioItemActionId.CreateFolder | StudioItemActionId.RenameItem>,
1818
required: true,
1919
},
2020
parentItem: {
2121
type: Object as PropType<TreeItem>,
2222
required: true,
2323
},
24+
renamedItem: {
25+
type: Object as PropType<TreeItem>,
26+
default: null,
27+
},
2428
})
2529
30+
const originalName = computed(() => props.renamedItem?.name || '')
31+
const originalExtension = computed(() => props.renamedItem?.id.split('.').pop() as ContentFileExtension || ContentFileExtension.Markdown)
32+
2633
const schema = z.object({
2734
name: z.string()
2835
.min(1, 'Name cannot be empty')
@@ -33,8 +40,8 @@ const schema = z.object({
3340
3441
type Schema = z.output<typeof schema>
3542
const state = reactive<Schema>({
36-
name: '',
37-
extension: ContentFileExtension.Markdown,
43+
name: originalName.value,
44+
extension: originalExtension.value,
3845
})
3946
4047
const action = computed<StudioAction>(() => {
@@ -69,11 +76,29 @@ const tooltipText = computed(() => {
6976
function onSubmit(_event: FormSubmitEvent<Schema>) {
7077
const fsPath = joinURL(props.parentItem.fsPath, `${state.name}.${state.extension}`)
7178
72-
action.value.handler!({
73-
routePath: routePath.value,
74-
fsPath,
75-
content: `New ${state.name} file`,
76-
})
79+
let params: CreateFileParams | CreateFolderParams | RenameFileParams
80+
switch (props.actionId) {
81+
case StudioItemActionId.CreateDocument:
82+
params = {
83+
routePath: routePath.value,
84+
fsPath,
85+
content: `New ${state.name} file`,
86+
}
87+
break
88+
case StudioItemActionId.CreateFolder:
89+
params = {
90+
fsPath,
91+
}
92+
break
93+
case StudioItemActionId.RenameItem:
94+
params = {
95+
id: props.renamedItem.id,
96+
newFsPath: joinURL(props.parentItem.fsPath, `${state.name}.${state.extension}`),
97+
}
98+
break
99+
}
100+
101+
action.value.handler!(params)
77102
}
78103
</script>
79104

src/app/src/components/shared/item/ItemTree.vue

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
import type { TreeItem } from '../../../types'
33
import type { PropType } from 'vue'
44
import { useStudio } from '../../../composables/useStudio'
5+
import { computed } from 'vue'
56
67
const { context } = useStudio()
78
8-
defineProps({
9+
const props = defineProps({
910
type: {
1011
type: String as PropType<'directory' | 'file'>,
1112
required: true,
@@ -14,11 +15,17 @@ defineProps({
1415
type: Array as PropType<TreeItem[]>,
1516
default: () => [],
1617
},
17-
showCreationForm: {
18+
showForm: {
1819
type: Boolean,
1920
default: false,
2021
},
2122
})
23+
24+
const filteredTree = computed(() => {
25+
if (!context.actionInProgress.value?.item) return props.tree
26+
27+
return props.tree.filter(item => item.id !== context.actionInProgress.value!.item?.id)
28+
})
2229
</script>
2330

2431
<template>
@@ -27,19 +34,20 @@ defineProps({
2734
ref="container"
2835
class="grid grid-cols-1 @sm:grid-cols-2 @xl:grid-cols-3 @4xl:grid-cols-4 @7xl:grid-cols-6 gap-2"
2936
>
30-
<li v-if="showCreationForm">
37+
<li v-if="showForm">
3138
<ItemCardForm
32-
:parent-item="context.featureTree.value.currentItem.value"
33-
:action-id="context.actionInProgress.value!"
39+
:parent-item="context.activeTree.value.currentItem.value"
40+
:action-id="context.actionInProgress.value!.id as never"
41+
:renamed-item="context.actionInProgress.value!.item"
3442
/>
3543
</li>
3644
<li
37-
v-for="(item, index) in tree"
45+
v-for="(item, index) in filteredTree"
3846
:key="`${item.id}-${index}`"
3947
>
4048
<ItemCard
4149
:item="item"
42-
@click="context.featureTree.value.select(item)"
50+
@click="context.activeTree.value.select(item)"
4351
/>
4452
</li>
4553
</ul>

0 commit comments

Comments
 (0)