refactor: abstract the logic of the value history to the recastBlock
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import React, { ReactNode, useRef, useEffect, useState } from 'react';
|
import React, { ReactNode, useRef, useEffect, useState } from 'react';
|
||||||
import { getPendantHistory } from '../utils';
|
|
||||||
import {
|
import {
|
||||||
getRecastItemValue,
|
getRecastItemValue,
|
||||||
RecastMetaProperty,
|
RecastMetaProperty,
|
||||||
@@ -30,6 +29,7 @@ export const PendantHistoryPanel = ({
|
|||||||
|
|
||||||
const [history, setHistory] = useState<RecastBlockValue[]>([]);
|
const [history, setHistory] = useState<RecastBlockValue[]>([]);
|
||||||
const popoverHandlerRef = useRef<{ [key: string]: PopperHandler }>({});
|
const popoverHandlerRef = useRef<{ [key: string]: PopperHandler }>({});
|
||||||
|
const { getValueHistory } = getRecastItemValue(block);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
@@ -38,7 +38,7 @@ export const PendantHistoryPanel = ({
|
|||||||
const missProperties = allProperties.filter(
|
const missProperties = allProperties.filter(
|
||||||
property => !currentBlockValues.find(v => v.id === property.id)
|
property => !currentBlockValues.find(v => v.id === property.id)
|
||||||
);
|
);
|
||||||
const pendantHistory = getPendantHistory({
|
const pendantHistory = getValueHistory({
|
||||||
recastBlockId: recastBlock.id,
|
recastBlockId: recastBlock.id,
|
||||||
});
|
});
|
||||||
const historyMap = missProperties.reduce<{
|
const historyMap = missProperties.reduce<{
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ export default ({
|
|||||||
user: { username, nickname, photo },
|
user: { username, nickname, photo },
|
||||||
} = useUserAndSpaces();
|
} = useUserAndSpaces();
|
||||||
|
|
||||||
const [selectedValue, setSelectedValue] = useState(initialValue?.value);
|
const [selectedValue, setSelectedValue] = useState(
|
||||||
|
initialValue?.value || ''
|
||||||
|
);
|
||||||
const [focus, setFocus] = useState(false);
|
const [focus, setFocus] = useState(false);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import { HelpCenterIcon } from '@toeverything/components/icons';
|
|||||||
import { PendantModifyPanel } from '../pendant-modify-panel';
|
import { PendantModifyPanel } from '../pendant-modify-panel';
|
||||||
import type { AsyncBlock } from '../../editor';
|
import type { AsyncBlock } from '../../editor';
|
||||||
import {
|
import {
|
||||||
|
getRecastItemValue,
|
||||||
type RecastBlockValue,
|
type RecastBlockValue,
|
||||||
type RecastMetaProperty,
|
type RecastMetaProperty,
|
||||||
} from '../../recast-block';
|
} from '../../recast-block';
|
||||||
import { getPendantConfigByType } from '../utils';
|
import { getPendantConfigByType } from '../utils';
|
||||||
import { usePendant } from '../use-pendant';
|
|
||||||
import {
|
import {
|
||||||
StyledPopoverWrapper,
|
StyledPopoverWrapper,
|
||||||
StyledOperationLabel,
|
StyledOperationLabel,
|
||||||
@@ -42,7 +42,8 @@ export const UpdatePendantPanel = ({
|
|||||||
}: Props) => {
|
}: Props) => {
|
||||||
const pendantOption = pendantOptions.find(v => v.type === property.type);
|
const pendantOption = pendantOptions.find(v => v.type === property.type);
|
||||||
const iconConfig = getPendantConfigByType(property.type);
|
const iconConfig = getPendantConfigByType(property.type);
|
||||||
const { removePendant } = usePendant(block);
|
const { removeValue } = getRecastItemValue(block);
|
||||||
|
|
||||||
const Icon = IconMap[iconConfig.iconName];
|
const Icon = IconMap[iconConfig.iconName];
|
||||||
const [fieldName, setFieldName] = useState(property.name);
|
const [fieldName, setFieldName] = useState(property.name);
|
||||||
const onUpdateSure = useOnUpdateSure({ block, property });
|
const onUpdateSure = useOnUpdateSure({ block, property });
|
||||||
@@ -108,7 +109,7 @@ export const UpdatePendantPanel = ({
|
|||||||
onDelete={
|
onDelete={
|
||||||
hasDelete
|
hasDelete
|
||||||
? async () => {
|
? async () => {
|
||||||
await removePendant(property);
|
await removeValue(property.id);
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import {
|
import {
|
||||||
genSelectOptionId,
|
genSelectOptionId,
|
||||||
|
getRecastItemValue,
|
||||||
type InformationProperty,
|
type InformationProperty,
|
||||||
type MultiSelectProperty,
|
type MultiSelectProperty,
|
||||||
type RecastMetaProperty,
|
type RecastMetaProperty,
|
||||||
type SelectOption,
|
type SelectOption,
|
||||||
type SelectProperty,
|
type SelectProperty,
|
||||||
|
useRecastBlock,
|
||||||
useRecastBlockMeta,
|
useRecastBlockMeta,
|
||||||
useSelectProperty,
|
useSelectProperty,
|
||||||
|
SelectValue,
|
||||||
|
MultiSelectValue,
|
||||||
|
StatusValue,
|
||||||
|
InformationValue,
|
||||||
|
TextValue,
|
||||||
|
DateValue,
|
||||||
} from '../../recast-block';
|
} from '../../recast-block';
|
||||||
import { type AsyncBlock } from '../../editor';
|
import { type AsyncBlock } from '../../editor';
|
||||||
import { usePendant } from '../use-pendant';
|
|
||||||
import {
|
import {
|
||||||
type OptionType,
|
type OptionType,
|
||||||
PendantTypes,
|
PendantTypes,
|
||||||
@@ -41,8 +48,8 @@ const genOptionWithId = (options: OptionType[] = []) => {
|
|||||||
export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
|
export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
|
||||||
const { addProperty } = useRecastBlockMeta();
|
const { addProperty } = useRecastBlockMeta();
|
||||||
const { createSelect } = useSelectProperty();
|
const { createSelect } = useSelectProperty();
|
||||||
const { setPendant } = usePendant(block);
|
const recastBlock = useRecastBlock();
|
||||||
|
const { setValue } = getRecastItemValue(block);
|
||||||
return async ({
|
return async ({
|
||||||
type,
|
type,
|
||||||
fieldName,
|
fieldName,
|
||||||
@@ -79,7 +86,15 @@ export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
|
|||||||
tempSelectedId: newValue,
|
tempSelectedId: newValue,
|
||||||
});
|
});
|
||||||
|
|
||||||
await setPendant(newProperty, selectedId);
|
await setValue(
|
||||||
|
{
|
||||||
|
id: newProperty.id,
|
||||||
|
type: newProperty.type,
|
||||||
|
value: selectedId,
|
||||||
|
} as SelectValue | MultiSelectValue | StatusValue,
|
||||||
|
recastBlock.id,
|
||||||
|
newProperty.id
|
||||||
|
);
|
||||||
} else if (type === PendantTypes.Information) {
|
} else if (type === PendantTypes.Information) {
|
||||||
const emailOptions = genOptionWithId(newPropertyItem.emailOptions);
|
const emailOptions = genOptionWithId(newPropertyItem.emailOptions);
|
||||||
|
|
||||||
@@ -97,7 +112,11 @@ export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
|
|||||||
locationOptions,
|
locationOptions,
|
||||||
} as Omit<InformationProperty, 'id'>);
|
} as Omit<InformationProperty, 'id'>);
|
||||||
|
|
||||||
await setPendant(newProperty, {
|
await setValue(
|
||||||
|
{
|
||||||
|
id: newProperty.id,
|
||||||
|
type: newProperty.type,
|
||||||
|
value: {
|
||||||
email: getOfficialSelected({
|
email: getOfficialSelected({
|
||||||
isMulti: true,
|
isMulti: true,
|
||||||
options: emailOptions,
|
options: emailOptions,
|
||||||
@@ -116,7 +135,11 @@ export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
|
|||||||
tempOptions: newPropertyItem.locationOptions,
|
tempOptions: newPropertyItem.locationOptions,
|
||||||
tempSelectedId: newValue.location,
|
tempSelectedId: newValue.location,
|
||||||
}),
|
}),
|
||||||
});
|
},
|
||||||
|
} as InformationValue,
|
||||||
|
recastBlock.id,
|
||||||
|
newProperty.id
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Color and background should use pendant config, but ui is not design now
|
// TODO: Color and background should use pendant config, but ui is not design now
|
||||||
const iconConfig = getPendantConfigByType(type);
|
const iconConfig = getPendantConfigByType(type);
|
||||||
@@ -129,8 +152,15 @@ export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
|
|||||||
color: iconConfig.color as CSSProperties['color'],
|
color: iconConfig.color as CSSProperties['color'],
|
||||||
iconName: iconConfig.iconName,
|
iconName: iconConfig.iconName,
|
||||||
});
|
});
|
||||||
|
await setValue(
|
||||||
await setPendant(newProperty, newValue);
|
{
|
||||||
|
id: newProperty.id,
|
||||||
|
type: newProperty.type,
|
||||||
|
value: newValue,
|
||||||
|
} as TextValue | DateValue,
|
||||||
|
recastBlock.id,
|
||||||
|
newProperty.id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -144,8 +174,9 @@ export const useOnUpdateSure = ({
|
|||||||
property: RecastMetaProperty;
|
property: RecastMetaProperty;
|
||||||
}) => {
|
}) => {
|
||||||
const { updateSelect } = useSelectProperty();
|
const { updateSelect } = useSelectProperty();
|
||||||
const { setPendant } = usePendant(block);
|
|
||||||
const { updateProperty } = useRecastBlockMeta();
|
const { updateProperty } = useRecastBlockMeta();
|
||||||
|
const { setValue } = getRecastItemValue(block);
|
||||||
|
const recastBlock = useRecastBlock();
|
||||||
|
|
||||||
return async ({
|
return async ({
|
||||||
type,
|
type,
|
||||||
@@ -199,7 +230,15 @@ export const useOnUpdateSure = ({
|
|||||||
tempSelectedId: newValue,
|
tempSelectedId: newValue,
|
||||||
});
|
});
|
||||||
|
|
||||||
await setPendant(selectProperty, selectedId);
|
await setValue(
|
||||||
|
{
|
||||||
|
id: selectProperty.id,
|
||||||
|
type: selectProperty.type,
|
||||||
|
value: selectedId,
|
||||||
|
} as SelectValue | MultiSelectValue | StatusValue,
|
||||||
|
recastBlock.id,
|
||||||
|
selectProperty.id
|
||||||
|
);
|
||||||
} else if (type === PendantTypes.Information) {
|
} else if (type === PendantTypes.Information) {
|
||||||
// const { emailOptions, phoneOptions, locationOptions } =
|
// const { emailOptions, phoneOptions, locationOptions } =
|
||||||
// property as InformationProperty;
|
// property as InformationProperty;
|
||||||
@@ -231,7 +270,11 @@ export const useOnUpdateSure = ({
|
|||||||
locationOptions,
|
locationOptions,
|
||||||
} as InformationProperty);
|
} as InformationProperty);
|
||||||
|
|
||||||
await setPendant(newProperty, {
|
await setValue(
|
||||||
|
{
|
||||||
|
id: newProperty.id,
|
||||||
|
type: newProperty.type,
|
||||||
|
value: {
|
||||||
email: getOfficialSelected({
|
email: getOfficialSelected({
|
||||||
isMulti: true,
|
isMulti: true,
|
||||||
options: emailOptions as SelectOption[],
|
options: emailOptions as SelectOption[],
|
||||||
@@ -250,9 +293,21 @@ export const useOnUpdateSure = ({
|
|||||||
tempOptions: newPropertyItem.locationOptions,
|
tempOptions: newPropertyItem.locationOptions,
|
||||||
tempSelectedId: newValue.location,
|
tempSelectedId: newValue.location,
|
||||||
}),
|
}),
|
||||||
});
|
},
|
||||||
|
} as InformationValue,
|
||||||
|
recastBlock.id,
|
||||||
|
newProperty.id
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
await setPendant(property, newValue);
|
await setValue(
|
||||||
|
{
|
||||||
|
id: property.id,
|
||||||
|
type: property.type,
|
||||||
|
value: newValue,
|
||||||
|
} as TextValue | DateValue,
|
||||||
|
recastBlock.id,
|
||||||
|
property.id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldName !== property.name) {
|
if (fieldName !== property.name) {
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import { getPendantController } from './utils';
|
|
||||||
import { AsyncBlock } from '../editor';
|
|
||||||
import { useRecastBlock } from '../recast-block';
|
|
||||||
|
|
||||||
export const usePendant = (block: AsyncBlock) => {
|
|
||||||
// const { getProperties, removeProperty } = useRecastBlockMeta();
|
|
||||||
const recastBlock = useRecastBlock();
|
|
||||||
|
|
||||||
return getPendantController(recastBlock, block);
|
|
||||||
};
|
|
||||||
@@ -1,124 +1,7 @@
|
|||||||
import {
|
import { PropertyType, SelectOption } from '../recast-block';
|
||||||
getRecastItemValue,
|
|
||||||
PropertyType,
|
|
||||||
RecastBlock,
|
|
||||||
RecastItem,
|
|
||||||
RecastMetaProperty,
|
|
||||||
RecastPropertyId,
|
|
||||||
SelectOption,
|
|
||||||
} from '../recast-block';
|
|
||||||
import { OptionIdType, OptionType, PendantConfig, PendantTypes } from './types';
|
import { OptionIdType, OptionType, PendantConfig, PendantTypes } from './types';
|
||||||
import { pendantConfig } from './config';
|
import { pendantConfig } from './config';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { AsyncBlock } from '../editor';
|
|
||||||
type Props = {
|
|
||||||
recastBlockId: string;
|
|
||||||
blockId: string;
|
|
||||||
propertyId: RecastPropertyId;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StorageMap = {
|
|
||||||
[recastBlockId: string]: {
|
|
||||||
[propertyId: RecastPropertyId]: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const LOCAL_STORAGE_NAME = 'TEMPORARY_PENDANT_DATA';
|
|
||||||
|
|
||||||
const ensureLocalStorage = () => {
|
|
||||||
const data = localStorage.getItem(LOCAL_STORAGE_NAME);
|
|
||||||
if (!data) {
|
|
||||||
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify({}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setPendantHistory = ({
|
|
||||||
recastBlockId,
|
|
||||||
blockId,
|
|
||||||
propertyId,
|
|
||||||
}: Props) => {
|
|
||||||
ensureLocalStorage();
|
|
||||||
const data: StorageMap = JSON.parse(
|
|
||||||
localStorage.getItem(LOCAL_STORAGE_NAME) as string
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!data[recastBlockId]) {
|
|
||||||
data[recastBlockId] = {};
|
|
||||||
}
|
|
||||||
const propertyValueRecord = data[recastBlockId];
|
|
||||||
propertyValueRecord[propertyId] = blockId;
|
|
||||||
|
|
||||||
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(data));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getPendantHistory = ({
|
|
||||||
recastBlockId,
|
|
||||||
}: {
|
|
||||||
recastBlockId: string;
|
|
||||||
}) => {
|
|
||||||
ensureLocalStorage();
|
|
||||||
const data: StorageMap = JSON.parse(
|
|
||||||
localStorage.getItem(LOCAL_STORAGE_NAME) as string
|
|
||||||
);
|
|
||||||
|
|
||||||
return data[recastBlockId] ?? {};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removePendantHistory = ({
|
|
||||||
recastBlockId,
|
|
||||||
propertyId,
|
|
||||||
}: {
|
|
||||||
recastBlockId: string;
|
|
||||||
propertyId: RecastPropertyId;
|
|
||||||
}) => {
|
|
||||||
ensureLocalStorage();
|
|
||||||
const data: StorageMap = JSON.parse(
|
|
||||||
localStorage.getItem(LOCAL_STORAGE_NAME) as string
|
|
||||||
);
|
|
||||||
if (!data[recastBlockId]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete data[recastBlockId][propertyId];
|
|
||||||
|
|
||||||
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(data));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getPendantController = (
|
|
||||||
recastBlock: RecastBlock,
|
|
||||||
block: AsyncBlock | RecastItem
|
|
||||||
) => {
|
|
||||||
const { setValue, removeValue } = getRecastItemValue(block);
|
|
||||||
|
|
||||||
const setPendant = async (property: RecastMetaProperty, newValue: any) => {
|
|
||||||
const nv = {
|
|
||||||
id: property.id,
|
|
||||||
type: property.type,
|
|
||||||
value: newValue,
|
|
||||||
};
|
|
||||||
|
|
||||||
setPendantHistory({
|
|
||||||
recastBlockId: recastBlock.id,
|
|
||||||
blockId: block.id,
|
|
||||||
propertyId: property.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return await setValue(nv);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removePendant = async (property: RecastMetaProperty) => {
|
|
||||||
removePendantHistory({
|
|
||||||
recastBlockId: block.id,
|
|
||||||
propertyId: property.id,
|
|
||||||
});
|
|
||||||
return await removeValue(property.id);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
setPendant,
|
|
||||||
removePendant,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In select pendant panel, use mock options instead of use `createSelect` when add or delete option
|
* In select pendant panel, use mock options instead of use `createSelect` when add or delete option
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
generateInitialOptions,
|
generateInitialOptions,
|
||||||
generateRandomFieldName,
|
generateRandomFieldName,
|
||||||
getPendantIconsConfigByName,
|
getPendantIconsConfigByName,
|
||||||
getPendantController,
|
|
||||||
} from '../block-pendant/utils';
|
} from '../block-pendant/utils';
|
||||||
import { SelectOption } from '../recast-block';
|
import { SelectOption } from '../recast-block';
|
||||||
|
|
||||||
@@ -117,31 +116,60 @@ export const moveCardToGroup = async ({
|
|||||||
group: KanbanGroup;
|
group: KanbanGroup;
|
||||||
recastBlock: RecastBlock;
|
recastBlock: RecastBlock;
|
||||||
}) => {
|
}) => {
|
||||||
const { setPendant, removePendant } = getPendantController(
|
const { setValue, removeValue } = getRecastItemValue(cardBlock);
|
||||||
recastBlock,
|
|
||||||
cardBlock
|
|
||||||
);
|
|
||||||
let success = false;
|
let success = false;
|
||||||
if (group.id === DEFAULT_GROUP_ID) {
|
if (group.id === DEFAULT_GROUP_ID) {
|
||||||
success = await removePendant(groupBy);
|
success = await removeValue(groupBy.id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (group.type) {
|
switch (group.type) {
|
||||||
case PropertyType.Select: {
|
case PropertyType.Select: {
|
||||||
success = await setPendant(groupBy, group.id);
|
success = await setValue(
|
||||||
|
{
|
||||||
|
id: groupBy.id,
|
||||||
|
type: group.type,
|
||||||
|
value: group.id,
|
||||||
|
},
|
||||||
|
recastBlock.id,
|
||||||
|
groupBy.id
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PropertyType.Status: {
|
case PropertyType.Status: {
|
||||||
success = await setPendant(groupBy, group.id);
|
success = await setValue(
|
||||||
|
{
|
||||||
|
id: groupBy.id,
|
||||||
|
type: group.type,
|
||||||
|
value: group.id,
|
||||||
|
},
|
||||||
|
recastBlock.id,
|
||||||
|
groupBy.id
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PropertyType.MultiSelect: {
|
case PropertyType.MultiSelect: {
|
||||||
success = await setPendant(groupBy, [group.id]);
|
success = await setValue(
|
||||||
|
{
|
||||||
|
id: groupBy.id,
|
||||||
|
type: group.type,
|
||||||
|
value: [group.id],
|
||||||
|
},
|
||||||
|
recastBlock.id,
|
||||||
|
groupBy.id
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PropertyType.Text: {
|
case PropertyType.Text: {
|
||||||
success = await setPendant(groupBy, group.id);
|
success = await setValue(
|
||||||
|
{
|
||||||
|
id: groupBy.id,
|
||||||
|
type: group.type,
|
||||||
|
value: group.id,
|
||||||
|
},
|
||||||
|
recastBlock.id,
|
||||||
|
groupBy.id
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
67
libs/components/editor-core/src/recast-block/history.ts
Normal file
67
libs/components/editor-core/src/recast-block/history.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { RecastPropertyId } from './types';
|
||||||
|
|
||||||
|
// TODO: The logic for keeping history should be supported by the network layer
|
||||||
|
type Props = {
|
||||||
|
recastBlockId: string;
|
||||||
|
blockId: string;
|
||||||
|
propertyId: RecastPropertyId;
|
||||||
|
};
|
||||||
|
|
||||||
|
type HistoryStorageMap = {
|
||||||
|
[recastBlockId: string]: {
|
||||||
|
[propertyId: RecastPropertyId]: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const LOCAL_STORAGE_NAME = 'TEMPORARY_HISTORY_DATA';
|
||||||
|
|
||||||
|
const ensureLocalStorage = () => {
|
||||||
|
const data = localStorage.getItem(LOCAL_STORAGE_NAME);
|
||||||
|
if (!data) {
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify({}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setHistory = ({ recastBlockId, blockId, propertyId }: Props) => {
|
||||||
|
ensureLocalStorage();
|
||||||
|
const data: HistoryStorageMap = JSON.parse(
|
||||||
|
localStorage.getItem(LOCAL_STORAGE_NAME) as string
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!data[recastBlockId]) {
|
||||||
|
data[recastBlockId] = {};
|
||||||
|
}
|
||||||
|
const propertyValueRecord = data[recastBlockId];
|
||||||
|
propertyValueRecord[propertyId] = blockId;
|
||||||
|
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getHistory = ({ recastBlockId }: { recastBlockId: string }) => {
|
||||||
|
ensureLocalStorage();
|
||||||
|
const data: HistoryStorageMap = JSON.parse(
|
||||||
|
localStorage.getItem(LOCAL_STORAGE_NAME) as string
|
||||||
|
);
|
||||||
|
|
||||||
|
return data[recastBlockId] ?? {};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeHistory = ({
|
||||||
|
recastBlockId,
|
||||||
|
propertyId,
|
||||||
|
}: {
|
||||||
|
recastBlockId: string;
|
||||||
|
propertyId: RecastPropertyId;
|
||||||
|
}) => {
|
||||||
|
ensureLocalStorage();
|
||||||
|
const data: HistoryStorageMap = JSON.parse(
|
||||||
|
localStorage.getItem(LOCAL_STORAGE_NAME) as string
|
||||||
|
);
|
||||||
|
if (!data[recastBlockId]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete data[recastBlockId][propertyId];
|
||||||
|
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(data));
|
||||||
|
};
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
SelectProperty,
|
SelectProperty,
|
||||||
TABLE_VALUES_KEY,
|
TABLE_VALUES_KEY,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
import { getHistory, removeHistory, setHistory } from './history';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a unique id for a property
|
* Generate a unique id for a property
|
||||||
@@ -240,7 +241,17 @@ export const getRecastItemValue = (block: RecastItem | AsyncBlock) => {
|
|||||||
return props[id];
|
return props[id];
|
||||||
};
|
};
|
||||||
|
|
||||||
const setValue = (newValue: RecastBlockValue) => {
|
const setValue = (
|
||||||
|
newValue: RecastBlockValue,
|
||||||
|
recastBlockId: string,
|
||||||
|
propertyId: RecastPropertyId
|
||||||
|
) => {
|
||||||
|
setHistory({
|
||||||
|
recastBlockId: recastBlockId,
|
||||||
|
blockId: block.id,
|
||||||
|
propertyId: propertyId,
|
||||||
|
});
|
||||||
|
|
||||||
return recastItem.setProperty(TABLE_VALUES_KEY, {
|
return recastItem.setProperty(TABLE_VALUES_KEY, {
|
||||||
...props,
|
...props,
|
||||||
[newValue.id]: newValue,
|
[newValue.id]: newValue,
|
||||||
@@ -249,9 +260,18 @@ export const getRecastItemValue = (block: RecastItem | AsyncBlock) => {
|
|||||||
|
|
||||||
const removeValue = (propertyId: RecastPropertyId) => {
|
const removeValue = (propertyId: RecastPropertyId) => {
|
||||||
const { [propertyId]: omitted, ...restProps } = props;
|
const { [propertyId]: omitted, ...restProps } = props;
|
||||||
|
|
||||||
|
removeHistory({
|
||||||
|
recastBlockId: block.id,
|
||||||
|
propertyId: propertyId,
|
||||||
|
});
|
||||||
|
|
||||||
return recastItem.setProperty(TABLE_VALUES_KEY, restProps);
|
return recastItem.setProperty(TABLE_VALUES_KEY, restProps);
|
||||||
};
|
};
|
||||||
return { getAllValue, getValue, setValue, removeValue };
|
|
||||||
|
const getValueHistory = getHistory;
|
||||||
|
|
||||||
|
return { getAllValue, getValue, setValue, removeValue, getValueHistory };
|
||||||
};
|
};
|
||||||
|
|
||||||
const isSelectLikeProperty = (
|
const isSelectLikeProperty = (
|
||||||
|
|||||||
Reference in New Issue
Block a user