diff --git a/client/src/api/index.ts b/client/src/api/index.ts index 4048356ef219..a32e076b84ff 100644 --- a/client/src/api/index.ts +++ b/client/src/api/index.ts @@ -7,18 +7,72 @@ import { components } from "@/api/schema"; */ export type HistorySummary = components["schemas"]["HistorySummary"]; -export interface HistorySummaryExtended extends HistorySummary { +/** + * Contains minimal information about a History with additional content stats. + * This is a subset of information that can be relatively frequently updated after + * certain actions are performed on the history. + */ +export interface HistoryContentsStats { + id: string; + update_time: string; size: number; contents_active: components["schemas"]["HistoryActiveContentCounts"]; +} + +/** + * Contains summary information plus additional details about the contents and owner of a History. + * This is used by the client API to simplify the handling of History objects. + * + * Data returned by the API when requesting `?view=summary&keys=size,contents_active,user_id`. + */ +export interface HistorySummaryExtended extends HistorySummary, HistoryContentsStats { user_id: string; } +type HistoryDetailedModel = components["schemas"]["HistoryDetailed"]; + /** * Contains additional details about a History. + * + * Data returned by the API when requesting `?view=detailed`. + */ +export interface HistoryDetailed extends HistoryDetailedModel { + // TODO: these fields are not present in the backend schema model `HistoryDetailedModel` but are serialized by the API + // when requesting ?view=detailed. We should consider adding them to the backend schema. + email_hash?: string; + empty: boolean; + hid_counter: number; +} + +type HistoryDetailedCommon = Omit< + HistoryDetailed, + "username" | "state" | "state_ids" | "state_details" | "email_hash" | "empty" +>; + +/** + * Alternative representation of history details used by the client API. + * Shares most of the fields with HistoryDetailed but not all and adds some additional fields. + * + * Data returned by the API when requesting `?view=dev-detailed`. */ -export type HistoryDetailed = components["schemas"]["HistoryDetailed"]; +export interface HistoryDevDetailed extends HistoryDetailedCommon { + contents_active: components["schemas"]["HistoryActiveContentCounts"]; +} -export type AnyHistory = HistorySummary | HistorySummaryExtended | HistoryDetailed; +/** + * Contains all available information about a History. + */ +export type HistoryExtended = HistoryDevDetailed & HistoryDetailed; + +/** + * Represents any amount of information about a History with the minimal being a HistorySummary. + */ +export type AnyHistory = + | HistorySummary + | HistorySummaryExtended + | HistoryDetailed + | HistoryDevDetailed + | HistoryExtended; /** * Contains minimal information about a HistoryContentItem. diff --git a/client/src/components/History/CurrentHistory/HistoryCounter.vue b/client/src/components/History/CurrentHistory/HistoryCounter.vue index 98efa0bf11b8..ce02cca585b4 100644 --- a/client/src/components/History/CurrentHistory/HistoryCounter.vue +++ b/client/src/components/History/CurrentHistory/HistoryCounter.vue @@ -9,14 +9,13 @@ import prettyBytes from "pretty-bytes"; import { computed, onMounted, ref, toRef } from "vue"; import { useRouter } from "vue-router/composables"; -import type { HistorySummary } from "@/api"; +import type { HistorySummaryExtended } from "@/api"; import { HistoryFilters } from "@/components/History/HistoryFilters.js"; import { useConfig } from "@/composables/config"; +import { useHistoryContentStats } from "@/composables/historyContentStats"; import { useStorageLocationConfiguration } from "@/composables/storageLocation"; import { useUserStore } from "@/stores/userStore"; -import { useDetailedHistory } from "./usesDetailedHistory"; - import PreferredStorePopover from "./PreferredStorePopover.vue"; import SelectPreferredStore from "./SelectPreferredStore.vue"; @@ -26,7 +25,7 @@ library.add(faDatabase, faEyeSlash, faHdd, faMapMarker, faSync, faTrash); const props = withDefaults( defineProps<{ - history: HistorySummary; + history: HistorySummaryExtended; isWatching?: boolean; lastChecked: Date; filterText?: string; @@ -47,7 +46,9 @@ const emit = defineEmits(["update:filter-text", "reloadContents"]); const router = useRouter(); const { config } = useConfig(); const { currentUser } = storeToRefs(useUserStore()); -const { historySize, numItemsActive, numItemsDeleted, numItemsHidden } = useDetailedHistory(toRef(props, "history")); +const { historySize, numItemsActive, numItemsDeleted, numItemsHidden } = useHistoryContentStats( + toRef(props, "history") +); const reloadButtonLoading = ref(false); const reloadButtonTitle = ref(""); diff --git a/client/src/components/History/CurrentHistory/HistoryOperations/DefaultOperations.vue b/client/src/components/History/CurrentHistory/HistoryOperations/DefaultOperations.vue index ad3f94fda94c..07bb357e4c3a 100644 --- a/client/src/components/History/CurrentHistory/HistoryOperations/DefaultOperations.vue +++ b/client/src/components/History/CurrentHistory/HistoryOperations/DefaultOperations.vue @@ -5,26 +5,26 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { BDropdown, BDropdownItem, BDropdownText, BModal } from "bootstrap-vue"; import { toRef } from "vue"; -import type { HistorySummary } from "@/api"; -import { useDetailedHistory } from "@/components/History/CurrentHistory/usesDetailedHistory"; +import type { HistorySummary, HistorySummaryExtended } from "@/api"; import { deleteAllHiddenContent, purgeAllDeletedContent, unhideAllHiddenContent, } from "@/components/History/model/crud"; import { iframeRedirect } from "@/components/plugins/legacyNavigation"; +import { useHistoryContentStats } from "@/composables/historyContentStats"; library.add(faCog); interface Props { - history: HistorySummary; + history: HistorySummaryExtended; } const props = defineProps(); const emit = defineEmits(["update:operation-running"]); -const { numItemsDeleted, numItemsHidden } = useDetailedHistory(toRef(props, "history")); +const { numItemsDeleted, numItemsHidden } = useHistoryContentStats(toRef(props, "history")); function onCopy() { iframeRedirect("/dataset/copy_datasets"); diff --git a/client/src/components/History/CurrentHistory/HistoryOperations/HistoryOperations.vue b/client/src/components/History/CurrentHistory/HistoryOperations/HistoryOperations.vue index cddb848018d5..4ae704e4b8fa 100644 --- a/client/src/components/History/CurrentHistory/HistoryOperations/HistoryOperations.vue +++ b/client/src/components/History/CurrentHistory/HistoryOperations/HistoryOperations.vue @@ -3,17 +3,18 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faCheckSquare, faCompress } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; -import type { HistorySummary } from "@/api"; +import type { HistorySummaryExtended } from "@/api"; import DefaultOperations from "@/components/History/CurrentHistory/HistoryOperations/DefaultOperations.vue"; library.add(faCheckSquare, faCompress); interface Props { - history: HistorySummary; + history: HistorySummaryExtended; hasMatches: boolean; expandedCount: number; showSelection: boolean; + isMultiViewItem: boolean; } const props = defineProps(); @@ -60,6 +61,7 @@ function onUpdateOperationStatus(updateTime: number) { diff --git a/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue b/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue index 766ef8ac9686..59076e8063af 100644 --- a/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue +++ b/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue @@ -1,5 +1,5 @@