Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Move settings from individual pages into one settings modal #2502

Merged
merged 96 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 94 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
afe4b8f
Clean up code
Mikehrn Jun 24, 2024
c2d3ddd
Added projects settings page
Mikehrn Jun 25, 2024
37c3b80
Merge branch 'main' into mike/workspace-settings
Mikehrn Jun 25, 2024
0b871d3
WIP
Mikehrn Jun 25, 2024
0348a98
Moved pages to modal
Mikehrn Jun 27, 2024
4522eab
update modal styling
Mikehrn Jul 1, 2024
415a854
SIdebar styling updates
andrewwallacespeckle Jul 1, 2024
1a402fe
Merged main
Mikehrn Jul 1, 2024
8a37e50
feat: refactor component
andrewwallacespeckle Jul 1, 2024
a2f3fab
Remove unused args
andrewwallacespeckle Jul 1, 2024
9a15818
Merge branch 'main' into andrew/web-1188-new-sidebar
andrewwallacespeckle Jul 1, 2024
317d1af
Remove styles. Semantic tags
andrewwallacespeckle Jul 1, 2024
7aa84a5
FE2 TESTING CHANGES
andrewwallacespeckle Jul 1, 2024
3ac423c
Merge branch 'andrew/web-1188-new-sidebar' into mike/update-modal-sty…
Mikehrn Jul 2, 2024
f7b4c8c
Merge branch 'andrew/web-1188-new-sidebar' into mike/workspace-settings
Mikehrn Jul 2, 2024
143ace1
Implemented sidebar
Mikehrn Jul 2, 2024
5b2ce3f
Remove Dialog temporarily
Mikehrn Jul 2, 2024
01930f7
Added missing pages
Mikehrn Jul 2, 2024
534190a
Change modal backdrop color
Mikehrn Jul 2, 2024
c8df175
Merge branch 'main' into andrew/web-1188-new-sidebar
andrewwallacespeckle Jul 2, 2024
04a6655
Merge branch 'main' into mike/workspace-settings
Mikehrn Jul 2, 2024
82f130b
Merge branch 'main' into mike/update-modal-styling
Mikehrn Jul 2, 2024
bb3f2e0
Merge branch 'mike/update-modal-styling' into mike/workspace-settings
Mikehrn Jul 2, 2024
a6aacb2
fix: add cursor-pointer to buttons
andrewwallacespeckle Jul 3, 2024
ea7fbe9
Changed modal to use LayoutDialog, added fullscreen variant to Layout…
Mikehrn Jul 3, 2024
f4ed08b
Merge branch 'andrew/web-1188-new-sidebar' into mike/workspace-settings
Mikehrn Jul 3, 2024
9affe30
Merge branch 'main' into andrew/web-1188-new-sidebar
andrewwallacespeckle Jul 3, 2024
22de9d4
Revert FE2 testing changes
andrewwallacespeckle Jul 3, 2024
f11506e
Make DUI3 friendly
andrewwallacespeckle Jul 3, 2024
25e185a
Revert unneeded upgrade
andrewwallacespeckle Jul 3, 2024
8fc8ea3
Clean up classes, align styling, align server settings pages
Mikehrn Jul 3, 2024
72f8ea9
Change modal to use url for displaying correct content
Mikehrn Jul 3, 2024
c2383c4
Cleanup code; change template to loop over config
Mikehrn Jul 4, 2024
2ac6eb1
Merge branch 'andrew/web-1188-new-sidebar' into mike/workspace-settings
Mikehrn Jul 4, 2024
5872fcb
Updated styling to align all pages on desktop
Mikehrn Jul 4, 2024
074f980
Added version control section
Mikehrn Jul 4, 2024
166a8d3
Clean up projects table layout
Mikehrn Jul 4, 2024
3e3e0e4
Improved mobile styling
Mikehrn Jul 5, 2024
11a00c5
Merge branch 'main' into mike/workspace-settings
Mikehrn Jul 5, 2024
7113170
Clean up layout, fix Dialog bugs, remove useHead from modal pages
Mikehrn Jul 5, 2024
2ae2a97
Update sub headings
benjaminvo Jul 5, 2024
ca598ba
CamelCase button copy
benjaminvo Jul 5, 2024
1ee8e3c
Add hover effect to dialog close button
benjaminvo Jul 5, 2024
89f4cdb
Minor tweaks to styling, copy, and button colors
Mikehrn Jul 8, 2024
d6d5d2c
Merged branch; fixed copy
Mikehrn Jul 8, 2024
8f76b49
Update copy; rename files; fix sidebar styling
Mikehrn Jul 8, 2024
4ed7338
Moved closed option to LayoutDialog; updated implementation in Settin…
Mikehrn Jul 8, 2024
44bf1d1
Fixed scrollbar being visible without overflow
Mikehrn Jul 8, 2024
2d0703c
Abstracted all header into 1 component
Mikehrn Jul 8, 2024
cc8d19d
Delete old files, move dialogs to settings folder
Mikehrn Jul 8, 2024
c963fe6
Added redirect from old URLs to new ones
Mikehrn Jul 8, 2024
15faf89
Cleanup: remove old files; move components into folder
Mikehrn Jul 8, 2024
c705bed
Added URL handling
Mikehrn Jul 10, 2024
05a9b02
Changed routes to be added progrmatically, so they can load the dashb…
Mikehrn Jul 10, 2024
02fca06
Merge branch 'main' into mike/workspace-settings
Mikehrn Jul 11, 2024
e4720d7
Merge branch 'main' into mike/workspace-settings
Mikehrn Jul 11, 2024
7222db4
Fix capitalization
Mikehrn Jul 11, 2024
eaf151c
Fix type issues and update copy
Mikehrn Jul 12, 2024
94fc96c
Minor bugfix after fixing types
Mikehrn Jul 12, 2024
8024551
Fix pipeline issue
Mikehrn Jul 15, 2024
3e2e218
Fix addidental delete
Mikehrn Jul 15, 2024
9051f14
Update Dialog.vue
Mikehrn Jul 15, 2024
654ebef
Remove route maniplulation from settings dialog
Mikehrn Jul 16, 2024
918c21e
Minor bugfixes
Mikehrn Jul 16, 2024
7c390ff
Fix dialog closing
Mikehrn Jul 16, 2024
97b6070
Fixed dialog on mobile
Mikehrn Jul 16, 2024
ff0ac5a
Fix linting
Mikehrn Jul 16, 2024
6753c23
Fix linting
Mikehrn Jul 16, 2024
9e6ad51
Merge branch 'main' into mike/workspace-settings
Mikehrn Jul 17, 2024
fe431eb
Added support for direct URLs
Mikehrn Jul 18, 2024
f254447
fix types
Mikehrn Jul 18, 2024
6cfef3c
Added fix for mobile safari
Mikehrn Jul 18, 2024
5776fcd
Added fix for mobile safari
Mikehrn Jul 18, 2024
ec06dff
Fixed typo
Mikehrn Jul 18, 2024
b51bc96
Fix height bug in sfari
Mikehrn Jul 18, 2024
e285816
Fixed breakpoint isses, added link to /settings
Mikehrn Jul 18, 2024
6283944
Fix typo
Mikehrn Jul 18, 2024
8fc78ec
Adjust weights and profile settings page header
benjaminvo Jul 18, 2024
d62ddbe
Merge branch 'mike/workspace-settings' of https://github.com/speckles…
benjaminvo Jul 18, 2024
7b90396
Change var name
Mikehrn Jul 18, 2024
73c01d3
Updated old redirects
Mikehrn Jul 18, 2024
dff3cba
Merged main
Mikehrn Jul 19, 2024
649a469
Moved onMounted, change typeof string to lodash
Mikehrn Jul 19, 2024
ec1e734
Small refactor for checking query, change to defineModel
Mikehrn Jul 19, 2024
41508d7
Small refactor for checking query, change to defineModel
Mikehrn Jul 19, 2024
d0797a9
Added fallback for invalid queries
Mikehrn Jul 19, 2024
ed24e9a
Fix type issues
Mikehrn Jul 19, 2024
a8c5de4
Moved scoped formatting to a function
Mikehrn Jul 19, 2024
667e6e4
Refactor to useDebouncedTextInput
Mikehrn Jul 19, 2024
5cf7ac5
Changed user to always be passed as a prop
Mikehrn Jul 19, 2024
74655d8
Remove leftover comment
Mikehrn Jul 19, 2024
f66213c
Small reactivity fix
Mikehrn Jul 19, 2024
d987ff0
Moved scrollclasses to apply to children, so it reset when component …
Mikehrn Jul 20, 2024
ed0fd98
Changed User to use fragments
Mikehrn Jul 22, 2024
0c2d338
Created new fragment for overarching user
Mikehrn Jul 22, 2024
7dd77ac
Hide server settings if you're not an admin
Mikehrn Jul 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
484 changes: 309 additions & 175 deletions packages/dui3/lib/common/generated/gql/graphql.ts

Large diffs are not rendered by default.

71 changes: 44 additions & 27 deletions packages/frontend-2/components/header/NavUserMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@
<NuxtLink
:class="[
active ? 'bg-foundation-focus' : '',
'flex gap-2.5 items-center px-3 py-2.5 text-sm text-foreground cursor-pointer transition mx-1 rounded'
'flex gap-3.5 items-center px-3 py-2.5 text-sm text-foreground cursor-pointer transition mx-1 rounded'
]"
@click="() => (showProfileEditDialog = true)"
@click="toggleSettingsDialog(settingsQueries.user.profile)"
>
<UserAvatar :user="activeUser" size="sm" class="-ml-0.5 mr-px" />
Edit profile
<UserCircleIcon class="w-5 h-5" />
Settings
</NuxtLink>
</MenuItem>
<MenuItem v-if="isAdmin" v-slot="{ active }">
Expand All @@ -51,10 +51,10 @@
active ? 'bg-foundation-focus' : '',
'flex gap-3.5 items-center px-3 py-2.5 text-sm text-foreground cursor-pointer transition mx-1 rounded'
]"
@click="goToServerManagement()"
@click="toggleSettingsDialog(settingsQueries.server.general)"
>
<Cog6ToothIcon class="w-5 h-5" />
Server management
<ServerStackIcon class="w-5 h-5" />
Server settings
</NuxtLink>
</MenuItem>
<MenuItem v-slot="{ active }">
Expand Down Expand Up @@ -127,11 +127,16 @@
</MenuItems>
</Transition>
</Menu>
<ServerManagementInviteDialog v-model:open="showInviteDialog" />
<UserProfileEditDialog v-model:open="showProfileEditDialog" />
<SettingsServerUserInviteDialog v-model:open="showInviteDialog" />
<SettingsDialog
v-model:open="showSettingsDialog"
v-model:target-menu-item="settingsDialogTarget"
/>
</div>
</template>
<script setup lang="ts">
import { isString } from 'lodash'
import { useBreakpoints } from '@vueuse/core'
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
import {
XMarkIcon,
Expand All @@ -140,54 +145,66 @@ import {
SunIcon,
MoonIcon,
EnvelopeIcon,
Cog6ToothIcon,
CloudArrowDownIcon,
ChatBubbleLeftRightIcon
ChatBubbleLeftRightIcon,
UserCircleIcon,
ServerStackIcon
} from '@heroicons/vue/24/outline'
import { Roles } from '@speckle/shared'
import { TailwindBreakpoints } from '~~/lib/common/helpers/tailwind'
import { useActiveUser } from '~~/lib/auth/composables/activeUser'
import { useAuthManager } from '~~/lib/auth/composables/auth'
import { useTheme } from '~~/lib/core/composables/theme'
import { useServerInfo } from '~/lib/core/composables/server'
import { homeRoute, profileRoute, connectorsPageUrl } from '~/lib/common/helpers/route'
import { connectorsPageUrl, settingsQueries } from '~/lib/common/helpers/route'
import type { RouteLocationRaw } from 'vue-router'

defineProps<{
loginUrl?: RouteLocationRaw
}>()

const route = useRoute()
const { logout } = useAuthManager()
const { activeUser, isGuest } = useActiveUser()
const { isDarkTheme, toggleTheme } = useTheme()
const { serverInfo } = useServerInfo()
const router = useRouter()
const route = useRoute()

const showInviteDialog = ref(false)
const showProfileEditDialog = ref(false)
const showSettingsDialog = ref(false)
const settingsDialogTarget = ref<string | null>(null)
const menuButtonId = useId()
const breakpoints = useBreakpoints(TailwindBreakpoints)
const isMobile = breakpoints.smaller('md')

const Icon = computed(() => (isDarkTheme.value ? SunIcon : MoonIcon))
const version = computed(() => serverInfo.value?.version)
const isAdmin = computed(() => activeUser.value?.role === Roles.Server.Admin)
const isProfileRoute = computed(() => route.path === profileRoute)

const toggleInviteDialog = () => {
showInviteDialog.value = true
}

const goToServerManagement = () => {
router.push('/server-management')
const toggleSettingsDialog = (target: string) => {
showSettingsDialog.value = true

// On mobile open the modal but dont set the target
settingsDialogTarget.value = !isMobile.value ? target : null
}

watch(
isProfileRoute,
(newVal, oldVal) => {
if (newVal && !oldVal) {
showProfileEditDialog.value = true
void router.replace({ path: homeRoute, force: true }) // in-place replace
}
},
{ immediate: true }
)
const deleteSettingsQuery = (): void => {
const currentQueryParams = { ...route.query }
delete currentQueryParams.settings
router.push({ query: currentQueryParams })
}

onMounted(() => {
const settingsQuery = route.query?.settings

if (settingsQuery && isString(settingsQuery)) {
showSettingsDialog.value = true
settingsDialogTarget.value = settingsQuery
deleteSettingsQuery()
}
})
</script>
2 changes: 1 addition & 1 deletion packages/frontend-2/components/onboarding/checklist/v1.vue
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@
>
<template #header>Your first upload</template>
</OnboardingDialogFirstSend>
<ServerManagementInviteDialog
<SettingsServerUserInviteDialog
v-model:open="showServerInviteDialog"
@update:open="(v) => (!v ? markComplete(3) : '')"
/>
Expand Down
22 changes: 0 additions & 22 deletions packages/frontend-2/components/server-management/Card.vue

This file was deleted.

51 changes: 0 additions & 51 deletions packages/frontend-2/components/server-management/CardRow.vue

This file was deleted.

156 changes: 156 additions & 0 deletions packages/frontend-2/components/settings/Dialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<template>
<LayoutDialog
v-model:open="isOpen"
v-bind="
isMobile ? { title: selectedMenuItem ? selectedMenuItem.title : 'Settings' } : {}
"
fullscreen
:show-back-button="isMobile && !!selectedMenuItem"
@back="targetMenuItem = null"
>
<div class="w-full h-full flex">
<LayoutSidebar
v-if="!isMobile || !selectedMenuItem"
class="w-full md:w-56 lg:w-60 md:p-4 md:pt-6 md:bg-foundation-page md:border-r md:border-outline-3"
>
<LayoutSidebarMenu>
<LayoutSidebarMenuGroup title="Account settings">
<template #title-icon>
<UserIcon class="h-5 w-5" />
</template>
<LayoutSidebarMenuGroupItem
v-for="(sidebarMenuItem, key) in menuItemConfig.user"
:key="key"
:label="sidebarMenuItem.title"
:class="{
'bg-foundation-focus hover:!bg-foundation-focus':
selectedMenuItem?.title === sidebarMenuItem.title
}"
@click="targetMenuItem = `${key}`"
/>
</LayoutSidebarMenuGroup>
<LayoutSidebarMenuGroup title="Server settings">
<template #title-icon>
<ServerStackIcon class="h-5 w-5" />
</template>
<LayoutSidebarMenuGroupItem
v-for="(sidebarMenuItem, key) in menuItemConfig.server"
:key="key"
:label="sidebarMenuItem.title"
:class="{
'bg-foundation-focus hover:!bg-foundation-focus':
selectedMenuItem?.title === sidebarMenuItem.title
}"
@click="targetMenuItem = `${key}`"
/>
</LayoutSidebarMenuGroup>
</LayoutSidebarMenu>
</LayoutSidebar>
<component
:is="selectedMenuItem.component"
v-if="selectedMenuItem"
:class="[
'bg-foundation md:px-10 md:py-12 md:bg-foundation w-full',
!isMobile && 'simple-scrollbar overflow-y-auto flex-1'
]"
:user="user"
/>
</div>
</LayoutDialog>
</template>

<script setup lang="ts">
import type { defineComponent } from 'vue'
import SettingsUserProfile from '~/components/settings/user/Profile.vue'
import SettingsUserNotifications from '~/components/settings/user/Notifications.vue'
import SettingsUserDeveloper from '~/components/settings/user/Developer.vue'
import SettingsServerGeneral from '~/components/settings/server/General.vue'
import SettingsServerProjects from '~/components/settings/server/Projects.vue'
import SettingsServerActiveUsers from '~/components/settings/server/ActiveUsers.vue'
import SettingsServerPendingInvitations from '~/components/settings/server/PendingInvitations.vue'
import { useBreakpoints } from '@vueuse/core'
import { TailwindBreakpoints } from '~~/lib/common/helpers/tailwind'
import { UserIcon, ServerStackIcon } from '@heroicons/vue/24/outline'
import { settingsQueries } from '~/lib/common/helpers/route'
import { useActiveUser } from '~/lib/auth/composables/activeUser'
import {
LayoutSidebar,
LayoutSidebarMenu,
LayoutSidebarMenuGroup
} from '@speckle/ui-components'

type MenuItem = {
title: string
component: ReturnType<typeof defineComponent>
}

const { activeUser: user } = useActiveUser()
const breakpoints = useBreakpoints(TailwindBreakpoints)
const isMobile = breakpoints.smaller('md')

const menuItemConfig = shallowRef<{ [key: string]: { [key: string]: MenuItem } }>({
user: {
[settingsQueries.user.profile]: {
title: 'Profile',
component: SettingsUserProfile
},
[settingsQueries.user.notifications]: {
title: 'Notifications',
component: SettingsUserNotifications
},
[settingsQueries.user.developerSettings]: {
title: 'Developer settings',
component: SettingsUserDeveloper
}
},
server: {
[settingsQueries.server.general]: {
title: 'General',
component: SettingsServerGeneral
},
[settingsQueries.server.projects]: {
title: 'Projects',
component: SettingsServerProjects
},
[settingsQueries.server.activeUsers]: {
title: 'Active users',
component: SettingsServerActiveUsers
},
[settingsQueries.server.pendingInvitations]: {
title: 'Pending invitations',
component: SettingsServerPendingInvitations
}
}
})

const isOpen = defineModel<boolean>('open', { required: true })
const targetMenuItem = defineModel<string | null>('targetMenuItem', { required: true })

const selectedMenuItem = computed((): MenuItem | null => {
const categories = [menuItemConfig.value.user, menuItemConfig.value.server]
for (const category of categories) {
if (targetMenuItem.value && targetMenuItem.value in category) {
return category[targetMenuItem.value]
}
}

if (!isMobile.value && targetMenuItem.value) {
// Fallback for invalid queries/typos
return targetMenuItem.value.includes('server')
? menuItemConfig.value.server.general
: menuItemConfig.value.user.profile
}

return null
})

watch(
() => user.value,
(newVal) => {
if (!newVal) {
isOpen.value = false
}
},
{ immediate: true }
)
</script>
Loading