mirror of
https://forgejo.merr.is/annika/isl-vue3.git
synced 2025-12-10 12:04:19 -05:00
I Think I've Successfully Re-Added Auth
This commit is contained in:
parent
5c0d3c2fd7
commit
d914b7cbd6
18 changed files with 269 additions and 93 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
|
@ -14,11 +14,12 @@
|
|||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@zitadel/vue": "^1.0.0",
|
||||
"axios": "^1.6.5",
|
||||
"axios-retry": "^4.0.0",
|
||||
"oidc-client-ts": "^3.0.1",
|
||||
"pinia": "^2.1.7",
|
||||
"vue": "^3.3.11",
|
||||
"vue-oidc-client": "^1.0.0-alpha.5",
|
||||
"vue-router": "^4.2.5",
|
||||
"vuetify": "^3.4.10"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
{
|
||||
"apiBaseURL": "http://localhost:3000"
|
||||
"apiBaseURL": "http://coder.local.merr.is:3000",
|
||||
"oidcAuthority": "https://auth.joes.moosenet.work",
|
||||
"oidcClientID": "255988227184328707@isekai:_slow_life_calculator",
|
||||
"oidcProjectID": "255987963094106115"
|
||||
}
|
||||
14
src/App.vue
14
src/App.vue
|
|
@ -1,25 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { RouterView } from 'vue-router'
|
||||
import GlobalHeader from '@/components/GlobalHeader.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { usePowerItems } from './stores/powerItems'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const { blessingPowerItems, fellowPowerItems, intimacyPowerItems } = storeToRefs(usePowerItems())
|
||||
|
||||
const isLoaded = computed(
|
||||
() =>
|
||||
!blessingPowerItems.value.keys().next().done &&
|
||||
!fellowPowerItems.value.keys().next().done &&
|
||||
!intimacyPowerItems.value.keys().next().done
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-app>
|
||||
<GlobalHeader />
|
||||
<v-main class="d-flex">
|
||||
<RouterView v-if="isLoaded" />
|
||||
<RouterView />
|
||||
</v-main>
|
||||
<v-footer app>
|
||||
<div>Copyright Annika Merris 2024</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { usePowerItems } from '@/stores/powerItems'
|
|||
import type { DataTableHeader } from '@/types/DataTableHeader'
|
||||
import type { PowerItem } from '@/types/PowerItem'
|
||||
import type { Ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
import type { VDataTable } from 'vuetify/components'
|
||||
|
||||
|
|
@ -128,11 +128,19 @@ const getColor = computed(() => (rarity: number): string => {
|
|||
})
|
||||
const allSelected = computed(() => events.value.length === selectedEvents.value.length)
|
||||
const partialSelected = computed(() => selectedEvents.value.length > 0)
|
||||
toggle()
|
||||
const isLoading = computed((): boolean => props.items.keys()?.next().done ?? false)
|
||||
watch(isLoading, (newLoading) => {
|
||||
if (!newLoading) {
|
||||
toggle()
|
||||
}
|
||||
})
|
||||
if (!isLoading.value) {
|
||||
toggle()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card fluid>
|
||||
<v-card fluid :loading="isLoading">
|
||||
<v-card-title>Special Items</v-card-title>
|
||||
<v-card-subtitle>Items from events</v-card-subtitle>
|
||||
<v-card-item>
|
||||
|
|
|
|||
|
|
@ -78,10 +78,11 @@ const getColor = computed(() => (rarity: number): string => {
|
|||
return 'green'
|
||||
}
|
||||
})
|
||||
const isLoading = computed((): boolean => props.items.keys()?.next().done ?? false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card :loading="isLoading">
|
||||
<v-card-title>Standard Items</v-card-title>
|
||||
<v-card-subtitle>Items that exist all the time</v-card-subtitle>
|
||||
<v-card-item>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { computed } from 'vue'
|
||||
|
||||
export interface Props {
|
||||
standardTotal: number
|
||||
minimumTotal: number
|
||||
maximumTotal: number
|
||||
averageTotal: number
|
||||
itemType: string
|
||||
standardTotal: number
|
||||
minimumTotal: number
|
||||
maximumTotal: number
|
||||
averageTotal: number
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
|
@ -17,17 +18,17 @@ const aveIncrease = computed(() => props.standardTotal + props.averageTotal)
|
|||
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>Overall Blessing Power Increase</v-card-title>
|
||||
<v-card-title>Overall {{ itemType }} Power Increase</v-card-title>
|
||||
<v-card-item>
|
||||
<v-list density="compact">
|
||||
<v-list-item>
|
||||
<v-list-item-title>Minimum: {{ minIncrease }}</v-list-item-title>
|
||||
<v-list-item-title>Minimum: {{ minIncrease }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-list-item-title>Maximum: {{ maxIncrease }}</v-list-item-title>
|
||||
<v-list-item-title>Maximum: {{ maxIncrease }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-list-item-title>Mean: {{ aveIncrease }}</v-list-item-title>
|
||||
<v-list-item-title>Mean: {{ aveIncrease }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card-item>
|
||||
|
|
|
|||
66
src/main.ts
66
src/main.ts
|
|
@ -2,17 +2,17 @@ import './assets/main.css'
|
|||
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
// Vuetify
|
||||
import 'vuetify/styles'
|
||||
import '@mdi/font/css/materialdesignicons.css'
|
||||
import { createVuetify } from 'vuetify'
|
||||
import axios from 'axios'
|
||||
import zitadelAuth from '@/services/zitadelAuth'
|
||||
import { apiBaseURL } from './types/ConfigSymbols'
|
||||
|
||||
import App from './App.vue'
|
||||
import { apiBaseURL, oidc } from './types/ConfigSymbols'
|
||||
import { configureOidc } from './services/authentikAuth'
|
||||
import router from './router'
|
||||
import { getConfig } from './services/siteConfig'
|
||||
import type { Config } from './types/Config'
|
||||
|
||||
const vuetify = createVuetify({
|
||||
icons: {
|
||||
|
|
@ -23,32 +23,30 @@ const vuetify = createVuetify({
|
|||
}
|
||||
})
|
||||
|
||||
// Stuff to get OIDC auth working through Zitadel
|
||||
declare module 'vue' {
|
||||
interface ComponentCustomProperties {
|
||||
$zitadel: typeof zitadelAuth
|
||||
const conf: Config = await getConfig().then((c: Config | null): Config => {
|
||||
if (c === null) {
|
||||
throw new Error("config was null")
|
||||
}
|
||||
return c
|
||||
}).catch((reason) => {
|
||||
console.log(reason)
|
||||
throw new Error(reason);
|
||||
})
|
||||
|
||||
const authentikAuth = await configureOidc()
|
||||
authentikAuth.startup().then((ok: boolean) => {
|
||||
if (ok) {
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
|
||||
app.use(router)
|
||||
app.use(vuetify)
|
||||
app.use(pinia)
|
||||
|
||||
app.provide(oidc, authentikAuth)
|
||||
|
||||
app.provide(apiBaseURL, conf.apiBaseURL)
|
||||
|
||||
app.mount('#app')
|
||||
}
|
||||
}
|
||||
|
||||
zitadelAuth.oidcAuth.startup().then(() => {
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
|
||||
app.use(router)
|
||||
app.use(vuetify)
|
||||
app.use(pinia)
|
||||
|
||||
app.config.globalProperties.$zitadel = zitadelAuth
|
||||
|
||||
// Fetch my config
|
||||
axios
|
||||
.get('/config.json?noCache=' + Date.now())
|
||||
.then((resp) => {
|
||||
app.provide(apiBaseURL, resp.data.apiBaseURL)
|
||||
|
||||
app.mount('#app')
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import zitadelAuth from '@/services/zitadelAuth'
|
||||
import { configureOidc } from '@/services/authentikAuth'
|
||||
import { getConfig } from '@/services/siteConfig'
|
||||
import type { Config } from '@/types/Config'
|
||||
import type { OidcAuth } from 'vue-oidc-client/vue3'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
const oidcAuth: OidcAuth = await configureOidc().then((value: OidcAuth): OidcAuth => value)
|
||||
const config: Config = await getConfig().then((value: Config | null): Config => value !== null ? value : {} as Config)
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
|
|
@ -34,7 +40,7 @@ const router = createRouter({
|
|||
path: '/login',
|
||||
name: 'login',
|
||||
meta: {
|
||||
authName: zitadelAuth.oidcAuth.authName
|
||||
authName: oidcAuth.authName
|
||||
},
|
||||
component: () => import('@/views/Login.vue')
|
||||
},
|
||||
|
|
@ -42,14 +48,25 @@ const router = createRouter({
|
|||
path: '/admin',
|
||||
name: 'admin',
|
||||
meta: {
|
||||
authName: zitadelAuth.oidcAuth.authName
|
||||
authName: oidcAuth.authName
|
||||
},
|
||||
component: () =>
|
||||
zitadelAuth.hasRole('admin') ? import('@/views/Admin.vue') : import('@/views/NoAccess.vue')
|
||||
hasRole('admin') ? import('@/views/Admin.vue') : import('@/views/NoAccess.vue')
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
zitadelAuth.oidcAuth.useRouter(router)
|
||||
const hasRole = (role: string) => {
|
||||
if (config.oidcProjectID === undefined) {
|
||||
throw new Error('Config was not loaded')
|
||||
}
|
||||
const roles = oidcAuth.userProfile[`urn:zitadel:iam:org:project:${config.oidcProjectID}:roles`] as Array<any>
|
||||
if (!roles) {
|
||||
return false
|
||||
}
|
||||
return roles.find(r => r[role])
|
||||
}
|
||||
|
||||
oidcAuth!.useRouter(router)
|
||||
|
||||
export default router
|
||||
|
|
|
|||
80
src/services/authentikAuth.ts
Normal file
80
src/services/authentikAuth.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import type { User } from 'oidc-client'
|
||||
import { createOidcAuth, SignInType, type OidcAuth, LogLevel } from 'vue-oidc-client/vue3'
|
||||
import { getConfig } from './siteConfig'
|
||||
import type { Config } from '@/types/Config'
|
||||
|
||||
const loco = window.location
|
||||
const appRootUrl = `${loco.protocol}//${loco.host}${import.meta.env.BASE_URL}`
|
||||
|
||||
let authObj = null as OidcAuth | null
|
||||
|
||||
export async function configureOidc() {
|
||||
if (authObj) return Promise.resolve(authObj)
|
||||
const appConfig: Config = await getConfig().then((c) => {
|
||||
if (c === null) {
|
||||
throw new Error("config was null")
|
||||
}
|
||||
return c
|
||||
}).catch((reason) => {
|
||||
console.log(reason)
|
||||
throw new Error(reason);
|
||||
})
|
||||
|
||||
const config = {
|
||||
authority: appConfig.oidcAuthority,
|
||||
client_id: appConfig.oidcClientID,
|
||||
response_type: 'code',
|
||||
scope: 'openid profile email api offline_access'
|
||||
}
|
||||
|
||||
authObj = createOidcAuth(
|
||||
'main',
|
||||
SignInType.Window,
|
||||
appRootUrl,
|
||||
{
|
||||
...config,
|
||||
// test use
|
||||
prompt: 'login'
|
||||
},
|
||||
console,
|
||||
LogLevel.Debug
|
||||
)
|
||||
|
||||
// handle events
|
||||
authObj.events.addAccessTokenExpiring(function () {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('access token expiring')
|
||||
})
|
||||
|
||||
authObj.events.addAccessTokenExpired(function () {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('access token expired')
|
||||
})
|
||||
|
||||
authObj.events.addSilentRenewError(function (err: Error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('silent renew error', err)
|
||||
})
|
||||
|
||||
authObj.events.addUserLoaded(function (user: User) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('user loaded', user)
|
||||
})
|
||||
|
||||
authObj.events.addUserUnloaded(function () {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('user unloaded')
|
||||
})
|
||||
|
||||
authObj.events.addUserSignedOut(function () {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('user signed out')
|
||||
})
|
||||
|
||||
authObj.events.addUserSessionChanged(function () {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('user session changed')
|
||||
})
|
||||
|
||||
return authObj
|
||||
}
|
||||
18
src/services/siteConfig.ts
Normal file
18
src/services/siteConfig.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import type { Config } from '@/types/Config'
|
||||
import axios from 'axios'
|
||||
|
||||
let configObject = null as Config | null
|
||||
|
||||
export async function getConfig() {
|
||||
if (configObject) return Promise.resolve(configObject)
|
||||
|
||||
configObject = await axios.get('/config.json?noCache=' + Date.now()).then((resp) => {
|
||||
return {
|
||||
apiBaseURL: resp.data.apiBaseURL,
|
||||
oidcAuthority: resp.data.oidcAuthority,
|
||||
oidcClientID: resp.data.oidcClientID,
|
||||
oidcProjectID: resp.data.oidcProjectID
|
||||
} as Config
|
||||
})
|
||||
return configObject
|
||||
}
|
||||
|
|
@ -3,8 +3,7 @@ import axios, { type AxiosRequestConfig } from 'axios'
|
|||
import { defineStore } from 'pinia'
|
||||
import { computed, ref, toRaw } from 'vue'
|
||||
import axiosRetry from 'axios-retry'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
import { apiBaseURL, apiBaseURL as apiBaseURLKey } from '@/types/ConfigSymbols'
|
||||
import { apiBaseURL as apiBaseURLKey } from '@/types/ConfigSymbols'
|
||||
import { inject } from 'vue'
|
||||
|
||||
const BLESSING = 1
|
||||
|
|
@ -21,21 +20,26 @@ const noCacheConfig: AxiosRequestConfig = {
|
|||
}
|
||||
|
||||
export const usePowerItems = defineStore('powerItems', () => {
|
||||
//#region privateVariables
|
||||
const BLESSING_POWER_ITEM_STORAGE = 'BLESSING_POWER_ITEM_STORAGE'
|
||||
const FELLOW_POWER_ITEM_STORAGE = 'FELLOW_POWER_ITEM_STORAGE'
|
||||
const INTIMACY_POWER_ITEM_STORAGE = 'INTIMACY_POWER_ITEM_STORAGE'
|
||||
const apiBaseURL = inject(apiBaseURLKey)!
|
||||
//#endregion
|
||||
|
||||
//#region state
|
||||
const blessingPowerItems = ref(new Map<string, PowerItem>())
|
||||
const fellowPowerItems = ref(new Map<string, PowerItem>())
|
||||
const intimacyPowerItems = ref(new Map<string, PowerItem>())
|
||||
const isLoadComplete = ref(false)
|
||||
const apiBaseURL = inject(apiBaseURLKey)!
|
||||
|
||||
//#endregion
|
||||
|
||||
axiosRetry(axios, {
|
||||
retries: 3,
|
||||
retryDelay: axiosRetry.exponentialDelay
|
||||
})
|
||||
|
||||
async function fetchPowerItems() {
|
||||
//#region loaders
|
||||
async function fetchBlessingItems() {
|
||||
axios
|
||||
.get(apiBaseURL + '/powerItems/byType/' + BLESSING + '/asMap', noCacheConfig)
|
||||
.then((resp) => {
|
||||
|
|
@ -52,6 +56,8 @@ export const usePowerItems = defineStore('powerItems', () => {
|
|||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
async function fetchFellowItems() {
|
||||
axios
|
||||
.get(apiBaseURL + '/powerItems/byType/' + FELLOW + '/asMap', noCacheConfig)
|
||||
.then((resp) => {
|
||||
|
|
@ -68,6 +74,8 @@ export const usePowerItems = defineStore('powerItems', () => {
|
|||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
async function fetchIntimacyItems() {
|
||||
axios
|
||||
.get(apiBaseURL + '/powerItems/byType/' + INTIMACY + '/asMap', noCacheConfig)
|
||||
.then((resp) => {
|
||||
|
|
@ -84,9 +92,10 @@ export const usePowerItems = defineStore('powerItems', () => {
|
|||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
isLoadComplete.value = true
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region setters
|
||||
function updateOwned(key: string, newOwned: number) {
|
||||
let cur = blessingPowerItems.value.get(key)
|
||||
if (cur !== undefined) {
|
||||
|
|
@ -118,16 +127,6 @@ export const usePowerItems = defineStore('powerItems', () => {
|
|||
}
|
||||
}
|
||||
|
||||
function mapToObj(map: Map<string, PowerItem>) {
|
||||
return Array.from(map).reduce((obj, [key, value]) => {
|
||||
// Doing weird magic to work with maps is infuriating, and I haven't found a better solution for this.
|
||||
// So ignore that error TypeScript, I (don't) know what I'm doing!
|
||||
// @ts-ignore: noImplicitAny
|
||||
obj[key] = value
|
||||
return obj
|
||||
}, {})
|
||||
}
|
||||
|
||||
function addPowerItem(newItem: PowerItem): Promise<PowerItem | null> {
|
||||
const resultPromise: Promise<PowerItem | null> = new Promise((resolve, reject) => {
|
||||
axios
|
||||
|
|
@ -140,7 +139,9 @@ export const usePowerItems = defineStore('powerItems', () => {
|
|||
|
||||
return resultPromise
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region computed
|
||||
const totalBlessingPower = computed(() =>
|
||||
[...blessingPowerItems.value.values()].reduce(
|
||||
(accumulator: number, currentValue: PowerItem) => {
|
||||
|
|
@ -323,15 +324,29 @@ export const usePowerItems = defineStore('powerItems', () => {
|
|||
0
|
||||
)
|
||||
)
|
||||
//#endregion
|
||||
|
||||
fetchPowerItems()
|
||||
//#region helpers
|
||||
function mapToObj(map: Map<string, PowerItem>) {
|
||||
return Array.from(map).reduce((obj, [key, value]) => {
|
||||
// Doing weird magic to work with maps is infuriating, and I haven't found a better solution for this.
|
||||
// So ignore that error TypeScript, I (don't) know what I'm doing!
|
||||
// @ts-ignore: noImplicitAny
|
||||
obj[key] = value
|
||||
return obj
|
||||
}, {})
|
||||
}
|
||||
//#endregion
|
||||
|
||||
return {
|
||||
blessingPowerItems,
|
||||
fellowPowerItems,
|
||||
intimacyPowerItems,
|
||||
isLoadComplete,
|
||||
fetchPowerItems,
|
||||
|
||||
fetchBlessingItems,
|
||||
fetchFellowItems,
|
||||
fetchIntimacyItems,
|
||||
|
||||
updateOwned,
|
||||
totalBlessingPower,
|
||||
standardBlessingItems,
|
||||
|
|
|
|||
6
src/types/Config.ts
Normal file
6
src/types/Config.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export type Config = {
|
||||
apiBaseURL: string,
|
||||
oidcAuthority: string,
|
||||
oidcClientID: string,
|
||||
oidcProjectID: string,
|
||||
}
|
||||
|
|
@ -1,7 +1,12 @@
|
|||
import type { InjectionKey } from "vue";
|
||||
import type { OidcAuth } from "vue-oidc-client/vue3";
|
||||
|
||||
const apiBaseURL = Symbol() as InjectionKey<string>
|
||||
const oidcProjectID = Symbol() as InjectionKey<string>
|
||||
const oidc = Symbol() as InjectionKey<OidcAuth>
|
||||
|
||||
export {
|
||||
apiBaseURL
|
||||
apiBaseURL,
|
||||
oidcProjectID,
|
||||
oidc
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import StandardItemsCard from '@/components/StandardItemsCard.vue'
|
|||
import SummaryCard from '@/components/SummaryCard.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { usePowerItems } from '@/stores/powerItems'
|
||||
import { onBeforeMount } from 'vue'
|
||||
|
||||
const {
|
||||
standardBlessingItems,
|
||||
|
|
@ -13,6 +14,15 @@ const {
|
|||
specialBlessingItemsMaxTotal,
|
||||
specialBlessingItemsAveTotal
|
||||
} = storeToRefs(usePowerItems())
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (standardBlessingItems.value.keys().next().done) {
|
||||
usePowerItems().fetchBlessingItems()
|
||||
}
|
||||
if (specialBlessingItems.value.keys().next().done) {
|
||||
usePowerItems().fetchBlessingItems()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -34,6 +44,7 @@ const {
|
|||
/>
|
||||
<SummaryCard
|
||||
class="ma-2 align-self-start"
|
||||
item-type="Blessing"
|
||||
:standard-total="standardBlessingItemTotal"
|
||||
:minimum-total="specialBlessingItemsMinTotal"
|
||||
:maximum-total="specialBlessingItemsMaxTotal"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import StandardItemsCard from '@/components/StandardItemsCard.vue'
|
|||
import SummaryCard from '@/components/SummaryCard.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { usePowerItems } from '@/stores/powerItems'
|
||||
import { onBeforeMount } from 'vue'
|
||||
|
||||
const {
|
||||
standardFellowItems,
|
||||
|
|
@ -13,6 +14,15 @@ const {
|
|||
specialFellowItemsMaxTotal,
|
||||
specialFellowItemsAveTotal
|
||||
} = storeToRefs(usePowerItems())
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (standardFellowItems.value.keys().next().done) {
|
||||
usePowerItems().fetchFellowItems()
|
||||
}
|
||||
if (specialFellowItems.value.keys().next().done) {
|
||||
usePowerItems().fetchFellowItems()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -33,6 +43,7 @@ const {
|
|||
:average-total="specialFellowItemsAveTotal"
|
||||
/>
|
||||
<SummaryCard
|
||||
item-type="Fellow"
|
||||
class="ma-2 align-self-start"
|
||||
:standard-total="standardFellowItemTotal"
|
||||
:minimum-total="specialFellowItemsMinTotal"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import StandardItemsCard from '@/components/StandardItemsCard.vue'
|
|||
import SummaryCard from '@/components/SummaryCard.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { usePowerItems } from '@/stores/powerItems'
|
||||
import { onBeforeMount } from 'vue'
|
||||
|
||||
const {
|
||||
standardIntimacyItems,
|
||||
|
|
@ -13,6 +14,15 @@ const {
|
|||
specialIntimacyItemsMaxTotal,
|
||||
specialIntimacyItemsAveTotal
|
||||
} = storeToRefs(usePowerItems())
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (standardIntimacyItems.value.keys().next().done) {
|
||||
usePowerItems().fetchIntimacyItems()
|
||||
}
|
||||
if (specialIntimacyItems.value.keys().next().done) {
|
||||
usePowerItems().fetchIntimacyItems()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -33,6 +43,7 @@ const {
|
|||
:average-total="specialIntimacyItemsAveTotal"
|
||||
/>
|
||||
<SummaryCard
|
||||
item-type="Intimacy"
|
||||
class="ma-2 align-self-start"
|
||||
:standard-total="standardIntimacyItemTotal"
|
||||
:minimum-total="specialIntimacyItemsMinTotal"
|
||||
|
|
|
|||
|
|
@ -28,14 +28,15 @@
|
|||
}
|
||||
</style>
|
||||
<script lang="ts">
|
||||
import { getCurrentInstance } from 'vue';
|
||||
import { oidc } from '@/types/ConfigSymbols';
|
||||
import { inject } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
computed: {
|
||||
user() {
|
||||
return this.$zitadel.oidcAuth.userProfile
|
||||
return inject(oidc)?.userProfile
|
||||
},
|
||||
claims() {
|
||||
if (this.user) {
|
||||
|
|
@ -51,11 +52,12 @@ export default defineComponent({
|
|||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
const zitadel = ref(getCurrentInstance()?.appContext.config.globalProperties.$zitadel!)
|
||||
const user = ref(zitadel.value.oidcAuth.userProfile)
|
||||
const zitadel = ref(inject(oidc))
|
||||
const user = ref(zitadel.value?.userProfile)
|
||||
const signout = function() {
|
||||
if (user.value) {
|
||||
zitadel.value.oidcAuth.signOut()
|
||||
zitadel.value?.signOut()
|
||||
}
|
||||
}
|
||||
console.log(zitadel.value)
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue