Skip to content

Commit

Permalink
Add timeline history for maltekstseksjoner
Browse files Browse the repository at this point in the history
  • Loading branch information
eriksson-daniel authored and cskrov committed Jun 3, 2024
1 parent 3fb7855 commit 6652d9e
Show file tree
Hide file tree
Showing 23 changed files with 615 additions and 53 deletions.
1 change: 1 addition & 0 deletions frontend/src/components/date-picker/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const CURRENT_YEAR_IN_CENTURY = Number.parseInt(new Date().getFullYear().toString().slice(2), 10);
export const ISO_FORMAT = 'yyyy-MM-dd';
export const PRETTY_FORMAT = 'dd.MM.yyyy';
export const PRETTY_DATETIME_FORMAT = 'dd.MM.yyyy HH:mm:ss';
export const FORMAT = 'yyyy-MM-dd';
export const ISO_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EditableTitle } from '@app/components/editable-title/editable-title';
import { EditorName } from '@app/components/editor-name/editor-name';
import { Filters } from '@app/components/maltekstseksjoner/filters';
import { MaltekstseksjonTexts } from '@app/components/maltekstseksjoner/maltekstseksjon/texts';
import { MaltekstHistoryModal } from '@app/components/maltekstseksjoner/maltekstseksjon/timeline/timeline';
import {
TagContainer,
TemplateSectionTagList,
Expand All @@ -19,18 +20,24 @@ import {
useUpdateYtelseHjemmelIdListMutation,
} from '@app/redux-api/maltekstseksjoner/mutations';
import { IGetMaltekstseksjonParams } from '@app/types/maltekstseksjoner/params';
import { IDraftMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';
import { IDraftMaltekstseksjon, IMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';
import { Container, DateTimeContainer, Header, MetadataContainer } from '../common';
import { Actions } from './actions';
import { Sidebar } from './sidebar';

interface MaltekstProps {
maltekstseksjon: IDraftMaltekstseksjon;
nextMaltekstseksjon?: IMaltekstseksjon;
query: IGetMaltekstseksjonParams;
onDraftDeleted: () => void;
}

export const DraftMaltekstSection = ({ maltekstseksjon, query, onDraftDeleted }: MaltekstProps) => {
export const DraftMaltekstSection = ({
maltekstseksjon,
nextMaltekstseksjon,
query,
onDraftDeleted,
}: MaltekstProps) => {
const { id, title } = maltekstseksjon;
const [updateTitle, { isLoading: isUpdatingTitle }] = useUpdateMaltekstTitleMutation({
fixedCacheKey: `${maltekstseksjon.id}-title`,
Expand Down Expand Up @@ -65,6 +72,10 @@ export const DraftMaltekstSection = ({ maltekstseksjon, query, onDraftDeleted }:
</DateTimeContainer>
<span>av {lastEditor === undefined ? 'Ukjent' : <EditorName editorId={lastEditor.navIdent} />}</span>
<TextHistory {...maltekstseksjon} isUpdating={isUpdating} />
<MaltekstHistoryModal
maltekstseksjon={maltekstseksjon}
nextMaltekstseksjonDate={nextMaltekstseksjon?.publishedDateTime}
/>
</MetadataContainer>
<Filters maltekst={maltekstseksjon} query={query} />
<TagContainer>
Expand All @@ -77,7 +88,7 @@ export const DraftMaltekstSection = ({ maltekstseksjon, query, onDraftDeleted }:

<Sidebar maltekstseksjon={maltekstseksjon} query={query} />

<MaltekstseksjonTexts maltekstseksjon={maltekstseksjon} query={query} />
<MaltekstseksjonTexts maltekstseksjon={maltekstseksjon} nextMaltekstseksjon={nextMaltekstseksjon} query={query} />
</Container>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useGetTextVersionsQuery } from '@app/redux-api/texts/queries';
import { IGetMaltekstseksjonParams, RichTextTypes } from '@app/types/common-text-types';
import { isApiError } from '@app/types/errors';
import { IMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';
import { IText } from '@app/types/texts/responses';
import { DragAndDropContext } from '../drag-and-drop/drag-context';
import { TextLink } from '../text-link';

Expand Down Expand Up @@ -43,7 +44,10 @@ export const LoadTextListItem = ({ textId, maltekstseksjon, query }: LoadTextLis
[setDraggedTextId, textId],
);

const text = !isLoading && versions !== undefined ? versions[0] : undefined;
const text =
!isLoading && versions !== undefined
? getFirstText(versions, maltekstseksjon.publishedDateTime !== null)
: undefined;

const isReady = text !== undefined;

Expand Down Expand Up @@ -145,3 +149,11 @@ const HelpTextContainer = styled.div`
max-width: 300px;
white-space: normal;
`;

const getFirstText = (versions: IText[], isPublished: boolean) => {
if (isPublished) {
return versions.at(0);
}

return versions.find((v) => v.published);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DateTime } from '@app/components/datetime/datetime';
import { getTitle } from '@app/components/editable-title/editable-title';
import { EditorName } from '@app/components/editor-name/editor-name';
import { MaltekstseksjonTexts } from '@app/components/maltekstseksjoner/maltekstseksjon/texts';
import { MaltekstHistoryModal } from '@app/components/maltekstseksjoner/maltekstseksjon/timeline/timeline';
import {
TagContainer,
TemplateSectionTagList,
Expand All @@ -16,7 +17,7 @@ import {
import { TextHistory } from '@app/components/text-history/text-history';
import { useCreateDraftFromVersionMutation } from '@app/redux-api/maltekstseksjoner/mutations';
import { IGetMaltekstseksjonParams } from '@app/types/maltekstseksjoner/params';
import { IPublishedMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';
import { IMaltekstseksjon, IPublishedMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';
import { TextListItem } from '../styled-components';
import {
ActionsContainer,
Expand All @@ -31,11 +32,17 @@ import { LoadTextListItem } from './list-item';

interface MaltekstProps {
maltekstseksjon: IPublishedMaltekstseksjon;
nextMaltekstseksjon?: IMaltekstseksjon;
query: IGetMaltekstseksjonParams;
onDraftCreated: (versionId: string) => void;
}

export const PublishedMaltekstSection = ({ maltekstseksjon, query, onDraftCreated }: MaltekstProps) => {
export const PublishedMaltekstSection = ({
maltekstseksjon,
nextMaltekstseksjon,
query,
onDraftCreated,
}: MaltekstProps) => {
const { textId: activeTextId } = useParams<{ textId: string }>();
const { id, title, textIdList, publishedDateTime, versionId, publishedBy } = maltekstseksjon;
const [createDraft, { isLoading }] = useCreateDraftFromVersionMutation();
Expand All @@ -60,6 +67,10 @@ export const PublishedMaltekstSection = ({ maltekstseksjon, query, onDraftCreate
av {publishedBy === null ? 'Ukjent' : <EditorName editorId={publishedBy} />}
</LabelValue>
<TextHistory {...maltekstseksjon} isUpdating={false} />
<MaltekstHistoryModal
maltekstseksjon={maltekstseksjon}
nextMaltekstseksjonDate={nextMaltekstseksjon?.publishedDateTime}
/>
</Row>
<TagContainer>
<TemplateSectionTagList templateSectionIdList={maltekstseksjon.templateSectionIdList} />
Expand All @@ -83,7 +94,7 @@ export const PublishedMaltekstSection = ({ maltekstseksjon, query, onDraftCreate
</List>
</SidebarContainer>

<MaltekstseksjonTexts maltekstseksjon={maltekstseksjon} query={query} />
<MaltekstseksjonTexts maltekstseksjon={maltekstseksjon} nextMaltekstseksjon={nextMaltekstseksjon} query={query} />
</Container>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import { DraftMaltekstSection } from './draft/draft';
import { PublishedMaltekstSection } from './maltekstseksjon-published';

interface Props {
id: string;
maltekstseksjon: IMaltekstseksjon;
query: IGetMaltekstseksjonParams;
}

export const MaltekstseksjonVersions = ({ id, query }: Props) => {
const { data: versions, isLoading } = useGetMaltekstseksjonVersionsQuery(id);
export const MaltekstseksjonVersions = ({ maltekstseksjon, query }: Props) => {
const { data: versions, isLoading } = useGetMaltekstseksjonVersionsQuery(maltekstseksjon.id);

if (isLoading || versions === undefined) {
return null;
Expand Down Expand Up @@ -81,14 +81,24 @@ const Loaded = ({ versions, first, query }: LoadedProps) => {
selectedTabId={maltekstseksjonVersionId}
setSelectedTabId={setSelectedTabId}
versions={versions}
createDraftPanel={(version) => (
createDraftPanel={(version, nextVersion) => (
<PanelContent>
<DraftMaltekstSection maltekstseksjon={version} query={query} onDraftDeleted={onDraftDeleted} />
<DraftMaltekstSection
maltekstseksjon={version}
nextMaltekstseksjon={nextVersion}
query={query}
onDraftDeleted={onDraftDeleted}
/>
</PanelContent>
)}
createPublishedPanel={(version) => (
createPublishedPanel={(version, nextVersion) => (
<PanelContent>
<PublishedMaltekstSection maltekstseksjon={version} query={query} onDraftCreated={onDraftCreated} />
<PublishedMaltekstSection
maltekstseksjon={version}
nextMaltekstseksjon={nextVersion}
query={query}
onDraftCreated={onDraftCreated}
/>
</PanelContent>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const Maltekstseksjon = ({ maltekstseksjon, query }: Props) => (
<UnpublishMaltekstseksjonButton id={maltekstseksjon.id} title={maltekstseksjon.title} query={query} />
</MaltekstseksjonHeader>

<MaltekstseksjonVersions id={maltekstseksjon.id} query={query} />
<MaltekstseksjonVersions maltekstseksjon={maltekstseksjon} query={query} />
</MaltekstseksjonContainer>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,57 @@ import { Alert, Loader } from '@navikt/ds-react';
import React, { useEffect, useState } from 'react';
import { styled } from 'styled-components';
import { RedaktoerRichText } from '@app/components/redaktoer-rich-text/redaktoer-rich-text';
import { isNotUndefined } from '@app/functions/is-not-type-guards';
import { isRichText } from '@app/functions/is-rich-plain-text';
import { useRedaktoerLanguage } from '@app/hooks/use-redaktoer-language';
import { SPELL_CHECK_LANGUAGES } from '@app/hooks/use-smart-editor-language';
import { EditorValue } from '@app/plate/types';
import { useUpdateTextIdListMutation } from '@app/redux-api/maltekstseksjoner/mutations';
import { useLazyGetTextByIdQuery } from '@app/redux-api/texts/queries';
import { useLazyGetTextVersionsQuery } from '@app/redux-api/texts/queries';
import { isApiError } from '@app/types/errors';
import { IMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';
import { IRichText } from '@app/types/texts/responses';

interface Props {
maltekstseksjon: IMaltekstseksjon;
nextMaltekstseksjon?: IMaltekstseksjon;
}

export const MaltekstseksjonPreview = ({ maltekstseksjon }: Props) => {
export const MaltekstseksjonPreview = ({ maltekstseksjon, nextMaltekstseksjon }: Props) => {
const [, { isLoading: isUpdating }] = useUpdateTextIdListMutation({ fixedCacheKey: maltekstseksjon.id });
const [texts, setTexts] = useState<IRichText[]>([]);
const [error, setError] = useState<string | null>(null);
const [getText] = useLazyGetTextByIdQuery();
const [getTextVersions] = useLazyGetTextVersionsQuery();
const { textIdList } = maltekstseksjon;
const lang = useRedaktoerLanguage();
const editorId = `${textIdList.join(':')}-${lang}-preview`;

useEffect(() => {
setError(null);

const promises = textIdList.map((textId) => getText(textId, true).unwrap());
const promises = textIdList.map((textId) => getTextVersions(textId, true).unwrap());

Promise.all(promises)
.then((textVersionsList) =>
textVersionsList
.map((textVersions) =>
textVersions.find((v) => {
if (maltekstseksjon.publishedDateTime === null || nextMaltekstseksjon === undefined) {
return true;
}

if (nextMaltekstseksjon.publishedDateTime === null) {
return v.publishedDateTime !== null;
}

return v.publishedDateTime !== null && v.publishedDateTime < nextMaltekstseksjon.publishedDateTime;
}),
)
.filter(isNotUndefined),
)
.then((textList) => setTexts(textList.filter(isRichText)))
.catch((e) => setError('data' in e && isApiError(e.data) ? e.data.detail : e.message));
}, [getText, textIdList]);
}, [getTextVersions, maltekstseksjon.published, maltekstseksjon.publishedDateTime, nextMaltekstseksjon, textIdList]);

if (error !== null) {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IMaltekstseksjon } from '@app/types/maltekstseksjoner/responses';

interface Props {
maltekstseksjon: IMaltekstseksjon;
nextMaltekstseksjon?: IMaltekstseksjon;
query: IGetMaltekstseksjonParams;
}

Expand All @@ -17,7 +18,7 @@ enum TabsEnum {
EDIT = 'EDIT',
}

export const MaltekstseksjonTexts = ({ maltekstseksjon, query }: Props) => {
export const MaltekstseksjonTexts = ({ maltekstseksjon, nextMaltekstseksjon, query }: Props) => {
const [activeTab, setActiveTab] = useState<TabsEnum>(TabsEnum.PREVIEW);
const textCount = maltekstseksjon.textIdList.length;
const [previousTextCount, setPreviousTextCount] = useState(textCount);
Expand All @@ -41,10 +42,10 @@ export const MaltekstseksjonTexts = ({ maltekstseksjon, query }: Props) => {
<Tabs.Tab value={TabsEnum.PREVIEW} label="Forhåndsvisning" icon={<MagnifyingGlassIcon aria-hidden />} />
</Tabs.List>
<StyledTabPanel value={TabsEnum.PREVIEW}>
<MaltekstseksjonPreview maltekstseksjon={maltekstseksjon} />
<MaltekstseksjonPreview maltekstseksjon={maltekstseksjon} nextMaltekstseksjon={nextMaltekstseksjon} />
</StyledTabPanel>
<StyledTabPanel value={TabsEnum.EDIT}>
<TextList maltekstseksjon={maltekstseksjon} query={query} />
<TextList maltekstseksjon={maltekstseksjon} nextMaltekstseksjon={nextMaltekstseksjon} query={query} />
</StyledTabPanel>
</StyledTabs>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { format } from 'date-fns';
import React from 'react';
import { styled } from 'styled-components';
import { ISO_DATETIME_FORMAT } from '@app/components/date-picker/constants';
import { Time } from '@app/components/time/time';

interface Props {
from: Date;
to: Date;
value: Date;
onChange: (value: Date) => void;
}

export const PinTime = ({ from, to, value, onChange }: Props) => {
const minTime = from.getTime();
const maxTime = to.getTime();
const length = maxTime - minTime;
const min = 0;
const max = length;
const step = length / 1_000;

return (
<Container>
<Time date={to} />
<input
type="datetime-local"
value={format(value, ISO_DATETIME_FORMAT)}
onChange={(e) => onChange(new Date(Number.parseInt(e.target.value, 10)))}
/>
<RangeInput
type="range"
min={min}
max={max}
step={step}
onChange={(e) => onChange(new Date(maxTime - Number.parseInt(e.target.value, 10)))}
value={maxTime - value.getTime()}
/>
<Time date={from} />
</Container>
);
};

const Container = styled.div`
display: flex;
flex-direction: row;
gap: 8px;
`;

const RangeInput = styled.input`
flex-grow: 1;
`;
Loading

0 comments on commit 6652d9e

Please sign in to comment.