Преглед изворни кода

Merge pull request #27641 from overleaf/ii-domain-capture-page

[web] Create domain capture page

GitOrigin-RevId: df16ba2cac683d315979be69f63e160ec402020b
ilkin-overleaf пре 1 година
родитељ
комит
222ecb55d6

+ 10 - 0
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": "",

+ 11 - 0
services/web/frontend/js/shared/components/labeled-divider.tsx

@@ -0,0 +1,11 @@
+import React from 'react'
+
+function LabeledDivider({ children }: { children: string }) {
+  return (
+    <div className="labeled-divider">
+      <span>{children}</span>
+    </div>
+  )
+}
+
+export default LabeledDivider

+ 15 - 6
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<React.PropsWithChildren<{ className?: string }>> = ({
-  children,
-  className,
-}) => {
+type OLCardProps = {
+  children:
+    | React.ReactNode
+    | ((Component: typeof Card.Body) => React.ReactElement)
+  className?: string
+  'data-testid'?: string
+}
+
+const OLCard: FC<OLCardProps> = ({ children, className, ...rest }) => {
   return (
-    <Card className={className}>
-      <Card.Body>{children}</Card.Body>
+    <Card className={className} {...rest}>
+      {typeof children === 'function' ? (
+        children(Card.Body)
+      ) : (
+        <Card.Body>{children}</Card.Body>
+      )}
     </Card>
   )
 }

+ 15 - 0
services/web/frontend/js/shared/svgs/building-compliance-green.svg

@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="42" height="38" viewBox="0 0 42 38" fill="none">
+<g clip-path="url(#clip0_47_137)">
+<path d="M41.5135 27.0169C41.4753 25.9308 41.4274 24.8448 41.3701 23.7587L41.2936 22.1486C41.2266 20.5481 40.0407 19.1858 38.5392 18.9762C37.602 18.8428 36.7317 18.576 35.5553 18.1569C35.125 18.0044 34.752 17.8425 34.3981 17.6805C34.3216 17.6424 34.2355 17.5852 34.1495 17.5281C33.8052 17.309 33.3461 17.0327 32.7819 16.8517V16.2991C32.7819 16.0705 32.7532 15.8418 32.7149 15.6227C35.0485 15.5655 36.9516 13.6411 36.9516 11.3165V10.1447C36.9516 8.00114 35.5936 6.06717 33.5852 5.32407L20.1482 0.360532C19.5744 0.150939 18.9719 0.0461426 18.3598 0.0461426C17.6043 0.0461426 16.8487 0.217627 16.1697 0.532016L4.06207 6.17196C2.25453 7.01034 1.08775 8.83951 1.08775 10.8211V11.4308C1.08775 12.6503 1.56594 13.803 2.4458 14.6605C2.81878 15.0225 3.24915 15.3083 3.70821 15.5179C3.67952 15.7084 3.65083 15.9085 3.65083 16.1086V23.8444C3.65083 23.9016 3.66995 23.9588 3.66995 24.0159C1.86241 24.5113 0.600006 26.1023 0.600006 28.1316C0.600006 30.5705 2.42667 32.4187 4.83673 32.4187H23.3903C25.0448 34.8671 27.7418 36.8773 30.5822 37.7347C30.9456 37.8681 31.3186 37.9348 31.7107 37.9348H31.7585C32.1411 37.9348 32.5236 37.8681 32.8775 37.7347C35.8518 36.8392 38.6922 34.667 40.3181 32.0567C41.4848 30.1799 41.5613 28.2649 41.5135 26.9979V27.0169Z" fill="#80CBA2"/>
+<path d="M9.40815 25.3592H7.74407C6.7877 25.3592 6.03217 24.7019 6.03217 23.8635V16.1276C6.03217 15.2893 6.77813 14.6319 7.74407 14.6319H9.48466C10.5749 14.6319 11.4261 15.3655 11.4261 16.2991V23.6349C11.4261 24.6066 10.5367 25.3688 9.39859 25.3688L9.40815 25.3592ZM7.95447 23.4538H9.40815C9.40815 23.4538 9.48466 23.4538 9.52292 23.4443V16.5278C9.52292 16.5278 9.50379 16.5278 9.49423 16.5278H7.96403V23.4538H7.95447Z" fill="black"/>
+<path d="M18.8954 25.3592H17.2408C16.2845 25.3592 15.5289 24.7019 15.5289 23.8635V16.1276C15.5289 15.2893 16.2749 14.6319 17.2408 14.6319H18.9814C20.0717 14.6319 20.9229 15.3655 20.9229 16.2991V23.6349C20.9229 24.6066 20.0334 25.3688 18.8954 25.3688V25.3592ZM17.4417 23.4538H18.8954C18.8954 23.4538 18.9719 23.4538 19.0101 23.4443V16.5278C19.0101 16.5278 18.991 16.5278 18.9814 16.5278H17.4512V23.4538H17.4417Z" fill="black"/>
+<path d="M35.7849 24.2541C35.5266 23.8159 34.9146 23.6444 34.4746 23.9111C32.7819 24.9591 31.4908 26.512 30.2953 28.0935C29.9414 27.5981 29.5111 27.1598 28.9946 26.7883C28.5834 26.4834 27.9235 26.7216 27.6844 27.1312C27.3975 27.6171 27.6079 28.122 28.0287 28.4364C27.9235 28.3602 28.1339 28.5222 28.153 28.5412C28.2295 28.6079 28.306 28.6746 28.373 28.7508C28.4495 28.827 28.5164 28.8937 28.5834 28.9699C28.6312 29.0176 28.6695 29.0747 28.7173 29.1224C28.679 29.0747 28.679 29.0843 28.7173 29.1319C28.8321 29.2939 28.9373 29.4749 29.0329 29.6464C29.1477 29.8655 29.1477 29.8655 29.2337 30.1227C29.3581 30.4847 29.6354 30.761 30.0275 30.8086C30.4388 30.8563 30.7448 30.6753 30.9839 30.3513C31.6916 29.4082 32.2559 28.627 33.021 27.741C33.4035 27.3027 33.7956 26.8835 34.226 26.4929C34.6755 26.0833 34.9337 25.8737 35.4406 25.5593C35.8805 25.2925 36.0526 24.7114 35.7849 24.2541Z" fill="black"/>
+<path d="M5.64006 13.5935C5.06624 13.5935 4.53068 13.3743 4.11944 12.9742C3.7082 12.5646 3.47867 12.0215 3.47867 11.4404V10.8307C3.47867 9.76364 4.10031 8.78236 5.07581 8.3346L17.1835 2.68512C17.8529 2.37073 18.6276 2.34215 19.3162 2.59938L32.7532 7.55339C33.8339 7.95352 34.5607 8.99196 34.5607 10.1352V11.307C34.5607 12.355 33.7 13.2314 32.648 13.241L5.66876 13.5935C5.66876 13.5935 5.64963 13.5935 5.64006 13.5935ZM18.3598 5.2955L6.72076 10.7259L31.6916 10.4019V10.2114L18.3598 5.2955Z" fill="black"/>
+<path d="M38.9122 22.2534C38.893 21.8819 38.6253 21.396 38.214 21.3389C36.9994 21.1674 35.9092 20.8149 34.7615 20.4052C34.2833 20.2337 33.8147 20.0432 33.3557 19.8146C32.8679 19.5764 32.2941 19.0429 31.7394 19.0429C31.2803 19.0429 30.8213 19.4049 30.41 19.6526V16.2991C30.41 15.3655 29.5589 14.6319 28.4686 14.6319H26.728C25.7716 14.6319 25.0161 15.2893 25.0161 16.1276V21.4437C24.7388 21.6151 24.5666 21.9676 24.5571 22.263C24.4997 23.5967 24.4423 24.921 24.3849 26.2548C24.3658 26.2548 24.3562 26.2548 24.3467 26.2548H4.83671C2.37884 26.2548 2.36927 30.0655 4.83671 30.0655H24.3371C24.4901 30.0655 24.6336 30.0465 24.7675 30.0179C24.8822 30.2942 25.0066 30.5609 25.1787 30.8277C26.5367 33.0189 28.9755 34.8481 31.4716 35.534C31.4812 35.534 31.4907 35.534 31.5003 35.534C31.5673 35.5531 31.6533 35.5531 31.7298 35.5531C31.8063 35.5531 31.8829 35.5531 31.9594 35.534C31.9689 35.534 31.9785 35.534 31.9881 35.534C34.4842 34.8385 36.9229 33.0094 38.281 30.8277C39.0078 29.6654 39.1704 28.4555 39.1226 27.1027C39.0652 25.4831 38.9791 23.873 38.9122 22.263V22.2534ZM26.9289 16.5278H28.459C28.459 16.5278 28.4782 16.5278 28.4877 16.5278V20.4719C27.9617 20.6529 27.4453 20.8244 26.9193 20.9768V16.5278H26.9289ZM36.7508 29.6654C35.6988 31.4565 33.7382 32.9713 31.7298 33.6096C29.7215 32.9713 27.7609 31.4565 26.7089 29.6654C26.0968 28.6174 26.2403 27.4361 26.2881 26.2738C26.3359 25.1973 26.3837 24.1207 26.4315 23.0537C27.3401 22.8727 28.2008 22.5964 29.0998 22.282C29.5876 22.1105 30.0562 21.92 30.5344 21.7199C30.8213 21.5961 31.0986 21.4627 31.3664 21.3198C31.4907 21.2531 31.6151 21.1864 31.7298 21.1102C31.8255 21.1674 31.9307 21.215 32.0167 21.2626C32.2845 21.4056 32.5714 21.5389 32.8488 21.6723C33.3078 21.8724 33.7765 22.0629 34.2451 22.2344C35.1823 22.5678 36.0813 22.8632 37.0281 23.0537C37.0759 24.1303 37.1238 25.2068 37.1716 26.2738C37.2194 27.4361 37.3629 28.6174 36.7508 29.6654Z" fill="black"/>
+</g>
+<defs>
+<clipPath id="clip0_47_137">
+<rect width="40.9231" height="37.9077" fill="white" transform="translate(0.600006 0.0461426)"/>
+</clipPath>
+</defs>
+</svg>

Разлика између датотеке није приказан због своје велике величине
+ 2 - 0
services/web/frontend/js/shared/svgs/cog-pen-green.svg


+ 18 - 0
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<typeof LabeledDivider>
+
+export const Default = (args: Args) => {
+  return <LabeledDivider {...args} />
+}
+
+const meta: Meta<typeof LabeledDivider> = {
+  title: 'Shared / Components / Labeled Divider',
+  component: LabeledDivider,
+  args: {
+    children: 'Text',
+  },
+}
+
+export default meta

+ 1 - 0
services/web/frontend/stylesheets/components/all.scss

@@ -48,3 +48,4 @@
 @import 'integrations-panel';
 @import 'group-members';
 @import 'upgrade-benefits';
+@import 'labeled-divider';

+ 8 - 0
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 {

+ 22 - 0
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;
+}

+ 10 - 0
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.</0>",
   "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</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>.",
   "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>you (__adminEmail__</1>).",
   "you_are_currently_logged_in_as": "You are currently logged in as <b>__email__</b>.",
+  "you_are_currently_signed_in_as_x": "You are currently signed in as <0>__email__</0>.",
   "you_are_on_a_paid_plan_contact_support_to_find_out_more": "You’re on an __appName__ Paid plan. <0>Contact Support</0> to find out more.",
   "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "You are on our <0>__planName__</0> plan as a <1>confirmed member</1> of <1>__institutionName__</1>",
   "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are on our <0>__planName__</0> plan as a <1>member</1> of the group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>",
+  "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</0> (you will lose edit access) or <1>leave the project</1>.",
   "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</0> 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</0> 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</0>, although you can still use it to insert tables in the <1>Code Editor</1>. 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__</0>) 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</0>.",

+ 74 - 0
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('<DomainCapture />', 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(<DomainCapture />)
+  })
+
+  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'
+      )
+    })
+  })
+})

Неке датотеке нису приказане због велике количине промена