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'
|
||||
]
|
||||
|
||||
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
|
||||
|
||||
// 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/seedrandom.min.js"></script>
|
||||
<script src="assets/vendor/chart.min.js"></script>
|
||||
<script src="assets/icons.js"></script>
|
||||
<script src="assets/base.js"></script>
|
||||
<script src="assets/js/icons.js"></script>
|
||||
<script src="assets/js/base.js"></script>
|
||||
|
@ -1,19 +1,4 @@
|
||||
<script type="module">
|
||||
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>
|
||||
<script type="module" src="assets/js/components/menu-main.js"></script>
|
||||
|
||||
<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">
|
||||
@ -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">
|
||||
<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">(coming soon)</span>
|
||||
<span class="text-xxs whitespace-no-wrap">(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">
|
||||
<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">(coming soon)</span>
|
||||
<span class="text-xxs whitespace-no-wrap">(coming soon)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -2,9 +2,8 @@
|
||||
<html lang="en">
|
||||
|
||||
{{ template "head.tpl.html" . }}
|
||||
<script src="assets/timezones.js"></script>
|
||||
|
||||
<script type="module">
|
||||
<script src="assets/js/timezones.js"></script>
|
||||
<script>
|
||||
// Constants
|
||||
const defaultTab = 'account'
|
||||
const userTimeZone = {{ .User.Location }}
|
||||
@ -15,41 +14,8 @@
|
||||
const formRegenerate = document.querySelector('#form-regenerate-summaries')
|
||||
const formImportWakatime = document.querySelector('#form-import-wakatime')
|
||||
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 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">
|
||||
<style>
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
{{ template "head.tpl.html" . }}
|
||||
|
||||
<script type="module">
|
||||
<script>
|
||||
// Constants
|
||||
const defaultAvatarUrl = 'assets/images/unknown.svg'
|
||||
const avatarUrlTemplate = {{ avatarUrlTemplate }}
|
||||
@ -11,37 +11,8 @@
|
||||
function guessTimezone() {
|
||||
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 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">
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
{{ template "head.tpl.html" . }}
|
||||
|
||||
<script type="module">
|
||||
<script>
|
||||
// Constants
|
||||
const timeSelection = '{{ .From | datetime }} - {{ .To | ceildate | datetime }}'
|
||||
const fromDate = '{{ .From | simpledate }}'
|
||||
@ -11,32 +11,8 @@
|
||||
|
||||
// Elements
|
||||
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 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">
|
||||
|
||||
@ -258,7 +234,7 @@
|
||||
wakapiData.machines = {{ .Machines | json }}
|
||||
wakapiData.labels = {{ .Labels | json }}
|
||||
</script>
|
||||
<script src="assets/summary.js"></script>
|
||||
<script src="assets/js/summary.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user