mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
refactor(wip): redesign settings page
This commit is contained in:
parent
4e7322c985
commit
7b7fa8bdf3
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
var securityHeaders = map[string]string{
|
var securityHeaders = map[string]string{
|
||||||
"Cross-Origin-Opener-Policy": "same-origin",
|
"Cross-Origin-Opener-Policy": "same-origin",
|
||||||
"Content-Security-Policy": "default-src 'self' 'unsafe-inline'; img-src 'self' https: data:; form-action 'self'; block-all-mixed-content;",
|
"Content-Security-Policy": "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' https: data:; form-action 'self'; block-all-mixed-content;",
|
||||||
"X-Frame-Options": "DENY",
|
"X-Frame-Options": "DENY",
|
||||||
"X-Content-Type-Options": "nosniff",
|
"X-Content-Type-Options": "nosniff",
|
||||||
}
|
}
|
||||||
|
@ -49,18 +49,6 @@ type SummaryItemContainer struct {
|
|||||||
Items []*SummaryItem
|
Items []*SummaryItem
|
||||||
}
|
}
|
||||||
|
|
||||||
type SummaryViewModel struct {
|
|
||||||
*Summary
|
|
||||||
*SummaryParams
|
|
||||||
User *User
|
|
||||||
AvatarURL string
|
|
||||||
LanguageColors map[string]string
|
|
||||||
Error string
|
|
||||||
Success string
|
|
||||||
ApiKey string
|
|
||||||
RawQuery string
|
|
||||||
}
|
|
||||||
|
|
||||||
type SummaryParams struct {
|
type SummaryParams struct {
|
||||||
From time.Time
|
From time.Time
|
||||||
To time.Time
|
To time.Time
|
||||||
|
@ -8,6 +8,7 @@ type SettingsViewModel struct {
|
|||||||
Aliases []*SettingsVMCombinedAlias
|
Aliases []*SettingsVMCombinedAlias
|
||||||
Labels []*SettingsVMCombinedLabel
|
Labels []*SettingsVMCombinedLabel
|
||||||
Projects []string
|
Projects []string
|
||||||
|
ApiKey string
|
||||||
Success string
|
Success string
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
package view
|
package view
|
||||||
|
|
||||||
|
import "github.com/muety/wakapi/models"
|
||||||
|
|
||||||
type SummaryViewModel struct {
|
type SummaryViewModel struct {
|
||||||
Success string
|
*models.Summary
|
||||||
|
*models.SummaryParams
|
||||||
|
User *models.User
|
||||||
|
AvatarURL string
|
||||||
|
LanguageColors map[string]string
|
||||||
Error string
|
Error string
|
||||||
|
Success string
|
||||||
|
ApiKey string
|
||||||
|
RawQuery string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SummaryViewModel) WithSuccess(m string) *SummaryViewModel {
|
func (s *SummaryViewModel) WithSuccess(m string) *SummaryViewModel {
|
||||||
|
@ -682,6 +682,7 @@ func (h *SettingsHandler) buildViewModel(r *http.Request) *view.SettingsViewMode
|
|||||||
Aliases: combinedAliases,
|
Aliases: combinedAliases,
|
||||||
Labels: combinedLabels,
|
Labels: combinedLabels,
|
||||||
Projects: projects,
|
Projects: projects,
|
||||||
|
ApiKey: user.ApiKey,
|
||||||
Success: r.URL.Query().Get("success"),
|
Success: r.URL.Query().Get("success"),
|
||||||
Error: r.URL.Query().Get("error"),
|
Error: r.URL.Query().Get("error"),
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
conf "github.com/muety/wakapi/config"
|
conf "github.com/muety/wakapi/config"
|
||||||
"github.com/muety/wakapi/middlewares"
|
"github.com/muety/wakapi/middlewares"
|
||||||
"github.com/muety/wakapi/models"
|
|
||||||
"github.com/muety/wakapi/models/view"
|
"github.com/muety/wakapi/models/view"
|
||||||
su "github.com/muety/wakapi/routes/utils"
|
su "github.com/muety/wakapi/routes/utils"
|
||||||
"github.com/muety/wakapi/services"
|
"github.com/muety/wakapi/services"
|
||||||
@ -61,7 +60,7 @@ func (h *SummaryHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vm := models.SummaryViewModel{
|
vm := view.SummaryViewModel{
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
SummaryParams: summaryParams,
|
SummaryParams: summaryParams,
|
||||||
User: user,
|
User: user,
|
||||||
|
@ -20,3 +20,4 @@ Iconify.addCollection({"prefix":"fa-solid","icons":{"external-link-alt":{"body":
|
|||||||
Iconify.addCollection({"prefix":"simple-icons","icons":{"wakatime":{"body":"<path d=\"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12s12-5.373 12-12S18.627 0 12 0zm0 2.824a9.176 9.176 0 1 1 0 18.352a9.176 9.176 0 0 1 0-18.352zm5.097 5.058c-.327 0-.61.19-.764.45c-1.025 1.463-2.21 3.162-3.288 4.706l-.387-.636a.897.897 0 0 0-.759-.439a.901.901 0 0 0-.788.492l-.357.581l-1.992-2.943a.897.897 0 0 0-.761-.446c-.514 0-.903.452-.903.96a1 1 0 0 0 .207.61l2.719 3.96c.152.272.44.47.776.47a.91.91 0 0 0 .787-.483c.046-.071.23-.368.314-.504l.324.52c-.035-.047.076.113.087.13c.024.031.054.059.078.085c.019.019.04.036.058.052c.036.033.08.056.115.08c.025.016.052.028.076.04c.029.015.06.024.088.035c.058.025.122.027.18.04c.031.004.064.003.092.005c.29 0 .546-.149.707-.36c1.4-2 2.842-4.055 4.099-5.849A.995.995 0 0 0 18 8.842c0-.508-.389-.96-.903-.96\" fill=\"currentColor\"/>"}},"width":24,"height":24});
|
Iconify.addCollection({"prefix":"simple-icons","icons":{"wakatime":{"body":"<path d=\"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12s12-5.373 12-12S18.627 0 12 0zm0 2.824a9.176 9.176 0 1 1 0 18.352a9.176 9.176 0 0 1 0-18.352zm5.097 5.058c-.327 0-.61.19-.764.45c-1.025 1.463-2.21 3.162-3.288 4.706l-.387-.636a.897.897 0 0 0-.759-.439a.901.901 0 0 0-.788.492l-.357.581l-1.992-2.943a.897.897 0 0 0-.761-.446c-.514 0-.903.452-.903.96a1 1 0 0 0 .207.61l2.719 3.96c.152.272.44.47.776.47a.91.91 0 0 0 .787-.483c.046-.071.23-.368.314-.504l.324.52c-.035-.047.076.113.087.13c.024.031.054.059.078.085c.019.019.04.036.058.052c.036.033.08.056.115.08c.025.016.052.028.076.04c.029.015.06.024.088.035c.058.025.122.027.18.04c.031.004.064.003.092.005c.29 0 .546-.149.707-.36c1.4-2 2.842-4.055 4.099-5.849A.995.995 0 0 0 18 8.842c0-.508-.389-.96-.903-.96\" fill=\"currentColor\"/>"}},"width":24,"height":24});
|
||||||
Iconify.addCollection({"prefix":"heroicons-solid","icons":{"light-bulb":{"body":"<g fill=\"none\"><path d=\"M11 3a1 1 0 1 0-2 0v1a1 1 0 1 0 2 0V3z\" fill=\"currentColor\"/><path d=\"M15.657 5.757a1 1 0 0 0-1.414-1.414l-.707.707a1 1 0 0 0 1.414 1.414l.707-.707z\" fill=\"currentColor\"/><path d=\"M18 10a1 1 0 0 1-1 1h-1a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M5.05 6.464A1 1 0 1 0 6.464 5.05l-.707-.707a1 1 0 0 0-1.414 1.414l.707.707z\" fill=\"currentColor\"/><path d=\"M5 10a1 1 0 0 1-1 1H3a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M8 16v-1h4v1a2 2 0 1 1-4 0z\" fill=\"currentColor\"/><path d=\"M12 14c.015-.34.208-.646.477-.859a4 4 0 1 0-4.954 0c.27.213.462.519.476.859h4.002z\" fill=\"currentColor\"/></g>"},"server":{"body":"<g fill=\"none\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 13a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-2zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/></g>"}},"width":20,"height":20});
|
Iconify.addCollection({"prefix":"heroicons-solid","icons":{"light-bulb":{"body":"<g fill=\"none\"><path d=\"M11 3a1 1 0 1 0-2 0v1a1 1 0 1 0 2 0V3z\" fill=\"currentColor\"/><path d=\"M15.657 5.757a1 1 0 0 0-1.414-1.414l-.707.707a1 1 0 0 0 1.414 1.414l.707-.707z\" fill=\"currentColor\"/><path d=\"M18 10a1 1 0 0 1-1 1h-1a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M5.05 6.464A1 1 0 1 0 6.464 5.05l-.707-.707a1 1 0 0 0-1.414 1.414l.707.707z\" fill=\"currentColor\"/><path d=\"M5 10a1 1 0 0 1-1 1H3a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M8 16v-1h4v1a2 2 0 1 1-4 0z\" fill=\"currentColor\"/><path d=\"M12 14c.015-.34.208-.646.477-.859a4 4 0 1 0-4.954 0c.27.213.462.519.476.859h4.002z\" fill=\"currentColor\"/></g>"},"server":{"body":"<g fill=\"none\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 13a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-2zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/></g>"}},"width":20,"height":20});
|
||||||
Iconify.addCollection({"prefix":"ion","icons":{"rocket":{"body":"<path d=\"M328.85 156.79a26.69 26.69 0 1 0 18.88 7.81a26.6 26.6 0 0 0-18.88-7.81z\" fill=\"currentColor\"/><path d=\"M477.44 50.06a.29.29 0 0 1 0-.09a20.4 20.4 0 0 0-15.13-15.3c-29.8-7.27-76.68.48-128.63 21.28c-52.36 21-101.42 52-134.58 85.22A320.7 320.7 0 0 0 169.55 175c-22.33-1-42 2.18-58.57 9.41c-57.74 25.41-74.23 90.44-78.62 117.14a25 25 0 0 0 27.19 29h.13l64.32-7.02c.08.82.17 1.57.24 2.26a34.36 34.36 0 0 0 9.9 20.72l31.39 31.41a34.27 34.27 0 0 0 20.71 9.91l2.15.23l-7 64.24v.13A25 25 0 0 0 206 480a25.25 25.25 0 0 0 4.15-.34C237 475.34 302 459.05 327.34 401c7.17-16.46 10.34-36.05 9.45-58.34a314.78 314.78 0 0 0 33.95-29.55c33.43-33.26 64.53-81.92 85.31-133.52c20.69-51.36 28.48-98.59 21.39-129.53zM370.38 224.94a58.77 58.77 0 1 1 0-83.07a58.3 58.3 0 0 1 0 83.07z\" fill=\"currentColor\"/><path d=\"M161.93 386.44a16 16 0 0 0-11 2.67c-6.39 4.37-12.81 8.69-19.29 12.9c-13.11 8.52-28.79-6.44-21-20l12.15-21a16 16 0 0 0-15.16-24.91A61.25 61.25 0 0 0 72 353.56c-3.66 3.67-14.79 14.81-20.78 57.26A357.94 357.94 0 0 0 48 447.59A16 16 0 0 0 64 464h.4a359.87 359.87 0 0 0 36.8-3.2c42.47-6 53.61-17.14 57.27-20.8a60.49 60.49 0 0 0 17.39-35.74a16 16 0 0 0-13.93-17.82z\" fill=\"currentColor\"/>"}},"width":512,"height":512});
|
Iconify.addCollection({"prefix":"ion","icons":{"rocket":{"body":"<path d=\"M328.85 156.79a26.69 26.69 0 1 0 18.88 7.81a26.6 26.6 0 0 0-18.88-7.81z\" fill=\"currentColor\"/><path d=\"M477.44 50.06a.29.29 0 0 1 0-.09a20.4 20.4 0 0 0-15.13-15.3c-29.8-7.27-76.68.48-128.63 21.28c-52.36 21-101.42 52-134.58 85.22A320.7 320.7 0 0 0 169.55 175c-22.33-1-42 2.18-58.57 9.41c-57.74 25.41-74.23 90.44-78.62 117.14a25 25 0 0 0 27.19 29h.13l64.32-7.02c.08.82.17 1.57.24 2.26a34.36 34.36 0 0 0 9.9 20.72l31.39 31.41a34.27 34.27 0 0 0 20.71 9.91l2.15.23l-7 64.24v.13A25 25 0 0 0 206 480a25.25 25.25 0 0 0 4.15-.34C237 475.34 302 459.05 327.34 401c7.17-16.46 10.34-36.05 9.45-58.34a314.78 314.78 0 0 0 33.95-29.55c33.43-33.26 64.53-81.92 85.31-133.52c20.69-51.36 28.48-98.59 21.39-129.53zM370.38 224.94a58.77 58.77 0 1 1 0-83.07a58.3 58.3 0 0 1 0 83.07z\" fill=\"currentColor\"/><path d=\"M161.93 386.44a16 16 0 0 0-11 2.67c-6.39 4.37-12.81 8.69-19.29 12.9c-13.11 8.52-28.79-6.44-21-20l12.15-21a16 16 0 0 0-15.16-24.91A61.25 61.25 0 0 0 72 353.56c-3.66 3.67-14.79 14.81-20.78 57.26A357.94 357.94 0 0 0 48 447.59A16 16 0 0 0 64 464h.4a359.87 359.87 0 0 0 36.8-3.2c42.47-6 53.61-17.14 57.27-20.8a60.49 60.49 0 0 0 17.39-35.74a16 16 0 0 0-13.93-17.82z\" fill=\"currentColor\"/>"}},"width":512,"height":512});
|
||||||
|
Iconify.addCollection({"prefix":"clarity","icons":{"warning-standard-solid":{"body":"<path class=\"clr-i-solid clr-i-solid-path-1\" d=\"M34.6 29.21L20.71 3.65a3.22 3.22 0 0 0-5.66 0L1.17 29.21A3.22 3.22 0 0 0 4 34h27.77a3.22 3.22 0 0 0 2.83-4.75zM16.6 10a1.4 1.4 0 0 1 2.8 0v12a1.4 1.4 0 0 1-2.8 0zM18 29.85a1.8 1.8 0 1 1 1.8-1.8a1.8 1.8 0 0 1-1.8 1.8z\" fill=\"currentColor\"/>"}},"width":36,"height":36});
|
||||||
|
1
static/assets/vendor/petite-vue.min.js
vendored
Normal file
1
static/assets/vendor/petite-vue.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,3 +1,4 @@
|
|||||||
|
<script src="assets/app.js"></script>
|
||||||
<script src="assets/vendor/iconify.basic.min.js"></script>
|
<script src="assets/vendor/iconify.basic.min.js"></script>
|
||||||
<script src="assets/vendor/seedrandom.min.js"></script>
|
<script src="assets/vendor/seedrandom.min.js"></script>
|
||||||
<script src="assets/vendor/chart.min.js"></script>
|
<script src="assets/vendor/chart.min.js"></script>
|
||||||
|
@ -17,4 +17,5 @@
|
|||||||
<link href="assets/vendor/tailwind.dist.css" rel="stylesheet">
|
<link href="assets/vendor/tailwind.dist.css" rel="stylesheet">
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<link href="assets/app.css" rel="stylesheet">
|
<link href="assets/app.css" rel="stylesheet">
|
||||||
|
<script src="assets/vendor/petite-vue.min.js" defer></script>
|
||||||
</head>
|
</head>
|
@ -12,7 +12,7 @@
|
|||||||
<main class="mt-10 flex-grow flex justify-center w-full">
|
<main class="mt-10 flex-grow flex justify-center w-full">
|
||||||
<div class="flex-grow max-w-lg mt-10">
|
<div class="flex-grow max-w-lg mt-10">
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<h1 class="font-semibold text-2xl text-white m-0">Welcome!</h1>
|
<h1 class="font-semibold text-3xl text-white m-0">Welcome!</h1>
|
||||||
<span class="text-gray-600">Log in to continue using Wakapi</span>
|
<span class="text-gray-600">Log in to continue using Wakapi</span>
|
||||||
</div>
|
</div>
|
||||||
<form action="login" method="post">
|
<form action="login" method="post">
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
{{ template "logo.tpl.html" }}
|
{{ template "logo.tpl.html" }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer">
|
<a class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer" href="summary">
|
||||||
<span class="iconify inline text-2xl text-gray-400" data-icon="ic:round-dashboard"></span>
|
<span class="iconify inline text-2xl text-gray-400" data-icon="ic:round-dashboard"></span>
|
||||||
<a class="text-gray-300" href="summary">Dashboard</a>
|
<span class="text-gray-300">Dashboard</span>
|
||||||
</div>
|
</a>
|
||||||
|
|
||||||
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-not-allowed">
|
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-not-allowed">
|
||||||
<span class="iconify inline text-2xl text-gray-700" data-icon="bi:people-fill"></span>
|
<span class="iconify inline text-2xl text-gray-700" data-icon="bi:people-fill"></span>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<div class="hidden flex bg-gray-850 shadow-md z-10 p-2 absolute top-0 right-0 rounded popup mt-12 w-full" id="resources-menu-dropdown">
|
<div class="hidden flex bg-gray-850 shadow-md z-10 p-2 absolute top-0 right-0 rounded popup mt-12 w-full" id="resources-menu-dropdown">
|
||||||
<div class="flex-grow flex flex-col">
|
<div class="flex-grow flex flex-col">
|
||||||
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
|
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
|
||||||
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/muety/wakapi" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
|
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/muety/wakapi" target="_blank" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
|
||||||
<span class="text-sm">GitHub</span>
|
<span class="text-sm">GitHub</span>
|
||||||
<span class="iconify inline" data-icon="codicon:github-inverted"></span>
|
<span class="iconify inline" data-icon="codicon:github-inverted"></span>
|
||||||
</a>
|
</a>
|
||||||
@ -44,13 +44,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
|
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
|
||||||
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://wakatime.com" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
|
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://wakatime.com" target="_blank" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
|
||||||
<span class="text-sm">WakaTime</span>
|
<span class="text-sm">WakaTime</span>
|
||||||
<span class="iconify inline" data-icon="simple-icons:wakatime"></span>
|
<span class="iconify inline" data-icon="simple-icons:wakatime"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
|
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
|
||||||
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/sponsors/muety" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
|
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/sponsors/muety" target="_blank" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
|
||||||
<span class="text-sm">Donate</span>
|
<span class="text-sm">Donate</span>
|
||||||
<span class="iconify inline" data-icon="bx:bxs-heart"></span>
|
<span class="iconify inline" data-icon="bx:bxs-heart"></span>
|
||||||
</a>
|
</a>
|
||||||
@ -59,10 +59,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer">
|
<a class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer" href="settings">
|
||||||
<span class="iconify inline text-2xl text-gray-400" data-icon="ci:settings-filled"></span>
|
<span class="iconify inline text-2xl text-gray-400" data-icon="ci:settings-filled"></span>
|
||||||
<a class="text-gray-400" href="settings">Settings</a>
|
<span class="text-gray-400">Settings</span>
|
||||||
</div>
|
</a>
|
||||||
|
|
||||||
<div class="flex-grow"></div>
|
<div class="flex-grow"></div>
|
||||||
|
|
||||||
|
@ -4,6 +4,25 @@
|
|||||||
{{ template "head.tpl.html" . }}
|
{{ template "head.tpl.html" . }}
|
||||||
<script src="assets/timezones.js"></script>
|
<script src="assets/timezones.js"></script>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
const defaultTab = 'account'
|
||||||
|
|
||||||
|
PetiteVue.createApp({
|
||||||
|
$delimiters: ['${', '}'],
|
||||||
|
activeTab: defaultTab,
|
||||||
|
updateTab() {
|
||||||
|
this.activeTab = window.location.hash.slice(1) || defaultTab
|
||||||
|
},
|
||||||
|
isActive(tab) {
|
||||||
|
return this.activeTab === tab
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.updateTab()
|
||||||
|
window.addEventListener('hashchange', () => this.updateTab())
|
||||||
|
}
|
||||||
|
}).mount()
|
||||||
|
</script>
|
||||||
|
|
||||||
<body class="bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-xl mx-auto justify-center">
|
<body class="bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-xl mx-auto justify-center">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -20,52 +39,71 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{{ template "header.tpl.html" . }}
|
{{ template "menu-main.tpl.html" . }}
|
||||||
|
|
||||||
<div class="w-full flex justify-center">
|
|
||||||
<div class="flex items-center justify-between max-w-2xl flex-grow">
|
|
||||||
<div><a href="" class="text-gray-500 text-sm cursor-pointer">← Go back</a></div>
|
|
||||||
<div><h1 class="font-semibold text-2xl text-white m-0 border-b-4 border-green-700">Settings</h1></div>
|
|
||||||
<div> </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ template "alerts.tpl.html" . }}
|
{{ template "alerts.tpl.html" . }}
|
||||||
|
|
||||||
<main class="mt-4 flex-grow flex justify-center w-full">
|
<main class="mt-10 flex-grow flex justify-center w-full" v-scope @vue:mounted="mounted">
|
||||||
<div class="flex flex-col flex-grow max-w-2xl mt-8">
|
<div class="flex flex-col flex-grow mt-10">
|
||||||
|
<h1 class="font-semibold text-3xl text-white m-0 mb-4">Settings</h1>
|
||||||
|
|
||||||
<details class="my-8 pb-8 border-b border-gray-700" id="details-account">
|
<ul class="flex space-x-4 mb-16 text-gray-600">
|
||||||
<summary class="cursor-pointer">
|
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('account'), 'hover:text-gray-500': !isActive('account') }">
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"
|
<a href="settings#account" @click="updateTab">Account</a>
|
||||||
id="preferences-heading">
|
</li>
|
||||||
Account Preferences
|
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('data'), 'hover:text-gray-500': !isActive('data') }">
|
||||||
</h2>
|
<a href="settings#data" @click="updateTab">Data</a>
|
||||||
</summary>
|
</li>
|
||||||
<div class="w-full">
|
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('permissions'), 'hover:text-gray-500': !isActive('permissions') }">
|
||||||
<form class="mt-10" action="" method="post">
|
<a href="settings#permissions" @click="updateTab">Permissions</a>
|
||||||
|
</li>
|
||||||
|
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('integrations'), 'hover:text-gray-500': !isActive('integrations') }">
|
||||||
|
<a href="settings#integrations" @click="updateTab">Integrations</a>
|
||||||
|
</li>
|
||||||
|
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('danger_zone'), 'hover:text-gray-500': !isActive('danger_zone') }">
|
||||||
|
<a href="settings#danger_zone" @click="updateTab">Danger Zone</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="account" class="tab flex flex-col space-y-4" v-if="isActive('account')">
|
||||||
|
<!-- Account Settings -->
|
||||||
|
<form action="" method="post" class="w-3/4">
|
||||||
<input type="hidden" name="action" value="update_user">
|
<input type="hidden" name="action" value="update_user">
|
||||||
<div class="mb-8 flex justify-between items-center space-x-4">
|
|
||||||
<label class="inline-block text-sm text-gray-500 w-1/3" for="select-timezone">Time Zone</label>
|
<div class="flex mb-8">
|
||||||
|
<div class="w-1/2 mr-4 inline-block">
|
||||||
|
<label class="font-semibold text-gray-300" for="select-timezone">Time Zone</label>
|
||||||
|
<span class="block text-sm text-gray-600">Time Zone, which you are located in. Relevant for displaying daily statistics.</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 ml-4">
|
||||||
<select name="location" id="select-timezone"
|
<select name="location" id="select-timezone"
|
||||||
class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded flex-grow py-1 px-3 cursor-pointer">
|
class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full cursor-pointer">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-8 flex justify-between items-center space-x-4">
|
<div class="flex mb-8">
|
||||||
<label class="inline-block text-sm text-gray-500 w-1/3" for="email">E-Mail Address</label>
|
<div class="w-1/2 mr-4 inline-block">
|
||||||
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded flex-grow py-1 px-3"
|
<label class="font-semibold text-gray-300" for="email">E-Mail Address</label>
|
||||||
|
<span class="block text-sm text-gray-600">Optional in general, but required for weekly reports and for resetting your password.</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 ml-4">
|
||||||
|
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
|
||||||
type="email" id="email"
|
type="email" id="email"
|
||||||
name="email" placeholder="Enter your e-mail address"
|
name="email" placeholder="Enter your e-mail address"
|
||||||
value="{{ .User.Email }}">
|
value="{{ .User.Email }}">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ if .User.Email }}
|
{{ if .User.Email }}
|
||||||
<div class="flex items-center w-full text-gray-500 text-sm my-2 w-1/3 space-x-4">
|
<div class="flex mb-8">
|
||||||
<span class="inline-block text-sm text-gray-500 w-1/3">Weekly E-Mail Reports</span>
|
<div class="w-1/2 mr-4 inline-block">
|
||||||
<div class="justify-start">
|
<label class="font-semibold text-gray-300" for="reports_weekly">Weekly E-Mail Reports</label>
|
||||||
|
<span class="block text-sm text-gray-600">Opt in to receive a summary of your coding activity once a week.</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 ml-4">
|
||||||
<select autocomplete="off" name="reports_weekly"
|
<select autocomplete="off" name="reports_weekly"
|
||||||
class="cursor-pointer shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3">
|
class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full cursor-pointer">
|
||||||
<option value="false" class="cursor-pointer" {{ if not .User.ReportsWeekly }} selected{{ end }}>Disabled</option>
|
<option value="false" class="cursor-pointer" {{ if not .User.ReportsWeekly }} selected{{ end }}>Disabled</option>
|
||||||
<option value="true" class="cursor-pointer" {{ if .User.ReportsWeekly }} selected {{ end }}>Enabled</option>
|
<option value="true" class="cursor-pointer" {{ if .User.ReportsWeekly }} selected {{ end }}>Enabled</option>
|
||||||
</select>
|
</select>
|
||||||
@ -73,162 +111,164 @@
|
|||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<div class="text-gray-300 text-sm mt-8">E-Mail address is optional, but required for some features
|
|
||||||
that you cannot use else. Also, if you do not add an e-mail address, you will not be able to
|
|
||||||
reset your password in case you forget it.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-end mt-4">
|
<div class="flex justify-end mt-4">
|
||||||
<button type="submit"
|
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
||||||
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm self-end">
|
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details class="mb-8 pb-8 border-b border-gray-700" id="details-password">
|
<div class="w-3/4">
|
||||||
<summary class="cursor-pointer">
|
<hr class="border-t border-gray-800 my-4">
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" id="password">
|
</div>
|
||||||
Change Password
|
|
||||||
</h2>
|
<!-- Password -->
|
||||||
</summary>
|
<form class="w-3/4" action="" method="post">
|
||||||
<div class="w-full">
|
|
||||||
<form class="mt-10" action="" method="post">
|
|
||||||
<input type="hidden" name="action" value="change_password">
|
<input type="hidden" name="action" value="change_password">
|
||||||
<div class="mb-8">
|
|
||||||
<label class="inline-block text-sm mb-1 text-gray-500" for="password_old">Current
|
<div class="flex mb-8">
|
||||||
Password</label>
|
<div class="w-1/2 mr-4 inline-block">
|
||||||
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded w-full py-1 px-3"
|
<label class="font-semibold text-gray-300" for="password_old">Current Password</label>
|
||||||
|
<span class="block text-sm text-gray-600">Enter your old password for verification.</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 ml-4">
|
||||||
|
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
|
||||||
type="password" id="password_old"
|
type="password" id="password_old"
|
||||||
name="password_old" placeholder="Enter your old password" minlength="6" required>
|
name="password_old" placeholder="Old password" minlength="6" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-8">
|
</div>
|
||||||
<label class="inline-block text-sm mb-1 text-gray-500" for="password_new">New Password</label>
|
|
||||||
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded w-full py-1 px-3"
|
<div class="flex mb-8">
|
||||||
|
<div class="w-1/2 mr-4 inline-block">
|
||||||
|
<label class="font-semibold text-gray-300" for="password_new">New Password</label>
|
||||||
|
<span class="block text-sm text-gray-600">Choose a new password. Preferably, it is at least 8 characters long and contains letters, digits and special chars.</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 ml-4">
|
||||||
|
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
|
||||||
type="password" id="password_new"
|
type="password" id="password_new"
|
||||||
name="password_new" placeholder="Choose a password" minlength="6" required>
|
name="password_new" placeholder="New password" minlength="6" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-8">
|
</div>
|
||||||
<label class="inline-block text-sm mb-1 text-gray-500" for="password_repeat">And again
|
|
||||||
...</label>
|
<div class="flex mb-8">
|
||||||
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded w-full py-1 px-3"
|
<div class="w-1/2 mr-4 inline-block">
|
||||||
|
<label class="font-semibold text-gray-300" for="password_repeat">Repeat Password</label>
|
||||||
|
<span class="block text-sm text-gray-600">Once again ...</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 ml-4">
|
||||||
|
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
|
||||||
type="password" id="password_repeat"
|
type="password" id="password_repeat"
|
||||||
name="password_repeat" placeholder="Repeat your password" minlength="6" required>
|
name="password_repeat" placeholder="Repeat your password" minlength="6" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between float-right">
|
</div>
|
||||||
<button type="submit"
|
|
||||||
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
<div class="flex justify-end mt-4">
|
||||||
|
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
|
||||||
|
|
||||||
<details class="mb-8 pb-8 border-b border-gray-700" id="details-aliases">
|
<div id="data" class="tab flex flex-col space-y-4" v-if="isActive('data')">
|
||||||
<summary class="cursor-pointer">
|
<!-- Aliases -->
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block">
|
<div class="w-full">
|
||||||
Aliases
|
<div class="flex mb-8">
|
||||||
</h2>
|
<div class="w-1/3 mr-4 inline-block">
|
||||||
</summary>
|
<span class="font-semibold text-gray-300 text-lg">Aliases</span>
|
||||||
<div class="w-full" id="aliases">
|
<p class="block text-sm text-gray-600">You can specify aliases for any type of entity. For instance, you can define a rule, that both "myapp-frontend" and "myapp-backend" are combined under a project called "myapp".</p>
|
||||||
<div class="text-gray-300 text-sm mb-4 mt-6">
|
|
||||||
You can specify aliases for any type of entity. For instance, you can define a rule, that both <span
|
|
||||||
class="inline-block mb-1 text-gray-500 italic">myapp-frontend</span> and <span
|
|
||||||
class="inline-block mb-1 text-gray-500 italic">myapp-backend</span> are combined under a
|
|
||||||
project called <span class="inline-block mb-1 text-gray-500 italic">myapp</span>.
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="w-2/3 ml-4 inline-block">
|
||||||
{{ if .Aliases }}
|
{{ if .Aliases }}
|
||||||
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Rules</h3>
|
<div class="mb-8">
|
||||||
|
<h3 class="inline-block font-semibold text-gray-300">Rules</h3>
|
||||||
{{ range $i, $alias := .Aliases }}
|
{{ range $i, $alias := .Aliases }}
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm"
|
<div class="text-gray-300 border-1 w-full inline-block my-1 py-1 text-align text-sm"
|
||||||
style="line-height: 1.8">
|
style="line-height: 1.8">
|
||||||
▸ All <span class="underline">{{ $alias.Type | typeName }}s</span> named
|
▸ All <span class="font-semibold">{{ $alias.Type | typeName }}s</span> named
|
||||||
{{ range $j, $value := $alias.Values }}
|
{{ range $j, $value := $alias.Values }}
|
||||||
<span class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono">{{- $value -}}</span>
|
<span class="text-white text-sm bg-gray-900 rounded py-1 px-2 font-semibold text-green-700">{{- $value -}}</span>
|
||||||
{{ if lt $j (add (len $alias.Values) -2) }}
|
{{ if lt $j (add (len $alias.Values) -2) }}
|
||||||
<span class="-ml-1">{{- ", " | capitalize -}}</span>
|
<span class="-ml-1">{{- ", " | capitalize -}}</span>
|
||||||
{{ else if lt $j (add (len $alias.Values) -1) }}
|
{{ else if lt $j (add (len $alias.Values) -1) }}
|
||||||
<span>{{- "or" -}}</span>
|
<span>{{- "or" -}}</span>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
are mapped to <span class="underline">{{ $alias.Type | typeName }}</span> <span
|
are mapped to <span class="font-semibold">{{ $alias.Type | typeName }}</span> <span
|
||||||
class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono">{{ $alias.Key }}</span>.
|
class="text-white text-sm bg-gray-900 rounded py-1 px-2 font-semibold text-green-700">{{ $alias.Key }}</span>
|
||||||
</div>
|
</div>
|
||||||
<form class="float-right" action="" method="post">
|
<form class="float-right" action="" method="post">
|
||||||
<input type="hidden" name="action" value="delete_alias">
|
<input type="hidden" name="action" value="delete_alias">
|
||||||
<input type="hidden" id="delete_alias_key" name="key" required value="{{ $alias.Key }}">
|
<input type="hidden" id="delete_alias_key" name="key" required value="{{ $alias.Key }}">
|
||||||
<input type="hidden" id="delete_alias_type" name="type" required value="{{ $alias.Type }}">
|
<input type="hidden" id="delete_alias_type" name="type" required value="{{ $alias.Type }}">
|
||||||
<button type="submit"
|
<button type="submit" class="py-2 px-4 rounded bg-gray-850 hover:bg-gray-800 text-red-600 text-sm" title="Delete rule">✕</button>
|
||||||
class="py-1 px-3 rounded border border-red-500 hover:border-red-600 text-gray-400 text-sm">
|
|
||||||
✕
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="mb-8"></div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white mb-2">Add Rule</h3>
|
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
|
<h3 class="inline-block font-semibold text-gray-300">Add Rule</h3>
|
||||||
|
|
||||||
<input type="hidden" name="action" value="add_alias">
|
<input type="hidden" name="action" value="add_alias">
|
||||||
<div class="flex items-center mt-2 w-full text-gray-500 text-sm">
|
<div class="flex items-center mt-2 w-full text-gray-500 text-sm">
|
||||||
<span class="mr-2">Map</span>
|
<span class="mr-2">Map</span>
|
||||||
<select name="type" id="select-type"
|
<select name="type" id="select-type"
|
||||||
class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3 cursor-pointer">
|
class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
|
||||||
{{ range $i, $t := entityTypes }}
|
{{ range $i, $t := entityTypes }}
|
||||||
<option value="{{ $t }}">{{ $t | typeName | capitalize }}</option>
|
<option value="{{ $t }}">{{ $t | typeName | capitalize }}</option>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
<span class="mx-2">named</span>
|
<span class="mx-2">named</span>
|
||||||
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"
|
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
|
||||||
type="text" id="alias-value" style="width: 130px;"
|
type="text" id="alias-value" style="width: 130px;"
|
||||||
name="value" placeholder="myapp-frontend" minlength="1" required>
|
name="value" placeholder="Original name" minlength="1" required>
|
||||||
<span class="mx-2">to</span>
|
<span class="mx-2">to</span>
|
||||||
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"
|
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
|
||||||
type="text" id="alias-key" style="width: 100px"
|
type="text" id="alias-key" style="width: 100px"
|
||||||
name="key" placeholder="myapp" minlength="1" required>
|
name="key" placeholder="Replacement" minlength="1" required>
|
||||||
<div class="flex-grow flex justify-end">
|
<div class="flex justify-end ml-4">
|
||||||
<button type="submit"
|
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
||||||
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
|
|
||||||
<details class="mb-8 pb-8 border-b border-gray-700" id="details-labels">
|
|
||||||
<summary class="cursor-pointer">
|
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block">
|
|
||||||
Project Labels
|
|
||||||
</h2>
|
|
||||||
</summary>
|
|
||||||
<div class="w-full" id="project-labels">
|
|
||||||
<div class="text-gray-300 text-sm mb-4 mt-6">
|
|
||||||
You can assign labels (aka. tags) to projects to group them together, e.g. by <span class="inline-block mb-1 text-gray-500 italic">private</span> and <span
|
|
||||||
class="inline-block mb-1 text-gray-500 italic">work</span>.
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<hr class="border-t border-gray-800 my-4">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Project Labels -->
|
||||||
|
<div class="w-full">
|
||||||
|
<div class="flex mb-8">
|
||||||
|
<div class="w-1/3 mr-4 inline-block">
|
||||||
|
<span class="font-semibold text-gray-300 text-lg">Project Labels</span>
|
||||||
|
<p class="block text-sm text-gray-600">You can assign labels (aka. tags) to projects to group them together, e.g. by "private" and "work".</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-2/3 ml-4 inline-block">
|
||||||
{{ if .Labels }}
|
{{ if .Labels }}
|
||||||
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Labels</h3>
|
<div class="mb-8">
|
||||||
|
<h3 class="inline-block font-semibold text-gray-300">Labels</h3>
|
||||||
{{ range $i, $label := .Labels }}
|
{{ range $i, $label := .Labels }}
|
||||||
<div class="flex items-center" action="" method="post">
|
<div class="flex items-center" action="" method="post">
|
||||||
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm"
|
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm"
|
||||||
style="line-height: 1.8">
|
style="line-height: 1.8">
|
||||||
▸ <span class="font-semibold text-white font-mono">{{ $label.Key }}:</span>
|
▸ <span class="font-semibold text-gray-300">{{ $label.Key }}:</span>
|
||||||
{{ range $j, $value := $label.Values }}
|
{{ range $j, $value := $label.Values }}
|
||||||
<form action="" method="post" class="text-white text-xs bg-gray-900 rounded-full py-1 px-2 my-1 inline-flex justify-between items-center space-x-2">
|
<form action="" method="post" class="text-white text-xs bg-gray-900 rounded-full py-1 px-2 my-1 inline-flex justify-between items-center space-x-2">
|
||||||
<input type="hidden" name="action" value="delete_label">
|
<input type="hidden" name="action" value="delete_label">
|
||||||
<input type="hidden" name="key" value="{{ $label.Key }}">
|
<input type="hidden" name="key" value="{{ $label.Key }}">
|
||||||
<input type="hidden" name="value" value="{{ $value }}">
|
<input type="hidden" name="value" value="{{ $value }}">
|
||||||
<span>{{- $value -}}</span>
|
<span>{{- $value -}}</span>
|
||||||
<button type="submit" class="bg-gray-800 text-center hover:bg-gray-700 rounded-full w-4 h-4 leading-none" title="Delete label">x</button>
|
<button type="submit" class="bg-gray-800 text-center hover:bg-gray-700 rounded-full w-4 h-4 leading-none text-red-600" title="Delete label">x</button>
|
||||||
</form>
|
</form>
|
||||||
{{ if lt $j (add (len $label.Values) -1) }}
|
{{ if lt $j (add (len $label.Values) -1) }}
|
||||||
<span class="-ml-1">{{- ", " | capitalize -}}</span>
|
<span class="-ml-1">{{- ", " | capitalize -}}</span>
|
||||||
@ -238,33 +278,23 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="mb-8"></div>
|
<div class="mb-8"></div>
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{ if .Projects }}
|
{{ if .Projects }}
|
||||||
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white mb-2">Add Label</h3>
|
<h3 class="inline-block font-semibold text-gray-300">Add Label</h3>
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
<input type="hidden" name="action" value="add_label">
|
<input type="hidden" name="action" value="add_label">
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
<div class="flex justify-between items-center mt-2 w-full text-gray-500 text-sm space-x-4">
|
<div class="flex items-center mt-2 w-full text-gray-500 text-sm space-x-4">
|
||||||
<div class="w-1/2 flex flex-col flex-grow">
|
|
||||||
<span>Project</span>
|
|
||||||
<select name="key" id="select-project"
|
<select name="key" id="select-project"
|
||||||
class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3 cursor-pointer">
|
class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
|
||||||
{{ range $i, $p := .Projects }}
|
{{ range $i, $p := .Projects }}
|
||||||
<option value="{{ $p }}">{{ $p }}</option>
|
<option value="{{ $p }}">{{ $p }}</option>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
|
||||||
<div class="w-1/2 flex flex-col flex-grow">
|
|
||||||
<span>Label</span>
|
|
||||||
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"
|
|
||||||
type="text" id="label-value"
|
type="text" id="label-value"
|
||||||
name="value" placeholder="work" minlength="1" required>
|
name="value" placeholder="Label" minlength="1" required>
|
||||||
</div>
|
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
||||||
</div>
|
|
||||||
<div class="flex-grow flex justify-end">
|
|
||||||
<button type="submit"
|
|
||||||
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -274,68 +304,72 @@
|
|||||||
<div class="text-gray-300 text-sm mb-4 mt-6">You don't have any projects, yet. Start out by sending a few heartbeats before you can then assign labels.</div>
|
<div class="text-gray-300 text-sm mb-4 mt-6">You don't have any projects, yet. Start out by sending a few heartbeats before you can then assign labels.</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</details>
|
{{end}}
|
||||||
|
</div>
|
||||||
<details class="mb-8 pb-8 border-b border-gray-700" id="details-mappings">
|
</div>
|
||||||
<summary class="cursor-pointer">
|
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"
|
|
||||||
id="languages">
|
|
||||||
Custom Mappings
|
|
||||||
</h2>
|
|
||||||
</summary>
|
|
||||||
<div class="w-full">
|
|
||||||
<div class="text-gray-300 text-sm mb-4 mt-6">
|
|
||||||
You can specify custom mapping from file extensions to programming languages, for instance a <span
|
|
||||||
class="inline-block mb-1 text-gray-500 italic">.jsx</span> file could be mapped to the <span
|
|
||||||
class="inline-block mb-1 text-gray-500 italic">React</span> language.
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<hr class="border-t border-gray-800 my-4">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Language Mappings -->
|
||||||
|
<div class="w-full">
|
||||||
|
<div class="flex mb-8">
|
||||||
|
<div class="w-1/3 mr-4 inline-block">
|
||||||
|
<span class="font-semibold text-gray-300 text-lg">Language Mappings</span>
|
||||||
|
<p class="block text-sm text-gray-600">You can specify custom mapping from file extensions to programming languages, for instance a ".jsx" file could be mapped to the "React" language.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-2/3 ml-4 inline-block">
|
||||||
{{ if .LanguageMappings }}
|
{{ if .LanguageMappings }}
|
||||||
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Rules</h3>
|
<div class="mb-8">
|
||||||
|
<h3 class="inline-block font-semibold text-gray-300">Rules</h3>
|
||||||
{{ range $i, $mapping := .LanguageMappings }}
|
{{ range $i, $mapping := .LanguageMappings }}
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm">
|
<div class="text-gray-300 border-1 w-full inline-block my-1 py-1 text-align text-sm">
|
||||||
▸ When filename ends in <span
|
▸ When filename ends in <span
|
||||||
class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono mr-1">{{ $mapping.Extension }}</span>
|
class="text-green-700 text-sm bg-gray-900 rounded py-1 px-2 font-semibold mr-1">{{ $mapping.Extension }}</span>
|
||||||
then change the <span class="underline">language</span> to <span
|
then change the <span class="font-semibold">language</span> to <span
|
||||||
class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono mr-1">{{ $mapping.Language }}</span>
|
class="text-green-700 text-sm bg-gray-900 rounded py-1 px-2 font-semibold mr-1">{{ $mapping.Language }}</span>
|
||||||
</div>
|
</div>
|
||||||
<form class="float-right" action="" method="post">
|
<form class="float-right" action="" method="post">
|
||||||
<input type="hidden" name="action" value="delete_mapping">
|
<input type="hidden" name="action" value="delete_mapping">
|
||||||
<input type="hidden" id="mapping_id" name="mapping_id" required value="{{ $mapping.ID }}">
|
<input type="hidden" id="mapping_id" name="mapping_id" required value="{{ $mapping.ID }}">
|
||||||
<button type="submit"
|
<button type="submit" class="py-2 px-4 rounded bg-gray-850 hover:bg-gray-800 text-red-600 text-sm" title="Delete rule">✕</button>
|
||||||
class="py-1 px-3 rounded border border-red-500 hover:border-red-600 text-gray-400 text-sm">
|
|
||||||
✕
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="mb-8"></div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Add Rule</h3>
|
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
|
<h3 class="inline-block font-semibold text-gray-300">Add Rule</h3>
|
||||||
|
|
||||||
<input type="hidden" name="action" value="add_mapping">
|
<input type="hidden" name="action" value="add_mapping">
|
||||||
<div class="flex items-center w-full text-gray-500 text-sm">
|
<div class="flex items-center w-full text-gray-500 text-sm">
|
||||||
<span class="mr-2">When filename ends in</span>
|
<span class="mr-2">When filename ends in</span>
|
||||||
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"
|
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer"
|
||||||
type="text" id="extension" style="width: 70px"
|
type="text" id="extension" style="width: 70px"
|
||||||
name="extension" placeholder=".py" minlength="1" required>
|
name="extension" placeholder=".py" minlength="1" required>
|
||||||
<span class="mx-2">change language to</span>
|
<span class="mx-2">change language to</span>
|
||||||
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"
|
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer"
|
||||||
type="text" id="language" style="width: 100px"
|
type="text" id="language" style="width: 100px"
|
||||||
name="language" placeholder="Python" minlength="1" required>
|
name="language" placeholder="Python" minlength="1" required>
|
||||||
<div class="flex-grow flex justify-end">
|
<div class="flex justify-end ml-4">
|
||||||
<button type="submit"
|
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
||||||
class="py-1 px-3 my-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
|
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="permissions" class="tab flex flex-col space-y-4" v-if="isActive('permissions')">
|
||||||
|
<!-- TODO -->
|
||||||
<details class="mb-8 pb-8 border-b border-gray-700" id="details-public-data">
|
<details class="mb-8 pb-8 border-b border-gray-700" id="details-public-data">
|
||||||
<summary class="cursor-pointer">
|
<summary class="cursor-pointer">
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block">
|
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block">
|
||||||
@ -460,7 +494,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="integrations" class="tab flex flex-col space-y-4" v-if="isActive('integrations')">
|
||||||
|
<!-- TODO -->
|
||||||
<details class="mb-8 pb-8 border-b border-gray-700" id="details-integrations">
|
<details class="mb-8 pb-8 border-b border-gray-700" id="details-integrations">
|
||||||
<summary class="cursor-pointer">
|
<summary class="cursor-pointer">
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"
|
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"
|
||||||
@ -617,7 +654,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="danger_zone" class="tab flex flex-col space-y-4" v-if="isActive('danger_zone')">
|
||||||
|
<!-- TODO -->
|
||||||
<details class="mb-8 pb-8" id="details-danger-zone">
|
<details class="mb-8 pb-8" id="details-danger-zone">
|
||||||
<summary class="cursor-pointer">
|
<summary class="cursor-pointer">
|
||||||
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" id="danger">
|
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" id="danger">
|
||||||
@ -704,6 +744,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<main class="mt-10 flex-grow flex justify-center w-full">
|
<main class="mt-10 flex-grow flex justify-center w-full">
|
||||||
<div class="flex-grow max-w-lg mt-10">
|
<div class="flex-grow max-w-lg mt-10">
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<h1 class="font-semibold text-2xl text-white m-0 mb-2">Sign up to Wakapi</h1>
|
<h1 class="font-semibold text-3xl text-white m-0 mb-2">Sign up to Wakapi</h1>
|
||||||
<p class="text-sm text-gray-600">
|
<p class="text-sm text-gray-600">
|
||||||
Welcome to Wakapi! Your first step is to create an account.
|
Welcome to Wakapi! Your first step is to create an account.
|
||||||
Afterwards, make sure to set up the <a href="https://wakatime.com" target="_blank" rel="noopener noreferrer" class="text-gray-300 hover:text-gray-400">WakaTime</a> client tools.
|
Afterwards, make sure to set up the <a href="https://wakatime.com" target="_blank" rel="noopener noreferrer" class="text-gray-300 hover:text-gray-400">WakaTime</a> client tools.
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
{{ template "menu-main.tpl.html" . }}
|
{{ template "menu-main.tpl.html" . }}
|
||||||
|
|
||||||
|
{{ template "alerts.tpl.html" . }}
|
||||||
|
|
||||||
{{ if .User.HasData }}
|
{{ if .User.HasData }}
|
||||||
|
|
||||||
<div class="flex justify-end mt-12 relative">
|
<div class="flex justify-end mt-12 relative">
|
||||||
@ -46,8 +48,6 @@
|
|||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ template "alerts.tpl.html" . }}
|
|
||||||
|
|
||||||
<main class="flex flex-col items-center mt-10 flex-grow">
|
<main class="flex flex-col items-center mt-10 flex-grow">
|
||||||
|
|
||||||
{{ if .User.HasData }}
|
{{ if .User.HasData }}
|
||||||
@ -161,7 +161,7 @@
|
|||||||
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="label-container" style="height: 300px">
|
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="label-container" style="height: 300px">
|
||||||
<div class="flex justify-between text-lg">
|
<div class="flex justify-between text-lg">
|
||||||
<span class="font-semibold whitespace-no-wrap">Labels</span>
|
<span class="font-semibold whitespace-no-wrap">Labels</span>
|
||||||
<a href="settings#details-labels" class="ml-4 h-8 inline flex-grow">
|
<a href="settings#data" class="ml-4 inline p-2 hover:bg-gray-800 rounded" style="margin-top: -5px">
|
||||||
<span class="iconify inline" data-icon="twemoji:gear"></span>
|
<span class="iconify inline" data-icon="twemoji:gear"></span>
|
||||||
</a>
|
</a>
|
||||||
<div class="flex justify-end flex-1 text-xs items-center">
|
<div class="flex justify-end flex-1 text-xs items-center">
|
||||||
@ -182,12 +182,12 @@
|
|||||||
<div class="pb-4">
|
<div class="pb-4">
|
||||||
<img src="assets/images/welcome.svg" width="200px" alt="User welcome illustration">
|
<img src="assets/images/welcome.svg" width="200px" alt="User welcome illustration">
|
||||||
</div>
|
</div>
|
||||||
<h1 class="font-semibold text-2xl text-white m-0 w-full">Welcome to Wakapi!</h1>
|
<h1 class="font-semibold text-3xl text-white m-0 w-full">Welcome to Wakapi!</h1>
|
||||||
<p>
|
<p>
|
||||||
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.
|
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>
|
</p>
|
||||||
<div class="w-full pt-10 flex flex-col space-y-4">
|
<div class="w-full pt-10 flex flex-col space-y-4">
|
||||||
<h1 class="font-semibold text-2xl text-white m-0 mb-2">Setup Instructions</h1>
|
<h1 class="font-semibold text-3xl text-white m-0 mb-2">Setup Instructions</h1>
|
||||||
<div class="w-full bg-gray-850 text-left rounded-md py-4 px-8 text-xs font-mono shadow-md">
|
<div class="w-full bg-gray-850 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>
|
# <strong>Step 1:</strong> Download WakaTime plugin for your IDE<br>
|
||||||
# See: https://wakatime.com/plugins<br><br>
|
# See: https://wakatime.com/plugins<br><br>
|
||||||
@ -238,8 +238,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script src="assets/app.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user