feat(sidepanel): implement multi-select and delete functionality for account records
- Added a new feature to allow users to select multiple account records and delete them. - Introduced a filter system to categorize account records based on their status (success, failed, stopped, retry). - Enhanced the UI with a toolbar for selection and deletion actions, including a confirmation modal for deletions. - Updated the CSS for better styling of the new toolbar and selection states. - Implemented backend support for deleting selected records and syncing the remaining records. - Added unit tests to ensure the new functionality works as expected.
This commit is contained in:
@@ -254,6 +254,30 @@
|
||||
return normalizeAccountRunHistory(nextHistory);
|
||||
}
|
||||
|
||||
function deleteAccountRunHistoryEntries(history, recordIds = []) {
|
||||
const normalizedHistory = normalizeAccountRunHistory(history);
|
||||
const normalizedIds = Array.isArray(recordIds)
|
||||
? recordIds
|
||||
.map((value) => String(value || '').trim().toLowerCase())
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
if (!normalizedIds.length) {
|
||||
return {
|
||||
deletedCount: 0,
|
||||
nextHistory: normalizedHistory,
|
||||
};
|
||||
}
|
||||
|
||||
const selectedIds = new Set(normalizedIds);
|
||||
const nextHistory = normalizedHistory.filter((record) => !selectedIds.has(buildRecordId(record.recordId || record.email)));
|
||||
|
||||
return {
|
||||
deletedCount: normalizedHistory.length - nextHistory.length,
|
||||
nextHistory: normalizeAccountRunHistory(nextHistory),
|
||||
};
|
||||
}
|
||||
|
||||
async function appendAccountRunHistoryRecord(status, stateOverride = null, reason = '') {
|
||||
const state = stateOverride || await getState();
|
||||
const record = buildAccountRunHistoryRecord(state, status, reason);
|
||||
@@ -384,12 +408,42 @@
|
||||
};
|
||||
}
|
||||
|
||||
async function deleteAccountRunHistoryRecords(recordIds = [], stateOverride = null) {
|
||||
const state = stateOverride || await getState();
|
||||
const history = await getPersistedAccountRunHistory();
|
||||
const { deletedCount, nextHistory } = deleteAccountRunHistoryEntries(history, recordIds);
|
||||
|
||||
if (!deletedCount) {
|
||||
return {
|
||||
deletedCount: 0,
|
||||
remainingCount: history.length,
|
||||
};
|
||||
}
|
||||
|
||||
await setPersistedAccountRunHistory(nextHistory);
|
||||
|
||||
try {
|
||||
const filePath = await syncAccountRunHistorySnapshot(nextHistory, state);
|
||||
if (filePath) {
|
||||
await addLog(`账号记录快照已同步到本地:${filePath}`, 'info');
|
||||
}
|
||||
} catch (err) {
|
||||
await addLog(getErrorMessage(err), 'warn');
|
||||
}
|
||||
|
||||
return {
|
||||
deletedCount,
|
||||
remainingCount: nextHistory.length,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
appendAccountRunRecord,
|
||||
appendAccountRunHistoryRecord,
|
||||
buildAccountRunHistoryRecord,
|
||||
buildAccountRunHistorySnapshotPayload,
|
||||
clearAccountRunHistory,
|
||||
deleteAccountRunHistoryRecords,
|
||||
getPersistedAccountRunHistory,
|
||||
normalizeAccountRunHistory,
|
||||
normalizeAccountRunHistoryRecord,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
cancelScheduledAutoRun,
|
||||
checkIcloudSession,
|
||||
clearAccountRunHistory,
|
||||
deleteAccountRunHistoryRecords,
|
||||
clearAutoRunTimerAlarm,
|
||||
clearLuckmailRuntimeState,
|
||||
clearStopRequest,
|
||||
@@ -300,6 +301,19 @@
|
||||
return { ok: true, ...result };
|
||||
}
|
||||
|
||||
case 'DELETE_ACCOUNT_RUN_HISTORY_RECORDS': {
|
||||
const state = await getState();
|
||||
if (isAutoRunLockedState(state)) {
|
||||
throw new Error('自动流程运行中,当前不能删除邮箱记录。');
|
||||
}
|
||||
if (typeof deleteAccountRunHistoryRecords !== 'function') {
|
||||
return { ok: true, deletedCount: 0, remainingCount: 0 };
|
||||
}
|
||||
const recordIds = Array.isArray(message.payload?.recordIds) ? message.payload.recordIds : [];
|
||||
const result = await deleteAccountRunHistoryRecords(recordIds, state);
|
||||
return { ok: true, ...result };
|
||||
}
|
||||
|
||||
case 'EXECUTE_STEP': {
|
||||
clearStopRequest();
|
||||
if (message.source === 'sidepanel') {
|
||||
|
||||
Reference in New Issue
Block a user