update
parent
3931d30181
commit
829e7637ca
|
@ -1,5 +1,5 @@
|
||||||
dist
|
dist
|
||||||
node_modules
|
node_modules
|
||||||
.parcel-cache
|
.parcel-cache
|
||||||
public/css/main.css*
|
public/css/main.css.map
|
||||||
public/js/main.js*
|
public/js/main.js*
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -4,13 +4,20 @@
|
||||||
|
|
||||||
* download files #26
|
* download files #26
|
||||||
* add goto last line toolbar #21
|
* add goto last line toolbar #21
|
||||||
* use parcel to load main.js
|
|
||||||
* use icons
|
* use icons
|
||||||
|
* bind ctrl-s (cmd-s) to fileSave
|
||||||
|
* refactor as lib #15
|
||||||
|
* Set Title to be changeable #24
|
||||||
|
* show run result below #33
|
||||||
|
* set font size #31
|
||||||
|
* Hide Config zone for other usage such as go playground #23
|
||||||
|
|
||||||
## Fix
|
## Fix
|
||||||
|
|
||||||
* all cmds should be pass straight back to user
|
* all cmd output should be pass straight back to user
|
||||||
* timeout on none ending cmds #34
|
* timeout on none ending cmd #34
|
||||||
|
* add sys setting to conf #32
|
||||||
|
* Apply should save before taking action #19
|
||||||
|
|
||||||
# 0.1.1
|
# 0.1.1
|
||||||
|
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -23,10 +23,10 @@ run: build
|
||||||
.PHONY: web
|
.PHONY: web
|
||||||
web:
|
web:
|
||||||
npm run build
|
npm run build
|
||||||
npm run js-dev
|
# npm run js-dev
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: web
|
build:
|
||||||
go build ${LDFLAGS} -o dist/${PROJ} cmd/$(PROJ)/main.go
|
go build ${LDFLAGS} -o dist/${PROJ} cmd/$(PROJ)/main.go
|
||||||
|
|
||||||
|
|
||||||
|
|
5
app.go
5
app.go
|
@ -28,7 +28,10 @@ type Page struct {
|
||||||
Error string
|
Error string
|
||||||
File ActiveFile
|
File ActiveFile
|
||||||
Editor Editor
|
Editor Editor
|
||||||
|
|
||||||
Static bool
|
Static bool
|
||||||
|
HideConfig bool
|
||||||
|
ResultBellow bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -63,6 +66,8 @@ func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
||||||
Platform: plat,
|
Platform: plat,
|
||||||
},
|
},
|
||||||
Static: cui.NoReconfig,
|
Static: cui.NoReconfig,
|
||||||
|
HideConfig: cui.HideConfig,
|
||||||
|
ResultBellow: cui.ResultBellow,
|
||||||
}
|
}
|
||||||
|
|
||||||
content := ""
|
content := ""
|
||||||
|
|
|
@ -100,7 +100,7 @@ func main() {
|
||||||
// setup routes
|
// setup routes
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: flagBind,
|
Addr: flagBind,
|
||||||
WriteTimeout: time.Second * 3,
|
WriteTimeout: time.Second * 30,
|
||||||
ReadTimeout: time.Second * 30,
|
ReadTimeout: time.Second * 30,
|
||||||
Handler: cui,
|
Handler: cui,
|
||||||
}
|
}
|
||||||
|
|
10
configui.go
10
configui.go
|
@ -48,7 +48,15 @@ type ConfigUI struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *ConfigUI {
|
func New() *ConfigUI {
|
||||||
tmpl := template.Must(template.New("").ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
|
tmpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||||
|
"step": func(from, to, step uint) []uint {
|
||||||
|
items := []uint{}
|
||||||
|
for i := from; i <= to; i += step {
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
},
|
||||||
|
}).ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
|
||||||
return &ConfigUI{
|
return &ConfigUI{
|
||||||
fileIndex: map[string]int{},
|
fileIndex: map[string]int{},
|
||||||
AppName: "ConfigUI",
|
AppName: "ConfigUI",
|
||||||
|
|
4
file.go
4
file.go
|
@ -75,12 +75,12 @@ func (f *File) Do() (string, error) {
|
||||||
done <- string(out)
|
done <- string(out)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(10 * time.Second):
|
||||||
cmd.Process.Kill()
|
cmd.Process.Kill()
|
||||||
log.Println("timeout")
|
log.Println("timeout")
|
||||||
return "", errors.New("command timeout")
|
return "", errors.New("command timeout")
|
||||||
case out := <-done:
|
case out := <-done:
|
||||||
log.Println("\n", out)
|
log.Printf("\n%v", out)
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,7 @@
|
||||||
{{define "base/script"}}
|
{{define "base/script"}}
|
||||||
<script>
|
<script>
|
||||||
window.ToolIsFollow = false;
|
window.ToolIsFollow = false;
|
||||||
|
window.ContentChanged = false;
|
||||||
|
|
||||||
async function FileGet(follower=false){
|
async function FileGet(follower=false){
|
||||||
let f = ''
|
let f = ''
|
||||||
|
@ -37,7 +38,10 @@ async function FileSave(){
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
})
|
})
|
||||||
}).catch(err=>{console.log(err);return;});
|
}).catch(err=>{console.log(err);return;});
|
||||||
if (res.ok) window.location.reload();
|
if (res.ok) {
|
||||||
|
window.location.reload();
|
||||||
|
window.ContentChanged = false
|
||||||
|
}
|
||||||
else Catch(res)
|
else Catch(res)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -49,6 +53,7 @@ async function FileSave(){
|
||||||
})
|
})
|
||||||
}).catch(err=>{console.log(err);return;});
|
}).catch(err=>{console.log(err);return;});
|
||||||
if(!res.ok) Catch(res)
|
if(!res.ok) Catch(res)
|
||||||
|
else window.ContentChanged = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +76,25 @@ async function FileApply(){
|
||||||
}
|
}
|
||||||
|
|
||||||
async function Catch(res){
|
async function Catch(res){
|
||||||
console.trace()
|
{{/* console.trace()
|
||||||
console.log(res)
|
console.log(res) */}}
|
||||||
const msg = await res.text()
|
const msg = await res.text()
|
||||||
ShowError(msg)
|
ShowError(msg)
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setResult(){
|
||||||
|
var result_editor = ace.edit("result_editor");
|
||||||
|
window.result_editor = result_editor
|
||||||
|
result_editor.setTheme("ace/theme/monokai");
|
||||||
|
result_editor.session.setMode("ace/mode/sh");
|
||||||
|
result_editor.setReadOnly(true);
|
||||||
|
result_editor.setOptions({
|
||||||
|
maxLines: 1000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// starting point
|
// starting point
|
||||||
(function(){
|
(function(){
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,21 @@ function setEditor(){
|
||||||
editor.session.setUseWrapMode(false);
|
editor.session.setUseWrapMode(false);
|
||||||
editor.session.setNewLineMode('{{.Editor.Platform}}')
|
editor.session.setNewLineMode('{{.Editor.Platform}}')
|
||||||
editor.setReadOnly({{.File.RO}});
|
editor.setReadOnly({{.File.RO}});
|
||||||
|
|
||||||
|
editor.session.on('change', function(delta) {
|
||||||
|
// delta.start, delta.end, delta.lines, delta.action
|
||||||
|
window.ContentChanged = true
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.commands.addCommand({
|
||||||
|
name: 'SaveContent',
|
||||||
|
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
||||||
|
exec: function(editor) {
|
||||||
|
//...
|
||||||
|
FileSave()
|
||||||
|
},
|
||||||
|
readOnly: false // false if this command should not apply in readOnly mode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
|
@ -14,6 +14,7 @@
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
{{if not .HideConfig}}
|
||||||
<p class="menu-label">
|
<p class="menu-label">
|
||||||
System
|
System
|
||||||
</p>
|
</p>
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
href="/"
|
href="/"
|
||||||
>Config</a></li>
|
>Config</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{{end}}
|
||||||
</aside>
|
</aside>
|
||||||
</section>
|
</section>
|
||||||
{{end}}
|
{{end}}
|
|
@ -23,17 +23,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function setResult(){
|
|
||||||
var result_editor = ace.edit("result_editor");
|
|
||||||
window.result_editor = result_editor
|
|
||||||
result_editor.setTheme("ace/theme/monokai");
|
|
||||||
result_editor.session.setMode("ace/mode/sh");
|
|
||||||
result_editor.setReadOnly(true);
|
|
||||||
result_editor.setOptions({
|
|
||||||
maxLines: 1000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function ResultViewTog(){
|
function ResultViewTog(){
|
||||||
let el = document.getElementById('result_view')
|
let el = document.getElementById('result_view')
|
||||||
el.classList.toggle('is-active')
|
el.classList.toggle('is-active')
|
||||||
|
|
|
@ -47,6 +47,16 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<div class="select is-small">
|
||||||
|
<select onchange="toolSetFontSize(this)">
|
||||||
|
<option value="1rem">1rem</option>
|
||||||
|
{{range step 8 36 2}}
|
||||||
|
<option value="{{.}}px">{{.}}px</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -63,12 +73,14 @@
|
||||||
{{if not .File.RO}}
|
{{if not .File.RO}}
|
||||||
<p class="control">
|
<p class="control">
|
||||||
{{if eq .File.Name .AppName}}
|
{{if eq .File.Name .AppName}}
|
||||||
|
{{if not .Static}}
|
||||||
<button class="button is-small has-tooltip-arrow"
|
<button class="button is-small has-tooltip-arrow"
|
||||||
data-tooltip="Apply" onclick="toolSave()">
|
data-tooltip="Apply" onclick="toolSave()">
|
||||||
<span class="icon is-small"><span class="material-icons" id="toolSaveIco">
|
<span class="icon is-small"><span class="material-icons" id="toolSaveIco">
|
||||||
play_arrow
|
play_arrow
|
||||||
</span></span>
|
</span></span>
|
||||||
</button>
|
</button>
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<button class="button is-small has-tooltip-arrow"
|
<button class="button is-small has-tooltip-arrow"
|
||||||
data-tooltip="Save" onclick="toolSave()">
|
data-tooltip="Save" onclick="toolSave()">
|
||||||
|
@ -91,7 +103,6 @@
|
||||||
</p>
|
</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{/* TEST */}}
|
|
||||||
<p class="control">
|
<p class="control">
|
||||||
<a class="button is-small has-tooltip-arrow" data-tooltip="Download"
|
<a class="button is-small has-tooltip-arrow" data-tooltip="Download"
|
||||||
href="/api/export?name={{.File.Name}}">
|
href="/api/export?name={{.File.Name}}">
|
||||||
|
@ -145,6 +156,12 @@ function toolFormat(){
|
||||||
beautify.beautify(editor.session);
|
beautify.beautify(editor.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toolSetFontSize(obj){
|
||||||
|
let value = obj.value;
|
||||||
|
document.getElementById('editor').style.fontSize=value;
|
||||||
|
document.getElementById('result_editor').style.fontSize=value;
|
||||||
|
}
|
||||||
|
|
||||||
function toolFollow(){
|
function toolFollow(){
|
||||||
if (ToolIsFollow){
|
if (ToolIsFollow){
|
||||||
ToolIsFollow = false
|
ToolIsFollow = false
|
||||||
|
@ -184,12 +201,15 @@ async function toolSave(){
|
||||||
async function toolApply(){
|
async function toolApply(){
|
||||||
let el = document.getElementById('toolApplyIco');
|
let el = document.getElementById('toolApplyIco');
|
||||||
let originText = el.innerText;
|
let originText = el.innerText;
|
||||||
el.innerText='refreash';
|
el.innerText='rotate_right';
|
||||||
el.classList.add("icn-loading")
|
el.classList.add("icn-loading")
|
||||||
FileApply()
|
if (window.ContentChanged){
|
||||||
|
await FileSave()
|
||||||
|
}
|
||||||
|
await FileApply()
|
||||||
el.innerText=originText;
|
el.innerText=originText;
|
||||||
el.classList.remove("icn-loading")
|
el.classList.remove("icn-loading")
|
||||||
ResultViewTog()
|
{{if not .ResultBellow}}ResultViewTog(){{end}}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
|
@ -24,10 +24,21 @@ var Active = "{{.File.Name}}";
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
{{if and .HideConfig (eq .File.Name .AppName)}}
|
||||||
|
Home
|
||||||
|
{{else}}
|
||||||
{{template "components/editor" .}}
|
{{template "components/editor" .}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{if .ResultBellow}}
|
||||||
|
<div class="box">
|
||||||
|
<div id="result_editor"></div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{if not .ResultBellow}}
|
||||||
{{template "components/result" .}}
|
{{template "components/result" .}}
|
||||||
|
{{end}}
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
||||||
{{end}}
|
{{end}}
|
Loading…
Reference in New Issue