- fixed displaying dynamic tags;

This commit is contained in:
Vitalii Kiiko
2026-03-26 14:27:38 +01:00
parent 40430ef94d
commit 8f8f565117
2 changed files with 103 additions and 1 deletions

View File

@@ -4,6 +4,24 @@ import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core';
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US';
import '@univerjs/preset-sheets-core/lib/index.css';
const TAG_RE = /^\{\{gepafin_field:[^|]+\|[^}]+}}$/;
const buildTagMap = (workbookData) => {
const map = {};
if (!workbookData?.sheets) return map;
const sheetId = workbookData.sheetOrder?.[0];
const sheet = sheetId ? workbookData.sheets[sheetId] : Object.values(workbookData.sheets)[0];
if (!sheet?.cellData) return map;
Object.entries(sheet.cellData).forEach(([r, row]) => {
Object.entries(row).forEach(([c, cell]) => {
if (typeof cell.f === 'string' && TAG_RE.test(cell.f)) {
map[`${r}:${c}`] = { v: cell.v, f: cell.f };
}
});
});
return map;
};
const parseWorkbook = (val) => {
if (!val) return null;
if (typeof val === 'object' && val.sheets) return val;
@@ -23,6 +41,8 @@ const Spreadsheet = ({ fieldName, defaultValue, setDataFn, template }) => {
const univerRef = useRef(null);
const univerAPIRef = useRef(null);
const saveTimerRef = useRef(null);
const isRestoringRef = useRef(false);
const tagCellMapRef = useRef({});
useEffect(() => {
if (!containerRef.current) return;
@@ -43,8 +63,40 @@ const Spreadsheet = ({ fieldName, defaultValue, setDataFn, template }) => {
univerAPIRef.current = univerAPI;
const initialData = parseWorkbook(defaultValue) || parseWorkbook(template) || { name: 'Sheet' };
tagCellMapRef.current = buildTagMap(initialData);
univerAPI.createWorkbook(initialData);
const restoreTagCells = () => {
if (isRestoringRef.current) return;
const wb = univerAPIRef.current?.getActiveWorkbook();
if (!wb) return;
const sheet = wb.getActiveSheet();
if (!sheet) return;
const saved = wb.save();
if (!saved?.sheets) return;
const sheetId = saved.sheetOrder?.[0];
const sheetData = sheetId ? saved.sheets[sheetId] : Object.values(saved.sheets)[0];
if (!sheetData?.cellData) return;
const restorations = [];
Object.entries(sheetData.cellData).forEach(([r, row]) => {
Object.entries(row).forEach(([c, cell]) => {
if (typeof cell.v === 'string' && TAG_RE.test(cell.v)) {
const orig = tagCellMapRef.current[`${r}:${c}`];
if (orig) restorations.push({ r: +r, c: +c, v: orig.v, f: orig.f });
}
});
});
if (restorations.length === 0) return;
isRestoringRef.current = true;
restorations.forEach(({ r, c, v, f }) => {
sheet.getRange(r, c, 1, 1).setValues([[{ v, f }]]);
});
isRestoringRef.current = false;
};
let restoreTimer;
univerAPI.addEvent(univerAPI.Event.BeforeCommandExecute, () => {
clearTimeout(saveTimerRef.current);
saveTimerRef.current = setTimeout(() => {
@@ -53,10 +105,13 @@ const Spreadsheet = ({ fieldName, defaultValue, setDataFn, template }) => {
setDataFn(fieldName, wb.save());
}
}, 300);
clearTimeout(restoreTimer);
restoreTimer = setTimeout(restoreTagCells, 80);
});
return () => {
clearTimeout(saveTimerRef.current);
clearTimeout(restoreTimer);
if (univerRef.current) {
univerRef.current.dispose();
univerRef.current = null;

View File

@@ -12,6 +12,8 @@ import { useStoreValue } from '../../../../../../store';
// tools
import { xlsxToWorkbookData } from '../../../../../BandoEdit/components/BandoEditFormStep3Excel/xlsxToWorkbookData';
const TAG_RE = /^\{\{gepafin_field:([^|]+)\|([^}]+)}}$/;
const ElementSettingSpreadsheet = ({ value, name, setDataFn }) => {
const callFormFields = useStoreValue('callFormFields');
const [tagTooltip, setTagTooltip] = useState(null);
@@ -19,6 +21,7 @@ const ElementSettingSpreadsheet = ({ value, name, setDataFn }) => {
const univerRef = useRef(null);
const univerAPIRef = useRef(null);
const formFieldsRef = useRef([]);
const isRestoringRef = useRef(false);
const mousePos = useRef({ x: 0, y: 0 });
const fileInputRef = useRef(null);
@@ -60,11 +63,54 @@ const ElementSettingSpreadsheet = ({ value, name, setDataFn }) => {
univerRef.current = univer;
univerAPIRef.current = univerAPI;
// Disable adding new sheets
// Restore tag cells whose display value was overwritten by raw tag on blur
const restoreTagCells = () => {
if (isRestoringRef.current) return;
const wb = univerAPIRef.current?.getActiveWorkbook();
if (!wb) return;
const sheet = wb.getActiveSheet();
if (!sheet) return;
const saved = wb.save();
if (!saved?.sheets) return;
const sheetId = saved.sheetOrder?.[0];
const sheetData = sheetId ? saved.sheets[sheetId] : Object.values(saved.sheets)[0];
if (!sheetData?.cellData) return;
const restorations = [];
Object.entries(sheetData.cellData).forEach(([r, row]) => {
Object.entries(row).forEach(([c, cell]) => {
const match = typeof cell.v === 'string' && cell.v.match(TAG_RE);
if (match) {
const tagIds = match[1].split(',');
const type = match[2];
const field = formFieldsRef.current.find(f =>
f.ids.some(id => tagIds.includes(String(id)))
);
const displayValue = type === 'value'
? (field?.placeholder || '')
: (field?.label || match[1]);
restorations.push({ r: +r, c: +c, v: displayValue, f: cell.v });
}
});
});
if (restorations.length === 0) return;
isRestoringRef.current = true;
restorations.forEach(({ r, c, v, f }) => {
sheet.getRange(r, c, 1, 1).setValues([[{ v, f }]]);
});
isRestoringRef.current = false;
};
let restoreTimer;
// Disable adding new sheets; also schedule tag-cell restoration after each command
univerAPI.addEvent(univerAPI.Event.BeforeCommandExecute, (event) => {
if (event.id === 'sheet.command.insert-sheet') {
event.cancel = true;
}
clearTimeout(restoreTimer);
restoreTimer = setTimeout(restoreTagCells, 80);
});
// Context menu: "Inserisci variabile GEPAFIN"
@@ -113,6 +159,7 @@ const ElementSettingSpreadsheet = ({ value, name, setDataFn }) => {
setTagTooltip(null);
}
});
}, []); // refs are stable
// Keep formFieldsRef in sync with store value