🔨 Added missing file statuses on Dashboard and Library
This commit is contained in:
@@ -42,6 +42,7 @@ export const RecentlyImported = (
|
|||||||
sourcedMetadata,
|
sourcedMetadata,
|
||||||
canonicalMetadata,
|
canonicalMetadata,
|
||||||
inferredMetadata,
|
inferredMetadata,
|
||||||
|
importStatus,
|
||||||
} = comic;
|
} = comic;
|
||||||
|
|
||||||
// Parse sourced metadata (GraphQL returns as strings)
|
// Parse sourced metadata (GraphQL returns as strings)
|
||||||
@@ -63,7 +64,7 @@ export const RecentlyImported = (
|
|||||||
!isUndefined(comicvine) &&
|
!isUndefined(comicvine) &&
|
||||||
!isUndefined(comicvine.volumeInformation);
|
!isUndefined(comicvine.volumeInformation);
|
||||||
const hasComicInfo = !isNil(comicInfo) && !isEmpty(comicInfo);
|
const hasComicInfo = !isNil(comicInfo) && !isEmpty(comicInfo);
|
||||||
const isMissingFile = isNil(rawFileDetails);
|
const isMissingFile = importStatus?.isRawFileMissing === true;
|
||||||
const cardState = isMissingFile
|
const cardState = isMissingFile
|
||||||
? "missing"
|
? "missing"
|
||||||
: (hasComicInfo || isComicVineMetadataAvailable) ? "scraped" : "imported";
|
: (hasComicInfo || isComicVineMetadataAvailable) ? "scraped" : "imported";
|
||||||
@@ -131,7 +132,7 @@ export const RecentlyImported = (
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Raw file presence */}
|
{/* Raw file presence */}
|
||||||
{isNil(rawFileDetails) && (
|
{isMissingFile && (
|
||||||
<span className="h-6 w-5 sm:shrink-0 sm:items-center sm:gap-2">
|
<span className="h-6 w-5 sm:shrink-0 sm:items-center sm:gap-2">
|
||||||
<i className="icon-[solar--file-corrupted-outline] h-5 w-5" />
|
<i className="icon-[solar--file-corrupted-outline] h-5 w-5" />
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ export const Library = (): ReactElement => {
|
|||||||
columns={missingFilesColumns}
|
columns={missingFilesColumns}
|
||||||
sourceData={missingFilesData?.getComicBooks?.docs ?? []}
|
sourceData={missingFilesData?.getComicBooks?.docs ?? []}
|
||||||
rowClickHandler={navigateToMissingComicDetail}
|
rowClickHandler={navigateToMissingComicDetail}
|
||||||
getRowClassName={() => "bg-card-missing/40"}
|
getRowClassName={() => "bg-card-missing/40 hover:bg-card-missing/20"}
|
||||||
paginationHandlers={{ nextPage: () => {}, previousPage: () => {} }}
|
paginationHandlers={{ nextPage: () => {}, previousPage: () => {} }}
|
||||||
>
|
>
|
||||||
<FilterDropdown />
|
<FilterDropdown />
|
||||||
@@ -328,6 +328,11 @@ export const Library = (): ReactElement => {
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
sourceData={searchResults?.hits.hits}
|
sourceData={searchResults?.hits.hits}
|
||||||
rowClickHandler={navigateToComicDetail}
|
rowClickHandler={navigateToComicDetail}
|
||||||
|
getRowClassName={(row) =>
|
||||||
|
missingIdSet.has(row.original._id)
|
||||||
|
? "bg-card-missing/40 hover:bg-card-missing/20"
|
||||||
|
: "hover:bg-slate-100/30 dark:hover:bg-slate-700/20"
|
||||||
|
}
|
||||||
paginationHandlers={{ nextPage, previousPage }}
|
paginationHandlers={{ nextPage, previousPage }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
|||||||
@@ -104,11 +104,22 @@ const renderCard = (props: ICardProps): ReactElement => {
|
|||||||
case "vertical-2":
|
case "vertical-2":
|
||||||
return (
|
return (
|
||||||
<div className={`block rounded-md max-w-64 h-fit shadow-md shadow-white-400 ${getCardStateClass(props.cardState) || "bg-gray-200 dark:bg-slate-500"}`}>
|
<div className={`block rounded-md max-w-64 h-fit shadow-md shadow-white-400 ${getCardStateClass(props.cardState) || "bg-gray-200 dark:bg-slate-500"}`}>
|
||||||
<img
|
<div className="relative">
|
||||||
alt="Home"
|
{props.imageUrl ? (
|
||||||
src={props.imageUrl}
|
<img
|
||||||
className="rounded-t-md object-cover"
|
alt="Home"
|
||||||
/>
|
src={props.imageUrl}
|
||||||
|
className="rounded-t-md object-cover"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="rounded-t-md h-48 bg-gray-100 dark:bg-slate-600" />
|
||||||
|
)}
|
||||||
|
{props.cardState === "missing" && (
|
||||||
|
<div className="absolute inset-0 flex items-center justify-center rounded-t-md bg-card-missing/70">
|
||||||
|
<i className="icon-[solar--file-broken-bold] w-16 h-16 text-red-500" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{props.title ? (
|
{props.title ? (
|
||||||
<div className="px-3 pt-3 mb-2">
|
<div className="px-3 pt-3 mb-2">
|
||||||
|
|||||||
@@ -34,11 +34,10 @@ export const MetadataPanel = (props: IMetadatPanelProps): ReactElement => {
|
|||||||
{
|
{
|
||||||
name: "rawFileDetails",
|
name: "rawFileDetails",
|
||||||
content: () => (
|
content: () => (
|
||||||
<dl className={`${isMissing ? "bg-card-missing dark:bg-card-missing" : "bg-card-imported dark:bg-card-imported"} dark:text-slate-800 p-2 sm:p-3 rounded-lg`}>
|
<dl
|
||||||
|
className={`${isMissing ? "bg-card-missing dark:bg-card-missing" : "bg-card-imported dark:bg-card-imported"} dark:text-slate-800 p-2 sm:p-3 rounded-lg`}
|
||||||
|
>
|
||||||
<dt className="flex items-center gap-2">
|
<dt className="flex items-center gap-2">
|
||||||
{isMissing && (
|
|
||||||
<i className="icon-[solar--file-remove-broken] w-4 h-4 text-red-600 shrink-0"></i>
|
|
||||||
)}
|
|
||||||
<p className="text-sm sm:text-lg">{issueName}</p>
|
<p className="text-sm sm:text-lg">{issueName}</p>
|
||||||
</dt>
|
</dt>
|
||||||
<dd className="text-xs sm:text-sm">
|
<dd className="text-xs sm:text-sm">
|
||||||
@@ -87,6 +86,13 @@ export const MetadataPanel = (props: IMetadatPanelProps): ReactElement => {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Missing file Icon */}
|
||||||
|
{isMissing && (
|
||||||
|
<span className="pr-2 pt-1" title="File backing this comic is missing">
|
||||||
|
<i className="icon-[solar--file-remove-broken] w-5 h-5 text-red-600 shrink-0"></i>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Uncompressed version available? */}
|
{/* Uncompressed version available? */}
|
||||||
{rawFileDetails.archive?.uncompressed && (
|
{rawFileDetails.archive?.uncompressed && (
|
||||||
<span className="inline-flex items-center bg-slate-50 text-slate-800 text-xs px-2 rounded-md dark:text-slate-900 dark:bg-slate-400">
|
<span className="inline-flex items-center bg-slate-50 text-slate-800 text-xs px-2 rounded-md dark:text-slate-900 dark:bg-slate-400">
|
||||||
@@ -188,7 +194,6 @@ export const MetadataPanel = (props: IMetadatPanelProps): ReactElement => {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col sm:flex-row gap-3 sm:gap-5 my-3">
|
<div className="flex flex-col sm:flex-row gap-3 sm:gap-5 my-3">
|
||||||
<div className="w-32 sm:w-56 lg:w-52 shrink-0">
|
<div className="w-32 sm:w-56 lg:w-52 shrink-0">
|
||||||
|
|
||||||
<Card
|
<Card
|
||||||
imageUrl={url}
|
imageUrl={url}
|
||||||
orientation={"cover-only"}
|
orientation={"cover-only"}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { ReactElement, useMemo, useState } from "react";
|
import React, { ReactElement, useMemo, useState, useRef, useEffect, useLayoutEffect } from "react";
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
flexRender,
|
flexRender,
|
||||||
@@ -8,19 +8,38 @@ import {
|
|||||||
PaginationState,
|
PaginationState,
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Props for {@link T2Table}.
|
||||||
|
*/
|
||||||
interface T2TableProps {
|
interface T2TableProps {
|
||||||
|
/** Row data to render. */
|
||||||
sourceData?: unknown[];
|
sourceData?: unknown[];
|
||||||
|
/** Total number of records across all pages, used for pagination display. */
|
||||||
totalPages?: number;
|
totalPages?: number;
|
||||||
|
/** Column definitions (TanStack Table {@link ColumnDef} array). */
|
||||||
columns?: unknown[];
|
columns?: unknown[];
|
||||||
|
/** Callbacks for navigating between pages. */
|
||||||
paginationHandlers?: {
|
paginationHandlers?: {
|
||||||
nextPage?(...args: unknown[]): unknown;
|
nextPage?(...args: unknown[]): unknown;
|
||||||
previousPage?(...args: unknown[]): unknown;
|
previousPage?(...args: unknown[]): unknown;
|
||||||
};
|
};
|
||||||
|
/** Called with the TanStack row object when a row is clicked. */
|
||||||
rowClickHandler?(...args: unknown[]): unknown;
|
rowClickHandler?(...args: unknown[]): unknown;
|
||||||
|
/** Returns additional CSS classes for a given row (e.g. for highlight states). */
|
||||||
getRowClassName?(row: any): string;
|
getRowClassName?(row: any): string;
|
||||||
|
/** Optional slot rendered in the toolbar area (e.g. a search input). */
|
||||||
children?: any;
|
children?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A paginated data table with a two-row sticky header.
|
||||||
|
*
|
||||||
|
* The header rounds its corners only while stuck to the top of the scroll
|
||||||
|
* container, detected via {@link IntersectionObserver} on a sentinel element
|
||||||
|
* placed immediately before the table. The second header row's `top` offset
|
||||||
|
* is measured from the DOM at mount time so the two rows stay flush regardless
|
||||||
|
* of font size or padding changes.
|
||||||
|
*/
|
||||||
export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
||||||
const {
|
const {
|
||||||
sourceData,
|
sourceData,
|
||||||
@@ -31,6 +50,27 @@ export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
|||||||
getRowClassName,
|
getRowClassName,
|
||||||
} = tableOptions;
|
} = tableOptions;
|
||||||
|
|
||||||
|
const sentinelRef = useRef<HTMLDivElement>(null);
|
||||||
|
const firstHeaderRowRef = useRef<HTMLTableRowElement>(null);
|
||||||
|
const [isSticky, setIsSticky] = useState(false);
|
||||||
|
const [firstRowHeight, setFirstRowHeight] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const sentinel = sentinelRef.current;
|
||||||
|
if (!sentinel) return;
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
([entry]) => setIsSticky(!entry.isIntersecting),
|
||||||
|
{ threshold: 0 },
|
||||||
|
);
|
||||||
|
observer.observe(sentinel);
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (firstHeaderRowRef.current)
|
||||||
|
setFirstRowHeight(firstHeaderRowRef.current.getBoundingClientRect().height);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const [{ pageIndex, pageSize }, setPagination] = useState<PaginationState>({
|
const [{ pageIndex, pageSize }, setPagination] = useState<PaginationState>({
|
||||||
pageIndex: 1,
|
pageIndex: 1,
|
||||||
pageSize: 15,
|
pageSize: 15,
|
||||||
@@ -44,10 +84,7 @@ export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
|||||||
[pageIndex, pageSize],
|
[pageIndex, pageSize],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/** Advances to the next page and notifies the parent via {@link T2TableProps.paginationHandlers}. */
|
||||||
* Pagination control to move forward one page
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
const goToNextPage = () => {
|
const goToNextPage = () => {
|
||||||
setPagination({
|
setPagination({
|
||||||
pageIndex: pageIndex + 1,
|
pageIndex: pageIndex + 1,
|
||||||
@@ -56,10 +93,7 @@ export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
|||||||
nextPage(pageIndex, pageSize);
|
nextPage(pageIndex, pageSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** Goes back one page and notifies the parent via {@link T2TableProps.paginationHandlers}. */
|
||||||
* Pagination control to move backward one page
|
|
||||||
* @returns void
|
|
||||||
**/
|
|
||||||
const goToPreviousPage = () => {
|
const goToPreviousPage = () => {
|
||||||
setPagination({
|
setPagination({
|
||||||
pageIndex: pageIndex - 1,
|
pageIndex: pageIndex - 1,
|
||||||
@@ -115,26 +149,33 @@ export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div ref={sentinelRef} />
|
||||||
<table className="table-auto w-full text-sm text-gray-900 dark:text-slate-100">
|
<table className="table-auto w-full text-sm text-gray-900 dark:text-slate-100">
|
||||||
<thead className="sticky top-0 z-10 bg-white dark:bg-slate-900">
|
<thead>
|
||||||
{table.getHeaderGroups().map((headerGroup, groupIndex) => (
|
{table.getHeaderGroups().map((headerGroup, groupIndex) => {
|
||||||
<tr key={headerGroup.id}>
|
return (
|
||||||
{headerGroup.headers.map((header, index) => (
|
<tr key={headerGroup.id} ref={groupIndex === 0 ? firstHeaderRowRef : undefined}>
|
||||||
<th
|
{headerGroup.headers.map((header) => (
|
||||||
key={header.id}
|
<th
|
||||||
colSpan={header.colSpan}
|
key={header.id}
|
||||||
className="px-3 py-2 text-[11px] font-semibold tracking-wide uppercase text-left text-gray-500 dark:text-slate-400 border-b border-gray-300 dark:border-slate-700"
|
colSpan={header.colSpan}
|
||||||
>
|
style={groupIndex === 1 ? { top: firstRowHeight } : undefined}
|
||||||
{header.isPlaceholder
|
className={[
|
||||||
? null
|
'sticky z-10 px-3 py-2 text-[11px] font-semibold tracking-wide uppercase text-left',
|
||||||
: flexRender(
|
'text-gray-500 dark:text-slate-400 bg-white dark:bg-slate-900',
|
||||||
header.column.columnDef.header,
|
groupIndex === 0
|
||||||
header.getContext(),
|
? `top-0 ${isSticky ? 'first:rounded-tl-xl last:rounded-tr-xl' : ''}`
|
||||||
)}
|
: `border-b-2 border-gray-200 dark:border-slate-600 shadow-md ${isSticky ? 'first:rounded-bl-xl last:rounded-br-xl' : ''}`,
|
||||||
</th>
|
].join(' ')}
|
||||||
))}
|
>
|
||||||
</tr>
|
{header.isPlaceholder
|
||||||
))}
|
? null
|
||||||
|
: flexRender(header.column.columnDef.header, header.getContext())}
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -142,7 +183,7 @@ export const T2Table = (tableOptions: T2TableProps): ReactElement => {
|
|||||||
<tr
|
<tr
|
||||||
key={row.id}
|
key={row.id}
|
||||||
onClick={() => rowClickHandler(row)}
|
onClick={() => rowClickHandler(row)}
|
||||||
className={`border-b border-gray-200 dark:border-slate-700 hover:bg-slate-100/30 dark:hover:bg-slate-700/20 transition-colors cursor-pointer ${getRowClassName ? getRowClassName(row) : ""}`}
|
className={`border-b border-gray-200 dark:border-slate-700 transition-colors cursor-pointer ${getRowClassName ? getRowClassName(row) : "hover:bg-slate-100/30 dark:hover:bg-slate-700/20"}`}
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<td key={cell.id} className="px-3 py-2 align-top">
|
<td key={cell.id} className="px-3 py-2 align-top">
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ export type AcquisitionSourceInput = {
|
|||||||
wanted?: InputMaybe<Scalars['Boolean']['input']>;
|
wanted?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AddTorrentInput = {
|
||||||
|
comicObjectId: Scalars['ID']['input'];
|
||||||
|
torrentToDownload: Scalars['String']['input'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddTorrentResult = {
|
||||||
|
__typename?: 'AddTorrentResult';
|
||||||
|
result?: Maybe<Scalars['JSON']['output']>;
|
||||||
|
};
|
||||||
|
|
||||||
export type AppSettings = {
|
export type AppSettings = {
|
||||||
__typename?: 'AppSettings';
|
__typename?: 'AppSettings';
|
||||||
bittorrent?: Maybe<BittorrentSettings>;
|
bittorrent?: Maybe<BittorrentSettings>;
|
||||||
@@ -405,6 +415,7 @@ export type ImportStats = {
|
|||||||
export type ImportStatus = {
|
export type ImportStatus = {
|
||||||
__typename?: 'ImportStatus';
|
__typename?: 'ImportStatus';
|
||||||
isImported?: Maybe<Scalars['Boolean']['output']>;
|
isImported?: Maybe<Scalars['Boolean']['output']>;
|
||||||
|
isRawFileMissing?: Maybe<Scalars['Boolean']['output']>;
|
||||||
matchedResult?: Maybe<MatchedResult>;
|
matchedResult?: Maybe<MatchedResult>;
|
||||||
tagged?: Maybe<Scalars['Boolean']['output']>;
|
tagged?: Maybe<Scalars['Boolean']['output']>;
|
||||||
};
|
};
|
||||||
@@ -609,6 +620,8 @@ export type Mutation = {
|
|||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
/** Placeholder for future mutations */
|
/** Placeholder for future mutations */
|
||||||
_empty?: Maybe<Scalars['String']['output']>;
|
_empty?: Maybe<Scalars['String']['output']>;
|
||||||
|
/** Add a torrent to qBittorrent */
|
||||||
|
addTorrent?: Maybe<AddTorrentResult>;
|
||||||
analyzeImage: ImageAnalysisResult;
|
analyzeImage: ImageAnalysisResult;
|
||||||
applyComicVineMatch: Comic;
|
applyComicVineMatch: Comic;
|
||||||
bulkResolveMetadata: Array<Comic>;
|
bulkResolveMetadata: Array<Comic>;
|
||||||
@@ -626,6 +639,11 @@ export type Mutation = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationAddTorrentArgs = {
|
||||||
|
input: AddTorrentInput;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationAnalyzeImageArgs = {
|
export type MutationAnalyzeImageArgs = {
|
||||||
imageFilePath: Scalars['String']['input'];
|
imageFilePath: Scalars['String']['input'];
|
||||||
};
|
};
|
||||||
@@ -768,6 +786,7 @@ export type PublisherStats = {
|
|||||||
|
|
||||||
export type Query = {
|
export type Query = {
|
||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
|
_empty?: Maybe<Scalars['String']['output']>;
|
||||||
analyzeMetadataConflicts: Array<MetadataConflict>;
|
analyzeMetadataConflicts: Array<MetadataConflict>;
|
||||||
bundles: Array<Bundle>;
|
bundles: Array<Bundle>;
|
||||||
comic?: Maybe<Comic>;
|
comic?: Maybe<Comic>;
|
||||||
@@ -1265,7 +1284,7 @@ export type GetRecentComicsQueryVariables = Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type GetRecentComicsQuery = { __typename?: 'Query', comics: { __typename?: 'ComicConnection', totalCount: number, comics: Array<{ __typename?: 'Comic', id: string, createdAt?: string | null, updatedAt?: string | null, inferredMetadata?: { __typename?: 'InferredMetadata', issue?: { __typename?: 'Issue', name?: string | null, number?: number | null, year?: string | null, subtitle?: string | null } | null } | null, rawFileDetails?: { __typename?: 'RawFileDetails', name?: string | null, extension?: string | null, cover?: { __typename?: 'Cover', filePath?: string | null } | null, archive?: { __typename?: 'Archive', uncompressed?: boolean | null } | null } | null, sourcedMetadata?: { __typename?: 'SourcedMetadata', comicvine?: string | null, comicInfo?: string | null, locg?: { __typename?: 'LOCGMetadata', name?: string | null, publisher?: string | null, cover?: string | null } | null } | null, canonicalMetadata?: { __typename?: 'CanonicalMetadata', title?: { __typename?: 'MetadataField', value?: string | null } | null, series?: { __typename?: 'MetadataField', value?: string | null } | null, issueNumber?: { __typename?: 'MetadataField', value?: string | null } | null, publisher?: { __typename?: 'MetadataField', value?: string | null } | null } | null }> } };
|
export type GetRecentComicsQuery = { __typename?: 'Query', comics: { __typename?: 'ComicConnection', totalCount: number, comics: Array<{ __typename?: 'Comic', id: string, createdAt?: string | null, updatedAt?: string | null, inferredMetadata?: { __typename?: 'InferredMetadata', issue?: { __typename?: 'Issue', name?: string | null, number?: number | null, year?: string | null, subtitle?: string | null } | null } | null, rawFileDetails?: { __typename?: 'RawFileDetails', name?: string | null, extension?: string | null, cover?: { __typename?: 'Cover', filePath?: string | null } | null, archive?: { __typename?: 'Archive', uncompressed?: boolean | null } | null } | null, sourcedMetadata?: { __typename?: 'SourcedMetadata', comicvine?: string | null, comicInfo?: string | null, locg?: { __typename?: 'LOCGMetadata', name?: string | null, publisher?: string | null, cover?: string | null } | null } | null, canonicalMetadata?: { __typename?: 'CanonicalMetadata', title?: { __typename?: 'MetadataField', value?: string | null } | null, series?: { __typename?: 'MetadataField', value?: string | null } | null, issueNumber?: { __typename?: 'MetadataField', value?: string | null } | null, publisher?: { __typename?: 'MetadataField', value?: string | null } | null } | null, importStatus?: { __typename?: 'ImportStatus', isRawFileMissing?: boolean | null } | null }> } };
|
||||||
|
|
||||||
export type GetWantedComicsQueryVariables = Exact<{
|
export type GetWantedComicsQueryVariables = Exact<{
|
||||||
paginationOptions: PaginationOptionsInput;
|
paginationOptions: PaginationOptionsInput;
|
||||||
@@ -1706,6 +1725,9 @@ export const GetRecentComicsDocument = `
|
|||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
importStatus {
|
||||||
|
isRawFileMissing
|
||||||
|
}
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ query GetRecentComics($limit: Int) {
|
|||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
importStatus {
|
||||||
|
isRawFileMissing
|
||||||
|
}
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user