mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 22:23:42 +01:00
Add "Set as main document" to file tree menu (#30399)
GitOrigin-RevId: e05a7d0b103226bdc34e559d0d48c12183abdf5a
This commit is contained in:
@@ -1641,6 +1641,7 @@
|
||||
"session_error": "",
|
||||
"session_expired_redirecting_to_login": "",
|
||||
"sessions": "",
|
||||
"set_as_main_document": "",
|
||||
"set_color": "",
|
||||
"set_column_width": "",
|
||||
"set_up_single_sign_on": "",
|
||||
@@ -2260,6 +2261,7 @@
|
||||
"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_also_right_click_a_file_to_set_it_as_main": "",
|
||||
"you_can_buy_this_plan_but_not_as_a_trial": "",
|
||||
"you_can_manage_your_reference_manager_integrations_from_your_account_settings_page": "",
|
||||
"you_can_now_enable_sso": "",
|
||||
|
||||
+18
-3
@@ -23,6 +23,8 @@ function FileTreeItemMenuItems() {
|
||||
startUploadingDocOrFile,
|
||||
downloadPath,
|
||||
selectedFileName,
|
||||
canSetRootDocId,
|
||||
setRootDocId,
|
||||
} = useFileTreeActionable()
|
||||
|
||||
const { project } = useProjectContext()
|
||||
@@ -63,10 +65,23 @@ function FileTreeItemMenuItems() {
|
||||
</DropdownItem>
|
||||
</li>
|
||||
) : null}
|
||||
{canSetRootDocId ? (
|
||||
<>
|
||||
<DropdownDivider />
|
||||
<li role="none">
|
||||
<DropdownItem onClick={setRootDocId}>
|
||||
{t('set_as_main_document')}
|
||||
</DropdownItem>
|
||||
</li>
|
||||
</>
|
||||
) : null}
|
||||
{canDelete ? (
|
||||
<li role="none">
|
||||
<DropdownItem onClick={startDeleting}>{t('delete')}</DropdownItem>
|
||||
</li>
|
||||
<>
|
||||
<DropdownDivider />
|
||||
<li role="none">
|
||||
<DropdownItem onClick={startDeleting}>{t('delete')}</DropdownItem>
|
||||
</li>
|
||||
</>
|
||||
) : null}
|
||||
{canCreate ? (
|
||||
<>
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
NewDocEntity,
|
||||
NewLinkedFileEntity,
|
||||
NewEntity,
|
||||
syncRootDocId,
|
||||
} from '../util/sync-mutation'
|
||||
import { findInTree, findInTreeOrThrow } from '../util/find-in-tree'
|
||||
import { isNameUniqueInFolder } from '../util/is-name-unique-in-folder'
|
||||
@@ -39,6 +40,7 @@ import { useReferencesContext } from '@/features/ide-react/context/references-co
|
||||
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
|
||||
import { FileTreeEntity } from '@ol-types/file-tree-entity'
|
||||
import { Doc } from '@ol-types/doc'
|
||||
import { isValidTeXFile } from '@/main/is-valid-tex-file'
|
||||
|
||||
type DroppedFile = File & {
|
||||
relativePath?: string
|
||||
@@ -87,6 +89,8 @@ const FileTreeActionableContext = createContext<
|
||||
droppedFiles: { files: File[]; targetFolderId: string } | null
|
||||
setDroppedFiles: (value: DroppedFiles | null) => void
|
||||
downloadPath?: string
|
||||
canSetRootDocId: boolean
|
||||
setRootDocId: () => Promise<void>
|
||||
}
|
||||
| undefined
|
||||
>(undefined)
|
||||
@@ -230,11 +234,13 @@ function fileTreeActionableReducer(state: State, action: Action) {
|
||||
export const FileTreeActionableProvider: FC<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { projectId } = useProjectContext()
|
||||
const { projectId, project, updateProject } = useProjectContext()
|
||||
const { fileTreeReadOnly } = useFileTreeData()
|
||||
const { indexAllReferences } = useReferencesContext()
|
||||
const { write } = usePermissionsContext()
|
||||
|
||||
const rootDocId = project?.rootDocId
|
||||
|
||||
const [state, dispatch] = useReducer(
|
||||
fileTreeReadOnly
|
||||
? fileTreeActionableReadOnlyReducer
|
||||
@@ -522,6 +528,34 @@ export const FileTreeActionableProvider: FC<React.PropsWithChildren> = ({
|
||||
}
|
||||
}, [fileTreeData, projectId, selectedEntityIds])
|
||||
|
||||
const canSetRootDocId = useMemo(() => {
|
||||
// must have write permission on the project
|
||||
if (!write) {
|
||||
return false
|
||||
}
|
||||
|
||||
// must be only one file selected
|
||||
if (!selectedFileName) {
|
||||
return false
|
||||
}
|
||||
|
||||
// must not already be the root doc
|
||||
if (rootDocId && selectedEntityIds.has(rootDocId)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// must have a valid root doc extension
|
||||
return isValidTeXFile(selectedFileName)
|
||||
}, [rootDocId, selectedEntityIds, selectedFileName, write])
|
||||
|
||||
const setRootDocId = useCallback(async () => {
|
||||
const [selectedEntityId] = selectedEntityIds
|
||||
|
||||
await syncRootDocId(projectId, selectedEntityId)
|
||||
|
||||
updateProject({ rootDocId: selectedEntityId })
|
||||
}, [projectId, selectedEntityIds, updateProject])
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
canDelete: write && selectedEntityIds.size > 0 && !isRootFolderSelected,
|
||||
@@ -549,6 +583,8 @@ export const FileTreeActionableProvider: FC<React.PropsWithChildren> = ({
|
||||
droppedFiles,
|
||||
setDroppedFiles,
|
||||
downloadPath,
|
||||
canSetRootDocId,
|
||||
setRootDocId,
|
||||
}),
|
||||
[
|
||||
cancel,
|
||||
@@ -573,6 +609,8 @@ export const FileTreeActionableProvider: FC<React.PropsWithChildren> = ({
|
||||
startUploadingDocOrFile,
|
||||
state,
|
||||
write,
|
||||
canSetRootDocId,
|
||||
setRootDocId,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@@ -88,3 +88,9 @@ export function syncCreateEntity<T extends NewEntity>(
|
||||
function getEntityPathName(entityType: string) {
|
||||
return entityType === 'fileRef' ? 'file' : entityType
|
||||
}
|
||||
|
||||
export function syncRootDocId(projectId: string, rootDocId: string) {
|
||||
return postJSON(`/project/${projectId}/settings`, {
|
||||
body: { rootDocId },
|
||||
})
|
||||
}
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ export default function RootDocumentSetting() {
|
||||
<DropdownSetting
|
||||
id="rootDocId"
|
||||
label={t('main_document')}
|
||||
description={t('the_primary_file_for_compiling_your_project')}
|
||||
description={`${t('the_primary_file_for_compiling_your_project')} ${t('you_can_also_right_click_a_file_to_set_it_as_main')}`}
|
||||
disabled={!write}
|
||||
options={validDocsOptions}
|
||||
onChange={changeRootDocId}
|
||||
|
||||
Reference in New Issue
Block a user