From 7f485bb93a729fb1687ee07bb4697202a6214b82 Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Thu, 9 Jan 2025 09:40:34 +0200 Subject: [PATCH 1/2] wip --- src/core/apollo/generated/apollo-helpers.ts | 2 + src/core/apollo/generated/apollo-hooks.ts | 6 + src/core/apollo/generated/graphql-schema.ts | 11 +- src/core/i18n/en/translation.en.json | 2 + src/core/ui/content/PageContentBlock.tsx | 1 + src/core/ui/content/PageContentColumn.tsx | 1 + src/core/ui/icon/RoundedIcon.tsx | 10 +- .../queries/AccountInformation.graphql | 6 + .../Account/ContributorAccountView.tsx | 198 ++++++++++++++---- .../CreateInnovationHubDialog.tsx | 13 +- 10 files changed, 205 insertions(+), 45 deletions(-) diff --git a/src/core/apollo/generated/apollo-helpers.ts b/src/core/apollo/generated/apollo-helpers.ts index 92c078466f..394327b0b3 100644 --- a/src/core/apollo/generated/apollo-helpers.ts +++ b/src/core/apollo/generated/apollo-helpers.ts @@ -8,6 +8,7 @@ export type AccountKeySpecifier = ( | 'agent' | 'authorization' | 'createdDate' + | 'externalSubscriptionID' | 'host' | 'id' | 'innovationHubs' @@ -25,6 +26,7 @@ export type AccountFieldPolicy = { agent?: FieldPolicy | FieldReadFunction; authorization?: FieldPolicy | FieldReadFunction; createdDate?: FieldPolicy | FieldReadFunction; + externalSubscriptionID?: FieldPolicy | FieldReadFunction; host?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; innovationHubs?: FieldPolicy | FieldReadFunction; diff --git a/src/core/apollo/generated/apollo-hooks.ts b/src/core/apollo/generated/apollo-hooks.ts index 525546adf7..4a08cb6389 100644 --- a/src/core/apollo/generated/apollo-hooks.ts +++ b/src/core/apollo/generated/apollo-hooks.ts @@ -5127,6 +5127,7 @@ export const AccountInformationDocument = gql` lookup { account(ID: $accountId) { id + externalSubscriptionID authorization { id myPrivileges @@ -5134,6 +5135,11 @@ export const AccountInformationDocument = gql` license { id availableEntitlements + entitlements { + type + limit + usage + } } host { id diff --git a/src/core/apollo/generated/graphql-schema.ts b/src/core/apollo/generated/graphql-schema.ts index f214762955..a52525a66f 100644 --- a/src/core/apollo/generated/graphql-schema.ts +++ b/src/core/apollo/generated/graphql-schema.ts @@ -41,6 +41,8 @@ export type Account = { authorization?: Maybe; /** The date at which the entity was created. */ createdDate?: Maybe; + /** The external subscription ID for this Account. */ + externalSubscriptionID?: Maybe; /** The Account host. */ host?: Maybe; /** The ID of the entity */ @@ -3619,7 +3621,7 @@ export type Mutation = { /** Create a test customer on wingback. */ adminWingbackCreateTestCustomer: Scalars['String']; /** Get wingback customer entitlements. */ - adminWingbackGetCustomerEntitlements: Scalars['String']; + adminWingbackGetCustomerEntitlements: Array; /** Reset the Authorization Policy on the specified AiServer. */ aiServerAuthorizationPolicyReset: AiServer; /** Creates a new AiPersonaService on the aiServer. */ @@ -8453,6 +8455,7 @@ export type AccountInformationQuery = { | { __typename?: 'Account'; id: string; + externalSubscriptionID?: string | undefined; authorization?: | { __typename?: 'Authorization'; id: string; myPrivileges?: Array | undefined } | undefined; @@ -8460,6 +8463,12 @@ export type AccountInformationQuery = { __typename?: 'License'; id: string; availableEntitlements?: Array | undefined; + entitlements: Array<{ + __typename?: 'LicenseEntitlement'; + type: LicenseEntitlementType; + limit: number; + usage: number; + }>; }; host?: | { __typename?: 'Organization'; id: string } diff --git a/src/core/i18n/en/translation.en.json b/src/core/i18n/en/translation.en.json index 22a6fd1e82..ee7be58cf7 100644 --- a/src/core/i18n/en/translation.en.json +++ b/src/core/i18n/en/translation.en.json @@ -1956,8 +1956,10 @@ "account": { "description": "Here you find all your Spaces, Virtual Contributors, and other hosted resources. If you have any questions, feel free to reach out to the Alkemio team.", "hostedSpaces": "Hosted Spaces", + "hostedSpacesNotice": "You've created {{usage}} out of your {{limit}} available Spaces in your account.", "virtualContributors": "Virtual Contributors", "innovationPacks": "$t(common.innovation-packs)", + "usageNotice": "You have created {{usage}} out of your {{limit}} available {{type}} in your account.", "noTemplates": "This Template Pack doesn't have any template yet", "customHomepages": "Custom Homepages", "hostTitle": "Host", diff --git a/src/core/ui/content/PageContentBlock.tsx b/src/core/ui/content/PageContentBlock.tsx index 3c004faba7..d817a27aa2 100644 --- a/src/core/ui/content/PageContentBlock.tsx +++ b/src/core/ui/content/PageContentBlock.tsx @@ -31,5 +31,6 @@ const PageContentBlock = forwardRef(({ ac ); }); +PageContentBlock.displayName = 'PageContentBlock'; export default PageContentBlock; diff --git a/src/core/ui/content/PageContentColumn.tsx b/src/core/ui/content/PageContentColumn.tsx index f97420b6fc..bfa62e99c8 100644 --- a/src/core/ui/content/PageContentColumn.tsx +++ b/src/core/ui/content/PageContentColumn.tsx @@ -16,5 +16,6 @@ const PageContentColumn = forwardRef(({ )); +PageContentColumn.displayName = 'PageContentColumn'; export default PageContentColumn; diff --git a/src/core/ui/icon/RoundedIcon.tsx b/src/core/ui/icon/RoundedIcon.tsx index 30c007dd52..bbedf74060 100644 --- a/src/core/ui/icon/RoundedIcon.tsx +++ b/src/core/ui/icon/RoundedIcon.tsx @@ -7,6 +7,7 @@ export type RoundedIconProps = Pick & Omit & { component: ComponentType; iconSize?: SvgIconProps['fontSize'] | 'xsmall'; + disabled?: boolean; }; const getFontSize = (theme: Theme) => (iconSize: SvgIconProps['fontSize'] | 'xsmall') => { @@ -15,8 +16,13 @@ const getFontSize = (theme: Theme) => (iconSize: SvgIconProps['fontSize'] | 'xsm } }; -const RoundedIcon = ({ size, iconSize = size, component: Icon, sx, ...containerProps }: RoundedIconProps) => ( - getFontSize(theme)(iconSize), ...sx }}> +const RoundedIcon = ({ size, iconSize = size, component: Icon, sx, disabled, ...containerProps }: RoundedIconProps) => ( + getFontSize(theme)(iconSize), ...sx }} + > ); diff --git a/src/domain/account/queries/AccountInformation.graphql b/src/domain/account/queries/AccountInformation.graphql index f0b86e1a73..cfc9334069 100644 --- a/src/domain/account/queries/AccountInformation.graphql +++ b/src/domain/account/queries/AccountInformation.graphql @@ -2,6 +2,7 @@ query AccountInformation($accountId: UUID!) { lookup { account(ID: $accountId) { id + externalSubscriptionID authorization { id myPrivileges @@ -9,6 +10,11 @@ query AccountInformation($accountId: UUID!) { license { id availableEntitlements + entitlements { + type + limit + usage + } } host { id diff --git a/src/domain/community/contributor/Account/ContributorAccountView.tsx b/src/domain/community/contributor/Account/ContributorAccountView.tsx index 08866309f8..da808284dd 100644 --- a/src/domain/community/contributor/Account/ContributorAccountView.tsx +++ b/src/domain/community/contributor/Account/ContributorAccountView.tsx @@ -1,11 +1,11 @@ -import { useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import AddIcon from '@mui/icons-material/Add'; -import { IconButton } from '@mui/material'; +import { Box, IconButton, Tooltip } from '@mui/material'; import { makeStyles } from '@mui/styles'; import PageContentColumn from '@/core/ui/content/PageContentColumn'; import PageContentBlock from '@/core/ui/content/PageContentBlock'; -import { BlockTitle } from '@/core/ui/typography'; +import { BlockTitle, Caption, Text } from '@/core/ui/typography'; import JourneyCardHorizontal, { JourneyCardHorizontalSkeleton, } from '@/domain/journey/common/JourneyCardHorizontal/JourneyCardHorizontal'; @@ -21,6 +21,7 @@ import useNewVirtualContributorWizard from '@/main/topLevelPages/myDashboard/new import CreateInnovationHubDialog from '@/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog'; import { AuthorizationPrivilege, + LicenseEntitlement, LicenseEntitlementType, SpaceLevel, SpaceType, @@ -60,10 +61,12 @@ interface AccountProfile { export interface AccountTabResourcesProps { id: string; + externalSubscriptionID?: string; authorization?: { myPrivileges?: AuthorizationPrivilege[] }; license?: { id: string; availableEntitlements?: LicenseEntitlementType[]; + entitlements?: Pick[]; }; spaces: { id: string; @@ -142,6 +145,12 @@ const useStyles = makeStyles(() => ({ justifyContent: 'space-between', height: '100%', }, + guttersRow: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + height: '100%', + }, })); export const ContributorAccountView = ({ accountHostName, account, loading }: ContributorAccountViewProps) => { @@ -154,6 +163,8 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co const [entity, setSelectedEntity] = useState(undefined); const styles = useStyles(); const myAccountEntitlements = account?.license?.availableEntitlements || []; + const myAccountEntitlementDetails = account?.license?.entitlements || []; + const externalSubscriptionID = account?.externalSubscriptionID; const isEntitledToCreateSpace = [ LicenseEntitlementType.AccountSpaceFree, @@ -175,22 +186,39 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co ); const privileges = account?.authorization?.myPrivileges ?? []; - const isPlatformAdmin = privileges.includes(AuthorizationPrivilege.PlatformAdmin); - - // Note: have information about whether it is the privilege or entitlement that blocks the enabling of the creation, give user more feedback. - const canCreateSpace = - privileges.includes(AuthorizationPrivilege.CreateSpace) && (isEntitledToCreateSpace || isPlatformAdmin); - const canCreateInnovationPack = - privileges.includes(AuthorizationPrivilege.CreateInnovationPack) && - (isEntitledToCreateInnovationPack || isPlatformAdmin); - const canCreateInnovationHub = - privileges.includes(AuthorizationPrivilege.CreateInnovationHub) && - (isEntitledToCreateInnovationHub || isPlatformAdmin); + // const isPlatformAdmin = privileges.includes(AuthorizationPrivilege.PlatformAdmin); + const isPlatformAdmin = false; + + const canCreateSpace = privileges.includes(AuthorizationPrivilege.CreateSpace) || isPlatformAdmin; + const canCreateInnovationPack = privileges.includes(AuthorizationPrivilege.CreateInnovationPack) || isPlatformAdmin; + const canCreateInnovationHub = privileges.includes(AuthorizationPrivilege.CreateInnovationHub) || isPlatformAdmin; const canCreateVirtualContributor = - privileges.includes(AuthorizationPrivilege.CreateVirtualContributor) && (isEntitledToCreateVC || isPlatformAdmin); + privileges.includes(AuthorizationPrivilege.CreateVirtualContributor) || isPlatformAdmin; const canDeleteEntities = privileges.includes(AuthorizationPrivilege.Delete); + const { limit: hostedSpaceLimit = 0, usage: hostedSpaceUsage = 0 } = + myAccountEntitlementDetails.find( + entitlement => + entitlement.type === LicenseEntitlementType.AccountSpaceFree || + entitlement.type === LicenseEntitlementType.AccountSpacePlus || + entitlement.type === LicenseEntitlementType.AccountSpacePremium + ) ?? {}; + + const { limit: vcLimit = 0, usage: vcUsage = 0 } = + myAccountEntitlementDetails.find( + entitlement => entitlement.type === LicenseEntitlementType.AccountVirtualContributor + ) ?? {}; + + const { limit: innovationPackLimit = 0, usage: innovationPackUsage = 0 } = + myAccountEntitlementDetails.find( + entitlement => entitlement.type === LicenseEntitlementType.AccountInnovationPack + ) ?? {}; + + const { limit: innovationHubLimit = 0, usage: innovationHubUsage = 0 } = + myAccountEntitlementDetails.find(entitlement => entitlement.type === LicenseEntitlementType.AccountInnovationHub) ?? + {}; + const clearDeleteState = () => { setDeleteDialogOpen(false); setSelectedEntity(undefined); @@ -396,7 +424,18 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co return ( - {t('pages.admin.generic.sections.account.hostedSpaces')} + + {t('pages.admin.generic.sections.account.hostedSpaces')} + + + {loading && } @@ -416,17 +455,18 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co ))} - + {canCreateSpace && ( <> - setCreateDialogOpen(true)} - > - - + tooltip={t('pages.admin.generic.sections.account.usageNotice', { + type: t('pages.admin.generic.sections.account.hostedSpaces'), + usage: hostedSpaceUsage, + limit: hostedSpaceLimit, + })} + /> {createDialogOpen && ( - {t('pages.admin.generic.sections.account.virtualContributors')} + + {t('pages.admin.generic.sections.account.virtualContributors')} + + {loading && } @@ -454,45 +504,73 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co /> ))} - + {canCreateVirtualContributor && ( - startWizard(account)} - > - - + tooltip={t('pages.admin.generic.sections.account.usageNotice', { + type: t('pages.admin.generic.sections.account.virtualContributors'), + usage: vcUsage, + limit: vcLimit, + })} + /> )} - {t('pages.admin.generic.sections.account.innovationPacks')} + + {t('pages.admin.generic.sections.account.innovationPacks')} + + {loading && } {!loading && innovationPacks?.map(pack => ( ))} - - {canCreateInnovationPack && account?.id && } + + {/*extract the buttons from the dialogs*/} + {canCreateInnovationPack && account?.id && ( + + )} - {t('pages.admin.generic.sections.account.customHomepages')} + + {t('pages.admin.generic.sections.account.customHomepages')} + + {loading && } {!loading && innovationHubs?.map(hub => ( ))} - + {canCreateInnovationHub && account?.id && ( - + )} @@ -506,8 +584,50 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co /> )} + {externalSubscriptionID && Wingback id: {externalSubscriptionID}} ); }; export default ContributorAccountView; + +const TextWithTooltip = ({ text, tooltip }: { text: string; tooltip: string }) => { + return ( + {tooltip}} placement="top"> + {text} + + ); +}; + +const CreationButton = ({ + tooltip, + disabled, + onClick, +}: { + tooltip: string; + onClick: () => void; + disabled?: boolean; +}) => { + const { t } = useTranslation(); + + const button = ( + + + + ); + + return disabled ? ( + + {button} + + ) : ( + { button } + ); +}; diff --git a/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx b/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx index 9d0690a35c..dee086226a 100644 --- a/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx +++ b/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx @@ -14,9 +14,10 @@ import { useNotification } from '@/core/ui/notifications/useNotification'; type CreateInnovationHubDialogProps = { accountId: string | undefined; accountHostName: string | undefined; + disabled?: boolean; }; -const CreateInnovationHubDialog = ({ accountId, accountHostName = '' }: CreateInnovationHubDialogProps) => { +const CreateInnovationHubDialog = ({ accountId, accountHostName = '', disabled }: CreateInnovationHubDialogProps) => { const { t } = useTranslation(); const notify = useNotification(); @@ -68,8 +69,14 @@ const CreateInnovationHubDialog = ({ accountId, accountHostName = '' }: CreateIn /> - setIsOpen(true)}> - + setIsOpen(true)} + disabled={disabled} + > + ); From 79bed2611d647f85b8da354f1b7e004a677c530a Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Thu, 9 Jan 2025 14:11:15 +0200 Subject: [PATCH 2/2] removed state from some dialogs --- src/core/i18n/en/translation.en.json | 9 +- src/core/ui/button/CreationButton.tsx | 41 +++++++ .../MarkdownInput/FormikMarkdownField.tsx | 3 + src/core/ui/typography/TextWithTooltip.tsx | 13 ++ .../CreateInnovationPackDialog.tsx | 47 +++++--- .../admin/InnovationPackForm.tsx | 7 +- .../Account/ContributorAccountView.tsx | 114 ++++++------------ .../CreateInnovationHubDialog.tsx | 53 ++++---- .../InnovationHubsAdmin/InnovationHubForm.tsx | 5 +- 9 files changed, 167 insertions(+), 125 deletions(-) create mode 100644 src/core/ui/button/CreationButton.tsx create mode 100644 src/core/ui/typography/TextWithTooltip.tsx diff --git a/src/core/i18n/en/translation.en.json b/src/core/i18n/en/translation.en.json index ee7be58cf7..00d059e41e 100644 --- a/src/core/i18n/en/translation.en.json +++ b/src/core/i18n/en/translation.en.json @@ -1956,10 +1956,10 @@ "account": { "description": "Here you find all your Spaces, Virtual Contributors, and other hosted resources. If you have any questions, feel free to reach out to the Alkemio team.", "hostedSpaces": "Hosted Spaces", - "hostedSpacesNotice": "You've created {{usage}} out of your {{limit}} available Spaces in your account.", "virtualContributors": "Virtual Contributors", "innovationPacks": "$t(common.innovation-packs)", "usageNotice": "You have created {{usage}} out of your {{limit}} available {{type}} in your account.", + "limitNotice": "Contact the Alkemio team to increase the limits on your account", "noTemplates": "This Template Pack doesn't have any template yet", "customHomepages": "Custom Homepages", "hostTitle": "Host", @@ -2163,7 +2163,12 @@ }, "back-button": "All $t(common.innovation-packs)", "save-new-for-details": "Save the new Template Pack to edit the rest of the details", - "saved-successfully": "Saved Successfully" + "saved-successfully": "Saved Successfully", + "notifications": { + "pack-created": "$t(common.innovation-pack) created successfuly.", + "pack-error": "An error occurred while creating the $t(common.innovation-pack).", + "pack-removed": "$t(common.innovation-pack) '{{name}}' removed successfully." + } }, "innovationHubs": { "create": "Create Innovation Hub", diff --git a/src/core/ui/button/CreationButton.tsx b/src/core/ui/button/CreationButton.tsx new file mode 100644 index 0000000000..9bd31c6645 --- /dev/null +++ b/src/core/ui/button/CreationButton.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Box, IconButton, Tooltip } from '@mui/material'; +import RoundedIcon from '@/core/ui/icon/RoundedIcon'; +import AddIcon from '@mui/icons-material/Add'; +import { Caption } from '@/core/ui/typography'; + +const CreationButton = ({ + disabledTooltip, + disabled, + onClick, +}: { + disabledTooltip: string; + onClick: () => void; + disabled?: boolean; +}) => { + const { t } = useTranslation(); + + const button = ( + + + + ); + + return disabled && disabledTooltip ? ( + {disabledTooltip}}> + {button} + + ) : ( + <>{button} + ); +}; + +export default CreationButton; diff --git a/src/core/ui/forms/MarkdownInput/FormikMarkdownField.tsx b/src/core/ui/forms/MarkdownInput/FormikMarkdownField.tsx index 2751ea331d..b479831385 100644 --- a/src/core/ui/forms/MarkdownInput/FormikMarkdownField.tsx +++ b/src/core/ui/forms/MarkdownInput/FormikMarkdownField.tsx @@ -46,6 +46,9 @@ const FilledDetector = ({ value }: { value: string | undefined }) => { return null; }; +/** + * Requires StorageConfigContextProvider + */ export const FormikMarkdownField = ({ title, name, diff --git a/src/core/ui/typography/TextWithTooltip.tsx b/src/core/ui/typography/TextWithTooltip.tsx new file mode 100644 index 0000000000..e1c76a1cc9 --- /dev/null +++ b/src/core/ui/typography/TextWithTooltip.tsx @@ -0,0 +1,13 @@ +import { Tooltip } from '@mui/material'; +import { Caption, Text } from '@/core/ui/typography/components'; +import React from 'react'; + +const TextWithTooltip = ({ text, tooltip }: { text: string; tooltip: string }) => { + return ( + {tooltip}} placement="top"> + {text} + + ); +}; + +export default TextWithTooltip; diff --git a/src/domain/InnovationPack/CreateInnovationPackDialog/CreateInnovationPackDialog.tsx b/src/domain/InnovationPack/CreateInnovationPackDialog/CreateInnovationPackDialog.tsx index 9596dcb635..54898f6ce3 100644 --- a/src/domain/InnovationPack/CreateInnovationPackDialog/CreateInnovationPackDialog.tsx +++ b/src/domain/InnovationPack/CreateInnovationPackDialog/CreateInnovationPackDialog.tsx @@ -1,17 +1,27 @@ -import { useState } from 'react'; import InnovationPackForm, { InnovationPackFormValues } from '../admin/InnovationPackForm'; // Assuming InnovationPackForm is in the same directory import DialogWithGrid from '@/core/ui/dialog/DialogWithGrid'; import { useTranslation } from 'react-i18next'; -import { DialogContent, IconButton } from '@mui/material'; +import { DialogContent } from '@mui/material'; import { useCreateInnovationPackMutation } from '@/core/apollo/generated/apollo-hooks'; import DialogHeader from '@/core/ui/dialog/DialogHeader'; import { BlockTitle } from '@/core/ui/typography'; -import AddIcon from '@mui/icons-material/Add'; -import RoundedIcon from '@/core/ui/icon/RoundedIcon'; +import { useNotification } from '@/core/ui/notifications/useNotification'; +import { StorageConfigContextProvider } from '@/domain/storage/StorageBucket/StorageConfigContext'; +import { useUserContext } from '@/domain/community/user'; -const CreateInnovationPackDialog = ({ accountId }: { accountId: string | undefined }) => { +const CreateInnovationPackDialog = ({ + accountId, + open = false, + onClose, +}: { + accountId: string | undefined; + open: boolean | undefined; + onClose?: () => void; +}) => { const { t } = useTranslation(); - const [isOpen, setIsOpen] = useState(false); + const notify = useNotification(); + const { user } = useUserContext(); + const userId = user?.user.id; const [createInnovationPack, { loading }] = useCreateInnovationPackMutation(); @@ -19,7 +29,7 @@ const CreateInnovationPackDialog = ({ accountId }: { accountId: string | undefin if (!accountId) { return; } - const { data } = await createInnovationPack({ + await createInnovationPack({ variables: { packData: { accountID: accountId, @@ -31,29 +41,32 @@ const CreateInnovationPackDialog = ({ accountId }: { accountId: string | undefin }, }, refetchQueries: ['AdminInnovationPacksList', 'AccountInformation', 'InnovationLibrary'], + onCompleted: () => { + notify(t('pages.admin.innovation-packs.notifications.pack-created'), 'success'); + onClose?.(); + }, + onError: () => { + notify(t('pages.admin.innovation-packs.notifications.pack-error'), 'error'); + }, }); - if (data?.createInnovationPack.nameID) { - setIsOpen(false); - } }; - if (!accountId) { + if (!accountId || !userId) { return null; } return ( <> - setIsOpen(false)} columns={6}> - setIsOpen(false)}> + + {t('pages.admin.innovation-packs.create')} - + + + - setIsOpen(true)}> - - ); }; diff --git a/src/domain/InnovationPack/admin/InnovationPackForm.tsx b/src/domain/InnovationPack/admin/InnovationPackForm.tsx index 7a0723eb5c..9fcdfc8f12 100644 --- a/src/domain/InnovationPack/admin/InnovationPackForm.tsx +++ b/src/domain/InnovationPack/admin/InnovationPackForm.tsx @@ -45,7 +45,9 @@ type InnovationPackFormProps = { loading?: boolean; onSubmit: (formData: InnovationPackFormValues) => void; }; - +/** + * Requires StorageConfigContextProvider + */ const InnovationPackForm = ({ isNew = false, nameID, @@ -116,6 +118,7 @@ const InnovationPackForm = ({ )} {t('pages.admin.innovation-packs.save-new-for-details')} )} - + handleSubmit()} /> diff --git a/src/domain/community/contributor/Account/ContributorAccountView.tsx b/src/domain/community/contributor/Account/ContributorAccountView.tsx index da808284dd..4aef8d2d4d 100644 --- a/src/domain/community/contributor/Account/ContributorAccountView.tsx +++ b/src/domain/community/contributor/Account/ContributorAccountView.tsx @@ -1,11 +1,9 @@ import React, { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import AddIcon from '@mui/icons-material/Add'; -import { Box, IconButton, Tooltip } from '@mui/material'; import { makeStyles } from '@mui/styles'; import PageContentColumn from '@/core/ui/content/PageContentColumn'; import PageContentBlock from '@/core/ui/content/PageContentBlock'; -import { BlockTitle, Caption, Text } from '@/core/ui/typography'; +import { BlockTitle, Caption } from '@/core/ui/typography'; import JourneyCardHorizontal, { JourneyCardHorizontalSkeleton, } from '@/domain/journey/common/JourneyCardHorizontal/JourneyCardHorizontal'; @@ -15,7 +13,6 @@ import InnovationHubCardHorizontal, { InnovationHubCardHorizontalSkeleton, } from '@/domain/innovationHub/InnovationHubCardHorizontal/InnovationHubCardHorizontal'; import { Actions } from '@/core/ui/actions/Actions'; -import RoundedIcon from '@/core/ui/icon/RoundedIcon'; import CreateSpaceDialog from '@/domain/journey/space/createSpace/CreateSpaceDialog'; import useNewVirtualContributorWizard from '@/main/topLevelPages/myDashboard/newVirtualContributorWizard/useNewVirtualContributorWizard'; import CreateInnovationHubDialog from '@/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog'; @@ -35,6 +32,8 @@ import { useDeleteSpaceMutation, useDeleteVirtualContributorOnAccountMutation, } from '@/core/apollo/generated/apollo-hooks'; +import CreationButton from '@/core/ui/button/CreationButton'; +import TextWithTooltip from '@/core/ui/typography/TextWithTooltip'; import { useNotification } from '@/core/ui/notifications/useNotification'; import EntityConfirmDeleteDialog from '@/domain/journey/space/pages/SpaceSettings/EntityConfirmDeleteDialog'; import InnovationPackCardHorizontal, { @@ -149,7 +148,6 @@ const useStyles = makeStyles(() => ({ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', - height: '100%', }, })); @@ -157,7 +155,9 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co const { t } = useTranslation(); const notify = useNotification(); const { startWizard, NewVirtualContributorWizard } = useNewVirtualContributorWizard(); - const [createDialogOpen, setCreateDialogOpen] = useState(false); + const [createSpaceDialogOpen, setCreateSpaceDialogOpen] = useState(false); + const [createInnovationHubDialogOpen, setCreateInnovationHubDialogOpen] = useState(false); + const [createInnovationPackDialogOpen, setCreateInnovationPackDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [selectedId, setSelectedId] = useState(undefined); const [entity, setSelectedEntity] = useState(undefined); @@ -186,14 +186,11 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co ); const privileges = account?.authorization?.myPrivileges ?? []; - // const isPlatformAdmin = privileges.includes(AuthorizationPrivilege.PlatformAdmin); - const isPlatformAdmin = false; - const canCreateSpace = privileges.includes(AuthorizationPrivilege.CreateSpace) || isPlatformAdmin; - const canCreateInnovationPack = privileges.includes(AuthorizationPrivilege.CreateInnovationPack) || isPlatformAdmin; - const canCreateInnovationHub = privileges.includes(AuthorizationPrivilege.CreateInnovationHub) || isPlatformAdmin; - const canCreateVirtualContributor = - privileges.includes(AuthorizationPrivilege.CreateVirtualContributor) || isPlatformAdmin; + const canCreateSpace = privileges.includes(AuthorizationPrivilege.CreateSpace); + const canCreateInnovationPack = privileges.includes(AuthorizationPrivilege.CreateInnovationPack); + const canCreateInnovationHub = privileges.includes(AuthorizationPrivilege.CreateInnovationHub); + const canCreateVirtualContributor = privileges.includes(AuthorizationPrivilege.CreateVirtualContributor); const canDeleteEntities = privileges.includes(AuthorizationPrivilege.Delete); @@ -460,17 +457,13 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co <> setCreateDialogOpen(true)} - tooltip={t('pages.admin.generic.sections.account.usageNotice', { - type: t('pages.admin.generic.sections.account.hostedSpaces'), - usage: hostedSpaceUsage, - limit: hostedSpaceLimit, - })} + onClick={() => setCreateSpaceDialogOpen(true)} + disabledTooltip={t('pages.admin.generic.sections.account.limitNotice')} /> - {createDialogOpen && ( + {createSpaceDialogOpen && ( setCreateDialogOpen(false)} + onClose={() => setCreateSpaceDialogOpen(false)} account={{ id: account?.id, name: accountHostName }} /> )} @@ -509,11 +502,7 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co startWizard(account)} - tooltip={t('pages.admin.generic.sections.account.usageNotice', { - type: t('pages.admin.generic.sections.account.virtualContributors'), - usage: vcUsage, - limit: vcLimit, - })} + disabledTooltip={t('pages.admin.generic.sections.account.limitNotice')} /> )} @@ -539,9 +528,19 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co ))} - {/*extract the buttons from the dialogs*/} {canCreateInnovationPack && account?.id && ( - + <> + setCreateInnovationPackDialogOpen(true)} + disabledTooltip={t('pages.admin.generic.sections.account.limitNotice')} + /> + setCreateInnovationPackDialogOpen(false)} + /> + )} @@ -566,11 +565,19 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co ))} {canCreateInnovationHub && account?.id && ( - + <> + setCreateInnovationHubDialogOpen(true)} + disabledTooltip={t('pages.admin.generic.sections.account.limitNotice')} + /> + setCreateInnovationHubDialogOpen(false)} + /> + )} @@ -590,44 +597,3 @@ export const ContributorAccountView = ({ accountHostName, account, loading }: Co }; export default ContributorAccountView; - -const TextWithTooltip = ({ text, tooltip }: { text: string; tooltip: string }) => { - return ( - {tooltip}} placement="top"> - {text} - - ); -}; - -const CreationButton = ({ - tooltip, - disabled, - onClick, -}: { - tooltip: string; - onClick: () => void; - disabled?: boolean; -}) => { - const { t } = useTranslation(); - - const button = ( - - - - ); - - return disabled ? ( - - {button} - - ) : ( - { button } - ); -}; diff --git a/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx b/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx index dee086226a..be020c9f5e 100644 --- a/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx +++ b/src/domain/innovationHub/CreateInnovationHub/CreateInnovationHubDialog.tsx @@ -1,28 +1,32 @@ -import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { DialogContent, IconButton } from '@mui/material'; -import AddIcon from '@mui/icons-material/Add'; +import { DialogContent } from '@mui/material'; import DialogWithGrid from '@/core/ui/dialog/DialogWithGrid'; import DialogHeader from '@/core/ui/dialog/DialogHeader'; import { BlockTitle } from '@/core/ui/typography'; -import RoundedIcon from '@/core/ui/icon/RoundedIcon'; import InnovationHubForm, { InnovationHubFormValues } from '../InnovationHubsAdmin/InnovationHubForm'; import { useCreateInnovationHubMutation } from '@/core/apollo/generated/apollo-hooks'; import { InnovationHubType } from '@/core/apollo/generated/graphql-schema'; import { useNotification } from '@/core/ui/notifications/useNotification'; +import { useUserContext } from '@/domain/community/user'; +import { StorageConfigContextProvider } from '@/domain/storage/StorageBucket/StorageConfigContext'; type CreateInnovationHubDialogProps = { accountId: string | undefined; accountHostName: string | undefined; - disabled?: boolean; + open: boolean | undefined; + onClose?: () => void; }; -const CreateInnovationHubDialog = ({ accountId, accountHostName = '', disabled }: CreateInnovationHubDialogProps) => { +const CreateInnovationHubDialog = ({ + accountId, + accountHostName = '', + open = false, + onClose, +}: CreateInnovationHubDialogProps) => { const { t } = useTranslation(); - const notify = useNotification(); - - const [isOpen, setIsOpen] = useState(false); + const { user } = useUserContext(); + const userId = user?.user.id; const [createInnovationHub, { loading }] = useCreateInnovationHubMutation(); @@ -45,39 +49,32 @@ const CreateInnovationHubDialog = ({ accountId, accountHostName = '', disabled } refetchQueries: ['AdminInnovationHubsList', 'AccountInformation'], onCompleted: () => { notify(t('pages.admin.innovationHubs.success'), 'success'); - setIsOpen(false); + onClose?.(); }, }); }; - if (!accountId) { + if (!accountId || !userId) { return null; } return ( <> - setIsOpen(false)} columns={6}> - setIsOpen(false)}> + + {t('pages.admin.innovationHubs.create')} - + + + - setIsOpen(true)} - disabled={disabled} - > - - ); }; diff --git a/src/domain/innovationHub/InnovationHubsAdmin/InnovationHubForm.tsx b/src/domain/innovationHub/InnovationHubsAdmin/InnovationHubForm.tsx index b8aac9181d..8d7c1eaed5 100644 --- a/src/domain/innovationHub/InnovationHubsAdmin/InnovationHubForm.tsx +++ b/src/domain/innovationHub/InnovationHubsAdmin/InnovationHubForm.tsx @@ -91,7 +91,7 @@ const InnovationHubForm = ({ {({ values: { profile }, errors, handleSubmit }) => { return ( - + {!isNew && profileId ? ( @@ -135,7 +136,7 @@ const InnovationHubForm = ({ {t('pages.admin.innovationHubs.saveForMoreDetails')} )} - + 0}