Skip to content

Commit 9b5c911

Browse files
committed
Addresses Review Comments
1 parent 7e3091b commit 9b5c911

File tree

23 files changed

+179
-120
lines changed

23 files changed

+179
-120
lines changed

frontend/components/initiative/Toolbar.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
import { type InitiativeUserRelationship } from '@/openapi/generated/pacta'
33
44
const localePath = useLocalePath()
5-
const { getMaybeMe } = useSession()
65
const { t } = useI18n()
7-
6+
const { getMaybeMe } = await useSession()
87
const { isAdmin, maybeMe } = await getMaybeMe()
8+
99
const prefix = 'InitiativeToolbar'
1010
const tt = (key: string) => t(`${prefix}.${key}`)
1111

frontend/components/modal/FakeUsers.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
<script setup lang="ts">
22
const { fakeUsers: { fakeUsersVisible } } = useModal()
33
const { t } = useI18n()
4-
const { getMaybeMe, refreshMaybeMe } = useSession()
5-
const { isAuthenticated, signIn, signOut } = await useMSAL()
4+
const isAuthenticated = useIsAuthenticated()
65
const localePath = useLocalePath()
6+
const [
7+
{ signOut },
8+
{ getMaybeMe, refreshMaybeMe },
9+
{ signIn },
10+
] = await Promise.all([
11+
useMSAL(),
12+
useSession(),
13+
useSignIn(),
14+
])
715
816
const prefix = 'ModalFakeUsers'
917
const tt = (s: string) => t(`${prefix}.${s}`)

frontend/components/standard/Nav.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@ import { type MenuItem } from 'primevue/menuitem'
33
44
const { t } = useI18n()
55
const localePath = useLocalePath()
6-
const { isAuthenticated, signIn, signOut } = await useMSAL()
7-
const { getMaybeMe } = useSession()
6+
const isAuthenticated = useIsAuthenticated()
87
const router = useRouter()
9-
8+
const [
9+
{ signOut },
10+
{ signIn },
11+
{ getMaybeMe },
12+
] = await Promise.all([
13+
useMSAL(),
14+
useSignIn(),
15+
useSession(),
16+
])
1017
const { isAdmin, maybeMe } = await getMaybeMe()
1118
1219
const prefix = 'StandardNav'

frontend/components/user/Editor.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<script setup lang="ts">
22
import { type EditorUser } from '@/lib/editor'
33
4-
const { getMaybeMe } = useSession()
54
const { t } = useI18n()
6-
5+
const { getMaybeMe } = await useSession()
76
const { maybeMe } = await getMaybeMe()
87
98
interface Props {

frontend/components/user/Toolbar.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<script setup lang="ts">
2-
const { getMaybeMe } = useSession()
3-
2+
const { t } = useI18n()
43
const localePath = useLocalePath()
4+
const { getMaybeMe } = await useSession()
55
const { isAdmin, maybeMe } = await getMaybeMe()
6-
const { t } = useI18n()
76
87
interface Props {
98
userId: string
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const useIsAuthenticated = () => {
2+
const prefix = 'useIsAuthenticated'
3+
const isAuthenticated = useState<boolean>(`${prefix}.isAuthenticated`, () => true)
4+
return isAuthenticated
5+
}

frontend/composables/useMSAL.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ import { computed } from 'vue'
1919
import { type APIKey } from '~/openapi/generated/user'
2020

2121
export const useMSAL = async () => {
22-
const { isAuthenticated } = useSession()
22+
const isAuthenticated = useIsAuthenticated()
2323

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

3737
const router = useRouter()
38-
const { userClientWithAuth, pactaClientWithAuth } = useAPI()
38+
const { userClientWithAuth } = useAPI()
3939
const localePath = useLocalePath()
4040

4141
const { $msal: { msalConfig, b2cPolicies } } = useNuxtApp()
@@ -239,16 +239,15 @@ export const useMSAL = async () => {
239239
.then(handleResponse)
240240
}
241241

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

247247
const req = { scopes }
248248
return instance.value.loginPopup(req)
249249
.then(handleResponse)
250-
.then(getToken)
251-
.then(token => pactaClientWithAuth(token.idToken).userAuthenticationFollowup())
250+
.then(() => { /* cast to void */ })
252251
.catch((err) => {
253252
console.log('useMSAL.loginPopup', err)
254253
})
@@ -291,7 +290,7 @@ export const useMSAL = async () => {
291290
}
292291

293292
return {
294-
signIn,
293+
msalSignIn,
295294
signOut,
296295
createAPIKey,
297296
getToken,

frontend/composables/useSession.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { type User } from '@/openapi/generated/pacta'
22

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

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

frontend/composables/useSignIn.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const useSignIn = async () => {
2+
const [
3+
{ msalSignIn },
4+
pactaClient,
5+
{ refreshMaybeMe },
6+
] = await Promise.all([
7+
useMSAL(),
8+
usePACTA(),
9+
useSession(),
10+
])
11+
12+
const signIn = () => msalSignIn()
13+
.then(() => pactaClient.userAuthenticationFollowup())
14+
.then(() => refreshMaybeMe())
15+
16+
return { signIn }
17+
}

frontend/composables/useTime.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
export const useTime = () => {
2+
const { locale: i18nLocale, t } = useI18n()
3+
const defaultLocale = 'en-US'
4+
const locale = computed(() => i18nLocale.value || defaultLocale)
5+
6+
const prefix = 'useTime'
7+
const tt = (key: string) => t(`${prefix}.${key}`)
8+
9+
const humanReadableDateLong = (t: Date): ComputedRef<string> => {
10+
return computed(() => {
11+
if (new Date().getDate() === t.getDate()) {
12+
return tt('today')
13+
}
14+
return t.toLocaleString(locale.value, { dateStyle: 'long' })
15+
})
16+
}
17+
18+
const humanReadableDate = (t: Date): ComputedRef<string> => {
19+
return computed(() => {
20+
if (new Date().getDate() === t.getDate()) {
21+
return tt('today')
22+
}
23+
return t.toLocaleString(locale.value, { dateStyle: 'short' })
24+
})
25+
}
26+
27+
const humanReadableTime = (t: Date): ComputedRef<string> => {
28+
return computed(() => {
29+
if (new Date().getDate() === t.getDate()) {
30+
return t.toLocaleTimeString(locale.value, { timeStyle: 'short' })
31+
}
32+
return t.toLocaleString(locale.value, { dateStyle: 'short', timeStyle: 'short' })
33+
})
34+
}
35+
36+
const humanReadableDateLongFromStandardString = (s: string): ComputedRef<string> => {
37+
return humanReadableDateLong(new Date(Date.parse(s)))
38+
}
39+
40+
const humanReadableDateFromStandardString = (s: string): ComputedRef<string> => {
41+
return humanReadableDate(new Date(Date.parse(s)))
42+
}
43+
44+
const humanReadableTimeFromStandardString = (asStr: string): ComputedRef<string> => {
45+
return humanReadableTime(new Date(Date.parse(asStr)))
46+
}
47+
48+
const humanReadableTimeWithSeconds = (t: Date): ComputedRef<string> => {
49+
return computed(() => {
50+
const now = new Date()
51+
if (now.getDate() === t.getDate()) {
52+
if (now.getHours() === t.getHours()) {
53+
return t.toLocaleTimeString(locale.value, { hour: 'numeric', minute: '2-digit', second: '2-digit' })
54+
}
55+
return t.toLocaleTimeString(locale.value, { timeStyle: 'short' })
56+
}
57+
return t.toLocaleString(locale.value, { dateStyle: 'short', timeStyle: 'short' })
58+
})
59+
}
60+
61+
return {
62+
humanReadableDateFromStandardString,
63+
humanReadableDateLongFromStandardString,
64+
humanReadableTimeFromStandardString,
65+
humanReadableTimeWithSeconds,
66+
}
67+
}

frontend/lang/en.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,15 @@
9898
"Unused": "Unused",
9999
"Includes Illegal Characters": "Includes illegal characters"
100100
},
101+
"pages/join": {
102+
"Join Initiative:": "Join Initiative:",
103+
"You've been invited to join an initiative": "You've been invited to join an initiative",
104+
"You can learn more about the initiative here.": "You can learn more about the initiative here.",
105+
"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.",
106+
"what-shared": "If you accept X, Y, Z will be whared with the initiative administrators, but A, B, C will not be.",
107+
"do-accept": "Do you want to accept this invitation?",
108+
"Not Now": "Not Now",
109+
"Accept Invitation": "Accept Invitation",
110+
"This invitation has already been used.": "This invitation has already been used.",
111+
}
101112
}

frontend/lib/time/index.ts

Lines changed: 0 additions & 57 deletions
This file was deleted.

frontend/nuxt.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ export default defineNuxtConfig({
5454
locales: [
5555
{ code: 'en', iso: 'en-US', file: { path: 'en.json', cache: false }, name: 'English' },
5656
{ code: 'fr', iso: 'fr-FR', file: { path: 'fr.json', cache: false }, name: 'Français' },
57-
{ code: 'es', iso: 'es-ES', file: { path: 'es.json', cache: false }, name: 'Deutsch' },
58-
{ code: 'de', iso: 'de-DE', file: { path: 'de.json', cache: false }, name: 'Español' },
57+
{ code: 'es', iso: 'es-ES', file: { path: 'es.json', cache: false }, name: 'Español' },
58+
{ code: 'de', iso: 'de-DE', file: { path: 'de.json', cache: false }, name: 'Deutsch' },
5959
],
6060
lazy: true,
6161
langDir: 'lang',

frontend/pages/admin/initiative/index.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script setup lang="ts">
2-
import { humanReadableTimeFromStandardString } from '@/lib/time'
3-
2+
const { humanReadableTimeFromStandardString } = useTime()
43
const router = useRouter()
54
const pactaClient = await usePACTA()
65
const { loading: { withLoading } } = useModal()

frontend/pages/index.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<script setup lang="ts">
2-
const { isAuthenticated, signIn, signOut } = await useMSAL()
2+
const isAuthenticated = useIsAuthenticated()
3+
const { signOut } = await useMSAL()
4+
const { signIn } = await useSignIn()
35
</script>
46

57
<template>

frontend/pages/initiative/[id]/index.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<script setup lang="ts">
2-
import { humanReadableDateFromStandardString } from '@/lib/time'
3-
42
const pactaClient = await usePACTA()
53
const { fromParams } = useURLParams()
4+
const { humanReadableDateFromStandardString } = useTime()
65
76
const id = presentOrCheckURL(fromParams('id'))
87
const prefix = `initiative/${id}/invitations`

frontend/pages/initiative/[id]/invitations.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<script setup lang="ts">
2-
import { humanReadableTimeFromStandardString } from '@/lib/time'
32
import type DataTable from 'primevue/datatable'
4-
// const router = useRouter()
53
4+
const { humanReadableTimeFromStandardString } = useTime()
65
const { public: { baseURL } } = useRuntimeConfig()
76
const { t } = useI18n()
8-
const pactaClient = await usePACTA()
97
const { loading: { withLoading } } = useModal()
108
const { fromParams } = useURLParams()
119
const localePath = useLocalePath()
10+
const pactaClient = await usePACTA()
1211
1312
const tt = (key: string) => t(`initiative/invitations.${key}`)
1413

0 commit comments

Comments
 (0)