Files
jiapu/public/js/growth-pages.js
T
2026-09-13 19:41:18 +08:00

746 lines
28 KiB
JavaScript

(function (root, factory) {
if (typeof module === 'object' && module.exports) {
module.exports = factory(root);
return;
}
root.GrowthPages = factory(root);
if (root.document) {
root.document.addEventListener('DOMContentLoaded', function () {
root.GrowthPages.init();
});
}
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
'use strict';
function confirmAction(message) {
if (root.ProfileUI && typeof root.ProfileUI.confirmAction === 'function') {
return root.ProfileUI.confirmAction(message);
}
return Promise.resolve(!root['confirm'] || root['confirm'](message));
}
var MediaDisplay = root.MediaDisplay || (typeof require === 'function' ? require('./media-display.js') : null);
var documentRef = root.document;
var recordsById = Object.create(null);
var canEditContent = false;
var writePending = false;
function getApi() {
return root.GenealogyApi && root.GenealogyApi.defaultClient;
}
function query(selector, rootNode) {
return documentRef ? (rootNode || documentRef).querySelector(selector) : null;
}
function queryAll(selector, rootNode) {
return documentRef ? Array.prototype.slice.call((rootNode || documentRef).querySelectorAll(selector)) : [];
}
function getQueryParam(search, name) {
var params = new URLSearchParams(String(search || '').replace(/^\?/, ''));
return params.get(name) || '';
}
function normalizeId(value) {
if (value === undefined || value === null || value === '') return '';
if (typeof value === 'number' && !Number.isSafeInteger(value)) return '';
return /^[1-9][0-9]*$/.test(String(value)) ? String(value) : '';
}
function getCurrentGenealogyId(search) {
var source = search === undefined && root.location ? root.location.search : search;
var fromProfile;
if (search === undefined && root.ProfileUI && root.ProfileUI.getGenealogyId) {
fromProfile = root.ProfileUI.getGenealogyId();
if (fromProfile) return normalizeId(fromProfile);
}
return normalizeId(getQueryParam(source, 'genealogyId'));
}
function getCurrentRecordId(search) {
var source = search === undefined && root.location ? root.location.search : search;
return normalizeId(getQueryParam(source, 'recordId'));
}
function trimOrUndefined(value) {
var text = String(value === undefined || value === null ? '' : value).trim();
return text || undefined;
}
function toSafeInteger(value) {
var text = trimOrUndefined(value);
var number;
if (text === undefined) return undefined;
number = Number(text);
return Number.isSafeInteger(number) ? number : undefined;
}
function toBackendDateTime(value) {
var text = trimOrUndefined(value);
if (!text) return undefined;
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(text)) return text.replace('T', ' ') + ':00';
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(text)) return text.replace('T', ' ');
return text;
}
function toDateInputValue(value) {
var text = String(value || '');
return /^\d{4}-\d{2}-\d{2}/.test(text) ? text.slice(0, 10) : '';
}
function toDateTimeInputValue(value) {
var text = String(value || '');
if (!/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}/.test(text)) return '';
return text.slice(0, 16).replace(' ', 'T');
}
function buildGrowthRecordBody(values) {
var source = values || {};
var body = {
recordTitle: String(source.recordTitle || '').trim()
};
var lineagePersonId = trimOrUndefined(source.lineagePersonId);
var recordType = trimOrUndefined(source.recordType);
var recordContent = trimOrUndefined(source.recordContent);
var recordDate = trimOrUndefined(source.recordDate);
var remindTime = toBackendDateTime(source.remindTime);
var mediaOssIds = trimOrUndefined(source.mediaOssIds);
var sortOrderText = trimOrUndefined(source.sortOrder);
var status = trimOrUndefined(source.status);
if (lineagePersonId !== undefined) body.lineagePersonId = lineagePersonId;
if (recordType !== undefined) body.recordType = recordType;
if (recordContent !== undefined) body.recordContent = recordContent;
if (recordDate !== undefined) body.recordDate = recordDate;
if (remindTime !== undefined) body.remindTime = remindTime;
if (source.mediaOssIds !== undefined) body.mediaOssIds = mediaOssIds || '';
if (sortOrderText !== undefined) {
body.sortOrder = toSafeInteger(sortOrderText);
if (body.sortOrder === undefined) body.invalidSortOrder = true;
}
if (status !== undefined) body.status = status;
return body;
}
function validateGrowthRecordBody(body) {
if (!body || !body.recordTitle) return '请填写记录标题';
if (body.lineagePersonId !== undefined && !normalizeId(body.lineagePersonId)) return '请选择有效的世系人物';
if (body.mediaOssIds !== undefined && body.mediaOssIds !== '' && !/^[1-9][0-9]*(,[1-9][0-9]*)*$/.test(body.mediaOssIds)) {
return '附件上传结果无效';
}
if (body.invalidSortOrder || (Object.prototype.hasOwnProperty.call(body, 'sortOrder') && !Number.isSafeInteger(body.sortOrder))) {
return '排序值必须是安全整数';
}
if (body.recordDate !== undefined && !/^\d{4}-\d{2}-\d{2}$/.test(body.recordDate)) return '记录日期格式无效';
if (body.remindTime !== undefined && !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(body.remindTime)) {
return '提醒时间格式无效';
}
if (body.status === '1') return '当前 PC 无法重新读取停用记录,暂不开放停用';
if (body.status !== undefined && body.status !== '0') return '记录状态只能是 0';
return '';
}
function stringValue(value) {
return value === undefined || value === null ? '' : String(value);
}
function optionalSafeInteger(value) {
var number;
if (value === undefined || value === null || value === '') return undefined;
number = Number(value);
return Number.isSafeInteger(number) ? number : undefined;
}
function normalizeGrowthRecord(item) {
var recordId = normalizeId(item && item.recordId);
var genealogyId = normalizeId(item && item.genealogyId);
var appUserId = normalizeId(item && item.appUserId);
var lineagePersonId = normalizeId(item && item.lineagePersonId);
var title = String(item && item.recordTitle || '').trim();
var status = stringValue(item && item.status);
var mediaFiles = MediaDisplay ? MediaDisplay.normalizeFileList(item && item.mediaFiles) : [];
var sortOrder = optionalSafeInteger(item && item.sortOrder);
var record;
if (!recordId || !genealogyId || !title || (status !== '0' && status !== '1')) return null;
if (item.appUserId !== undefined && item.appUserId !== null && item.appUserId !== '' && !appUserId) return null;
if (item.lineagePersonId !== undefined && item.lineagePersonId !== null && item.lineagePersonId !== '' && !lineagePersonId) return null;
if (item.sortOrder !== undefined && item.sortOrder !== null && item.sortOrder !== '' && sortOrder === undefined) return null;
record = {
recordId: recordId,
genealogyId: genealogyId,
genealogyNo: stringValue(item.genealogyNo),
genealogyName: stringValue(item.genealogyName),
surname: stringValue(item.surname),
appUserNickName: stringValue(item.appUserNickName),
appUserPhone: stringValue(item.appUserPhone),
lineagePersonNo: stringValue(item.lineagePersonNo),
lineagePersonName: stringValue(item.lineagePersonName),
recordType: stringValue(item.recordType),
recordTitle: title,
recordContent: stringValue(item.recordContent),
recordDate: stringValue(item.recordDate),
remindTime: stringValue(item.remindTime),
status: status,
remark: stringValue(item.remark)
};
if (mediaFiles.length) record.mediaFiles = mediaFiles;
if (appUserId) record.appUserId = appUserId;
if (lineagePersonId) record.lineagePersonId = lineagePersonId;
if (sortOrder !== undefined) record.sortOrder = sortOrder;
return record;
}
function matchesSavedRecord(item, expectedRecordId) {
var record = normalizeGrowthRecord(item);
return Boolean(record && record.recordId === normalizeId(expectedRecordId));
}
function normalizeLineageOption(item) {
var personId = normalizeId(item && (item.personId || item.lineagePersonId));
var name = String(item && (item.name || item.lineagePersonName) || '').trim();
if (!personId || !name) return null;
return {
personId: personId,
name: name,
generationName: stringValue(item.generationName)
};
}
function escapeHtml(value) {
return stringValue(value)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
function renderLineageOptions(data, selectedId, fallbackName) {
var selected = normalizeId(selectedId);
var options = Array.isArray(data) ? data.map(normalizeLineageOption).filter(Boolean) : [];
var selectedFound = options.some(function (option) { return option.personId === selected; });
if (selected && !selectedFound && fallbackName) {
options.push({ personId: selected, name: String(fallbackName), generationName: '' });
}
return '<option value="">不关联世系人物</option>' + options.map(function (option) {
return '<option value="' + escapeHtml(option.personId) + '"' +
(option.personId === selected ? ' selected' : '') + '>' +
escapeHtml(option.name + (option.generationName ? ' · ' + option.generationName : '')) +
'</option>';
}).join('');
}
function attachmentCount(mediaFiles) {
return Array.isArray(mediaFiles) ? mediaFiles.length : 0;
}
function buildListUrl(genealogyId, recordId) {
var url = 'profile-growth.html?genealogyId=' + encodeURIComponent(genealogyId);
return recordId ? url + '&recordId=' + encodeURIComponent(recordId) : url;
}
function buildEditUrl(genealogyId, recordId) {
var url = 'profile-growth-edit.html?genealogyId=' + encodeURIComponent(genealogyId);
return recordId ? url + '&recordId=' + encodeURIComponent(recordId) : url;
}
function canEditRecords(genealogy) {
return Boolean(genealogy && (genealogy.canEditContent === true || genealogy.canManage === true));
}
function renderGrowthRow(record) {
var summary = [];
var actions = '<button class="pill" type="button" data-growth-detail-id="' +
escapeHtml(record.recordId) + '">查看详情</button>';
if (record.lineagePersonName) summary.push(record.lineagePersonName);
if (record.recordType) summary.push(record.recordType);
if (record.recordDate) summary.push(record.recordDate);
if (!summary.length) summary.push('未填写日期和关联人物');
if (canEditContent) {
actions += '<a class="pill" href="' + escapeHtml(buildEditUrl(record.genealogyId, record.recordId)) +
'">编辑</a><button class="pill is-danger" type="button" data-growth-delete-id="' +
escapeHtml(record.recordId) + '">删除</button>';
}
return '<article class="module-row growth-row"><div><h3>' + escapeHtml(record.recordTitle) + '</h3><p>' +
escapeHtml(summary.join(' · ')) + '</p></div><div class="row-actions">' + actions + '</div></article>';
}
function detailValue(label, value) {
return '<p><span>' + escapeHtml(label) + '</span><b>' + escapeHtml(value || '未提供') + '</b></p>';
}
function renderGrowthDetail(record) {
var count;
var actions = '';
if (!record) return stateHtml('empty', '请选择一条成长记录查看详情');
count = attachmentCount(record.mediaFiles);
if (canEditContent) {
actions = '<div class="bottom-actions"><a class="btn ghost" href="' +
escapeHtml(buildEditUrl(record.genealogyId, record.recordId)) + '">编辑记录</a>' +
'<button class="btn danger" type="button" data-growth-delete-id="' +
escapeHtml(record.recordId) + '">删除记录</button></div>';
}
return (MediaDisplay ? MediaDisplay.renderGallery(record.mediaFiles, { label: '成长记录附件' }) : '') +
'<div class="form-like growth-detail">' +
detailValue('标题', record.recordTitle) +
detailValue('关联人物', record.lineagePersonName || record.lineagePersonNo) +
detailValue('记录类型', record.recordType) +
detailValue('记录日期', record.recordDate) +
detailValue('提醒时间', record.remindTime) +
detailValue('记录内容', record.recordContent) +
detailValue('附件', count ? count + ' 个附件' : '未上传') +
detailValue('记录人', record.appUserNickName) +
detailValue('状态', record.status === '0' ? '正常' : '停用') +
detailValue('备注', record.remark) +
'</div>' + actions;
}
function showMessage(message) {
if (root.layui && root.layui.layer) {
root.layui.layer.msg(message);
return;
}
if (root.alert) root.alert(message);
}
function shouldRedirectToLogin(api, error) {
var status = error && (error.status || error.code);
return !api || !api.getToken || !api.getToken() || Number(status) === 401;
}
function isForbidden(error) {
return Number(error && (error.status || error.code)) === 403;
}
function getApiStateType(error) {
return isForbidden(error) ? 'forbidden' : 'error';
}
function redirectUnauthorized(api, error) {
if (!shouldRedirectToLogin(api, error)) return false;
if (api && api.clearToken) api.clearToken();
root.NavigationUtil.open('login.html');
return true;
}
function syncGenealogyLinks() {
if (root.ProfileUI && root.ProfileUI.syncGenealogyContextLinks) root.ProfileUI.syncGenealogyContextLinks();
}
function stateHtml(type, message) {
if (root.ProfileUI && root.ProfileUI.renderApiState) return root.ProfileUI.renderApiState(type, message);
return '<div class="api-state api-state--' + type + '" role="' +
(type === 'error' || type === 'forbidden' ? 'alert' : 'status') +
'" aria-live="polite">' + escapeHtml(message) + '</div>';
}
function setState(container, type, message) {
if (!container) return;
if (root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(container, type, message);
return;
}
container.innerHTML = stateHtml(type, message);
}
function setFormStatus(message, type) {
var status = query('[data-growth-form-status]');
if (!status) return;
if (!message) {
status.innerHTML = '';
return;
}
if (type && root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(status, type, message);
return;
}
status.textContent = message;
}
function setEditorEnabled(enabled, message, type) {
var placeholder = query('[data-growth-editor-placeholder]');
queryAll('[data-growth-editor], [data-growth-editor-action]').forEach(function (element) {
element.hidden = !enabled;
});
if (placeholder) {
placeholder.hidden = Boolean(enabled);
if (!enabled && message) {
if (type) setState(placeholder, type, message);
else placeholder.textContent = message;
}
}
}
function setEditAccess(enabled) {
canEditContent = Boolean(enabled);
queryAll('[data-growth-create-link]').forEach(function (element) {
element.hidden = !canEditContent;
});
}
async function loadCapability(api, genealogyId) {
var genealogy = await api.genealogyDetail(genealogyId);
setEditAccess(canEditRecords(genealogy));
return genealogy;
}
function renderNoContext() {
var list = query('[data-growth-list]');
var detail = query('[data-growth-detail]');
var message = '请先选择家谱,再查看或维护成长记录。';
setState(list, 'empty', message);
setState(detail, 'empty', '当前没有家谱上下文。');
setEditAccess(false);
setEditorEnabled(false, message, 'empty');
setFormStatus(message, 'empty');
}
function requireGenealogyId() {
var genealogyId = getCurrentGenealogyId();
if (!genealogyId) renderNoContext();
return genealogyId;
}
function setWritePending(pending, label) {
var submit = query('[data-growth-form] [type="submit"]');
writePending = Boolean(pending);
queryAll('[data-growth-form] input, [data-growth-form] textarea, [data-growth-form] select, [data-growth-form] button, [data-growth-delete-id]').forEach(function (control) {
control.disabled = writePending;
});
if (submit) {
if (!submit.dataset.defaultLabel) submit.dataset.defaultLabel = submit.textContent;
submit.textContent = writePending && label ? label : submit.dataset.defaultLabel;
submit.setAttribute('aria-busy', writePending ? 'true' : 'false');
}
}
function renderGrowthRecords(data) {
var container = query('[data-growth-list]');
var normalized = Array.isArray(data) ? data.map(normalizeGrowthRecord) : [];
var invalidCount = normalized.filter(function (record) { return !record; }).length;
var records = normalized.filter(Boolean);
recordsById = Object.create(null);
records.forEach(function (record) {
recordsById[record.recordId] = record;
});
if (!container) return records;
if (!Array.isArray(data) || invalidCount) {
setState(container, 'error', '成长记录响应缺少稳定 GrowthRecordVo 字段,请联系后端核对。');
return [];
}
if (!records.length) {
setState(container, 'empty', '暂无成长记录');
return [];
}
container.innerHTML = records.map(renderGrowthRow).join('');
return records;
}
function renderDetail(record) {
var container = query('[data-growth-detail]');
if (container) container.innerHTML = renderGrowthDetail(record);
}
async function loadGrowthDetail(recordId) {
var api = getApi();
var genealogyId = requireGenealogyId();
var record;
if (!genealogyId || !normalizeId(recordId) || redirectUnauthorized(api)) return null;
setState(query('[data-growth-detail]'), 'loading', '正在加载成长记录详情…');
try {
record = normalizeGrowthRecord(await api.growthRecordDetail(genealogyId, recordId));
if (!record) throw new Error('成长记录详情响应缺少稳定 GrowthRecordVo 字段');
recordsById[record.recordId] = record;
renderDetail(record);
return record;
} catch (error) {
if (redirectUnauthorized(api, error)) return null;
setState(
query('[data-growth-detail]'),
getApiStateType(error),
isForbidden(error) ? '当前账号无权查看该成长记录。' : '成长记录详情加载失败,请稍后重试。'
);
showMessage(isForbidden(error) ? '当前账号无权查看该成长记录。' : (error.message || '成长记录详情加载失败'));
return null;
}
}
async function loadGrowthRecords() {
var api = getApi();
var genealogyId;
var records;
var requestedRecordId;
if (redirectUnauthorized(api)) return;
genealogyId = requireGenealogyId();
if (!genealogyId) return;
syncGenealogyLinks();
setState(query('[data-growth-list]'), 'loading', '正在加载成长记录…');
try {
await loadCapability(api, genealogyId);
records = renderGrowthRecords(await api.growthRecords(genealogyId));
requestedRecordId = getCurrentRecordId();
if (requestedRecordId && recordsById[requestedRecordId]) {
await loadGrowthDetail(requestedRecordId);
} else if (records.length) {
await loadGrowthDetail(records[0].recordId);
} else {
renderDetail(null);
}
} catch (error) {
if (redirectUnauthorized(api, error)) return;
setEditAccess(false);
setState(
query('[data-growth-list]'),
getApiStateType(error),
isForbidden(error) ? '当前账号无权查看该家谱的成长记录。' : '成长记录加载失败,请稍后重试。'
);
showMessage(isForbidden(error) ? '当前账号无权查看该家谱的成长记录。' : (error.message || '成长记录加载失败'));
}
}
function getFormValues(form) {
var values = {};
queryAll('[name]', form).forEach(function (field) {
values[field.name] = field.value;
});
return values;
}
function setFieldValue(name, value) {
var field = query('[data-growth-form] [name="' + name + '"]');
if (field) field.value = value === undefined || value === null ? '' : String(value);
}
function fillGrowthForm(record) {
var contentField;
var editorInstance;
setFieldValue('lineagePersonId', record.lineagePersonId);
setFieldValue('recordType', record.recordType);
setFieldValue('recordTitle', record.recordTitle);
setFieldValue('recordContent', record.recordContent);
setFieldValue('recordDate', toDateInputValue(record.recordDate));
setFieldValue('remindTime', toDateTimeInputValue(record.remindTime));
setFieldValue('sortOrder', record.sortOrder);
setFieldValue('status', '0');
contentField = query('[data-growth-form] [name="recordContent"]');
if (contentField && root.AppRichEditor && root.AppRichEditor.init) {
editorInstance = root.AppRichEditor.init(contentField);
if (editorInstance && editorInstance.editor && editorInstance.editor.setHtml) {
editorInstance.editor.setHtml(record.recordContent || '');
}
}
}
function applyLineageOptions(data, selectedId, fallbackName) {
var select = query('[data-growth-lineage-person]');
if (select) select.innerHTML = renderLineageOptions(data, selectedId, fallbackName);
}
async function loadGrowthEditor() {
var api = getApi();
var genealogyId;
var recordId;
var result;
var record;
if (redirectUnauthorized(api)) return;
genealogyId = requireGenealogyId();
if (!genealogyId) return;
recordId = getCurrentRecordId();
syncGenealogyLinks();
setEditorEnabled(false, '正在加载成长记录编辑信息…', 'loading');
setFormStatus('正在读取家谱权限…', 'loading');
try {
await loadCapability(api, genealogyId);
if (!canEditContent) throw { status: 403, message: '当前账号无权维护该家谱的成长记录。' };
result = await Promise.all([
api.lineagePersonOptions(genealogyId),
recordId ? api.growthRecordDetail(genealogyId, recordId) : Promise.resolve(null)
]);
record = recordId ? normalizeGrowthRecord(result[1]) : null;
if (recordId && !record) throw new Error('成长记录详情响应缺少稳定 GrowthRecordVo 字段');
applyLineageOptions(result[0], record && record.lineagePersonId, record && record.lineagePersonName);
if (record) {
fillGrowthForm(record);
root.AttachmentEditor.setFiles('#growthMediaOssIds', result[1].mediaFiles || []);
if (query('[data-growth-editor-title]')) query('[data-growth-editor-title]').textContent = '编辑成长记录';
}
setEditorEnabled(true);
setFormStatus('');
} catch (error) {
if (redirectUnauthorized(api, error)) return;
setEditAccess(false);
setEditorEnabled(false, isForbidden(error)
? '当前账号无权维护该家谱的成长记录。'
: (error.message || '成长记录编辑信息加载失败'), getApiStateType(error));
setFormStatus(
isForbidden(error) ? '当前账号无权维护该家谱的成长记录。' : (error.message || '成长记录编辑信息加载失败'),
getApiStateType(error)
);
}
}
async function submitGrowthRecord(form) {
var api = getApi();
var genealogyId = requireGenealogyId();
var recordId = getCurrentRecordId();
var body;
var validation;
var result;
var saved;
var savedId;
var verifiedDetail;
if (writePending || !canEditContent || !genealogyId || redirectUnauthorized(api)) return;
body = buildGrowthRecordBody(getFormValues(form));
validation = validateGrowthRecordBody(body);
if (validation) {
setFormStatus(validation, 'error');
return;
}
delete body.invalidSortOrder;
setWritePending(true, '正在保存…');
setFormStatus('正在保存成长记录…', 'loading');
try {
result = recordId
? await api.updateGrowthRecord(genealogyId, recordId, body)
: await api.createGrowthRecord(genealogyId, body);
saved = normalizeGrowthRecord(result);
savedId = recordId || (saved && saved.recordId);
if (!savedId) throw new Error('保存响应缺少 recordId');
verifiedDetail = await api.growthRecordDetail(genealogyId, savedId);
if (!matchesSavedRecord(verifiedDetail, savedId)) throw new Error('保存后重读未返回同一条成长记录');
root.NavigationUtil.open(buildListUrl(genealogyId, savedId));
} catch (error) {
if (redirectUnauthorized(api, error)) return;
setFormStatus(
isForbidden(error) ? '当前账号无权保存该成长记录。' : (error.message || '成长记录保存失败'),
getApiStateType(error)
);
} finally {
setWritePending(false);
}
}
async function deleteGrowthRecord(recordId) {
var api = getApi();
var genealogyId = requireGenealogyId();
var record = recordsById[recordId];
if (writePending || !canEditContent || !genealogyId || !normalizeId(recordId) || redirectUnauthorized(api)) return;
if (!await confirmAction('确认删除“' + (record ? record.recordTitle : '该成长记录') + '”吗?删除后不可恢复,并会释放附件引用。')) return;
setWritePending(true);
try {
await api.deleteGrowthRecord(genealogyId, recordId);
await loadGrowthRecords();
showMessage('成长记录已删除');
} catch (error) {
if (redirectUnauthorized(api, error)) return;
showMessage(isForbidden(error) ? '当前账号无权删除该成长记录。' : (error.message || '成长记录删除失败'));
} finally {
setWritePending(false);
}
}
function clearMediaSelection() {
root.AttachmentEditor.clear('#growthMediaOssIds');
}
function bindActions() {
if (!documentRef) return;
documentRef.addEventListener('click', function (event) {
var detailButton = event.target.closest('[data-growth-detail-id]');
var deleteButton = event.target.closest('[data-growth-delete-id]');
var clearMediaButton = event.target.closest('[data-growth-clear-media]');
var recordId;
var genealogyId;
if (detailButton) {
event.preventDefault();
recordId = detailButton.getAttribute('data-growth-detail-id');
genealogyId = requireGenealogyId();
if (root.history && genealogyId) root.history.replaceState(null, '', buildListUrl(genealogyId, recordId));
loadGrowthDetail(recordId).then(function (record) {
if (record && root.ProfileUI && root.ProfileUI.revealDetail) {
root.ProfileUI.revealDetail(query('[data-growth-detail-heading]'));
}
});
return;
}
if (deleteButton) {
event.preventDefault();
deleteGrowthRecord(deleteButton.getAttribute('data-growth-delete-id'));
return;
}
if (clearMediaButton) {
event.preventDefault();
clearMediaSelection();
}
});
documentRef.addEventListener('submit', function (event) {
var form = event.target.closest('[data-growth-form]');
if (!form) return;
event.preventDefault();
submitGrowthRecord(form);
});
}
function init() {
if (!documentRef) return;
bindActions();
if (query('[data-growth-page]')) loadGrowthRecords();
if (query('[data-growth-edit-page]')) loadGrowthEditor();
}
return {
getCurrentGenealogyId: getCurrentGenealogyId,
getCurrentRecordId: getCurrentRecordId,
buildGrowthRecordBody: buildGrowthRecordBody,
validateGrowthRecordBody: validateGrowthRecordBody,
normalizeGrowthRecord: normalizeGrowthRecord,
matchesSavedRecord: matchesSavedRecord,
canEditRecords: canEditRecords,
renderLineageOptions: renderLineageOptions,
renderGrowthDetail: renderGrowthDetail,
shouldRedirectToLogin: shouldRedirectToLogin,
isForbidden: isForbidden,
init: init
};
});