From 0f5d7e1a49d2d163d17a469327d16630834c5983 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Fri, 10 May 2024 19:13:34 +0300 Subject: [PATCH 01/30] client-5862 virtual contributor profile init - basic info --- src/core/apollo/generated/apollo-hooks.ts | 80 +++++++++++++++++++ src/core/apollo/generated/graphql-schema.ts | 41 ++++++++++ .../VirtualContributor.graphql | 24 ++++++ .../layout/VCPageBanner.tsx | 22 +++++ .../layout/VCPageLayout.tsx | 49 ++++++++++++ .../vcProfilePage/VCProfilePage.tsx | 35 ++++++++ .../vcProfilePage/VCProfilePageView.tsx | 72 +++++++++++++++++ .../views/VCProfileView.tsx | 25 ++++++ src/main/routing/TopLevelRoutes.tsx | 13 +++ src/main/routing/urlBuilders.ts | 2 + src/main/routing/urlParams.ts | 1 + 11 files changed, 364 insertions(+) create mode 100644 src/domain/community/virtualContributor/VirtualContributor.graphql create mode 100644 src/domain/community/virtualContributor/layout/VCPageBanner.tsx create mode 100644 src/domain/community/virtualContributor/layout/VCPageLayout.tsx create mode 100644 src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx create mode 100644 src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx create mode 100644 src/domain/community/virtualContributor/views/VCProfileView.tsx diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index e0dd544ae0..4bad514551 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -15029,6 +15029,86 @@ export function refetchUserOrganizationIdsQuery(variables: SchemaTypes.UserOrgan return { query: UserOrganizationIdsDocument, variables: variables }; } +export const VirtualContributorDocument = gql` + query VirtualContributor($id: UUID_NAMEID!) { + virtualContributor(ID: $id) { + id + nameID + virtualPersona { + id + nameID + prompt + profile { + id + displayName + description + } + } + profile { + id + displayName + description + avatar: visual(type: AVATAR) { + ...VisualFull + } + } + } + } + ${VisualFullFragmentDoc} +`; + +/** + * __useVirtualContributorQuery__ + * + * To run a query within a React component, call `useVirtualContributorQuery` and pass it any options that fit your needs. + * When your component renders, `useVirtualContributorQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useVirtualContributorQuery({ + * variables: { + * id: // value for 'id' + * }, + * }); + */ +export function useVirtualContributorQuery( + baseOptions: Apollo.QueryHookOptions< + SchemaTypes.VirtualContributorQuery, + SchemaTypes.VirtualContributorQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + VirtualContributorDocument, + options + ); +} + +export function useVirtualContributorLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + SchemaTypes.VirtualContributorQuery, + SchemaTypes.VirtualContributorQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + VirtualContributorDocument, + options + ); +} + +export type VirtualContributorQueryHookResult = ReturnType; +export type VirtualContributorLazyQueryHookResult = ReturnType; +export type VirtualContributorQueryResult = Apollo.QueryResult< + SchemaTypes.VirtualContributorQuery, + SchemaTypes.VirtualContributorQueryVariables +>; +export function refetchVirtualContributorQuery(variables: SchemaTypes.VirtualContributorQueryVariables) { + return { query: VirtualContributorDocument, variables: variables }; +} + export const InnovationHubAvailableSpacesDocument = gql` query InnovationHubAvailableSpaces { spaces(filter: { visibilities: [ACTIVE, DEMO] }) { diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index bf07d8a13a..8f0ff01052 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -16780,6 +16780,47 @@ export type UserOrganizationIdsQuery = { }; }; +export type VirtualContributorQueryVariables = Exact<{ + id: Scalars['UUID_NAMEID']; +}>; + +export type VirtualContributorQuery = { + __typename?: 'Query'; + virtualContributor: { + __typename?: 'VirtualContributor'; + id: string; + nameID: string; + virtualPersona: { + __typename?: 'VirtualPersona'; + id: string; + nameID: string; + prompt: string; + profile: { __typename?: 'Profile'; id: string; displayName: string; description?: string | undefined }; + }; + profile: { + __typename?: 'Profile'; + id: string; + displayName: string; + description?: string | undefined; + avatar?: + | { + __typename?: 'Visual'; + id: string; + uri: string; + name: string; + allowedTypes: Array; + aspectRatio: number; + maxHeight: number; + maxWidth: number; + minHeight: number; + minWidth: number; + alternativeText?: string | undefined; + } + | undefined; + }; + }; +}; + export type ContextDetailsFragment = { __typename?: 'Context'; id: string; diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql new file mode 100644 index 0000000000..18e0501560 --- /dev/null +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -0,0 +1,24 @@ +query VirtualContributor ($id: UUID_NAMEID!) { + virtualContributor (ID: $id) { + id + nameID + virtualPersona { + id + nameID + prompt + profile { + id + displayName + description + } + } + profile { + id + displayName + description + avatar: visual(type: AVATAR) { + ...VisualFull + } + } + } +} diff --git a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx new file mode 100644 index 0000000000..bf363c8e14 --- /dev/null +++ b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { useVirtualContributorQuery } from '../../../../core/apollo/generated/apollo-hooks'; +import { useUrlParams } from '../../../../core/routing/useUrlParams'; +import ProfilePageBanner from '../../../common/profile/ProfilePageBanner'; + +const VCPageBanner = () => { + const { vcNameId = '' } = useUrlParams(); + + const { data, loading } = useVirtualContributorQuery({ + variables: { + id: vcNameId, + }, + }); + + const profile = data?.virtualContributor.profile; + + const userId = data?.virtualContributor.id; + + return ; +}; + +export default VCPageBanner; diff --git a/src/domain/community/virtualContributor/layout/VCPageLayout.tsx b/src/domain/community/virtualContributor/layout/VCPageLayout.tsx new file mode 100644 index 0000000000..cd4a332c7b --- /dev/null +++ b/src/domain/community/virtualContributor/layout/VCPageLayout.tsx @@ -0,0 +1,49 @@ +import React, { PropsWithChildren } from 'react'; +import TopLevelPageBreadcrumbs from '../../../../main/topLevelPages/topLevelPageBreadcrumbs/TopLevelPageBreadcrumbs'; +import { AssignmentIndOutlined } from '@mui/icons-material'; +import { useUrlParams } from '../../../../core/routing/useUrlParams'; +import { buildVCProfileUrl } from '../../../../main/routing/urlBuilders'; +import TopLevelLayout from '../../../../main/ui/layout/TopLevelLayout'; +import BreadcrumbsItem from '../../../../core/ui/navigation/BreadcrumbsItem'; +import GroupOutlinedIcon from '@mui/icons-material/GroupOutlined'; +import { useTranslation } from 'react-i18next'; +import VCPageBanner from './VCPageBanner'; +import { useVirtualContributorQuery } from '../../../../core/apollo/generated/apollo-hooks'; + +interface VCPageLayoutProps {} + +const VCPageLayout = ({ ...props }: PropsWithChildren) => { + const { vcNameId = '' } = useUrlParams(); + + const { data, loading } = useVirtualContributorQuery({ + variables: { + id: vcNameId, + }, + }); + + const { t } = useTranslation(); + + return ( + + + {t('pages.contributors.shortName')} + + + {data?.virtualContributor.profile.displayName} + + + } + header={} + {...props} + /> + ); +}; + +export default VCPageLayout; diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx new file mode 100644 index 0000000000..04dfbf4fe2 --- /dev/null +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import Loading from '../../../../core/ui/loading/Loading'; +import { useUrlParams } from '../../../../core/routing/useUrlParams'; +import { Error404 } from '../../../../core/pages/Errors/Error404'; +import VCPageLayout from '../layout/VCPageLayout'; +import VCProfilePageView from './VCProfilePageView'; +import { useVirtualContributorQuery } from '../../../../core/apollo/generated/apollo-hooks'; + +export const VCProfilePage = () => { + const { vcNameId = '' } = useUrlParams(); + + const { data, loading, error } = useVirtualContributorQuery({ + variables: { + id: vcNameId, + }, + }); + + if (loading) return ; + + if (error) { + return ( + + + + ); + } + + return ( + + + + ); +}; + +export default VCProfilePage; diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx new file mode 100644 index 0000000000..21bfa780c3 --- /dev/null +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx @@ -0,0 +1,72 @@ +import React, { FC, PropsWithChildren } from 'react'; +import { useTranslation } from 'react-i18next'; +import AssociatedOrganizationsLazilyFetched from '../../contributor/organization/AssociatedOrganizations/AssociatedOrganizationsLazilyFetched'; +import PageContent from '../../../../core/ui/content/PageContent'; +import PageContentColumn from '../../../../core/ui/content/PageContentColumn'; +import { VirtualContributorQuery } from '../../../../core/apollo/generated/graphql-schema'; +import VCProfileView from '../views/VCProfileView'; +import { BlockTitle } from '../../../../core/ui/typography'; +import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; +import WrapperMarkdown from '../../../../core/ui/markdown/WrapperMarkdown'; + +interface Props { + virtualContributor: VirtualContributorQuery['virtualContributor'] | undefined; +} + +export const VCProfilePageView: FC> = ({ virtualContributor }) => { + const { t } = useTranslation(); + + return ( + + + + + + + + + Knowledge + + Answers Alkemio Help gives are based on the body of knowledge that is specified in the following Space: + + + + + + Personality + + For its tone of voice and interaction style, Alkemio Help uses the following personality: + + + + + + Context + + Alkemio Help uses the following information from the Space it is invited to so it can provide you with + meaningful answers: Space about page: Name, Tagline, location, etc. Context information Statistics + + + + + + Privacy + + For Alkemio, safeguarding your data is of utmost importance. We are committed to maintaining the security + and privacy of your information. When interacting with a Virtual Contributor, only the data explicitly + specified on the left (Context) is used to generate meaningful answers. Importantly, your (Space) data is + not utilized for training the Virtual Contributor.  Additionally, please note that questions and answers + exchanged with the Virtual Contributor may be visible to the Alkemio team. + + + + + + ); +}; + +export default VCProfilePageView; diff --git a/src/domain/community/virtualContributor/views/VCProfileView.tsx b/src/domain/community/virtualContributor/views/VCProfileView.tsx new file mode 100644 index 0000000000..b1bd3ec289 --- /dev/null +++ b/src/domain/community/virtualContributor/views/VCProfileView.tsx @@ -0,0 +1,25 @@ +import { Grid } from '@mui/material'; +import React, { FC } from 'react'; +import { useTranslation } from 'react-i18next'; +import { VirtualContributorQuery } from '../../../../core/apollo/generated/graphql-schema'; +import ProfileDetail from '../../profile/ProfileDetail/ProfileDetail'; +import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; + +interface Props { + virtualContributor: VirtualContributorQuery['virtualContributor'] | undefined; +} + +export const VCProfileView: FC = ({ virtualContributor }) => { + const { t } = useTranslation(); + const bio = virtualContributor?.profile?.description; + + return ( + + + + + + ); +}; + +export default VCProfileView; diff --git a/src/main/routing/TopLevelRoutes.tsx b/src/main/routing/TopLevelRoutes.tsx index 8c88043f90..e97a422e28 100644 --- a/src/main/routing/TopLevelRoutes.tsx +++ b/src/main/routing/TopLevelRoutes.tsx @@ -30,6 +30,7 @@ import NonIdentity from '../../domain/platform/routes/NonIdentity'; import useRedirectToIdentityDomain from '../../core/auth/authentication/routing/useRedirectToIdentityDomain'; import { EntityPageLayoutHolder, NotFoundPageLayout, RenderPoint } from '../../domain/journey/common/EntityPageLayout'; import RedirectToWelcomeSite from '../../domain/platform/routes/RedirectToWelcomeSite'; +import VCProfilePage from '../../domain/community/virtualContributor/vcProfilePage/VCProfilePage'; export const TopLevelRoutes: FC = () => { useRedirectToIdentityDomain(); @@ -96,6 +97,18 @@ export const TopLevelRoutes: FC = () => { } /> + + + + + + + + } + /> `/admin export const buildUserProfileUrl = (userNameId: string) => `/user/${userNameId}`; +export const buildVCProfileUrl = (vcNameId: string) => `/vc/${vcNameId}`; + export const buildUserProfileSettingsUrl = (userNameId: string) => `${buildUserProfileUrl(userNameId)}/settings/profile`; diff --git a/src/main/routing/urlParams.ts b/src/main/routing/urlParams.ts index 068f16adf6..d33490eb30 100644 --- a/src/main/routing/urlParams.ts +++ b/src/main/routing/urlParams.ts @@ -10,6 +10,7 @@ export default interface UrlParams extends Record { projectNameId?: string; applicationId?: string; userNameId?: string; + vcNameId?: string; role?: AuthorizationCredential; discussionNameId?: string; calloutNameId?: string; From 5e177cfe25beb9dc20c902262f0520784abda2e9 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Mon, 13 May 2024 12:36:52 +0300 Subject: [PATCH 02/30] client-5862 Virtual contributor label on profile page --- .../common/profile/ProfilePageBanner.tsx | 4 ++++ .../VirtualContributorLabel.tsx | 21 ++++++++++++------- .../VirtualContributorsIcons.tsx | 17 +++++++++++++++ .../layout/VCPageBanner.tsx | 10 ++++++++- 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 src/domain/community/virtualContributor/VirtualContributorsIcons.tsx diff --git a/src/domain/common/profile/ProfilePageBanner.tsx b/src/domain/common/profile/ProfilePageBanner.tsx index abf5fe1ad3..dd3c699299 100644 --- a/src/domain/common/profile/ProfilePageBanner.tsx +++ b/src/domain/common/profile/ProfilePageBanner.tsx @@ -13,6 +13,7 @@ import { Visual } from '../visual/Visual'; import { Location } from '../../../core/ui/location/getLocationString'; import { useTranslation } from 'react-i18next'; import PageBannerWatermark from '../../../main/ui/platformNavigation/PageBannerWatermark'; +import VirtualContributorLabel from '../../community/virtualContributor/VirtualContributorLabel'; const banner: Visual = { uri: '/alkemio-banner/global-banner.jpg', @@ -37,6 +38,7 @@ export interface ProfilePageBannerProps { settingsUri?: string; onSendMessage?: (messageText: string) => Promise; loading?: boolean; + isVirtualContributor?: boolean; } const ProfilePageBanner = ({ @@ -45,6 +47,7 @@ const ProfilePageBanner = ({ settingsUri, onSendMessage, loading = false, + isVirtualContributor = false, }: ProfilePageBannerProps) => { const isMobile = useMediaQuery(theme => theme.breakpoints.down('lg')); @@ -96,6 +99,7 @@ const ProfilePageBanner = ({ {profile?.displayName} {profile?.location && } + {isVirtualContributor && } {onSendMessage && ( diff --git a/src/domain/community/virtualContributor/VirtualContributorLabel.tsx b/src/domain/community/virtualContributor/VirtualContributorLabel.tsx index 6049ab67c5..d1dddead8f 100644 --- a/src/domain/community/virtualContributor/VirtualContributorLabel.tsx +++ b/src/domain/community/virtualContributor/VirtualContributorLabel.tsx @@ -1,18 +1,25 @@ import { CaptionSmall } from '../../../core/ui/typography'; import { useTranslation } from 'react-i18next'; -import { ReactComponent as VirtualContributorIcon } from './VirtualContributor.svg'; -import { SvgIcon } from '@mui/material'; +import { Chip, SvgIcon } from '@mui/material'; import { gutters } from '../../../core/ui/grid/utils'; +import VCIcon from './VirtualContributorsIcons'; -const VirtualContributorLabel = () => { +const VirtualContributorLabel = ({ chip = false }) => { const { t } = useTranslation(); + if (chip) { + return ( + } + /> + ); + } + return ( - + {t('community.virtualContributor')} ); diff --git a/src/domain/community/virtualContributor/VirtualContributorsIcons.tsx b/src/domain/community/virtualContributor/VirtualContributorsIcons.tsx new file mode 100644 index 0000000000..804dc34512 --- /dev/null +++ b/src/domain/community/virtualContributor/VirtualContributorsIcons.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +const VCIcon = ({ fill = '#1C1B1F', ...props }) => ( + + + + + + + + +); + +export default VCIcon; diff --git a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx index bf363c8e14..9808ab73d3 100644 --- a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx +++ b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx @@ -16,7 +16,15 @@ const VCPageBanner = () => { const userId = data?.virtualContributor.id; - return ; + return ( + + ); }; export default VCPageBanner; From a9f9e81f0c3582b7fd3423b6fcce6f9110b173f9 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Mon, 13 May 2024 19:36:16 +0300 Subject: [PATCH 03/30] client-5862 Virtual contributor profile - tags, tagline, org --- src/core/apollo/generated/apollo-helpers.ts | 42 +++++++++++++- src/core/apollo/generated/apollo-hooks.ts | 8 ++- src/core/apollo/generated/graphql-schema.ts | 38 ++++++++++++- .../common/profile/ProfilePageBanner.tsx | 2 +- .../VirtualContributor.graphql | 8 ++- .../vcProfilePage/HostOrganization.tsx | 55 +++++++++++++++++++ .../vcProfilePage/VCProfilePageView.tsx | 11 +--- .../NewVirtualContributorForm.tsx | 34 +++++++++++- 8 files changed, 177 insertions(+), 21 deletions(-) create mode 100644 src/domain/community/virtualContributor/vcProfilePage/HostOrganization.tsx diff --git a/src/core/apollo/generated/apollo-helpers.ts b/src/core/apollo/generated/apollo-helpers.ts index 590f124501..d97122a67d 100644 --- a/src/core/apollo/generated/apollo-helpers.ts +++ b/src/core/apollo/generated/apollo-helpers.ts @@ -1285,11 +1285,19 @@ export type LibraryFieldPolicy = { innovationPacks?: FieldPolicy | FieldReadFunction; storageAggregator?: FieldPolicy | FieldReadFunction; }; -export type LicenseKeySpecifier = ('authorization' | 'featureFlags' | 'id' | 'visibility' | LicenseKeySpecifier)[]; +export type LicenseKeySpecifier = ( + | 'authorization' + | 'featureFlags' + | 'id' + | 'privileges' + | 'visibility' + | LicenseKeySpecifier +)[]; export type LicenseFieldPolicy = { authorization?: FieldPolicy | FieldReadFunction; featureFlags?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; + privileges?: FieldPolicy | FieldReadFunction; visibility?: FieldPolicy | FieldReadFunction; }; export type LicenseFeatureFlagKeySpecifier = ('enabled' | 'name' | LicenseFeatureFlagKeySpecifier)[]; @@ -1297,6 +1305,23 @@ export type LicenseFeatureFlagFieldPolicy = { enabled?: FieldPolicy | FieldReadFunction; name?: FieldPolicy | FieldReadFunction; }; +export type LicensePolicyKeySpecifier = ('authorization' | 'featureFlagRules' | 'id' | LicensePolicyKeySpecifier)[]; +export type LicensePolicyFieldPolicy = { + authorization?: FieldPolicy | FieldReadFunction; + featureFlagRules?: FieldPolicy | FieldReadFunction; + id?: FieldPolicy | FieldReadFunction; +}; +export type LicensePolicyRuleFeatureFlagKeySpecifier = ( + | 'featureFlagName' + | 'grantedPrivileges' + | 'name' + | LicensePolicyRuleFeatureFlagKeySpecifier +)[]; +export type LicensePolicyRuleFeatureFlagFieldPolicy = { + featureFlagName?: FieldPolicy | FieldReadFunction; + grantedPrivileges?: FieldPolicy | FieldReadFunction; + name?: FieldPolicy | FieldReadFunction; +}; export type LifecycleKeySpecifier = ( | 'id' | 'machineDef' @@ -1358,6 +1383,7 @@ export type LookupQueryResultsKeySpecifier = ( | 'post' | 'profile' | 'room' + | 'space' | 'storageAggregator' | 'whiteboard' | 'whiteboardTemplate' @@ -1381,6 +1407,7 @@ export type LookupQueryResultsFieldPolicy = { post?: FieldPolicy | FieldReadFunction; profile?: FieldPolicy | FieldReadFunction; room?: FieldPolicy | FieldReadFunction; + space?: FieldPolicy | FieldReadFunction; storageAggregator?: FieldPolicy | FieldReadFunction; whiteboard?: FieldPolicy | FieldReadFunction; whiteboardTemplate?: FieldPolicy | FieldReadFunction; @@ -1865,6 +1892,7 @@ export type PlatformKeySpecifier = ( | 'innovationHubs' | 'latestReleaseDiscussion' | 'library' + | 'licensePolicy' | 'metadata' | 'storageAggregator' | PlatformKeySpecifier @@ -1878,6 +1906,7 @@ export type PlatformFieldPolicy = { innovationHubs?: FieldPolicy | FieldReadFunction; latestReleaseDiscussion?: FieldPolicy | FieldReadFunction; library?: FieldPolicy | FieldReadFunction; + licensePolicy?: FieldPolicy | FieldReadFunction; metadata?: FieldPolicy | FieldReadFunction; storageAggregator?: FieldPolicy | FieldReadFunction; }; @@ -3335,6 +3364,17 @@ export type StrictTypedTypePolicies = { keyFields?: false | LicenseFeatureFlagKeySpecifier | (() => undefined | LicenseFeatureFlagKeySpecifier); fields?: LicenseFeatureFlagFieldPolicy; }; + LicensePolicy?: Omit & { + keyFields?: false | LicensePolicyKeySpecifier | (() => undefined | LicensePolicyKeySpecifier); + fields?: LicensePolicyFieldPolicy; + }; + LicensePolicyRuleFeatureFlag?: Omit & { + keyFields?: + | false + | LicensePolicyRuleFeatureFlagKeySpecifier + | (() => undefined | LicensePolicyRuleFeatureFlagKeySpecifier); + fields?: LicensePolicyRuleFeatureFlagFieldPolicy; + }; Lifecycle?: Omit & { keyFields?: false | LifecycleKeySpecifier | (() => undefined | LifecycleKeySpecifier); fields?: LifecycleFieldPolicy; diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 4bad514551..819d128d52 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -15036,18 +15036,20 @@ export const VirtualContributorDocument = gql` nameID virtualPersona { id - nameID prompt profile { - id displayName - description } } profile { id displayName description + tagline + tagsets { + id + tags + } avatar: visual(type: AVATAR) { ...VisualFull } diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 8f0ff01052..d212d94882 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -2229,6 +2229,8 @@ export type License = { featureFlags: Array; /** The ID of the entity */ id: Scalars['UUID']; + /** The privileges granted based on this License. */ + privileges?: Maybe>; /** Visibility of the Space. */ visibility: SpaceVisibility; }; @@ -2247,6 +2249,29 @@ export enum LicenseFeatureFlagName { WhiteboardMultiUser = 'WHITEBOARD_MULTI_USER', } +export type LicensePolicy = { + __typename?: 'LicensePolicy'; + /** The authorization rules for the entity */ + authorization?: Maybe; + /** The set of credential rules that are contained by this License Policy. */ + featureFlagRules?: Maybe>; + /** The ID of the entity */ + id: Scalars['UUID']; +}; + +export type LicensePolicyRuleFeatureFlag = { + __typename?: 'LicensePolicyRuleFeatureFlag'; + featureFlagName: LicenseFeatureFlagName; + grantedPrivileges: Array; + name?: Maybe; +}; + +export enum LicensePrivilege { + CalloutSaveAsTemplate = 'CALLOUT_SAVE_AS_TEMPLATE', + VirtualContributorAccess = 'VIRTUAL_CONTRIBUTOR_ACCESS', + WhiteboardMultiUser = 'WHITEBOARD_MULTI_USER', +} + export type Lifecycle = { __typename?: 'Lifecycle'; /** The ID of the entity */ @@ -2323,6 +2348,8 @@ export type LookupQueryResults = { profile?: Maybe; /** Lookup the specified Room */ room?: Maybe; + /** Lookup the specified Space */ + space?: Maybe; /** Lookup the specified StorageAggregator */ storageAggregator?: Maybe; /** Lookup the specified Whiteboard */ @@ -2400,6 +2427,10 @@ export type LookupQueryResultsRoomArgs = { ID: Scalars['UUID']; }; +export type LookupQueryResultsSpaceArgs = { + ID: Scalars['UUID']; +}; + export type LookupQueryResultsStorageAggregatorArgs = { ID: Scalars['UUID']; }; @@ -3593,6 +3624,8 @@ export type Platform = { latestReleaseDiscussion?: Maybe; /** The Innovation Library for the platform */ library: Library; + /** The LicensePolicy in use by the platform. */ + licensePolicy: LicensePolicy; /** Alkemio Services Metadata. */ metadata: Metadata; /** The StorageAggregator with documents in use by Users + Organizations on the Platform. */ @@ -16793,15 +16826,16 @@ export type VirtualContributorQuery = { virtualPersona: { __typename?: 'VirtualPersona'; id: string; - nameID: string; prompt: string; - profile: { __typename?: 'Profile'; id: string; displayName: string; description?: string | undefined }; + profile: { __typename?: 'Profile'; displayName: string }; }; profile: { __typename?: 'Profile'; id: string; displayName: string; description?: string | undefined; + tagline: string; + tagsets?: Array<{ __typename?: 'Tagset'; id: string; tags: Array }> | undefined; avatar?: | { __typename?: 'Visual'; diff --git a/src/domain/common/profile/ProfilePageBanner.tsx b/src/domain/common/profile/ProfilePageBanner.tsx index dd3c699299..7b88598d1f 100644 --- a/src/domain/common/profile/ProfilePageBanner.tsx +++ b/src/domain/common/profile/ProfilePageBanner.tsx @@ -99,7 +99,6 @@ const ProfilePageBanner = ({ {profile?.displayName} {profile?.location && } - {isVirtualContributor && } {onSendMessage && ( @@ -112,6 +111,7 @@ const ProfilePageBanner = ({ )} + {isVirtualContributor && } } subtitle={profile?.tagline} diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql index 18e0501560..bb652ed2d3 100644 --- a/src/domain/community/virtualContributor/VirtualContributor.graphql +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -4,18 +4,20 @@ query VirtualContributor ($id: UUID_NAMEID!) { nameID virtualPersona { id - nameID prompt profile { - id displayName - description } } profile { id displayName description + tagline + tagsets { + id + tags + } avatar: visual(type: AVATAR) { ...VisualFull } diff --git a/src/domain/community/virtualContributor/vcProfilePage/HostOrganization.tsx b/src/domain/community/virtualContributor/vcProfilePage/HostOrganization.tsx new file mode 100644 index 0000000000..e28582b61f --- /dev/null +++ b/src/domain/community/virtualContributor/vcProfilePage/HostOrganization.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; +import PageContentBlockHeader from '../../../../core/ui/content/PageContentBlockHeader'; +import BadgeCardView from '../../../../core/ui/list/BadgeCardView'; +import Avatar from '../../../../core/ui/avatar/Avatar'; +import { BlockSectionTitle } from '../../../../core/ui/typography'; +import getLocationString from '../../../../core/ui/location/getLocationString'; +import { useTranslation } from 'react-i18next'; +import { LocationIcon } from '../../../timeline/calendar/icons/LocationIcon'; +import { theme } from '../../../../core/ui/themes/default/Theme'; + +// TODO: Replace with real data +const profile = { + avatar: { + uri: 'https://alkem.io/api/private/rest/storage/document/e58662b2-50f1-4c33-a8b4-40d601000afd', + }, + displayName: 'Alkemio Foundation', + location: { + city: 'Hague', + country: 'NL', + }, +}; + +const HostOrganization = () => { + const { t } = useTranslation(); + + return ( + <> + + + + {profile.displayName[0]} + + } + > + {profile.displayName} + {profile.location && ( + + + {getLocationString(profile.location)} + + )} + + + + ); +}; + +export default HostOrganization; diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx index 21bfa780c3..d861ed8728 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx @@ -1,6 +1,4 @@ import React, { FC, PropsWithChildren } from 'react'; -import { useTranslation } from 'react-i18next'; -import AssociatedOrganizationsLazilyFetched from '../../contributor/organization/AssociatedOrganizations/AssociatedOrganizationsLazilyFetched'; import PageContent from '../../../../core/ui/content/PageContent'; import PageContentColumn from '../../../../core/ui/content/PageContentColumn'; import { VirtualContributorQuery } from '../../../../core/apollo/generated/graphql-schema'; @@ -8,23 +6,18 @@ import VCProfileView from '../views/VCProfileView'; import { BlockTitle } from '../../../../core/ui/typography'; import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; import WrapperMarkdown from '../../../../core/ui/markdown/WrapperMarkdown'; +import HostOrganization from './HostOrganization'; interface Props { virtualContributor: VirtualContributorQuery['virtualContributor'] | undefined; } export const VCProfilePageView: FC> = ({ virtualContributor }) => { - const { t } = useTranslation(); - return ( - + diff --git a/src/domain/platform/admin/virtual-contributors/NewVirtualContributorForm.tsx b/src/domain/platform/admin/virtual-contributors/NewVirtualContributorForm.tsx index 9336a98fbb..c7996f55ca 100644 --- a/src/domain/platform/admin/virtual-contributors/NewVirtualContributorForm.tsx +++ b/src/domain/platform/admin/virtual-contributors/NewVirtualContributorForm.tsx @@ -20,10 +20,16 @@ import FormikSelect from '../../../../core/ui/forms/FormikSelect'; import { useBackToStaticPath } from '../../../../core/routing/useBackToPath'; import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; import PageContentBlockHeader from '../../../../core/ui/content/PageContentBlockHeader'; +import { TagsetSegment } from '../components/Common/TagsetSegment'; +import { Tagset, TagsetType } from '../../../../core/apollo/generated/graphql-schema'; +import { DEFAULT_TAGSET } from '../../../common/tags/tagset.constants'; +import { SMALL_TEXT_LENGTH } from '../../../../core/ui/forms/field-length.constants'; interface NewVirtualContributorFormValues { displayName: string; virtualPersonaID: string; + tagline: string; + tagsets: Tagset[]; } interface NewVirtualContributorFormProps { @@ -34,7 +40,7 @@ const NewVirtualContributorForm = ({ parentPagePath }: NewVirtualContributorForm const { t } = useTranslation(); const navigateBack = useBackToStaticPath(parentPagePath); const notify = useNotification(); - const initialValues = { displayName: '', virtualPersonaID: '' }; + const initialValues = { displayName: '', virtualPersonaID: '', tagline: '', tagsets: [] }; const { data: virtualPersonas } = useVirtualContributorAvailablePersonasQuery(); const [createVirtualContributor, { loading }] = useCreateVirtualContributorMutation({ refetchQueries: [refetchAdminVirtualContributorsQuery()], @@ -45,7 +51,7 @@ const NewVirtualContributorForm = ({ parentPagePath }: NewVirtualContributorForm }; const [handleSubmit] = useLoadingState(async (values: NewVirtualContributorFormValues) => { - const { displayName, virtualPersonaID } = values; + const { displayName, virtualPersonaID, tagline, tagsets } = values; await createVirtualContributor({ variables: { @@ -54,6 +60,13 @@ const NewVirtualContributorForm = ({ parentPagePath }: NewVirtualContributorForm nameID: `V-P-${uuidv4()}`.slice(0, 25).toLocaleLowerCase(), profileData: { displayName, + tagline, + tagsets: [ + { + ...tagsets[0], + name: DEFAULT_TAGSET, + }, + ], }, }, }, @@ -72,6 +85,16 @@ const NewVirtualContributorForm = ({ parentPagePath }: NewVirtualContributorForm [virtualPersonas] ); + const tagsets = [ + { + id: '', + name: DEFAULT_TAGSET, + tags: [], + allowedValues: [], + type: TagsetType.Freeform, + }, + ] as Tagset[]; + return ( @@ -81,6 +104,13 @@ const NewVirtualContributorForm = ({ parentPagePath }: NewVirtualContributorForm + + + + {t('buttons.save')} + + + + + ); + }} + + + ); + } +}; + +export default VirtualContributorForm; From f5c845ed447275b2fda6c65b982e58c46d54a13f Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 11:05:15 +0300 Subject: [PATCH 13/30] VC Edti - working form with basic info updates --- src/core/apollo/generated/apollo-hooks.ts | 4 +- src/core/apollo/generated/graphql-schema.ts | 11 +++- .../VirtualContributor.graphql | 3 +- .../vcSettingsPage/VCSettingsPage.tsx | 5 +- .../vcSettingsPage/VirtualContributorForm.tsx | 55 ++++++++++--------- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 19a7f5c281..bf86538f08 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -14117,8 +14117,7 @@ export const VirtualContributorDocument = gql` description tagline tagsets { - id - tags + ...TagsetDetails } url avatar: visual(type: AVATAR) { @@ -14127,6 +14126,7 @@ export const VirtualContributorDocument = gql` } } } + ${TagsetDetailsFragmentDoc} ${VisualFullFragmentDoc} `; diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 6041279da0..f9db770f74 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -17331,7 +17331,16 @@ export type VirtualContributorQuery = { description?: string | undefined; tagline: string; url: string; - tagsets?: Array<{ __typename?: 'Tagset'; id: string; tags: Array }> | undefined; + tagsets?: + | Array<{ + __typename?: 'Tagset'; + id: string; + name: string; + tags: Array; + allowedValues: Array; + type: TagsetType; + }> + | undefined; avatar?: | { __typename?: 'Visual'; diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql index f7fa75b79a..8d226e1ea8 100644 --- a/src/domain/community/virtualContributor/VirtualContributor.graphql +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -8,8 +8,7 @@ query VirtualContributor ($id: UUID_NAMEID!) { description tagline tagsets { - id - tags + ...TagsetDetails } url avatar: visual(type: AVATAR) { diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index 55c9ffd7ae..528131543b 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -24,10 +24,7 @@ export const VCSettingsPage = () => { variables: { virtualContributorData: { ID: virtualContributor.ID, - profileData: { - displayName: virtualContributor.name, - description: virtualContributor.description, - }, + profileData: virtualContributor.profileData, }, }, }); diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index 51c6921299..58f3c40cd0 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -14,6 +14,8 @@ import Gutters from '../../../../core/ui/grid/Gutters'; import useLoadingState from '../../../shared/utils/useLoadingState'; import { Actions } from '../../../../core/ui/actions/Actions'; import { LoadingButton } from '@mui/lab'; +import { TagsetSegment } from '../../../platform/admin/components/Common/TagsetSegment'; +import { UpdateTagset } from '../../../common/profile/Profile'; interface VirtualContributorProps { id: string; @@ -23,12 +25,7 @@ interface VirtualContributorProps { displayName: string; description?: string; tagline: string; - tagsets?: - | { - id: string; - tags: string[]; - }[] - | undefined; + tagsets?: Tagset[] | undefined; url: string; avatar?: Visual | undefined; }; @@ -61,7 +58,7 @@ export const VirtualContributorForm: FC = ({ const { nameID, - profile: { displayName, description, tagline }, + profile: { displayName, description, tagline, tagsets }, } = currentVirtualContributor; const initialValues: VirtualContributorFromProps = { @@ -70,6 +67,7 @@ export const VirtualContributorForm: FC = ({ description: description ?? '', tagline: tagline, avatar: avatar, + tagsets: tagsets, }; const validationSchema = yup.object().shape({ @@ -78,27 +76,33 @@ export const VirtualContributorForm: FC = ({ description: profileSegmentSchema.fields?.description || yup.string(), }); + const getUpdatedTagsets = (updatedTagsets: Tagset[]) => { + const result: UpdateTagset[] = []; + updatedTagsets.forEach(updatedTagset => { + const originalTagset = tagsets?.find(value => value.name === updatedTagset.name); + if (originalTagset) result.push({ ...originalTagset, tags: updatedTagset.tags }); + }); + + return result; + }; + const [handleSubmit, loading] = useLoadingState(async (values: VirtualContributorFromProps) => { - const { tagsets, description, tagline, ...otherData } = values; + const { tagsets, description, tagline, name, ...otherData } = values; + const updatedTagsets = getUpdatedTagsets(tagsets || []); const virtualContributor = { ID: currentVirtualContributor.id, - description, + profileData: { + displayName: name, + description, + tagline, + tagsets: updatedTagsets.map(r => ({ + ID: r.id, + id: undefined, + tags: r.tags ?? [], + })), + }, ...otherData, - // bodyOfKnowledgeType: BodyOfKnowledgeType.Space, - // profile: { - // displayName: otherData.name, - // description, - // tagline, - // tagsets: updatedTagsets.map(r => ({ - // ...r, - // ID: r.id, - // id: '', - // allowedValues: [], - // type: TagsetType.Freeform, - // tags: r.tags ?? [], - // })), - // }, }; await onSave?.(virtualContributor); @@ -143,15 +147,16 @@ export const VirtualContributorForm: FC = ({ enableReinitialize onSubmit={handleSubmit} > - {({ values: { avatar }, handleSubmit }) => { + {({ values: { avatar, tagsets }, handleSubmit }) => { return (
<> - + + {tagsets && } From 83530055f6be9e9fe080c2207714f0d95d7413d8 Mon Sep 17 00:00:00 2001 From: Valentin Yanakiev Date: Wed, 29 May 2024 17:07:31 +0300 Subject: [PATCH 14/30] Revert "Removed prompt from the New Virtual Persona Form" This reverts commit 13533efd31b71757b4cfb030e7cbfcda0d1666ea. --- src/core/apollo/generated/apollo-helpers.ts | 23 +----- src/core/apollo/generated/apollo-hooks.ts | 2 +- src/core/apollo/generated/graphql-schema.ts | 82 +++++-------------- .../space/createSpace/CreateNewSpace.graphql | 2 +- .../virtual-contributors/NewPersonaForm.tsx | 34 ++++---- 5 files changed, 42 insertions(+), 101 deletions(-) diff --git a/src/core/apollo/generated/apollo-helpers.ts b/src/core/apollo/generated/apollo-helpers.ts index ad2d21d871..4226cb4ab5 100644 --- a/src/core/apollo/generated/apollo-helpers.ts +++ b/src/core/apollo/generated/apollo-helpers.ts @@ -13,7 +13,6 @@ export type AccountKeySpecifier = ( | 'library' | 'license' | 'spaceID' - | 'subscriptions' | AccountKeySpecifier )[]; export type AccountFieldPolicy = { @@ -25,12 +24,6 @@ export type AccountFieldPolicy = { library?: FieldPolicy | FieldReadFunction; license?: FieldPolicy | FieldReadFunction; spaceID?: FieldPolicy | FieldReadFunction; - subscriptions?: FieldPolicy | FieldReadFunction; -}; -export type AccountSubscriptionKeySpecifier = ('expires' | 'name' | AccountSubscriptionKeySpecifier)[]; -export type AccountSubscriptionFieldPolicy = { - expires?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; }; export type ActivityCreatedSubscriptionResultKeySpecifier = ( | 'activity' @@ -1352,7 +1345,6 @@ export type LicensePlanKeySpecifier = ( | 'enabled' | 'id' | 'isFree' - | 'licenseCredential' | 'name' | 'pricePerMonth' | 'requiresContactSupport' @@ -1365,7 +1357,6 @@ export type LicensePlanFieldPolicy = { enabled?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; isFree?: FieldPolicy | FieldReadFunction; - licenseCredential?: FieldPolicy | FieldReadFunction; name?: FieldPolicy | FieldReadFunction; pricePerMonth?: FieldPolicy | FieldReadFunction; requiresContactSupport?: FieldPolicy | FieldReadFunction; @@ -1390,17 +1381,9 @@ export type LicensePolicyRuleFeatureFlagFieldPolicy = { grantedPrivileges?: FieldPolicy | FieldReadFunction; name?: FieldPolicy | FieldReadFunction; }; -export type LicensingKeySpecifier = ( - | 'authorization' - | 'basePlan' - | 'id' - | 'plans' - | 'policy' - | LicensingKeySpecifier -)[]; +export type LicensingKeySpecifier = ('authorization' | 'id' | 'plans' | 'policy' | LicensingKeySpecifier)[]; export type LicensingFieldPolicy = { authorization?: FieldPolicy | FieldReadFunction; - basePlan?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; plans?: FieldPolicy | FieldReadFunction; policy?: FieldPolicy | FieldReadFunction; @@ -3009,10 +2992,6 @@ export type StrictTypedTypePolicies = { keyFields?: false | AccountKeySpecifier | (() => undefined | AccountKeySpecifier); fields?: AccountFieldPolicy; }; - AccountSubscription?: Omit & { - keyFields?: false | AccountSubscriptionKeySpecifier | (() => undefined | AccountSubscriptionKeySpecifier); - fields?: AccountSubscriptionFieldPolicy; - }; ActivityCreatedSubscriptionResult?: Omit & { keyFields?: | false diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 01986e642a..2ad4cadfc3 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -15853,7 +15853,7 @@ export function refetchLegacySubspaceDashboardPageQuery( export const CreateNewSpaceDocument = gql` mutation CreateNewSpace($hostId: UUID_NAMEID!, $spaceData: CreateSpaceInput!, $planId: UUID) { - createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, licensePlanID: $planId }) { + createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, planID: $planId }) { id spaceID } diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 01fbe3c78f..edf9ae7129 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -52,8 +52,6 @@ export type Account = { license: License; /** The ID for the root space for the Account . */ spaceID: Scalars['String']; - /** The subscriptions active for this Account. */ - subscriptions: Array; }; export type AccountAuthorizationResetInput = { @@ -61,14 +59,6 @@ export type AccountAuthorizationResetInput = { accountID: Scalars['UUID_NAMEID']; }; -export type AccountSubscription = { - __typename?: 'AccountSubscription'; - /** The expiry date of this subscription, null if it does never expire. */ - expires?: Maybe; - /** The name of the Subscription. */ - name: Scalars['String']; -}; - export type ActivityCreatedSubscriptionInput = { /** The collaboration on which to subscribe for new activity */ collaborationID: Scalars['UUID']; @@ -1417,8 +1407,8 @@ export type ConvertSubsubspaceToSubspaceInput = { export type CreateAccountInput = { /** The host Organization or User for the account */ hostID: Scalars['UUID_NAMEID']; - /** The license plan selected for the account */ - licensePlanID?: InputMaybe; + /** The plan selected for the account */ + planID?: InputMaybe; /** The root Space to be created. */ spaceData: CreateSpaceInput; }; @@ -1748,6 +1738,7 @@ export type CreateVirtualPersonaInput = { /** A readable identifier, unique within the containing scope. */ nameID: Scalars['NameID']; profileData: CreateProfileInput; + prompt: Scalars['JSON']; }; export type CreateWhiteboardInput = { @@ -1777,7 +1768,7 @@ export type Credential = { /** The User issuing the credential */ issuer?: Maybe; resourceID: Scalars['String']; - type: CredentialType; + type: AuthorizationCredential; }; export type CredentialDefinition = { @@ -1804,31 +1795,6 @@ export type CredentialMetadataOutput = { uniqueType: Scalars['String']; }; -export enum CredentialType { - AccountHost = 'ACCOUNT_HOST', - BetaTester = 'BETA_TESTER', - GlobalAdmin = 'GLOBAL_ADMIN', - GlobalCommunityRead = 'GLOBAL_COMMUNITY_READ', - GlobalLicenseManager = 'GLOBAL_LICENSE_MANAGER', - GlobalRegistered = 'GLOBAL_REGISTERED', - GlobalSpacesReader = 'GLOBAL_SPACES_READER', - GlobalSupport = 'GLOBAL_SUPPORT', - InnovationPackProvider = 'INNOVATION_PACK_PROVIDER', - LicenseSpaceEnterprise = 'LICENSE_SPACE_ENTERPRISE', - LicenseSpaceFree = 'LICENSE_SPACE_FREE', - LicenseSpacePlus = 'LICENSE_SPACE_PLUS', - LicenseSpacePremium = 'LICENSE_SPACE_PREMIUM', - OrganizationAdmin = 'ORGANIZATION_ADMIN', - OrganizationAssociate = 'ORGANIZATION_ASSOCIATE', - OrganizationOwner = 'ORGANIZATION_OWNER', - SpaceAdmin = 'SPACE_ADMIN', - SpaceLead = 'SPACE_LEAD', - SpaceMember = 'SPACE_MEMBER', - SpaceSubspaceAdmin = 'SPACE_SUBSPACE_ADMIN', - UserGroupMember = 'USER_GROUP_MEMBER', - UserSelfManagement = 'USER_SELF_MANAGEMENT', -} - export type DeleteActorGroupInput = { ID: Scalars['UUID']; }; @@ -2333,13 +2299,6 @@ export type License = { visibility: SpaceVisibility; }; -export enum LicenseCredential { - LicenseSpaceEnterprise = 'LICENSE_SPACE_ENTERPRISE', - LicenseSpaceFree = 'LICENSE_SPACE_FREE', - LicenseSpacePlus = 'LICENSE_SPACE_PLUS', - LicenseSpacePremium = 'LICENSE_SPACE_PREMIUM', -} - export type LicenseFeatureFlag = { __typename?: 'LicenseFeatureFlag'; /** Is this feature flag enabled? */ @@ -2362,8 +2321,6 @@ export type LicensePlan = { id: Scalars['UUID']; /** Is this plan free? */ isFree: Scalars['Boolean']; - /** The credential to represent this plan */ - licenseCredential: LicenseCredential; /** The name of the License Plan */ name: Scalars['String']; /** The price per month of this plan. */ @@ -2405,8 +2362,6 @@ export type Licensing = { __typename?: 'Licensing'; /** The authorization rules for the entity */ authorization?: Maybe; - /** The base License Plan assigned to all Accounts in use on the platform. */ - basePlan: LicensePlan; /** The ID of the entity */ id: Scalars['UUID']; /** The License Plans in use on the platform. */ @@ -5523,6 +5478,7 @@ export type UpdateVirtualPersonaInput = { nameID?: InputMaybe; /** The Profile of this entity. */ profileData?: InputMaybe; + prompt: Scalars['JSON']; }; export type UpdateVisualInput = { @@ -5983,7 +5939,7 @@ export type UserAgentSsiFragment = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: CredentialType }> + | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: AuthorizationCredential }> | undefined; verifiedCredentials?: | Array<{ @@ -6016,7 +5972,7 @@ export type UserSsiQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: CredentialType }> + | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: AuthorizationCredential }> | undefined; verifiedCredentials?: | Array<{ @@ -14368,7 +14324,7 @@ export type CommunityPageMembersFragment = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> | undefined; }; profile: { @@ -15131,7 +15087,7 @@ export type ContributorsPageUsersQuery = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> | undefined; }; userProfile: { @@ -15211,7 +15167,7 @@ export type UserContributorPaginatedFragment = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> | undefined; }; userProfile: { @@ -15249,7 +15205,7 @@ export type UserContributorFragment = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> | undefined; }; userProfile: { @@ -16378,7 +16334,7 @@ export type UserAgentFragment = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: CredentialType }> + | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: AuthorizationCredential }> | undefined; }; }; @@ -16395,7 +16351,7 @@ export type UserDetailsFragment = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16508,7 +16464,7 @@ export type CreateUserMutation = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16565,7 +16521,7 @@ export type CreateUserNewRegistrationMutation = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16700,7 +16656,7 @@ export type UpdateUserMutation = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16771,7 +16727,7 @@ export type UserQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string; id: string }> + | Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string; id: string }> | undefined; }; profile: { @@ -16861,7 +16817,7 @@ export type UserProfileQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string; id: string }> + | Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string; id: string }> | undefined; }; profile: { @@ -16996,7 +16952,7 @@ export type UserProviderQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string; id: string }> + | Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string; id: string }> | undefined; }; profile: { diff --git a/src/domain/journey/space/createSpace/CreateNewSpace.graphql b/src/domain/journey/space/createSpace/CreateNewSpace.graphql index 27bc6ab035..8b0013c60f 100644 --- a/src/domain/journey/space/createSpace/CreateNewSpace.graphql +++ b/src/domain/journey/space/createSpace/CreateNewSpace.graphql @@ -1,5 +1,5 @@ mutation CreateNewSpace($hostId: UUID_NAMEID!, $spaceData: CreateSpaceInput!, $planId: UUID) { - createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, licensePlanID: $planId }) { + createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, planID: $planId }) { id spaceID } diff --git a/src/domain/platform/admin/virtual-contributors/NewPersonaForm.tsx b/src/domain/platform/admin/virtual-contributors/NewPersonaForm.tsx index 236b03d2ab..fbf56a492e 100644 --- a/src/domain/platform/admin/virtual-contributors/NewPersonaForm.tsx +++ b/src/domain/platform/admin/virtual-contributors/NewPersonaForm.tsx @@ -26,6 +26,7 @@ interface NewPersonaFormValues { displayName: string; nameId: string; description: string; + prompt: string; engine: VirtualContributorEngine; } @@ -40,6 +41,7 @@ const NewPersonaForm = ({ parentPagePath }: NewPersonaFormProps) => { const initialValues = { displayName: '', nameId: '', + prompt: '', description: '', engine: VirtualContributorEngine.Expert, }; @@ -51,22 +53,25 @@ const NewPersonaForm = ({ parentPagePath }: NewPersonaFormProps) => { navigateBack(); }; - const [handleSubmit] = useLoadingState(async ({ displayName, engine, nameId, description }: NewPersonaFormValues) => { - await createPersona({ - variables: { - virtualPersonaData: { - nameID: nameId, - profileData: { - displayName, - description, + const [handleSubmit] = useLoadingState( + async ({ displayName, prompt, engine, nameId, description }: NewPersonaFormValues) => { + await createPersona({ + variables: { + virtualPersonaData: { + prompt, + nameID: nameId, + profileData: { + displayName, + description, + }, + engine, }, - engine, }, - }, - }); - notify('Persona Created Successfully!', 'success'); - navigateBack(); - }); + }); + notify('Persona Created Successfully!', 'success'); + navigateBack(); + } + ); const engines = useMemo( () => @@ -88,6 +93,7 @@ const NewPersonaForm = ({ parentPagePath }: NewPersonaFormProps) => { + Date: Thu, 30 May 2024 11:57:58 +0300 Subject: [PATCH 15/30] Revert prompt --- src/core/apollo/generated/apollo-helpers.ts | 27 +++++- src/core/apollo/generated/apollo-hooks.ts | 2 +- src/core/apollo/generated/graphql-schema.ts | 85 +++++++++++++++---- .../space/createSpace/CreateNewSpace.graphql | 2 +- 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/src/core/apollo/generated/apollo-helpers.ts b/src/core/apollo/generated/apollo-helpers.ts index 4226cb4ab5..e262c658af 100644 --- a/src/core/apollo/generated/apollo-helpers.ts +++ b/src/core/apollo/generated/apollo-helpers.ts @@ -13,6 +13,7 @@ export type AccountKeySpecifier = ( | 'library' | 'license' | 'spaceID' + | 'subscriptions' | AccountKeySpecifier )[]; export type AccountFieldPolicy = { @@ -24,6 +25,12 @@ export type AccountFieldPolicy = { library?: FieldPolicy | FieldReadFunction; license?: FieldPolicy | FieldReadFunction; spaceID?: FieldPolicy | FieldReadFunction; + subscriptions?: FieldPolicy | FieldReadFunction; +}; +export type AccountSubscriptionKeySpecifier = ('expires' | 'name' | AccountSubscriptionKeySpecifier)[]; +export type AccountSubscriptionFieldPolicy = { + expires?: FieldPolicy | FieldReadFunction; + name?: FieldPolicy | FieldReadFunction; }; export type ActivityCreatedSubscriptionResultKeySpecifier = ( | 'activity' @@ -1345,6 +1352,7 @@ export type LicensePlanKeySpecifier = ( | 'enabled' | 'id' | 'isFree' + | 'licenseCredential' | 'name' | 'pricePerMonth' | 'requiresContactSupport' @@ -1357,6 +1365,7 @@ export type LicensePlanFieldPolicy = { enabled?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; isFree?: FieldPolicy | FieldReadFunction; + licenseCredential?: FieldPolicy | FieldReadFunction; name?: FieldPolicy | FieldReadFunction; pricePerMonth?: FieldPolicy | FieldReadFunction; requiresContactSupport?: FieldPolicy | FieldReadFunction; @@ -1381,9 +1390,17 @@ export type LicensePolicyRuleFeatureFlagFieldPolicy = { grantedPrivileges?: FieldPolicy | FieldReadFunction; name?: FieldPolicy | FieldReadFunction; }; -export type LicensingKeySpecifier = ('authorization' | 'id' | 'plans' | 'policy' | LicensingKeySpecifier)[]; +export type LicensingKeySpecifier = ( + | 'authorization' + | 'basePlan' + | 'id' + | 'plans' + | 'policy' + | LicensingKeySpecifier +)[]; export type LicensingFieldPolicy = { authorization?: FieldPolicy | FieldReadFunction; + basePlan?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; plans?: FieldPolicy | FieldReadFunction; policy?: FieldPolicy | FieldReadFunction; @@ -2869,6 +2886,7 @@ export type VirtualContributorKeySpecifier = ( | 'account' | 'agent' | 'authorization' + | 'bodyOfKnowledgeID' | 'bodyOfKnowledgeType' | 'id' | 'nameID' @@ -2881,6 +2899,7 @@ export type VirtualContributorFieldPolicy = { account?: FieldPolicy | FieldReadFunction; agent?: FieldPolicy | FieldReadFunction; authorization?: FieldPolicy | FieldReadFunction; + bodyOfKnowledgeID?: FieldPolicy | FieldReadFunction; bodyOfKnowledgeType?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; nameID?: FieldPolicy | FieldReadFunction; @@ -2895,6 +2914,7 @@ export type VirtualPersonaKeySpecifier = ( | 'id' | 'nameID' | 'profile' + | 'prompt' | VirtualPersonaKeySpecifier )[]; export type VirtualPersonaFieldPolicy = { @@ -2904,6 +2924,7 @@ export type VirtualPersonaFieldPolicy = { id?: FieldPolicy | FieldReadFunction; nameID?: FieldPolicy | FieldReadFunction; profile?: FieldPolicy | FieldReadFunction; + prompt?: FieldPolicy | FieldReadFunction; }; export type VirtualPersonaResultKeySpecifier = ( | 'answer' @@ -2992,6 +3013,10 @@ export type StrictTypedTypePolicies = { keyFields?: false | AccountKeySpecifier | (() => undefined | AccountKeySpecifier); fields?: AccountFieldPolicy; }; + AccountSubscription?: Omit & { + keyFields?: false | AccountSubscriptionKeySpecifier | (() => undefined | AccountSubscriptionKeySpecifier); + fields?: AccountSubscriptionFieldPolicy; + }; ActivityCreatedSubscriptionResult?: Omit & { keyFields?: | false diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 2ad4cadfc3..01986e642a 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -15853,7 +15853,7 @@ export function refetchLegacySubspaceDashboardPageQuery( export const CreateNewSpaceDocument = gql` mutation CreateNewSpace($hostId: UUID_NAMEID!, $spaceData: CreateSpaceInput!, $planId: UUID) { - createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, planID: $planId }) { + createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, licensePlanID: $planId }) { id spaceID } diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index edf9ae7129..4ec49d49e4 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -52,6 +52,8 @@ export type Account = { license: License; /** The ID for the root space for the Account . */ spaceID: Scalars['String']; + /** The subscriptions active for this Account. */ + subscriptions: Array; }; export type AccountAuthorizationResetInput = { @@ -59,6 +61,14 @@ export type AccountAuthorizationResetInput = { accountID: Scalars['UUID_NAMEID']; }; +export type AccountSubscription = { + __typename?: 'AccountSubscription'; + /** The expiry date of this subscription, null if it does never expire. */ + expires?: Maybe; + /** The name of the Subscription. */ + name: Scalars['String']; +}; + export type ActivityCreatedSubscriptionInput = { /** The collaboration on which to subscribe for new activity */ collaborationID: Scalars['UUID']; @@ -1407,8 +1417,8 @@ export type ConvertSubsubspaceToSubspaceInput = { export type CreateAccountInput = { /** The host Organization or User for the account */ hostID: Scalars['UUID_NAMEID']; - /** The plan selected for the account */ - planID?: InputMaybe; + /** The license plan selected for the account */ + licensePlanID?: InputMaybe; /** The root Space to be created. */ spaceData: CreateSpaceInput; }; @@ -1768,7 +1778,7 @@ export type Credential = { /** The User issuing the credential */ issuer?: Maybe; resourceID: Scalars['String']; - type: AuthorizationCredential; + type: CredentialType; }; export type CredentialDefinition = { @@ -1795,6 +1805,31 @@ export type CredentialMetadataOutput = { uniqueType: Scalars['String']; }; +export enum CredentialType { + AccountHost = 'ACCOUNT_HOST', + BetaTester = 'BETA_TESTER', + GlobalAdmin = 'GLOBAL_ADMIN', + GlobalCommunityRead = 'GLOBAL_COMMUNITY_READ', + GlobalLicenseManager = 'GLOBAL_LICENSE_MANAGER', + GlobalRegistered = 'GLOBAL_REGISTERED', + GlobalSpacesReader = 'GLOBAL_SPACES_READER', + GlobalSupport = 'GLOBAL_SUPPORT', + InnovationPackProvider = 'INNOVATION_PACK_PROVIDER', + LicenseSpaceEnterprise = 'LICENSE_SPACE_ENTERPRISE', + LicenseSpaceFree = 'LICENSE_SPACE_FREE', + LicenseSpacePlus = 'LICENSE_SPACE_PLUS', + LicenseSpacePremium = 'LICENSE_SPACE_PREMIUM', + OrganizationAdmin = 'ORGANIZATION_ADMIN', + OrganizationAssociate = 'ORGANIZATION_ASSOCIATE', + OrganizationOwner = 'ORGANIZATION_OWNER', + SpaceAdmin = 'SPACE_ADMIN', + SpaceLead = 'SPACE_LEAD', + SpaceMember = 'SPACE_MEMBER', + SpaceSubspaceAdmin = 'SPACE_SUBSPACE_ADMIN', + UserGroupMember = 'USER_GROUP_MEMBER', + UserSelfManagement = 'USER_SELF_MANAGEMENT', +} + export type DeleteActorGroupInput = { ID: Scalars['UUID']; }; @@ -2299,6 +2334,13 @@ export type License = { visibility: SpaceVisibility; }; +export enum LicenseCredential { + LicenseSpaceEnterprise = 'LICENSE_SPACE_ENTERPRISE', + LicenseSpaceFree = 'LICENSE_SPACE_FREE', + LicenseSpacePlus = 'LICENSE_SPACE_PLUS', + LicenseSpacePremium = 'LICENSE_SPACE_PREMIUM', +} + export type LicenseFeatureFlag = { __typename?: 'LicenseFeatureFlag'; /** Is this feature flag enabled? */ @@ -2321,6 +2363,8 @@ export type LicensePlan = { id: Scalars['UUID']; /** Is this plan free? */ isFree: Scalars['Boolean']; + /** The credential to represent this plan */ + licenseCredential: LicenseCredential; /** The name of the License Plan */ name: Scalars['String']; /** The price per month of this plan. */ @@ -2362,6 +2406,8 @@ export type Licensing = { __typename?: 'Licensing'; /** The authorization rules for the entity */ authorization?: Maybe; + /** The base License Plan assigned to all Accounts in use on the platform. */ + basePlan: LicensePlan; /** The ID of the entity */ id: Scalars['UUID']; /** The License Plans in use on the platform. */ @@ -5657,6 +5703,8 @@ export type VirtualContributor = Contributor & { agent: Agent; /** The authorization rules for the Contributor */ authorization?: Maybe; + /** The body of knowledge ID used for the Virtual Contributor */ + bodyOfKnowledgeID: Scalars['UUID']; /** The body of knowledge type used for the Virtual Contributor */ bodyOfKnowledgeType: BodyOfKnowledgeType; /** The ID of the Contributor */ @@ -5672,6 +5720,7 @@ export type VirtualContributor = Contributor & { }; export enum VirtualContributorEngine { + CommunityManager = 'COMMUNITY_MANAGER', Expert = 'EXPERT', Guidance = 'GUIDANCE', } @@ -5690,6 +5739,8 @@ export type VirtualPersona = { nameID: Scalars['NameID']; /** The Profile for the VirtualPersona. */ profile: Profile; + /** The prompt used by this Virtual Persona */ + prompt: Scalars['String']; }; export enum VirtualPersonaAccessMode { @@ -5939,7 +5990,7 @@ export type UserAgentSsiFragment = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: AuthorizationCredential }> + | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: CredentialType }> | undefined; verifiedCredentials?: | Array<{ @@ -5972,7 +6023,7 @@ export type UserSsiQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: AuthorizationCredential }> + | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: CredentialType }> | undefined; verifiedCredentials?: | Array<{ @@ -14324,7 +14375,7 @@ export type CommunityPageMembersFragment = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> | undefined; }; profile: { @@ -15087,7 +15138,7 @@ export type ContributorsPageUsersQuery = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> | undefined; }; userProfile: { @@ -15167,7 +15218,7 @@ export type UserContributorPaginatedFragment = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> | undefined; }; userProfile: { @@ -15205,7 +15256,7 @@ export type UserContributorFragment = { __typename?: 'Agent'; id: string; credentials?: - | Array<{ __typename?: 'Credential'; id: string; type: AuthorizationCredential; resourceID: string }> + | Array<{ __typename?: 'Credential'; id: string; type: CredentialType; resourceID: string }> | undefined; }; userProfile: { @@ -16334,7 +16385,7 @@ export type UserAgentFragment = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: AuthorizationCredential }> + | Array<{ __typename?: 'Credential'; id: string; resourceID: string; type: CredentialType }> | undefined; }; }; @@ -16351,7 +16402,7 @@ export type UserDetailsFragment = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16464,7 +16515,7 @@ export type CreateUserMutation = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16521,7 +16572,7 @@ export type CreateUserNewRegistrationMutation = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16656,7 +16707,7 @@ export type UpdateUserMutation = { accountUpn: string; agent: { __typename?: 'Agent'; - credentials?: Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string }> | undefined; + credentials?: Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string }> | undefined; }; profile: { __typename?: 'Profile'; @@ -16727,7 +16778,7 @@ export type UserQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string; id: string }> + | Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string; id: string }> | undefined; }; profile: { @@ -16817,7 +16868,7 @@ export type UserProfileQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string; id: string }> + | Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string; id: string }> | undefined; }; profile: { @@ -16952,7 +17003,7 @@ export type UserProviderQuery = { id: string; did?: string | undefined; credentials?: - | Array<{ __typename?: 'Credential'; type: AuthorizationCredential; resourceID: string; id: string }> + | Array<{ __typename?: 'Credential'; type: CredentialType; resourceID: string; id: string }> | undefined; }; profile: { diff --git a/src/domain/journey/space/createSpace/CreateNewSpace.graphql b/src/domain/journey/space/createSpace/CreateNewSpace.graphql index 8b0013c60f..27bc6ab035 100644 --- a/src/domain/journey/space/createSpace/CreateNewSpace.graphql +++ b/src/domain/journey/space/createSpace/CreateNewSpace.graphql @@ -1,5 +1,5 @@ mutation CreateNewSpace($hostId: UUID_NAMEID!, $spaceData: CreateSpaceInput!, $planId: UUID) { - createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, planID: $planId }) { + createAccount(accountData: { hostID: $hostId, spaceData: $spaceData, licensePlanID: $planId }) { id spaceID } From 59356b2bf92c62f3819686bf138cef972bf2498d Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 11:59:01 +0300 Subject: [PATCH 16/30] vc host related inputs --- .../vcSettingsPage/VCSettingsPage.tsx | 1 - .../vcSettingsPage/VirtualContributorForm.tsx | 44 +++++++++++-------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index 528131543b..d0ccf98856 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -40,7 +40,6 @@ export const VCSettingsPage = () => { virtualContributor={data?.virtualContributor} avatar={data?.virtualContributor.profile.avatar} onSave={handleUpdate} - title={''} /> )} diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index 58f3c40cd0..5963fd5552 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -9,13 +9,15 @@ import { ProfileSegment, profileSegmentSchema } from '../../../platform/admin/co import { Button, Grid } from '@mui/material'; import WrapperButton from '../../../../core/ui/button/deprecated/WrapperButton'; import VisualUpload from '../../../../core/ui/upload/VisualUpload/VisualUpload'; -import Section, { Header } from '../../../../core/ui/content/deprecated/Section'; +import Section from '../../../../core/ui/content/deprecated/Section'; import Gutters from '../../../../core/ui/grid/Gutters'; import useLoadingState from '../../../shared/utils/useLoadingState'; import { Actions } from '../../../../core/ui/actions/Actions'; import { LoadingButton } from '@mui/lab'; import { TagsetSegment } from '../../../platform/admin/components/Common/TagsetSegment'; import { UpdateTagset } from '../../../common/profile/Profile'; +import FormikInputField from '../../../../core/ui/forms/FormikInputField/FormikInputField'; +import { theme } from '../../../../core/ui/themes/default/Theme'; interface VirtualContributorProps { id: string; @@ -51,7 +53,6 @@ export const VirtualContributorForm: FC = ({ virtualContributor: currentVirtualContributor, avatar, onSave, - title = 'Virtual Contributor', }) => { const navigate = useNavigate(); const { t } = useTranslation(); @@ -116,20 +117,13 @@ export const VirtualContributorForm: FC = ({ ); - const getVisualAvatar = avatar => { - if (avatar) { - return ( - - ); - } - return null; - }; + const HostFields = () => ( + <> + + + + + ); if (!currentVirtualContributor) { return ( @@ -150,16 +144,28 @@ export const VirtualContributorForm: FC = ({ {({ values: { avatar, tagsets }, handleSubmit }) => { return ( -
-
+
+ ) + } + > <> {tagsets && } + - + From 6177e163c30cb9e0321d50435e653ba7db3934b2 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 13:32:38 +0300 Subject: [PATCH 17/30] vc profile - dynamic display of Host and BodyOfKnowledge subpace --- src/core/apollo/generated/apollo-hooks.ts | 89 +++++++++++++++++++ src/core/apollo/generated/graphql-schema.ts | 61 +++++++++++++ .../VirtualContributor.graphql | 35 ++++++++ .../vcProfilePage/HostCardClean.tsx | 2 +- .../vcProfilePage/SpaceHorizontalCard.tsx | 64 +++++++++++++ .../vcProfilePage/VCProfilePage.tsx | 18 +++- .../vcProfilePage/VCProfilePageView.tsx | 45 +++------- 7 files changed, 277 insertions(+), 37 deletions(-) create mode 100644 src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 01986e642a..a66ba6420e 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -14111,6 +14111,23 @@ export const VirtualContributorDocument = gql` virtualContributor(ID: $id) { id nameID + bodyOfKnowledgeID + account { + spaceID + host { + profile { + displayName + tagline + avatar: visual(type: AVATAR) { + uri + } + location { + city + country + } + } + } + } profile { id displayName @@ -14181,6 +14198,78 @@ export function refetchVirtualContributorQuery(variables: SchemaTypes.VirtualCon return { query: VirtualContributorDocument, variables: variables }; } +export const BodyOfKnowledgeProfileDocument = gql` + query BodyOfKnowledgeProfile($spaceId: UUID!) { + lookup { + space(ID: $spaceId) { + profile { + displayName + tagline + url + avatar: visual(type: AVATAR) { + uri + } + cardBanner: visual(type: CARD) { + uri + } + } + } + } + } +`; + +/** + * __useBodyOfKnowledgeProfileQuery__ + * + * To run a query within a React component, call `useBodyOfKnowledgeProfileQuery` and pass it any options that fit your needs. + * When your component renders, `useBodyOfKnowledgeProfileQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useBodyOfKnowledgeProfileQuery({ + * variables: { + * spaceId: // value for 'spaceId' + * }, + * }); + */ +export function useBodyOfKnowledgeProfileQuery( + baseOptions: Apollo.QueryHookOptions< + SchemaTypes.BodyOfKnowledgeProfileQuery, + SchemaTypes.BodyOfKnowledgeProfileQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + BodyOfKnowledgeProfileDocument, + options + ); +} + +export function useBodyOfKnowledgeProfileLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + SchemaTypes.BodyOfKnowledgeProfileQuery, + SchemaTypes.BodyOfKnowledgeProfileQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + BodyOfKnowledgeProfileDocument, + options + ); +} + +export type BodyOfKnowledgeProfileQueryHookResult = ReturnType; +export type BodyOfKnowledgeProfileLazyQueryHookResult = ReturnType; +export type BodyOfKnowledgeProfileQueryResult = Apollo.QueryResult< + SchemaTypes.BodyOfKnowledgeProfileQuery, + SchemaTypes.BodyOfKnowledgeProfileQueryVariables +>; +export function refetchBodyOfKnowledgeProfileQuery(variables: SchemaTypes.BodyOfKnowledgeProfileQueryVariables) { + return { query: BodyOfKnowledgeProfileDocument, variables: variables }; +} + export const InnovationHubAvailableSpacesDocument = gql` query InnovationHubAvailableSpaces { spaces(filter: { visibilities: [ACTIVE, DEMO] }) { diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 4ec49d49e4..d7db61fc1a 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -17329,6 +17329,43 @@ export type VirtualContributorQuery = { __typename?: 'VirtualContributor'; id: string; nameID: string; + bodyOfKnowledgeID: string; + account: { + __typename?: 'Account'; + spaceID: string; + host?: + | { + __typename?: 'Organization'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + location?: { __typename?: 'Location'; city: string; country: string } | undefined; + }; + } + | { + __typename?: 'User'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + location?: { __typename?: 'Location'; city: string; country: string } | undefined; + }; + } + | { + __typename?: 'VirtualContributor'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + location?: { __typename?: 'Location'; city: string; country: string } | undefined; + }; + } + | undefined; + }; profile: { __typename?: 'Profile'; id: string; @@ -17355,6 +17392,30 @@ export type VirtualContributorQuery = { }; }; +export type BodyOfKnowledgeProfileQueryVariables = Exact<{ + spaceId: Scalars['UUID']; +}>; + +export type BodyOfKnowledgeProfileQuery = { + __typename?: 'Query'; + lookup: { + __typename?: 'LookupQueryResults'; + space?: + | { + __typename?: 'Space'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + url: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + cardBanner?: { __typename?: 'Visual'; uri: string } | undefined; + }; + } + | undefined; + }; +}; + export type ContextDetailsFragment = { __typename?: 'Context'; id: string; diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql index 8012390860..6438f2f84c 100644 --- a/src/domain/community/virtualContributor/VirtualContributor.graphql +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -2,6 +2,23 @@ query VirtualContributor ($id: UUID_NAMEID!) { virtualContributor (ID: $id) { id nameID + bodyOfKnowledgeID + account { + spaceID + host { + profile { + displayName + tagline + avatar: visual(type: AVATAR) { + uri + } + location { + city + country + } + } + } + } profile { id displayName @@ -17,3 +34,21 @@ query VirtualContributor ($id: UUID_NAMEID!) { } } } + +query BodyOfKnowledgeProfile($spaceId: UUID!) { + lookup { + space(ID: $spaceId) { + profile { + displayName + tagline + url + avatar: visual(type: AVATAR) { + uri + } + cardBanner: visual(type: CARD) { + uri + } + } + } + } +} \ No newline at end of file diff --git a/src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx b/src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx index 4069d37fed..0f35d6c397 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx @@ -11,7 +11,7 @@ import { theme } from '../../../../core/ui/themes/default/Theme'; interface HostProps { hostProfile?: { - avatar: { + avatar?: { uri: string; }; displayName: string; diff --git a/src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx b/src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx new file mode 100644 index 0000000000..296b18892e --- /dev/null +++ b/src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx @@ -0,0 +1,64 @@ +import React, { FC } from 'react'; +import BadgeCardView from '../../../../core/ui/list/BadgeCardView'; +import Avatar from '../../../../core/ui/avatar/Avatar'; +import { BlockSectionTitle } from '../../../../core/ui/typography'; +import { useTranslation } from 'react-i18next'; +import { theme } from '../../../../core/ui/themes/default/Theme'; +import RouterLink from '../../../../core/ui/link/RouterLink'; +import defaultJourneyCardBanner from '../../../../domain/journey/defaultVisuals/Card.jpg'; + +// TODO: add cardBanner if we want support of Spaces as BOK +export interface BokProps { + bokProfile: + | { + avatar?: { + uri: string; + }; + displayName: string; + tagline: string; + url: string; + } + | undefined; + showDefaults?: boolean; +} + +const DEFULT_BOK = { + avatar: { + uri: 'https://alkem.io/api/private/rest/storage/document/1057e0c1-2d47-4821-8848-20ec19cb2a0d', + }, + displayName: 'Welcome @ Alkemio!', + tagline: 'Take 5 minutes to get started', + url: 'https://alkem.io/welcome-space', +}; + +const SpaceHorizontalCard: FC = ({ bokProfile, showDefaults }) => { + const { t } = useTranslation(); + + const bodyOfKnowledge = bokProfile ? bokProfile : showDefaults ? DEFULT_BOK : undefined; + + if (!bodyOfKnowledge) { + return null; + } + + return ( + + {bodyOfKnowledge.displayName} + + } + component={RouterLink} + to={bodyOfKnowledge.url} + > + {bodyOfKnowledge.displayName} + {bodyOfKnowledge.tagline} + + ); +}; + +export default SpaceHorizontalCard; diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx index 04dfbf4fe2..bd4ee3e9d9 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx @@ -4,7 +4,10 @@ import { useUrlParams } from '../../../../core/routing/useUrlParams'; import { Error404 } from '../../../../core/pages/Errors/Error404'; import VCPageLayout from '../layout/VCPageLayout'; import VCProfilePageView from './VCProfilePageView'; -import { useVirtualContributorQuery } from '../../../../core/apollo/generated/apollo-hooks'; +import { + useBodyOfKnowledgeProfileQuery, + useVirtualContributorQuery, +} from '../../../../core/apollo/generated/apollo-hooks'; export const VCProfilePage = () => { const { vcNameId = '' } = useUrlParams(); @@ -15,6 +18,13 @@ export const VCProfilePage = () => { }, }); + const { data: bokProfile, loading: loadingBok } = useBodyOfKnowledgeProfileQuery({ + variables: { + spaceId: data?.virtualContributor.bodyOfKnowledgeID || '', + }, + skip: !data?.virtualContributor.bodyOfKnowledgeID, + }); + if (loading) return ; if (error) { @@ -27,7 +37,11 @@ export const VCProfilePage = () => { return ( - + ); }; diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx index f54b227a3d..5cd8d0838c 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx @@ -6,35 +6,28 @@ import BookIcon from '@mui/icons-material/Book'; import PageContent from '../../../../core/ui/content/PageContent'; import PageContentColumn from '../../../../core/ui/content/PageContentColumn'; import { VirtualContributorQuery } from '../../../../core/apollo/generated/graphql-schema'; -import { BlockSectionTitle, BlockTitle, Text } from '../../../../core/ui/typography'; +import { BlockTitle, Text } from '../../../../core/ui/typography'; import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; import HostCardClean from './HostCardClean'; import useTheme from '@mui/material/styles/useTheme'; import { Trans, useTranslation } from 'react-i18next'; -import BadgeCardView from '../../../../core/ui/list/BadgeCardView'; -import Avatar from '../../../../core/ui/avatar/Avatar'; -import RouterLink from '../../../../core/ui/link/RouterLink'; import ProfileDetail from '../../profile/ProfileDetail/ProfileDetail'; +import SpaceHorizontalCard, { BokProps } from './SpaceHorizontalCard'; -interface Props { +interface Props extends BokProps { virtualContributor: VirtualContributorQuery['virtualContributor'] | undefined; + showDefaults?: boolean; } -const DEFULT_PROFILE = { - avatar: { - uri: 'https://alkem.io/api/private/rest/storage/document/1057e0c1-2d47-4821-8848-20ec19cb2a0d', - }, - displayName: 'Welcome @ Alkemio!', - tagline: 'Take 5 minutes to get started', - url: 'https://alkem.io/welcome-space', -}; - -export const VCProfilePageView: FC> = ({ virtualContributor }) => { +export const VCProfilePageView: FC> = ({ + virtualContributor, + bokProfile, + showDefaults = false, +}) => { const theme = useTheme(); const { t } = useTranslation(); const name = virtualContributor?.profile.displayName || t('pages.virtual-contributor-profile.default-name'); - const profile = DEFULT_PROFILE; const SectionTitle = ({ children }) => ( @@ -55,7 +48,7 @@ export const VCProfilePageView: FC> = ({ virtualContrib aria-label="description" /> - + @@ -65,23 +58,7 @@ export const VCProfilePageView: FC> = ({ virtualContrib - - {profile.displayName} - - } - component={RouterLink} - to={profile.url} - > - {profile.displayName} - {profile.tagline} - + From b250a0b3169e96c4ac6f12cc96d5299caa63732a Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 15:19:30 +0300 Subject: [PATCH 18/30] fix display for legacy VCs with no account --- .../virtualContributor/vcProfilePage/VCProfilePageView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx index 5cd8d0838c..a5fbddd145 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx @@ -48,7 +48,7 @@ export const VCProfilePageView: FC> = ({ aria-label="description" /> - + From c725b283b1996d8fc0fd0c8f309753e85360769e Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 15:43:20 +0300 Subject: [PATCH 19/30] show the edit profile option on Update privilege --- src/core/apollo/generated/apollo-hooks.ts | 3 + src/core/apollo/generated/graphql-schema.ts | 79 ++++++++++--------- .../VirtualContributor.graphql | 3 + .../layout/VCPageBanner.tsx | 11 +-- 4 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index b47c34d6f1..a05ee58d23 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -14112,6 +14112,9 @@ export const VirtualContributorDocument = gql` id nameID bodyOfKnowledgeID + authorization { + myPrivileges + } account { spaceID host { diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 3cae08f364..3ae6108c99 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -5698,7 +5698,7 @@ export type VerifiedCredentialClaim = { export type VirtualContributor = Contributor & { __typename?: 'VirtualContributor'; /** The account under which the virtual contributor was created */ - account: Account; + account?: Maybe; /** The Agent representing this User. */ agent: Agent; /** The authorization rules for the Contributor */ @@ -17330,42 +17330,47 @@ export type VirtualContributorQuery = { id: string; nameID: string; bodyOfKnowledgeID: string; - account: { - __typename?: 'Account'; - spaceID: string; - host?: - | { - __typename?: 'Organization'; - profile: { - __typename?: 'Profile'; - displayName: string; - tagline: string; - avatar?: { __typename?: 'Visual'; uri: string } | undefined; - location?: { __typename?: 'Location'; city: string; country: string } | undefined; - }; - } - | { - __typename?: 'User'; - profile: { - __typename?: 'Profile'; - displayName: string; - tagline: string; - avatar?: { __typename?: 'Visual'; uri: string } | undefined; - location?: { __typename?: 'Location'; city: string; country: string } | undefined; - }; - } - | { - __typename?: 'VirtualContributor'; - profile: { - __typename?: 'Profile'; - displayName: string; - tagline: string; - avatar?: { __typename?: 'Visual'; uri: string } | undefined; - location?: { __typename?: 'Location'; city: string; country: string } | undefined; - }; - } - | undefined; - }; + authorization?: + | { __typename?: 'Authorization'; myPrivileges?: Array | undefined } + | undefined; + account?: + | { + __typename?: 'Account'; + spaceID: string; + host?: + | { + __typename?: 'Organization'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + location?: { __typename?: 'Location'; city: string; country: string } | undefined; + }; + } + | { + __typename?: 'User'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + location?: { __typename?: 'Location'; city: string; country: string } | undefined; + }; + } + | { + __typename?: 'VirtualContributor'; + profile: { + __typename?: 'Profile'; + displayName: string; + tagline: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + location?: { __typename?: 'Location'; city: string; country: string } | undefined; + }; + } + | undefined; + } + | undefined; profile: { __typename?: 'Profile'; id: string; diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql index 660287cb0f..598a19b9ac 100644 --- a/src/domain/community/virtualContributor/VirtualContributor.graphql +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -3,6 +3,9 @@ query VirtualContributor ($id: UUID_NAMEID!) { id nameID bodyOfKnowledgeID + authorization { + myPrivileges + } account { spaceID host { diff --git a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx index 30c8ae22bf..b7b1bb1079 100644 --- a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx +++ b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx @@ -3,6 +3,7 @@ import { useVirtualContributorQuery } from '../../../../core/apollo/generated/ap import { useUrlParams } from '../../../../core/routing/useUrlParams'; import ProfilePageBanner from '../../../common/profile/ProfilePageBanner'; import { buildVCProfileSettingsUrl } from '../../../../main/routing/urlBuilders'; +import { AuthorizationPrivilege } from '../../../../core/apollo/generated/graphql-schema'; const VCPageBanner = () => { const { vcNameId = '' } = useUrlParams(); @@ -15,16 +16,16 @@ const VCPageBanner = () => { const profile = data?.virtualContributor.profile; - const userId = data?.virtualContributor.id; + const vcId = data?.virtualContributor.id; - // TODO: implement hasSettings priviliges - // TBD but the current user has to be the HOST of the Account where the VC is used - const hasSettingsAccess = false; + const hasSettingsAccess = data?.virtualContributor.authorization?.myPrivileges?.includes( + AuthorizationPrivilege.Update + ); return ( Date: Thu, 30 May 2024 16:46:57 +0300 Subject: [PATCH 20/30] layout style improvements --- .../vcSettingsPage/VCSettingsPage.tsx | 23 +++-- .../vcSettingsPage/VirtualContributorForm.tsx | 84 ++++++++++--------- 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index d0ccf98856..46a1b47151 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -7,6 +7,9 @@ import { useVirtualContributorQuery, } from '../../../../core/apollo/generated/apollo-hooks'; import VirtualContributorForm from './VirtualContributorForm'; +import PageContentColumn from '../../../../core/ui/content/PageContentColumn'; +import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; +import PageContent from '../../../../core/ui/content/PageContent'; export const VCSettingsPage = () => { const { vcNameId = '' } = useUrlParams(); @@ -35,13 +38,19 @@ export const VCSettingsPage = () => { // TODO: StorageProvider for the VC return ( - {data?.virtualContributor && ( - - )} + + + + {data?.virtualContributor && ( + + )} + + + ); }; diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index 5963fd5552..3b790e652c 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -2,22 +2,23 @@ import { Form, Formik } from 'formik'; import React, { FC } from 'react'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; +import { Box, Button, Theme, useMediaQuery } from '@mui/material'; +import { LoadingButton } from '@mui/lab'; import { Tagset, UpdateVirtualContributorInput, Visual } from '../../../../core/apollo/generated/graphql-schema'; import useNavigate from '../../../../core/routing/useNavigate'; import { NameSegment, nameSegmentSchema } from '../../../platform/admin/components/Common/NameSegment'; import { ProfileSegment, profileSegmentSchema } from '../../../platform/admin/components/Common/ProfileSegment'; -import { Button, Grid } from '@mui/material'; -import WrapperButton from '../../../../core/ui/button/deprecated/WrapperButton'; import VisualUpload from '../../../../core/ui/upload/VisualUpload/VisualUpload'; -import Section from '../../../../core/ui/content/deprecated/Section'; import Gutters from '../../../../core/ui/grid/Gutters'; import useLoadingState from '../../../shared/utils/useLoadingState'; import { Actions } from '../../../../core/ui/actions/Actions'; -import { LoadingButton } from '@mui/lab'; import { TagsetSegment } from '../../../platform/admin/components/Common/TagsetSegment'; import { UpdateTagset } from '../../../common/profile/Profile'; import FormikInputField from '../../../../core/ui/forms/FormikInputField/FormikInputField'; import { theme } from '../../../../core/ui/themes/default/Theme'; +import GridContainer from '../../../../core/ui/grid/GridContainer'; +import GridProvider from '../../../../core/ui/grid/GridProvider'; +import GridItem from '../../../../core/ui/grid/GridItem'; interface VirtualContributorProps { id: string; @@ -54,8 +55,10 @@ export const VirtualContributorForm: FC = ({ avatar, onSave, }) => { - const navigate = useNavigate(); const { t } = useTranslation(); + const navigate = useNavigate(); + const handleBack = () => navigate(-1); + const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('sm')); const { nameID, @@ -109,12 +112,10 @@ export const VirtualContributorForm: FC = ({ await onSave?.(virtualContributor); }); - const handleBack = () => navigate(-1); - const backButton = ( - - - + ); const HostFields = () => ( @@ -144,36 +145,39 @@ export const VirtualContributorForm: FC = ({ {({ values: { avatar, tagsets }, handleSubmit }) => { return ( -
- ) - } - > - - <> - - - {tagsets && } - - - - - - - {t('buttons.save')} - - -
+ + + + {avatar && ( + + + + )} + + + + <> + + + {tagsets && } + + + {backButton} + + {t('buttons.save')} + + + + + + + ); }} From 5b9810ca922642614084712c07d7000e2864dd89 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 17:19:29 +0300 Subject: [PATCH 21/30] pr fixes --- .../vcSettingsPage/VCSettingsPage.tsx | 44 +++++++++++-------- .../vcSettingsPage/VirtualContributorForm.tsx | 19 ++++---- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index 46a1b47151..b96a29e0bd 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -10,10 +10,14 @@ import VirtualContributorForm from './VirtualContributorForm'; import PageContentColumn from '../../../../core/ui/content/PageContentColumn'; import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; import PageContent from '../../../../core/ui/content/PageContent'; +import { useNotification } from '../../../../core/ui/notifications/useNotification'; +import { StorageConfigContextProvider } from '../../../storage/StorageBucket/StorageConfigContext'; export const VCSettingsPage = () => { const { vcNameId = '' } = useUrlParams(); + const notify = useNotification(); + const { data, loading } = useVirtualContributorQuery({ variables: { id: vcNameId, @@ -22,36 +26,40 @@ export const VCSettingsPage = () => { const [updateContributorMutation] = useUpdateVirtualContributorMutation(); - const handleUpdate = async virtualContributor => { - await updateContributorMutation({ + const handleUpdate = virtualContributor => { + updateContributorMutation({ variables: { virtualContributorData: { ID: virtualContributor.ID, profileData: virtualContributor.profileData, }, }, + onCompleted: () => { + notify('Profile updated successfully', 'success'); + }, }); }; if (loading) return ; - // TODO: StorageProvider for the VC return ( - - - - - {data?.virtualContributor && ( - - )} - - - - + + + + + + {data?.virtualContributor && ( + + )} + + + + + ); }; diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index 3b790e652c..2c85349180 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -75,16 +75,18 @@ export const VirtualContributorForm: FC = ({ }; const validationSchema = yup.object().shape({ - name: nameSegmentSchema.fields?.name || yup.string(), - nameID: nameSegmentSchema.fields?.nameID || yup.string(), - description: profileSegmentSchema.fields?.description || yup.string(), + name: nameSegmentSchema.fields?.name ?? yup.string(), + nameID: nameSegmentSchema.fields?.nameID ?? yup.string(), + description: profileSegmentSchema.fields?.description ?? yup.string(), }); const getUpdatedTagsets = (updatedTagsets: Tagset[]) => { const result: UpdateTagset[] = []; updatedTagsets.forEach(updatedTagset => { const originalTagset = tagsets?.find(value => value.name === updatedTagset.name); - if (originalTagset) result.push({ ...originalTagset, tags: updatedTagset.tags }); + if (originalTagset) { + result.push({ ...originalTagset, tags: updatedTagset.tags }); + } }); return result; @@ -92,7 +94,7 @@ export const VirtualContributorForm: FC = ({ const [handleSubmit, loading] = useLoadingState(async (values: VirtualContributorFromProps) => { const { tagsets, description, tagline, name, ...otherData } = values; - const updatedTagsets = getUpdatedTagsets(tagsets || []); + const updatedTagsets = getUpdatedTagsets(tagsets ?? []); const virtualContributor = { ID: currentVirtualContributor.id, @@ -102,7 +104,6 @@ export const VirtualContributorForm: FC = ({ tagline, tagsets: updatedTagsets.map(r => ({ ID: r.id, - id: undefined, tags: r.tags ?? [], })), }, @@ -120,9 +121,9 @@ export const VirtualContributorForm: FC = ({ const HostFields = () => ( <> - - - + + + ); From 68c4d5c5a902e8b7e095d2984a535b9fc4c7c550 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 17:57:04 +0300 Subject: [PATCH 22/30] BodyOfKnowledge Name display --- .../vcSettingsPage/VCSettingsPage.tsx | 9 ++++++++ .../vcSettingsPage/VirtualContributorForm.tsx | 22 +++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index b96a29e0bd..b40f8c6864 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -3,6 +3,7 @@ import Loading from '../../../../core/ui/loading/Loading'; import { useUrlParams } from '../../../../core/routing/useUrlParams'; import VCPageLayout from '../layout/VCPageLayout'; import { + useBodyOfKnowledgeProfileQuery, useUpdateVirtualContributorMutation, useVirtualContributorQuery, } from '../../../../core/apollo/generated/apollo-hooks'; @@ -24,6 +25,13 @@ export const VCSettingsPage = () => { }, }); + const { data: bokProfile } = useBodyOfKnowledgeProfileQuery({ + variables: { + spaceId: data?.virtualContributor.bodyOfKnowledgeID || '', + }, + skip: !data?.virtualContributor.bodyOfKnowledgeID, + }); + const [updateContributorMutation] = useUpdateVirtualContributorMutation(); const handleUpdate = virtualContributor => { @@ -51,6 +59,7 @@ export const VCSettingsPage = () => { {data?.virtualContributor && ( diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index 2c85349180..d35f451720 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -19,10 +19,18 @@ import { theme } from '../../../../core/ui/themes/default/Theme'; import GridContainer from '../../../../core/ui/grid/GridContainer'; import GridProvider from '../../../../core/ui/grid/GridProvider'; import GridItem from '../../../../core/ui/grid/GridItem'; +import { BokProps } from '../vcProfilePage/SpaceHorizontalCard'; interface VirtualContributorProps { id: string; nameID: string; + account?: { + host?: { + profile: { + displayName: string; + }; + }; + }; profile: { id: string; displayName: string; @@ -41,9 +49,11 @@ interface VirtualContributorFromProps { tagline: string; tagsets?: Tagset[]; avatar: Visual | undefined; + hostDisplayName: string; + subSpaceName: string; } -interface Props { +interface Props extends BokProps { virtualContributor: VirtualContributorProps; avatar: Visual | undefined; onSave?: (virtualContributor: UpdateVirtualContributorInput) => void; @@ -52,6 +62,7 @@ interface Props { export const VirtualContributorForm: FC = ({ virtualContributor: currentVirtualContributor, + bokProfile, avatar, onSave, }) => { @@ -63,7 +74,9 @@ export const VirtualContributorForm: FC = ({ const { nameID, profile: { displayName, description, tagline, tagsets }, + account, } = currentVirtualContributor; + const { displayName: subSpaceName } = bokProfile ?? {}; const initialValues: VirtualContributorFromProps = { name: displayName, @@ -72,6 +85,8 @@ export const VirtualContributorForm: FC = ({ tagline: tagline, avatar: avatar, tagsets: tagsets, + hostDisplayName: account?.host?.profile.displayName ?? '', + subSpaceName: subSpaceName ?? '', }; const validationSchema = yup.object().shape({ @@ -121,9 +136,8 @@ export const VirtualContributorForm: FC = ({ const HostFields = () => ( <> - - - + + ); From b8bb9a72eee349bbfe173846256e23a6527e9ed3 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 30 May 2024 18:37:52 +0300 Subject: [PATCH 23/30] PR fixes and improvements --- src/core/apollo/generated/apollo-hooks.ts | 5 +++ src/core/apollo/generated/graphql-schema.ts | 17 ++++--- src/core/i18n/en/translation.en.json | 4 ++ .../VirtualContributor.graphql | 5 +++ .../BasicSpaceCard.tsx} | 45 +++++++++---------- .../HostCard.tsx} | 10 ++--- .../layout/VCPageBanner.tsx | 3 +- .../layout/VCPageLayout.tsx | 3 +- .../vcProfilePage/VCProfilePage.tsx | 10 ++++- .../vcProfilePage/VCProfilePageView.tsx | 11 ++--- .../vcSettingsPage/VCSettingsPage.tsx | 12 ++++- .../vcSettingsPage/VirtualContributorForm.tsx | 5 ++- src/main/routing/urlBuilders.ts | 4 -- 13 files changed, 80 insertions(+), 54 deletions(-) rename src/domain/community/virtualContributor/{vcProfilePage/SpaceHorizontalCard.tsx => components/BasicSpaceCard.tsx} (55%) rename src/domain/community/virtualContributor/{vcProfilePage/HostCardClean.tsx => components/HostCard.tsx} (87%) diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index a05ee58d23..3e63f7724f 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -14113,18 +14113,23 @@ export const VirtualContributorDocument = gql` nameID bodyOfKnowledgeID authorization { + id myPrivileges } account { + id spaceID host { + id profile { + id displayName tagline avatar: visual(type: AVATAR) { uri } location { + id city country } diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 3ae6108c99..af5866a797 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -1740,7 +1740,7 @@ export type CreateVirtualContributorOnAccountInput = { /** A readable identifier, unique within the containing scope. */ nameID: Scalars['NameID']; profileData: CreateProfileInput; - virtualPersonaID: Scalars['UUID']; + virtualPersonaID?: InputMaybe; }; export type CreateVirtualPersonaInput = { @@ -17331,41 +17331,48 @@ export type VirtualContributorQuery = { nameID: string; bodyOfKnowledgeID: string; authorization?: - | { __typename?: 'Authorization'; myPrivileges?: Array | undefined } + | { __typename?: 'Authorization'; id: string; myPrivileges?: Array | undefined } | undefined; account?: | { __typename?: 'Account'; + id: string; spaceID: string; host?: | { __typename?: 'Organization'; + id: string; profile: { __typename?: 'Profile'; + id: string; displayName: string; tagline: string; avatar?: { __typename?: 'Visual'; uri: string } | undefined; - location?: { __typename?: 'Location'; city: string; country: string } | undefined; + location?: { __typename?: 'Location'; id: string; city: string; country: string } | undefined; }; } | { __typename?: 'User'; + id: string; profile: { __typename?: 'Profile'; + id: string; displayName: string; tagline: string; avatar?: { __typename?: 'Visual'; uri: string } | undefined; - location?: { __typename?: 'Location'; city: string; country: string } | undefined; + location?: { __typename?: 'Location'; id: string; city: string; country: string } | undefined; }; } | { __typename?: 'VirtualContributor'; + id: string; profile: { __typename?: 'Profile'; + id: string; displayName: string; tagline: string; avatar?: { __typename?: 'Visual'; uri: string } | undefined; - location?: { __typename?: 'Location'; city: string; country: string } | undefined; + location?: { __typename?: 'Location'; id: string; city: string; country: string } | undefined; }; } | undefined; diff --git a/src/core/i18n/en/translation.en.json b/src/core/i18n/en/translation.en.json index d0e9850090..ee0bb199d0 100644 --- a/src/core/i18n/en/translation.en.json +++ b/src/core/i18n/en/translation.en.json @@ -2448,6 +2448,7 @@ } }, "virtual-contributor-profile": { + "title": "Virtual Contributor Profile", "default-name": "Alkemio Help", "description": "Description", "references": "References", @@ -2472,6 +2473,9 @@ "description": "For Alkemio, safeguarding your data is of utmost importance. We are committed to maintaining the security and privacy of your information.", "bullets": "
  • When interacting with a Virtual Contributor, only the data explicitly specified on the left (Context) is used to generate meaningful answers.
  • Importantly, your (Space) data is not utilized for training the Virtual Contributor.
  • Additionally, please note that questions and answers exchanged with the Virtual Contributor may be visible to the Alkemio team.
" } + }, + "settings": { + "title": "Virtual Contributor Settings" } }, "user-credentials": { diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql index 598a19b9ac..1dd4fe9871 100644 --- a/src/domain/community/virtualContributor/VirtualContributor.graphql +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -4,18 +4,23 @@ query VirtualContributor ($id: UUID_NAMEID!) { nameID bodyOfKnowledgeID authorization { + id myPrivileges } account { + id spaceID host { + id profile { + id displayName tagline avatar: visual(type: AVATAR) { uri } location { + id city country } diff --git a/src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx b/src/domain/community/virtualContributor/components/BasicSpaceCard.tsx similarity index 55% rename from src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx rename to src/domain/community/virtualContributor/components/BasicSpaceCard.tsx index 296b18892e..2987068017 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/SpaceHorizontalCard.tsx +++ b/src/domain/community/virtualContributor/components/BasicSpaceCard.tsx @@ -8,21 +8,21 @@ import RouterLink from '../../../../core/ui/link/RouterLink'; import defaultJourneyCardBanner from '../../../../domain/journey/defaultVisuals/Card.jpg'; // TODO: add cardBanner if we want support of Spaces as BOK -export interface BokProps { - bokProfile: - | { - avatar?: { - uri: string; - }; - displayName: string; - tagline: string; - url: string; - } - | undefined; +export interface BasicSpaceProps { + avatar?: { + uri: string; + }; + displayName: string; + tagline: string; + url: string; +} + +interface Props { + space: BasicSpaceProps | undefined; showDefaults?: boolean; } -const DEFULT_BOK = { +const DEFULT_SPACE_DATA = { avatar: { uri: 'https://alkem.io/api/private/rest/storage/document/1057e0c1-2d47-4821-8848-20ec19cb2a0d', }, @@ -31,12 +31,12 @@ const DEFULT_BOK = { url: 'https://alkem.io/welcome-space', }; -const SpaceHorizontalCard: FC = ({ bokProfile, showDefaults }) => { +const BasicSpaceCard: FC = ({ space, showDefaults }) => { const { t } = useTranslation(); - const bodyOfKnowledge = bokProfile ? bokProfile : showDefaults ? DEFULT_BOK : undefined; + const spaceData = space ? space : showDefaults ? DEFULT_SPACE_DATA : undefined; - if (!bodyOfKnowledge) { + if (!spaceData) { return null; } @@ -45,20 +45,19 @@ const SpaceHorizontalCard: FC = ({ bokProfile, showDefaults }) => { marginTop={theme.spacing(2)} visual={ - {bodyOfKnowledge.displayName} + {spaceData.displayName} } component={RouterLink} - to={bodyOfKnowledge.url} + to={spaceData.url} > - {bodyOfKnowledge.displayName} - {bodyOfKnowledge.tagline} + {spaceData.displayName} + {spaceData.tagline} ); }; -export default SpaceHorizontalCard; +export default BasicSpaceCard; diff --git a/src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx b/src/domain/community/virtualContributor/components/HostCard.tsx similarity index 87% rename from src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx rename to src/domain/community/virtualContributor/components/HostCard.tsx index 0f35d6c397..895fb4de53 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/HostCardClean.tsx +++ b/src/domain/community/virtualContributor/components/HostCard.tsx @@ -33,7 +33,7 @@ const DEFAULT_PROFILE = { }, }; -const HostCardClean: FC = ({ hostProfile }) => { +const HostCard: FC = ({ hostProfile }) => { const { t } = useTranslation(); const profile = hostProfile || DEFAULT_PROFILE; @@ -44,11 +44,7 @@ const HostCardClean: FC = ({ hostProfile }) => { + {profile.displayName[0]} } @@ -66,4 +62,4 @@ const HostCardClean: FC = ({ hostProfile }) => { ); }; -export default HostCardClean; +export default HostCard; diff --git a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx index b7b1bb1079..aff74e92cf 100644 --- a/src/domain/community/virtualContributor/layout/VCPageBanner.tsx +++ b/src/domain/community/virtualContributor/layout/VCPageBanner.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { useVirtualContributorQuery } from '../../../../core/apollo/generated/apollo-hooks'; import { useUrlParams } from '../../../../core/routing/useUrlParams'; import ProfilePageBanner from '../../../common/profile/ProfilePageBanner'; -import { buildVCProfileSettingsUrl } from '../../../../main/routing/urlBuilders'; import { AuthorizationPrivilege } from '../../../../core/apollo/generated/graphql-schema'; const VCPageBanner = () => { @@ -27,7 +26,7 @@ const VCPageBanner = () => { isVirtualContributor entityId={vcId} profile={profile} - settingsUri={hasSettingsAccess ? buildVCProfileSettingsUrl(data?.virtualContributor.nameID || '') : undefined} + settingsUri={hasSettingsAccess ? `${data?.virtualContributor.profile.url}/settings/profile` : undefined} loading={loading} /> ); diff --git a/src/domain/community/virtualContributor/layout/VCPageLayout.tsx b/src/domain/community/virtualContributor/layout/VCPageLayout.tsx index cd4a332c7b..0649d194ae 100644 --- a/src/domain/community/virtualContributor/layout/VCPageLayout.tsx +++ b/src/domain/community/virtualContributor/layout/VCPageLayout.tsx @@ -2,7 +2,6 @@ import React, { PropsWithChildren } from 'react'; import TopLevelPageBreadcrumbs from '../../../../main/topLevelPages/topLevelPageBreadcrumbs/TopLevelPageBreadcrumbs'; import { AssignmentIndOutlined } from '@mui/icons-material'; import { useUrlParams } from '../../../../core/routing/useUrlParams'; -import { buildVCProfileUrl } from '../../../../main/routing/urlBuilders'; import TopLevelLayout from '../../../../main/ui/layout/TopLevelLayout'; import BreadcrumbsItem from '../../../../core/ui/navigation/BreadcrumbsItem'; import GroupOutlinedIcon from '@mui/icons-material/GroupOutlined'; @@ -34,7 +33,7 @@ const VCPageLayout = ({ ...props }: PropsWithChildren) => { loading={loading} avatar={data?.virtualContributor.profile.avatar} iconComponent={AssignmentIndOutlined} - uri={buildVCProfileUrl(vcNameId ?? '')} + uri={data?.virtualContributor.profile.url ?? ''} > {data?.virtualContributor.profile.displayName} diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx index bd4ee3e9d9..acf25b8ebc 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx @@ -8,8 +8,11 @@ import { useBodyOfKnowledgeProfileQuery, useVirtualContributorQuery, } from '../../../../core/apollo/generated/apollo-hooks'; +import { useTranslation } from 'react-i18next'; export const VCProfilePage = () => { + const { t } = useTranslation(); + const { vcNameId = '' } = useUrlParams(); const { data, loading, error } = useVirtualContributorQuery({ @@ -20,12 +23,15 @@ export const VCProfilePage = () => { const { data: bokProfile, loading: loadingBok } = useBodyOfKnowledgeProfileQuery({ variables: { - spaceId: data?.virtualContributor.bodyOfKnowledgeID || '', + spaceId: data?.virtualContributor.bodyOfKnowledgeID!, }, skip: !data?.virtualContributor.bodyOfKnowledgeID, }); - if (loading) return ; + if (loading) + return ( + + ); if (error) { return ( diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx index a5fbddd145..c0ba007fbb 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx @@ -8,14 +8,15 @@ import PageContentColumn from '../../../../core/ui/content/PageContentColumn'; import { VirtualContributorQuery } from '../../../../core/apollo/generated/graphql-schema'; import { BlockTitle, Text } from '../../../../core/ui/typography'; import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; -import HostCardClean from './HostCardClean'; +import HostCard from '../components/HostCard'; import useTheme from '@mui/material/styles/useTheme'; import { Trans, useTranslation } from 'react-i18next'; import ProfileDetail from '../../profile/ProfileDetail/ProfileDetail'; -import SpaceHorizontalCard, { BokProps } from './SpaceHorizontalCard'; +import BasicSpaceCard, { BasicSpaceProps } from '../components/BasicSpaceCard'; -interface Props extends BokProps { +interface Props { virtualContributor: VirtualContributorQuery['virtualContributor'] | undefined; + bokProfile?: BasicSpaceProps; showDefaults?: boolean; } @@ -48,7 +49,7 @@ export const VCProfilePageView: FC> = ({ aria-label="description" />
- +
@@ -58,7 +59,7 @@ export const VCProfilePageView: FC> = ({ - + diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index b40f8c6864..b3ee3d7598 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -13,8 +13,11 @@ import PageContentBlock from '../../../../core/ui/content/PageContentBlock'; import PageContent from '../../../../core/ui/content/PageContent'; import { useNotification } from '../../../../core/ui/notifications/useNotification'; import { StorageConfigContextProvider } from '../../../storage/StorageBucket/StorageConfigContext'; +import { useTranslation } from 'react-i18next'; export const VCSettingsPage = () => { + const { t } = useTranslation(); + const { vcNameId = '' } = useUrlParams(); const notify = useNotification(); @@ -27,7 +30,7 @@ export const VCSettingsPage = () => { const { data: bokProfile } = useBodyOfKnowledgeProfileQuery({ variables: { - spaceId: data?.virtualContributor.bodyOfKnowledgeID || '', + spaceId: data?.virtualContributor.bodyOfKnowledgeID!, }, skip: !data?.virtualContributor.bodyOfKnowledgeID, }); @@ -48,7 +51,12 @@ export const VCSettingsPage = () => { }); }; - if (loading) return ; + if (loading) + return ( + + ); return ( diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index d35f451720..62ee39a9e5 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -19,7 +19,7 @@ import { theme } from '../../../../core/ui/themes/default/Theme'; import GridContainer from '../../../../core/ui/grid/GridContainer'; import GridProvider from '../../../../core/ui/grid/GridProvider'; import GridItem from '../../../../core/ui/grid/GridItem'; -import { BokProps } from '../vcProfilePage/SpaceHorizontalCard'; +import { BasicSpaceProps } from '../components/BasicSpaceCard'; interface VirtualContributorProps { id: string; @@ -53,8 +53,9 @@ interface VirtualContributorFromProps { subSpaceName: string; } -interface Props extends BokProps { +interface Props { virtualContributor: VirtualContributorProps; + bokProfile?: BasicSpaceProps; avatar: Visual | undefined; onSave?: (virtualContributor: UpdateVirtualContributorInput) => void; title?: string; diff --git a/src/main/routing/urlBuilders.ts b/src/main/routing/urlBuilders.ts index 2c497f51d9..295ecd5188 100644 --- a/src/main/routing/urlBuilders.ts +++ b/src/main/routing/urlBuilders.ts @@ -11,8 +11,6 @@ export const buildSettingsUrl = (entityUrl: string) => { export const buildUserProfileUrl = (userNameId: string) => `/user/${userNameId}`; -export const buildVCProfileUrl = (vcNameId: string) => `/vc/${vcNameId}`; - export const buildUserProfileSettingsUrl = (userNameId: string) => `${buildUserProfileUrl(userNameId)}/settings/profile`; @@ -37,5 +35,3 @@ export const buildUpdatesUrl = (journeyLocation: string) => { export const buildAboutUrl = (journeyLocation: string | undefined) => { return journeyLocation && `${journeyLocation}/about`; }; - -export const buildVCProfileSettingsUrl = (nameID: string) => `/vc/${nameID}/settings/profile`; From 92ec36352d5054ef01dd0b4044978c48493fb135 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Fri, 31 May 2024 12:16:54 +0300 Subject: [PATCH 24/30] Create VC on Account init --- src/core/apollo/generated/apollo-hooks.ts | 119 ++++++++++++++++++ src/core/apollo/generated/graphql-schema.ts | 32 ++++- src/core/i18n/en/translation.en.json | 13 ++ .../pages/SpaceAccount/SpaceAccountView.tsx | 86 ++++++++++++- .../CreateVirtualContributorDialog.tsx | 77 ++++++++++++ .../SpaceSettings/VirtualContributor.graphql | 25 ++++ 6 files changed, 346 insertions(+), 6 deletions(-) create mode 100644 src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx create mode 100644 src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 3e63f7724f..db0846b1ad 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -17198,6 +17198,125 @@ export type UpdateSpaceSettingsMutationOptions = Apollo.BaseMutationOptions< SchemaTypes.UpdateSpaceSettingsMutation, SchemaTypes.UpdateSpaceSettingsMutationVariables >; +export const CreateVirtualContributorOnAccountDocument = gql` + mutation createVirtualContributorOnAccount($virtualContributorData: CreateVirtualContributorOnAccountInput!) { + createVirtualContributor(virtualContributorData: $virtualContributorData) { + id + } + } +`; +export type CreateVirtualContributorOnAccountMutationFn = Apollo.MutationFunction< + SchemaTypes.CreateVirtualContributorOnAccountMutation, + SchemaTypes.CreateVirtualContributorOnAccountMutationVariables +>; + +/** + * __useCreateVirtualContributorOnAccountMutation__ + * + * To run a mutation, you first call `useCreateVirtualContributorOnAccountMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useCreateVirtualContributorOnAccountMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [createVirtualContributorOnAccountMutation, { data, loading, error }] = useCreateVirtualContributorOnAccountMutation({ + * variables: { + * virtualContributorData: // value for 'virtualContributorData' + * }, + * }); + */ +export function useCreateVirtualContributorOnAccountMutation( + baseOptions?: Apollo.MutationHookOptions< + SchemaTypes.CreateVirtualContributorOnAccountMutation, + SchemaTypes.CreateVirtualContributorOnAccountMutationVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useMutation< + SchemaTypes.CreateVirtualContributorOnAccountMutation, + SchemaTypes.CreateVirtualContributorOnAccountMutationVariables + >(CreateVirtualContributorOnAccountDocument, options); +} + +export type CreateVirtualContributorOnAccountMutationHookResult = ReturnType< + typeof useCreateVirtualContributorOnAccountMutation +>; +export type CreateVirtualContributorOnAccountMutationResult = + Apollo.MutationResult; +export type CreateVirtualContributorOnAccountMutationOptions = Apollo.BaseMutationOptions< + SchemaTypes.CreateVirtualContributorOnAccountMutation, + SchemaTypes.CreateVirtualContributorOnAccountMutationVariables +>; +export const SpaceSubspacesDocument = gql` + query spaceSubspaces($spaceId: UUID_NAMEID!) { + space(ID: $spaceId) { + id + profile { + id + displayName + } + account { + id + } + subspaces { + id + profile { + id + displayName + } + } + } + } +`; + +/** + * __useSpaceSubspacesQuery__ + * + * To run a query within a React component, call `useSpaceSubspacesQuery` and pass it any options that fit your needs. + * When your component renders, `useSpaceSubspacesQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useSpaceSubspacesQuery({ + * variables: { + * spaceId: // value for 'spaceId' + * }, + * }); + */ +export function useSpaceSubspacesQuery( + baseOptions: Apollo.QueryHookOptions +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + SpaceSubspacesDocument, + options + ); +} + +export function useSpaceSubspacesLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + SpaceSubspacesDocument, + options + ); +} + +export type SpaceSubspacesQueryHookResult = ReturnType; +export type SpaceSubspacesLazyQueryHookResult = ReturnType; +export type SpaceSubspacesQueryResult = Apollo.QueryResult< + SchemaTypes.SpaceSubspacesQuery, + SchemaTypes.SpaceSubspacesQueryVariables +>; +export function refetchSpaceSubspacesQuery(variables: SchemaTypes.SpaceSubspacesQueryVariables) { + return { query: SpaceSubspacesDocument, variables: variables }; +} + export const SpaceDashboardNavigationChallengesDocument = gql` query SpaceDashboardNavigationChallenges($spaceId: UUID!) { lookup { diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index af5866a797..d94b426344 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -1748,7 +1748,7 @@ export type CreateVirtualPersonaInput = { /** A readable identifier, unique within the containing scope. */ nameID: Scalars['NameID']; profileData: CreateProfileInput; - prompt: Scalars['JSON']; + prompt?: InputMaybe; }; export type CreateWhiteboardInput = { @@ -5524,7 +5524,7 @@ export type UpdateVirtualPersonaInput = { nameID?: InputMaybe; /** The Profile of this entity. */ profileData?: InputMaybe; - prompt: Scalars['JSON']; + prompt?: InputMaybe; }; export type UpdateVisualInput = { @@ -21319,6 +21319,34 @@ export type UpdateSpaceSettingsMutation = { }; }; +export type CreateVirtualContributorOnAccountMutationVariables = Exact<{ + virtualContributorData: CreateVirtualContributorOnAccountInput; +}>; + +export type CreateVirtualContributorOnAccountMutation = { + __typename?: 'Mutation'; + createVirtualContributor: { __typename?: 'VirtualContributor'; id: string }; +}; + +export type SpaceSubspacesQueryVariables = Exact<{ + spaceId: Scalars['UUID_NAMEID']; +}>; + +export type SpaceSubspacesQuery = { + __typename?: 'Query'; + space: { + __typename?: 'Space'; + id: string; + profile: { __typename?: 'Profile'; id: string; displayName: string }; + account: { __typename?: 'Account'; id: string }; + subspaces: Array<{ + __typename?: 'Space'; + id: string; + profile: { __typename?: 'Profile'; id: string; displayName: string }; + }>; + }; +}; + export type SpaceDashboardNavigationChallengesQueryVariables = Exact<{ spaceId: Scalars['UUID']; }>; diff --git a/src/core/i18n/en/translation.en.json b/src/core/i18n/en/translation.en.json index ee0bb199d0..862e202c4c 100644 --- a/src/core/i18n/en/translation.en.json +++ b/src/core/i18n/en/translation.en.json @@ -1898,6 +1898,10 @@ "createSubspaces": "Create Subspaces: allow members to create Subspaces in this Space. If you deactivate this, you can still create Subspaces yourself and add other people as an admin inside the Subspace.", "inheritRights": "Allow Space members to contribute.", "supportAsAdmin": "Alkemio Support: Allow the Alkemio Support team to act as an admin in this Space." + }, + "account": { + "vc-section-title": "Virtual Contributors created from this Space", + "vc-create-button": "Create Virtual Contributor" } } }, @@ -2796,5 +2800,14 @@ } } } + }, + "virtualContributorDialog": { + "title": "Create a Virtual Contributor", + "name": "Name", + "info-text": "Select the Space or Subspace that you want to use as a body of knowledge for this Virtual Contributor", + "confirm-deletion": { + "title": "Confirm Virtual Contributor Deletion", + "description": "Are you certain you want to delete this Virtual Contributor? Keep in mind that this action is irreversible. All profile information will be removed and people will no longer be able to interact with the Virtual Contributor. " + } } } diff --git a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx index 729e0ca766..2311e55d5d 100644 --- a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx +++ b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx @@ -1,7 +1,9 @@ -import { FC, useState } from 'react'; +import { FC, useMemo, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; -import { Box, CircularProgress } from '@mui/material'; +import { Box, Button, CircularProgress } from '@mui/material'; +import ControlPointIcon from '@mui/icons-material/ControlPoint'; +import { v4 as uuidv4 } from 'uuid'; import { buildOrganizationUrl } from '../../../../../main/routing/urlBuilders'; import PageContent from '../../../../../core/ui/content/PageContent'; import PageContentBlock from '../../../../../core/ui/content/PageContentBlock'; @@ -11,18 +13,23 @@ import { BlockTitle, Caption } from '../../../../../core/ui/typography'; import { useNotification } from '../../../../../core/ui/notifications/useNotification'; import ContributorCardHorizontal from '../../../../../core/ui/card/ContributorCardHorizontal'; import Gutters from '../../../../../core/ui/grid/Gutters'; -import { AuthorizationPrivilege } from '../../../../../core/apollo/generated/graphql-schema'; +import { AuthorizationPrivilege, BodyOfKnowledgeType } from '../../../../../core/apollo/generated/graphql-schema'; import { - refetchAdminSpacesListQuery, + useCreateVirtualContributorOnAccountMutation, useDeleteSpaceMutation, + refetchAdminSpacesListQuery, useSpaceHostQuery, useSpacePrivilegesQuery, + useSpaceSubspacesQuery, } from '../../../../../core/apollo/generated/apollo-hooks'; import { gutters } from '../../../../../core/ui/grid/utils'; import { ROUTE_HOME } from '../../../../platform/routes/constants'; import { useSpace } from '../../SpaceContext/useSpace'; import { DeleteIcon } from '../SpaceSettings/icon/DeleteIcon'; import SpaceProfileDeleteDialog from '../SpaceSettings/SpaceProfileDeleteDialog'; +import CreateVirtualContributorDialog, { + VirtualContributorFormValues, +} from '../SpaceSettings/CreateVirtualContributorDialog'; interface SpaceAccountPageProps { journeyId: string; @@ -38,6 +45,9 @@ const SpaceAccountView: FC = ({ journeyId }) => { const [openDeleteDialog, setOpenDeleteDialog] = useState(false); const openDialog = () => setOpenDeleteDialog(true); const closeDialog = () => setOpenDeleteDialog(false); + const [isCreateVCDialogOpen, setIsCreateVCDialogOpen] = useState(false); + const openCreateVCDialog = () => setIsCreateVCDialogOpen(true); + const closeCreateVCDialog = () => setIsCreateVCDialogOpen(false); const { spaceId, spaceNameId, license } = useSpace(); @@ -75,6 +85,50 @@ const SpaceAccountView: FC = ({ journeyId }) => { }); }; + const { data: spaceData, loading: subspacesLoading } = useSpaceSubspacesQuery({ + variables: { + spaceId: spaceNameId, + }, + skip: !spaceNameId, + }); + + const subspaces = useMemo(() => { + const result = + spaceData?.space?.subspaces.map(subspace => ({ + id: subspace.id, + name: subspace?.profile.displayName, + })) ?? []; + + result.push({ + id: spaceId, + name: spaceData?.space?.profile.displayName || '', + }); + + return result; + }, [spaceData]); + + const [createVirtualContributorOnAccount, { loading: loadingVCCreation }] = + useCreateVirtualContributorOnAccountMutation(); + + const handleCreateVirtualContributor = async ({ displayName, bodyOfKnowledgeID }: VirtualContributorFormValues) => { + await createVirtualContributorOnAccount({ + variables: { + virtualContributorData: { + nameID: `v-c-${uuidv4()}`.slice(0, 25).toLocaleLowerCase(), + profileData: { + displayName, + }, + accountID: spaceData?.space.account.id ?? '', + bodyOfKnowledgeID, + bodyOfKnowledgeType: BodyOfKnowledgeType.Space, + }, + }, + }); + + notify('Virtual Contributor Created Successfully!', 'success'); + closeCreateVCDialog(); + }; + const ALKEMIO_DOMAIN = 'https://alkem.io/'; const loading = deletingSpace && spacePriviledgesLoading && hostOrganizationLoading; @@ -124,6 +178,23 @@ const SpaceAccountView: FC = ({ journeyId }) => { /> + + + {t('pages.admin.space.settings.account.vc-section-title')} + + + {canDelete && ( @@ -144,6 +215,13 @@ const SpaceAccountView: FC = ({ journeyId }) => { )} )} + {loading && ( {' '} diff --git a/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx b/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx new file mode 100644 index 0000000000..efd54311d8 --- /dev/null +++ b/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx @@ -0,0 +1,77 @@ +import { FC } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button, Dialog, DialogContent } from '@mui/material'; +import LoadingButton from '@mui/lab/LoadingButton'; +import DialogHeader from '../../../../../core/ui/dialog/DialogHeader'; +import Gutters from '../../../../../core/ui/grid/Gutters'; +import { Actions } from '../../../../../core/ui/actions/Actions'; +import { gutters } from '../../../../../core/ui/grid/utils'; +import { Form, Formik } from 'formik'; +import FormikInputField from '../../../../../core/ui/forms/FormikInputField/FormikInputField'; +import FormikSelect from '../../../../../core/ui/forms/FormikSelect'; +import useLoadingState from '../../../../shared/utils/useLoadingState'; + +export interface VirtualContributorFormValues { + displayName: string; + bodyOfKnowledgeID: string; +} + +interface CreateVirtualContributorDialogProps { + spaces: { name: string; id: string }[]; + open: boolean; + onClose: () => void; + onCreate: ({ bodyOfKnowledgeID, displayName }) => void; + submitting: boolean; +} + +const CreateVirtualContributorDialog: FC = ({ + spaces, + open, + onClose, + onCreate, + submitting, +}) => { + const { t } = useTranslation(); + + const initialValues = { + displayName: '', + spaces: [], + bodyOfKnowledgeID: '', + }; + + const [handleCreate, loading] = useLoadingState(async (values: VirtualContributorFormValues) => { + await onCreate?.({ + ...values, + }); + }); + + return ( + + + + + +
+ + + + + + {t('buttons.create')} + + + +
+
+
+
+ ); +}; + +export default CreateVirtualContributorDialog; diff --git a/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql b/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql new file mode 100644 index 0000000000..d588eace83 --- /dev/null +++ b/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql @@ -0,0 +1,25 @@ +mutation createVirtualContributorOnAccount($virtualContributorData: CreateVirtualContributorOnAccountInput!) { + createVirtualContributor(virtualContributorData: $virtualContributorData) { + id + } +} + +query spaceSubspaces($spaceId: UUID_NAMEID!) { + space (ID: $spaceId) { + id + profile { + id + displayName + } + account { + id + } + subspaces { + id + profile { + id + displayName + } + } + } +} \ No newline at end of file From d3c62be2887abaec64c3000ca1601f9f889faeae Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Fri, 31 May 2024 15:54:06 +0300 Subject: [PATCH 25/30] display vc --- src/core/apollo/generated/apollo-helpers.ts | 4 + src/core/apollo/generated/apollo-hooks.ts | 73 ++++++++++++++++++- src/core/apollo/generated/graphql-schema.ts | 55 +++++++++++--- .../pages/SpaceAccount/SpaceAccountView.tsx | 43 +++++++---- .../ContributorOnAccountCard.tsx | 47 ++++++++++++ .../CreateVirtualContributorDialog.tsx | 8 +- .../SpaceSettings/VirtualContributor.graphql | 28 ++++++- 7 files changed, 226 insertions(+), 32 deletions(-) create mode 100644 src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx diff --git a/src/core/apollo/generated/apollo-helpers.ts b/src/core/apollo/generated/apollo-helpers.ts index e262c658af..4ac324265e 100644 --- a/src/core/apollo/generated/apollo-helpers.ts +++ b/src/core/apollo/generated/apollo-helpers.ts @@ -5,6 +5,7 @@ export type APMFieldPolicy = { rumEnabled?: FieldPolicy | FieldReadFunction; }; export type AccountKeySpecifier = ( + | 'activeSubscription' | 'agent' | 'authorization' | 'defaults' @@ -14,9 +15,11 @@ export type AccountKeySpecifier = ( | 'license' | 'spaceID' | 'subscriptions' + | 'virtualContributors' | AccountKeySpecifier )[]; export type AccountFieldPolicy = { + activeSubscription?: FieldPolicy | FieldReadFunction; agent?: FieldPolicy | FieldReadFunction; authorization?: FieldPolicy | FieldReadFunction; defaults?: FieldPolicy | FieldReadFunction; @@ -26,6 +29,7 @@ export type AccountFieldPolicy = { license?: FieldPolicy | FieldReadFunction; spaceID?: FieldPolicy | FieldReadFunction; subscriptions?: FieldPolicy | FieldReadFunction; + virtualContributors?: FieldPolicy | FieldReadFunction; }; export type AccountSubscriptionKeySpecifier = ('expires' | 'name' | AccountSubscriptionKeySpecifier)[]; export type AccountSubscriptionFieldPolicy = { diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index db0846b1ad..296e99ea95 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -17199,9 +17199,13 @@ export type UpdateSpaceSettingsMutationOptions = Apollo.BaseMutationOptions< SchemaTypes.UpdateSpaceSettingsMutationVariables >; export const CreateVirtualContributorOnAccountDocument = gql` - mutation createVirtualContributorOnAccount($virtualContributorData: CreateVirtualContributorOnAccountInput!) { + mutation CreateVirtualContributorOnAccount($virtualContributorData: CreateVirtualContributorOnAccountInput!) { createVirtualContributor(virtualContributorData: $virtualContributorData) { id + profile { + id + url + } } } `; @@ -17249,8 +17253,59 @@ export type CreateVirtualContributorOnAccountMutationOptions = Apollo.BaseMutati SchemaTypes.CreateVirtualContributorOnAccountMutation, SchemaTypes.CreateVirtualContributorOnAccountMutationVariables >; +export const DeleteVirtualContributorOnAccountDocument = gql` + mutation DeleteVirtualContributorOnAccount($virtualContributorData: DeleteVirtualContributorInput!) { + deleteVirtualContributor(deleteData: $virtualContributorData) { + id + } + } +`; +export type DeleteVirtualContributorOnAccountMutationFn = Apollo.MutationFunction< + SchemaTypes.DeleteVirtualContributorOnAccountMutation, + SchemaTypes.DeleteVirtualContributorOnAccountMutationVariables +>; + +/** + * __useDeleteVirtualContributorOnAccountMutation__ + * + * To run a mutation, you first call `useDeleteVirtualContributorOnAccountMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteVirtualContributorOnAccountMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deleteVirtualContributorOnAccountMutation, { data, loading, error }] = useDeleteVirtualContributorOnAccountMutation({ + * variables: { + * virtualContributorData: // value for 'virtualContributorData' + * }, + * }); + */ +export function useDeleteVirtualContributorOnAccountMutation( + baseOptions?: Apollo.MutationHookOptions< + SchemaTypes.DeleteVirtualContributorOnAccountMutation, + SchemaTypes.DeleteVirtualContributorOnAccountMutationVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useMutation< + SchemaTypes.DeleteVirtualContributorOnAccountMutation, + SchemaTypes.DeleteVirtualContributorOnAccountMutationVariables + >(DeleteVirtualContributorOnAccountDocument, options); +} + +export type DeleteVirtualContributorOnAccountMutationHookResult = ReturnType< + typeof useDeleteVirtualContributorOnAccountMutation +>; +export type DeleteVirtualContributorOnAccountMutationResult = + Apollo.MutationResult; +export type DeleteVirtualContributorOnAccountMutationOptions = Apollo.BaseMutationOptions< + SchemaTypes.DeleteVirtualContributorOnAccountMutation, + SchemaTypes.DeleteVirtualContributorOnAccountMutationVariables +>; export const SpaceSubspacesDocument = gql` - query spaceSubspaces($spaceId: UUID_NAMEID!) { + query SpaceSubspaces($spaceId: UUID_NAMEID!) { space(ID: $spaceId) { id profile { @@ -17259,12 +17314,26 @@ export const SpaceSubspacesDocument = gql` } account { id + virtualContributors { + id + bodyOfKnowledgeID + profile { + displayName + url + avatar: visual(type: AVATAR) { + uri + } + } + } } subspaces { id profile { id displayName + avatar: visual(type: AVATAR) { + uri + } } } } diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index d94b426344..5c0f9e7a86 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -36,6 +36,8 @@ export type Apm = { export type Account = { __typename?: 'Account'; + /** The "highest" subscription active for this Account. */ + activeSubscription?: Maybe; /** The Agent representing this Account. */ agent: Agent; /** The authorization rules for the entity */ @@ -54,6 +56,8 @@ export type Account = { spaceID: Scalars['String']; /** The subscriptions active for this Account. */ subscriptions: Array; + /** The virtual contributors for this Account. */ + virtualContributors: Array; }; export type AccountAuthorizationResetInput = { @@ -66,7 +70,7 @@ export type AccountSubscription = { /** The expiry date of this subscription, null if it does never expire. */ expires?: Maybe; /** The name of the Subscription. */ - name: Scalars['String']; + name: LicenseCredential; }; export type ActivityCreatedSubscriptionInput = { @@ -758,6 +762,7 @@ export enum AuthorizationPrivilege { } export enum BodyOfKnowledgeType { + Other = 'OTHER', Space = 'SPACE', } @@ -1735,8 +1740,8 @@ export type CreateUserInput = { export type CreateVirtualContributorOnAccountInput = { accountID: Scalars['UUID']; - bodyOfKnowledgeID: Scalars['UUID']; - bodyOfKnowledgeType: BodyOfKnowledgeType; + bodyOfKnowledgeID?: InputMaybe; + bodyOfKnowledgeType?: InputMaybe; /** A readable identifier, unique within the containing scope. */ nameID: Scalars['NameID']; profileData: CreateProfileInput; @@ -5704,9 +5709,9 @@ export type VirtualContributor = Contributor & { /** The authorization rules for the Contributor */ authorization?: Maybe; /** The body of knowledge ID used for the Virtual Contributor */ - bodyOfKnowledgeID: Scalars['UUID']; + bodyOfKnowledgeID?: Maybe; /** The body of knowledge type used for the Virtual Contributor */ - bodyOfKnowledgeType: BodyOfKnowledgeType; + bodyOfKnowledgeType?: Maybe; /** The ID of the Contributor */ id: Scalars['UUID']; /** A name identifier of the Contributor, unique within a given scope. */ @@ -17329,7 +17334,7 @@ export type VirtualContributorQuery = { __typename?: 'VirtualContributor'; id: string; nameID: string; - bodyOfKnowledgeID: string; + bodyOfKnowledgeID?: string | undefined; authorization?: | { __typename?: 'Authorization'; id: string; myPrivileges?: Array | undefined } | undefined; @@ -21325,7 +21330,20 @@ export type CreateVirtualContributorOnAccountMutationVariables = Exact<{ export type CreateVirtualContributorOnAccountMutation = { __typename?: 'Mutation'; - createVirtualContributor: { __typename?: 'VirtualContributor'; id: string }; + createVirtualContributor: { + __typename?: 'VirtualContributor'; + id: string; + profile: { __typename?: 'Profile'; id: string; url: string }; + }; +}; + +export type DeleteVirtualContributorOnAccountMutationVariables = Exact<{ + virtualContributorData: DeleteVirtualContributorInput; +}>; + +export type DeleteVirtualContributorOnAccountMutation = { + __typename?: 'Mutation'; + deleteVirtualContributor: { __typename?: 'VirtualContributor'; id: string }; }; export type SpaceSubspacesQueryVariables = Exact<{ @@ -21338,11 +21356,30 @@ export type SpaceSubspacesQuery = { __typename?: 'Space'; id: string; profile: { __typename?: 'Profile'; id: string; displayName: string }; - account: { __typename?: 'Account'; id: string }; + account: { + __typename?: 'Account'; + id: string; + virtualContributors: Array<{ + __typename?: 'VirtualContributor'; + id: string; + bodyOfKnowledgeID?: string | undefined; + profile: { + __typename?: 'Profile'; + displayName: string; + url: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + }; + }>; + }; subspaces: Array<{ __typename?: 'Space'; id: string; - profile: { __typename?: 'Profile'; id: string; displayName: string }; + profile: { + __typename?: 'Profile'; + id: string; + displayName: string; + avatar?: { __typename?: 'Visual'; uri: string } | undefined; + }; }>; }; }; diff --git a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx index 2311e55d5d..47c00bb08a 100644 --- a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx +++ b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx @@ -30,6 +30,7 @@ import SpaceProfileDeleteDialog from '../SpaceSettings/SpaceProfileDeleteDialog' import CreateVirtualContributorDialog, { VirtualContributorFormValues, } from '../SpaceSettings/CreateVirtualContributorDialog'; +import ContributorOnAccountCard from '../SpaceSettings/ContributorOnAccountCard'; interface SpaceAccountPageProps { journeyId: string; @@ -85,7 +86,7 @@ const SpaceAccountView: FC = ({ journeyId }) => { }); }; - const { data: spaceData, loading: subspacesLoading } = useSpaceSubspacesQuery({ + const { data: spaceData, loading: spaceDataLoading } = useSpaceSubspacesQuery({ variables: { spaceId: spaceNameId, }, @@ -107,11 +108,19 @@ const SpaceAccountView: FC = ({ journeyId }) => { return result; }, [spaceData]); + const currentVirtualContributor = useMemo(() => { + if (spaceData?.space?.account?.id && spaceData?.space?.account?.virtualContributors) { + return spaceData?.space?.account?.virtualContributors[0]; + } + + return null; + }, [spaceData]); + const [createVirtualContributorOnAccount, { loading: loadingVCCreation }] = useCreateVirtualContributorOnAccountMutation(); const handleCreateVirtualContributor = async ({ displayName, bodyOfKnowledgeID }: VirtualContributorFormValues) => { - await createVirtualContributorOnAccount({ + const vsResponse = await createVirtualContributorOnAccount({ variables: { virtualContributorData: { nameID: `v-c-${uuidv4()}`.slice(0, 25).toLocaleLowerCase(), @@ -127,6 +136,7 @@ const SpaceAccountView: FC = ({ journeyId }) => { notify('Virtual Contributor Created Successfully!', 'success'); closeCreateVCDialog(); + navigate(vsResponse.data?.createVirtualContributor.profile.url ?? ''); }; const ALKEMIO_DOMAIN = 'https://alkem.io/'; @@ -181,18 +191,21 @@ const SpaceAccountView: FC = ({ journeyId }) => { {t('pages.admin.space.settings.account.vc-section-title')} - + {!currentVirtualContributor && !spaceDataLoading && ( + + )} + {currentVirtualContributor && } {canDelete && ( @@ -220,7 +233,7 @@ const SpaceAccountView: FC = ({ journeyId }) => { open={isCreateVCDialogOpen} onClose={closeCreateVCDialog} onCreate={handleCreateVirtualContributor} - submitting={loadingVCCreation || subspacesLoading} + submitting={loadingVCCreation || spaceDataLoading} /> {loading && ( diff --git a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx new file mode 100644 index 0000000000..8f564a04cf --- /dev/null +++ b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx @@ -0,0 +1,47 @@ +import { FC } from 'react'; +import BasicSpaceCard from '../../../../community/virtualContributor/components/BasicSpaceCard'; +import { DeleteIcon } from '../SpaceSettings/icon/DeleteIcon'; +import Gutters from '../../../../../core/ui/grid/Gutters'; +import { Button } from '@mui/material'; + +interface ContributorOnAccountCardProps { + contributor?: { + profile: { + displayName: string; + url: string; + avatar?: { + uri: string; + }; + }; + }; + space?: { + profile: { + displayName: string; + avatar?: { + uri: string; + }; + }; + }; +} + +const ContributorOnAccountCard: FC = ({ contributor, space }) => { + const spaceData = { + displayName: contributor?.profile.displayName ?? '', + url: contributor?.profile.url ? contributor?.profile.url + '/settings/profile' : '', + avatar: { + uri: contributor?.profile.avatar?.uri ?? '', + }, + tagline: space?.profile.displayName ?? '', + }; + + return ( + <> + + + + {currentVirtualContributor && ( + )} - {currentVirtualContributor && } +
{canDelete && ( @@ -226,15 +261,23 @@ const SpaceAccountView: FC = ({ journeyId }) => { submitting={deletingSpace} /> )} + + )} - {loading && ( {' '} diff --git a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx index 8f564a04cf..2cd1349a6c 100644 --- a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx +++ b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx @@ -1,8 +1,9 @@ import { FC } from 'react'; +import IconButton from '@mui/material/IconButton'; import BasicSpaceCard from '../../../../community/virtualContributor/components/BasicSpaceCard'; import { DeleteIcon } from '../SpaceSettings/icon/DeleteIcon'; import Gutters from '../../../../../core/ui/grid/Gutters'; -import { Button } from '@mui/material'; +import { buildSettingsUrl } from '../../../../../main/routing/urlBuilders'; interface ContributorOnAccountCardProps { contributor?: { @@ -22,12 +23,13 @@ interface ContributorOnAccountCardProps { }; }; }; + onDeleteClick: () => void; } -const ContributorOnAccountCard: FC = ({ contributor, space }) => { +const ContributorOnAccountCard: FC = ({ contributor, space, onDeleteClick }) => { const spaceData = { displayName: contributor?.profile.displayName ?? '', - url: contributor?.profile.url ? contributor?.profile.url + '/settings/profile' : '', + url: contributor?.profile.url ? buildSettingsUrl(contributor?.profile.url) : '', avatar: { uri: contributor?.profile.avatar?.uri ?? '', }, @@ -35,12 +37,15 @@ const ContributorOnAccountCard: FC = ({ contribut }; return ( - <> - - - void; onDelete: () => void; @@ -18,6 +20,7 @@ interface SpaceProfileDeleteDialogProps { const SpaceProfileDeleteDialog: FC = ({ entity, + description, open, onClose, onDelete, @@ -32,7 +35,9 @@ const SpaceProfileDeleteDialog: FC = ({ - {t('components.deleteSpace.confirmDialog.description', { entity: entity })} + + {t(description ?? 'components.deleteSpace.confirmDialog.description', { entity: entity })}{' '} + setChecked(!checked)} />} label={{t('components.deleteSpace.confirmDialog.checkbox', { entity: entity })}} diff --git a/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql b/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql index 172861de19..dbf173c0ff 100644 --- a/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql +++ b/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql @@ -25,6 +25,7 @@ query SpaceSubspaces($spaceId: UUID_NAMEID!) { id virtualContributors { id + nameID bodyOfKnowledgeID profile { displayName From 285f9da5cc2e3080a6c747c81616df2e8e1781f5 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Fri, 31 May 2024 19:42:26 +0300 Subject: [PATCH 27/30] vc card url to profile instead of profile's settings --- .../space/pages/SpaceSettings/ContributorOnAccountCard.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx index 2cd1349a6c..fada7e897f 100644 --- a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx +++ b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx @@ -3,7 +3,6 @@ import IconButton from '@mui/material/IconButton'; import BasicSpaceCard from '../../../../community/virtualContributor/components/BasicSpaceCard'; import { DeleteIcon } from '../SpaceSettings/icon/DeleteIcon'; import Gutters from '../../../../../core/ui/grid/Gutters'; -import { buildSettingsUrl } from '../../../../../main/routing/urlBuilders'; interface ContributorOnAccountCardProps { contributor?: { @@ -29,7 +28,7 @@ interface ContributorOnAccountCardProps { const ContributorOnAccountCard: FC = ({ contributor, space, onDeleteClick }) => { const spaceData = { displayName: contributor?.profile.displayName ?? '', - url: contributor?.profile.url ? buildSettingsUrl(contributor?.profile.url) : '', + url: contributor?.profile.url ? contributor?.profile.url : '', avatar: { uri: contributor?.profile.avatar?.uri ?? '', }, From c438a9d3f6dc40645e5d0f5e6567d0cec643a8b8 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Mon, 3 Jun 2024 10:26:55 +0300 Subject: [PATCH 28/30] vc create privilege check --- src/core/apollo/generated/apollo-helpers.ts | 6 ++++ src/core/apollo/generated/apollo-hooks.ts | 3 ++ src/core/apollo/generated/graphql-schema.ts | 34 +++++++++++++++++++ .../pages/SpaceAccount/SpaceAccountView.tsx | 22 +++++++----- .../ContributorOnAccountCard.tsx | 16 ++++++--- .../SpaceSettings/VirtualContributor.graphql | 3 ++ 6 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/core/apollo/generated/apollo-helpers.ts b/src/core/apollo/generated/apollo-helpers.ts index 4ef443cab0..d0e696f7ba 100644 --- a/src/core/apollo/generated/apollo-helpers.ts +++ b/src/core/apollo/generated/apollo-helpers.ts @@ -1599,6 +1599,7 @@ export type MutationKeySpecifier = ( | 'deleteCallout' | 'deleteCalloutTemplate' | 'deleteCollaboration' + | 'deleteCommunityGuidelinesTemplate' | 'deleteDiscussion' | 'deleteDocument' | 'deleteInnovationFlowTemplate' @@ -1660,6 +1661,7 @@ export type MutationKeySpecifier = ( | 'updateCalloutsSortOrder' | 'updateCommunityApplicationForm' | 'updateCommunityGuidelines' + | 'updateCommunityGuidelinesTemplate' | 'updateDiscussion' | 'updateDocument' | 'updateEcosystemModel' @@ -1757,6 +1759,7 @@ export type MutationFieldPolicy = { deleteCallout?: FieldPolicy | FieldReadFunction; deleteCalloutTemplate?: FieldPolicy | FieldReadFunction; deleteCollaboration?: FieldPolicy | FieldReadFunction; + deleteCommunityGuidelinesTemplate?: FieldPolicy | FieldReadFunction; deleteDiscussion?: FieldPolicy | FieldReadFunction; deleteDocument?: FieldPolicy | FieldReadFunction; deleteInnovationFlowTemplate?: FieldPolicy | FieldReadFunction; @@ -1818,6 +1821,7 @@ export type MutationFieldPolicy = { updateCalloutsSortOrder?: FieldPolicy | FieldReadFunction; updateCommunityApplicationForm?: FieldPolicy | FieldReadFunction; updateCommunityGuidelines?: FieldPolicy | FieldReadFunction; + updateCommunityGuidelinesTemplate?: FieldPolicy | FieldReadFunction; updateDiscussion?: FieldPolicy | FieldReadFunction; updateDocument?: FieldPolicy | FieldReadFunction; updateEcosystemModel?: FieldPolicy | FieldReadFunction; @@ -2020,6 +2024,7 @@ export type PlatformLocationsKeySpecifier = ( | 'releases' | 'security' | 'support' + | 'switchplan' | 'terms' | 'tips' | PlatformLocationsKeySpecifier @@ -2046,6 +2051,7 @@ export type PlatformLocationsFieldPolicy = { releases?: FieldPolicy | FieldReadFunction; security?: FieldPolicy | FieldReadFunction; support?: FieldPolicy | FieldReadFunction; + switchplan?: FieldPolicy | FieldReadFunction; terms?: FieldPolicy | FieldReadFunction; tips?: FieldPolicy | FieldReadFunction; }; diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index c91c3083d2..1e9b08ba18 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -17314,6 +17314,9 @@ export const SpaceSubspacesDocument = gql` } account { id + authorization { + myPrivileges + } virtualContributors { id nameID diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index d696f18367..b603f6ad54 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -1863,6 +1863,10 @@ export type DeleteCollaborationInput = { ID: Scalars['UUID']; }; +export type DeleteCommunityGuidelinesTemplateInput = { + ID: Scalars['UUID']; +}; + export type DeleteDiscussionInput = { ID: Scalars['UUID']; }; @@ -2794,6 +2798,8 @@ export type Mutation = { deleteCalloutTemplate: CalloutTemplate; /** Delete Collaboration. */ deleteCollaboration: Collaboration; + /** Deletes the specified CommunityGuidelines Template. */ + deleteCommunityGuidelinesTemplate: CommunityGuidelinesTemplate; /** Deletes the specified Discussion. */ deleteDiscussion: Discussion; /** Deletes the specified Document. */ @@ -2916,6 +2922,8 @@ export type Mutation = { updateCommunityApplicationForm: Community; /** Updates the CommunityGuidelines. */ updateCommunityGuidelines: CommunityGuidelines; + /** Updates the specified CommunityGuidelinesTemplate. */ + updateCommunityGuidelinesTemplate: CommunityGuidelinesTemplate; /** Updates the specified Discussion. */ updateDiscussion: Discussion; /** Updates the specified Document. */ @@ -3196,6 +3204,10 @@ export type MutationDeleteCollaborationArgs = { deleteData: DeleteCollaborationInput; }; +export type MutationDeleteCommunityGuidelinesTemplateArgs = { + deleteData: DeleteCommunityGuidelinesTemplateInput; +}; + export type MutationDeleteDiscussionArgs = { deleteData: DeleteDiscussionInput; }; @@ -3432,6 +3444,10 @@ export type MutationUpdateCommunityGuidelinesArgs = { communityGuidelinesData: UpdateCommunityGuidelinesInput; }; +export type MutationUpdateCommunityGuidelinesTemplateArgs = { + communityGuidelinesTemplateInput: UpdateCommunityGuidelinesTemplateInput; +}; + export type MutationUpdateDiscussionArgs = { updateData: UpdateDiscussionInput; }; @@ -3837,6 +3853,8 @@ export type PlatformLocations = { security: Scalars['String']; /** URL where users can get support for the platform */ support: Scalars['String']; + /** URL for the link Contact in the HomePage to switch between plans */ + switchplan: Scalars['String']; /** URL to the terms of usage for the platform */ terms: Scalars['String']; /** URL where users can get tips and tricks */ @@ -5190,6 +5208,19 @@ export type UpdateCommunityGuidelinesInput = { profile: UpdateProfileInput; }; +export type UpdateCommunityGuidelinesOfTemplateInput = { + /** The Profile for this community guidelines. */ + profile: UpdateProfileInput; +}; + +export type UpdateCommunityGuidelinesTemplateInput = { + ID: Scalars['UUID']; + /** The Community guidelines to associate with this template. */ + communityGuidelines?: InputMaybe; + /** The Profile of the Template. */ + profile?: InputMaybe; +}; + export type UpdateContextInput = { impact?: InputMaybe; vision?: InputMaybe; @@ -21371,6 +21402,9 @@ export type SpaceSubspacesQuery = { account: { __typename?: 'Account'; id: string; + authorization?: + | { __typename?: 'Authorization'; myPrivileges?: Array | undefined } + | undefined; virtualContributors: Array<{ __typename?: 'VirtualContributor'; id: string; diff --git a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx index 7a6acdbce1..1d529e4623 100644 --- a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx +++ b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx @@ -117,6 +117,9 @@ const SpaceAccountView: FC = ({ journeyId }) => { skip: !spaceNameId, }); + const accountPrivileges = spaceData?.space?.account.authorization?.myPrivileges ?? []; + const canCreateVirtualContributor = accountPrivileges?.includes(AuthorizationPrivilege.CreateVirtualContributor); + const subspaces = useMemo(() => { const result = spaceData?.space?.subspaces.map(subspace => ({ @@ -230,17 +233,20 @@ const SpaceAccountView: FC = ({ journeyId }) => { )} - + {canCreateVirtualContributor && ( + + )} {canDelete && ( diff --git a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx index fada7e897f..47ad42cb23 100644 --- a/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx +++ b/src/domain/journey/space/pages/SpaceSettings/ContributorOnAccountCard.tsx @@ -22,10 +22,16 @@ interface ContributorOnAccountCardProps { }; }; }; + hasDelete?: boolean; onDeleteClick: () => void; } -const ContributorOnAccountCard: FC = ({ contributor, space, onDeleteClick }) => { +const ContributorOnAccountCard: FC = ({ + contributor, + space, + hasDelete = false, + onDeleteClick, +}) => { const spaceData = { displayName: contributor?.profile.displayName ?? '', url: contributor?.profile.url ? contributor?.profile.url : '', @@ -41,9 +47,11 @@ const ContributorOnAccountCard: FC = ({ contribut sx={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', width: '100%' }} > - - - + {hasDelete && ( + + + + )} ); }; diff --git a/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql b/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql index dbf173c0ff..39440af497 100644 --- a/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql +++ b/src/domain/journey/space/pages/SpaceSettings/VirtualContributor.graphql @@ -23,6 +23,9 @@ query SpaceSubspaces($spaceId: UUID_NAMEID!) { } account { id + authorization { + myPrivileges + } virtualContributors { id nameID From 14210961f9c46b156012af8bd48c8111b7355610 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Mon, 3 Jun 2024 11:27:18 +0300 Subject: [PATCH 29/30] vc create form validation --- .../space/pages/SpaceAccount/SpaceAccountView.tsx | 1 + .../SpaceSettings/CreateVirtualContributorDialog.tsx | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx index 6fe74491e1..9f482e808c 100644 --- a/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx +++ b/src/domain/journey/space/pages/SpaceAccount/SpaceAccountView.tsx @@ -198,6 +198,7 @@ const SpaceAccountView: FC = ({ journeyId }) => { const vsResponse = await createVirtualContributorOnAccount({ variables: { virtualContributorData: { + // todo: guarantee uniqueness but use createNameId(displayName) nameID: `v-c-${uuidv4()}`.slice(0, 25).toLocaleLowerCase(), profileData: { displayName, diff --git a/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx b/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx index f586b25c69..771be0d7e5 100644 --- a/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx +++ b/src/domain/journey/space/pages/SpaceSettings/CreateVirtualContributorDialog.tsx @@ -2,6 +2,7 @@ import { FC } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, Dialog, DialogContent } from '@mui/material'; import LoadingButton from '@mui/lab/LoadingButton'; +import * as yup from 'yup'; import DialogHeader from '../../../../../core/ui/dialog/DialogHeader'; import Gutters from '../../../../../core/ui/grid/Gutters'; import { Actions } from '../../../../../core/ui/actions/Actions'; @@ -11,6 +12,7 @@ import FormikInputField from '../../../../../core/ui/forms/FormikInputField/Form import FormikSelect from '../../../../../core/ui/forms/FormikSelect'; import useLoadingState from '../../../../shared/utils/useLoadingState'; import { Caption } from '../../../../../core/ui/typography'; +import { nameSegmentSchema } from '../../../../platform/admin/components/Common/NameSegment'; export interface VirtualContributorFormValues { displayName: string; @@ -40,6 +42,11 @@ const CreateVirtualContributorDialog: FC = bodyOfKnowledgeID: '', }; + const validationSchema = yup.object().shape({ + displayName: nameSegmentSchema.fields?.name ?? yup.string(), + bodyOfKnowledgeID: yup.string().required(t('forms.validations.required')), + }); + const [handleCreate, loading] = useLoadingState(async (values: VirtualContributorFormValues) => { await onCreate?.({ ...values, @@ -50,14 +57,15 @@ const CreateVirtualContributorDialog: FC = - + - + {t('virtualContributorSpaceSettings.info-text')} From 9fe2e0fcdbf7cc902dcc5f58cf34a5e8a8f0d169 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Mon, 3 Jun 2024 12:15:14 +0300 Subject: [PATCH 30/30] pr fixes --- src/core/apollo/generated/apollo-hooks.ts | 4 ++ src/core/apollo/generated/graphql-schema.ts | 6 ++- src/core/i18n/en/translation.en.json | 2 +- .../VirtualContributor.graphql | 4 ++ .../components/HostCard.tsx | 2 +- .../vcProfilePage/VCProfilePage.tsx | 2 +- .../vcProfilePage/VCProfilePageView.tsx | 46 +++++++++---------- .../vcSettingsPage/VCSettingsPage.tsx | 2 +- .../vcSettingsPage/VirtualContributorForm.tsx | 32 ++++++------- 9 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 3198ad9b36..271df98663 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -14233,14 +14233,18 @@ export const BodyOfKnowledgeProfileDocument = gql` query BodyOfKnowledgeProfile($spaceId: UUID!) { lookup { space(ID: $spaceId) { + id profile { + id displayName tagline url avatar: visual(type: AVATAR) { + id uri } cardBanner: visual(type: CARD) { + id uri } } diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index 4bd3a68eba..8055867878 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -17502,13 +17502,15 @@ export type BodyOfKnowledgeProfileQuery = { space?: | { __typename?: 'Space'; + id: string; profile: { __typename?: 'Profile'; + id: string; displayName: string; tagline: string; url: string; - avatar?: { __typename?: 'Visual'; uri: string } | undefined; - cardBanner?: { __typename?: 'Visual'; uri: string } | undefined; + avatar?: { __typename?: 'Visual'; id: string; uri: string } | undefined; + cardBanner?: { __typename?: 'Visual'; id: string; uri: string } | undefined; }; } | undefined; diff --git a/src/core/i18n/en/translation.en.json b/src/core/i18n/en/translation.en.json index d5cb468156..9b626eac99 100644 --- a/src/core/i18n/en/translation.en.json +++ b/src/core/i18n/en/translation.en.json @@ -2459,7 +2459,7 @@ "help": "Credentials that the user holds issued by trusted parties" } }, - "virtual-contributor-profile": { + "virtualContributorProfile": { "title": "Virtual Contributor Profile", "default-name": "Alkemio Help", "description": "Description", diff --git a/src/domain/community/virtualContributor/VirtualContributor.graphql b/src/domain/community/virtualContributor/VirtualContributor.graphql index 1dd4fe9871..3b70faeb77 100644 --- a/src/domain/community/virtualContributor/VirtualContributor.graphql +++ b/src/domain/community/virtualContributor/VirtualContributor.graphql @@ -46,14 +46,18 @@ query VirtualContributor ($id: UUID_NAMEID!) { query BodyOfKnowledgeProfile($spaceId: UUID!) { lookup { space(ID: $spaceId) { + id profile { + id displayName tagline url avatar: visual(type: AVATAR) { + id uri } cardBanner: visual(type: CARD) { + id uri } } diff --git a/src/domain/community/virtualContributor/components/HostCard.tsx b/src/domain/community/virtualContributor/components/HostCard.tsx index 895fb4de53..c724646860 100644 --- a/src/domain/community/virtualContributor/components/HostCard.tsx +++ b/src/domain/community/virtualContributor/components/HostCard.tsx @@ -41,7 +41,7 @@ const HostCard: FC = ({ hostProfile }) => { return ( <> - + diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx index acf25b8ebc..2fa0c4bcbb 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePage.tsx @@ -30,7 +30,7 @@ export const VCProfilePage = () => { if (loading) return ( - + ); if (error) { diff --git a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx index 946b0caa81..dbf70f6a94 100644 --- a/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx +++ b/src/domain/community/virtualContributor/vcProfilePage/VCProfilePageView.tsx @@ -21,6 +21,14 @@ interface Props { showDefaults?: boolean; } +const SectionTitle = ({ children }) => ( + theme.spacing(1)}> + {children} + +); + +const SectionContent = ({ children }) => {children}; + export const VCProfilePageView: FC> = ({ virtualContributor, bokProfile, @@ -29,16 +37,7 @@ export const VCProfilePageView: FC> = ({ const theme = useTheme(); const { t } = useTranslation(); - const name = virtualContributor?.profile.displayName || t('pages.virtual-contributor-profile.default-name'); - - const SectionTitle = ({ children }) => ( - - {children} - - ); - const SectionContent = ({ children, withBottomOffset = false }) => ( - {children} - ); + const name = virtualContributor?.profile.displayName || t('pages.virtualContributorProfile.default-name'); return ( @@ -56,28 +55,29 @@ export const VCProfilePageView: FC> = ({ - {t('pages.virtual-contributor-profile.sections.knowledge.title')} + {t('pages.virtualContributorProfile.sections.knowledge.title')} - - - + + + - {t('pages.virtual-contributor-profile.sections.personality.title')} + {t('pages.virtualContributorProfile.sections.personality.title')} - - + + + - {t('pages.virtual-contributor-profile.sections.context.title')} + {t('pages.virtualContributorProfile.sections.context.title')} - + , li:
  • }} /> @@ -85,12 +85,12 @@ export const VCProfilePageView: FC> = ({ - {t('pages.virtual-contributor-profile.sections.privacy.title')} + {t('pages.virtualContributorProfile.sections.privacy.title')} - + , li:
  • }} /> diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx index b3ee3d7598..3ab991493f 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VCSettingsPage.tsx @@ -54,7 +54,7 @@ export const VCSettingsPage = () => { if (loading) return ( ); diff --git a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx index 98bbd52b91..0fe38978a4 100644 --- a/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx +++ b/src/domain/community/virtualContributor/vcSettingsPage/VirtualContributorForm.tsx @@ -2,7 +2,7 @@ import { Form, Formik } from 'formik'; import React, { FC } from 'react'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; -import { Box, Button, Theme, useMediaQuery } from '@mui/material'; +import { Box, Button } from '@mui/material'; import { LoadingButton } from '@mui/lab'; import { Tagset, UpdateVirtualContributorInput, Visual } from '../../../../core/apollo/generated/graphql-schema'; import useNavigate from '../../../../core/routing/useNavigate'; @@ -20,6 +20,7 @@ import GridContainer from '../../../../core/ui/grid/GridContainer'; import GridProvider from '../../../../core/ui/grid/GridProvider'; import GridItem from '../../../../core/ui/grid/GridItem'; import { BasicSpaceProps } from '../components/BasicSpaceCard'; +import { useColumns } from '../../../../core/ui/grid/GridContext'; interface VirtualContributorProps { id: string; @@ -70,7 +71,8 @@ export const VirtualContributorForm: FC = ({ const { t } = useTranslation(); const navigate = useNavigate(); const handleBack = () => navigate(-1); - const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('sm')); + const cols = useColumns(); + const isMobile = cols < 5; const { nameID, @@ -169,7 +171,7 @@ export const VirtualContributorForm: FC = ({ - + {avatar && ( = ({ )} - + - <> - - - {tagsets && } - - - {backButton} - - {t('buttons.save')} - - - + + + {tagsets && } + + + {backButton} + + {t('buttons.save')} + +