refactor: redefine tailwind build

chore: encapsulate commonly used css classes
chore: add npm scripts for building tailwind and iconify assets
This commit is contained in:
Ferdinand Mütsch 2021-12-19 13:04:00 +01:00
parent c217f8e664
commit aebfdc535d
22 changed files with 1270 additions and 106764 deletions

2
.gitignore vendored
View File

@ -9,7 +9,5 @@ config*.yml
!config.default.yml
!testing/config.testing.yml
pkged.go
package.json
yarn.lock
package-lock.json
node_modules

View File

@ -299,17 +299,11 @@ $ ./testing/run_api_tests.sh
## 🤓 Developer Notes
### Building web assets
To keep things minimal, Wakapi does not contain a `package.json`, `node_modules` or any sort of frontend build step. Instead, all JS and CSS assets are included as static files and checked in to Git. This way we can avoid requiring NodeJS to build Wakapi. However, for [TailwindCSS](https://tailwindcss.com/docs/installation#building-for-production) it makes sense to run it through a "build" step to benefit from purging and significantly reduce it in size. To only require this at the time of development, the compiled asset is checked in to Git as well. Similarly, [Iconify](https://iconify.design/docs/icon-bundles/) bundles are also created at development time and checked in to the repo.
To keep things minimal, all JS and CSS assets are included as static files and checked in to Git. [TailwindCSS](https://tailwindcss.com/docs/installation#building-for-production) and [Iconify](https://iconify.design/docs/icon-bundles/) require an additional build step. To only require this at the time of development, the compiled assets are checked in to Git as well.
#### TailwindCSS
```bash
$ tailwindcss-cli build static/assets/vendor/tailwind.css -o static/assets/vendor/tailwind.dist.css
```
#### Iconify
```bash
$ yarn add -D @iconify/json-tools @iconify/json
$ node scripts/bundle_icons.js
$ yarn
$ yarn build # or: yarn watch
```
New icons can be added by editing the `icons` array in [scripts/bundle_icons.js](scripts/bundle_icons.js).

15
package.json Normal file
View File

@ -0,0 +1,15 @@
{
"scripts": {
"build": "npm run build:icons && npm run build:tailwind",
"build:tailwind": "tailwindcss build -i static/assets/css/app.css -o static/assets/css/app.dist.css --minify",
"build:icons": "node scripts/bundle_icons.js",
"watch": "chokidar \"./views/**/*.html\" \"./static/assets/js/**/*.js\" \"./static/assets/css/**/*.css\" -i \"**/vendor/*\" -i \"**/*.dist.*\" -c \"npm run build\""
},
"devDependencies": {
"@iconify/json": "^1.1.444",
"@iconify/json-tools": "^1.0.10",
"chokidar-cli": "^3.0.0",
"tailwindcss": "2.2.19"
},
"dependencies": {}
}

View File

@ -56,7 +56,7 @@ let icons = [
'fluent:key-24-filled'
]
const output = path.normalize(path.join(__dirname, '../static/assets/js/icons.js'))
const output = path.normalize(path.join(__dirname, '../static/assets/js/icons.dist.js'))
const pretty = false
// Sort icons by collections: filtered[prefix][array of icons]

View File

@ -1,39 +0,0 @@
body {
font-family: 'Source Sans 3', 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
}
[v-cloak] {
display: none;
}
.bg-gray-850 {
background-color: #242b3a;
}
.hover\:bg-gray-850:hover {
--bg-opacity: 1;
background-color: #242b3a;
}
::-webkit-calendar-picker-indicator {
filter: invert(1);
cursor: pointer;
}
.text-xxs {
font-size: 0.65rem;
}
.mt-14 {
margin-top: 3.5rem;
}
.text-7xl {
font-size: 4.5rem;
line-height: 1.1;
}
.text-8xl {
font-size: 5rem;
line-height: 1.1;
}

95
static/assets/css/app.css Normal file
View File

@ -0,0 +1,95 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Base definition */
body {
font-family: 'Source Sans 3', 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
}
[v-cloak] {
display: none;
}
/* Additional classes */
.bg-gray-850 {
background-color: #242b3a;
}
.hover\:bg-gray-850:hover {
--bg-opacity: 1;
background-color: #242b3a;
}
.text-xxs {
font-size: 0.65rem;
}
.mt-14 {
margin-top: 3.5rem;
}
.text-7xl {
font-size: 4.5rem;
line-height: 1.1;
}
.text-8xl {
font-size: 5rem;
line-height: 1.1;
}
.imp\:cursor-not-allowed {
@apply cursor-not-allowed !important;
}
/* Custom classes */
.h1 {
@apply font-semibold text-3xl text-white m-0
}
.h1-subcaption {
@apply text-gray-600 text-sm;
}
.btn-default {
@apply py-2 px-4 font-semibold rounded bg-gray-800 hover:bg-gray-850 text-white text-sm;
}
.btn-primary {
@apply py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm;
}
.btn-danger {
@apply py-2 px-4 font-semibold rounded bg-red-600 hover:bg-red-700 text-white text-sm;
}
.input-default {
@apply appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4;
}
.select-default {
@apply input-default cursor-pointer;
}
.menu-item {
@apply flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer;
}
.submenu-item {
@apply hover:bg-gray-800 rounded p-1 text-right;
}
.chip {
@apply text-xs bg-gray-850 rounded rounded-full py-1 px-2 font-semibold inline-block mb-1;
}
.link {
@apply font-semibold text-gray-400 hover:text-gray-300;
}
::-webkit-calendar-picker-indicator {
filter: invert(1);
cursor: pointer;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<script src="assets/vendor/iconify.basic.min.js"></script>
<script src="assets/vendor/seedrandom.min.js"></script>
<script src="assets/vendor/chart.min.js"></script>
<script src="assets/js/icons.js"></script>
<script src="assets/js/icons.dist.js"></script>
<script src="assets/js/base.js"></script>

View File

@ -11,11 +11,6 @@
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon-16x16.png">
<link rel="manifest" href="assets/site.webmanifest">
<link href="assets/vendor/source-sans-3.css" rel="stylesheet">
{{ if isDev }}
<link href="assets/vendor/tailwind.css" rel="stylesheet">
{{ else }}
<link href="assets/vendor/tailwind.dist.css" rel="stylesheet">
{{ end }}
<link href="assets/app.css" rel="stylesheet">
<link href="assets/css/app.dist.css" rel="stylesheet">
<script src="assets/vendor/petite-vue.min.js" defer></script>
</head>

View File

@ -9,7 +9,7 @@
<main class="mt-10 flex-grow flex w-full">
<div class="flex-grow max-w-4xl flex flex-col">
<h1 class="font-semibold text-3xl text-white m-0">Imprint & Data Privacy</h1>
<h1 class="h1">Imprint & Data Privacy</h1>
<p>
{{ htmlSafe .HtmlText }}
</p>

View File

@ -11,7 +11,7 @@
<div class="absolute flex top-0 right-0 mr-8 mt-10 py-2">
<div class="mx-1">
<a href="login" class="py-2 px-4 block rounded bg-green-700 hover:bg-green-800 text-white text-sm font-semibold">
<a href="login" class="btn-primary">
<span class="iconify inline" data-icon="fluent:key-24-filled"></span> &nbsp;Login</a>
</div>
</div>
@ -27,25 +27,25 @@
<div class="flex justify-center mt-8 mb-4 space-x-2">
<a href="login">
<button type="button"
class="py-2 px-4 rounded bg-green-700 hover:bg-green-800 text-white font-semibold"><span class="iconify inline" data-icon="ion:rocket"></span> Let's Go!
class="btn-primary"><span class="iconify inline" data-icon="ion:rocket"></span> Let's Go!
</button>
</a>
<a href="https://github.com/muety/wakapi#%EF%B8%8F-how-to-use" target="_blank" rel="noopener noreferrer">
<button type="button" class="py-2 px-4 rounded bg-gray-800 hover:bg-gray-850 text-white"><span class="iconify inline" data-icon="heroicons-solid:server"></span> Get Your Own
<button type="button" class="btn-default"><span class="iconify inline" data-icon="heroicons-solid:server"></span> Get Your Own
</button>
</a>
<a href="https://github.com/sponsors/muety" target="_blank" rel="noopener noreferrer">
<button type="button" class="py-2 px-4 rounded bg-gray-800 hover:bg-gray-850 text-white"><span class="iconify inline" data-icon="bx:bxs-heart"></span> Support Us
<button type="button" class="btn-default"><span class="iconify inline" data-icon="bx:bxs-heart"></span> Support Us
</button>
</a>
<a href="https://github.com/muety/wakapi" target="_blank" rel="noopener noreferrer">
<button type="button" class="py-2 px-4 rounded bg-gray-800 hover:bg-gray-850 text-white">
<button type="button" class="btn-default">
<span class="iconify inline text-white" data-icon="codicon:github-inverted"></span>
</button>
</a>
</div>
<p class="text-center text-gray-500 text-sm mb-4">
<p class="text-center text-gray-500 text-sm my-4">
This system has tracked a total of </span>
{{ range $d := .TotalHours | printf "%d" | toRunes }}
<span class="bg-gray-900 rounded-sm p-1 border border-gray-700 font-mono text-gray-400" style="margin: auto -1px;" title="{{ $.TotalHours }} hours (updated every hour)">{{ $d }}</span>

View File

@ -12,17 +12,17 @@
<main class="mt-10 flex-grow flex justify-center w-full">
<div class="flex-grow max-w-lg mt-10">
<div class="mb-8">
<h1 class="font-semibold text-3xl text-white m-0">Welcome!</h1>
<span class="text-gray-600">Log in to continue using Wakapi</span>
<h1 class="h1">Welcome!</h1>
<span class="h1-subcaption">Log in to continue using Wakapi</span>
</div>
<form action="login" method="post">
<div class="mb-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<input class="input-default"
type="text" id="username" autocomplete="username"
name="username" placeholder="Username" minlength="1" required autofocus>
</div>
<div class="mb-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<input class="input-default"
type="password" id="password" autocomplete="current-password"
name="password" placeholder="Password" minlength="6" required>
</div>
@ -32,9 +32,9 @@
</a>
<div class="flex space-x-2">
<a href="signup">
<button type="button" class="py-2 px-4 font-semibold rounded bg-gray-800 hover:bg-gray-850 text-white text-sm">Sign up</button>
<button type="button" class="btn-default">Sign up</button>
</a>
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">Log in</button>
<button type="submit" class="btn-primary">Log in</button>
</div>
</div>
</form>

View File

@ -5,51 +5,51 @@
{{ template "logo.tpl.html" }}
</div>
<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">
<a class="menu-item" href="summary">
<span class="iconify inline text-2xl text-gray-400" data-icon="ic:round-dashboard"></span>
<span class="text-gray-300 hidden lg:inline-block">Dashboard</span>
</a>
<div class="menu-item hidden sm: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 hidden sm:flex imp:cursor-not-allowed">
<span class="iconify inline text-2xl text-gray-700" data-icon="bi:people-fill"></span>
<a class="text-gray-600 leading-none hidden lg:inline-block">Team<br>
<span class="text-xxs whitespace-no-wrap">(coming soon)</span>
<span class="text-xxs whitespace-nowrap">(coming soon)</span>
</a>
</div>
<div class="menu-item hidden sm: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 hidden sm:flex imp:cursor-not-allowed">
<span class="iconify inline text-2xl text-gray-700" data-icon="fluent:data-bar-horizontal-24-filled"></span>
<a class="text-gray-600 leading-none hidden lg:inline-block">Leaderboard<br>
<span class="text-xxs whitespace-no-wrap">(coming soon)</span>
<span class="text-xxs whitespace-nowrap">(coming soon)</span>
</a>
</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 relative" @click="state.showDropdownResources = !state.showDropdownResources" data-trigger-for="showDropdownResources">
<div class="menu-item relative" @click="state.showDropdownResources = !state.showDropdownResources" data-trigger-for="showDropdownResources">
<span class="iconify inline text-2xl text-gray-400" data-icon="ph:books-bold"></span>
<a class="text-gray-400 hidden lg:inline-block">Resources</a>
<span class="iconify inline text-xl text-gray-400" data-icon="akar-icons:chevron-down"></span>
<div v-cloak v-show="state.showDropdownResources" class="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" style="min-width: 128px">
<div class="flex-grow flex flex-col">
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<div class="submenu-item">
<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" @click="state.showDropdownResources = !state.showDropdownResources" data-trigger-for="showDropdownResources">
<span class="text-sm">GitHub</span>
<span class="iconify inline" data-icon="codicon:github-inverted"></span>
</a>
</div>
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<div class="submenu-item">
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="swagger-ui" @click="state.showDropdownResources = !state.showDropdownResources" data-trigger-for="showDropdownResources">
<span class="text-sm">API Docs</span>
<span class="iconify inline" data-icon="bx:bx-code-curly"></span>
</a>
</div>
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<div class="submenu-item">
<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" @click="state.showDropdownResources = !state.showDropdownResources" data-trigger-for="showDropdownResources">
<span class="text-sm">WakaTime</span>
<span class="iconify inline" data-icon="simple-icons:wakatime"></span>
</a>
</div>
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<div class="submenu-item">
<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" @click="state.showDropdownResources = !state.showDropdownResources" data-trigger-for="showDropdownResources">
<span class="text-sm">Donate</span>
<span class="iconify inline" data-icon="bx:bxs-heart"></span>
@ -59,14 +59,14 @@
</div>
</div>
<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">
<a class="menu-item" href="settings">
<span class="iconify inline text-2xl text-gray-400" data-icon="ci:settings-filled"></span>
<span class="text-gray-400 hidden lg:inline-block">Settings</span>
</a>
<div class="flex-grow"></div>
<div class="flex-shrink-0 menu-item flex items-center text-sm font-semibold space-x-3 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer relative" @click="state.showDropdownUser = !state.showDropdownUser" data-trigger-for="showDropdownUser">
<div class="flex-shrink-0 menu-item relative" @click="state.showDropdownUser = !state.showDropdownUser" data-trigger-for="showDropdownUser">
<div class="hidden md:flex flex flex-col text-right">
<a class="text-gray-300">{{ .User.ID }}</a>
{{ if .User.Email }}
@ -79,7 +79,7 @@
<span class="iconify inline cursor-pointer text-gray-500 rounded-full border-green-700" style="width: 32px; height: 32px" data-icon="ic:round-person" @click="state.showDropdownUser = !state.showDropdownUser" data-trigger-for="showDropdownUser"></span>
{{ end }}
<div v-cloak v-show="state.showDropdownUser" class="flex bg-gray-850 shadow-md z-10 p-2 absolute top-0 right-0 rounded popup mt-14 w-full" id="user-menu-popup" style="min-width: 156px;">
<div v-cloak v-show="state.showDropdownUser" class="flex bg-gray-850 shadow-md z-10 p-2 absolute top-0 right-0 rounded popup mt-16 w-full" id="user-menu-popup" style="min-width: 156px;">
<div class="flex-grow flex flex-col">
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<button class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" @click="state.showApiKey = true" data-trigger-for="showApiKey">

View File

@ -12,20 +12,20 @@
<main class="mt-10 flex-grow flex justify-center w-full">
<div class="flex-grow max-w-lg mt-10">
<div class="mb-8">
<h1 class="font-semibold text-3xl text-white m-0">Reset Password</h1>
<span class="text-gray-600">
<h1 class="h1">Reset Password</h1>
<span class="h1-subcaption">
If you forgot your password, enter the e-mail address you associated with Wakapi to reset it and choose a new one. You will receive an e-mail afterwards. Make sure to check your spam folder.
</span>
</div>
<form action="reset-password" method="post">
<p class="text-sm text-white mb-8"></p>
<div class="mb-8">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<div class="mb-4">
<input class="input-default"
type="email" id="email"
name="email" placeholder="Enter your e-mail address" minlength="1" required autofocus>
</div>
<div class="flex justify-end items-center">
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">Reset</button>
<button type="submit" class="btn-primary">Reset</button>
</div>
</form>
</div>

View File

@ -7,30 +7,28 @@
{{ template "header.tpl.html" . }}
<div class="flex items-center justify-center">
<h1 class="font-semibold text-xl text-white m-0 border-b-4 border-green-700">Choose a new password</h1>
</div>
{{ template "alerts.tpl.html" . }}
<main class="mt-10 flex-grow flex justify-center w-full">
<div class="flex-grow max-w-lg mt-10">
<div class="mb-8">
<h1 class="h1">Choose a new password</h1>
<span class="h1-subcaption">You have requested to reset your password. Please choose a new one.</span>
</div>
<form action="set-password" method="post">
<div class="mb-8">
<label class="inline-block text-sm mb-1 text-gray-500" for="password">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="mb-4">
<input class="input-default"
type="password" id="password"
name="password" placeholder="Choose a password" minlength="6" required>
</div>
<div class="mb-8">
<label class="inline-block text-sm mb-1 text-gray-500" for="password_repeat">And again ...</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="mb-4">
<input class="input-default"
type="password" id="password_repeat"
name="password_repeat" placeholder="Repeat your password" minlength="6" required>
</div>
<div class="flex justify-end items-center">
<input type="hidden" name="token" value="{{ .Token }}">
<button type="submit" class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">Save</button>
<button type="submit" class="btn-primary">Save</button>
</div>
</form>
</div>

View File

@ -69,7 +69,7 @@
<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" class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full cursor-pointer" v-model="selectedTimezone">
<select name="location" id="select-timezone" class="select-default" v-model="selectedTimezone">
<option v-for="o in tzOptions" :value="o.value">{{ "{{" }}o.text{{ "}}" }}</option>
</select>
</div>
@ -81,7 +81,7 @@
<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"
<input class="input-default"
type="email" id="email"
name="email" placeholder="Enter your e-mail address"
value="{{ .User.Email }}">
@ -96,7 +96,7 @@
</div>
<div class="w-1/2 ml-4">
<select autocomplete="off" id="reports_weekly" name="reports_weekly"
class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full cursor-pointer">
class="select-default">
<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>
</select>
@ -105,7 +105,7 @@
{{ end }}
<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">
<button type="submit" class="btn-primary">
Save
</button>
</div>
@ -125,7 +125,7 @@
<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"
<input class="input-default"
type="password" id="password_old"
name="password_old" placeholder="Old password" minlength="6" required>
</div>
@ -137,7 +137,7 @@
<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"
<input class="input-default"
type="password" id="password_new"
name="password_new" placeholder="New password" minlength="6" required>
</div>
@ -149,14 +149,14 @@
<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"
<input class="input-default"
type="password" id="password_repeat"
name="password_repeat" placeholder="Repeat your password" minlength="6" required>
</div>
</div>
<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">
<button type="submit" class="btn-primary">
Save
</button>
</div>
@ -166,7 +166,7 @@
<div v-cloak id="data" class="tab flex flex-col space-y-4" v-if="isActive('data')">
<!-- Aliases -->
<div class="w-full">
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/3 mb-4 md:mb-0 inline-block">
<span class="font-semibold text-gray-300 text-lg">Aliases</span>
<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>
@ -182,7 +182,7 @@
style="line-height: 1.8">
&#9656;&nbsp; All <span class="font-semibold">{{ $alias.Type | typeName }}s</span> named
{{ range $j, $value := $alias.Values }}
<span class="text-white text-sm bg-gray-900 rounded py-1 px-2 font-semibold text-green-700">{{- $value -}}</span>
<span class="text-white chip text-green-700">{{- $value -}}</span>
{{ if lt $j (add (len $alias.Values) -2) }}
<span class="-ml-1">{{- ", " | capitalize -}}</span>
{{ else if lt $j (add (len $alias.Values) -1) }}
@ -190,7 +190,7 @@
{{ end }}
{{ end }}
are mapped to <span class="font-semibold">{{ $alias.Type | typeName }}</span> <span
class="text-white text-sm bg-gray-900 rounded py-1 px-2 font-semibold text-green-700">{{ $alias.Key }}</span>
class="text-white chip text-green-700">{{ $alias.Key }}</span>
</div>
<form class="float-right" action="" method="post">
<input type="hidden" name="action" value="delete_alias">
@ -209,22 +209,21 @@
<input type="hidden" name="action" value="add_alias">
<div class="flex items-center mt-2 w-full text-gray-500 text-sm">
<span class="mr-2">Map</span>
<select name="type" id="select-type"
class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select name="type" id="select-type" class="select-default" style="max-width: 256px">
{{ range $i, $t := entityTypes }}
<option value="{{ $t }}">{{ $t | typeName | capitalize }}</option>
{{ end }}
</select>
<span class="mx-2">named</span>
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
<input class="input-default"
type="text" id="alias-value" style="width: 130px;"
name="value" placeholder="Original name" minlength="1" required>
<span class="mx-2">to</span>
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
<input class="input-default"
type="text" id="alias-key" style="width: 100px"
name="key" placeholder="Replacement" minlength="1" required>
<div class="flex justify-end ml-4">
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
<button type="submit" class="btn-primary">
Add
</button>
</div>
@ -240,7 +239,7 @@
<!-- Project Labels -->
<div class="w-full">
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap md:flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/3 mb-4 md:mb-0 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>
@ -256,12 +255,12 @@
style="line-height: 1.8">
&#9656;&nbsp;&nbsp;<span class="font-semibold text-gray-300">{{ $label.Key }}:</span>
{{ 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="chip inline-flex justify-between items-center space-x-2 text-green-700">
<input type="hidden" name="action" value="delete_label">
<input type="hidden" name="key" value="{{ $label.Key }}">
<input type="hidden" name="value" value="{{ $value }}">
<span>{{- $value -}}</span>
<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>
<button type="submit" class="bg-gray-900 text-center hover:bg-gray-700 rounded-full w-4 h-4 leading-none text-red-600" title="Delete label">x</button>
</form>
{{ if lt $j (add (len $label.Values) -1) }}
<span class="-ml-1">{{- ", " | capitalize -}}</span>
@ -279,15 +278,15 @@
<div class="flex flex-col space-y-4">
<div class="flex items-center mt-2 w-full text-gray-500 text-sm space-x-4">
<select name="key" id="select-project"
class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
class="select-default flex-grow">
{{ range $i, $p := .Projects }}
<option value="{{ $p }}">{{ $p }}</option>
{{ end }}
</select>
<input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
<input class="input-default"
type="text" id="label-value"
name="value" placeholder="Label" minlength="1" required>
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
<button type="submit" class="btn-primary">
Add
</button>
</div>
@ -308,7 +307,7 @@
<!-- Language Mappings -->
<div class="w-full">
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap md:flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/3 mb-4 md:mb-0 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>
@ -319,12 +318,12 @@
<div class="mb-8">
<h3 class="inline-block font-semibold text-gray-300">Rules</h3>
{{ range $i, $mapping := .LanguageMappings }}
<div class="flex items-center">
<div class="flex items-center mb-2">
<div class="text-gray-300 border-1 w-full inline-block my-1 py-1 text-align text-sm">
&#9656;&nbsp; When filename ends in <span
class="text-green-700 text-sm bg-gray-900 rounded py-1 px-2 font-semibold mr-1">{{ $mapping.Extension }}</span>
class="text-green-700 chip mr-1">{{ $mapping.Extension }}</span>
then change the <span class="font-semibold">language</span> to <span
class="text-green-700 text-sm bg-gray-900 rounded py-1 px-2 font-semibold mr-1">{{ $mapping.Language }}</span>
class="text-green-700 chip mr-1">{{ $mapping.Language }}</span>
</div>
<form class="float-right" action="" method="post">
<input type="hidden" name="action" value="delete_mapping">
@ -342,15 +341,15 @@
<input type="hidden" name="action" value="add_mapping">
<div class="flex items-center w-full text-gray-500 text-sm">
<span class="mr-2">When filename ends in</span>
<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"
<input class="select-default flex-grow"
type="text" id="extension" style="width: 70px"
name="extension" placeholder=".py" minlength="1" required>
<span class="mx-2">change language to</span>
<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"
<input class="select-default flex-grow"
type="text" id="language" style="width: 100px"
name="language" placeholder="Python" minlength="1" required>
<div class="flex justify-end ml-4">
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
<button type="submit" class="btn-primary">
Add
</button>
</div>
@ -364,7 +363,7 @@
<div v-cloak id="permissions" class="tab flex flex-col space-y-4" v-if="isActive('permissions')">
<!-- Public Data -->
<form action="" method="post" class="w-full lg:w-3/4">
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap md:flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/2 mb-4 md:mb-0 inline-block">
<span class="font-semibold text-gray-300 text-lg">Aliases</span>
<p class="block text-sm text-gray-600">
@ -381,7 +380,7 @@
<span class="block text-sm text-gray-600">(in days; 0 = not public, -1 = unlimited)</span>
</div>
<div >
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
<input class="input-default"
style="max-width: 80px" type="number" id="max_days" name="max_days" min="-1" required
value="{{ .User.ShareDataMaxDays }}">
</div>
@ -392,7 +391,7 @@
<label class="font-semibold text-gray-300" for="share_projects">Share Projects</label>
</div>
<div >
<select autocomplete="off" id="share_projects" name="share_projects" class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select autocomplete="off" id="share_projects" name="share_projects" class="select-default flex-grow">
<option value="false" class="cursor-pointer" {{ if not .User.ShareProjects }} selected {{ end }}>No
</option>
<option value="true" class="cursor-pointer" {{ if .User.ShareProjects }} selected {{ end }}>Yes
@ -406,7 +405,7 @@
<label class="font-semibold text-gray-300" for="share_languages">Share Languages</label>
</div>
<div >
<select autocomplete="off" id="share_languages" name="share_languages" class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select autocomplete="off" id="share_languages" name="share_languages" class="select-default flex-grow">
<option value="false" class="cursor-pointer" {{ if not .User.ShareLanguages }} selected {{ end }}>No
</option>
<option value="true" class="cursor-pointer" {{ if .User.ShareLanguages }} selected {{ end }}>Yes
@ -420,7 +419,7 @@
<label class="font-semibold text-gray-300" for="share_editors">Share Editors</label>
</div>
<div >
<select autocomplete="off" id="share_editors" name="share_editors" class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select autocomplete="off" id="share_editors" name="share_editors" class="select-default flex-grow">
<option value="false" class="cursor-pointer" {{ if not .User.ShareEditors }} selected {{ end }}>No
</option>
<option value="true" class="cursor-pointer" {{ if .User.ShareEditors }} selected {{ end }}>Yes
@ -434,7 +433,7 @@
<label class="font-semibold text-gray-300" for="share_oss">Share OS'</label>
</div>
<div >
<select autocomplete="off" id="share_oss" name="share_oss" class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select autocomplete="off" id="share_oss" name="share_oss" class="select-default flex-grow">
<option value="false" class="cursor-pointer" {{ if not .User.ShareOSs }} selected {{ end }}>No
</option>
<option value="true" class="cursor-pointer" {{ if .User.ShareOSs }} selected {{ end }}>Yes
@ -448,7 +447,7 @@
<label class="font-semibold text-gray-300" for="share_machines">Share Machines</label>
</div>
<div >
<select autocomplete="off" id="share_machines" name="share_machines" class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select autocomplete="off" id="share_machines" name="share_machines" class="select-default flex-grow">
<option value="false" class="cursor-pointer" {{ if not .User.ShareMachines }} selected {{ end }}>No
</option>
<option value="true" class="cursor-pointer" {{ if .User.ShareMachines }} selected {{ end }}>Yes
@ -462,7 +461,7 @@
<label class="font-semibold text-gray-300" for="share_labels">Share Project Labels</label>
</div>
<div >
<select autocomplete="off" id="share_labels" name="share_labels" class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
<select autocomplete="off" id="share_labels" name="share_labels" class="select-default flex-grow">
<option value="false" class="cursor-pointer" {{ if not .User.ShareLabels }} selected {{ end }}>No
</option>
<option value="true" class="cursor-pointer" {{ if .User.ShareLabels }} selected {{ end }}>Yes
@ -474,7 +473,7 @@
</div>
<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">
<button type="submit" class="btn-primary">
Save
</button>
</div>
@ -490,13 +489,13 @@
{{ $placeholderText = "********" }}
{{ end }}
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap md:flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/2 mb-4 md:mb-0 inline-block">
<label class="font-semibold text-gray-300" for="select-timezone">WakaTime</label>
<span class="block text-sm text-gray-600">
You can connect Wakapi with the official WakaTime in a way that all heartbeats sent to Wakapi are relayed. This way, you can use both services at the same time. To get started, get <a class="text-gray-400 hover:text-gray-300 font-semibold" href="https://wakatime.com/developers#authentication" rel="noopener noreferrer" target="_blank">your API key</a> and paste it here.<br><br>
You can connect Wakapi with the official WakaTime in a way that all heartbeats sent to Wakapi are relayed. This way, you can use both services at the same time. To get started, get <a class="link" href="https://wakatime.com/developers#authentication" rel="noopener noreferrer" target="_blank">your API key</a> and paste it here.<br><br>
Please note: When enabling this feature, the operators of this server will, in theory, have unlimited access to your data stored in WakaTime. If you are concerned about your privacy, please do not enable this integration or wait for OAuth 2 authentication (<a
class="font-semibold text-gray-400 hover:text-gray-300" target="_blank" href="https://github.com/muety/wakapi/issues/94" rel="noopener noreferrer">#94</a>) to be implemented.
class="link" target="_blank" href="https://github.com/muety/wakapi/issues/94" rel="noopener noreferrer">#94</a>) to be implemented.
</span>
</div>
<div class="w-full md:w-1/2">
@ -508,10 +507,10 @@
<div class="flex justify-end mt-4">
{{ if not .User.WakatimeApiKey }}
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">Connect</button>
<button type="submit" class="btn-primary">Connect</button>
{{ else }}
<button id="btn-import-wakatime" type="button" class="py-2 px-4 font-semibold rounded bg-gray-850 hover:bg-gray-800 text-white text-sm mr-1" @click.stop="confirmWakatimeImport">Import Data</button>
<button type="submit" class="py-2 px-4 font-semibold rounded bg-red-600 hover:bg-red-700 text-white text-sm ml-1">Disconnect</button>
<button type="submit" class="btn-danger ml-1">Disconnect</button>
{{ end }}
</div>
</form>
@ -525,11 +524,11 @@
</div>
<div class="w-full lg:w-3/4">
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap md:flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/2 mb-4 md:mb-0 inline-block">
<label class="font-semibold text-gray-300" for="select-timezone">Badges (Shields.IO)</label>
<span class="block text-sm text-gray-600">
The integration with <a class="font-semibold text-gray-400 hover:text-gray-300" href="https://shields.io" target="_blank" rel="noreferrer noopener">Shields.IO</a> allows to generate badges for README pages or forums. To enable this feature, you need to grant public, unauthorized access to the respective endpoints. See <a class="font-semibold text-gray-400 hover:text-gray-300" href="settings#permissions">Permissions</a>.<br><br>
The integration with <a class="link" href="https://shields.io" target="_blank" rel="noreferrer noopener">Shields.IO</a> allows to generate badges for README pages or forums. To enable this feature, you need to grant public, unauthorized access to the respective endpoints. See <a class="link" href="settings#permissions">Permissions</a>.<br><br>
Only available on public instances, not on localhost.
</span>
</div>
@ -575,11 +574,11 @@
</div>
<div class="w-full lg:w-3/4">
<div class="flex flex-wrap md:flex-no-wrap mb-8 gap-x-4">
<div class="flex flex-wrap md:flex-nowrap mb-8 gap-x-4">
<div class="w-full md:w-1/2 mb-4 md:mb-0 inline-block">
<label class="font-semibold text-gray-300" for="select-timezone">GitHub Readme Stats</label>
<span class="block text-sm text-gray-600">
Wakapi intregrates with <a class="font-semibold text-gray-400 hover:text-gray-300" href="https://github.com/anuraghazra/github-readme-stats#wakatime-week-stats" target="_blank" rel="noreferrer noopener">GitHub Readme Stats</a> to generate fancy cards for you. To enable this feature, you need to grant public, unauthorized access to the respective endpoints. See <a class="font-semibold text-gray-400 hover:text-gray-300" href="settings#permissions">Permissions</a>.<br><br>
Wakapi intregrates with <a class="link" href="https://github.com/anuraghazra/github-readme-stats#wakatime-week-stats" target="_blank" rel="noreferrer noopener">GitHub Readme Stats</a> to generate fancy cards for you. To enable this feature, you need to grant public, unauthorized access to the respective endpoints. See <a class="link" href="settings#permissions">Permissions</a>.<br><br>
Only available on public instances, not on localhost.
</span>
</div>
@ -612,7 +611,7 @@
</span>
</div>
<div class="w-1/2 ml-4">
<button type="button" class="py-2 px-4 font-semibold rounded bg-red-600 hover:bg-red-700 text-white text-sm ml-1" @click.stop="confirmRegenerate">Clear and regenerate</button>
<button type="button" class="btn-danger ml-1" @click.stop="confirmRegenerate">Clear and regenerate</button>
</div>
</form>
@ -626,7 +625,7 @@
</span>
</div>
<div class="w-1/2 ml-4">
<button type="submit" class="py-2 px-4 font-semibold rounded bg-red-600 hover:bg-red-700 text-white text-sm ml-1">Reset API key</button>
<button type="submit" class="btn-danger ml-1">Reset API key</button>
</div>
</form>
@ -640,7 +639,7 @@
</span>
</div>
<div class="w-1/2 ml-4">
<button type="button" class="py-2 px-4 font-semibold rounded bg-red-600 hover:bg-red-700 text-white text-sm ml-1" @click.stop="confirmDeleteAccount">Delete account</button>
<button type="button" class="btn-danger ml-1" @click.stop="confirmDeleteAccount">Delete account</button>
</div>
</form>
</div>

View File

@ -23,8 +23,8 @@
<main class="mt-10 flex-grow flex justify-center w-full" id="signup-page">
<div class="flex-grow max-w-lg mt-10">
<div class="mb-8">
<h1 class="font-semibold text-3xl text-white m-0 mb-2">Sign up to Wakapi</h1>
<p class="text-sm text-gray-600">
<h1 class="h1">Sign up to Wakapi</h1>
<p class="h1-subcaption">
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.
Instruction can be found in our <a href="https://github.com/muety/wakapi#-client-setup" target="_blank"
@ -46,7 +46,7 @@
<div>
<div class="mb-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<input class="input-default"
v-model="username"
type="text" id="username"
name="username" placeholder="Choose a username" minlength="1"
@ -54,7 +54,7 @@
required autofocus>
</div>
<div class="mb-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<input class="input-default"
v-model="email"
type="email" id="email"
name="email" @keyup="updateAvatar" placeholder="Your e-mail address">
@ -63,12 +63,12 @@
</div>
</div>
<div class="mb-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<input class="input-default"
type="password" id="password"
name="password" placeholder="Choose a password" minlength="6" required>
</div>
<div class="mb-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded w-full py-2 px-4"
<input class="input-default"
type="password" id="password_repeat"
name="password_repeat" placeholder="And again..." minlength="6" required>
</div>
@ -81,9 +81,9 @@
<div class="flex space-x-2 justify-end">
<a href="login">
<button type="button" class="py-2 px-4 font-semibold rounded bg-gray-800 hover:bg-gray-850 text-white text-sm">Log in</button>
<button type="button" class="btn-primary">Log in</button>
</a>
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
<button type="submit" class="btn-default">
Create Account
</button>
</div>

View File

@ -91,7 +91,7 @@
<div class="w-full lg:w-1/2 p-1" style="max-width: 100vw;">
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="project-container" style="height: 608px">
<div class="flex justify-between">
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap">Projects</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Projects</span>
<div class="flex justify-end flex-1 text-xs items-center">
<input type="number" min="1" id="project-top-picker" data-entity="0" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10">
</div>
@ -107,7 +107,7 @@
<div class="flex flex-col space-y-2">
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="language-container" style="height: 300px">
<div class="flex justify-between">
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap">Languages</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Languages</span>
<div class="flex justify-end flex-1 text-xs items-center">
<input type="number" min="1" id="language-top-picker" data-entity="3" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10">
</div>
@ -120,7 +120,7 @@
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="editor-container" style="height: 300px">
<div class="flex justify-between">
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap">Editors</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Editors</span>
<div class="flex justify-end flex-1 text-xs items-center">
<input type="number" min="1" id="editor-top-picker" data-entity="2" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10">
</div>
@ -138,8 +138,8 @@
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="os-container" style="height: 300px">
<div class="flex justify-between">
<div>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap mr-1 cursor-pointer">Operating Systems</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap ml-1 cursor-pointer text-gray-600" onclick="swapCharts('machine', 'os')">Machines</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap mr-1 cursor-pointer">Operating Systems</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap ml-1 cursor-pointer text-gray-600" onclick="swapCharts('machine', 'os')">Machines</span>
</div>
<div class="flex justify-end flex-1 text-xs items-center">
<input type="number" min="1" id="os-top-picker" data-entity="1" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10">
@ -155,8 +155,8 @@
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="machine-container" style="height: 300px">
<div class="flex justify-between">
<div>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap mr-1 cursor-pointer text-gray-600" onclick="swapCharts('os', 'machine')">Operating Systems</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-no-wrap ml-1 cursor-pointer">Machines</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap mr-1 cursor-pointer text-gray-600" onclick="swapCharts('os', 'machine')">Operating Systems</span>
<span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap ml-1 cursor-pointer">Machines</span>
</div>
<div class="flex justify-end flex-1 text-xs items-center">
<input type="number" min="1" id="machine-top-picker" data-entity="4" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10">
@ -171,7 +171,7 @@
<div class="w-full lg:w-1/2 p-1" style="max-width: 100vw;">
<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">
<span class="font-semibold whitespace-no-wrap">Labels</span>
<span class="font-semibold whitespace-nowrap">Labels</span>
<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>
</a>

1048
yarn.lock Normal file

File diff suppressed because it is too large Load Diff