Skip to content

Commit

Permalink
Addresses Review Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
gbdubs committed Nov 15, 2023
1 parent 7e3091b commit 9b5c911
Show file tree
Hide file tree
Showing 23 changed files with 179 additions and 120 deletions.
4 changes: 2 additions & 2 deletions frontend/components/initiative/Toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import { type InitiativeUserRelationship } from '@/openapi/generated/pacta'
const localePath = useLocalePath()
const { getMaybeMe } = useSession()
const { t } = useI18n()
const { getMaybeMe } = await useSession()
const { isAdmin, maybeMe } = await getMaybeMe()
const prefix = 'InitiativeToolbar'
const tt = (key: string) => t(`${prefix}.${key}`)
Expand Down
12 changes: 10 additions & 2 deletions frontend/components/modal/FakeUsers.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<script setup lang="ts">
const { fakeUsers: { fakeUsersVisible } } = useModal()
const { t } = useI18n()
const { getMaybeMe, refreshMaybeMe } = useSession()
const { isAuthenticated, signIn, signOut } = await useMSAL()
const isAuthenticated = useIsAuthenticated()
const localePath = useLocalePath()
const [
{ signOut },
{ getMaybeMe, refreshMaybeMe },
{ signIn },
] = await Promise.all([
useMSAL(),
useSession(),
useSignIn(),
])
const prefix = 'ModalFakeUsers'
const tt = (s: string) => t(`${prefix}.${s}`)
Expand Down
13 changes: 10 additions & 3 deletions frontend/components/standard/Nav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@ import { type MenuItem } from 'primevue/menuitem'
const { t } = useI18n()
const localePath = useLocalePath()
const { isAuthenticated, signIn, signOut } = await useMSAL()
const { getMaybeMe } = useSession()
const isAuthenticated = useIsAuthenticated()
const router = useRouter()
const [
{ signOut },
{ signIn },
{ getMaybeMe },
] = await Promise.all([
useMSAL(),
useSignIn(),
useSession(),
])
const { isAdmin, maybeMe } = await getMaybeMe()
const prefix = 'StandardNav'
Expand Down
3 changes: 1 addition & 2 deletions frontend/components/user/Editor.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<script setup lang="ts">
import { type EditorUser } from '@/lib/editor'
const { getMaybeMe } = useSession()
const { t } = useI18n()
const { getMaybeMe } = await useSession()
const { maybeMe } = await getMaybeMe()
interface Props {
Expand Down
5 changes: 2 additions & 3 deletions frontend/components/user/Toolbar.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<script setup lang="ts">
const { getMaybeMe } = useSession()
const { t } = useI18n()
const localePath = useLocalePath()
const { getMaybeMe } = await useSession()
const { isAdmin, maybeMe } = await getMaybeMe()
const { t } = useI18n()
interface Props {
userId: string
Expand Down
5 changes: 5 additions & 0 deletions frontend/composables/useIsAuthenticated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const useIsAuthenticated = () => {
const prefix = 'useIsAuthenticated'
const isAuthenticated = useState<boolean>(`${prefix}.isAuthenticated`, () => true)
return isAuthenticated
}
13 changes: 6 additions & 7 deletions frontend/composables/useMSAL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import { computed } from 'vue'
import { type APIKey } from '~/openapi/generated/user'

export const useMSAL = async () => {
const { isAuthenticated } = useSession()
const isAuthenticated = useIsAuthenticated()

// Don't initialize the MSAL client if we're not in the browser.
if (process.server) {
const jwt = useCookie('jwt')
isAuthenticated.value = !!jwt.value
return {
signIn: () => Promise.reject(new Error('cannot call signIn on server')),
msalSignIn: () => Promise.reject(new Error('cannot call signIn on server')),
signOut: () => Promise.reject(new Error('cannot call signOut on server')),
createAPIKey: () => Promise.reject(new Error('cannot call createAPIKey on server')),
getToken: () => Promise.reject(new Error('cannot call getToken on server')),
Expand All @@ -35,7 +35,7 @@ export const useMSAL = async () => {
}

const router = useRouter()
const { userClientWithAuth, pactaClientWithAuth } = useAPI()
const { userClientWithAuth } = useAPI()
const localePath = useLocalePath()

const { $msal: { msalConfig, b2cPolicies } } = useNuxtApp()
Expand Down Expand Up @@ -239,16 +239,15 @@ export const useMSAL = async () => {
.then(handleResponse)
}

const signIn = () => {
const msalSignIn: () => Promise<void> = (): Promise<void> => {
if (!instance.value) {
return Promise.reject(new Error('MSAL instance was not yet initialized'))
}

const req = { scopes }
return instance.value.loginPopup(req)
.then(handleResponse)
.then(getToken)
.then(token => pactaClientWithAuth(token.idToken).userAuthenticationFollowup())
.then(() => { /* cast to void */ })
.catch((err) => {
console.log('useMSAL.loginPopup', err)
})
Expand Down Expand Up @@ -291,7 +290,7 @@ export const useMSAL = async () => {
}

return {
signIn,
msalSignIn,
signOut,
createAPIKey,
getToken,
Expand Down
10 changes: 5 additions & 5 deletions frontend/composables/useSession.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { type User } from '@/openapi/generated/pacta'

export const useSession = () => {
const prefix = 'useSession'
const isAuthenticated = useState<boolean>(`${prefix}.isAuthenticated`, () => true)
export const useSession = async () => {
const isAuthenticated = useIsAuthenticated()
const pactaClient = await usePACTA()

const prefix = 'useSession'
const currentUser = useState<User | undefined>(`${prefix}.currentUser`, () => undefined)
const isAdmin = computed<boolean>(() => !!currentUser.value && currentUser.value.admin)
const isSuperAdmin = computed<boolean>(() => !!currentUser.value && currentUser.value.superAdmin)
Expand All @@ -25,8 +26,7 @@ export const useSession = () => {
// We're the first to request a user, kick of the request and hop in line at the front of the queue.
return new Promise((resolve) => {
resolvers.value.push(resolve)
void usePACTA()
.then(pactaClient => pactaClient.findUserByMe())
void pactaClient.findUserByMe()
.then(m => {
currentUser.value = m

Expand Down
17 changes: 17 additions & 0 deletions frontend/composables/useSignIn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const useSignIn = async () => {
const [
{ msalSignIn },
pactaClient,
{ refreshMaybeMe },
] = await Promise.all([
useMSAL(),
usePACTA(),
useSession(),
])

const signIn = () => msalSignIn()
.then(() => pactaClient.userAuthenticationFollowup())
.then(() => refreshMaybeMe())

return { signIn }
}
67 changes: 67 additions & 0 deletions frontend/composables/useTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export const useTime = () => {
const { locale: i18nLocale, t } = useI18n()
const defaultLocale = 'en-US'
const locale = computed(() => i18nLocale.value || defaultLocale)

const prefix = 'useTime'
const tt = (key: string) => t(`${prefix}.${key}`)

const humanReadableDateLong = (t: Date): ComputedRef<string> => {
return computed(() => {
if (new Date().getDate() === t.getDate()) {
return tt('today')
}
return t.toLocaleString(locale.value, { dateStyle: 'long' })
})
}

const humanReadableDate = (t: Date): ComputedRef<string> => {
return computed(() => {
if (new Date().getDate() === t.getDate()) {
return tt('today')
}
return t.toLocaleString(locale.value, { dateStyle: 'short' })
})
}

const humanReadableTime = (t: Date): ComputedRef<string> => {
return computed(() => {
if (new Date().getDate() === t.getDate()) {
return t.toLocaleTimeString(locale.value, { timeStyle: 'short' })
}
return t.toLocaleString(locale.value, { dateStyle: 'short', timeStyle: 'short' })
})
}

const humanReadableDateLongFromStandardString = (s: string): ComputedRef<string> => {
return humanReadableDateLong(new Date(Date.parse(s)))
}

const humanReadableDateFromStandardString = (s: string): ComputedRef<string> => {
return humanReadableDate(new Date(Date.parse(s)))
}

const humanReadableTimeFromStandardString = (asStr: string): ComputedRef<string> => {
return humanReadableTime(new Date(Date.parse(asStr)))
}

const humanReadableTimeWithSeconds = (t: Date): ComputedRef<string> => {
return computed(() => {
const now = new Date()
if (now.getDate() === t.getDate()) {
if (now.getHours() === t.getHours()) {
return t.toLocaleTimeString(locale.value, { hour: 'numeric', minute: '2-digit', second: '2-digit' })
}
return t.toLocaleTimeString(locale.value, { timeStyle: 'short' })
}
return t.toLocaleString(locale.value, { dateStyle: 'short', timeStyle: 'short' })
})
}

return {
humanReadableDateFromStandardString,
humanReadableDateLongFromStandardString,
humanReadableTimeFromStandardString,
humanReadableTimeWithSeconds,
}
}
11 changes: 11 additions & 0 deletions frontend/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,15 @@
"Unused": "Unused",
"Includes Illegal Characters": "Includes illegal characters"
},
"pages/join": {
"Join Initiative:": "Join Initiative:",
"You've been invited to join an initiative": "You've been invited to join an initiative",
"You can learn more about the initiative here.": "You can learn more about the initiative here.",
"if-accept": "If you accept this invitation, you'll be able to add your portfolios to the project, where they will be included in aggregated analysis. You aren't required to accept this invitation if you just want to run the analysis on your own, but joining the initiative may enable you to access internal benefits, like the ability to see the analysis results from the aggregated portfolios.",
"what-shared": "If you accept X, Y, Z will be whared with the initiative administrators, but A, B, C will not be.",
"do-accept": "Do you want to accept this invitation?",
"Not Now": "Not Now",
"Accept Invitation": "Accept Invitation",
"This invitation has already been used.": "This invitation has already been used.",
}
}
57 changes: 0 additions & 57 deletions frontend/lib/time/index.ts

This file was deleted.

4 changes: 2 additions & 2 deletions frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export default defineNuxtConfig({
locales: [
{ code: 'en', iso: 'en-US', file: { path: 'en.json', cache: false }, name: 'English' },
{ code: 'fr', iso: 'fr-FR', file: { path: 'fr.json', cache: false }, name: 'Français' },
{ code: 'es', iso: 'es-ES', file: { path: 'es.json', cache: false }, name: 'Deutsch' },
{ code: 'de', iso: 'de-DE', file: { path: 'de.json', cache: false }, name: 'Español' },
{ code: 'es', iso: 'es-ES', file: { path: 'es.json', cache: false }, name: 'Español' },
{ code: 'de', iso: 'de-DE', file: { path: 'de.json', cache: false }, name: 'Deutsch' },
],
lazy: true,
langDir: 'lang',
Expand Down
3 changes: 1 addition & 2 deletions frontend/pages/admin/initiative/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { humanReadableTimeFromStandardString } from '@/lib/time'
const { humanReadableTimeFromStandardString } = useTime()
const router = useRouter()
const pactaClient = await usePACTA()
const { loading: { withLoading } } = useModal()
Expand Down
4 changes: 3 additions & 1 deletion frontend/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const { isAuthenticated, signIn, signOut } = await useMSAL()
const isAuthenticated = useIsAuthenticated()
const { signOut } = await useMSAL()
const { signIn } = await useSignIn()
</script>

<template>
Expand Down
3 changes: 1 addition & 2 deletions frontend/pages/initiative/[id]/index.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script setup lang="ts">
import { humanReadableDateFromStandardString } from '@/lib/time'
const pactaClient = await usePACTA()
const { fromParams } = useURLParams()
const { humanReadableDateFromStandardString } = useTime()
const id = presentOrCheckURL(fromParams('id'))
const prefix = `initiative/${id}/invitations`
Expand Down
5 changes: 2 additions & 3 deletions frontend/pages/initiative/[id]/invitations.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<script setup lang="ts">
import { humanReadableTimeFromStandardString } from '@/lib/time'
import type DataTable from 'primevue/datatable'
// const router = useRouter()
const { humanReadableTimeFromStandardString } = useTime()
const { public: { baseURL } } = useRuntimeConfig()
const { t } = useI18n()
const pactaClient = await usePACTA()
const { loading: { withLoading } } = useModal()
const { fromParams } = useURLParams()
const localePath = useLocalePath()
const pactaClient = await usePACTA()
const tt = (key: string) => t(`initiative/invitations.${key}`)
Expand Down
Loading

0 comments on commit 9b5c911

Please sign in to comment.