diff --git a/jsconfig.base.json b/jsconfig.base.json deleted file mode 100644 index b1b48e841..000000000 --- a/jsconfig.base.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "compilerOptions": { - "target": "es2021", - "module": "commonJS" - }, - "exclude": ["node_modules"] -} diff --git a/packages/frontend-2/.env.example b/packages/frontend-2/.env.example index a96acaa88..4a36b7b4b 100644 --- a/packages/frontend-2/.env.example +++ b/packages/frontend-2/.env.example @@ -40,6 +40,9 @@ NUXT_PUBLIC_INTERCOM_APP_ID= # Enable Autodesk construction cloud integration NUXT_PUBLIC_FF_ACC_INTEGRATION_ENABLED=false +# Local or remote URL for dashboards +NUXT_PUBLIC_DASHBOARDS_ORIGIN=http://localhost:8083 + ########################################################## # Local dev settings ########################################################## diff --git a/packages/frontend-2/assets/images/viewer/saved-views/plan_upsell.webp b/packages/frontend-2/assets/images/viewer/saved-views/plan_upsell.webp deleted file mode 100644 index 73812efd2..000000000 Binary files a/packages/frontend-2/assets/images/viewer/saved-views/plan_upsell.webp and /dev/null differ diff --git a/packages/frontend-2/components/auth/RegisterWithEmailBlock.vue b/packages/frontend-2/components/auth/RegisterWithEmailBlock.vue index 6ad390fea..e3286ea8d 100644 --- a/packages/frontend-2/components/auth/RegisterWithEmailBlock.vue +++ b/packages/frontend-2/components/auth/RegisterWithEmailBlock.vue @@ -14,13 +14,7 @@ show-label :disabled="isEmailDisabled" auto-focus - :help=" - emailIsBlocked - ? 'A work email makes it easier to discover and collaborate with your coworkers on Speckle.' - : '' - " autocomplete="email" - @blur="onEmailChange" /> ('newsletterConsent', { required: true }) const loading = ref(false) const password = ref('') const email = ref('') -const emailIsBlocked = ref(false) -const emailRules = [isEmail] +const emailRules = computed(() => + inviteToken.value || !isNoPersonalEmailsEnabled.value + ? [isEmail] + : [isEmail, doesNotContainBlockedDomain] +) const nameRules = [isRequired] const isEmailDisabled = computed(() => !!props.inviteEmail?.length || loading.value) @@ -121,11 +120,6 @@ const finalLoginRoute = computed(() => { return result.fullPath }) -const onEmailChange = () => { - if (!isWorkspacesEnabled.value) return - emailIsBlocked.value = checkIfEmailIsBlocked(email.value) -} - const onSubmit = handleSubmit(async (fullUser) => { try { loading.value = true diff --git a/packages/frontend-2/components/common/ConfirmDialog.vue b/packages/frontend-2/components/common/ConfirmDialog.vue index 8011670ee..f8bc9ac30 100644 --- a/packages/frontend-2/components/common/ConfirmDialog.vue +++ b/packages/frontend-2/components/common/ConfirmDialog.vue @@ -1,6 +1,6 @@ @@ -160,7 +178,8 @@ import { connectorsRoute, workspaceRoute, tutorialsRoute, - docsPageUrl + docsPageUrl, + dashboardsRoute } from '~/lib/common/helpers/route' import { useRoute } from 'vue-router' import { useActiveUser } from '~~/lib/auth/composables/activeUser' @@ -168,6 +187,8 @@ import { useMixpanel } from '~~/lib/core/composables/mp' import { useActiveWorkspaceSlug } from '~/lib/user/composables/activeWorkspace' import { graphql } from '~/lib/common/generated/gql' import { useQuery } from '@vue/apollo-composable' +import dayjs from 'dayjs' +import { useActiveUserMeta } from '~/lib/user/composables/meta' const dashboardSidebarQuery = graphql(` query DashboardSidebar { @@ -181,21 +202,53 @@ const dashboardSidebarQuery = graphql(` } `) +const sidebarPermissionsQuery = graphql(` + query SidebarPermissions($slug: String!) { + workspaceBySlug(slug: $slug) { + permissions { + canListDashboards { + ...FullPermissionCheckResult + } + } + } + } +`) + const { isLoggedIn } = useActiveUser() const isWorkspacesEnabled = useIsWorkspacesEnabled() +const isDashboardsEnabled = useIsDashboardsModuleEnabled() const route = useRoute() const activeWorkspaceSlug = useActiveWorkspaceSlug() const { $intercom } = useNuxtApp() const mixpanel = useMixpanel() +const { result: permissionsResult } = useQuery( + sidebarPermissionsQuery, + () => ({ + slug: activeWorkspaceSlug.value || '' + }), + () => ({ + enabled: isDashboardsEnabled.value && !!activeWorkspaceSlug.value + }) +) const { result } = useQuery(dashboardSidebarQuery, () => ({}), { enabled: isWorkspacesEnabled.value }) +const { hasDismissedIntelligenceCommunityStandUpBanner } = useActiveUserMeta() const isOpenMobile = ref(false) const showExplainerVideoDialog = ref(false) +const showIntelligenceCommunityStandUpPromo = computed(() => { + if (hasDismissedIntelligenceCommunityStandUpBanner.value) return false + return dayjs().isBefore('2025-09-10', 'day') +}) const activeWorkspace = computed(() => result.value?.activeUser?.activeWorkspace) -const showProjectsLink = computed(() => { +const canListDashboards = computed(() => { + return permissionsResult.value?.workspaceBySlug?.permissions?.canListDashboards + ?.authorized +}) + +const showWorkspaceLinks = computed(() => { return isWorkspacesEnabled.value ? activeWorkspace.value ? !!activeWorkspace.value?.role diff --git a/packages/frontend-2/components/dashboards/Card.vue b/packages/frontend-2/components/dashboards/Card.vue new file mode 100644 index 000000000..a796f7d4f --- /dev/null +++ b/packages/frontend-2/components/dashboards/Card.vue @@ -0,0 +1,103 @@ + + + diff --git a/packages/frontend-2/components/dashboards/CreateDialog.vue b/packages/frontend-2/components/dashboards/CreateDialog.vue new file mode 100644 index 000000000..ed9674fa4 --- /dev/null +++ b/packages/frontend-2/components/dashboards/CreateDialog.vue @@ -0,0 +1,70 @@ + + + diff --git a/packages/frontend-2/components/dashboards/EditDialog.vue b/packages/frontend-2/components/dashboards/EditDialog.vue new file mode 100644 index 000000000..1b4e9a793 --- /dev/null +++ b/packages/frontend-2/components/dashboards/EditDialog.vue @@ -0,0 +1,85 @@ + + + diff --git a/packages/frontend-2/components/dashboards/List.vue b/packages/frontend-2/components/dashboards/List.vue new file mode 100644 index 000000000..d0d357819 --- /dev/null +++ b/packages/frontend-2/components/dashboards/List.vue @@ -0,0 +1,105 @@ + + + diff --git a/packages/frontend-2/components/dashboards/Share.vue b/packages/frontend-2/components/dashboards/Share.vue new file mode 100644 index 000000000..8283788f8 --- /dev/null +++ b/packages/frontend-2/components/dashboards/Share.vue @@ -0,0 +1,133 @@ + + + + diff --git a/packages/frontend-2/components/error/page/Renderer.vue b/packages/frontend-2/components/error/page/Renderer.vue index a674d9749..f1acd6f68 100644 --- a/packages/frontend-2/components/error/page/Renderer.vue +++ b/packages/frontend-2/components/error/page/Renderer.vue @@ -25,10 +25,10 @@ const props = defineProps<{ isGenericErrorPage?: boolean }>() -const route = useRoute() +const route = useCurrentRouteTillNavigated() -const isProjectRoute = computed(() => route.path.match(/\/projects\/[^/]+/)) -const isWorkspaceRoute = computed(() => route.path.match(/\/workspaces\/[^/]+/)) +const isProjectRoute = computed(() => route.value.path.match(/\/projects\/[^/]+/)) +const isWorkspaceRoute = computed(() => route.value.path.match(/\/workspaces\/[^/]+/)) const finalError = computed(() => formatAppError(props.error)) const isNoProjectAccessError = computed( diff --git a/packages/frontend-2/components/header/Empty.vue b/packages/frontend-2/components/header/Empty.vue index 8e34c5b93..668fe7ade 100644 --- a/packages/frontend-2/components/header/Empty.vue +++ b/packages/frontend-2/components/header/Empty.vue @@ -6,6 +6,9 @@
+
+ +
diff --git a/packages/frontend-2/components/header/nav/Bar.vue b/packages/frontend-2/components/header/nav/Bar.vue index fc5617f2f..fe368c27d 100644 --- a/packages/frontend-2/components/header/nav/Bar.vue +++ b/packages/frontend-2/components/header/nav/Bar.vue @@ -27,7 +27,7 @@ -
+
() + const isWorkspacesEnabled = useIsWorkspacesEnabled() const { activeUser, isLoggedIn } = useActiveUser() const route = useRoute() diff --git a/packages/frontend-2/components/header/nav/Share.vue b/packages/frontend-2/components/header/nav/Share.vue index 2b6ef75d2..af8ddb3a3 100644 --- a/packages/frontend-2/components/header/nav/Share.vue +++ b/packages/frontend-2/components/header/nav/Share.vue @@ -1,9 +1,13 @@