mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-06-03 08:28:54 -04:00
refactor: replace TypeORM with knex.js
Co-authored-by: Philip Molares <philip.molares@udo.edu> Signed-off-by: Philip Molares <philip.molares@udo.edu> Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
parent
6e151c8a1b
commit
c0ce00b3f9
242 changed files with 4601 additions and 6871 deletions
|
@ -6,8 +6,10 @@
|
|||
import { measurePerformance } from '../../../utils/measure-performance'
|
||||
import type { ParserOptions } from '@hedgedoc/html-to-react'
|
||||
import { convertHtmlToReact } from '@hedgedoc/html-to-react'
|
||||
import type DOMPurify from 'dompurify'
|
||||
import { sanitize } from 'dompurify'
|
||||
import DOMPurify from 'dompurify'
|
||||
// see https://github.com/cure53/DOMPurify/issues/1034#issuecomment-2493211056
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const { sanitize } = DOMPurify
|
||||
import React, { Fragment, useMemo } from 'react'
|
||||
|
||||
export interface HtmlToReactProps {
|
||||
|
|
|
@ -12,7 +12,7 @@ import React, { useCallback } from 'react'
|
|||
import { FileEarmarkPlus as IconPlus } from 'react-bootstrap-icons'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useFrontendConfig } from '../frontend-config-context/use-frontend-config'
|
||||
import { GuestAccess } from '@hedgedoc/commons'
|
||||
import { PermissionLevel } from '@hedgedoc/commons'
|
||||
import { useIsLoggedIn } from '../../../hooks/common/use-is-logged-in'
|
||||
|
||||
/**
|
||||
|
@ -27,14 +27,14 @@ export const NewNoteButton: React.FC = () => {
|
|||
const createNewNoteAndRedirect = useCallback((): void => {
|
||||
createNote('')
|
||||
.then((note) => {
|
||||
router?.push(`/n/${note.metadata.primaryAddress}`)
|
||||
router?.push(`/n/${note.metadata.primaryAlias}`)
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
showErrorNotification(error.message)
|
||||
})
|
||||
}, [router, showErrorNotification])
|
||||
|
||||
if (!isLoggedIn && guestAccessLevel !== GuestAccess.CREATE) {
|
||||
if (!isLoggedIn && guestAccessLevel !== PermissionLevel.CREATE) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('create non existing note hint', () => {
|
|||
.mockImplementation(async (markdown, primaryAlias): Promise<NoteDto> => {
|
||||
expect(markdown).toBe('')
|
||||
expect(primaryAlias).toBe(mockedNoteId)
|
||||
const metadata: NoteMetadataDto = Mock.of<NoteMetadataDto>({ primaryAddress: 'mockedPrimaryAlias' })
|
||||
const metadata: NoteMetadataDto = Mock.of<NoteMetadataDto>({ primaryAlias: 'mockedPrimaryAlias' })
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
await waitForOtherPromisesToFinish()
|
||||
return Mock.of<NoteDto>({ metadata })
|
||||
|
|
|
@ -11,7 +11,6 @@ import { NoteInfoLineUpdatedBy } from '../editor-page/sidebar/specific-sidebar-e
|
|||
import styles from './document-infobar.module.scss'
|
||||
import React from 'react'
|
||||
import { Pencil as IconPencil } from 'react-bootstrap-icons'
|
||||
import { Trans } from 'react-i18next'
|
||||
|
||||
/**
|
||||
* Renders an info bar with metadata about the current note.
|
||||
|
@ -34,10 +33,9 @@ export const DocumentInfobar: React.FC = () => {
|
|||
<hr />
|
||||
</div>
|
||||
<span className={'ms-auto'}>
|
||||
{noteDetails.viewCount} <Trans i18nKey={'views.readOnly.viewCount'} />
|
||||
<InternalLink
|
||||
text={''}
|
||||
href={`/n/${noteDetails.primaryAddress}`}
|
||||
href={`/n/${noteDetails.primaryAlias}`}
|
||||
icon={IconPencil}
|
||||
className={'text-primary text-decoration-none mx-1'}
|
||||
title={linkTitle}
|
||||
|
|
|
@ -53,14 +53,14 @@ export const useHandleUpload = (): handleUploadSignature => {
|
|||
: t('editor.upload.uploadFile.withoutDescription', { fileName: file.name })
|
||||
|
||||
const uploadPlaceholder = ``
|
||||
const noteId = getGlobalState().noteDetails?.id
|
||||
if (noteId === undefined) {
|
||||
const noteAlias = getGlobalState().noteDetails?.primaryAlias
|
||||
if (noteAlias === undefined) {
|
||||
return
|
||||
}
|
||||
changeContent(({ currentSelection }) => {
|
||||
return replaceSelection(cursorSelection ?? currentSelection, uploadPlaceholder, false)
|
||||
})
|
||||
uploadFile(noteId, file)
|
||||
uploadFile(noteAlias, file)
|
||||
.then(({ uuid }) => {
|
||||
const fullUrl = `${baseUrl}media/${uuid}`
|
||||
const replacement = ``
|
||||
|
|
|
@ -14,7 +14,7 @@ const LOCAL_FALLBACK_URL = 'ws://localhost:8080/realtime/'
|
|||
* Provides the URL for the realtime endpoint.
|
||||
*/
|
||||
export const useWebsocketUrl = (): URL | null => {
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.id)
|
||||
const noteAlias = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
const baseUrl = useBaseUrl()
|
||||
|
||||
const websocketUrl = useMemo(() => {
|
||||
|
@ -33,11 +33,11 @@ export const useWebsocketUrl = (): URL | null => {
|
|||
}, [baseUrl])
|
||||
|
||||
return useMemo(() => {
|
||||
if (noteId === '' || noteId === undefined) {
|
||||
if (noteAlias === '' || noteAlias === undefined) {
|
||||
return null
|
||||
}
|
||||
const url = new URL(websocketUrl)
|
||||
url.search = `?noteId=${noteId}`
|
||||
url.search = `?noteAlias=${noteAlias}`
|
||||
return url
|
||||
}, [noteId, websocketUrl])
|
||||
}, [noteAlias, websocketUrl])
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export const MediaBrowserSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
|
|||
selectedMenuId
|
||||
}) => {
|
||||
useTranslation()
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.id ?? '')
|
||||
const noteAlias = useApplicationState((state) => state.noteDetails?.primaryAlias ?? '')
|
||||
const [mediaEntryForDeletion, setMediaEntryForDeletion] = useState<MediaUploadDto | null>(null)
|
||||
|
||||
const hide = selectedMenuId !== DocumentSidebarMenuSelection.NONE && selectedMenuId !== menuId
|
||||
|
@ -43,7 +43,7 @@ export const MediaBrowserSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({
|
|||
onClick(menuId)
|
||||
}, [menuId, onClick])
|
||||
|
||||
const { value, loading, error } = useAsync(() => getMediaForNote(noteId), [expand, noteId])
|
||||
const { value, loading, error } = useAsync(() => getMediaForNote(noteAlias), [expand, noteAlias])
|
||||
|
||||
const mediaEntries = useMemo(() => {
|
||||
if (loading || error || !value) {
|
||||
|
|
|
@ -15,7 +15,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
*/
|
||||
export const NoteInfoLineUpdatedBy: React.FC = () => {
|
||||
useTranslation()
|
||||
const noteUpdateUser = useApplicationState((state) => state.noteDetails?.updateUsername)
|
||||
const noteUpdateUser = useApplicationState((state) => state.noteDetails?.lastUpdatedBy)
|
||||
|
||||
const userBlock = useMemo(() => {
|
||||
if (!noteUpdateUser) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { useTranslatedText } from '../../../../../../hooks/common/use-translated-text'
|
||||
import { UiIcon } from '../../../../../common/icons/ui-icon'
|
||||
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||
import { GuestAccess } from '@hedgedoc/commons'
|
||||
import { PermissionLevel } from '@hedgedoc/commons'
|
||||
import React, { useMemo } from 'react'
|
||||
import { Button, ToggleButtonGroup } from 'react-bootstrap'
|
||||
import { Eye as IconEye, Pencil as IconPencil, X as IconX } from 'react-bootstrap-icons'
|
||||
|
@ -24,7 +24,7 @@ export enum PermissionType {
|
|||
|
||||
export interface PermissionEntryButtonsProps {
|
||||
type: PermissionType
|
||||
currentSetting: GuestAccess
|
||||
currentSetting: PermissionLevel
|
||||
name: string
|
||||
onSetReadOnly: () => void
|
||||
onSetWriteable: () => void
|
||||
|
@ -79,14 +79,14 @@ export const PermissionEntryButtons: React.FC<PermissionEntryButtonsProps & Perm
|
|||
<Button
|
||||
disabled={disabled}
|
||||
title={setReadOnlyTitle}
|
||||
variant={currentSetting === GuestAccess.READ ? 'secondary' : 'outline-secondary'}
|
||||
variant={currentSetting === PermissionLevel.READ ? 'secondary' : 'outline-secondary'}
|
||||
onClick={onSetReadOnly}>
|
||||
<UiIcon icon={IconEye} />
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
title={setWritableTitle}
|
||||
variant={currentSetting === GuestAccess.WRITE ? 'secondary' : 'outline-secondary'}
|
||||
variant={currentSetting === PermissionLevel.WRITE ? 'secondary' : 'outline-secondary'}
|
||||
onClick={onSetWriteable}>
|
||||
<UiIcon icon={IconPencil} />
|
||||
</Button>
|
||||
|
|
|
@ -10,7 +10,7 @@ import { setNotePermissionsFromServer } from '../../../../../../redux/note-detai
|
|||
import { IconButton } from '../../../../../common/icon-button/icon-button'
|
||||
import { useUiNotifications } from '../../../../../notifications/ui-notification-boundary'
|
||||
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||
import { GuestAccess, SpecialGroup } from '@hedgedoc/commons'
|
||||
import { PermissionLevel, SpecialGroup } from '@hedgedoc/commons'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { ToggleButtonGroup } from 'react-bootstrap'
|
||||
import { Eye as IconEye, Pencil as IconPencil, SlashCircle as IconSlashCircle } from 'react-bootstrap-icons'
|
||||
|
@ -19,7 +19,7 @@ import { PermissionInconsistentAlert } from './permission-inconsistent-alert'
|
|||
import { cypressId } from '../../../../../../utils/cypress-attribute'
|
||||
|
||||
export interface PermissionEntrySpecialGroupProps {
|
||||
level: GuestAccess
|
||||
level: PermissionLevel
|
||||
type: SpecialGroup
|
||||
inconsistent?: boolean
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
|||
disabled,
|
||||
inconsistent
|
||||
}) => {
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.primaryAddress)
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
const { t } = useTranslation()
|
||||
const { showErrorNotification } = useUiNotifications()
|
||||
|
||||
|
@ -98,7 +98,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
|||
<IconButton
|
||||
icon={IconSlashCircle}
|
||||
title={denyGroupText}
|
||||
variant={level === GuestAccess.DENY ? 'secondary' : 'outline-secondary'}
|
||||
variant={level === PermissionLevel.DENY ? 'secondary' : 'outline-secondary'}
|
||||
onClick={onSetEntryDenied}
|
||||
disabled={disabled}
|
||||
className={'p-1'}
|
||||
|
@ -107,7 +107,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
|||
<IconButton
|
||||
icon={IconEye}
|
||||
title={viewOnlyGroupText}
|
||||
variant={level === GuestAccess.READ ? 'secondary' : 'outline-secondary'}
|
||||
variant={level === PermissionLevel.READ ? 'secondary' : 'outline-secondary'}
|
||||
onClick={onSetEntryReadOnly}
|
||||
disabled={disabled}
|
||||
className={'p-1'}
|
||||
|
@ -116,7 +116,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
|||
<IconButton
|
||||
icon={IconPencil}
|
||||
title={editGroupText}
|
||||
variant={level === GuestAccess.WRITE ? 'secondary' : 'outline-secondary'}
|
||||
variant={level === PermissionLevel.WRITE ? 'secondary' : 'outline-secondary'}
|
||||
onClick={onSetEntryWriteable}
|
||||
disabled={disabled}
|
||||
className={'p-1'}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { useUiNotifications } from '../../../../../notifications/ui-notification
|
|||
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||
import { PermissionEntryButtons, PermissionType } from './permission-entry-buttons'
|
||||
import type { NoteUserPermissionEntryDto } from '@hedgedoc/commons'
|
||||
import { GuestAccess, SpecialGroup } from '@hedgedoc/commons'
|
||||
import { PermissionLevel, SpecialGroup } from '@hedgedoc/commons'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { useAsync } from 'react-use'
|
||||
import { PermissionInconsistentAlert } from './permission-inconsistent-alert'
|
||||
|
@ -33,7 +33,7 @@ export const PermissionEntryUser: React.FC<PermissionEntryUserProps & Permission
|
|||
entry,
|
||||
disabled
|
||||
}) => {
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.primaryAddress)
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
const { showErrorNotification } = useUiNotifications()
|
||||
const { [SpecialGroup.EVERYONE]: everyonePermission, [SpecialGroup.LOGGED_IN]: loggedInPermission } =
|
||||
useGetSpecialPermissions()
|
||||
|
@ -94,7 +94,7 @@ export const PermissionEntryUser: React.FC<PermissionEntryUserProps & Permission
|
|||
<PermissionInconsistentAlert show={permissionInconsistent ?? false} />
|
||||
<PermissionEntryButtons
|
||||
type={PermissionType.USER}
|
||||
currentSetting={entry.canEdit ? GuestAccess.WRITE : GuestAccess.READ}
|
||||
currentSetting={entry.canEdit ? PermissionLevel.WRITE : PermissionLevel.READ}
|
||||
name={value.displayName}
|
||||
onSetReadOnly={onSetEntryReadOnly}
|
||||
onSetWriteable={onSetEntryWriteable}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { useIsOwner } from '../../../../../../hooks/common/use-is-owner'
|
||||
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||
import { PermissionEntrySpecialGroup } from './permission-entry-special-group'
|
||||
import { GuestAccess, SpecialGroup } from '@hedgedoc/commons'
|
||||
import { PermissionLevel, SpecialGroup } from '@hedgedoc/commons'
|
||||
import React, { Fragment, useMemo } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useGetSpecialPermissions } from './hooks/use-get-special-permissions'
|
||||
|
@ -23,8 +23,16 @@ export const PermissionSectionSpecialGroups: React.FC<PermissionDisabledProps> =
|
|||
|
||||
const specialGroupEntries = useMemo(() => {
|
||||
return {
|
||||
everyoneLevel: groupEveryone ? (groupEveryone.canEdit ? GuestAccess.WRITE : GuestAccess.READ) : GuestAccess.DENY,
|
||||
loggedInLevel: groupLoggedIn ? (groupLoggedIn.canEdit ? GuestAccess.WRITE : GuestAccess.READ) : GuestAccess.DENY,
|
||||
everyoneLevel: groupEveryone
|
||||
? groupEveryone.canEdit
|
||||
? PermissionLevel.WRITE
|
||||
: PermissionLevel.READ
|
||||
: PermissionLevel.DENY,
|
||||
loggedInLevel: groupLoggedIn
|
||||
? groupLoggedIn.canEdit
|
||||
? PermissionLevel.WRITE
|
||||
: PermissionLevel.READ
|
||||
: PermissionLevel.DENY,
|
||||
loggedInInconsistentAlert: groupEveryone && (!groupLoggedIn || (groupEveryone.canEdit && !groupLoggedIn.canEdit))
|
||||
}
|
||||
}, [groupEveryone, groupLoggedIn])
|
||||
|
|
|
@ -12,11 +12,11 @@ import React, { useMemo } from 'react'
|
|||
import { ListGroup } from 'react-bootstrap'
|
||||
|
||||
interface RevisionListProps {
|
||||
selectedRevisionId?: number
|
||||
selectedRevisionId?: string
|
||||
revisions?: RevisionMetadataDto[]
|
||||
loadingRevisions: boolean
|
||||
error?: Error | boolean
|
||||
onRevisionSelect: (selectedRevisionId: number) => void
|
||||
onRevisionSelect: (selectedRevisionId: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,10 +47,10 @@ export const RevisionList: React.FC<RevisionListProps> = ({
|
|||
})
|
||||
.map((revisionListEntry) => (
|
||||
<RevisionListEntry
|
||||
active={selectedRevisionId === revisionListEntry.id}
|
||||
onSelect={() => onRevisionSelect(revisionListEntry.id)}
|
||||
active={selectedRevisionId === revisionListEntry.uuid}
|
||||
onSelect={() => onRevisionSelect(revisionListEntry.uuid)}
|
||||
revision={revisionListEntry}
|
||||
key={revisionListEntry.id}
|
||||
key={revisionListEntry.uuid}
|
||||
/>
|
||||
))
|
||||
}, [loadingRevisions, onRevisionSelect, revisions, selectedRevisionId])
|
||||
|
|
|
@ -26,18 +26,18 @@ import { useAsync } from 'react-use'
|
|||
export const RevisionModalBody = ({ onShowDeleteModal, onHide }: RevisionModal) => {
|
||||
useTranslation()
|
||||
const isOwner = useIsOwner()
|
||||
const [selectedRevisionId, setSelectedRevisionId] = useState<number>()
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.id)
|
||||
const [selectedRevisionId, setSelectedRevisionId] = useState<string>()
|
||||
const noteAlias = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
const {
|
||||
value: revisions,
|
||||
error,
|
||||
loading
|
||||
} = useAsync(async () => {
|
||||
if (!noteId) {
|
||||
if (!noteAlias) {
|
||||
return []
|
||||
}
|
||||
return getAllRevisions(noteId)
|
||||
}, [noteId])
|
||||
return getAllRevisions(noteAlias)
|
||||
}, [noteAlias])
|
||||
|
||||
const revisionLength = revisions?.length ?? 0
|
||||
const enableDeleteRevisions = revisionLength > 1 && isOwner
|
||||
|
|
|
@ -15,7 +15,7 @@ import { Button, Modal } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
interface RevisionModalFooter {
|
||||
selectedRevisionId?: number
|
||||
selectedRevisionId?: string
|
||||
disableDeleteRevisions: boolean
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ export const RevisionModalFooter: React.FC<RevisionModalFooterProps> = ({
|
|||
disableDeleteRevisions
|
||||
}) => {
|
||||
useTranslation()
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.id)
|
||||
const noteAlias = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
const { showErrorNotification } = useUiNotifications()
|
||||
|
||||
const onRevertToRevision = useCallback(() => {
|
||||
|
@ -47,15 +47,15 @@ export const RevisionModalFooter: React.FC<RevisionModalFooterProps> = ({
|
|||
}, [])
|
||||
|
||||
const onDownloadRevision = useCallback(() => {
|
||||
if (selectedRevisionId === undefined || noteId === undefined) {
|
||||
if (selectedRevisionId === undefined || noteAlias === undefined) {
|
||||
return
|
||||
}
|
||||
getRevision(noteId, selectedRevisionId)
|
||||
getRevision(noteAlias, selectedRevisionId)
|
||||
.then((revision) => {
|
||||
downloadRevision(noteId, revision)
|
||||
downloadRevision(noteAlias, revision)
|
||||
})
|
||||
.catch(showErrorNotification(''))
|
||||
}, [noteId, selectedRevisionId, showErrorNotification])
|
||||
}, [noteAlias, selectedRevisionId, showErrorNotification])
|
||||
|
||||
const openDeleteModal = useCallback(() => {
|
||||
onHide?.()
|
||||
|
|
|
@ -14,7 +14,7 @@ import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer'
|
|||
import { useAsync } from 'react-use'
|
||||
|
||||
export interface RevisionViewerProps {
|
||||
selectedRevisionId?: number
|
||||
selectedRevisionId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ export interface RevisionViewerProps {
|
|||
* @param allRevisions List of metadata for all available revisions.
|
||||
*/
|
||||
export const RevisionViewer: React.FC<RevisionViewerProps> = ({ selectedRevisionId }) => {
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.id)
|
||||
const noteAlias = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
const darkModeEnabled = useDarkModeState()
|
||||
|
||||
const {
|
||||
|
@ -32,10 +32,10 @@ export const RevisionViewer: React.FC<RevisionViewerProps> = ({ selectedRevision
|
|||
error,
|
||||
loading
|
||||
} = useAsync(async () => {
|
||||
if (noteId && selectedRevisionId !== undefined) {
|
||||
return await getRevision(noteId, selectedRevisionId)
|
||||
if (noteAlias && selectedRevisionId !== undefined) {
|
||||
return await getRevision(noteAlias, selectedRevisionId)
|
||||
}
|
||||
}, [selectedRevisionId, noteId])
|
||||
}, [selectedRevisionId, noteAlias])
|
||||
|
||||
const previousRevisionContent = useMemo(() => {
|
||||
if (revision === undefined) {
|
||||
|
@ -49,7 +49,7 @@ export const RevisionViewer: React.FC<RevisionViewerProps> = ({ selectedRevision
|
|||
return applyPatch(revision.content, inversePatch) || ''
|
||||
}, [revision])
|
||||
|
||||
if (!noteId || selectedRevisionId === undefined) {
|
||||
if (!noteAlias || selectedRevisionId === undefined) {
|
||||
return <Fragment />
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,16 @@ export interface LinkFieldProps {
|
|||
*/
|
||||
export const NoteUrlField: React.FC<LinkFieldProps> = ({ type }) => {
|
||||
const baseUrl = useBaseUrl()
|
||||
const noteId = useApplicationState((state) => state.noteDetails?.id)
|
||||
const noteAlias = useApplicationState((state) => state.noteDetails?.primaryAlias)
|
||||
|
||||
const url = useMemo(() => {
|
||||
if (noteId === undefined) {
|
||||
if (noteAlias === undefined) {
|
||||
return null
|
||||
}
|
||||
const url = new URL(baseUrl)
|
||||
url.pathname += `${type}/${noteId}`
|
||||
url.pathname += `${type}/${noteAlias}`
|
||||
return url.toString()
|
||||
}, [baseUrl, noteId, type])
|
||||
}, [baseUrl, noteAlias, type])
|
||||
|
||||
return !url ? null : <CopyableField content={url} shareOriginUrl={url} />
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { NewNoteButton } from '../../common/new-note-button/new-note-button'
|
|||
import { HistoryButton } from '../../layout/app-bar/app-bar-elements/help-dropdown/history-button'
|
||||
import { useFrontendConfig } from '../../common/frontend-config-context/use-frontend-config'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { GuestAccess } from '@hedgedoc/commons'
|
||||
import { PermissionLevel } from '@hedgedoc/commons'
|
||||
|
||||
/**
|
||||
* Renders the card with the options for not logged-in users.
|
||||
|
@ -20,7 +20,7 @@ export const GuestCard: React.FC = () => {
|
|||
|
||||
useTranslation()
|
||||
|
||||
if (guestAccessLevel === GuestAccess.DENY) {
|
||||
if (guestAccessLevel === PermissionLevel.DENY) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ export const GuestCard: React.FC = () => {
|
|||
<NewNoteButton />
|
||||
<HistoryButton />
|
||||
</div>
|
||||
{guestAccessLevel !== GuestAccess.CREATE && (
|
||||
{guestAccessLevel !== PermissionLevel.CREATE && (
|
||||
<div className={'text-muted mt-2 small'}>
|
||||
<Trans i18nKey={'login.guest.noteCreationDisabled'} />
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import React, { Fragment, useMemo } from 'react'
|
||||
import { useFrontendConfig } from '../../common/frontend-config-context/use-frontend-config'
|
||||
import type { AuthProviderWithCustomNameDto } from '@hedgedoc/commons'
|
||||
import { ProviderType } from '@hedgedoc/commons'
|
||||
import { AuthProviderType } from '@hedgedoc/commons'
|
||||
import { LdapLoginCard } from './ldap-login-card'
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ export const LdapLoginCards: React.FC = () => {
|
|||
|
||||
const ldapProviders = useMemo(() => {
|
||||
return authProviders
|
||||
.filter((provider) => provider.type === ProviderType.LDAP)
|
||||
.filter((provider) => provider.type === AuthProviderType.LDAP)
|
||||
.map((provider) => {
|
||||
const ldapProvider = provider as AuthProviderWithCustomNameDto
|
||||
return (
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import React, { useMemo } from 'react'
|
||||
import { Card } from 'react-bootstrap'
|
||||
import { useFrontendConfig } from '../../common/frontend-config-context/use-frontend-config'
|
||||
import { ProviderType } from '@hedgedoc/commons'
|
||||
import { AuthProviderType } from '@hedgedoc/commons'
|
||||
import { LocalLoginCardBody } from './local-login-card-body'
|
||||
import { LocalRegisterCardBody } from './register/local-register-card-body'
|
||||
|
||||
|
@ -18,7 +18,7 @@ export const LocalLoginCard: React.FC = () => {
|
|||
const frontendConfig = useFrontendConfig()
|
||||
|
||||
const localLoginEnabled = useMemo(() => {
|
||||
return frontendConfig.authProviders.some((provider) => provider.type === ProviderType.LOCAL)
|
||||
return frontendConfig.authProviders.some((provider) => provider.type === AuthProviderType.LOCAL)
|
||||
}, [frontendConfig])
|
||||
|
||||
if (!localLoginEnabled) {
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from 'react-bootstrap-icons'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import type { AuthProviderDto } from '@hedgedoc/commons'
|
||||
import { ProviderType } from '@hedgedoc/commons'
|
||||
import { AuthProviderType } from '@hedgedoc/commons'
|
||||
import { IconGitlab } from '../../common/icons/additional/icon-gitlab'
|
||||
import styles from './one-click-login-button.module.scss'
|
||||
|
||||
|
@ -37,7 +37,7 @@ const logger = new Logger('GetOneClickProviderMetadata')
|
|||
* @return Name, icon, URL and CSS class of the given provider for rendering a login button.
|
||||
*/
|
||||
export const getOneClickProviderMetadata = (provider: AuthProviderDto): OneClickMetadata => {
|
||||
if (provider.type !== ProviderType.OIDC) {
|
||||
if (provider.type !== AuthProviderType.OIDC) {
|
||||
logger.warn('Metadata for one-click-provider does not exist', provider)
|
||||
return {
|
||||
name: '',
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import type { AuthProviderDto } from '@hedgedoc/commons'
|
||||
import { ProviderType } from '@hedgedoc/commons'
|
||||
import { AuthProviderType } from '@hedgedoc/commons'
|
||||
|
||||
/**
|
||||
* Filters the given auth providers to one-click providers only.
|
||||
|
@ -13,5 +13,5 @@ import { ProviderType } from '@hedgedoc/commons'
|
|||
* @return only one click auth providers
|
||||
*/
|
||||
export const filterOneClickProviders = (authProviders: AuthProviderDto[]) => {
|
||||
return authProviders.filter((provider: AuthProviderDto): boolean => provider.type === ProviderType.OIDC)
|
||||
return authProviders.filter((provider: AuthProviderDto): boolean => provider.type === AuthProviderType.OIDC)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue