diff --git a/apps/dumili/api/services/indexation/index.ts b/apps/dumili/api/services/indexation/index.ts
index 9c8578c17..d7ff773ba 100644
--- a/apps/dumili/api/services/indexation/index.ts
+++ b/apps/dumili/api/services/indexation/index.ts
@@ -383,7 +383,20 @@ export default (io: Server) => {
indexationSocket.on("runKumikoOnPage", async (pageId, callback) => {
const { indexation } = indexationSocket.data;
- const page = indexation.pages.find(({ id }) => id === pageId)!;
+ const page = await prisma.page.findUnique({
+ where: {
+ id: pageId,
+ indexationId: indexation.id,
+ },
+ });
+
+ if (!page) {
+ callback({
+ error: `This indexation does not have any page with this ID`,
+ errorDetails: JSON.stringify({ pageId }),
+ });
+ return;
+ }
await setKumikoInferredPageStoryKinds([page]);
const entry = getEntryFromPage(indexation, pageId)!;
diff --git a/apps/dumili/api/services/indexation/types.ts b/apps/dumili/api/services/indexation/types.ts
index f9edf9ea7..ab52b22f0 100644
--- a/apps/dumili/api/services/indexation/types.ts
+++ b/apps/dumili/api/services/indexation/types.ts
@@ -51,7 +51,7 @@ export default abstract class {
abstract setPageUrl: (
id: number,
- url: string,
+ url: string|null,
callback: () => void,
) => void;
@@ -138,7 +138,7 @@ export default abstract class {
abstract runKumikoOnPage: (
pageId: page["id"],
callback: (
- data: Errorable<{ status: "OK" }, "Kumiko output could not be parsed">,
+ data: Errorable<{ status: "OK" }, "This indexation does not have any page with this ID"|"Kumiko output could not be parsed">,
) => void,
) => void;
diff --git a/apps/dumili/src/components/AiTooltip.vue b/apps/dumili/src/components/AiTooltip.vue
index eeba05e2c..0a7ceed1c 100644
--- a/apps/dumili/src/components/AiTooltip.vue
+++ b/apps/dumili/src/components/AiTooltip.vue
@@ -3,9 +3,11 @@
@mouseout="() => (showRepeat = false)"
@mouseover="() => (showRepeat = true)"
>
-
+
+
+
{{
$t("Type inconnu")
}}
- {{ $t("Types d'entrées déduits pour les pages") }}
-
- {{ $t("Type d'entrée déduit") }}
- {{
- storyKindAiSuggestion
- ? storyKinds[storyKindAiSuggestion?.kind]
- : $t("Non calculé")
- }}
-
-
- {{ $t("Résultats OCR pour la première case:") }}
-
- {{ $t("Histoires potentielles:") }}
- {{
- $t("Pas de résultats OCR")
- }}
diff --git a/apps/dumili/src/components/TableOfContentsPage.vue b/apps/dumili/src/components/TableOfContentsPage.vue
new file mode 100644
index 000000000..e2e5fa971
--- /dev/null
+++ b/apps/dumili/src/components/TableOfContentsPage.vue
@@ -0,0 +1,53 @@
+
+ {{ $t("Page") }} {{ pageNumber }}
+ {{ $t("Cases détectées") }}
+
+ {{ $t("Type d'entrée déduit pour la page") }}
+ {{
+ aiKumikoInferredStoryKind
+ ? storyKinds[aiKumikoInferredStoryKind] || $t("Non calculé")
+ : $t("Non calculé")
+ }}
+
+
+
+
\ No newline at end of file
diff --git a/apps/dumili/src/components/UploadModal.vue b/apps/dumili/src/components/UploadModal.vue
index 3b88669d0..14a9cdfcc 100644
--- a/apps/dumili/src/components/UploadModal.vue
+++ b/apps/dumili/src/components/UploadModal.vue
@@ -3,11 +3,10 @@
id="upload-modal"
v-model="modal"
:title="$t('Envoi d\'images de pages')"
- :cancel-title="$t('Annuler')"
align="center"
- hide-footer
+ no-footer
centered
- :class="{ 'pe-none': isProcessing }"
+ :class="{ 'pe-none': isUploading || processLog }"
content-class="h-100 "
dialog-class="h-100"
body-class="d-flex flex-column align-items-start overflow-auto"
@@ -53,7 +52,7 @@
-
+
@@ -63,25 +62,25 @@ import type {
CloudinaryUploadWidgetInfo,
} from "cloudinary-widget";
import { dumiliSocketInjectionKey } from "~/composables/useDumiliSocket";
+import { suggestions } from "~/stores/suggestions";
import { stores as webStores } from "~web";
const { indexationSocket } = inject(dumiliSocketInjectionKey)!;
+const { indexation } = storeToRefs(suggestions());
const { user } = storeToRefs(webStores.collection());
const modal = ref(true);
const uploadFileType = ref<"PDF" | "Images">("PDF");
-const { folderName, pages } = defineProps<{
+const { pages } = defineProps<{
pages: { id: number; pageNumber: number }[];
- folderName: string;
}>();
-console.log("folderName", folderName);
-
const currentPageIndex = ref(0);
-const isProcessing = ref(false);
+const showWidget = ref(true);
+const isUploading = ref(false);
const processLog = ref("");
const emit = defineEmits<{
@@ -101,6 +100,7 @@ const processPage = async (pageIndex: number, url: string) => {
};
onMounted(() => {
+ const folderName = indexation.value!.id;
const uploadWidget = cloudinary.createUploadWidget(
{
cloudName: import.meta.env.VITE_CLOUDINARY_CLOUDNAME,
@@ -123,9 +123,10 @@ onMounted(() => {
} else {
switch (result?.event) {
case "queues-start":
- isProcessing.value = true;
+ isUploading.value = true;
break;
case "success":
+ showWidget.value = false;
const info = result.info as CloudinaryUploadWidgetInfo;
console.log("Done! Here is the image info: ", info);
@@ -146,9 +147,7 @@ onMounted(() => {
await processPage(currentPageIndex.value++, info.secure_url);
}
currentPageIndex.value = 0;
- processLog.value = ``;
- isProcessing.value = false;
- uploadWidget.close();
+ modal.value = false;
emit("done");
break;
case "abort":
@@ -158,6 +157,12 @@ onMounted(() => {
}
},
);
+
+ watch(showWidget, (value) => {
+ if (!value) {
+ uploadWidget.close();
+ }
+ });
});
diff --git a/apps/dumili/src/composables/useHint.ts b/apps/dumili/src/composables/useHint.ts
index 70ec516f4..d8e6a67b1 100644
--- a/apps/dumili/src/composables/useHint.ts
+++ b/apps/dumili/src/composables/useHint.ts
@@ -6,7 +6,6 @@ import { dumiliSocketInjectionKey } from "./useDumiliSocket";
export default () => {
const { loadIndexation } = suggestions();
- const { indexation } = storeToRefs(suggestions());
const { fetchIssuecodeDetails, fetchPublicationNames } = coa();
const { issuecodeDetails } = storeToRefs(coa());
@@ -28,7 +27,7 @@ export default () => {
),
);
- await loadIndexation(indexation.value!.id);
+ await loadIndexation();
await fetchIssuecodeDetails(
results.covers.map(({ issuecode }) => issuecode!),
diff --git a/apps/dumili/src/pages/indexation/[id].vue b/apps/dumili/src/pages/indexation/[id].vue
index 09f83e339..51ca67750 100644
--- a/apps/dumili/src/pages/indexation/[id].vue
+++ b/apps/dumili/src/pages/indexation/[id].vue
@@ -1,15 +1,7 @@
-
-
-
- {{ $t("Envoyer des images de pages") }}
-
-
+
(undefined);
-const showUploadWidget = ref(false);
const route = useRoute();
const { t: $t } = useI18n();
diff --git a/apps/dumili/src/stores/ui.ts b/apps/dumili/src/stores/ui.ts
index d8ccf7603..b3c37f925 100644
--- a/apps/dumili/src/stores/ui.ts
+++ b/apps/dumili/src/stores/ui.ts
@@ -9,6 +9,7 @@ export const ui = defineStore("ui", () => {
const currentEntry = ref();
const currentPage = ref(0);
const visiblePages = ref | undefined>();
+ const pageHeight = ref(50);
watch(
indexation,
@@ -22,6 +23,7 @@ export const ui = defineStore("ui", () => {
showAiDetectionsOn: ref<{ type: "page" | "entry"; id: number } | undefined>(
undefined,
),
+ pageHeight,
currentPage,
visiblePages,
currentEntry,
diff --git a/apps/dumili/src/style.scss b/apps/dumili/src/style.scss
index e9d43a218..4a46b56e0 100644
--- a/apps/dumili/src/style.scss
+++ b/apps/dumili/src/style.scss
@@ -1,5 +1,9 @@
@use "sass:color";
+.opacity-100-hover:hover{
+ opacity: 1 !important;
+}
+
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
diff --git a/apps/dumili/translations/messages.en.json b/apps/dumili/translations/messages.en.json
index 9ab088bdd..88c717915 100644
--- a/apps/dumili/translations/messages.en.json
+++ b/apps/dumili/translations/messages.en.json
@@ -8,6 +8,7 @@
"Cette histoire fait généralement {originalPagesCount} pages mais l'entrée en contient {entryPagesCount}": "This story usually has {originalPagesCount} pages but the entry contains {entryPagesCount}",
"Combien de pages le magazine contient-il ? (y compris les pages que vous ne souhaitez pas indexer)": "How many pages does the magazine contain? (including pages you don't want to index)",
"Contenu inconnu": "Unknown content",
+ "Désassocier l'image": "Deassociate image",
"Détections AI": "AI detections",
"Dumili a trouvé des couvertures existantes ressemblant à la vôtre. Sélectionnez la couverture qui ressemble le plus à la vôtre.": "Dumili found existing covers that look like yours. Select the cover that looks most like yours.",
"Editeur de texte": "Text editor",
@@ -15,18 +16,22 @@
"Envoyer des images de pages": "Upload page files",
"Galerie des pages": "Gallery",
"Histoires potentielles:": "Potential stories:",
+ "Images": "Images",
"Indexations en cours": "Ongoing indexations",
"La première page est généralement une page de couverture": "The first page is usually a cover page",
"Le type de l'histoire sélectionnée ne correspond pas au type de l'entrée": "The type of the selected story doesn't correspond to the entry type",
"Les images envoyées seront associées aux pages {firstPage} à {lastPage}. Si votre PDF fait plus de {maxPages} page(s), les pages suivantes seront ignorées.": "The uploaded images will be associated with pages {firstPage} to {lastPage}. If your PDF has more than {maxPages} page(s), the next pages will be ignored.",
"Livre": "Book",
"Méta-données": "Metadata",
+ "Nombre de pages": "Number of pages",
"Non calculé": "Not calculated",
"Nouvelle indexation": "New indexation",
"Numéro inconnu": "Unknown issue",
"Page": "Page",
+ "Page {pageNumber} (ID: {id})": "Page {pageNumber} (ID: {id})",
"Personnaliser...": "Customize...",
"Pas de résultats OCR": "No OCR results",
+ "PDF": "PDF",
"Prix": "Price",
"Rechercher...": "Search...",
"Résultats OCR pour la première case:": "OCR results for the first page:",
@@ -44,6 +49,7 @@
"Veuillez entre le numéro": "Please type the number",
"Vous devez être connecté pour accéder à cette page.": "You must be logged in to access this page.",
"Vous devez spécifier une publication et un numéro pour continuer": "You must specify a publication and an issue number to continue",
+ "Vous êtes sur le point de supprimer les {numberOfPagesToDelete} dernières pages de l'indexation. Êtes-vous sûr(e) ?": "You are about to delete the last {numberOfPagesToDelete} pages of the indexation. Are you sure?",
"partie": "part",
"{numberOfPanels} cases trouvées": "{numberOfPanels} detected panels",
"{numberOfStories} histoires trouvées avec ces mots-clés": "{numberOfStories} stories found with these keywords",