@@ -107,7 +107,7 @@
-
+
We will delete all projects where you are the sole owner, and any associated
data. We will ask you to type in your email address and press the delete
button.
@@ -131,20 +131,20 @@
@@ -170,6 +170,7 @@ import { useRoute } from 'vue-router'
import { WorkspacePlanStatuses } from '~/lib/common/generated/gql/graphql'
import { isPaidPlan } from '~/lib/billing/helpers/types'
import { useWorkspaceSsoStatus } from '~/lib/workspaces/composables/sso'
+
graphql(`
fragment SettingsWorkspacesGeneral_Workspace on Workspace {
...SettingsWorkspacesGeneralEditAvatar_Workspace
@@ -189,11 +190,17 @@ graphql(`
}
`)
+definePageMeta({
+ layout: 'settings'
+})
+
+useHead({
+ title: 'Settings | Workspace - General'
+})
+
type FormValues = { name: string; description: string; defaultProjectRole: StreamRoles }
-const props = defineProps<{
- workspaceId: string
-}>()
+const routeSlug = computed(() => (route.params.slug as string) || '')
const IconEdit = resolveComponent('IconEdit')
@@ -207,12 +214,12 @@ const { mutate: updateMutation } = useMutation(settingsUpdateWorkspaceMutation)
const { result: workspaceResult, onResult } = useQuery(
settingsWorkspaceGeneralQuery,
() => ({
- id: props.workspaceId
+ slug: routeSlug.value
})
)
const config = useRuntimeConfig()
const { hasSsoEnabled, needsSsoLogin } = useWorkspaceSsoStatus({
- workspaceSlug: computed(() => workspaceResult.value?.workspace?.slug || '')
+ workspaceSlug: computed(() => workspaceResult.value?.workspaceBySlug?.slug || '')
})
const name = ref('')
@@ -224,7 +231,7 @@ const showLeaveDialog = ref(false)
const defaultProjectRole = ref()
const isAdmin = computed(
- () => workspaceResult.value?.workspace?.role === Roles.Workspace.Admin
+ () => workspaceResult.value?.workspaceBySlug?.role === Roles.Workspace.Admin
)
const canDeleteWorkspace = computed(
() =>
@@ -237,8 +244,8 @@ const canDeleteWorkspace = computed(
WorkspacePlanStatuses.PaymentFailed,
WorkspacePlanStatuses.CancelationScheduled
].includes(
- workspaceResult.value?.workspace?.plan?.status as WorkspacePlanStatuses
- ) && isPaidPlan(workspaceResult.value?.workspace?.plan?.name)
+ workspaceResult.value?.workspaceBySlug?.plan?.status as WorkspacePlanStatuses
+ ) && isPaidPlan(workspaceResult.value?.workspaceBySlug?.plan?.name)
))
)
const deleteWorkspaceTooltip = computed(() => {
@@ -250,15 +257,18 @@ const deleteWorkspaceTooltip = computed(() => {
})
const save = handleSubmit(async () => {
- if (!workspaceResult.value?.workspace) return
+ if (!workspaceResult.value?.workspaceBySlug) return
const input: WorkspaceUpdateInput = {
- id: workspaceResult.value.workspace.id
+ id: workspaceResult.value.workspaceBySlug.id
}
- if (name.value !== workspaceResult.value.workspace.name) input.name = name.value
- if (description.value !== workspaceResult.value.workspace.description)
+ if (name.value !== workspaceResult.value.workspaceBySlug.name) input.name = name.value
+ if (description.value !== workspaceResult.value.workspaceBySlug.description)
input.description = description.value
- if (defaultProjectRole.value !== workspaceResult.value.workspace.defaultProjectRole)
+ if (
+ defaultProjectRole.value !==
+ workspaceResult.value.workspaceBySlug.defaultProjectRole
+ )
input.defaultProjectRole = defaultProjectRole.value
const result = await updateMutation({ input }).catch(convertThrowIntoFetchResult)
@@ -274,7 +284,7 @@ const save = handleSubmit(async () => {
(key) => key !== 'id'
),
// eslint-disable-next-line camelcase
- workspace_id: props.workspaceId,
+ workspace_id: workspaceResult.value.workspaceBySlug.id,
source: 'settings'
})
} else {
@@ -290,10 +300,10 @@ const save = handleSubmit(async () => {
watch(
() => workspaceResult,
() => {
- if (workspaceResult.value?.workspace) {
- name.value = workspaceResult.value.workspace.name
- description.value = workspaceResult.value.workspace.description ?? ''
- slug.value = workspaceResult.value.workspace.slug ?? ''
+ if (workspaceResult.value?.workspaceBySlug) {
+ name.value = workspaceResult.value.workspaceBySlug.name
+ description.value = workspaceResult.value.workspaceBySlug.description ?? ''
+ slug.value = workspaceResult.value.workspaceBySlug.slug ?? ''
}
},
{ deep: true, immediate: true }
@@ -301,7 +311,8 @@ watch(
onResult((res) => {
if (res.data) {
- defaultProjectRole.value = res.data.workspace.defaultProjectRole as StreamRoles
+ defaultProjectRole.value = res.data.workspaceBySlug
+ .defaultProjectRole as StreamRoles
}
})
@@ -334,7 +345,7 @@ const openSlugEditDialog = () => {
}
const updateWorkspaceSlug = async (newSlug: string) => {
- if (!workspaceResult.value?.workspace) {
+ if (!workspaceResult.value?.workspaceBySlug) {
return
}
@@ -342,7 +353,7 @@ const updateWorkspaceSlug = async (newSlug: string) => {
const result = await updateMutation({
input: {
- id: workspaceResult.value.workspace.id,
+ id: workspaceResult.value.workspaceBySlug.id,
slug: newSlug
}
})
@@ -357,7 +368,7 @@ const updateWorkspaceSlug = async (newSlug: string) => {
slug.value = newSlug
- if (route.params.slug === oldSlug) {
+ if (routeSlug.value === oldSlug) {
router.replace(workspaceRoute(newSlug))
}
} else {
diff --git a/packages/frontend-2/components/settings/workspaces/Members.vue b/packages/frontend-2/pages/settings/workspaces/[slug]/members.vue
similarity index 73%
rename from packages/frontend-2/components/settings/workspaces/Members.vue
rename to packages/frontend-2/pages/settings/workspaces/[slug]/members.vue
index 2ca7135770..39ab3d58b0 100644
--- a/packages/frontend-2/components/settings/workspaces/Members.vue
+++ b/packages/frontend-2/pages/settings/workspaces/[slug]/members.vue
@@ -12,17 +12,17 @@
@@ -55,29 +55,34 @@ graphql(`
}
`)
-const props = defineProps<{
- workspaceId: string
-}>()
+definePageMeta({
+ layout: 'settings'
+})
+useHead({
+ title: 'Settings | Workspace - Members'
+})
+
+const slug = computed(() => (route.params.slug as string) || '')
+
+const route = useRoute()
const { result } = useQuery(settingsWorkspacesMembersQuery, () => ({
- workspaceId: props.workspaceId
+ slug: slug.value
}))
-const isAdmin = computed(() => result.value?.workspace?.role === Roles.Workspace.Admin)
-const workspace = computed(() => result.value?.workspace)
+const workspace = computed(() => result.value?.workspaceBySlug)
+const isAdmin = computed(() => workspace.value?.role === Roles.Workspace.Admin)
const memberCount = computed(
() =>
- result.value?.workspace.team.items.filter(
- (item) => item.role !== Roles.Workspace.Guest
- ).length
+ workspace.value?.team.items.filter((item) => item.role !== Roles.Workspace.Guest)
+ .length
)
const guestCount = computed(
() =>
- result.value?.workspace.team.items.filter(
- (item) => item.role === Roles.Workspace.Guest
- ).length
+ workspace.value?.team.items.filter((item) => item.role === Roles.Workspace.Guest)
+ .length
)
-const invitedCount = computed(() => result.value?.workspace.invitedTeam?.length)
+const invitedCount = computed(() => workspace.value?.invitedTeam?.length)
const tabItems = computed(() => [
{ title: 'Members', id: 'members', count: memberCount.value },
{ title: 'Guests', id: 'guests', count: guestCount.value },
diff --git a/packages/frontend-2/components/settings/workspaces/Projects.vue b/packages/frontend-2/pages/settings/workspaces/[slug]/projects.vue
similarity index 72%
rename from packages/frontend-2/components/settings/workspaces/Projects.vue
rename to packages/frontend-2/pages/settings/workspaces/[slug]/projects.vue
index 16cb8206ca..8c45ac8dcd 100644
--- a/packages/frontend-2/components/settings/workspaces/Projects.vue
+++ b/packages/frontend-2/pages/settings/workspaces/[slug]/projects.vue
@@ -12,9 +12,8 @@
v-else
v-model:search="search"
:projects="projects"
- :workspace-id="workspaceId"
- :disable-create="result?.workspace.readOnly"
- @close="$emit('close')"
+ :workspace-id="result?.workspaceBySlug.id"
+ :disable-create="result?.workspaceBySlug.readOnly"
/>
()
+definePageMeta({
+ layout: 'settings'
+})
+
+useHead({
+ title: 'Settings | Workspace - Projects'
+})
-defineEmits<{
- (e: 'close'): void
-}>()
+const route = useRoute()
const search = ref('')
+const slug = computed(() => (route.params.slug as string) || '')
+
const {
identifier,
onInfiniteLoad,
@@ -60,10 +63,10 @@ const {
baseVariables: computed(() => ({
limit: 50,
filter: { search: search.value?.length ? search.value : null },
- workspaceId: props.workspaceId
+ slug: slug.value
})),
- resolveKey: (vars) => [vars.workspaceId, vars.filter?.search || ''],
- resolveCurrentResult: (res) => res?.workspace.projects,
+ resolveKey: (vars) => [vars.slug, vars.filter?.search || ''],
+ resolveCurrentResult: (res) => res?.workspaceBySlug.projects,
resolveNextPageVariables: (baseVars, cursor) => ({
...baseVars,
cursor
@@ -71,8 +74,6 @@ const {
resolveCursorFromVariables: (vars) => vars.cursor
})
-const projects = computed(() => result.value?.workspace.projects.items || [])
-const workspaceSlug = computed(() => result.value?.workspace.slug || '')
-
-useWorkspaceProjectsUpdatedTracking(computed(() => workspaceSlug.value))
+const projects = computed(() => result.value?.workspaceBySlug.projects.items || [])
+useWorkspaceProjectsUpdatedTracking(computed(() => slug.value))
diff --git a/packages/frontend-2/components/settings/workspaces/Regions.vue b/packages/frontend-2/pages/settings/workspaces/[slug]/regions.vue
similarity index 91%
rename from packages/frontend-2/components/settings/workspaces/Regions.vue
rename to packages/frontend-2/pages/settings/workspaces/[slug]/regions.vue
index 95de1c1697..2a5082a012 100644
--- a/packages/frontend-2/components/settings/workspaces/Regions.vue
+++ b/packages/frontend-2/pages/settings/workspaces/[slug]/regions.vue
@@ -79,7 +79,7 @@
Upgrade to Business
@@ -120,10 +120,9 @@ import { useMutationLoading, useQuery, useQueryLoading } from '@vue/apollo-compo
import { graphql } from '~/lib/common/generated/gql'
import type { SettingsWorkspacesRegionsSelect_ServerRegionItemFragment } from '~/lib/common/generated/gql/graphql'
import { useMixpanel } from '~/lib/core/composables/mp'
-import { useMenuState } from '~/lib/settings/composables/menu'
import { settingsWorkspaceRegionsQuery } from '~/lib/settings/graphql/queries'
-import { SettingMenuKeys } from '~/lib/settings/helpers/types'
import { useSetDefaultWorkspaceRegion } from '~/lib/workspaces/composables/management'
+import { settingsWorkspaceRoutes } from '~/lib/common/helpers/route'
graphql(`
fragment SettingsWorkspacesRegions_Workspace on Workspace {
@@ -153,12 +152,18 @@ graphql(`
}
`)
-const props = defineProps<{
- workspaceId: string
-}>()
+definePageMeta({
+ layout: 'settings'
+})
+useHead({
+ title: 'Settings | Workspace - Regions'
+})
+
+const slug = computed(() => (route.params.slug as string) || '')
+
+const route = useRoute()
const mp = useMixpanel()
-const { goToWorkspaceMenuItem } = useMenuState()
const pageFetchPolicy = usePageQueryStandardFetchPolicy()
const isMutationLoading = useMutationLoading()
const isQueryLoading = useQueryLoading()
@@ -166,7 +171,7 @@ const setDefaultWorkspaceRegion = useSetDefaultWorkspaceRegion()
const { result } = useQuery(
settingsWorkspaceRegionsQuery,
() => ({
- workspaceId: props.workspaceId
+ slug: slug.value
}),
() => ({
fetchPolicy: pageFetchPolicy.value
@@ -175,7 +180,7 @@ const { result } = useQuery(
const showDefaultRegionSaveDisclaimer = ref(false)
const defaultRegion = ref
()
-const workspace = computed(() => result.value?.workspace)
+const workspace = computed(() => result.value?.workspaceBySlug)
const availableRegions = computed(
() => result.value?.serverInfo.multiRegion.regions || []
)
@@ -201,31 +206,28 @@ const onDefaultRegionSave = () => {
const saveDefaultRegion = async () => {
const regionKey = defaultRegion.value?.key
+ if (!workspace.value) return
if (!regionKey) return
- if (regionKey === result.value?.workspace.defaultRegion?.key) return
+ if (regionKey === workspace.value?.defaultRegion?.key) return
const res = await setDefaultWorkspaceRegion({
- workspaceId: props.workspaceId,
+ workspaceId: workspace.value?.id,
regionKey
})
if (res?.defaultRegion?.id) {
mp.track('Workspace Default Region Set', {
regionKey,
// eslint-disable-next-line camelcase
- workspace_id: props.workspaceId
+ workspace_id: workspace.value?.id
})
showDefaultRegionSaveDisclaimer.value = false
}
}
-const goToBilling = () => {
- goToWorkspaceMenuItem(props.workspaceId, SettingMenuKeys.Workspace.Billing)
-}
-
watch(
result,
() => {
- defaultRegion.value = result.value?.workspace.defaultRegion || undefined
+ defaultRegion.value = workspace.value?.defaultRegion || undefined
},
{ immediate: true }
)
diff --git a/packages/frontend-2/components/settings/workspaces/Security.vue b/packages/frontend-2/pages/settings/workspaces/[slug]/security.vue
similarity index 64%
rename from packages/frontend-2/components/settings/workspaces/Security.vue
rename to packages/frontend-2/pages/settings/workspaces/[slug]/security.vue
index aaea911b39..361b3510c3 100644
--- a/packages/frontend-2/components/settings/workspaces/Security.vue
+++ b/packages/frontend-2/pages/settings/workspaces/[slug]/security.vue
@@ -6,10 +6,7 @@
text="Manage verified workspace domains and associated features."
/>
-
+
@@ -18,10 +15,7 @@
class="pb-4 md:pb-6"
subheading
/>
-
+
With SSO enabled, allowed domains are configured on your identity provider's
side.
@@ -83,8 +77,8 @@
Domain protection
- Admins won't be able to add users as members (or admins) to a workspace
- unless they are part of a workspace's email domain.
+ Only users with email addresses from your verified domains can be added
+ as workspace members or administrators.
- Domain discoverability
+ Domain-based discoverability
- Makes your workspace discoverable by employees who sign up with your
- company's specified email domain.
+ When enabled, users with a verified email address from your verified
+ domain list will be able to able to automatically join this workspace.
@@ -126,19 +120,19 @@