import { Injectable } from '@angular/core'; import { ClientSettingsPages } from '@core/typings/brand.typing'; import { AdminUserPermissions } from '@core/typings/user.typing'; import { ClientSettingsService } from '@features/client-settings/client-settings.service'; import { UserService } from '@features/users/user.service'; import { ArrayHelpersService, CardItem } from '@yourcause/common'; import { PolicyService } from './policy.service'; export enum CardPageTypes { PROGRAM = 1, SETTINGS = 2, INSIGHTS = 3, ADMIN_SETTINGS = 4, CLIENT_MANAGEMENT = 5, PRODUCT_MANAGEMENT = 6 } @Injectable({ providedIn: 'root' }) export class CardsService { constructor ( private arrayHelper: ArrayHelpersService, private policyService: PolicyService, private clientSettingsService: ClientSettingsService, private userService: UserService ) { } get adminPermissions () { return this.userService.adminPermissions; } getCardsByType (pageType: CardPageTypes) { let cardsArray: CardItem[][]; switch (pageType) { case CardPageTypes.SETTINGS: cardsArray = this.getConfigurationPageCards(); break; case CardPageTypes.PROGRAM: cardsArray = this.getProgramSetupPageCards(); break; case CardPageTypes.INSIGHTS: cardsArray = this.getInsightsPageCards(); break; case CardPageTypes.ADMIN_SETTINGS: cardsArray = this.getAdminSettingsPageCards(); break; case CardPageTypes.CLIENT_MANAGEMENT: cardsArray = this.getClientManagementPageCards(); break; case CardPageTypes.PRODUCT_MANAGEMENT: cardsArray = this.getProductManagementPageCards(); break; } return cardsArray; } canSeePage (pageType: CardPageTypes) { let cardsArray: CardItem[][]; switch (pageType) { case CardPageTypes.SETTINGS: cardsArray = this.getConfigurationPageCards(); break; case CardPageTypes.PROGRAM: cardsArray = this.getProgramSetupPageCards(); break; case CardPageTypes.INSIGHTS: cardsArray = this.getInsightsPageCards(); break; case CardPageTypes.ADMIN_SETTINGS: cardsArray = this.getAdminSettingsPageCards(); break; case CardPageTypes.CLIENT_MANAGEMENT: cardsArray = this.getClientManagementPageCards(); break; case CardPageTypes.PRODUCT_MANAGEMENT: cardsArray = this.getProductManagementPageCards(); break; } return cardsArray.some((cards) => { return cards.some((card) => { return !card.disabled; }); }); } getConfigurationPageCards (): CardItem[][] { const canManageUsers = this.policyService.system.canManageUsers(); const canManageClientSettings = this.policyService.system.canManageClientSettings(); const canManageEmails = this.policyService.system.canManageEmails(); const canManageTags = this.policyService.system.canManageTags(); const canManageInKind = this.policyService.system.canManageInKind(); const canManageDocumentTemplates = this.policyService.system.canManageDocumentTemplates(); const canManageSFTPConnections = this.policyService.system.canManageSFTPConnections(); const hasSSO = this.clientSettingsService.clientSettings.hasSSO; const canConfigureWebServices = this.clientSettingsService.clientSettings.canConfigureWebservices; const allowExternalApis = this.clientSettingsService.clientSettings.allowExternalApis; const externalApiRoute = canConfigureWebServices ? '/management/configure/external-api/inbound' : '/management/configure/external-api/outbound'; const firstSet: CardItem[] = [{ title: 'Client Settings', description: 'Setup your logo, colors, currencies, and languages.', i18nTitleKey: 'common:hdrClientSettings', i18nDescriptionKey: 'CONFIG.textClientSettingsDescription', href: `/management/configure/client-settings/${ClientSettingsPages.COLORS}`, icon: 'edit', disabled: !canManageClientSettings }, { title: 'Document Templates', description: 'Create document templates using system information for use in the merge process.', i18nTitleKey: 'CONFIG:hdrDocumentTemplates', i18nDescriptionKey: 'CONFIG:textDocumentTemplatesDesc', href: '/management/configure/document-templates', icon: 'file-alt', disabled: !canManageDocumentTemplates }, hasSSO ? { title: 'Employee SSO Field Configuration', description: 'Map HR column names', i18nTitleKey: 'CONFIG:hdrEmployeeSSOFieldConfiguration', i18nDescriptionKey: 'CONFIG:textCustomColumnConfigDescription', href: '/management/configure/employee-sso-fields', icon: 'columns', disabled: !canManageClientSettings } : null, { title: 'In Kind', description: 'Import and create in-kind categories and items', i18nTitleKey: 'GLOBAL:hdrInKind', i18nDescriptionKey: 'CONFIG:textInKindDescription', href: '/management/configure/in-kind', icon: 'gift', disabled: !canManageInKind }, { title: 'System Emails', description: 'Manage emails sent from GrantsConnect', i18nTitleKey: 'GLOBAL:hdrSystemEmails', i18nDescriptionKey: 'CONFIG.SYSTEM_EMAILS_DESC', href: '/management/configure/system-emails', icon: 'envelope', disabled: !canManageEmails }, { title: 'System Tags', description: 'Create tags that can be used throughout GrantsConnect', i18nTitleKey: 'common:SYSTEM_TAGS', i18nDescriptionKey: 'CONFIG.SYSTEM_TAGS_DESC', href: '/management/configure/system-tags', icon: 'tag', disabled: !canManageTags }].filter((item) => !!item); const secondSet: CardItem[] = [{ title: 'Roles and Permissions', description: 'Create permissions based roles and assign users.', i18nTitleKey: 'common:ROLES_PERMISSIONS', i18nDescriptionKey: 'CONFIG.ROLES_PERMISSIONS_DESC', href: '/management/configure/roles', icon: 'lock', disabled: !canManageUsers }, { title: 'Users', description: 'Invite and manage users for this account.', i18nTitleKey: 'GLOBAL:textUsers', i18nDescriptionKey: 'CONFIG.MANAGE_ADMINS_DESC', href: '/management/configure/users', icon: 'user', disabled: !canManageUsers }, { title: 'Audiences', description: 'Designate audiences made up of internal and external individuals', i18nTitleKey: 'CONFIG:hdrAudiences', i18nDescriptionKey: 'CONFIG:textAudiencesDesc', href: '/management/configure/audiences', icon: 'users', disabled: !canManageClientSettings }]; const thirdSet: CardItem[] = [ { title: 'SFTP Connections', description: 'Secure your data exports with SFTP connections', i18nTitleKey: 'common:SFTPConnections', i18nDescriptionKey: 'CONFIG:textSFTPCredentialsDesc', href: '/management/configure/sftp-connections', icon: 'file-upload', disabled: !canManageClientSettings || !canManageSFTPConnections }, { title: 'Accounts Payable Configuration', description: 'Configure destination and headers for AP integration exports', i18nTitleKey: 'common:hdrAPConfiguration', i18nDescriptionKey: 'CONFIG:APConfigDescription', href: '/management/configure/ap-configuration', icon: 'file-invoice-dollar', disabled: !canManageClientSettings || !this.clientSettingsService.clientSettings.apEnabled }, { title: 'API Configuration', description: 'Use external APIs to load form field custom data and connect to GrantsConnect APIs to get and update data', i18nTitleKey: 'CONFIG:hdrApiConfiguration', i18nDescriptionKey: 'CONFIG:textExternalAPIConfigDescription2', href: externalApiRoute, icon: 'cloud', disabled: !canManageClientSettings || !(canConfigureWebServices || allowExternalApis) }]; return [ this.arrayHelper.sort(firstSet, 'title'), this.arrayHelper.sort(secondSet, 'title'), this.arrayHelper.sort(thirdSet, 'title') ]; } getProgramSetupPageCards (): CardItem[][] { const canManageWorkflows = this.policyService.system.canManageWorkflows(); const canManageFundingSources = this.policyService.system.canManageFundingSources(); const canManageBudgets = this.policyService.system.canManageBudgets(); const canManageForms = this.policyService.system.canManageForms(); const canManagePrograms = this.policyService.grantProgram.canManagePrograms(); const hasNominations = this.userService.user?.clientHasNominations; const canManageAutomation = this.policyService.system.canManageWorkflowAutomation(); const canManageInvitations = this.policyService.system.canManageInvitations(); const setupItems: CardItem[] = [{ title: 'Grant Programs', description: 'Setup your grant programs', i18nTitleKey: 'common:MANAGE_PROGRAMS', i18nDescriptionKey: 'CONFIG.MANAGE_PROGRAMS_DESC', href: '/management/program-setup/programs/all', icon: 'rocket', disabled: !canManagePrograms }, { title: 'Nomination Programs', description: 'Set up your nomination programs', i18nTitleKey: 'common:textNominationPrograms', i18nDescriptionKey: 'CONFIG:textNominationProgramsDesc', href: '/management/program-setup/nomination-programs/all', icon: 'badge', disabled: !canManagePrograms || !hasNominations }]; const configItems: CardItem[] = [{ title: 'Budgets', description: 'Create budgets that connect to your funding sources.', i18nTitleKey: 'GLOBAL:textBudgets', i18nDescriptionKey: 'CONFIG.MANAGE_BUDGETS_DESC', href: '/management/program-setup/budgets', icon: 'usd-circle', disabled: !canManageBudgets }, { title: 'Custom Forms', description: 'Create and manage forms to use in your Grant Programs.', i18nTitleKey: 'GLOBAL:textCustomForms', i18nDescriptionKey: 'CONFIG.MANAGE_FORMS_DESC', href: '/management/program-setup/forms', icon: 'file-check', disabled: !canManageForms }, { title: 'Funding Sources', description: 'Cash or In-kind sources to attach to your budgets.', i18nTitleKey: 'GLOBAL:textFundingSources', i18nDescriptionKey: 'CONFIG.MANAGE_FUNDING_DESC', href: '/management/program-setup/funding-sources/open', icon: 'university', disabled: !canManageFundingSources }, { title: 'Workflows', description: 'Create workflows and assign users.', i18nTitleKey: 'GLOBAL:textWorkflows', i18nDescriptionKey: 'CONFIG.MANAGE_WORKFLOWS_DESC', href: '/management/program-setup/workflows', icon: 'code-branch', disabled: !canManageWorkflows }, { title: 'Workflow Level Automation', description: 'Create and manage rules for workflow level routing', i18nTitleKey: 'common:hdrWorkflowLevelAutomation', i18nDescriptionKey: 'CONFIG:textCreateAndManageRulesDesc', href: '/management/program-setup/workflow-automation', icon: 'route', disabled: !canManageAutomation }]; const miscOptions = [{ title: 'Invitations', description: 'Send invitations to individuals and distribution lists', i18nTitleKey: 'PROGRAM:textInvitations', i18nDescriptionKey: 'PROGRAM:textInvitationsDesc', href: '/management/program-setup/invitations/invitations-list', icon: 'envelope', disabled: !canManageInvitations }]; return [ setupItems, miscOptions, configItems ]; } getInsightsPageCards () { const permission = this.policyService.insights; const canManage = this.policyService.grantApplication.canAccessApplicationManager(); const items: CardItem[] = [ { title: 'Applicants', i18nTitleKey: 'common:lblApplicants', href: '/management/insights/applicants', icon: 'users', i18nDescriptionKey: 'GLOBAL:textApplicantsInsightsDesc', description: 'Applicant request amounts, award and payment breakdown', disabled: !permission.canViewApplicants() }, { title: 'Awards', i18nTitleKey: 'common:hdrAwards', href: '/management/insights/awards', icon: 'trophy-alt', i18nDescriptionKey: 'GLOBAL:textAwardsInsightsDesc', description: 'Program and payment breakdown for awards', disabled: !permission.canViewAwards() }, { title: 'Budgets', i18nTitleKey: 'GLOBAL:textBudgets', href: '/management/insights/budgets', icon: 'usd-circle', i18nDescriptionKey: 'GLOBAL:textBudgetsInsightsDesc', description: 'Program, funding source, and payment breakdown for budgets', disabled: !permission.canViewBudgets() }, { title: 'Funding Sources', i18nTitleKey: 'GLOBAL:textFundingSources', href: '/management/insights/funding-sources', icon: 'hand-holding-usd', i18nDescriptionKey: 'GLOBAL:textFundingSourcesInsightsDesc', description: 'Budget and payment breakdown for funding sources', disabled: !permission.canViewFundingSources() }, { title: 'Organizations', i18nTitleKey: 'common:lblOrganizations', href: '/management/insights/organizations', icon: 'hands-helping', i18nDescriptionKey: 'GLOBAL:textOrganizationsInsightsDesc', description: 'Organization classification, request amount, award and payment breakdown', disabled: !permission.canViewOrganizations() }, { title: 'Programs', i18nTitleKey: 'GLOBAL:textPrograms', href: '/management/insights/program-manager', icon: 'chart-bar', i18nDescriptionKey: 'GLOBAL:textProgramsInsightsDesc', description: 'Application and payment breakdown for programs', disabled: !canManage || !permission.canViewPrograms() }]; return [ items ]; } getAdminSettingsPageCards () { const items: CardItem[] = [ { // Internal Admins Card title: 'Internal Admins', description: 'Manage internal admins with access to Admin Tools', i18nTitleKey: 'common:textInternalAdmin', i18nDescriptionKey: 'GLOBAL:textManageInternalAdmins', href: '/platform/admin-settings/internal-admins', icon: 'user-lock', disabled: !this.adminPermissions.includes(AdminUserPermissions.ViewUsers) }, { // Roles and Permissions Card title: 'Roles and Permissions', description: 'Manage roles and permissions for internal admins', i18nTitleKey: 'common:ROLES_PERMISSIONS', i18nDescriptionKey: 'GLOBAL:textManageRolesAndPermissions', href: '/platform/admin-settings/roles-and-permissions', icon: 'lock', disabled: !this.adminPermissions.includes(AdminUserPermissions.ManageRoles) } ]; return [ items ]; } getClientManagementPageCards () { const items: CardItem[] = [ { //Clients Card title: 'Clients', description: 'Create and view clients using GrantsConnect', i18nTitleKey: 'common:textClients', i18nDescriptionKey: 'GLOBAL:textManageClients', href: '/platform/client-management/clients', icon: 'building', disabled: false }, { //Email Logs Card title: 'Email Logs', description: 'View emails sent from GrantsConnect', i18nTitleKey: 'CONFIG:hdrEmailLogs', i18nDescriptionKey: 'GLOBAL:textEmailLogs', href: '/platform/client-management/email-logs', icon: 'envelope', disabled: !this.adminPermissions.includes(AdminUserPermissions.ViewEmailLogs) }, { //Grant Managers Card title: 'Grant Managers', description: 'Manage and impersonate Grant Managers', i18nTitleKey: 'common:hdrGrantManagers', i18nDescriptionKey: 'GLOBAL:textGrantManagers', href: '/platform/client-management/grant-managers', icon: 'user-tie', disabled: !this.adminPermissions.includes(AdminUserPermissions.ViewGrantManagers) }, { //Historical Imports Card title: 'Historical Imports', description: 'Import historical data', i18nTitleKey: 'CONFIG:hdrHistoricalImports', i18nDescriptionKey: 'GLOBAL:textHistoricalImports', href: '/platform/client-management/historical-imports', icon: 'file', disabled: !this.adminPermissions.includes(AdminUserPermissions.Import) }, { //Customer Insights Card title: 'Customer Insights', description: 'View changes in product usage over time', i18nTitleKey: 'CONFIG:hdrCustomerInsights', i18nDescriptionKey: 'GLOBAL:textCustomerInsightsDescription', href: '/platform/client-management/customer-insights', icon: 'chart-line', disabled: false } ]; return [ items ]; } getProductManagementPageCards () { const items: CardItem[] = [{ title: 'Release Notes', description: 'Manage in-app release note messaging', i18nTitleKey: 'common:hdrReleaseNotes', i18nDescriptionKey: 'common:textReleaseNotesDesc', href: '/platform/product-management/release-notes', icon: 'comment', disabled: !this.adminPermissions.includes(AdminUserPermissions.ResourceConfiguration) }, { title: 'Feature Flags', description: 'Manage user and client access to new features', i18nTitleKey: 'ADMIN:hdrFeatureFlags', i18nDescriptionKey: 'ADMIN:textFeatureFlagDescription', href: '/platform/product-management/feature-flags', icon: 'user-lock', disabled: !this.adminPermissions.includes(AdminUserPermissions.CanManageFeatureFlags) }, { title: 'Help Content', description: 'Link GrantsConnect pages to help content', i18nTitleKey: 'ADMIN:hdrHelpContent', i18nDescriptionKey: 'ADMIN:textHelpContentDescription', href: '/platform/product-management/help-content', icon: 'question-circle', disabled: !this.adminPermissions.includes(AdminUserPermissions.ResourceConfiguration) }, { title: 'Standard Product Configuration', description: 'Push standard product features to clients', i18nTitleKey: 'common:hdrStandardProductConfiguration', i18nDescriptionKey: 'GLOBAL:textStandardProductDescription', href: '/platform/product-management/standard-product-configuration', icon: 'toolbox', disabled: !this.adminPermissions.includes(AdminUserPermissions.CanManageStandardProductComponents) }]; return [ items ]; } }