mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
chore: move vue components to separate js files
This commit is contained in:
parent
ba54e7bb96
commit
c217f8e664
@ -56,7 +56,7 @@ let icons = [
|
|||||||
'fluent:key-24-filled'
|
'fluent:key-24-filled'
|
||||||
]
|
]
|
||||||
|
|
||||||
const output = path.normalize(path.join(__dirname, '../static/assets/icons.js'))
|
const output = path.normalize(path.join(__dirname, '../static/assets/js/icons.js'))
|
||||||
const pretty = false
|
const pretty = false
|
||||||
|
|
||||||
// Sort icons by collections: filtered[prefix][array of icons]
|
// Sort icons by collections: filtered[prefix][array of icons]
|
||||||
|
14
static/assets/js/components/menu-main.js
Normal file
14
static/assets/js/components/menu-main.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
PetiteVue.createApp({
|
||||||
|
$delimiters: ['${', '}'],
|
||||||
|
state: {
|
||||||
|
showDropdownResources: false,
|
||||||
|
showDropdownUser: false,
|
||||||
|
showApiKey: false
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
window.addEventListener('click', (e) => {
|
||||||
|
const skip = findParentAttribute(e.target, 'data-trigger-for')?.value
|
||||||
|
Object.keys(this.state).filter(k => k !== skip).forEach(k => this.state[k] = false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).mount('#main-menu')
|
33
static/assets/js/components/settings.js
Normal file
33
static/assets/js/components/settings.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
PetiteVue.createApp({
|
||||||
|
//$delimiters: ['${', '}'], // https://github.com/vuejs/petite-vue/pull/100
|
||||||
|
activeTab: defaultTab,
|
||||||
|
selectedTimezone: userTimeZone,
|
||||||
|
get tzOptions() {
|
||||||
|
return [defaultTzOption, ...tzs.sort().map(tz => ({ value: tz, text: tz }))]
|
||||||
|
},
|
||||||
|
updateTab() {
|
||||||
|
this.activeTab = window.location.hash.slice(1) || defaultTab
|
||||||
|
},
|
||||||
|
isActive(tab) {
|
||||||
|
return this.activeTab === tab
|
||||||
|
},
|
||||||
|
confirmRegenerate() {
|
||||||
|
if (confirm('Are you sure?')) {
|
||||||
|
formRegenerate.submit()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirmWakatimeImport() {
|
||||||
|
if (confirm('Are you sure? The import can not be undone.')) {
|
||||||
|
formImportWakatime.submit()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirmDeleteAccount() {
|
||||||
|
if (confirm('Are you sure? This can not be undone!')) {
|
||||||
|
formDelete.submit()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.updateTab()
|
||||||
|
window.addEventListener('hashchange', () => this.updateTab())
|
||||||
|
}
|
||||||
|
}).mount('#settings-page')
|
29
static/assets/js/components/signup.js
Normal file
29
static/assets/js/components/signup.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
let debounceTimeout
|
||||||
|
|
||||||
|
PetiteVue.createApp({
|
||||||
|
timezone: guessTimezone(),
|
||||||
|
username: '',
|
||||||
|
email: '',
|
||||||
|
avatarUrl: defaultAvatarUrl,
|
||||||
|
updateAvatar() {
|
||||||
|
if (!avatarUrlTemplate) return
|
||||||
|
if (debounceTimeout) {
|
||||||
|
clearTimeout(debounceTimeout)
|
||||||
|
}
|
||||||
|
debounceTimeout = setTimeout(() => {
|
||||||
|
let url = avatarUrlTemplate
|
||||||
|
|
||||||
|
if ((url.includes('{username') && !this.username) || (url.includes('{email') && !this.email)) {
|
||||||
|
url = defaultAvatarUrl
|
||||||
|
} else {
|
||||||
|
url = url.replaceAll('{username}', this.username)
|
||||||
|
url = url.replaceAll('{email}', this.email)
|
||||||
|
url = url.replaceAll('{username_hash}', MD5(this.username))
|
||||||
|
url = url.replaceAll('{email_hash}', MD5(this.email))
|
||||||
|
url = url.includes('{') ? defaultAvatarUrl : url
|
||||||
|
}
|
||||||
|
console.log(url)
|
||||||
|
this.avatarUrl = url
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}).mount('#signup-page')
|
24
static/assets/js/components/summary.js
Normal file
24
static/assets/js/components/summary.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
PetiteVue.createApp({
|
||||||
|
$delimiters: ['${', '}'],
|
||||||
|
state: {
|
||||||
|
showDropdownTimepicker: false,
|
||||||
|
},
|
||||||
|
fromDate: fromDate,
|
||||||
|
toDate: toDate,
|
||||||
|
timeSelection: timeSelection,
|
||||||
|
onDateUpdated() {
|
||||||
|
formTimePicker.submit()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
window.addEventListener('click', (e) => {
|
||||||
|
const skip = findParentAttribute(e.target, 'data-trigger-for')?.value
|
||||||
|
Object.keys(this.state).filter(k => k !== skip).forEach(k => this.state[k] = false)
|
||||||
|
})
|
||||||
|
|
||||||
|
const query = new URLSearchParams(window.location.search)
|
||||||
|
if (query.has('interval')) {
|
||||||
|
const refEl = document.getElementById(`time-option-${query.get('interval')}`)
|
||||||
|
this.timeSelection = refEl ? refEl.innerText : 'Unknown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).mount('#summary-page')
|
@ -1,5 +1,5 @@
|
|||||||
<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>
|
||||||
<script src="assets/icons.js"></script>
|
<script src="assets/js/icons.js"></script>
|
||||||
<script src="assets/base.js"></script>
|
<script src="assets/js/base.js"></script>
|
||||||
|
@ -1,19 +1,4 @@
|
|||||||
<script type="module">
|
<script type="module" src="assets/js/components/menu-main.js"></script>
|
||||||
PetiteVue.createApp({
|
|
||||||
$delimiters: ['${', '}'],
|
|
||||||
state: {
|
|
||||||
showDropdownResources: false,
|
|
||||||
showDropdownUser: false,
|
|
||||||
showApiKey: false
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
window.addEventListener('click', (e) => {
|
|
||||||
const skip = findParentAttribute(e.target, 'data-trigger-for')?.value
|
|
||||||
Object.keys(this.state).filter(k => k !== skip).forEach(k => this.state[k] = false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).mount('#main-menu')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="flex justify-between space-x-4 items-center relative" id="main-menu" v-scope @vue:mounted="mounted">
|
<div class="flex justify-between space-x-4 items-center relative" id="main-menu" v-scope @vue:mounted="mounted">
|
||||||
<div class="mr-8 hidden lg:inline-block flex-shrink-0">
|
<div class="mr-8 hidden lg:inline-block flex-shrink-0">
|
||||||
@ -28,14 +13,14 @@
|
|||||||
<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 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>
|
||||||
<a class="text-gray-600 leading-none hidden lg:inline-block">Team<br>
|
<a class="text-gray-600 leading-none hidden lg:inline-block">Team<br>
|
||||||
<span class="text-xxs">(coming soon)</span>
|
<span class="text-xxs whitespace-no-wrap">(coming soon)</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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 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="fluent:data-bar-horizontal-24-filled"></span>
|
<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>
|
<a class="text-gray-600 leading-none hidden lg:inline-block">Leaderboard<br>
|
||||||
<span class="text-xxs">(coming soon)</span>
|
<span class="text-xxs whitespace-no-wrap">(coming soon)</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
{{ template "head.tpl.html" . }}
|
{{ template "head.tpl.html" . }}
|
||||||
<script src="assets/timezones.js"></script>
|
<script src="assets/js/timezones.js"></script>
|
||||||
|
<script>
|
||||||
<script type="module">
|
|
||||||
// Constants
|
// Constants
|
||||||
const defaultTab = 'account'
|
const defaultTab = 'account'
|
||||||
const userTimeZone = {{ .User.Location }}
|
const userTimeZone = {{ .User.Location }}
|
||||||
@ -15,41 +14,8 @@
|
|||||||
const formRegenerate = document.querySelector('#form-regenerate-summaries')
|
const formRegenerate = document.querySelector('#form-regenerate-summaries')
|
||||||
const formImportWakatime = document.querySelector('#form-import-wakatime')
|
const formImportWakatime = document.querySelector('#form-import-wakatime')
|
||||||
const formDelete = document.querySelector('#form-delete-user')
|
const formDelete = document.querySelector('#form-delete-user')
|
||||||
|
|
||||||
PetiteVue.createApp({
|
|
||||||
//$delimiters: ['${', '}'], // https://github.com/vuejs/petite-vue/pull/100
|
|
||||||
activeTab: defaultTab,
|
|
||||||
selectedTimezone: userTimeZone,
|
|
||||||
get tzOptions() {
|
|
||||||
return [defaultTzOption, ...tzs.sort().map(tz => ({ value: tz, text: tz }))]
|
|
||||||
},
|
|
||||||
updateTab() {
|
|
||||||
this.activeTab = window.location.hash.slice(1) || defaultTab
|
|
||||||
},
|
|
||||||
isActive(tab) {
|
|
||||||
return this.activeTab === tab
|
|
||||||
},
|
|
||||||
confirmRegenerate() {
|
|
||||||
if (confirm('Are you sure?')) {
|
|
||||||
formRegenerate.submit()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
confirmWakatimeImport() {
|
|
||||||
if (confirm('Are you sure? The import can not be undone.')) {
|
|
||||||
formImportWakatime.submit()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
confirmDeleteAccount() {
|
|
||||||
if (confirm('Are you sure? This can not be undone!')) {
|
|
||||||
formDelete.submit()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.updateTab()
|
|
||||||
window.addEventListener('hashchange', () => this.updateTab())
|
|
||||||
}
|
|
||||||
}).mount('#settings-page')
|
|
||||||
</script>
|
</script>
|
||||||
|
<script type="module" src="assets/js/components/settings.js"></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>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{{ template "head.tpl.html" . }}
|
{{ template "head.tpl.html" . }}
|
||||||
|
|
||||||
<script type="module">
|
<script>
|
||||||
// Constants
|
// Constants
|
||||||
const defaultAvatarUrl = 'assets/images/unknown.svg'
|
const defaultAvatarUrl = 'assets/images/unknown.svg'
|
||||||
const avatarUrlTemplate = {{ avatarUrlTemplate }}
|
const avatarUrlTemplate = {{ avatarUrlTemplate }}
|
||||||
@ -11,37 +11,8 @@
|
|||||||
function guessTimezone() {
|
function guessTimezone() {
|
||||||
return Intl.DateTimeFormat().resolvedOptions().timeZone
|
return Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||||
}
|
}
|
||||||
|
|
||||||
let debounceTimeout
|
|
||||||
|
|
||||||
PetiteVue.createApp({
|
|
||||||
timezone: guessTimezone(),
|
|
||||||
username: '',
|
|
||||||
email: '',
|
|
||||||
avatarUrl: defaultAvatarUrl,
|
|
||||||
updateAvatar() {
|
|
||||||
if (!avatarUrlTemplate) return
|
|
||||||
if (debounceTimeout) {
|
|
||||||
clearTimeout(debounceTimeout)
|
|
||||||
}
|
|
||||||
debounceTimeout = setTimeout(() => {
|
|
||||||
let url = avatarUrlTemplate
|
|
||||||
|
|
||||||
if ((url.includes('{username') && !this.username) || (url.includes('{email') && !this.email)) {
|
|
||||||
url = defaultAvatarUrl
|
|
||||||
} else {
|
|
||||||
url = url.replaceAll('{username}', this.username)
|
|
||||||
url = url.replaceAll('{email}', this.email)
|
|
||||||
url = url.replaceAll('{username_hash}', MD5(this.username))
|
|
||||||
url = url.replaceAll('{email_hash}', MD5(this.email))
|
|
||||||
url = url.includes('{') ? defaultAvatarUrl : url
|
|
||||||
}
|
|
||||||
console.log(url)
|
|
||||||
this.avatarUrl = url
|
|
||||||
}, 500)
|
|
||||||
}
|
|
||||||
}).mount('#signup-page')
|
|
||||||
</script>
|
</script>
|
||||||
|
<script type="module" src="assets/js/components/signup.js"></script>
|
||||||
|
|
||||||
<body class="bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-lg 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-lg mx-auto justify-center">
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{{ template "head.tpl.html" . }}
|
{{ template "head.tpl.html" . }}
|
||||||
|
|
||||||
<script type="module">
|
<script>
|
||||||
// Constants
|
// Constants
|
||||||
const timeSelection = '{{ .From | datetime }} - {{ .To | ceildate | datetime }}'
|
const timeSelection = '{{ .From | datetime }} - {{ .To | ceildate | datetime }}'
|
||||||
const fromDate = '{{ .From | simpledate }}'
|
const fromDate = '{{ .From | simpledate }}'
|
||||||
@ -11,32 +11,8 @@
|
|||||||
|
|
||||||
// Elements
|
// Elements
|
||||||
const formTimePicker = document.getElementById('time-picker-form')
|
const formTimePicker = document.getElementById('time-picker-form')
|
||||||
|
|
||||||
PetiteVue.createApp({
|
|
||||||
$delimiters: ['${', '}'],
|
|
||||||
state: {
|
|
||||||
showDropdownTimepicker: false,
|
|
||||||
},
|
|
||||||
fromDate: fromDate,
|
|
||||||
toDate: toDate,
|
|
||||||
timeSelection: timeSelection,
|
|
||||||
onDateUpdated() {
|
|
||||||
formTimePicker.submit()
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
window.addEventListener('click', (e) => {
|
|
||||||
const skip = findParentAttribute(e.target, 'data-trigger-for')?.value
|
|
||||||
Object.keys(this.state).filter(k => k !== skip).forEach(k => this.state[k] = false)
|
|
||||||
})
|
|
||||||
|
|
||||||
const query = new URLSearchParams(window.location.search)
|
|
||||||
if (query.has('interval')) {
|
|
||||||
const refEl = document.getElementById(`time-option-${query.get('interval')}`)
|
|
||||||
this.timeSelection = refEl ? refEl.innerText : 'Unknown'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).mount('#summary-page')
|
|
||||||
</script>
|
</script>
|
||||||
|
<script type="module" src="assets/js/components/summary.js"></script>
|
||||||
|
|
||||||
<body class="relative 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="relative bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-xl mx-auto justify-center">
|
||||||
|
|
||||||
@ -258,7 +234,7 @@
|
|||||||
wakapiData.machines = {{ .Machines | json }}
|
wakapiData.machines = {{ .Machines | json }}
|
||||||
wakapiData.labels = {{ .Labels | json }}
|
wakapiData.labels = {{ .Labels | json }}
|
||||||
</script>
|
</script>
|
||||||
<script src="assets/summary.js"></script>
|
<script src="assets/js/summary.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user