browsing, adding, removing fileders in inspector
s-ol
3 years ago
93 | 93 | convert 'text/mermaid-graph', 'text/html', debugger\render!, fileder, facet.name |
94 | 94 | |
95 | 95 | handle: (method, path, facet, value) => |
96 | fileder = Fileder @store, path | |
97 | ||
98 | if not fileder | |
99 | -- fileder not found | |
100 | 404, "fileder '#{path}' not found" | |
101 | ||
102 | 96 | if not @flags.rw and method != 'GET' and method != 'HEAD' |
103 | 97 | return 403, 'editing not allowed' |
104 | 98 | |
105 | 99 | switch method |
106 | 100 | when 'GET', 'HEAD' |
101 | fileder = Fileder @store, path | |
102 | if not fileder | |
103 | -- fileder not found | |
104 | return 404, "fileder '#{path}' not found" | |
105 | ||
107 | 106 | val = switch facet.name |
108 | 107 | when '?index', '?tree' |
109 | 108 | -- serve fileder index |
128 | 127 | else |
129 | 128 | 406, "cant convert facet '#{facet.name}' to '#{facet.type}'" |
130 | 129 | when 'POST' |
131 | @store\create_facet path, facet.name, facet.type, value | |
132 | 200, 'ok' | |
130 | if facet | |
131 | @store\create_facet path, facet.name, facet.type, value | |
132 | 200, 'ok' | |
133 | else | |
134 | 200, @store\create_fileder dir_base path | |
133 | 135 | when 'PUT' |
134 | @store\update_facet path, facet.name, facet.type, value | |
135 | 200, 'ok' | |
136 | if facet | |
137 | @store\update_facet path, facet.name, facet.type, value | |
138 | 200, 'ok' | |
139 | else | |
140 | 501, "not implemented" | |
136 | 141 | when 'DELETE' |
137 | @store\remove_facet path, facet.name, facet.type | |
142 | if facet | |
143 | @store\remove_facet path, facet.name, facet.type | |
144 | else | |
145 | @store\remove_fileder path | |
138 | 146 | 200, 'ok' |
139 | 147 | else |
140 | 148 | 501, "not implemented" |
150 | 158 | path_facet or= path |
151 | 159 | path, facet = path_facet\match '(.*)/([^/]*)' |
152 | 160 | |
153 | type or= 'text/html+interactive' | |
154 | type = type\match '%s*(.*)' | |
155 | facet = Key facet, type | |
161 | facet = if facet == '' and method ~= 'GET' and method ~= 'HEAD' | |
162 | nil | |
163 | else | |
164 | type or= 'text/html+interactive' | |
165 | type = type\match '%s*(.*)' | |
166 | Key facet, type | |
156 | 167 | |
157 | 168 | value = stream\get_body_as_string! |
158 | 169 | ok, status, body = xpcall @.handle, err_and_trace, @, method, path, facet, value |
1 | 1 | import Key from require '.fileder' |
2 | 2 | import get_conversions, apply_conversions from require '.conversion' |
3 | 3 | import ReactiveVar, get_or_create, text, elements, tohtml from require 'mmm.component' |
4 | import pre, div, nav, span, button, a, code, option from elements | |
4 | import pre, div, nav, span, button, a, code, select, option from elements | |
5 | import link_to from (require '.util') elements | |
5 | 6 | import languages from require 'mmm.highlighting' |
6 | 7 | |
7 | 8 | keep = (var) -> |
165 | 166 | |
166 | 167 | -- rerender main content |
167 | 168 | refresh: (facet=@facet\get!) => |
168 | @content\set @get_content facet | |
169 | if facet == true -- deep refresh | |
170 | @fileder\transform (i) -> i | |
171 | else | |
172 | @content\set @get_content facet | |
169 | 173 | |
170 | 174 | -- render #browser-content |
171 | 175 | get_content: (prop, err=@error, convert=default_convert) => |
219 | 223 | return if facet == '' |
220 | 224 | @inspect_prop\set Key facet |
221 | 225 | |
222 | with elements.select :onchange | |
223 | \append option '(none)', value: '', disabled: true, selected: not value | |
226 | with select :onchange \append option '(none)', value: '', disabled: true, selected: not value | |
224 | 227 | if fileder |
225 | 228 | for value in pairs fileder.facet_keys |
226 | 229 | \append option value, :value, selected: value == current |
229 | 232 | if window\confirm "continuing will permanently remove the facet '#{@inspect_prop\get!}'." |
230 | 233 | fileder = @fileder\get! |
231 | 234 | fileder\set @inspect_prop\get!, nil |
232 | @fileder\set fileder -- trigger re-selection of active facet & inspector | |
235 | @refresh true | |
233 | 236 | |
234 | 237 | button 'add', class: 'tight', onclick: (_, e) -> |
235 | 238 | facet = window\prompt "please enter the facet string ('name: type' or 'type'):", 'text/markdown' |
254 | 257 | assert conversions, "cannot cast '#{key.type}'" |
255 | 258 | apply_conversions conversions, value, @, prop |
256 | 259 | |
260 | \append nav { | |
261 | span 'children' | |
262 | button 'add', onclick: (_, e) -> | |
263 | name = window\prompt "please enter the name of the child fileder:", 'unnamed_fileder' | |
264 | return if not name or name == '' or name == js.null | |
265 | child = @fileder\get!\add_child name | |
266 | @refresh true | |
267 | } | |
268 | \append @fileder\map (fileder) -> | |
269 | with div class: 'children' | |
270 | num = #fileder.children | |
271 | for i, child in ipairs fileder.children | |
272 | name = child\gett 'name: alpha' | |
273 | \append div { | |
274 | style: | |
275 | display: 'flex' | |
276 | 'justify-content': 'space-between' | |
277 | ||
278 | span '- ', (link_to child, code name), style: flex: 1 | |
279 | ||
280 | button '↑', disabled: i == 1, onclick: (_, e) -> | |
281 | fileder\reorder_child name, i - 1 | |
282 | @refresh true | |
283 | ||
284 | button '↓', disabled: i == num, onclick: (_, e) -> | |
285 | fileder\reorder_child name, i + 1 | |
286 | @refresh true | |
287 | ||
288 | button 'rm', onclick: (_, e) -> | |
289 | if window\confirm "continuing will permanently remove all content in '#{child.path}'." | |
290 | fileder\remove_child i | |
291 | @refresh true | |
292 | } | |
293 | ||
294 | ||
257 | 295 | default_convert = (key) => @get key.name, 'mmm/dom' |
258 | 296 | |
259 | 297 | navigate: (new) => |
305 | 305 | |
306 | 306 | @facets[key] = value |
307 | 307 | |
308 | -- add a child fileder with given name | |
309 | add_child: (name) => | |
310 | new_path = @store\create_fileder @path, name | |
311 | with new_child = Fileder @store, new_path | |
312 | table.insert @children, new_child | |
313 | ||
314 | -- remove a child with given index | |
315 | remove_child: (i) => | |
316 | removed = table.remove @children, i | |
317 | assert removed, "no such child fileder" | |
318 | @store\remove_fileder removed.path | |
319 | ||
308 | 320 | __tostring: => "Fileder:#{@path}" |
309 | 321 | |
310 | 322 | { |
49 | 49 | coroutine.yield path |
50 | 50 | |
51 | 51 | create_fileder: (parent, name) => |
52 | path = "#{parent}/#{name}" | |
52 | 53 | @log "creating fileder #{path}" |
53 | path = "#{parent}/#{name}" | |
54 | 54 | assert lfs.mkdir @root .. path |
55 | 55 | path |
56 | 56 |
60 | 60 | coroutine.yield child.path |
61 | 61 | |
62 | 62 | create_fileder: (parent, name) => |
63 | path = "#{parent}/#{name}" | |
63 | 64 | @log "creating fileder #{path}" |
64 | error "not implemented" | |
65 | req 'POST', "#{@host .. path}/" | |
65 | 66 | |
66 | 67 | remove_fileder: (path) => |
67 | 68 | @log "removing fileder #{path}" |
68 | error "not implemented" | |
69 | req 'DELETE', "#{@host .. path}/" | |
69 | 70 | |
70 | 71 | rename_fileder: (path, next_name) => |
71 | 72 | @log "renaming fileder #{path} -> '#{next_name}'" |