Skip to content

Commit 1e52742

Browse files
committed
Add basic UI for default content type selection
Extract onboarding and editProject flows into separate modules, as they will grow. Inside editProject, right away prompt this new dialog popup if no contentTypes are found in the project. It's a percepted next step of the onboarding flow. Some default contentTypes are hardcoded.
1 parent 6b57ee5 commit 1e52742

4 files changed

Lines changed: 136 additions & 26 deletions

File tree

src/cms/server/public/app.js

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import api from './api.js'
2-
import { setIframeSrc } from './common.js'
2+
import onboarding from './app/onboarding.js'
3+
import editProject from './app/editProject.js'
34

45
const findMostRecentProject = async () => {
56
console.log('checking workspace')
@@ -16,31 +17,6 @@ const findMostRecentProject = async () => {
1617
return workspace.projects[0]
1718
}
1819

19-
const onboarding = async () => {
20-
console.log('first time onboarding')
21-
const newProject = await api.workspace.createProject({
22-
name: prompt('Project name')
23-
})
24-
return editProject({
25-
ssgOptions: {
26-
rootDirectory: newProject.path
27-
}
28-
})
29-
}
30-
31-
const editProject = async ({ ssgOptions }) => {
32-
console.log('starting editor with ssgOptions', ssgOptions)
33-
await api.ssg.watch(ssgOptions)
34-
setIframeSrc()
35-
36-
const contentTypes = await api.contentTypes.get()
37-
if (contentTypes.length) {
38-
console.log('contentTypes', contentTypes)
39-
} else {
40-
console.log('no contentTypes')
41-
}
42-
}
43-
4420
window.addEventListener('DOMContentLoaded', async () => {
4521
const ssgOptions = await api.ssgOptions.get()
4622
if (ssgOptions.rootDirectory) {

src/cms/server/public/app/components/dialog.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ const dialog = {
2626

2727
show() {
2828
this.$el.showModal()
29+
},
30+
31+
hide() {
32+
this.$el.close()
2933
}
3034
}
3135

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import api from '../api.js'
2+
import { setIframeSrc } from '../common.js'
3+
import dialog from './components/dialog.js'
4+
5+
const defaultContentTypes = [{
6+
name: 'Homepage',
7+
model: 'homepage',
8+
description: 'A generic landing page',
9+
attributes: {
10+
title: 'title',
11+
description: 'text',
12+
content: 'content'
13+
}
14+
}, {
15+
name: 'Subpage',
16+
model: 'subpage',
17+
description: 'A generic subpage',
18+
attributes: {
19+
title: 'title',
20+
description: 'text',
21+
content: 'content'
22+
}
23+
}, {
24+
name: 'Blog',
25+
model: 'collection',
26+
description: 'A collection of blog posts',
27+
facets: ['tags', 'date', 'author'],
28+
collectionAlias: 'blog',
29+
categoryContentType: '',
30+
categoryAlias: '',
31+
categoriesAlias: '',
32+
entryContentType: 'BlogPost',
33+
entryAlias: 'post',
34+
entriesAlias: 'posts',
35+
attributes: {
36+
title: 'title',
37+
description: 'text',
38+
content: 'content'
39+
}
40+
}, {
41+
name: 'Category',
42+
model: 'category',
43+
description: 'A group of entries in a collection',
44+
attributes: {
45+
title: 'title',
46+
description: 'text',
47+
content: 'content'
48+
}
49+
}, {
50+
name: 'BlogPost',
51+
model: 'entry',
52+
description: 'Article in a blog',
53+
attributes: {
54+
title: 'title',
55+
tags: 'strings',
56+
author: 'Person',
57+
date: 'date',
58+
summary: 'text',
59+
content: 'content',
60+
coverImage: 'imageAttachment'
61+
}
62+
}, {
63+
name: 'Person',
64+
model: 'entry',
65+
description: 'A person',
66+
attributes: {
67+
title: 'title',
68+
email: 'email',
69+
bio: 'text',
70+
blogPosts: ['+BlogPost:author']
71+
}
72+
}]
73+
74+
const editProject = async ({ ssgOptions }) => {
75+
console.log('starting editor with ssgOptions', ssgOptions)
76+
await api.ssg.watch(ssgOptions)
77+
setIframeSrc()
78+
79+
const contentTypes = await api.contentTypes.get()
80+
if (contentTypes.length) {
81+
return console.log('contentTypes', contentTypes)
82+
}
83+
console.log('no contentTypes')
84+
85+
dialog.html(
86+
87+
`<h1>content types</h1>
88+
89+
<form>
90+
${defaultContentTypes.map(contentType => `
91+
<label><input type="checkbox" name="${contentType.name}">${contentType.name}</label>
92+
`
93+
).join('')}
94+
95+
<button>Ok</button>
96+
</form>`
97+
).show()
98+
99+
const form = dialog.find('form')
100+
form.addEventListener('submit', e => {
101+
const formData = new FormData(form)
102+
const keyValues = Array.from(formData.entries())
103+
const selectedKeys = keyValues.filter(([key, value]) => value === 'on').map(([key]) => key)
104+
const selectedContentTypes = defaultContentTypes.filter(ct => selectedKeys.includes(ct.name))
105+
console.log('selectedContentTypes', selectedContentTypes)
106+
e.preventDefault()
107+
selectedContentTypes.forEach(async contentType => {
108+
await api.contentTypes.create(contentType)
109+
})
110+
dialog.hide()
111+
})
112+
}
113+
114+
export default editProject
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import api from '../api.js'
2+
import editProject from './editProject.js'
3+
4+
const onboarding = async () => {
5+
console.log('first time onboarding')
6+
const newProject = await api.workspace.createProject({
7+
name: prompt('Project name')
8+
})
9+
return editProject({
10+
ssgOptions: {
11+
rootDirectory: newProject.path
12+
}
13+
})
14+
}
15+
16+
export default onboarding

0 commit comments

Comments
 (0)