mirror of
https://github.com/overleaf/overleaf.git
synced 2025-12-05 01:10:29 +00:00
Compare commits
5 Commits
2f5e629d65
...
3bba9c9fb7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bba9c9fb7 | ||
|
|
3b5ea89a1c | ||
|
|
aebff54a6b | ||
|
|
ab84e48545 | ||
|
|
18caa66bdf |
@@ -210,7 +210,7 @@ export function openFile(fileName: string, waitFor: string) {
|
||||
.click({ force: true })
|
||||
|
||||
// wait until we've switched to the selected file
|
||||
cy.findByText('Loading…').should('not.exist')
|
||||
cy.findByRole('status').should('not.exist')
|
||||
cy.findByText(waitFor)
|
||||
}
|
||||
|
||||
@@ -230,7 +230,10 @@ export function createNewFile() {
|
||||
.click({ force: true })
|
||||
|
||||
// wait until we've switched to the newly created empty file
|
||||
cy.findByText('Loading…').should('not.exist')
|
||||
cy.findByRole('textbox', { name: 'Source Editor editing' }).within(() => {
|
||||
cy.findByRole('status').should('not.exist')
|
||||
cy.get('.cm-line').should('have.length', 1)
|
||||
})
|
||||
cy.get('.cm-line').should('have.length', 1)
|
||||
|
||||
return fileName
|
||||
|
||||
@@ -531,6 +531,7 @@ module.exports = {
|
||||
rules: {
|
||||
'@overleaf/no-unnecessary-trans': 'error',
|
||||
'@overleaf/should-unescape-trans': 'error',
|
||||
'@overleaf/require-loading-label': 'error',
|
||||
|
||||
// https://astexplorer.net/
|
||||
'no-restricted-syntax': [
|
||||
|
||||
@@ -536,6 +536,7 @@ async function projectListPage(req, res, next) {
|
||||
aiBlocked,
|
||||
hasAiAssist,
|
||||
lastActive: user.lastActive,
|
||||
signUpDate: user.signUpDate,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ if(customerIoEnabled && ExposedSettings.cioWriteKey && ExposedSettings.cioSiteId
|
||||
function boolAttr(value) {
|
||||
return value !== undefined ? String(value) : null;
|
||||
}
|
||||
script(type="text/javascript", id="cio-loader", nonce=scriptNonce, data-best-subscription=(usersBestSubscription && usersBestSubscription.type), data-ai-blocked=boolAttr(aiBlocked), data-has-ai-assist=boolAttr(hasAiAssist), data-cio-write-key=ExposedSettings.cioWriteKey, data-cio-site-id=ExposedSettings.cioSiteId, data-session-analytics-id=getSessionAnalyticsId(), data-user-id=getLoggedInUserId(), data-last-active=lastActive).
|
||||
script(type="text/javascript", id="cio-loader", nonce=scriptNonce, data-best-subscription=(usersBestSubscription && usersBestSubscription.type), data-ai-blocked=boolAttr(aiBlocked), data-has-ai-assist=boolAttr(hasAiAssist), data-cio-write-key=ExposedSettings.cioWriteKey, data-cio-site-id=ExposedSettings.cioSiteId, data-session-analytics-id=getSessionAnalyticsId(), data-user-id=getLoggedInUserId(), data-last-active=lastActive, data-sign-up-date=signUpDate).
|
||||
|
||||
function parseBool(value) {
|
||||
return value === 'true' ? true : value === 'false' ? false : undefined;
|
||||
@@ -18,6 +18,7 @@ if(customerIoEnabled && ExposedSettings.cioWriteKey && ExposedSettings.cioSiteId
|
||||
var aiBlocked = parseBool(cioSettings.aiBlocked);
|
||||
var hasAiAssist = parseBool(cioSettings.hasAiAssist);
|
||||
var lastActive = cioSettings.lastActive;
|
||||
var signUpDate = cioSettings.signUpDate;
|
||||
|
||||
|
||||
!function(){var i="cioanalytics", analytics=(window[i]=window[i]||[]);if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.setAttribute('data-global-customerio-analytics-key', i);t.src="https://cdp.customer.io/v1/analytics-js/snippet/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._writeKey=key;analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.15.3";
|
||||
@@ -40,7 +41,7 @@ if(customerIoEnabled && ExposedSettings.cioWriteKey && ExposedSettings.cioSiteId
|
||||
if (typeof value !== 'undefined') obj[key] = value;
|
||||
}
|
||||
|
||||
var identifyData = {overleafId: userId, lastActive};
|
||||
var identifyData = {overleafId: userId, lastActive, signUpDate};
|
||||
addIfDefined(identifyData, 'best-subscription-type', usersBestSubscription);
|
||||
addIfDefined(identifyData, 'aiBlocked', aiBlocked);
|
||||
addIfDefined(identifyData, 'hasAiAssist', hasAiAssist);
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"accept_selected_changes": "",
|
||||
"accept_terms_and_conditions": "",
|
||||
"accepted_invite": "",
|
||||
"accepting": "",
|
||||
"access_all_premium_features": "",
|
||||
"access_all_premium_features_including_more_collaborators_real_time_track_changes_and_a_longer_compile_time": "",
|
||||
"access_denied": "",
|
||||
@@ -125,6 +126,7 @@
|
||||
"alignment": "",
|
||||
"all": "",
|
||||
"all_borders": "",
|
||||
"all_events": "",
|
||||
"all_features_in_group_standard_plus": "",
|
||||
"all_logs": "",
|
||||
"all_premium_features": "",
|
||||
@@ -267,7 +269,9 @@
|
||||
"cite_directly_or_import_references": "",
|
||||
"cite_faster": "",
|
||||
"clear_cached_files": "",
|
||||
"clear_filters": "",
|
||||
"clear_search": "",
|
||||
"clearing": "",
|
||||
"click_here_to_view_sl_in_lng": "",
|
||||
"click_to_unpause": "",
|
||||
"clicking_delete_will_remove_sso_config_and_clear_saml_data": "",
|
||||
@@ -359,6 +363,7 @@
|
||||
"create_project_in_github": "",
|
||||
"created": "",
|
||||
"created_at": "",
|
||||
"creating": "",
|
||||
"cross_reference": "",
|
||||
"current_file": "",
|
||||
"current_password": "",
|
||||
@@ -540,6 +545,7 @@
|
||||
"enables_real_time_syntax_checking_in_the_editor": "",
|
||||
"enabling": "",
|
||||
"end_of_document": "",
|
||||
"end_time_utc": "",
|
||||
"ensure_recover_account": "",
|
||||
"enter_any_size_including_units_or_valid_latex_command": "",
|
||||
"enter_the_code": "",
|
||||
@@ -556,6 +562,7 @@
|
||||
"error_processing_file": "",
|
||||
"errors": "",
|
||||
"essential_cookies_only": "",
|
||||
"event_type": "",
|
||||
"example_project": "",
|
||||
"existing_plan_active_until_term_end": "",
|
||||
"expand": "",
|
||||
@@ -573,6 +580,7 @@
|
||||
"fair_usage_policy_applies": "",
|
||||
"fast": "",
|
||||
"fast_draft": "",
|
||||
"feature_enabled_or_disabled": "",
|
||||
"features_like_track_changes": "",
|
||||
"feedback": "",
|
||||
"figure": "",
|
||||
@@ -646,6 +654,7 @@
|
||||
"generate_from_text_or_image": "",
|
||||
"generate_tables_and_equations": "",
|
||||
"generate_token": "",
|
||||
"generating": "",
|
||||
"generic_if_problem_continues_contact_us": "",
|
||||
"generic_linked_file_compile_error": "",
|
||||
"generic_something_went_wrong": "",
|
||||
@@ -1177,7 +1186,6 @@
|
||||
"open_pdf_in_separate_tab": "",
|
||||
"open_project": "",
|
||||
"open_target": "",
|
||||
"operation": "",
|
||||
"optional": "",
|
||||
"or": "",
|
||||
"organization_name": "",
|
||||
@@ -1393,9 +1401,11 @@
|
||||
"recompile_from_scratch": "",
|
||||
"recompile_pdf": "",
|
||||
"reconfirm_secondary_email": "",
|
||||
"reconfirming": "",
|
||||
"reconnect": "",
|
||||
"reconnecting": "",
|
||||
"reconnecting_in_x_secs": "",
|
||||
"recovering": "",
|
||||
"recurly_email_update_needed": "",
|
||||
"recurly_email_updated": "",
|
||||
"redirect_to_editor": "",
|
||||
@@ -1417,6 +1427,7 @@
|
||||
"refresh_page_after_starting_free_trial": "",
|
||||
"refreshing": "",
|
||||
"regards": "",
|
||||
"registering": "",
|
||||
"reject_change": "",
|
||||
"reject_selected_changes": "",
|
||||
"relink_your_account": "",
|
||||
@@ -1471,9 +1482,11 @@
|
||||
"restore_file_version": "",
|
||||
"restore_project_to_this_version": "",
|
||||
"restore_this_version": "",
|
||||
"restoring": "",
|
||||
"resync_completed": "",
|
||||
"resync_message": "",
|
||||
"resync_project_history": "",
|
||||
"resyncing": "",
|
||||
"retry_test": "",
|
||||
"reverse_x_sort_order": "",
|
||||
"revert_pending_plan_change": "",
|
||||
@@ -1576,6 +1589,7 @@
|
||||
"send_first_message": "",
|
||||
"send_message": "",
|
||||
"send_request": "",
|
||||
"sending": "",
|
||||
"server_error": "",
|
||||
"server_pro_license_entitlement_line_1": "",
|
||||
"server_pro_license_entitlement_line_2": "",
|
||||
@@ -1702,6 +1716,7 @@
|
||||
"start_free_trial": "",
|
||||
"start_free_trial_without_exclamation": "",
|
||||
"start_the_conversation_by_saying_hello_or_sharing_an_update": "",
|
||||
"start_time_utc": "",
|
||||
"start_typing_find_your_company": "",
|
||||
"start_typing_find_your_organization": "",
|
||||
"start_typing_find_your_university": "",
|
||||
@@ -1721,6 +1736,7 @@
|
||||
"subject_area": "",
|
||||
"subject_to_additional_vat": "",
|
||||
"submit_title": "",
|
||||
"submitting": "",
|
||||
"subscribe": "",
|
||||
"subscribe_to_find_the_symbols_you_need_faster": "",
|
||||
"subscribe_to_plan": "",
|
||||
@@ -2005,6 +2021,7 @@
|
||||
"unlinking": "",
|
||||
"unmerge_cells": "",
|
||||
"unpause_subscription": "",
|
||||
"unpausing": "",
|
||||
"unpublish": "",
|
||||
"unpublishing": "",
|
||||
"unsubscribe": "",
|
||||
|
||||
@@ -2,8 +2,8 @@ import OLFormGroup from '@/shared/components/ol/ol-form-group'
|
||||
import OLFormLabel from '@/shared/components/ol/ol-form-label'
|
||||
import OLFormSelect from '@/shared/components/ol/ol-form-select'
|
||||
import { ChangeEventHandler, useCallback, useEffect, useRef } from 'react'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { useEditorLeftMenuContext } from '@/features/editor-left-menu/components/editor-left-menu-context'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
type PossibleValue = string | number | boolean
|
||||
|
||||
@@ -82,14 +82,7 @@ export default function SettingsMenuSelect<T extends PossibleValue = string>({
|
||||
>
|
||||
<OLFormLabel>{label}</OLFormLabel>
|
||||
{loading ? (
|
||||
<p className="mb-0">
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
</p>
|
||||
<OLSpinner size="sm" />
|
||||
) : (
|
||||
<OLFormSelect
|
||||
size="sm"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { memo, useCallback, forwardRef } from 'react'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
@@ -18,6 +17,7 @@ import useEventListener from '../../../shared/hooks/use-event-listener'
|
||||
import { DetachRole } from '@/shared/context/detach-context'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import OLTooltip from '@/shared/components/ol/ol-tooltip'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
const isActiveDropdownItem = ({
|
||||
iconFor,
|
||||
@@ -171,24 +171,18 @@ export const LayoutDropdownButtonUi = ({
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<>
|
||||
{processing && (
|
||||
<div aria-live="assertive" className="visually-hidden">
|
||||
{t('layout_processing')}
|
||||
</div>
|
||||
)}
|
||||
<div aria-live="assertive" className="visually-hidden" id="layout-status">
|
||||
{processing ? t('layout_processing') : ''}
|
||||
</div>
|
||||
<Dropdown className="toolbar-item layout-dropdown" align="end">
|
||||
<DropdownToggle
|
||||
aria-describedby={processing ? 'layout-status' : undefined}
|
||||
id="layout-dropdown-btn"
|
||||
className="btn-full-height"
|
||||
as={LayoutDropdownToggleButton}
|
||||
>
|
||||
{processing ? (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
<OLSpinner size="sm" />
|
||||
) : (
|
||||
<MaterialIcon type="dock_to_right" className="align-middle" />
|
||||
)}
|
||||
@@ -257,15 +251,7 @@ export const LayoutDropdownButtonUi = ({
|
||||
detachIsLinked ? (
|
||||
'check'
|
||||
) : (
|
||||
<span className="spinner-container">
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
<span className="visually-hidden">{t('loading')}</span>
|
||||
</span>
|
||||
<OLSpinner size="sm" />
|
||||
)
|
||||
) : null
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useIdeRedesignSwitcherContext } from '../ide-react/context/ide-redesign
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { canUseNewEditorViaPrimaryFeatureFlag } from '../ide-redesign/utils/new-editor-utils'
|
||||
import { useSwitchEnableNewEditorState } from '../ide-redesign/hooks/use-switch-enable-new-editor-state'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
|
||||
const TryNewEditorButton = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -27,17 +26,9 @@ const TryNewEditorButton = () => {
|
||||
onClick={onClick}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
isLoading={loading}
|
||||
>
|
||||
{loading ? (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
) : (
|
||||
t('try_the_new_editor')
|
||||
)}
|
||||
{t('try_the_new_editor')}
|
||||
</OLButton>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -77,6 +77,7 @@ export function FileTreeModalCreateFileFooterContent({
|
||||
form="create-file"
|
||||
disabled={inFlight || !valid}
|
||||
isLoading={inFlight}
|
||||
loadingLabel={t('creating')}
|
||||
>
|
||||
{t('create')}
|
||||
</OLButton>
|
||||
|
||||
@@ -24,7 +24,7 @@ import OLFormGroup from '@/shared/components/ol/ol-form-group'
|
||||
import OLFormLabel from '@/shared/components/ol/ol-form-label'
|
||||
import OLForm from '@/shared/components/ol/ol-form'
|
||||
import OLFormSelect from '@/shared/components/ol/ol-form-select'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
export default function FileTreeImportFromProject() {
|
||||
const { t } = useTranslation()
|
||||
@@ -209,20 +209,8 @@ function SelectProject({
|
||||
|
||||
return (
|
||||
<OLFormGroup controlId="project-select">
|
||||
<OLFormLabel>{t('select_a_project')}</OLFormLabel>
|
||||
|
||||
{loading && (
|
||||
<span>
|
||||
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<OLFormLabel className="me-1">{t('select_a_project')}</OLFormLabel>
|
||||
{loading && <OLSpinner size="sm" />}
|
||||
<OLFormSelect
|
||||
disabled={!data}
|
||||
value={selectedProject ? selectedProject._id : ''}
|
||||
@@ -275,20 +263,8 @@ function SelectProjectOutputFile({
|
||||
className="row-spaced-small"
|
||||
controlId="project-output-file-select"
|
||||
>
|
||||
<OLFormLabel>{t('select_an_output_file')}</OLFormLabel>
|
||||
|
||||
{loading && (
|
||||
<span>
|
||||
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<OLFormLabel className="me-1">{t('select_an_output_file')}</OLFormLabel>
|
||||
{loading && <OLSpinner size="sm" />}
|
||||
<OLFormSelect
|
||||
disabled={!data}
|
||||
value={selectedProjectOutputFile?.path || ''}
|
||||
@@ -334,20 +310,8 @@ function SelectProjectEntity({
|
||||
|
||||
return (
|
||||
<OLFormGroup className="row-spaced-small" controlId="project-entity-select">
|
||||
<OLFormLabel>{t('select_a_file')}</OLFormLabel>
|
||||
|
||||
{loading && (
|
||||
<span>
|
||||
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<OLFormLabel className="me-1">{t('select_a_file')}</OLFormLabel>
|
||||
{loading && <OLSpinner size="sm" />}
|
||||
<OLFormSelect
|
||||
disabled={!data}
|
||||
value={selectedProjectEntity?.path || ''}
|
||||
|
||||
@@ -85,7 +85,12 @@ function FileTreeModalCreateFolder() {
|
||||
|
||||
<OLModalFooter>
|
||||
{inFlight ? (
|
||||
<OLButton variant="primary" disabled isLoading={inFlight} />
|
||||
<OLButton
|
||||
variant="primary"
|
||||
disabled
|
||||
isLoading={inFlight}
|
||||
loadingLabel={t('creating')}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<OLButton variant="secondary" onClick={handleHide}>
|
||||
|
||||
@@ -59,7 +59,12 @@ function FileTreeModalDelete() {
|
||||
|
||||
<OLModalFooter>
|
||||
{inFlight ? (
|
||||
<OLButton variant="danger" disabled isLoading />
|
||||
<OLButton
|
||||
variant="danger"
|
||||
disabled
|
||||
isLoading
|
||||
loadingLabel={t('deleting')}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<OLButton variant="secondary" onClick={handleHide}>
|
||||
|
||||
@@ -265,6 +265,7 @@ export function ManagersTable({
|
||||
variant="primary"
|
||||
onClick={addManagers}
|
||||
isLoading={inviteUserInflightCount > 0}
|
||||
loadingLabel={t('adding')}
|
||||
>
|
||||
{t('add')}
|
||||
</OLButton>
|
||||
|
||||
@@ -19,8 +19,8 @@ import { useGroupMembersContext } from '../../context/group-members-context'
|
||||
import getMeta from '@/utils/meta'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import DropdownListItem from '@/shared/components/dropdown/dropdown-list-item'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { sendMB } from '@/infrastructure/event-tracking'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
type resendInviteResponse = {
|
||||
success: boolean
|
||||
@@ -322,16 +322,7 @@ function MenuItemButton({
|
||||
as="button"
|
||||
tabIndex={-1}
|
||||
onClick={onClick}
|
||||
leadingIcon={
|
||||
isLoading ? (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
leadingIcon={isLoading ? <OLSpinner size="sm" /> : null}
|
||||
data-testid={dataTestId}
|
||||
variant={variant}
|
||||
>
|
||||
|
||||
@@ -128,6 +128,7 @@ export default function RemoveManagedUserModal({
|
||||
variant="danger"
|
||||
disabled={isLoading || isSuccess || !shouldEnableRemoveUserButton}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('removing')}
|
||||
>
|
||||
{t('remove_user')}
|
||||
</OLButton>
|
||||
|
||||
@@ -118,6 +118,7 @@ function AddLabelModal({ show, setShow, version }: AddLabelModalProps) {
|
||||
variant="primary"
|
||||
disabled={isLoading || !comment.length}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('adding')}
|
||||
>
|
||||
{t('history_add_label')}
|
||||
</OLButton>
|
||||
|
||||
@@ -122,6 +122,7 @@ const ChangeTag = forwardRef<HTMLElement, TagProps>(
|
||||
variant="danger"
|
||||
disabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('deleting')}
|
||||
onClick={localDeleteHandler}
|
||||
>
|
||||
{t('history_delete_label')}
|
||||
|
||||
@@ -51,6 +51,7 @@ export const RestoreProjectModal = ({
|
||||
onClick={onRestore}
|
||||
disabled={isRestoring}
|
||||
isLoading={isRestoring}
|
||||
loadingLabel={t('restoring')}
|
||||
>
|
||||
{t('restore')}
|
||||
</OLButton>
|
||||
|
||||
@@ -20,6 +20,7 @@ export default function ToolbarRestoreFileButton({
|
||||
size="sm"
|
||||
className="history-react-toolbar-restore-file-button"
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('restoring')}
|
||||
onClick={() => restoreDeletedFile(selection)}
|
||||
>
|
||||
{t('restore_file')}
|
||||
|
||||
@@ -37,6 +37,7 @@ function ToolbarRestoreFileToVersionButton({
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('restoring')}
|
||||
onClick={() => setShowConfirmModal(true)}
|
||||
>
|
||||
{t('restore_file_version')}
|
||||
|
||||
@@ -2,7 +2,7 @@ import OLFormSelect from '@/shared/components/ol/ol-form-select'
|
||||
import { ChangeEventHandler, useCallback } from 'react'
|
||||
import Setting from './setting'
|
||||
import classNames from 'classnames'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
type PossibleValue = string | number | boolean
|
||||
|
||||
@@ -64,12 +64,7 @@ export default function DropdownSetting<T extends PossibleValue = string>({
|
||||
return (
|
||||
<Setting controlId={id} label={label} description={description}>
|
||||
{loading ? (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
<OLSpinner size="sm" />
|
||||
) : (
|
||||
<OLFormSelect
|
||||
id={id}
|
||||
|
||||
@@ -11,8 +11,8 @@ import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useEventListener from '@/shared/hooks/use-event-listener'
|
||||
import { DetachRole } from '@/shared/context/detach-context'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
type LayoutOption = 'sideBySide' | 'editorOnly' | 'pdfOnly' | 'detachedPdf'
|
||||
|
||||
@@ -65,9 +65,7 @@ const LayoutDropdownItem = ({
|
||||
}) => {
|
||||
let trailingIcon: string | React.ReactNode | null = null
|
||||
if (processing) {
|
||||
trailingIcon = (
|
||||
<Spinner animation="border" aria-hidden="true" size="sm" role="status" />
|
||||
)
|
||||
trailingIcon = <OLSpinner size="sm" />
|
||||
} else if (active) {
|
||||
trailingIcon = 'check'
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ function DetachCompileButton() {
|
||||
})}
|
||||
size="sm"
|
||||
isLoading={compiling}
|
||||
loadingLabel={t('compiling')}
|
||||
>
|
||||
{t('recompile')}
|
||||
</OLButton>
|
||||
|
||||
@@ -9,7 +9,7 @@ import PdfHybridDownloadButton from './pdf-hybrid-download-button'
|
||||
import PdfHybridCodeCheckButton from './pdf-hybrid-code-check-button'
|
||||
import PdfOrphanRefreshButton from './pdf-orphan-refresh-button'
|
||||
import { DetachedSynctexControl } from './detach-synctex-control'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import LoadingSpinner from '@/shared/components/loading-spinner'
|
||||
|
||||
const ORPHAN_UI_TIMEOUT_MS = 5000
|
||||
|
||||
@@ -91,14 +91,7 @@ function PdfPreviewHybridToolbarConnectingInner() {
|
||||
return (
|
||||
<>
|
||||
<div className="toolbar-pdf-orphan">
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
|
||||
{t('tab_connecting')}…
|
||||
<LoadingSpinner size="sm" loadingText={`${t('tab_connecting')}…`} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -6,10 +6,10 @@ import { useTranslation } from 'react-i18next'
|
||||
import OLTooltip from '@/shared/components/ol/ol-tooltip'
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { Placement } from 'react-bootstrap/types'
|
||||
import useSynctex from '../hooks/use-synctex'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
const GoToCodeButton = memo(function GoToCodeButton({
|
||||
syncToCode,
|
||||
@@ -27,9 +27,7 @@ const GoToCodeButton = memo(function GoToCodeButton({
|
||||
|
||||
let buttonIcon = null
|
||||
if (syncToCodeInFlight) {
|
||||
buttonIcon = (
|
||||
<Spinner animation="border" aria-hidden="true" size="sm" role="status" />
|
||||
)
|
||||
buttonIcon = <OLSpinner size="sm" />
|
||||
} else if (!isDetachLayout) {
|
||||
buttonIcon = (
|
||||
<MaterialIcon type="arrow_left_alt" className="synctex-control-icon" />
|
||||
@@ -89,9 +87,7 @@ const GoToPdfButton = memo(function GoToPdfButton({
|
||||
|
||||
let buttonIcon = null
|
||||
if (syncToPdfInFlight) {
|
||||
buttonIcon = (
|
||||
<Spinner animation="border" aria-hidden="true" size="sm" role="status" />
|
||||
)
|
||||
buttonIcon = <OLSpinner size="sm" />
|
||||
} else if (!isDetachLayout) {
|
||||
buttonIcon = (
|
||||
<MaterialIcon type="arrow_right_alt" className="synctex-control-icon" />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
@@ -18,6 +17,7 @@ import { Project } from '../../../../../../types/project/dashboard/api'
|
||||
import CompileAndDownloadProjectPDFButton from '../table/cells/action-buttons/compile-and-download-project-pdf-button'
|
||||
import RenameProjectButton from '../table/cells/action-buttons/rename-project-button'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
type ActionDropdownProps = {
|
||||
project: Project
|
||||
@@ -89,13 +89,9 @@ function ActionsDropdown({ project }: ActionDropdownProps) {
|
||||
}}
|
||||
leadingIcon={
|
||||
pendingCompile ? (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
as="span"
|
||||
className="dropdown-item-leading-icon spinner"
|
||||
<OLSpinner
|
||||
size="sm"
|
||||
role="status"
|
||||
className="dropdown-item-leading-icon spinner"
|
||||
/>
|
||||
) : (
|
||||
'picture_as_pdf'
|
||||
|
||||
@@ -129,6 +129,7 @@ export default function CreateTagModal({
|
||||
status === 'pending' || !tagName?.length || !!validationError
|
||||
}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('creating')}
|
||||
>
|
||||
{t('create')}
|
||||
</OLButton>
|
||||
|
||||
@@ -72,6 +72,7 @@ export default function DeleteTagModal({
|
||||
variant="danger"
|
||||
disabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('deleting')}
|
||||
>
|
||||
{t('delete')}
|
||||
</OLButton>
|
||||
|
||||
@@ -139,6 +139,7 @@ export function EditTagModal({ id, tag, onEdit, onClose }: EditTagModalProps) {
|
||||
!!validationError
|
||||
}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('saving')}
|
||||
>
|
||||
{t('save')}
|
||||
</OLButton>
|
||||
|
||||
@@ -127,6 +127,7 @@ export function ManageTagModal({
|
||||
className="me-auto"
|
||||
disabled={isDeleteLoading || isUpdateLoading}
|
||||
isLoading={isDeleteLoading}
|
||||
loadingLabel={t('deleting')}
|
||||
>
|
||||
{t('delete_tag')}
|
||||
</OLButton>
|
||||
@@ -147,6 +148,7 @@ export function ManageTagModal({
|
||||
(newTagName === tag?.name && selectedColor === getTagColor(tag))
|
||||
)}
|
||||
isLoading={isUpdateLoading}
|
||||
loadingLabel={t('saving')}
|
||||
>
|
||||
{t('save_or_cancel-save')}
|
||||
</OLButton>
|
||||
|
||||
@@ -109,6 +109,7 @@ function ModalContentNewProjectForm({ onCancel, template = 'none' }: Props) {
|
||||
onClick={createNewProject}
|
||||
disabled={projectName === '' || isLoading || redirecting}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('creating')}
|
||||
>
|
||||
{t('create')}
|
||||
</OLButton>
|
||||
|
||||
@@ -58,6 +58,7 @@ function ReconfirmAffiliation({
|
||||
<OLButton
|
||||
variant="secondary"
|
||||
isLoading={isPending}
|
||||
loadingLabel={t('reconfirming')}
|
||||
disabled={isPending}
|
||||
onClick={() => {
|
||||
setIsPending(true)
|
||||
|
||||
@@ -9,7 +9,7 @@ import EmailsHeader from './emails/header'
|
||||
import EmailsRow from './emails/row'
|
||||
import AddEmail from './emails/add-email'
|
||||
import OLNotification from '@/shared/components/ol/ol-notification'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
import LoadingSpinner from '@/shared/components/loading-spinner'
|
||||
|
||||
function EmailsSectionContent() {
|
||||
const { t } = useTranslation()
|
||||
@@ -62,7 +62,7 @@ function EmailsSectionContent() {
|
||||
{isInitializing ? (
|
||||
<div className="affiliations-table-row-highlighted">
|
||||
<div className="affiliations-table-cell text-center">
|
||||
<OLSpinner size="sm" /> {t('loading')}...
|
||||
<LoadingSpinner size="sm" />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import OLButton, { OLButtonProps } from '@/shared/components/ol/ol-button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
function PrimaryButton({
|
||||
children,
|
||||
@@ -6,11 +7,13 @@ function PrimaryButton({
|
||||
isLoading,
|
||||
onClick,
|
||||
}: OLButtonProps) {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<OLButton
|
||||
size="sm"
|
||||
disabled={disabled && !isLoading}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('processing')}
|
||||
onClick={onClick}
|
||||
variant="secondary"
|
||||
>
|
||||
|
||||
@@ -22,6 +22,7 @@ function AddNewEmailBtn({
|
||||
variant="primary"
|
||||
disabled={(disabled && !isLoading) || !isValidEmail(email)}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('adding')}
|
||||
{...props}
|
||||
>
|
||||
{t('add_new_email')}
|
||||
|
||||
@@ -96,6 +96,7 @@ function ResendConfirmationCodeModal({
|
||||
variant={triggerVariant}
|
||||
disabled={groupLoading}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('sending')}
|
||||
onClick={handleResendConfirmationEmail}
|
||||
className={triggerVariant === 'link' ? 'btn-inline-link' : undefined}
|
||||
>
|
||||
|
||||
@@ -7,9 +7,9 @@ import classnames from 'classnames'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import Tag from '@/shared/components/tag'
|
||||
import { DropdownItem } from '@/shared/components/dropdown/dropdown-menu'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { Contact } from '../utils/types'
|
||||
import OLFormLabel from '@/shared/components/ol/ol-form-label'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
export type ContactItem = {
|
||||
email: string
|
||||
@@ -167,15 +167,7 @@ export default function SelectCollaborators({
|
||||
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
|
||||
<OLFormLabel className="small" {...getLabelProps()}>
|
||||
{t('add_email_address')}
|
||||
{loading && (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
className="ms-2"
|
||||
/>
|
||||
)}
|
||||
{loading && <OLSpinner size="sm" className="ms-2" />}
|
||||
</OLFormLabel>
|
||||
|
||||
<div className="host">
|
||||
|
||||
@@ -11,7 +11,7 @@ import OLModal, {
|
||||
} from '@/shared/components/ol/ol-modal'
|
||||
import OLNotification from '@/shared/components/ol/ol-notification'
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
const ReadOnlyTokenLink = lazy(() =>
|
||||
import('./link-sharing').then(({ ReadOnlyTokenLink }) => ({
|
||||
@@ -67,16 +67,7 @@ export default function ShareProjectModalContent({
|
||||
</OLModalBody>
|
||||
|
||||
<OLModalFooter>
|
||||
<div className="me-auto">
|
||||
{inFlight && (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="me-auto">{inFlight && <OLSpinner size="sm" />}</div>
|
||||
|
||||
<ClickableElementEnhancer
|
||||
onClick={cancel}
|
||||
|
||||
@@ -11,8 +11,8 @@ import OLModal, {
|
||||
} from '@/shared/components/ol/ol-modal'
|
||||
import OLNotification from '@/shared/components/ol/ol-notification'
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { ProjectMember } from '@/shared/context/types/project-metadata'
|
||||
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
||||
|
||||
export default function TransferOwnershipModal({
|
||||
member,
|
||||
@@ -68,16 +68,7 @@ export default function TransferOwnershipModal({
|
||||
)}
|
||||
</OLModalBody>
|
||||
<OLModalFooter>
|
||||
<div className="me-auto">
|
||||
{inflight && (
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
size="sm"
|
||||
role="status"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="me-auto">{inflight && <OLSpinner size="sm" />}</div>
|
||||
<OLButton variant="secondary" onClick={cancel} disabled={inflight}>
|
||||
{t('cancel')}
|
||||
</OLButton>
|
||||
|
||||
@@ -31,6 +31,7 @@ function ReactivateSubscription() {
|
||||
disabled={isLoading || isSuccess}
|
||||
onClick={handleReactivate}
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('reactivating')}
|
||||
>
|
||||
{t('reactivate_subscription')}
|
||||
</OLButton>
|
||||
|
||||
@@ -93,6 +93,7 @@ export function ConfirmUnpauseSubscriptionModal() {
|
||||
variant="primary"
|
||||
disabled={inflight}
|
||||
isLoading={inflight}
|
||||
loadingLabel={t('unpausing')}
|
||||
onClick={handleConfirmUnpause}
|
||||
>
|
||||
{t('unpause_subscription')}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { FC, useEffect, useMemo, useState } from 'react'
|
||||
import { WordCountData } from '@/features/word-count-modal/components/word-count-data'
|
||||
import { WordCountLoading } from '@/features/word-count-modal/components/word-count-loading'
|
||||
import { WordCountError } from '@/features/word-count-modal/components/word-count-error'
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import useAbortController from '@/shared/hooks/use-abort-controller'
|
||||
@@ -14,6 +13,7 @@ import { isMainFile } from '@/features/pdf-preview/util/editor-files'
|
||||
import { countWordsInFile } from '@/features/word-count-modal/utils/count-words-in-file'
|
||||
import { createSegmenters } from '@/features/word-count-modal/utils/segmenters'
|
||||
import { WordCountsClient } from './word-counts-client'
|
||||
import LoadingSpinner from '@/shared/components/loading-spinner'
|
||||
|
||||
export const WordCountClient: FC = () => {
|
||||
const [loading, setLoading] = useState(true)
|
||||
@@ -107,7 +107,7 @@ export const WordCountClient: FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{loading && !error && <WordCountLoading />}
|
||||
{loading && !error && <LoadingSpinner />}
|
||||
{error && <WordCountError />}
|
||||
{data && <WordCountsClient data={data} />}
|
||||
</>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Spinner } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export const WordCountLoading = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="loading">
|
||||
<Spinner animation="border" aria-hidden="true" size="sm" role="status" />
|
||||
|
||||
{t('loading')}…
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { FC, useEffect, useState } from 'react'
|
||||
import { ServerWordCountData } from '@/features/word-count-modal/components/word-count-data'
|
||||
import { WordCountLoading } from '@/features/word-count-modal/components/word-count-loading'
|
||||
import { WordCountError } from '@/features/word-count-modal/components/word-count-error'
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import { useLocalCompileContext } from '@/shared/context/local-compile-context'
|
||||
@@ -8,6 +7,7 @@ import useAbortController from '@/shared/hooks/use-abort-controller'
|
||||
import { getJSON } from '@/infrastructure/fetch-json'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import { WordCounts } from '@/features/word-count-modal/components/word-counts'
|
||||
import LoadingSpinner from '@/shared/components/loading-spinner'
|
||||
|
||||
export const WordCountServer: FC = () => {
|
||||
const { projectId } = useProjectContext()
|
||||
@@ -40,7 +40,7 @@ export const WordCountServer: FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{loading && !error && <WordCountLoading />}
|
||||
{loading && !error && <LoadingSpinner />}
|
||||
{error && <WordCountError />}
|
||||
{data && <WordCounts data={data} />}
|
||||
</>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { forwardRef } from 'react'
|
||||
import { Button as BS5Button, Spinner } from 'react-bootstrap'
|
||||
import { Button as BS5Button } from 'react-bootstrap'
|
||||
import type { ButtonProps } from '@/shared/components/types/button-props'
|
||||
import classNames from 'classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import OLSpinner from '../ol/ol-spinner'
|
||||
|
||||
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(
|
||||
@@ -56,13 +57,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
>
|
||||
{isLoading && (
|
||||
<span className="spinner-container">
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
as="span"
|
||||
className={loadingSpinnerClassName}
|
||||
role="status"
|
||||
/>
|
||||
<OLSpinner size="sm" className={loadingSpinnerClassName} />
|
||||
<span className="visually-hidden">
|
||||
{loadingLabel ?? t('loading')}
|
||||
</span>
|
||||
|
||||
@@ -42,6 +42,7 @@ function LoadingSpinner({
|
||||
|
||||
return (
|
||||
<div
|
||||
role="status"
|
||||
className={classNames(
|
||||
'loading',
|
||||
className,
|
||||
@@ -49,7 +50,6 @@ function LoadingSpinner({
|
||||
)}
|
||||
>
|
||||
<OLSpinner size={size} />
|
||||
|
||||
{loadingText || `${t('loading')}…`}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,13 +2,20 @@ import { Spinner } from 'react-bootstrap'
|
||||
|
||||
export type OLSpinnerSize = 'sm' | 'lg'
|
||||
|
||||
function OLSpinner({ size = 'sm' }: { size: OLSpinnerSize }) {
|
||||
function OLSpinner({
|
||||
size = 'sm',
|
||||
className,
|
||||
}: {
|
||||
size?: OLSpinnerSize
|
||||
className?: string
|
||||
}) {
|
||||
return (
|
||||
<Spinner
|
||||
size={size === 'sm' ? 'sm' : undefined}
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
role="status"
|
||||
className={className}
|
||||
data-testid="ol-spinner"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,10 +9,11 @@ import {
|
||||
import classNames from 'classnames'
|
||||
import { useSelect } from 'downshift'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Form, Spinner } from 'react-bootstrap'
|
||||
import { Form } from 'react-bootstrap'
|
||||
import FormControl from '@/shared/components/form/form-control'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { DropdownItem } from '@/shared/components/dropdown/dropdown-menu'
|
||||
import OLSpinner from './ol/ol-spinner'
|
||||
|
||||
export type SelectProps<T> = {
|
||||
// The items rendered as dropdown options.
|
||||
@@ -152,17 +153,7 @@ export const Select = <T,>({
|
||||
{optionalLabel && (
|
||||
<span className="fw-normal">({t('optional')})</span>
|
||||
)}{' '}
|
||||
{loading && (
|
||||
<span data-testid="spinner">
|
||||
<Spinner
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
as="span"
|
||||
role="status"
|
||||
size="sm"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
{loading && <OLSpinner size="sm" />}
|
||||
</Form.Label>
|
||||
) : null}
|
||||
<FormControl
|
||||
|
||||
@@ -64,7 +64,6 @@ import type { ScriptLogType } from '../../../modules/admin-panel/frontend/js/fea
|
||||
import { ActiveExperiment } from './labs-utils'
|
||||
import { Subscription as AdminSubscription } from '../../../types/admin/subscription'
|
||||
import { AdminCapability } from '../../../types/admin-capabilities'
|
||||
import { GroupAuditLog } from '../../../modules/group-audit-log/frontend/js/components/logs'
|
||||
import { AlgoliaConfig } from '../../../modules/algolia-search/frontend/js/types'
|
||||
import { WritefullPublicEnv } from '@wf/domain/writefull-public-env'
|
||||
|
||||
@@ -188,7 +187,6 @@ export interface Meta {
|
||||
'ol-legacyEditorThemes': string[]
|
||||
'ol-licenseQuantity'?: number
|
||||
'ol-loadingText': string
|
||||
'ol-logsForRendering': GroupAuditLog[]
|
||||
'ol-managedGroupSubscriptions': ManagedGroupSubscription[]
|
||||
'ol-managedInstitutions': ManagedInstitution[]
|
||||
'ol-managedPublishers': Publisher[]
|
||||
@@ -257,6 +255,7 @@ export interface Meta {
|
||||
'ol-showAiErrorAssistant': boolean
|
||||
'ol-showBrlGeoBanner': boolean
|
||||
'ol-showCouponField': boolean
|
||||
'ol-showFilters': boolean
|
||||
'ol-showGroupDiscount': boolean
|
||||
'ol-showGroupsAndEnterpriseBanner': boolean
|
||||
'ol-showInrGeoBanner': boolean
|
||||
|
||||
52
services/web/frontend/stories/loading-spinner.stories.tsx
Normal file
52
services/web/frontend/stories/loading-spinner.stories.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import LoadingSpinner, {
|
||||
FullSizeLoadingSpinner,
|
||||
} from '@/shared/components/loading-spinner'
|
||||
|
||||
type Story = StoryObj<typeof LoadingSpinner>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
loadingText: 'Loading content...',
|
||||
},
|
||||
}
|
||||
|
||||
export const WithDelay: Story = {
|
||||
args: {
|
||||
delay: 500,
|
||||
loadingText: 'This will appear after a 500ms delay...',
|
||||
},
|
||||
}
|
||||
|
||||
export const FullSize: StoryObj<typeof FullSizeLoadingSpinner> = {
|
||||
render: args => <FullSizeLoadingSpinner {...args} />,
|
||||
args: {
|
||||
loadingText: 'Loading entire section...',
|
||||
size: 'sm',
|
||||
},
|
||||
}
|
||||
|
||||
const meta: Meta<typeof LoadingSpinner> = {
|
||||
title: 'Shared / Components / Loading Spinner',
|
||||
component: LoadingSpinner,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
argTypes: {
|
||||
delay: {
|
||||
control: 'select',
|
||||
options: [0, 500],
|
||||
},
|
||||
size: {
|
||||
control: 'radio',
|
||||
options: ['lg', 'sm'],
|
||||
},
|
||||
},
|
||||
args: {
|
||||
size: 'sm',
|
||||
delay: 0,
|
||||
},
|
||||
render: args => <LoadingSpinner {...args} />,
|
||||
}
|
||||
|
||||
export default meta
|
||||
@@ -5,6 +5,7 @@
|
||||
.spinner-border {
|
||||
// Ensure the thickness of the spinner is independent of the font size of its container
|
||||
font-size: var(--font-size-03);
|
||||
margin-right: var(--spacing-02);
|
||||
}
|
||||
|
||||
// Adjust the small spinner to be 25% larger than Bootstrap's default in each dimension
|
||||
|
||||
@@ -538,6 +538,5 @@
|
||||
|
||||
max-height: 39px;
|
||||
font-size: var(--font-size-01);
|
||||
line-height: var(--line-height-01);
|
||||
margin-right: var(--spacing-04);
|
||||
}
|
||||
|
||||
@@ -345,6 +345,61 @@ $z-index-group-member-picker-list: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.group-discount-banner {
|
||||
border: 1px solid var(--neutral-20);
|
||||
border-radius: var(--border-radius-base);
|
||||
width: 50%;
|
||||
max-width: 576px;
|
||||
margin: auto;
|
||||
margin-top: var(--spacing-06);
|
||||
margin-bottom: var(--spacing-10);
|
||||
display: flex;
|
||||
gap: var(--spacing-06);
|
||||
padding: var(--spacing-06);
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.group-icon {
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
.text-and-cta {
|
||||
flex-grow: 8;
|
||||
display: flex;
|
||||
gap: var(--spacing-06);
|
||||
|
||||
@include media-breakpoint-down(lg) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.group-discount-text {
|
||||
flex-grow: 6;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.group-discount-text-heading {
|
||||
font-size: var(--font-size-03);
|
||||
font-weight: 600;
|
||||
line-height: var(--line-height-02);
|
||||
margin-bottom: var(--spacing-02);
|
||||
color: var(--neutral-90);
|
||||
}
|
||||
}
|
||||
|
||||
.group-discount-cta {
|
||||
flex-grow: 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.plans-new-table {
|
||||
width: 100%;
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
"alignment": "Alignment",
|
||||
"all": "All",
|
||||
"all_borders": "All borders",
|
||||
"all_events": "All events",
|
||||
"all_features_in_group_standard_plus": "All features in Group Standard, plus:",
|
||||
"all_logs": "All logs",
|
||||
"all_premium_features": "All premium features",
|
||||
@@ -176,6 +177,7 @@
|
||||
"anyone_with_link_can_view": "Anyone with this link can view this project",
|
||||
"app_on_x": "__appName__ on __social__",
|
||||
"appearance": "Appearance",
|
||||
"apply": "Apply ",
|
||||
"apply_educational_discount": "Apply educational discount",
|
||||
"apply_educational_discount_description": "40% discount for groups using __appName__ for teaching",
|
||||
"apply_educational_discount_description_with_group_discount": "Get a total of 40% off for groups using __appName__ for teaching",
|
||||
@@ -323,6 +325,7 @@
|
||||
"characters": "Characters",
|
||||
"chat": "Chat",
|
||||
"chat_error": "Could not load chat messages, please try again.",
|
||||
"chat_with_sales_team_50_or_more": "Chat with our sales team about larger discounts for groups of 50 or more.",
|
||||
"check_error_logs": "Check error logs",
|
||||
"check_your_email": "Check your email",
|
||||
"checking": "Checking",
|
||||
@@ -339,6 +342,7 @@
|
||||
"cite_faster": "Cite faster",
|
||||
"city": "City",
|
||||
"clear_cached_files": "Clear cached files",
|
||||
"clear_filters": "Clear filters",
|
||||
"clear_search": "clear search",
|
||||
"clear_sessions": "Clear sessions",
|
||||
"clear_sessions_description": "This is a list of other sessions (logins) which are active on your account, not including your current session. Click the \"Clear sessions\" button below to log them out.",
|
||||
@@ -693,6 +697,7 @@
|
||||
"enables_real_time_syntax_checking_in_the_editor": "Enables real-time syntax checking in the editor",
|
||||
"enabling": "Enabling",
|
||||
"end_of_document": "End of document",
|
||||
"end_time_utc": "End time (UTC)",
|
||||
"ensure_recover_account": "This will ensure that it can be used to recover your __appName__ account in case you lose access to your primary email address.",
|
||||
"enter_any_size_including_units_or_valid_latex_command": "Enter any size (including units) or valid LaTeX command",
|
||||
"enter_the_code": "Enter the 6-digit code sent to __email__.",
|
||||
@@ -714,6 +719,7 @@
|
||||
"es": "Spanish",
|
||||
"essential_cookies_only": "Essential cookies only",
|
||||
"estimated_number_of_overleaf_users": "Estimated number of __appName__ users",
|
||||
"event_type": "Event type",
|
||||
"every": "per",
|
||||
"everything_in_free_plus": "Everything in Free, plus…",
|
||||
"everything_in_group_professional_plus": "Everything in Group Professional, plus…",
|
||||
@@ -745,6 +751,7 @@
|
||||
"fast": "Fast",
|
||||
"fast_draft": "Fast [draft]",
|
||||
"fastest": "Fastest",
|
||||
"feature_enabled_or_disabled": "Feature enabled/disabled",
|
||||
"feature_included": "Feature included",
|
||||
"feature_not_included": "Feature not included",
|
||||
"featured": "Featured",
|
||||
@@ -844,6 +851,7 @@
|
||||
"generate_from_text_or_image": "From text or image",
|
||||
"generate_tables_and_equations": "Generate tables and equations from text and images. Try it for free in the Overleaf toolbar!",
|
||||
"generate_token": "Generate token",
|
||||
"generating": "Generating",
|
||||
"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",
|
||||
@@ -1179,6 +1187,7 @@
|
||||
"labs_program_benefits": "By signing up for Overleaf Labs you can get your hands on in-development features and try them out as much as you like. All we ask in return is your honest feedback to help us develop and improve. It’s important to note that features available in this program are still being tested and actively developed. This means they could change, be removed, or become part of a premium plan.",
|
||||
"language": "Language",
|
||||
"language_suggestions": "Language suggestions",
|
||||
"larger_discounts_available": "Larger discounts available",
|
||||
"last_active": "Last Active",
|
||||
"last_active_description": "Last time a project was opened.",
|
||||
"last_edit": "Last edit",
|
||||
@@ -1811,6 +1820,7 @@
|
||||
"reconfirm_account": "Reconfirm account",
|
||||
"reconfirm_explained": "We need to reconfirm your account. Please request a password reset link via the form below to reconfirm your account. If you have any problems reconfirming your account, please contact us at",
|
||||
"reconfirm_secondary_email": "To enhance the security of your __appName__ account, please reconfirm your secondary email address __emailAddress__.",
|
||||
"reconfirming": "Reconfirming",
|
||||
"reconnect": "Try again",
|
||||
"reconnecting": "Reconnecting",
|
||||
"reconnecting_in_x_secs": "Reconnecting in __seconds__ secs",
|
||||
@@ -1923,6 +1933,7 @@
|
||||
"resync_completed": "Resync completed!",
|
||||
"resync_message": "Resyncing project history can take several minutes depending on the size of the project.",
|
||||
"resync_project_history": "Resync Project History",
|
||||
"resyncing": "Resyncing",
|
||||
"retry_test": "Retry test",
|
||||
"return_to_login_page": "Return to Login page",
|
||||
"reverse_x_sort_order": "Reverse __x__ sort order",
|
||||
@@ -2188,6 +2199,7 @@
|
||||
"start_free_trial": "Start Free Trial!",
|
||||
"start_free_trial_without_exclamation": "Start Free Trial",
|
||||
"start_the_conversation_by_saying_hello_or_sharing_an_update": "Start the conversation by saying hello or sharing an update",
|
||||
"start_time_utc": "Start time (UTC)",
|
||||
"start_typing_find_your_company": " Start typing to find your company",
|
||||
"start_typing_find_your_organization": "Start typing to find your organization",
|
||||
"start_typing_find_your_university": "Start typing to find your university",
|
||||
@@ -2505,7 +2517,6 @@
|
||||
"uncategorized_projects": "Uncategorized Projects",
|
||||
"unconfirmed": "Unconfirmed",
|
||||
"undelete": "Undelete",
|
||||
"undeleting": "Undeleting",
|
||||
"understanding_labels": "Understanding labels",
|
||||
"undo": "Undo",
|
||||
"unfold_line": "Unfold line",
|
||||
@@ -2539,6 +2550,7 @@
|
||||
"unlinking": "Unlinking",
|
||||
"unmerge_cells": "Unmerge cells",
|
||||
"unpause_subscription": "Unpause subscription",
|
||||
"unpausing": "Unpausing",
|
||||
"unpublish": "Unpublish",
|
||||
"unpublishing": "Unpublishing",
|
||||
"unsubscribe": "Unsubscribe",
|
||||
|
||||
@@ -78,7 +78,11 @@ function RegisterForm({
|
||||
lg={4}
|
||||
className="mt-3 mt-lg-0 d-flex align-items-center flex-column flex-lg-row"
|
||||
>
|
||||
<OLButton type="submit" isLoading={isLoading}>
|
||||
<OLButton
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
loadingLabel={t('registering')}
|
||||
>
|
||||
Register
|
||||
</OLButton>
|
||||
</OLCol>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<svg width="37" height="40" viewBox="0 0 37 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M34.0038 27.9404C34.2069 27.3505 34.3111 26.7268 34.3111 26.0953C34.3111 23.8682 33.0273 21.9347 31.1602 20.9914C31.3372 20.7004 31.4909 20.3469 31.6028 19.9103C31.7461 19.3516 31.8034 18.6967 31.7591 18.164C31.7383 17.9093 31.7148 17.6702 31.6888 17.4442C31.4075 14.9338 30.0066 12.6859 27.8686 11.3346C26.4937 10.464 24.3245 9.72858 24.1553 8.82683C24.1474 8.79304 24.1422 8.75666 24.1344 8.72288C24.137 8.64492 24.1422 8.56436 24.1422 8.4864C24.1422 5.93446 22.5876 3.82171 20.3768 3.06808C19.882 2.87577 19.3378 2.76923 18.7414 2.76923C18.7128 2.76923 18.6815 2.76923 18.6529 2.76923C18.6242 2.76923 18.593 2.76923 18.5644 2.76923C17.968 2.76923 17.4238 2.87577 16.929 3.06808C14.7182 3.8243 13.1635 5.93446 13.1635 8.4864C13.1635 8.56696 13.1688 8.64492 13.1714 8.72288C13.1635 8.75666 13.1557 8.79304 13.1505 8.82683C12.9813 9.72858 10.8121 10.4666 9.43715 11.3346C7.29922 12.6859 5.89824 14.9338 5.617 17.4442C5.59096 17.6702 5.56752 17.9093 5.54669 18.164C5.49982 18.6967 5.55971 19.3516 5.70293 19.9103C5.81491 20.3469 5.96855 20.7029 6.14562 20.9914C4.27852 21.9347 2.99472 23.8682 2.99472 26.0953C2.99472 26.7268 3.10148 27.3505 3.302 27.9404C2.13278 29.1488 1.54166 30.8067 1.54166 32.8701V34.2241C1.54166 35.8846 2.89056 37.2308 4.55455 37.2308H32.7538C34.4178 37.2308 35.7667 35.8846 35.7667 34.2241V32.8701C35.7667 30.8067 35.1756 29.1488 34.0064 27.9404H34.0038Z" fill="#80CBA2"/>
|
||||
<path d="M14.5721 17.5385H23.5023C23.8058 17.5385 24.05 17.2906 24.05 16.9827V15.1589C24.05 13.8048 23.5203 12.508 22.5792 11.5505C22.2475 11.2139 21.8721 10.9295 21.4684 10.7025C21.9467 10.0607 22.227 9.24661 22.227 8.3569C22.227 6.29306 20.7253 4.61539 18.6914 4.61539C16.6574 4.61539 15.0041 6.29046 15.0041 8.3569C15.0041 9.26227 15.3203 10.092 15.8475 10.739C15.4669 10.9608 15.1146 11.2322 14.7984 11.5505C13.8547 12.508 13.5667 13.8048 13.5667 15.1589V16.5183C13.5667 17.0819 14.0167 17.5385 14.5721 17.5385ZM18.6888 6.65574C19.6145 6.65574 20.2136 7.4176 20.2136 8.3569C20.2136 9.29619 19.6119 10.0581 18.6888 10.0581C17.7657 10.0581 17.0123 9.29619 17.0123 8.3569C17.0123 7.4176 17.7631 6.65574 18.6888 6.65574ZM15.5775 14.6371C15.5775 14.0527 15.7703 13.476 16.1663 13.0507C16.6523 12.5289 17.254 12.2993 17.9585 12.1636C18.1925 12.1193 18.4317 12.0984 18.6708 12.0984H19.2879C20.2804 12.1141 20.5916 12.4193 21.1573 12.9933C21.723 13.5674 22.0418 14.3475 22.0418 15.1589C22.0418 15.3468 21.8927 15.4981 21.7075 15.4981H15.9169C15.7317 15.4981 15.5826 15.3468 15.5826 15.1589V14.6397L15.5775 14.6371Z" fill="black"/>
|
||||
<path d="M32.4027 29.0889C32.0612 28.7524 31.6748 28.468 31.2592 28.241C31.7515 27.5991 32.04 26.7851 32.04 25.8953C32.04 23.8315 30.4942 22.1538 28.4005 22.1538C26.3067 22.1538 24.6047 23.8289 24.6047 25.8953C24.6047 26.8007 24.9303 27.6304 25.4729 28.2775C25.0812 28.4993 24.7185 28.7706 24.393 29.0889C23.4215 30.0465 23.1251 31.3432 23.1251 32.6974V34.0567C23.1251 34.6203 23.5883 35.0769 24.16 35.0769H33.3529C33.6653 35.0769 33.9167 34.829 33.9167 34.5212V32.6974C33.9167 31.3432 33.3715 30.0465 32.4027 29.0889ZM28.3978 24.1942C29.3507 24.1942 29.9675 24.9561 29.9675 25.8953C29.9675 26.8346 29.3481 27.5965 28.3978 27.5965C27.4476 27.5965 26.672 26.8346 26.672 25.8953C26.672 24.9561 27.4449 24.1942 28.3978 24.1942ZM31.5027 33.0366H25.5417C25.3512 33.0366 25.1976 32.8852 25.1976 32.6974V32.1782C25.1976 31.5937 25.3962 31.0171 25.8038 30.5918C26.3041 30.07 26.9235 29.8404 27.6487 29.7047C27.8896 29.6603 28.1358 29.6395 28.3819 29.6395H29.0172C30.0389 29.6551 30.3592 29.9604 30.9416 30.5344C31.5239 31.1084 31.8521 31.8885 31.8521 32.7C31.8521 32.8878 31.6986 33.0392 31.508 33.0392L31.5027 33.0366Z" fill="black"/>
|
||||
<path d="M11.8341 28.241C12.3265 27.5991 12.615 26.7851 12.615 25.8953C12.615 23.8315 11.0692 22.1538 8.97542 22.1538C6.88167 22.1538 5.17967 23.8289 5.17967 25.8953C5.17967 26.8007 5.50524 27.6304 6.04787 28.2775C5.65612 28.4993 5.29349 28.7706 4.96791 29.0889C3.99647 30.0465 3.70001 31.3432 3.70001 32.6974V34.0567C3.70001 34.6203 4.16323 35.0769 4.73498 35.0769H13.9279C14.2402 35.0769 14.4917 34.829 14.4917 34.5212V32.6974C14.4917 31.3432 13.9464 30.0465 12.9776 29.0889C12.6362 28.7524 12.2497 28.468 11.8341 28.241ZM8.97277 24.1968C9.92568 24.1968 10.5424 24.9587 10.5424 25.898C10.5424 26.8372 9.92303 27.5991 8.97277 27.5991C8.02251 27.5991 7.24695 26.8372 7.24695 25.898C7.24695 24.9587 8.01986 24.1968 8.97277 24.1968ZM12.0777 33.0392H6.11669C5.92611 33.0392 5.77259 32.8878 5.77259 32.7V32.1808C5.77259 31.5963 5.97111 31.0197 6.37874 30.5944C6.87902 30.0726 7.49841 29.843 8.22368 29.7073C8.46455 29.6629 8.71072 29.6421 8.95689 29.6421H9.59216C10.6139 29.6577 10.9342 29.963 11.5165 30.537C12.0988 31.111 12.4271 31.8912 12.4271 32.7026C12.4271 32.8905 12.2735 33.0418 12.083 33.0418L12.0777 33.0392Z" fill="black"/>
|
||||
<path d="M27.8715 19.3063C27.8715 19.916 28.4282 20.4002 29.0682 20.2926C29.5677 20.2081 29.9424 19.7392 29.9059 19.2422C29.6354 15.4478 29.0838 14.5511 27.7128 12.7552C27.4552 12.417 27.0155 12.2351 26.5993 12.335C25.8604 12.5118 25.5794 13.3624 26.3937 14.3974C27.5437 15.9039 27.8715 17.2771 27.8715 19.3063Z" fill="black"/>
|
||||
<path d="M21.9215 27.8889C21.1343 28.1636 20.8286 28.2714 20.291 28.3639C18.9969 28.5847 17.6671 28.446 16.4417 27.9813C16.2303 27.9017 16.0239 27.8221 15.8201 27.7502C15.303 27.5654 14.7323 27.8375 14.5489 28.3613C14.3655 28.8851 14.6381 29.4576 15.1552 29.6425C16.3627 30.3357 17.1295 30.4616 18.411 30.4616C19.6924 30.4616 20.5764 30.4616 22.4615 29.6425C22.9787 29.4576 23.2513 28.8825 23.0679 28.3613C22.8844 27.8401 22.4412 27.704 21.9215 27.8914V27.8889Z" fill="black"/>
|
||||
<path d="M8.36483 20.2261C9.14108 20.5458 9.66675 19.8604 9.66675 19.3079C9.66675 17.2824 9.99904 15.9269 11.2029 14.4231C11.7885 13.6584 11.9111 12.7479 11.3745 12.5075C10.9033 12.1776 10.236 12.2645 9.88465 12.707C8.6481 14.7376 8.02437 14.9346 7.7166 18.3361C7.66757 18.8859 7.83099 20.0061 8.36756 20.2261H8.36483Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -434,7 +434,7 @@ describe('<PdfSynctexControls/>', function () {
|
||||
'not.be.disabled'
|
||||
)
|
||||
|
||||
cy.findByRole('status', { hidden: true }).should('not.exist')
|
||||
cy.findByTestId('ol-spinner').should('not.exist')
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
@@ -448,7 +448,7 @@ describe('<PdfSynctexControls/>', function () {
|
||||
'be.disabled'
|
||||
)
|
||||
|
||||
cy.findByRole('status', { hidden: true }).should('have.length', 1)
|
||||
cy.findByTestId('ol-spinner').should('have.length', 1)
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('<Select />', function () {
|
||||
describe('initial rendering', function () {
|
||||
it('renders default text', function () {
|
||||
render({ defaultText: 'Choose an item' })
|
||||
cy.findByTestId('spinner').should('not.exist')
|
||||
cy.findByTestId('ol-spinner').should('not.exist')
|
||||
cy.findByRole('combobox').should('have.value', 'Choose an item')
|
||||
})
|
||||
|
||||
@@ -102,7 +102,7 @@ describe('<Select />', function () {
|
||||
label: 'test label',
|
||||
loading: true,
|
||||
})
|
||||
cy.findByTestId('spinner')
|
||||
cy.findByTestId('ol-spinner')
|
||||
})
|
||||
|
||||
it('does not render a spinner while loading if there is no label', function () {
|
||||
@@ -110,7 +110,7 @@ describe('<Select />', function () {
|
||||
defaultText: 'Choose an item',
|
||||
loading: true,
|
||||
})
|
||||
cy.findByTestId('spinner').should('not.exist')
|
||||
cy.findByTestId('ol-spinner').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -884,7 +884,7 @@ describe('<UserNotifications />', function () {
|
||||
screen.getByRole('button', { name: 'Send confirmation code' })
|
||||
)
|
||||
|
||||
await waitForElementToBeRemoved(() => screen.getByText(/loading/i))
|
||||
await waitForElementToBeRemoved(() => screen.getByText(/sending/i))
|
||||
screen.getByText(/Enter the 6-digit code sent to foo@overleaf.com/i)
|
||||
expect(sendReconfirmationMock.callHistory.called()).to.be.true
|
||||
fireEvent.click(
|
||||
|
||||
@@ -220,7 +220,7 @@ describe('<EmailsSection />', function () {
|
||||
|
||||
await waitForElementToBeRemoved(() =>
|
||||
screen.getByRole('button', {
|
||||
name: 'Loading',
|
||||
name: /adding/i,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ describe('ProjectListController', function () {
|
||||
first_name: 'bjkdsjfk',
|
||||
features: {},
|
||||
emails: [{ email: 'test@overleaf.com' }],
|
||||
lastActive: new Date(1),
|
||||
lastActive: new Date(2),
|
||||
signUpDate: new Date(1),
|
||||
lastLoginIp: '111.111.111.112',
|
||||
}
|
||||
ctx.users = {
|
||||
|
||||
Reference in New Issue
Block a user