Skip to content

Commit

Permalink
move batch operations to history store; use api methods there
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedhamidawan committed Jul 24, 2024
1 parent 0230551 commit c386dd9
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 77 deletions.
25 changes: 10 additions & 15 deletions client/src/components/Grid/configs/histories.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
faBurn,
faExchangeAlt,
faEye,
faPlus,
Expand All @@ -10,7 +11,7 @@ import {
} from "@fortawesome/free-solid-svg-icons";
import { useEventBus } from "@vueuse/core";

import { deleteHistories, deleteHistory, historiesFetcher, undeleteHistories, undeleteHistory } from "@/api/histories";
import { historiesFetcher } from "@/api/histories";
import { updateTags } from "@/api/tags";
import { useHistoryStore } from "@/stores/historyStore";
import Filtering, { contains, equals, expandNameTag, toBool, type ValidFilter } from "@/utils/filtering";
Expand Down Expand Up @@ -70,9 +71,8 @@ const batch: BatchOperationArray = [
if (confirm(_l(`Are you sure that you want to delete the selected histories?`))) {
try {
const historyIds = data.map((x) => String(x.id));
await deleteHistories({ ids: historyIds });
const historyStore = useHistoryStore();
await historyStore.handleTotalCountChange(data.length, true);
await historyStore.deleteHistories(historyIds);
return {
status: "success",
message: `Deleted ${data.length} histories.`,
Expand All @@ -94,9 +94,8 @@ const batch: BatchOperationArray = [
if (confirm(_l(`Are you sure that you want to restore the selected histories?`))) {
try {
const historyIds = data.map((x) => String(x.id));
await undeleteHistories({ ids: historyIds });
const historyStore = useHistoryStore();
await historyStore.handleTotalCountChange(data.length);
await historyStore.restoreHistories(historyIds);
return {
status: "success",
message: `Restored ${data.length} histories.`,
Expand All @@ -112,15 +111,14 @@ const batch: BatchOperationArray = [
},
{
title: "Purge",
icon: faTrash,
icon: faBurn,
condition: (data: Array<HistoryEntry>) => !data.some((x) => x.purged),
handler: async (data: Array<HistoryEntry>) => {
if (confirm(_l(`Are you sure that you want to permanently delete the selected histories?`))) {
try {
const historyIds = data.map((x) => String(x.id));
await deleteHistories({ ids: historyIds, purge: true });
const historyStore = useHistoryStore();
await historyStore.handleTotalCountChange(data.length, true);
await historyStore.deleteHistories(historyIds, true);
return {
status: "success",
message: `Purged ${data.length} histories.`,
Expand Down Expand Up @@ -191,9 +189,8 @@ const fields: FieldArray = [
handler: async (data: HistoryEntry) => {
if (confirm(_l("Are you sure that you want to delete this history?"))) {
try {
await deleteHistory({ history_id: String(data.id) });
const historyStore = useHistoryStore();
await historyStore.handleTotalCountChange(1, true);
await historyStore.deleteHistory(String(data.id));
return {
status: "success",
message: `'${data.name}' has been deleted.`,
Expand All @@ -209,14 +206,13 @@ const fields: FieldArray = [
},
{
title: "Delete Permanently",
icon: faTrash,
icon: faBurn,
condition: (data: HistoryEntry) => !data.purged,
handler: async (data: HistoryEntry) => {
if (confirm(_l("Are you sure that you want to permanently delete this history?"))) {
try {
await deleteHistory({ history_id: String(data.id), purge: true });
const historyStore = useHistoryStore();
await historyStore.handleTotalCountChange(1, true);
await historyStore.deleteHistory(String(data.id), true);
return {
status: "success",
message: `'${data.name}' has been permanently deleted.`,
Expand All @@ -236,9 +232,8 @@ const fields: FieldArray = [
condition: (data: HistoryEntry) => !!data.deleted && !data.purged,
handler: async (data: HistoryEntry) => {
try {
await undeleteHistory({ history_id: String(data.id) });
const historyStore = useHistoryStore();
await historyStore.handleTotalCountChange(1);
await historyStore.restoreHistory(String(data.id));
return {
status: "success",
message: `'${data.name}' has been restored.`,
Expand Down
81 changes: 70 additions & 11 deletions client/src/stores/historyStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ import type {
HistorySummary,
HistorySummaryExtended,
} from "@/api";
import { historyFetcher } from "@/api/histories";
import {
deleteHistories as deleteHistoriesByIds,
deleteHistory as deleteHistoryById,
historyFetcher,
undeleteHistories,
undeleteHistory,
} from "@/api/histories";
import { archiveHistory, unarchiveHistory } from "@/api/histories.archived";
import { HistoryFilters } from "@/components/History/HistoryFilters";
import { useUserLocalStorage } from "@/composables/userLocalStorage";
import {
cloneHistory,
createAndSelectNewHistory,
deleteHistoryById,
getCurrentHistoryFromServer,
getHistoryByIdFromServer,
getHistoryCount,
Expand Down Expand Up @@ -190,16 +195,67 @@ export const useHistoryStore = defineStore("historyStore", () => {
return filteredHistoryIds[0];
}

async function deleteHistory(historyId: string, purge: boolean) {
const deletedHistory = (await deleteHistoryById(historyId, purge)) as HistorySummary;
const nextAvailableHistoryId = getNextAvailableHistoryId([deletedHistory.id]);
if (nextAvailableHistoryId) {
await setCurrentHistory(nextAvailableHistoryId);
} else {
await createNewHistory();
async function deleteHistory(historyId: string, purge = false) {
try {
const { data } = await deleteHistoryById({ history_id: historyId, purge });
const deletedHistory = data as AnyHistory;
if (currentHistoryId.value === historyId) {
const nextAvailableHistoryId = getNextAvailableHistoryId([deletedHistory.id]);
if (nextAvailableHistoryId) {
await setCurrentHistory(nextAvailableHistoryId);
} else {
await createNewHistory();
}
}
del(storedHistories.value, deletedHistory.id);
await handleTotalCountChange(1, true);
} catch (error) {
rethrowSimple(error);
}
}

async function deleteHistories(ids: string[], purge = false) {
try {
const { data } = await deleteHistoriesByIds({ ids, purge });
const deletedHistories = data as AnyHistory[];
const historyIds = deletedHistories.map((x) => String(x.id));
if (currentHistoryId.value && historyIds.includes(currentHistoryId.value)) {
const nextAvailableHistoryId = getNextAvailableHistoryId(historyIds);
if (nextAvailableHistoryId) {
await setCurrentHistory(nextAvailableHistoryId);
} else {
await createNewHistory();
}
}
deletedHistories.forEach((history) => {
del(storedHistories.value, history.id);
});
await handleTotalCountChange(deletedHistories.length, true);
} catch (error) {
rethrowSimple(error);
}
}

async function restoreHistory(historyId: string) {
try {
const { data } = await undeleteHistory({ history_id: historyId });
const restoredHistory = data as AnyHistory;
await handleTotalCountChange(1);
setHistory(restoredHistory);
} catch (error) {
rethrowSimple(error);
}
}

async function restoreHistories(ids: string[]) {
try {
const { data } = await undeleteHistories({ ids });
const restoredHistories = data as AnyHistory[];
await handleTotalCountChange(restoredHistories.length);
setHistories(restoredHistories);
} catch (error) {
rethrowSimple(error);
}
del(storedHistories.value, deletedHistory.id);
await handleTotalCountChange(1, true);
}

async function loadCurrentHistory(since?: string): Promise<HistoryDevDetailed | undefined> {
Expand Down Expand Up @@ -348,6 +404,9 @@ export const useHistoryStore = defineStore("historyStore", () => {
copyHistory,
createNewHistory,
deleteHistory,
deleteHistories,
restoreHistory,
restoreHistories,
handleTotalCountChange,
loadCurrentHistory,
loadHistories,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import axios from "axios";
import { prependPath } from "utils/redirect";
import axios, { type AxiosResponse } from "axios";
import type { ApiResponse } from "openapi-typescript-fetch";

import type { AnyHistory } from "@/api";
import { prependPath } from "@/utils/redirect";

/**
* Generic json getter
* @param {*} response
* @return {Object} response.data or throws an error if response status is not 200
* @param response
* @return response.data or throws an error if response status is not 200
*/
function doResponse(response) {
function doResponse(response: AxiosResponse | ApiResponse) {
if (response.status !== 200) {
throw new Error(response);
throw new Error(response.statusText);
}
return response.data;
}

/**
* Some current endpoints don't accept JSON, so we need to
* do some massaging to send in old form post data.
* @param {Object} fields
*/
function formData(fields = {}) {
function formData(fields = {} as Record<string, any>) {
return Object.keys(fields).reduce((result, fieldName) => {
result.set(fieldName, fields[fieldName]);
return result;
}, new FormData());
}

/**
* Default history request parameters.
*/
/** Default history request parameters. */
const stdHistoryParams = {
view: "summary",
};
Expand All @@ -43,7 +43,7 @@ const extendedHistoryParams = {

/**
* Create a new history, select it as the current history, and return it if successful.
* @return {Object} the new history or throws an error if new history creation fails
* @return the new history or throws an error if new history creation fails
*/
export async function createAndSelectNewHistory() {
const url = "history/create_new_current";
Expand All @@ -57,11 +57,11 @@ export async function createAndSelectNewHistory() {

/**
* Generates copy of history on server.
* @param {Object} history Source history
* @param {String} name New history name
* @param {Boolean} copyAll Copy existing contents
* @param history Source history
* @param name New history name
* @param copyAll Copy existing contents
*/
export async function cloneHistory(history, name, copyAll) {
export async function cloneHistory(history: AnyHistory, name: string, copyAll: boolean) {
const url = "api/histories";
const payload = {
name,
Expand All @@ -73,47 +73,36 @@ export async function cloneHistory(history, name, copyAll) {
return doResponse(response);
}

/**
* Delete history on server and return the deleted history.
* @param {String} id Encoded history id
* @param {Boolean} [purge=false] Permanent delete
*/
export async function deleteHistoryById(id, purge = false) {
const url = `api/histories/${id}` + (purge ? "?purge=True" : "");
const response = await axios.delete(prependPath(url), { params: stdHistoryParams });
return doResponse(response);
}

/**
* Get current history from server and return it.
* @param {String} since timestamp to get histories since
* @return {Object} the current history
* @param since timestamp to get histories since
* @return the current history
*/
export async function getCurrentHistoryFromServer(since = undefined) {
export async function getCurrentHistoryFromServer(since: string | undefined = undefined) {
const url = "history/current_history_json";
const response = await axios.get(prependPath(url), { params: { since: since } });
return doResponse(response);
}

/**
* Set current history on server and return it.
* @param {String} historyId Encoded history id
* @return {Object} the current history
* @param historyId Encoded history id
* @return the current history
*/
export async function setCurrentHistoryOnServer(historyId) {
export async function setCurrentHistoryOnServer(historyId: string) {
const url = "history/set_as_current";
const response = await axios.get(prependPath(url), { params: { id: historyId } });
return doResponse(response);
}

/**
* Get list of histories from server and return them.
* @param {Number} offset to start from (default = 0)
* @param {Number | null} limit of histories to load (default = null; in which case no limit)
* @param {String} queryString to append to url in the form `q=filter&qv=val&q=...`
* @return {Promise.<Array>} list of histories
* @param offset to start from (default = 0)
* @param limit of histories to load (default = null; in which case no limit)
* @param queryString to append to url in the form `q=filter&qv=val&q=...`
* @return list of histories
*/
export async function getHistoryList(offset = 0, limit = null, queryString = "") {
export async function getHistoryList(offset = 0, limit: number | null = null, queryString = "") {
const params = `view=summary&order=update_time&offset=${offset}`;
let url = `api/histories?${params}`;
if (limit !== null) {
Expand All @@ -128,7 +117,7 @@ export async function getHistoryList(offset = 0, limit = null, queryString = "")

/**
* Get number of histories for current user from server and return them.
* @return {Promise.<Number>} number of histories
* @return number of histories
*/
export async function getHistoryCount() {
// This url is temp. for this PR, waiting on:
Expand All @@ -138,11 +127,8 @@ export async function getHistoryCount() {
return doResponse(response);
}

/**
* Load one history by id
* @param {String} id
*/
export async function getHistoryByIdFromServer(id) {
/** Load one history by id */
export async function getHistoryByIdFromServer(id: string) {
const path = `api/histories/${id}`;
const response = await axios.get(prependPath(path), { params: extendedHistoryParams });
return doResponse(response);
Expand All @@ -151,10 +137,10 @@ export async function getHistoryByIdFromServer(id) {
/**
* Set permissions to private for indicated history
* TODO: rewrite API endpoint for this
* @param {Object} history the history to secure
* @return {Object} the secured history
* @param history the history to secure
* @return the secured history
*/
export async function secureHistoryOnServer(history) {
export async function secureHistoryOnServer(history: AnyHistory) {
const { id } = history;
const url = "history/make_private";
const response = await axios.post(prependPath(url), formData({ history_id: id }));
Expand All @@ -166,11 +152,11 @@ export async function secureHistoryOnServer(history) {

/**
* Update specific fields in history
* @param {Object} historyId the history id to update
* @param {Object} payload fields to update
* @return {Object} the updated history
* @param historyId the history id to update
* @param payload fields to update
* @return the updated history
*/
export async function updateHistoryFields(historyId, payload) {
export async function updateHistoryFields(historyId: string, payload: Record<string, any>) {
const url = `api/histories/${historyId}`;
const response = await axios.put(prependPath(url), payload, { params: extendedHistoryParams });
return doResponse(response);
Expand Down

0 comments on commit c386dd9

Please sign in to comment.