projects-panel.html
173 lines1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<!-- Projects Panel -->
<div class="panel-card">
<div class="flex items-center justify-between px-4 pt-3 pb-1">
<h3 class="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Projects</h3>
<div class="flex gap-0.5">
<button class="w-6 h-6 inline-flex items-center justify-center rounded text-slate-300 hover:text-indigo-600 hover:bg-indigo-50 transition-colors" onclick="document.getElementById('new-project-modal').showModal()" title="New Congo Project">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" /></svg>
</button>
<button class="w-6 h-6 inline-flex items-center justify-center rounded text-slate-300 hover:text-indigo-600 hover:bg-indigo-50 transition-colors" onclick="document.getElementById('clone-modal').showModal()" title="Clone Repo">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
</button>
<button class="w-6 h-6 inline-flex items-center justify-center rounded text-slate-300 hover:text-slate-500 hover:bg-slate-100 transition-colors" onclick="document.getElementById('init-modal').showModal()" title="Init Empty Repo">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
</button>
</div>
</div>
{{if dashboard.Repositories}}
{{$svcMap := dashboard.ServicesByRepo}}
<div class="px-1 pb-2">
{{range $repo := dashboard.Repositories}}
<div class="group flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-white/60 hover:shadow-sm hover:shadow-slate-200/50 transition-all duration-200">
<div class="w-2 h-2 rounded-full shrink-0
{{if eq $repo.StatusDetail "clean"}}bg-emerald-400 glow-emerald
{{else if $repo.StatusDetail}}bg-amber-400 glow-amber
{{else if eq $repo.Status "missing"}}bg-red-400 glow-red
{{else}}bg-slate-300{{end}}"
title="{{if $repo.StatusDetail}}{{$repo.StatusDetail}}{{else}}{{$repo.Status}}{{end}}"></div>
<a href="/repos/{{$repo.ID}}" class="text-[13px] font-medium text-slate-700 truncate flex-1 hover:text-indigo-600 transition-colors">{{$repo.Name}}</a>
<div class="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0">
{{if ne $repo.Status "missing"}}
<a href="/repos/{{$repo.ID}}/files" hx-boost="true"
class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-slate-300 hover:text-slate-500 hover:bg-slate-100 transition-colors" title="Browse files">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
</a>
<a href="/coder/?folder=/home/coder/repos/{{$repo.Name}}" target="_blank"
class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-indigo-300 hover:text-indigo-600 hover:bg-indigo-50 transition-colors" title="Open in IDE">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
</a>
{{if $repo.URL}}
<button class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-slate-300 hover:text-blue-500 hover:bg-blue-50 transition-colors"
hx-post="/repos/{{$repo.ID}}/pull" hx-target="body" title="Pull latest">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
</button>
{{end}}
{{end}}
<button class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-slate-200 hover:text-red-400 hover:bg-red-50 transition-colors"
hx-post="/repos/{{$repo.ID}}/delete" hx-confirm="Delete {{$repo.Name}}? This removes all files." hx-target="body" title="Delete">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
<span class="text-[10px] font-mono text-slate-500 bg-slate-100/80 px-1.5 py-0.5 rounded-md shrink-0">{{$repo.Branch}}</span>
{{with index $svcMap $repo.ID}}
<span class="text-[10px] font-medium text-violet-500 bg-violet-50 px-1.5 py-0.5 rounded-md shrink-0" title="{{.}} deployed service{{if gt . 1}}s{{end}}">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3 inline -mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2" /></svg>
{{.}}
</span>
{{end}}
</div>
{{end}}
</div>
{{else}}
<div class="text-center py-8 px-4">
<div class="inline-flex items-center justify-center w-10 h-10 rounded-xl bg-slate-50 mb-3">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-slate-300" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
</div>
<p class="text-[12px] text-slate-400 mb-1">No projects yet</p>
<p class="text-[11px] text-slate-300 mb-3">Create a new project or clone an existing repo</p>
<div class="flex gap-2 justify-center">
<button class="inline-flex items-center gap-1 text-[11px] font-medium text-indigo-500 hover:text-indigo-600 transition-colors" onclick="document.getElementById('new-project-modal').showModal()">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" /></svg>
New Project
</button>
<span class="text-slate-200">|</span>
<button class="inline-flex items-center gap-1 text-[11px] font-medium text-indigo-500 hover:text-indigo-600 transition-colors" onclick="document.getElementById('clone-modal').showModal()">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
Clone
</button>
</div>
</div>
{{end}}
</div>
<!-- New Project Modal -->
<dialog id="new-project-modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box bg-white/95 backdrop-blur-xl border border-slate-200/60 shadow-2xl max-w-md p-6 rounded-2xl">
<h3 class="text-base font-bold text-slate-800 mb-0.5">New Congo Project</h3>
<p class="text-[11px] text-slate-400 mb-5">Scaffold a full-stack app with the Congo framework</p>
<form method="dialog"><button class="btn btn-sm btn-circle btn-ghost absolute right-3 top-3 text-slate-300">x</button></form>
<form hx-post="/repos/new" hx-target="body">
<div class="form-control mb-4">
<label class="floating-label">
<span>Project Name</span>
<input type="text" name="name" class="input input-bordered w-full font-mono" placeholder="my-app" required pattern="[a-z0-9_-]+" title="Lowercase letters, numbers, hyphens, underscores" autofocus />
</label>
</div>
<div class="mb-5">
<div class="text-[10px] font-semibold uppercase tracking-wider text-slate-400 mb-2.5">Exclude from scaffold</div>
<div class="grid grid-cols-2 gap-2.5">
<label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
<input type="checkbox" name="no_frontend" class="checkbox checkbox-xs" />
<span>Frontend</span>
</label>
<label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
<input type="checkbox" name="no_database" class="checkbox checkbox-xs" />
<span>Database</span>
</label>
<label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
<input type="checkbox" name="no_assistant" class="checkbox checkbox-xs" />
<span>AI / Assistant</span>
</label>
<label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
<input type="checkbox" name="no_platform" class="checkbox checkbox-xs" />
<span>Cloud Deploy</span>
</label>
</div>
</div>
<div class="flex justify-end gap-2">
<button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('new-project-modal').close()">Cancel</button>
<button type="submit" class="btn btn-primary btn-sm">Create Project</button>
</div>
</form>
</div>
<form method="dialog" class="modal-backdrop bg-black/10 backdrop-blur-[1px]"><button>close</button></form>
</dialog>
<!-- Clone Modal -->
<dialog id="clone-modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box bg-white/95 backdrop-blur-xl border border-slate-200/60 shadow-2xl max-w-md p-6 rounded-2xl">
<h3 class="text-base font-bold text-slate-800 mb-0.5">Clone Repository</h3>
<p class="text-[11px] text-slate-400 mb-5">Import an existing repository from a git URL</p>
<form method="dialog"><button class="btn btn-sm btn-circle btn-ghost absolute right-3 top-3 text-slate-300">x</button></form>
<form hx-post="/repos/clone" hx-target="body">
<div class="form-control mb-3">
<label class="floating-label"><span>Git URL</span>
<input type="text" name="url" class="input input-bordered w-full font-mono" placeholder="https://github.com/user/repo" required autofocus />
</label>
</div>
<div class="form-control mb-5">
<label class="floating-label"><span>Name (optional)</span>
<input type="text" name="name" class="input input-bordered w-full font-mono" placeholder="custom-name" />
</label>
<p class="text-[10px] text-slate-400 mt-1 ml-0.5">Leave empty to use the repository name</p>
</div>
<div class="flex justify-end gap-2">
<button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('clone-modal').close()">Cancel</button>
<button type="submit" class="btn btn-primary btn-sm">Clone</button>
</div>
</form>
</div>
<form method="dialog" class="modal-backdrop bg-black/10 backdrop-blur-[1px]"><button>close</button></form>
</dialog>
<!-- Init Modal -->
<dialog id="init-modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box bg-white/95 backdrop-blur-xl border border-slate-200/60 shadow-2xl max-w-md p-6 rounded-2xl">
<h3 class="text-base font-bold text-slate-800 mb-0.5">New Repository</h3>
<p class="text-[11px] text-slate-400 mb-5">Initialize an empty git repository</p>
<form method="dialog"><button class="btn btn-sm btn-circle btn-ghost absolute right-3 top-3 text-slate-300">x</button></form>
<form hx-post="/repos/init" hx-target="body">
<div class="form-control mb-5">
<label class="floating-label"><span>Repository Name</span>
<input type="text" name="name" class="input input-bordered w-full font-mono" placeholder="my-project" required autofocus />
</label>
</div>
<div class="flex justify-end gap-2">
<button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('init-modal').close()">Cancel</button>
<button type="submit" class="btn btn-primary btn-sm">Create</button>
</div>
</form>
</div>
<form method="dialog" class="modal-backdrop bg-black/10 backdrop-blur-[1px]"><button>close</button></form>
</dialog>