Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"dependencies": {
"@analytics/google-tag-manager": "^0.6.0",
"@appquality/languages": "1.4.3",
"@appquality/unguess-design-system": "4.0.50--canary.549.a1152e0.0",
"@appquality/unguess-design-system": "4.0.50--canary.549.d5b9e5c.0",
"@atlaskit/pragmatic-drag-and-drop": "^1.7.4",
"@atlaskit/pragmatic-drag-and-drop-flourish": "^2.0.3",
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
Expand Down
6 changes: 6 additions & 0 deletions src/assets/icons/dashboard_customize.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@
"__PLAN_INSTRUCTION_NOTE_SIZE_ERROR_EMPTY": "Required field: enter a text to continue",
"__PLAN_MISSING_MODULES_ERROR": "Some items are missing",
"__PLAN_OUT_OF_SCOPE_SIZE_ERROR_TOO_LONG": "Character limit exceeded: Please reduce your text to 512 characters",
"__PLAN_PAGE_ADD_CUSTOM_FEATURE_BUTTON": "Add custom features",
"__PLAN_PAGE_ADD_MODULE_BLOCK_BUTTON": "Add item",
"__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_SUBTITLE": "Provide the necessary details to describe this activity",
"__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_TITLE": "Available informations",
Expand All @@ -794,6 +795,8 @@
"__PLAN_PAGE_DRAFT_ACTIVITY_INFO_STARTING_PRICE_INFO": "*Adding features may require a custom quote",
"__PLAN_PAGE_DRAFT_ACTIVITY_INFO_TEMPLATE_TYPE": "STANDARD PACKAGE",
"__PLAN_PAGE_DRAFT_ACTIVITY_INFO_TITLE": "Activity Info",
"__PLAN_PAGE_EXPERT_REVIEW_TOOLTIP_CONTENT": "Custom features require expert review (2 days) and personalized pricing. You can always return to the standard setup.",
"__PLAN_PAGE_EXPERT_REVIEW_WARNING": "Requires expert review",
"__PLAN_PAGE_GROUP_TITLE_ACTIVITY_SCOPE": "Activity Scope",
"__PLAN_PAGE_GROUP_TITLE_ADDITIONAL_DETAILS": "Additional Details",
"__PLAN_PAGE_GROUP_TITLE_ADVANCED_CRITERIA": "Other",
Expand Down Expand Up @@ -975,6 +978,7 @@
"__PLAN_PAGE_MODULE_SETUP_NOTE_DESCRIPTION_EDITOR_PLACEHOLDER": "In this section, you can set up the manual to guide testers during the activity.",
"__PLAN_PAGE_MODULE_SETUP_NOTE_REMOVE_BUTTON": "Delete",
"__PLAN_PAGE_MODULE_SETUP_NOTE_TITLE": "Before starting",
"__PLAN_PAGE_MODULE_TARGET_ALERT": "Custom participant numbers require expert review and may increase pricing",
"__PLAN_PAGE_MODULE_TARGET_LABEL": "Enter number of participants",
"__PLAN_PAGE_MODULE_TARGET_NOTE_BLOCK_TITLE": "Before Starting",
"__PLAN_PAGE_MODULE_TARGET_NOTE_DESCRIPTION_EDITOR_HEADER_TITLE": "Write here",
Expand Down
4 changes: 4 additions & 0 deletions src/locales/it/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@
"__PLAN_INSTRUCTION_NOTE_SIZE_ERROR_EMPTY": "",
"__PLAN_MISSING_MODULES_ERROR": "",
"__PLAN_OUT_OF_SCOPE_SIZE_ERROR_TOO_LONG": "",
"__PLAN_PAGE_ADD_CUSTOM_FEATURE_BUTTON": "",
"__PLAN_PAGE_ADD_MODULE_BLOCK_BUTTON": "",
"__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_SUBTITLE": "",
"__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_TITLE": "",
Expand All @@ -824,6 +825,8 @@
"__PLAN_PAGE_DRAFT_ACTIVITY_INFO_STARTING_PRICE_INFO": "",
"__PLAN_PAGE_DRAFT_ACTIVITY_INFO_TEMPLATE_TYPE": "",
"__PLAN_PAGE_DRAFT_ACTIVITY_INFO_TITLE": "",
"__PLAN_PAGE_EXPERT_REVIEW_TOOLTIP_CONTENT": "",
"__PLAN_PAGE_EXPERT_REVIEW_WARNING": "",
"__PLAN_PAGE_GROUP_TITLE_ACTIVITY_SCOPE": "",
"__PLAN_PAGE_GROUP_TITLE_ADDITIONAL_DETAILS": "",
"__PLAN_PAGE_GROUP_TITLE_ADVANCED_CRITERIA": "",
Expand Down Expand Up @@ -1008,6 +1011,7 @@
"__PLAN_PAGE_MODULE_SETUP_NOTE_DESCRIPTION_EDITOR_PLACEHOLDER": "",
"__PLAN_PAGE_MODULE_SETUP_NOTE_REMOVE_BUTTON": "",
"__PLAN_PAGE_MODULE_SETUP_NOTE_TITLE": "",
"__PLAN_PAGE_MODULE_TARGET_ALERT": "",
"__PLAN_PAGE_MODULE_TARGET_LABEL": "",
"__PLAN_PAGE_MODULE_TARGET_NOTE_BLOCK_TITLE": "",
"__PLAN_PAGE_MODULE_TARGET_NOTE_DESCRIPTION_EDITOR_HEADER_TITLE": "",
Expand Down
22 changes: 13 additions & 9 deletions src/pages/Plan/Controls/IconButtonMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const IconButtonMenu = () => {

const { setIsSaveTemplateModalOpen, setIsDeleteModalOpen } = usePlanContext();
const { planId } = useParams();
const { plan } = usePlan(planId);
const { plan, planComposedStatus } = usePlan(planId);

const handleMenuClick = (value?: string) => {
if (value === 'delete') {
Expand All @@ -58,14 +58,18 @@ const IconButtonMenu = () => {
</IconButton>
)}
>
<ButtonMenu.Item
data-qa="save-template-action-item"
value="save_template"
icon={<SaveTemplateIcon />}
>
{t('__PLAN_SAVE_TEMPLATE_CTA')}
</ButtonMenu.Item>
<Divider />
{planComposedStatus !== 'PurchasableDraft' && (
<>
<ButtonMenu.Item
data-qa="save-template-action-item"
value="save_template"
icon={<SaveTemplateIcon />}
>
{t('__PLAN_SAVE_TEMPLATE_CTA')}
</ButtonMenu.Item>
<Divider />
</>
)}
<OptionalTooltip
show={plan?.status !== 'draft'}
content={t('__PLAN_DELETE_PLAN_TOOLTIP')}
Expand Down
48 changes: 48 additions & 0 deletions src/pages/Plan/common/ExpertReviewWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
getColor,
IconButton,
SM,
Tooltip,
} from '@appquality/unguess-design-system';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ReactComponent as InfoIcon } from 'src/assets/icons/info-icon.svg';
import styled from 'styled-components';

const ExpertReviewWarningStyled = styled.div`
&:before {
content: '';
flex-shrink: 0;
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: ${(p) => p.theme.palette.yellow[500]};
}
font-size: ${({ theme }) => theme.fontSizes.sm};
display: flex;
align-items: center;
gap: ${({ theme }) => theme.space.xs};
color: ${(p) => getColor(p.theme.colors.warningHue, 700)};
`;

export const ExpertReviewWarning = (
props: React.ComponentProps<typeof ExpertReviewWarningStyled>
) => {
const { t } = useTranslation();

return (
<ExpertReviewWarningStyled {...props}>
<SM as="span">{t('__PLAN_PAGE_EXPERT_REVIEW_WARNING')}</SM>
<Tooltip
appendToNode={document.body}
type="light"
content={t('__PLAN_PAGE_EXPERT_REVIEW_TOOLTIP_CONTENT')}
>
<IconButton>
<InfoIcon />
</IconButton>
</Tooltip>
</ExpertReviewWarningStyled>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AccordionNew,
Alert,
Button,
FormField,
Input,
Expand Down Expand Up @@ -130,6 +131,9 @@ const TargetSize = () => {
</>
)}
</StyledInfoBox>
<Alert style={{ marginTop: appTheme.space.sm }} type="info">
{t('__PLAN_PAGE_MODULE_TARGET_ALERT')}
</Alert>
</FormField>
</div>
</AccordionNew.Panel>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Button, getColor } from '@appquality/unguess-design-system';
import { useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { appTheme } from 'src/app/theme';
import { ReactComponent as PlusIcon } from 'src/assets/icons/plus-water-circle-add-icon.svg';
import { usePlan } from 'src/hooks/usePlan';
import { ExpertReviewWarning } from 'src/pages/Plan/common/ExpertReviewWarning';
import styled from 'styled-components';
import { useModuleTasksContext } from '../context';

const ButtonContainer = styled.div`
display: flex;
justify-content: flex-start;
margin: ${({ theme }) => theme.space.lg} ${({ theme }) => theme.space.xxl};
padding: ${({ theme }) => theme.space.xs};
border-left: 4px solid
Expand All @@ -17,6 +19,8 @@ const ButtonContainer = styled.div`
const AddTaskButton = () => {
const { t } = useTranslation();
const triggerRef = useRef<HTMLButtonElement>(null);
const { planId } = useParams();
const { planComposedStatus } = usePlan(planId);
const { setModalRef } = useModuleTasksContext();

return (
Expand All @@ -33,6 +37,10 @@ const AddTaskButton = () => {
</Button.StartIcon>
{t('__PLAN_PAGE_MODULE_TASKS_ADD_TASK_BUTTON')}
</Button>
{(planComposedStatus === 'PurchasableDraft' ||
planComposedStatus === 'PrequotedDraft') && (
<ExpertReviewWarning style={{ marginLeft: appTheme.space.sm }} />
)}
</ButtonContainer>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
} from '@appquality/unguess-design-system';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';

Check warning on line 10 in src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/TasksList.tsx

View workflow job for this annotation

GitHub Actions / validate

'useParams' is defined but never used
import { appTheme } from 'src/app/theme';
import { FEATURE_FLAG_CHANGE_MODULES_VARIANTS } from 'src/constants';
import { useModule } from 'src/features/modules/useModule';
import { useModuleConfiguration } from 'src/features/modules/useModuleConfiguration';
import { useFeatureFlag } from 'src/hooks/useFeatureFlag';
import { usePlan } from 'src/hooks/usePlan';

Check warning on line 16 in src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/TasksList.tsx

View workflow job for this annotation

GitHub Actions / validate

'usePlan' is defined but never used
import { DeleteModuleConfirmationModal } from 'src/pages/Plan/modules/modal/DeleteModuleConfirmationModal';
import styled from 'styled-components';
import { useIconWithValidation } from '../../useIcon';
Expand Down
36 changes: 30 additions & 6 deletions src/pages/Plan/navigation/aside/AddBlockButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Button } from '@appquality/unguess-design-system';
import { useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { useAppSelector } from 'src/app/hooks';
import { appTheme } from 'src/app/theme';
import { ReactComponent as CustomFeatureIcon } from 'src/assets/icons/dashboard_customize.svg';
import { ReactComponent as PlusIcon } from 'src/assets/icons/plus-icon.svg';
import { useModuleConfiguration } from 'src/features/modules/useModuleConfiguration';
import { usePlan } from 'src/hooks/usePlan';
import styled from 'styled-components';
import { ExpertReviewWarning } from '../../common/ExpertReviewWarning';
import { usePlanContext } from '../../context/planContext';
import { getModulesByTab } from '../../modules/Factory';
import { usePlanNavContext } from './context';
Expand All @@ -20,7 +24,8 @@ const AddBlockButton = () => {
const { t } = useTranslation();
const triggerRef = useRef<HTMLButtonElement>(null);
const { setModalRef } = usePlanNavContext();
const { getPlanStatus } = useModuleConfiguration();
const { planId } = useParams();
const { planComposedStatus } = usePlan(planId);
const { activeTab } = usePlanContext();
const availableModules = getModulesByTab(activeTab.name);
const { currentModules } = useAppSelector((state) => state.planModules);
Expand All @@ -34,18 +39,37 @@ const AddBlockButton = () => {
<ButtonContainer>
<Button
data-qa="plan_page_button_additem"
isPrimary
isPrimary={planComposedStatus === 'UnquotedDraft'}
isPill={false}
ref={triggerRef}
onClick={() => setModalRef(triggerRef.current)}
isStretched
disabled={items.length === 0 || getPlanStatus() !== 'draft'}
disabled={
items.length === 0 ||
(planComposedStatus !== 'PurchasableDraft' &&
planComposedStatus !== 'UnquotedDraft' &&
planComposedStatus !== 'PrequotedDraft')
}
>
<Button.StartIcon>
<PlusIcon />
{planComposedStatus === 'UnquotedDraft' ? (
<PlusIcon />
) : (
<CustomFeatureIcon />
)}
</Button.StartIcon>
{t('__PLAN_PAGE_ADD_MODULE_BLOCK_BUTTON')}
{planComposedStatus === 'UnquotedDraft'
? t('__PLAN_PAGE_ADD_MODULE_BLOCK_BUTTON')
: t('__PLAN_PAGE_ADD_CUSTOM_FEATURE_BUTTON')}
</Button>
{planComposedStatus !== 'UnquotedDraft' && (
<ExpertReviewWarning
style={{
marginTop: appTheme.space.md,
marginLeft: appTheme.space.sm,
}}
/>
)}
</ButtonContainer>
);
};
Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/dashboard_home.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ test.describe('Home page', () => {
await dashboard.mockWorkspace();
await planCreationInterface.mockGetProjects();
await planCreationInterface.mockPostPlans();
await planCreationInterface.mockGetNewPlan();
await dashboard.mockWorkspacesList();
await promoList.mockPromoTemplates();
await dashboard.open();
Expand Down Expand Up @@ -79,6 +80,6 @@ test.describe('Home page', () => {
template_id: promoList.promoItems[0].id,
});
// expect that navigation to the plan page is triggered
await expect(page).toHaveURL(`/plans/${newPlanId}`);
await expect(page).toHaveURL(`/plans/${newPlanId}?tab=setup`);
});
});
6 changes: 5 additions & 1 deletion tests/e2e/template/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ import mockPostPlans from '../../api/workspaces/wid/plans/_post/201_Example_1.js
import getProjects from '../../api/workspaces/wid/projects/_get/200_Example_1.json';
import getTemplate from '../../api/workspaces/wid/templates/tid/_get/200_Example_1.json';
import { expect, test } from '../../fixtures/app';
import { PlanCreationInterface } from '../../fixtures/components/PlanCreationInterface';
import { Template } from '../../fixtures/pages/Template';

test.describe('template page', () => {
let template: Template;
let planCreationInterface: PlanCreationInterface;

test.beforeEach(async ({ page }) => {
template = new Template(page);
planCreationInterface = new PlanCreationInterface(page);
await template.loggedIn();
await template.mockPreferences();
await template.mockWorkspace();
await template.mockGetTemplate();
await template.mockGetProjects();
await planCreationInterface.mockGetNewPlan();
await template.mockWorkspacesList();
await template.mockPostPlans();
await template.open();
Expand Down Expand Up @@ -61,6 +65,6 @@ test.describe('template page', () => {
template_id: getTemplate.id,
});
// expect that navigation to the plan page is triggered
await expect(page).toHaveURL(`/plans/${newPlanId}`);
await expect(page).toHaveURL(`/plans/${newPlanId}?tab=setup`);
});
});
2 changes: 1 addition & 1 deletion tests/e2e/templates/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ test.describe('Templates page', () => {
template_id: getTemplates.items[0].id,
});
// expect that navigation to the plan page is triggered
await expect(page).toHaveURL(`/plans/${newPlanId}`);
await expect(page).toHaveURL(`/plans/${newPlanId}?tab=setup`);
});
});

Expand Down
4 changes: 1 addition & 3 deletions tests/fixtures/pages/Plan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export class PlanPage extends UnguessPage {

static getTitleFromPlan(plan: any) {
const titleModule = plan.config.modules.find(
(module) => module.type === 'title'
(module: any) => module.type === 'title'
);
if (!titleModule) {
throw new Error('No title module found in plan');
Expand Down Expand Up @@ -485,6 +485,4 @@ export class PlanPage extends UnguessPage {
}
);
}

as;
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@
dependencies:
hls.js "^1.4.8"

"@appquality/unguess-design-system@4.0.50--canary.549.a1152e0.0":
version "4.0.50--canary.549.a1152e0.0"
resolved "https://registry.yarnpkg.com/@appquality/unguess-design-system/-/unguess-design-system-4.0.50--canary.549.a1152e0.0.tgz#77414a26f3044b0aa1e2dba26a9e25def32b530a"
integrity sha512-EdeirzFhDsM6ac/Bvno/n0AHBDFiwh/FZBdAJPlVGZAyatfOUXgPtbbfABSxFQAjSisbDszfAptHH9ior/6NpQ==
"@appquality/unguess-design-system@4.0.50--canary.549.d5b9e5c.0":
version "4.0.50--canary.549.d5b9e5c.0"
resolved "https://registry.yarnpkg.com/@appquality/unguess-design-system/-/unguess-design-system-4.0.50--canary.549.d5b9e5c.0.tgz#cb689e9a0de197fc77644f55fb8ed15d2c18349f"
integrity sha512-yv8hjGDkNyxIaFhQiAt1vmSKHcJb4CsL85cRzZh0UaZB9WomRlVFI+PlMAvVTbazvUi6OieI1CVtwpt2+0+pWQ==
dependencies:
"@appquality/stream-player" "1.0.6"
"@nivo/bar" "^0.87.0"
Expand Down
Loading