• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

scriptype / writ-cms / 22203879000

19 Feb 2026 11:06PM UTC coverage: 38.437% (-0.1%) from 38.574%
22203879000

push

github

scriptype
Draft a proto-layout for contentType selection

List of types and a visualisation of current ontology is imagined. The
former is hereby attempted, and the latter needs more think

618 of 3672 branches covered (16.83%)

Branch coverage included in aggregate %.

0 of 8 new or added lines in 2 files covered. (0.0%)

21 existing lines in 1 file now uncovered.

2166 of 3571 relevant lines covered (60.66%)

1169.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/cms/server/public/app/explorePanel/createContentType.js
1
import api from '../../api.js'
2
import dialog from '../components/dialog.js'
3

4
const modelConfigs = {
×
5
  homepage: [],
6
  subpage: [],
7
  collection: [
8
    'collectionAlias',
9
    'categoryContentType',
10
    'categoryAlias',
11
    'categoriesAlias',
12
    'entryContentType',
13
    'entryAlias',
14
    'entriesAlias',
15
    'facets'
16
  ],
17
  category: [
18
    'categoryAlias',
19
    'categoriesAlias',
20
    'entryContentType',
21
    'entryAlias',
22
    'entriesAlias'
23
  ],
24
  entry: []
25
}
26

27
export default async () => {
28
  dialog.html(`
×
29
<pre>
30
<form>
31
  <label>
32
    Name:
33
    <input type="text" required name="name">
34
  </label>
35
  <label>
36
    Description:
37
    <input type="text" name="description">
38
  </label>
39
  <label>
40
    Model:
41
    <select name="model">
42
      <option value=""></option>
43
      <option value="homepage">homepage</option>
44
      <option value="subpage">subpage</option>
45
      <option value="collection">collection</option>
46
      <option value="category">category</option>
47
      <option value="entry">entry</option>
48
    </select>
49
  </label>
50
  <div id="model-config"></div>
51
  <fieldset>
52
    <legend>Attributes</legend>
53
    <label>
54
      attr1 name:
55
      <input type="text" name="attribute-1-name"></input>
56
    </label>
57
    <label>
58
      attr1 type:
59
      <input type="text" name="attribute-1-type"></input>
60
    </label>
61

62
    <label>
63
      attr2 name:
64
      <input type="text" name="attribute-2-name"></input>
65
    </label>
66
    <label>
67
      attr2 type:
68
      <input type="text" name="attribute-2-type"></input>
69
    </label>
70

71
    <label>
72
      attr3 name:
73
      <input type="text" name="attribute-3-name"></input>
74
    </label>
75
    <label>
76
      attr3 type:
77
      <input type="text" name="attribute-3-type"></input>
78
    </label>
79

80
    <label>
81
      attr4 name:
82
      <input type="text" name="attribute-4-name"></input>
83
    </label>
84
    <label>
85
      attr4 type:
86
      <input type="text" name="attribute-4-type"></input>
87
    </label>
88

89
    <label>
90
      attr5 name:
91
      <input type="text" name="attribute-5-name"></input>
92
    </label>
93
    <label>
94
      attr5 type:
95
      <input type="text" name="attribute-5-type"></input>
96
    </label>
97
  </fieldset>
98

99
  <button type="submit">Create</button>
100
</form>
101
</pre>`).show()
102

UNCOV
103
  const form = dialog.find('form')
×
104

105
  const nameInput = dialog.find('input[name=name]')
×
106
  const modelSelect = dialog.find('select[name=model]')
×
107
  const modelConfigContainer = dialog.find('#model-config')
×
UNCOV
108
  const submitButton = dialog.find('button[type=submit]')
×
109

110
  const validate = () => {
×
111
    if (!modelSelect.value) {
×
UNCOV
112
      return false
×
113
    }
114

115
    if (!nameInput.value) {
×
UNCOV
116
      return false
×
117
    }
118

UNCOV
119
    return true
×
120
  }
121

122
  nameInput.addEventListener('input', () => {
×
UNCOV
123
    submitButton.toggleAttribute('disabled', !validate())
×
124
  })
125

126
  modelSelect.addEventListener('change', () => {
×
UNCOV
127
    submitButton.toggleAttribute('disabled', !validate())
×
128

129
    const modelConfig = modelConfigs[modelSelect.value]
×
130
    const modelConfigInputs = modelConfig.map(configName => (
×
UNCOV
131
  `<label>
×
132
    ${configName}:
133
    <input type="text" name="${configName}"></input>
134
  </label>`)).join('')
UNCOV
135
    modelConfigContainer.innerHTML = modelConfigInputs.length ? (
×
136
  `<fieldset>
137
    <legend>Model configuration</legend>
138
    ${modelConfigInputs}
139
  </fieldset>`
140
    ) : ''
141
  })
142

UNCOV
143
  submitButton.toggleAttribute('disabled', !validate())
×
144

145
  form.addEventListener('submit', async (e) => {
×
146
    e.preventDefault()
×
147
    const formData = new FormData(form)
×
UNCOV
148
    const nonEmptyData = Object.fromEntries(
×
149
      Array
150
        .from(formData.entries())
151
        .filter(([key, value]) => value !== '')
×
UNCOV
152
        .filter(([key]) => !key.match(/attribute-\d/))
×
153
        .map(([key, value]) => {
154
          if (key.startsWith('[') && key.endsWith(']')) {
×
UNCOV
155
            return [key, value.split(',').map(v => v.trim())]
×
156
          }
UNCOV
157
          return [ key, value ]
×
158
        })
159
    )
UNCOV
160
    nonEmptyData.attributes = [{
×
161
      name: form.querySelector('[name=attribute-1-name]').value,
162
      type: form.querySelector('[name=attribute-1-type]').value
163
    }, {
164
      name: form.querySelector('[name=attribute-2-name]').value,
165
      type: form.querySelector('[name=attribute-2-type]').value
166
    }, {
167
      name: form.querySelector('[name=attribute-3-name]').value,
168
      type: form.querySelector('[name=attribute-3-type]').value
169
    }, {
170
      name: form.querySelector('[name=attribute-4-name]').value,
171
      type: form.querySelector('[name=attribute-4-type]').value
172
    }, {
173
      name: form.querySelector('[name=attribute-5-name]').value,
174
      type: form.querySelector('[name=attribute-5-type]').value
175
    }]
UNCOV
176
      .filter(({ name, type}) => name && type)
×
177
      .map(({ name, type }) => {
178
        if (type.startsWith('[') && type.endsWith(']')) {
×
UNCOV
179
          return {
×
180
            name,
UNCOV
181
            type: type.slice(1, -1).split(',').map(v => v.trim())
×
182
          }
183
        }
UNCOV
184
        return { name, type}
×
185
      })
186
      .reduce((acc, { name, type }) => {
UNCOV
187
        return {
×
188
          ...acc,
189
          [name]: type
190
        }
191
      }, {})
192
    console.log('creating contentType', nonEmptyData)
×
UNCOV
193
    await api.contentTypes.create(nonEmptyData)
×
194
  })
195
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc