mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
feat: display setup instructions on startup (resolve #120)
This commit is contained in:
parent
e4c413a33c
commit
218c571859
@ -61,6 +61,7 @@ I'd love to get some community feedback from active Wakapi users. If you want, p
|
|||||||
* ✅ Partially compatible with WakaTime
|
* ✅ Partially compatible with WakaTime
|
||||||
* ✅ WakaTime integration
|
* ✅ WakaTime integration
|
||||||
* ✅ Support for Prometheus exports
|
* ✅ Support for Prometheus exports
|
||||||
|
* ✅ Lightning fast
|
||||||
* ✅ Self-hosted
|
* ✅ Self-hosted
|
||||||
|
|
||||||
## 🚧 Roadmap
|
## 🚧 Roadmap
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
"DataWeave": "#003a52",
|
"DataWeave": "#003a52",
|
||||||
"DM": "#447265",
|
"DM": "#447265",
|
||||||
"Dockerfile": "#384d54",
|
"Dockerfile": "#384d54",
|
||||||
|
"Docker": "#384d54",
|
||||||
"Dogescript": "#cca760",
|
"Dogescript": "#cca760",
|
||||||
"Dylan": "#6c616e",
|
"Dylan": "#6c616e",
|
||||||
"E": "#ccce35",
|
"E": "#ccce35",
|
||||||
|
@ -53,6 +53,7 @@ type SummaryViewModel struct {
|
|||||||
Error string
|
Error string
|
||||||
Success string
|
Success string
|
||||||
ApiKey string
|
ApiKey string
|
||||||
|
RawQuery string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SummaryParams struct {
|
type SummaryParams struct {
|
||||||
|
@ -39,6 +39,7 @@ func (h *SummaryHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
loadTemplates()
|
loadTemplates()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawQuery := r.URL.RawQuery
|
||||||
q := r.URL.Query()
|
q := r.URL.Query()
|
||||||
if q.Get("interval") == "" && q.Get("from") == "" {
|
if q.Get("interval") == "" && q.Get("from") == "" {
|
||||||
q.Set("interval", "today")
|
q.Set("interval", "today")
|
||||||
@ -65,6 +66,7 @@ func (h *SummaryHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
EditorColors: utils.FilterColors(h.config.App.GetEditorColors(), summary.Editors),
|
EditorColors: utils.FilterColors(h.config.App.GetEditorColors(), summary.Editors),
|
||||||
OSColors: utils.FilterColors(h.config.App.GetOSColors(), summary.OperatingSystems),
|
OSColors: utils.FilterColors(h.config.App.GetOSColors(), summary.OperatingSystems),
|
||||||
ApiKey: user.ApiKey,
|
ApiKey: user.ApiKey,
|
||||||
|
RawQuery: rawQuery,
|
||||||
}
|
}
|
||||||
|
|
||||||
templates[conf.SummaryTemplate].Execute(w, vm)
|
templates[conf.SummaryTemplate].Execute(w, vm)
|
||||||
|
@ -317,8 +317,10 @@ function equalizeHeights() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTotal(items) {
|
function getTotal(items) {
|
||||||
|
const el = document.getElementById('total-span')
|
||||||
|
if (!el) return
|
||||||
let total = items.reduce((acc, d) => acc + d.total, 0)
|
let total = items.reduce((acc, d) => acc + d.total, 0)
|
||||||
document.getElementById('total-span').innerText = total.toString().toHHMMSS()
|
el.innerText = total.toString().toHHMMSS()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomColor(seed) {
|
function getRandomColor(seed) {
|
||||||
|
@ -10,3 +10,25 @@
|
|||||||
<a href="imprint" class="border-b border-green-700">Imprint, Cookies & Data Privacy</a>
|
<a href="imprint" class="border-b border-green-700">Imprint, Cookies & Data Privacy</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
const baseUrl = location.href.substring(0, location.href.lastIndexOf('/'))
|
||||||
|
document.querySelectorAll('.with-url-src').forEach(e => {
|
||||||
|
e.setAttribute('src', e.getAttribute('src').replace('%s', baseUrl))
|
||||||
|
e.classList.remove('hidden')
|
||||||
|
})
|
||||||
|
document.querySelectorAll('.with-url-src-no-scheme').forEach(e => {
|
||||||
|
const strippedUrl = baseUrl.replace(/https?:\/\//, '')
|
||||||
|
e.setAttribute('src', e.getAttribute('src').replace('%s', strippedUrl))
|
||||||
|
e.classList.remove('hidden')
|
||||||
|
})
|
||||||
|
document.querySelectorAll('.with-url-inner').forEach(e => {
|
||||||
|
e.innerHTML = e.innerHTML.replace('%s', baseUrl)
|
||||||
|
e.classList.remove('hidden')
|
||||||
|
})
|
||||||
|
document.querySelectorAll('.with-url-inner-no-scheme').forEach(e => {
|
||||||
|
const strippedUrl = baseUrl.replace(/https?:\/\//, '')
|
||||||
|
e.innerHTML = e.innerHTML.replace('%s', strippedUrl)
|
||||||
|
e.classList.remove('hidden')
|
||||||
|
})
|
||||||
|
</script>
|
@ -72,6 +72,7 @@
|
|||||||
class="underline">Prometheus</a> metrics via <a
|
class="underline">Prometheus</a> metrics via <a
|
||||||
href="https://github.com/MacroPower/wakatime_exporter" target="_blank"
|
href="https://github.com/MacroPower/wakatime_exporter" target="_blank"
|
||||||
rel="noopener noreferrer" class="underline">exporter</a></li>
|
rel="noopener noreferrer" class="underline">exporter</a></li>
|
||||||
|
<li>✅ Lightning fast</li>
|
||||||
<li>✅ Self-hosted</li>
|
<li>✅ Self-hosted</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -534,26 +534,6 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const baseUrl = location.href.substring(0, location.href.indexOf('/settings'))
|
|
||||||
document.querySelectorAll('.with-url-src').forEach(e => {
|
|
||||||
e.setAttribute('src', e.getAttribute('src').replace('%s', baseUrl))
|
|
||||||
e.classList.remove('hidden')
|
|
||||||
})
|
|
||||||
document.querySelectorAll('.with-url-src-no-scheme').forEach(e => {
|
|
||||||
const strippedUrl = baseUrl.replace(/https?:\/\//, '')
|
|
||||||
e.setAttribute('src', e.getAttribute('src').replace('%s', strippedUrl))
|
|
||||||
e.classList.remove('hidden')
|
|
||||||
})
|
|
||||||
document.querySelectorAll('.with-url-inner').forEach(e => {
|
|
||||||
e.innerHTML = e.innerHTML.replace('%s', baseUrl)
|
|
||||||
e.classList.remove('hidden')
|
|
||||||
})
|
|
||||||
document.querySelectorAll('.with-url-inner-no-scheme').forEach(e => {
|
|
||||||
const strippedUrl = baseUrl.replace(/https?:\/\//, '')
|
|
||||||
e.innerHTML = e.innerHTML.replace('%s', strippedUrl)
|
|
||||||
e.classList.remove('hidden')
|
|
||||||
})
|
|
||||||
|
|
||||||
const btnRegenerate = document.querySelector('#btn-regenerate-summaries')
|
const btnRegenerate = document.querySelector('#btn-regenerate-summaries')
|
||||||
const formRegenerate = document.querySelector('#form-regenerate-summaries')
|
const formRegenerate = document.querySelector('#form-regenerate-summaries')
|
||||||
btnRegenerate.addEventListener('click', () => {
|
btnRegenerate.addEventListener('click', () => {
|
||||||
|
@ -53,16 +53,27 @@
|
|||||||
|
|
||||||
{{ template "alerts.tpl.html" . }}
|
{{ template "alerts.tpl.html" . }}
|
||||||
|
|
||||||
<main class="mt-10 flex-grow">
|
<main class="flex flex-col items-center mt-10 flex-grow">
|
||||||
|
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<div class="p-1">
|
<div class="p-1">
|
||||||
<div class="flex justify-center p-4 bg-gray-900 border border-gray-700 text-gray-300 rounded-md shadow">
|
<div class="flex justify-center p-4 bg-gray-900 border border-gray-700 text-gray-300 rounded-md shadow">
|
||||||
<p class="mx-2"><strong>▶️</strong> <span title="Start Time">{{ .FromTime.T | date }}</span></p>
|
<p class="mx-2"><strong>▶️</strong> <span title="Start Time">{{ .FromTime.T | date }}</span></p>
|
||||||
<p class="mx-2"><strong>⏹️</strong> <span title="End Time">{{ .ToTime.T | date }}</span></p>
|
<p class="mx-2"><strong>⏹️</strong> <span title="End Time">{{ .ToTime.T | date }}</span></p>
|
||||||
<p class="mx-2"><strong>⏱️</strong> <span id="total-span" title="Total Hours"></span></p>
|
<p class="mx-2">
|
||||||
|
<strong>⏱️</strong>
|
||||||
|
{{ if gt .Summary.TotalTime 0 }}
|
||||||
|
<span id="total-span" title="Total Hours"></span>
|
||||||
|
{{ else }}
|
||||||
|
<span title="Total Hours">No Data</span>
|
||||||
|
{{ end }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{ if or (gt .Summary.TotalTime 0) (ne .RawQuery "") }}
|
||||||
|
|
||||||
<div class="flex flex-wrap justify-center">
|
<div class="flex flex-wrap justify-center">
|
||||||
<div class="w-full lg:w-1/2 p-1">
|
<div class="w-full lg:w-1/2 p-1">
|
||||||
<div class="p-4 pb-10 bg-gray-900 border border-gray-700 text-gray-300 rounded-md shadow m-2 flex flex-col" id="project-container" style="height: 300px">
|
<div class="p-4 pb-10 bg-gray-900 border border-gray-700 text-gray-300 rounded-md shadow m-2 flex flex-col" id="project-container" style="height: 300px">
|
||||||
@ -76,8 +87,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<canvas id="chart-projects" class="mt-2"></canvas>
|
<canvas id="chart-projects" class="mt-2"></canvas>
|
||||||
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
||||||
<img src="assets/images/no_data.svg" class="w-20" alt="No data"/>
|
<span class="text-md font-semibold text-gray-500 mt-4">No data ...</span>
|
||||||
<span class="text-sm mt-4">No data available ...</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -93,8 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<canvas id="chart-os"></canvas>
|
<canvas id="chart-os"></canvas>
|
||||||
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
||||||
<img src="assets/images/no_data.svg" class="w-20" alt="No data"/>
|
<span class="text-md font-semibold text-gray-500 mt-4">No data ...</span>
|
||||||
<span class="text-sm mt-4">No data available ...</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -110,8 +119,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<canvas id="chart-language"></canvas>
|
<canvas id="chart-language"></canvas>
|
||||||
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
||||||
<img src="assets/images/no_data.svg" class="w-20" alt="No data"/>
|
<span class="text-md font-semibold text-gray-500 mt-4">No data ...</span>
|
||||||
<span class="text-sm mt-4">No data available ...</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -127,8 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<canvas id="chart-editor"></canvas>
|
<canvas id="chart-editor"></canvas>
|
||||||
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
||||||
<img src="assets/images/no_data.svg" class="w-20" alt="No data"/>
|
<span class="text-md font-semibold text-gray-500 mt-4">No data ...</span>
|
||||||
<span class="text-sm mt-4">No data available ...</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -144,18 +151,55 @@
|
|||||||
</div>
|
</div>
|
||||||
<canvas id="chart-machine"></canvas>
|
<canvas id="chart-machine"></canvas>
|
||||||
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
<div class="hidden placeholder-container flex items-center justify-center h-full flex-col">
|
||||||
<img src="assets/images/no_data.svg" class="w-20" alt="No data"/>
|
<span class="text-md font-semibold text-gray-500 mt-4">No data ...</span>
|
||||||
<span class="text-sm mt-4">No data available ...</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{ else }}
|
||||||
|
|
||||||
|
<div class="max-w-screen-sm flex flex-col items-center mt-12 space-y-8 text-gray-300 text-center">
|
||||||
|
<div class="pb-4">
|
||||||
|
<img src="assets/images/welcome.svg" width="200px">
|
||||||
|
</div>
|
||||||
|
<p class="text-sm">
|
||||||
|
<strong>Welcome to Wakapi! 👋</strong> It looks like there is no data available for the specified time range.<br>If you logged in to Wakapi for the first time, see the setup instructions below on how to get started.
|
||||||
|
</p>
|
||||||
|
<div class="w-full pt-10 flex flex-col space-y-4">
|
||||||
|
<div>
|
||||||
|
<h3 class="inline-block font-semibold text-md border-b border-green-700">Setup Instructions</h3>
|
||||||
|
</div>
|
||||||
|
<div class="w-full bg-gray-900 text-left rounded-md py-4 px-8 text-xs font-mono shadow-md">
|
||||||
|
# <strong>Step 1:</strong> Download WakaTime plugin for your IDE<br>
|
||||||
|
# See: https://wakatime.com/plugins<br><br>
|
||||||
|
|
||||||
|
# <strong>Step 2:</strong> Adapt your config<br>
|
||||||
|
$ vi ~/.wakatime.cfg<br>
|
||||||
|
|
||||||
|
# Set <i>api_url = <span class="with-url-inner">%s/api/heartbeat</span></i><br>
|
||||||
|
# Set <i>api_key = <span id="api-key-instruction"></span></i><br><br>
|
||||||
|
|
||||||
|
# <strong>Step 3:</strong> Start coding and then check back here!
|
||||||
|
</div>
|
||||||
|
<p class="pt-4 text-sm">
|
||||||
|
More at <a href="https://github.com/muety/wakapi" target="_blank" rel="noreferrer noopener" class="font-mono border-b border-green-700">github.com/muety/wakapi</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{{ template "footer.tpl.html" . }}
|
{{ template "footer.tpl.html" . }}
|
||||||
|
|
||||||
{{ template "foot.tpl.html" . }}
|
{{ template "foot.tpl.html" . }}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.querySelector('#api-key-instruction').innerHTML = document.querySelector('#api-key-container').value
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const languageColors = {{ .LanguageColors | json }}
|
const languageColors = {{ .LanguageColors | json }}
|
||||||
const editorColors = {{ .EditorColors | json }}
|
const editorColors = {{ .EditorColors | json }}
|
||||||
|
Loading…
Reference in New Issue
Block a user