diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index b539a60bba..98ec3b3dba 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -247,6 +247,7 @@ "change_the_ownership_of_your_personal_projects": "", "change_to_group_plan": "", "change_to_this_plan": "", + "change_your_email": "", "changing_the_position_of_your_figure": "", "changing_the_position_of_your_table": "", "chat": "", @@ -643,6 +644,7 @@ "generic_if_problem_continues_contact_us": "", "generic_linked_file_compile_error": "", "generic_something_went_wrong": "", + "get_access_to_enterprise_features": "", "get_ai_assist": "", "get_collaborative_benefits": "", "get_discounted_plan": "", @@ -889,12 +891,14 @@ "it_looks_like_your_account_is_billed_manually_purchasing_additional_license_or_upgrading_subscription": "", "it_looks_like_your_payment_details_are_missing_please_update_your_billing_information": "", "italics": "", + "join": "", "join_beta": "", "join_beta_program": "", "join_now": "", "join_overleaf_labs": "", "join_project": "", "join_team_explanation": "", + "join_x_enterprise_group": "", "joined_team": "", "joining": "", "justify": "", @@ -1177,6 +1181,7 @@ "optional": "", "or": "", "organization_name": "", + "organization_x_has_an_enterprise_license": "", "organize_tags": "", "other": "", "other_logs_and_files": "", @@ -1427,6 +1432,7 @@ "remove_sso_login_option": "", "remove_tag": "", "remove_user": "", + "remove_your_company_email": "", "removed_from_project": "", "removing": "", "rename": "", @@ -1738,6 +1744,7 @@ "switch_to_new_editor": "", "switch_to_old_editor": "", "switch_to_pdf": "", + "switch_to_personal_email_to_keep_your_accounts_separate": "", "switch_to_standard_plan": "", "symbol": "", "symbol_palette": "", @@ -2152,9 +2159,11 @@ "you_are_a_manager_of_publisher_x": "", "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "", "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "", + "you_are_currently_signed_in_as_x": "", "you_are_on_a_paid_plan_contact_support_to_find_out_more": "", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "", + "you_are_using_your_organization_email_x_would_like_you_to_take_action": "", "you_can_also_choose_to_view_anonymously_or_leave_the_project": "", "you_can_buy_this_plan_but_not_as_a_trial": "", "you_can_leave_the_experiment_from_your_account_settings_at_any_time": "", @@ -2184,6 +2193,7 @@ "you_need_to_configure_your_sso_settings": "", "you_unpaused_your_subscription": "", "you_will_be_able_to_reassign_subscription": "", + "youll_continue_to_have_access_to_all_of_your_projects": "", "youll_get_best_results_in_visual_but_can_be_used_in_source": "", "youll_need_to_ask_the_github_repository_owner": "", "youll_no_longer_need_to_remember_credentials": "", diff --git a/services/web/frontend/js/shared/components/labeled-divider.tsx b/services/web/frontend/js/shared/components/labeled-divider.tsx new file mode 100644 index 0000000000..a98f01ff8a --- /dev/null +++ b/services/web/frontend/js/shared/components/labeled-divider.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +function LabeledDivider({ children }: { children: string }) { + return ( +
+ {children} +
+ ) +} + +export default LabeledDivider diff --git a/services/web/frontend/js/shared/components/ol/ol-card.tsx b/services/web/frontend/js/shared/components/ol/ol-card.tsx index f5ff025d10..e6be7f2415 100644 --- a/services/web/frontend/js/shared/components/ol/ol-card.tsx +++ b/services/web/frontend/js/shared/components/ol/ol-card.tsx @@ -1,13 +1,22 @@ import { Card } from 'react-bootstrap' import { FC } from 'react' -const OLCard: FC> = ({ - children, - className, -}) => { +type OLCardProps = { + children: + | React.ReactNode + | ((Component: typeof Card.Body) => React.ReactElement) + className?: string + 'data-testid'?: string +} + +const OLCard: FC = ({ children, className, ...rest }) => { return ( - - {children} + + {typeof children === 'function' ? ( + children(Card.Body) + ) : ( + {children} + )} ) } diff --git a/services/web/frontend/js/shared/svgs/building-compliance-green.svg b/services/web/frontend/js/shared/svgs/building-compliance-green.svg new file mode 100644 index 0000000000..e8dce8c737 --- /dev/null +++ b/services/web/frontend/js/shared/svgs/building-compliance-green.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/services/web/frontend/js/shared/svgs/cog-pen-green.svg b/services/web/frontend/js/shared/svgs/cog-pen-green.svg new file mode 100644 index 0000000000..76b76f3ee3 --- /dev/null +++ b/services/web/frontend/js/shared/svgs/cog-pen-green.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/services/web/frontend/stories/labeled-divider.stories.tsx b/services/web/frontend/stories/labeled-divider.stories.tsx new file mode 100644 index 0000000000..1139bc9e4b --- /dev/null +++ b/services/web/frontend/stories/labeled-divider.stories.tsx @@ -0,0 +1,18 @@ +import LabeledDivider from '@/shared/components/labeled-divider' +import { Meta } from '@storybook/react' + +type Args = React.ComponentProps + +export const Default = (args: Args) => { + return +} + +const meta: Meta = { + title: 'Shared / Components / Labeled Divider', + component: LabeledDivider, + args: { + children: 'Text', + }, +} + +export default meta diff --git a/services/web/frontend/stylesheets/components/all.scss b/services/web/frontend/stylesheets/components/all.scss index 872184615f..b7ddbe6290 100644 --- a/services/web/frontend/stylesheets/components/all.scss +++ b/services/web/frontend/stylesheets/components/all.scss @@ -48,3 +48,4 @@ @import 'integrations-panel'; @import 'group-members'; @import 'upgrade-benefits'; +@import 'labeled-divider'; diff --git a/services/web/frontend/stylesheets/components/card.scss b/services/web/frontend/stylesheets/components/card.scss index 85a49ef990..4011281f1a 100644 --- a/services/web/frontend/stylesheets/components/card.scss +++ b/services/web/frontend/stylesheets/components/card.scss @@ -193,6 +193,14 @@ padding: var(--spacing-09); } } + + .card-icon-left { + width: 52px; + height: 56px; + display: flex; + align-items: center; + justify-content: center; + } } .card-gray { diff --git a/services/web/frontend/stylesheets/components/labeled-divider.scss b/services/web/frontend/stylesheets/components/labeled-divider.scss new file mode 100644 index 0000000000..3327efcde7 --- /dev/null +++ b/services/web/frontend/stylesheets/components/labeled-divider.scss @@ -0,0 +1,22 @@ +.labeled-divider { + display: flex; + align-items: center; + text-align: center; + margin: var(--spacing-06) 0; + color: var(--content-secondary); + + @include body-sm; +} + +.labeled-divider::before, +.labeled-divider::after { + content: ''; + flex: 1; + border-bottom: var(--bs-border-width) solid var(--border-divider); +} + +.labeled-divider span { + margin: 0 var(--spacing-04); + overflow: hidden; + word-break: break-word; +} diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 58463e4a1e..3a30f68e73 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -316,6 +316,7 @@ "change_the_ownership_of_your_personal_projects": "Change the ownership of your personal projects to the new account. <0>Find out how to change project owner.", "change_to_group_plan": "Change to a group plan", "change_to_this_plan": "Change to this plan", + "change_your_email": "Change your email", "changing_the_position_of_your_figure": "Changing the position of your figure", "changing_the_position_of_your_table": "Changing the position of your table", "chat": "Chat", @@ -840,6 +841,7 @@ "generic_if_problem_continues_contact_us": "If the problem continues please contact us", "generic_linked_file_compile_error": "This project’s output files are not available because it failed to compile. Please open the project to see the compilation error details.", "generic_something_went_wrong": "Sorry, something went wrong", + "get_access_to_enterprise_features": "Get access to enterprise features and benefits provided by your organization.", "get_ai_assist": "Get AI Assist", "get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline", "get_discounted_plan": "Get discounted plan", @@ -1145,6 +1147,7 @@ "italics": "Italics", "ja": "Japanese", "january": "January", + "join": "Join", "join_beta": "Join beta", "join_beta_program": "Join the beta program", "join_labs": "Join Labs", @@ -1153,6 +1156,7 @@ "join_project": "Join Project", "join_sl_to_view_project": "Join __appName__ to view this project", "join_team_explanation": "Please click the button below to join the group subscription and enjoy the benefits of an upgraded __appName__ account", + "join_x_enterprise_group": "Join __companyName__ enterprise group", "joined_team": "You have joined the group subscription managed by __inviterName__", "joining": "Joining", "july": "July", @@ -1536,6 +1540,7 @@ "organization_name": "Organization name", "organization_or_company_name": "Organization or company name", "organization_or_company_type": "Organization or company type", + "organization_x_has_an_enterprise_license": "Your organization __companyName__ now has an Overleaf enterprise license", "organize_tags": "Organize Tags", "original_price": "Original price", "other": "Other", @@ -1857,6 +1862,7 @@ "remove_sso_login_option": "Remove the SSO login option for your users.", "remove_tag": "Remove tag __tagName__", "remove_user": "Remove user", + "remove_your_company_email": "Remove your company email from your personal account", "removed": "removed", "removed_from_project": "Removed from project", "removing": "Removing", @@ -2234,6 +2240,7 @@ "switch_to_new_editor": "Switch to new editor", "switch_to_old_editor": "Switch to old editor", "switch_to_pdf": "Switch to PDF", + "switch_to_personal_email_to_keep_your_accounts_separate": "Switch to a personal email to keep your accounts separate.", "switch_to_standard_plan": "Switch to Standard plan", "symbol": "Symbol", "symbol_palette": "Symbol palette", @@ -2707,9 +2714,11 @@ "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager of the <0>__planName__ group subscription <1>__groupName__ administered by <1>__adminEmail__.", "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager of the <0>__planName__ group subscription <1>__groupName__ administered by <1>you (__adminEmail__).", "you_are_currently_logged_in_as": "You are currently logged in as __email__.", + "you_are_currently_signed_in_as_x": "You are currently signed in as <0>__email__.", "you_are_on_a_paid_plan_contact_support_to_find_out_more": "You’re on an __appName__ Paid plan. <0>Contact Support to find out more.", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "You are on our <0>__planName__ plan as a <1>confirmed member of <1>__institutionName__", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are on our <0>__planName__ plan as a <1>member of the group subscription <1>__groupName__ administered by <1>__adminEmail__", + "you_are_using_your_organization_email_x_would_like_you_to_take_action": "Because you are using your organization email on Overleaf, __companyName__ would like you to take one of the following actions.", "you_can_also_choose_to_view_anonymously_or_leave_the_project": "You can also choose to <0>view anonymously (you will lose edit access) or <1>leave the project.", "you_can_buy_this_plan_but_not_as_a_trial": "You can buy this plan but not as a trial, as you’ve completed a trial recently.", "you_can_leave_the_experiment_from_your_account_settings_at_any_time": "You can leave the experiment from your <0>account settings at any time.", @@ -2742,6 +2751,7 @@ "you_unpaused_your_subscription": "You unpaused your subscription.", "you_will_be_able_to_contact_us_any_time_to_share_your_feedback": "<0>You will be able to contact us any time to share your feedback", "you_will_be_able_to_reassign_subscription": "You will be able to reassign their subscription membership to another person in your organization", + "youll_continue_to_have_access_to_all_of_your_projects": "You’ll continue to have access to all of your projects.", "youll_get_best_results_in_visual_but_can_be_used_in_source": "You’ll get the best results from using this tool in the <0>Visual Editor, although you can still use it to insert tables in the <1>Code Editor. Once you’ve selected the number of rows and columns you need, the table will appear in your document and you can double click in a cell to add contents to it.", "youll_need_to_ask_the_github_repository_owner": "You’ll need to ask the GitHub repository owner (<0>__repoOwnerEmail__) to reconnect the project.", "youll_no_longer_need_to_remember_credentials": "You’ll no longer need to remember a separate email address and password. Instead, you will use single-sign on to login to Overleaf. <0>Read more about SSO.", diff --git a/services/web/test/frontend/features/group-management/components/domain-capture.spec.tsx b/services/web/test/frontend/features/group-management/components/domain-capture.spec.tsx new file mode 100644 index 0000000000..db89129106 --- /dev/null +++ b/services/web/test/frontend/features/group-management/components/domain-capture.spec.tsx @@ -0,0 +1,74 @@ +import DomainCapture from '../../../../../modules/group-settings/frontend/js/components/domain-capture' + +describe('', function () { + beforeEach(function () { + this.email = 'user@example.com' + this.groupName = 'test-group' + + cy.window().then(win => { + win.metaAttributesCache.set('ol-user', { + email: this.email, + first_name: 'Nice', + last_name: 'Wombat', + }) + win.metaAttributesCache.set('ol-email', this.email) + win.metaAttributesCache.set('ol-groupName', this.groupName) + }) + + cy.mount() + }) + + it('renders the heading', function () { + cy.findByRole('heading', { + name: new RegExp( + `your organization ${this.groupName} now has an Overleaf enterprise license`, + 'i' + ), + }) + }) + + it('renders the description', function () { + cy.findByTestId('domain-capture-signed-in-as') + .invoke('text') + .should( + 'match', + new RegExp(`you are currently signed in as ${this.email}`, 'i') + ) + cy.findByText( + new RegExp( + `because you are using your organization email on Overleaf, ${this.groupName} would like you to take one of the following actions`, + 'i' + ) + ) + }) + + it('renders the join group card', function () { + cy.findByTestId('domain-capture-join-card').within(() => { + cy.findByRole('heading', { + name: new RegExp(`join ${this.groupName} enterprise group`, 'i'), + }) + cy.findByText( + /get access to enterprise features and benefits provided by your organization/i + ) + cy.findByText(/you’ll continue to have access to all of your projects/i) + cy.findByRole('button', { name: /join/i }) + }) + }) + + it('renders the remove company email card', function () { + cy.findByTestId('domain-capture-remove-email-card').within(() => { + cy.findByRole('heading', { + name: /remove your company email from your personal account/i, + }) + cy.findByText( + /switch to a personal email to keep your accounts separate/i + ) + cy.findByText(/you’ll continue to have access to all of your projects/i) + cy.findByRole('link', { name: /change your email/i }).should( + 'have.attr', + 'href', + '/user/settings' + ) + }) + }) +})