mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
More automatic eslint fixes, update baseline and eslint docs
This commit is contained in:
parent
e8962782ed
commit
16fe07cce7
@ -13,6 +13,18 @@ Interesting options are:
|
||||
- ``--quiet`` to only get errors and silence the warnings
|
||||
- ``--fix`` to have ESLint fix what it can, automatically. This will not fix everything.
|
||||
|
||||
Baseline
|
||||
--------
|
||||
|
||||
To allow us the time to fix linting errors/warnings a baseline has been created using the following command
|
||||
- ``npx eslint-baseline "**/*.{js,vue}"``
|
||||
|
||||
The baseline has been commited and the gitlab CI setup to only fail upon new errors/warnings being created.
|
||||
When fixing errors/warnings manually, please update the baseline.
|
||||
|
||||
1. Delete the current baseline file
|
||||
2. Run the above command locally, this will automatically create a new baseline that should be commited
|
||||
|
||||
Rules
|
||||
-----
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
import {makeFetch} from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
import {PostStoreObjectSignature, StoredObject} from "../../types";
|
||||
import { makeFetch } from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
import { PostStoreObjectSignature, StoredObject } from "../../types";
|
||||
|
||||
const algo = 'AES-CBC';
|
||||
const algo = "AES-CBC";
|
||||
|
||||
const URL_POST = '/asyncupload/temp_url/generate/post';
|
||||
const URL_POST = "/asyncupload/temp_url/generate/post";
|
||||
|
||||
const keyDefinition = {
|
||||
name: algo,
|
||||
length: 256
|
||||
length: 256,
|
||||
};
|
||||
|
||||
const createFilename = (): string => {
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let text = "";
|
||||
const possible =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
for (let i = 0; i < 7; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
@ -29,14 +30,22 @@ const createFilename = (): string => {
|
||||
* @returns {Promise<StoredObject>} A Promise that resolves to the newly created StoredObject.
|
||||
*/
|
||||
export const fetchNewStoredObject = async (): Promise<StoredObject> => {
|
||||
return makeFetch("POST", '/api/1.0/doc-store/stored-object/create', null);
|
||||
}
|
||||
return makeFetch("POST", "/api/1.0/doc-store/stored-object/create", null);
|
||||
};
|
||||
|
||||
export const uploadVersion = async (uploadFile: ArrayBuffer, storedObject: StoredObject): Promise<string> => {
|
||||
export const uploadVersion = async (
|
||||
uploadFile: ArrayBuffer,
|
||||
storedObject: StoredObject,
|
||||
): Promise<string> => {
|
||||
const params = new URLSearchParams();
|
||||
params.append('expires_delay', "180");
|
||||
params.append('submit_delay', "180");
|
||||
const asyncData: PostStoreObjectSignature = await makeFetch("GET", `/api/1.0/doc-store/async-upload/temp_url/${storedObject.uuid}/generate/post` + "?" + params.toString());
|
||||
params.append("expires_delay", "180");
|
||||
params.append("submit_delay", "180");
|
||||
const asyncData: PostStoreObjectSignature = await makeFetch(
|
||||
"GET",
|
||||
`/api/1.0/doc-store/async-upload/temp_url/${storedObject.uuid}/generate/post` +
|
||||
"?" +
|
||||
params.toString(),
|
||||
);
|
||||
const suffix = createFilename();
|
||||
const filename = asyncData.prefix + suffix;
|
||||
const formData = new FormData();
|
||||
@ -50,7 +59,7 @@ export const uploadVersion = async (uploadFile: ArrayBuffer, storedObject: Store
|
||||
const response = await window.fetch(asyncData.url, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("Error while sending file to store", response);
|
||||
@ -58,13 +67,22 @@ export const uploadVersion = async (uploadFile: ArrayBuffer, storedObject: Store
|
||||
}
|
||||
|
||||
return Promise.resolve(filename);
|
||||
}
|
||||
};
|
||||
|
||||
export const encryptFile = async (originalFile: ArrayBuffer): Promise<[ArrayBuffer, Uint8Array, JsonWebKey]> => {
|
||||
export const encryptFile = async (
|
||||
originalFile: ArrayBuffer,
|
||||
): Promise<[ArrayBuffer, Uint8Array, JsonWebKey]> => {
|
||||
const iv = crypto.getRandomValues(new Uint8Array(16));
|
||||
const key = await window.crypto.subtle.generateKey(keyDefinition, true, [ "encrypt", "decrypt" ]);
|
||||
const exportedKey = await window.crypto.subtle.exportKey('jwk', key);
|
||||
const encrypted = await window.crypto.subtle.encrypt({ name: algo, iv: iv}, key, originalFile);
|
||||
const key = await window.crypto.subtle.generateKey(keyDefinition, true, [
|
||||
"encrypt",
|
||||
"decrypt",
|
||||
]);
|
||||
const exportedKey = await window.crypto.subtle.exportKey("jwk", key);
|
||||
const encrypted = await window.crypto.subtle.encrypt(
|
||||
{ name: algo, iv: iv },
|
||||
key,
|
||||
originalFile,
|
||||
);
|
||||
|
||||
return Promise.resolve([encrypted, iv, exportedKey]);
|
||||
};
|
||||
|
@ -1,18 +1,22 @@
|
||||
import {CollectionEventPayload} from "../../../../../ChillMainBundle/Resources/public/module/collection";
|
||||
import {createApp} from "vue";
|
||||
import DropFileWidget from "../../vuejs/DropFileWidget/DropFileWidget.vue"
|
||||
import {StoredObject, StoredObjectVersion} from "../../types";
|
||||
import {_createI18n} from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||
import { CollectionEventPayload } from "../../../../../ChillMainBundle/Resources/public/module/collection";
|
||||
import { createApp } from "vue";
|
||||
import DropFileWidget from "../../vuejs/DropFileWidget/DropFileWidget.vue";
|
||||
import { StoredObject, StoredObjectVersion } from "../../types";
|
||||
import { _createI18n } from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||
const i18n = _createI18n({});
|
||||
|
||||
const startApp = (divElement: HTMLDivElement, collectionEntry: null|HTMLLIElement): void => {
|
||||
console.log('app started', divElement);
|
||||
const input_stored_object: HTMLInputElement|null = divElement.querySelector("input[data-stored-object]");
|
||||
const startApp = (
|
||||
divElement: HTMLDivElement,
|
||||
collectionEntry: null | HTMLLIElement,
|
||||
): void => {
|
||||
console.log("app started", divElement);
|
||||
const input_stored_object: HTMLInputElement | null =
|
||||
divElement.querySelector("input[data-stored-object]");
|
||||
if (null === input_stored_object) {
|
||||
throw new Error('input to stored object not found');
|
||||
throw new Error("input to stored object not found");
|
||||
}
|
||||
|
||||
let existingDoc: StoredObject|null = null;
|
||||
let existingDoc: StoredObject | null = null;
|
||||
if (input_stored_object.value !== "") {
|
||||
existingDoc = JSON.parse(input_stored_object.value);
|
||||
}
|
||||
@ -20,69 +24,87 @@ const startApp = (divElement: HTMLDivElement, collectionEntry: null|HTMLLIElemen
|
||||
divElement.appendChild(app_container);
|
||||
|
||||
const app = createApp({
|
||||
template: '<drop-file-widget :existingDoc="this.$data.existingDoc" :allowRemove="true" @addDocument="this.addDocument" @removeDocument="removeDocument"></drop-file-widget>',
|
||||
template:
|
||||
'<drop-file-widget :existingDoc="this.$data.existingDoc" :allowRemove="true" @addDocument="this.addDocument" @removeDocument="removeDocument"></drop-file-widget>',
|
||||
data(vm) {
|
||||
return {
|
||||
existingDoc: existingDoc,
|
||||
}
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DropFileWidget,
|
||||
},
|
||||
methods: {
|
||||
addDocument: function({stored_object, stored_object_version}: {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void {
|
||||
console.log('object added', stored_object);
|
||||
console.log('version added', stored_object_version);
|
||||
addDocument: function ({
|
||||
stored_object,
|
||||
stored_object_version,
|
||||
}: {
|
||||
stored_object: StoredObject;
|
||||
stored_object_version: StoredObjectVersion;
|
||||
}): void {
|
||||
console.log("object added", stored_object);
|
||||
console.log("version added", stored_object_version);
|
||||
this.$data.existingDoc = stored_object;
|
||||
this.$data.existingDoc.currentVersion = stored_object_version;
|
||||
input_stored_object.value = JSON.stringify(this.$data.existingDoc);
|
||||
input_stored_object.value = JSON.stringify(
|
||||
this.$data.existingDoc,
|
||||
);
|
||||
},
|
||||
removeDocument: function(object: StoredObject): void {
|
||||
console.log('catch remove document', object);
|
||||
removeDocument: function (object: StoredObject): void {
|
||||
console.log("catch remove document", object);
|
||||
input_stored_object.value = "";
|
||||
this.$data.existingDoc = undefined;
|
||||
console.log('collectionEntry', collectionEntry);
|
||||
console.log("collectionEntry", collectionEntry);
|
||||
|
||||
if (null !== collectionEntry) {
|
||||
console.log('will remove collection');
|
||||
console.log("will remove collection");
|
||||
collectionEntry.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
app.use(i18n).mount(app_container);
|
||||
}
|
||||
window.addEventListener('collection-add-entry', ((e: CustomEvent<CollectionEventPayload>) => {
|
||||
};
|
||||
window.addEventListener("collection-add-entry", ((
|
||||
e: CustomEvent<CollectionEventPayload>,
|
||||
) => {
|
||||
const detail = e.detail;
|
||||
const divElement: null|HTMLDivElement = detail.entry.querySelector('div[data-stored-object]');
|
||||
const divElement: null | HTMLDivElement = detail.entry.querySelector(
|
||||
"div[data-stored-object]",
|
||||
);
|
||||
|
||||
if (null === divElement) {
|
||||
throw new Error('div[data-stored-object] not found');
|
||||
throw new Error("div[data-stored-object] not found");
|
||||
}
|
||||
|
||||
startApp(divElement, detail.entry);
|
||||
}) as EventListener);
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const upload_inputs: NodeListOf<HTMLDivElement> = document.querySelectorAll('div[data-stored-object]');
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const upload_inputs: NodeListOf<HTMLDivElement> = document.querySelectorAll(
|
||||
"div[data-stored-object]",
|
||||
);
|
||||
|
||||
upload_inputs.forEach((input: HTMLDivElement): void => {
|
||||
// test for a parent to check if this is a collection entry
|
||||
let collectionEntry: null|HTMLLIElement = null;
|
||||
let parent = input.parentElement;
|
||||
console.log('parent', parent);
|
||||
let collectionEntry: null | HTMLLIElement = null;
|
||||
const parent = input.parentElement;
|
||||
console.log("parent", parent);
|
||||
if (null !== parent) {
|
||||
let grandParent = parent.parentElement;
|
||||
console.log('grandParent', grandParent);
|
||||
const grandParent = parent.parentElement;
|
||||
console.log("grandParent", grandParent);
|
||||
if (null !== grandParent) {
|
||||
if (grandParent.tagName.toLowerCase() === 'li' && grandParent.classList.contains('entry')) {
|
||||
if (
|
||||
grandParent.tagName.toLowerCase() === "li" &&
|
||||
grandParent.classList.contains("entry")
|
||||
) {
|
||||
collectionEntry = grandParent as HTMLLIElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
startApp(input, collectionEntry);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
export {}
|
||||
export {};
|
||||
|
@ -1,27 +1,34 @@
|
||||
import {_createI18n} from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||
import {createApp} from "vue";
|
||||
import { _createI18n } from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||
import { createApp } from "vue";
|
||||
import DocumentActionButtonsGroup from "../../vuejs/DocumentActionButtonsGroup.vue";
|
||||
import {StoredObject, StoredObjectStatusChange} from "../../types";
|
||||
import {defineComponent} from "vue";
|
||||
import { StoredObject, StoredObjectStatusChange } from "../../types";
|
||||
import { defineComponent } from "vue";
|
||||
import DownloadButton from "../../vuejs/StoredObjectButton/DownloadButton.vue";
|
||||
import ToastPlugin from "vue-toast-notification";
|
||||
|
||||
|
||||
|
||||
const i18n = _createI18n({});
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function (e) {
|
||||
document.querySelectorAll<HTMLDivElement>('div[data-download-button-single]').forEach((el) => {
|
||||
const storedObject = JSON.parse(el.dataset.storedObject as string) as StoredObject;
|
||||
const title = el.dataset.title as string;
|
||||
const app = createApp({
|
||||
components: {DownloadButton},
|
||||
data() {
|
||||
return {storedObject, title, classes: {btn: true, "btn-outline-primary": true}};
|
||||
},
|
||||
template: '<download-button :stored-object="storedObject" :at-version="storedObject.currentVersion" :classes="classes" :filename="title" :direct-download="true"></download-button>',
|
||||
});
|
||||
window.addEventListener("DOMContentLoaded", function (e) {
|
||||
document
|
||||
.querySelectorAll<HTMLDivElement>("div[data-download-button-single]")
|
||||
.forEach((el) => {
|
||||
const storedObject = JSON.parse(
|
||||
el.dataset.storedObject as string,
|
||||
) as StoredObject;
|
||||
const title = el.dataset.title as string;
|
||||
const app = createApp({
|
||||
components: { DownloadButton },
|
||||
data() {
|
||||
return {
|
||||
storedObject,
|
||||
title,
|
||||
classes: { btn: true, "btn-outline-primary": true },
|
||||
};
|
||||
},
|
||||
template:
|
||||
'<download-button :stored-object="storedObject" :at-version="storedObject.currentVersion" :classes="classes" :filename="title" :direct-download="true"></download-button>',
|
||||
});
|
||||
|
||||
app.use(i18n).use(ToastPlugin).mount(el);
|
||||
});
|
||||
app.use(i18n).use(ToastPlugin).mount(el);
|
||||
});
|
||||
});
|
||||
|
@ -1,54 +1,73 @@
|
||||
import {_createI18n} from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||
import { _createI18n } from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||
import DocumentActionButtonsGroup from "../../vuejs/DocumentActionButtonsGroup.vue";
|
||||
import {createApp} from "vue";
|
||||
import {StoredObject, StoredObjectStatusChange} from "../../types";
|
||||
import {is_object_ready} from "../../vuejs/StoredObjectButton/helpers";
|
||||
import { createApp } from "vue";
|
||||
import { StoredObject, StoredObjectStatusChange } from "../../types";
|
||||
import { is_object_ready } from "../../vuejs/StoredObjectButton/helpers";
|
||||
import ToastPlugin from "vue-toast-notification";
|
||||
|
||||
const i18n = _createI18n({});
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function (e) {
|
||||
document.querySelectorAll<HTMLDivElement>('div[data-download-buttons]').forEach((el) => {
|
||||
const app = createApp({
|
||||
components: {DocumentActionButtonsGroup},
|
||||
data() {
|
||||
window.addEventListener("DOMContentLoaded", function (e) {
|
||||
document
|
||||
.querySelectorAll<HTMLDivElement>("div[data-download-buttons]")
|
||||
.forEach((el) => {
|
||||
const app = createApp({
|
||||
components: { DocumentActionButtonsGroup },
|
||||
data() {
|
||||
const datasets = el.dataset as {
|
||||
filename: string;
|
||||
canEdit: string;
|
||||
storedObject: string;
|
||||
buttonSmall: string;
|
||||
davLink: string;
|
||||
davLinkExpiration: string;
|
||||
};
|
||||
|
||||
const datasets = el.dataset as {
|
||||
filename: string,
|
||||
canEdit: string,
|
||||
storedObject: string,
|
||||
buttonSmall: string,
|
||||
davLink: string,
|
||||
davLinkExpiration: string,
|
||||
};
|
||||
const storedObject = JSON.parse(
|
||||
datasets.storedObject,
|
||||
) as StoredObject,
|
||||
filename = datasets.filename,
|
||||
canEdit = datasets.canEdit === "1",
|
||||
small = datasets.buttonSmall === "1",
|
||||
davLink =
|
||||
"davLink" in datasets && datasets.davLink !== ""
|
||||
? datasets.davLink
|
||||
: null,
|
||||
davLinkExpiration =
|
||||
"davLinkExpiration" in datasets
|
||||
? Number.parseInt(datasets.davLinkExpiration)
|
||||
: null;
|
||||
return {
|
||||
storedObject,
|
||||
filename,
|
||||
canEdit,
|
||||
small,
|
||||
davLink,
|
||||
davLinkExpiration,
|
||||
};
|
||||
},
|
||||
template:
|
||||
'<document-action-buttons-group :can-edit="canEdit" :filename="filename" :stored-object="storedObject" :small="small" :dav-link="davLink" :dav-link-expiration="davLinkExpiration" @on-stored-object-status-change="onStoredObjectStatusChange"></document-action-buttons-group>',
|
||||
methods: {
|
||||
onStoredObjectStatusChange: function (
|
||||
newStatus: StoredObjectStatusChange,
|
||||
): void {
|
||||
this.$data.storedObject.status = newStatus.status;
|
||||
this.$data.storedObject.filename = newStatus.filename;
|
||||
this.$data.storedObject.type = newStatus.type;
|
||||
|
||||
const
|
||||
storedObject = JSON.parse(datasets.storedObject) as StoredObject,
|
||||
filename = datasets.filename,
|
||||
canEdit = datasets.canEdit === '1',
|
||||
small = datasets.buttonSmall === '1',
|
||||
davLink = 'davLink' in datasets && datasets.davLink !== '' ? datasets.davLink : null,
|
||||
davLinkExpiration = 'davLinkExpiration' in datasets ? Number.parseInt(datasets.davLinkExpiration) : null
|
||||
;
|
||||
// remove eventual div which inform pending status
|
||||
document
|
||||
.querySelectorAll(
|
||||
`[data-docgen-is-pending="${this.$data.storedObject.id}"]`,
|
||||
)
|
||||
.forEach(function (el) {
|
||||
el.remove();
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return { storedObject, filename, canEdit, small, davLink, davLinkExpiration };
|
||||
},
|
||||
template: '<document-action-buttons-group :can-edit="canEdit" :filename="filename" :stored-object="storedObject" :small="small" :dav-link="davLink" :dav-link-expiration="davLinkExpiration" @on-stored-object-status-change="onStoredObjectStatusChange"></document-action-buttons-group>',
|
||||
methods: {
|
||||
onStoredObjectStatusChange: function(newStatus: StoredObjectStatusChange): void {
|
||||
this.$data.storedObject.status = newStatus.status;
|
||||
this.$data.storedObject.filename = newStatus.filename;
|
||||
this.$data.storedObject.type = newStatus.type;
|
||||
|
||||
// remove eventual div which inform pending status
|
||||
document.querySelectorAll(`[data-docgen-is-pending="${this.$data.storedObject.id}"]`)
|
||||
.forEach(function(el) {
|
||||
el.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.use(i18n).use(ToastPlugin).mount(el);
|
||||
})
|
||||
app.use(i18n).use(ToastPlugin).mount(el);
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import {
|
||||
DateTime,
|
||||
User,
|
||||
} from "../../../ChillMainBundle/Resources/public/types";
|
||||
import {SignedUrlGet} from "./vuejs/StoredObjectButton/helpers";
|
||||
import { SignedUrlGet } from "./vuejs/StoredObjectButton/helpers";
|
||||
|
||||
export type StoredObjectStatus = "empty" | "ready" | "failure" | "pending";
|
||||
|
||||
@ -64,23 +64,22 @@ export interface StoredObjectStatusChange {
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface StoredObjectVersionWithPointInTime extends StoredObjectVersionPersisted {
|
||||
export interface StoredObjectVersionWithPointInTime
|
||||
extends StoredObjectVersionPersisted {
|
||||
"point-in-times": StoredObjectPointInTime[];
|
||||
"from-restored": StoredObjectVersionPersisted|null;
|
||||
"from-restored": StoredObjectVersionPersisted | null;
|
||||
}
|
||||
|
||||
export interface StoredObjectPointInTime {
|
||||
id: number;
|
||||
byUser: User | null;
|
||||
reason: 'keep-before-conversion'|'keep-by-user';
|
||||
reason: "keep-before-conversion" | "keep-by-user";
|
||||
}
|
||||
|
||||
/**
|
||||
* Function executed by the WopiEditButton component.
|
||||
*/
|
||||
export type WopiEditButtonExecutableBeforeLeaveFunction = {
|
||||
(): Promise<void>;
|
||||
};
|
||||
export type WopiEditButtonExecutableBeforeLeaveFunction = () => Promise<void>;
|
||||
|
||||
/**
|
||||
* Object containing information for performering a POST request to a swift object store
|
||||
@ -135,7 +134,7 @@ export interface ZoomLevel {
|
||||
id: number;
|
||||
zoom: number;
|
||||
label: {
|
||||
fr?: string,
|
||||
nl?: string
|
||||
fr?: string;
|
||||
nl?: string;
|
||||
};
|
||||
}
|
@ -5,29 +5,29 @@ import App from "./App.vue";
|
||||
|
||||
const appMessages = {
|
||||
fr: {
|
||||
yes: 'Oui',
|
||||
are_you_sure: 'Êtes-vous sûr·e?',
|
||||
you_are_going_to_sign: 'Vous allez signer le document',
|
||||
signature_confirmation: 'Confirmation de la signature',
|
||||
sign: 'Signer',
|
||||
choose_another_signature: 'Choisir une autre zone',
|
||||
cancel: 'Annuler',
|
||||
last_sign_zone: 'Zone de signature précédente',
|
||||
next_sign_zone: 'Zone de signature suivante',
|
||||
add_sign_zone: 'Ajouter une zone de signature',
|
||||
click_on_document: 'Cliquer sur le document',
|
||||
last_zone: 'Zone précédente',
|
||||
next_zone: 'Zone suivante',
|
||||
add_zone: 'Ajouter une zone',
|
||||
another_zone: 'Autre zone',
|
||||
electronic_signature_in_progress: 'Signature électronique en cours...',
|
||||
loading: 'Chargement...',
|
||||
remove_sign_zone: 'Enlever la zone',
|
||||
return: 'Retour',
|
||||
see_all_pages: 'Voir toutes les pages',
|
||||
all_pages: 'Toutes les pages',
|
||||
}
|
||||
}
|
||||
yes: "Oui",
|
||||
are_you_sure: "Êtes-vous sûr·e?",
|
||||
you_are_going_to_sign: "Vous allez signer le document",
|
||||
signature_confirmation: "Confirmation de la signature",
|
||||
sign: "Signer",
|
||||
choose_another_signature: "Choisir une autre zone",
|
||||
cancel: "Annuler",
|
||||
last_sign_zone: "Zone de signature précédente",
|
||||
next_sign_zone: "Zone de signature suivante",
|
||||
add_sign_zone: "Ajouter une zone de signature",
|
||||
click_on_document: "Cliquer sur le document",
|
||||
last_zone: "Zone précédente",
|
||||
next_zone: "Zone suivante",
|
||||
add_zone: "Ajouter une zone",
|
||||
another_zone: "Autre zone",
|
||||
electronic_signature_in_progress: "Signature électronique en cours...",
|
||||
loading: "Chargement...",
|
||||
remove_sign_zone: "Enlever la zone",
|
||||
return: "Retour",
|
||||
see_all_pages: "Voir toutes les pages",
|
||||
all_pages: "Toutes les pages",
|
||||
},
|
||||
};
|
||||
|
||||
const i18n = _createI18n(appMessages);
|
||||
|
||||
|
@ -1,12 +1,33 @@
|
||||
import {StoredObject, StoredObjectVersionPersisted, StoredObjectVersionWithPointInTime} from "../../../types";
|
||||
import {fetchResults, makeFetch} from "../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
import {
|
||||
StoredObject,
|
||||
StoredObjectVersionPersisted,
|
||||
StoredObjectVersionWithPointInTime,
|
||||
} from "../../../types";
|
||||
import {
|
||||
fetchResults,
|
||||
makeFetch,
|
||||
} from "../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
|
||||
export const get_versions = async (storedObject: StoredObject): Promise<StoredObjectVersionWithPointInTime[]> => {
|
||||
const versions = await fetchResults<StoredObjectVersionWithPointInTime>(`/api/1.0/doc-store/stored-object/${storedObject.uuid}/versions`);
|
||||
export const get_versions = async (
|
||||
storedObject: StoredObject,
|
||||
): Promise<StoredObjectVersionWithPointInTime[]> => {
|
||||
const versions = await fetchResults<StoredObjectVersionWithPointInTime>(
|
||||
`/api/1.0/doc-store/stored-object/${storedObject.uuid}/versions`,
|
||||
);
|
||||
|
||||
return versions.sort((a: StoredObjectVersionWithPointInTime, b: StoredObjectVersionWithPointInTime) => b.version - a.version);
|
||||
}
|
||||
return versions.sort(
|
||||
(
|
||||
a: StoredObjectVersionWithPointInTime,
|
||||
b: StoredObjectVersionWithPointInTime,
|
||||
) => b.version - a.version,
|
||||
);
|
||||
};
|
||||
|
||||
export const restore_version = async (version: StoredObjectVersionPersisted): Promise<StoredObjectVersionWithPointInTime> => {
|
||||
return await makeFetch<null, StoredObjectVersionWithPointInTime>("POST", `/api/1.0/doc-store/stored-object/restore-from-version/${version.id}`);
|
||||
}
|
||||
export const restore_version = async (
|
||||
version: StoredObjectVersionPersisted,
|
||||
): Promise<StoredObjectVersionWithPointInTime> => {
|
||||
return await makeFetch<null, StoredObjectVersionWithPointInTime>(
|
||||
"POST",
|
||||
`/api/1.0/doc-store/stored-object/restore-from-version/${version.id}`,
|
||||
);
|
||||
};
|
||||
|
@ -1,200 +1,235 @@
|
||||
import {StoredObject, StoredObjectStatus, StoredObjectStatusChange, StoredObjectVersion} from "../../types";
|
||||
import {makeFetch} from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
import {
|
||||
StoredObject,
|
||||
StoredObjectStatus,
|
||||
StoredObjectStatusChange,
|
||||
StoredObjectVersion,
|
||||
} from "../../types";
|
||||
import { makeFetch } from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
|
||||
const MIMES_EDIT = new Set([
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.oasis.opendocument.text',
|
||||
'application/vnd.oasis.opendocument.text-flat-xml',
|
||||
'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'application/vnd.oasis.opendocument.spreadsheet-flat-xml',
|
||||
'application/vnd.oasis.opendocument.presentation',
|
||||
'application/vnd.oasis.opendocument.presentation-flat-xml',
|
||||
'application/vnd.oasis.opendocument.graphics',
|
||||
'application/vnd.oasis.opendocument.graphics-flat-xml',
|
||||
'application/vnd.oasis.opendocument.chart',
|
||||
'application/msword',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.ms-word.document.macroEnabled.12',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
||||
'application/vnd.ms-excel.sheet.macroEnabled.12',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
|
||||
'application/x-dif-document',
|
||||
'text/spreadsheet',
|
||||
'text/csv',
|
||||
'application/x-dbase',
|
||||
'text/rtf',
|
||||
'text/plain',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.oasis.opendocument.text",
|
||||
"application/vnd.oasis.opendocument.text-flat-xml",
|
||||
"application/vnd.oasis.opendocument.spreadsheet",
|
||||
"application/vnd.oasis.opendocument.spreadsheet-flat-xml",
|
||||
"application/vnd.oasis.opendocument.presentation",
|
||||
"application/vnd.oasis.opendocument.presentation-flat-xml",
|
||||
"application/vnd.oasis.opendocument.graphics",
|
||||
"application/vnd.oasis.opendocument.graphics-flat-xml",
|
||||
"application/vnd.oasis.opendocument.chart",
|
||||
"application/msword",
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/vnd.ms-word.document.macroEnabled.12",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/vnd.ms-excel.sheet.binary.macroEnabled.12",
|
||||
"application/vnd.ms-excel.sheet.macroEnabled.12",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/vnd.ms-powerpoint.presentation.macroEnabled.12",
|
||||
"application/x-dif-document",
|
||||
"text/spreadsheet",
|
||||
"text/csv",
|
||||
"application/x-dbase",
|
||||
"text/rtf",
|
||||
"text/plain",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
|
||||
]);
|
||||
|
||||
|
||||
|
||||
const MIMES_VIEW = new Set([
|
||||
...MIMES_EDIT,
|
||||
[
|
||||
'image/svg+xml',
|
||||
'application/vnd.sun.xml.writer',
|
||||
'application/vnd.sun.xml.calc',
|
||||
'application/vnd.sun.xml.impress',
|
||||
'application/vnd.sun.xml.draw',
|
||||
'application/vnd.sun.xml.writer.global',
|
||||
'application/vnd.sun.xml.writer.template',
|
||||
'application/vnd.sun.xml.calc.template',
|
||||
'application/vnd.sun.xml.impress.template',
|
||||
'application/vnd.sun.xml.draw.template',
|
||||
'application/vnd.oasis.opendocument.text-master',
|
||||
'application/vnd.oasis.opendocument.text-template',
|
||||
'application/vnd.oasis.opendocument.text-master-template',
|
||||
'application/vnd.oasis.opendocument.spreadsheet-template',
|
||||
'application/vnd.oasis.opendocument.presentation-template',
|
||||
'application/vnd.oasis.opendocument.graphics-template',
|
||||
'application/vnd.ms-word.template.macroEnabled.12',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'application/vnd.ms-excel.template.macroEnabled.12',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'application/vnd.ms-powerpoint.template.macroEnabled.12',
|
||||
'application/vnd.wordperfect',
|
||||
'application/x-aportisdoc',
|
||||
'application/x-hwp',
|
||||
'application/vnd.ms-works',
|
||||
'application/x-mswrite',
|
||||
'application/vnd.lotus-1-2-3',
|
||||
'image/cgm',
|
||||
'image/vnd.dxf',
|
||||
'image/x-emf',
|
||||
'image/x-wmf',
|
||||
'application/coreldraw',
|
||||
'application/vnd.visio2013',
|
||||
'application/vnd.visio',
|
||||
'application/vnd.ms-visio.drawing',
|
||||
'application/x-mspublisher',
|
||||
'application/x-sony-bbeb',
|
||||
'application/x-gnumeric',
|
||||
'application/macwriteii',
|
||||
'application/x-iwork-numbers-sffnumbers',
|
||||
'application/vnd.oasis.opendocument.text-web',
|
||||
'application/x-pagemaker',
|
||||
'application/x-fictionbook+xml',
|
||||
'application/clarisworks',
|
||||
'image/x-wpg',
|
||||
'application/x-iwork-pages-sffpages',
|
||||
'application/x-iwork-keynote-sffkey',
|
||||
'application/x-abiword',
|
||||
'image/x-freehand',
|
||||
'application/vnd.sun.xml.chart',
|
||||
'application/x-t602',
|
||||
'image/bmp',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/tiff',
|
||||
'image/jpg',
|
||||
'image/jpeg',
|
||||
'application/pdf',
|
||||
]
|
||||
])
|
||||
...MIMES_EDIT,
|
||||
[
|
||||
"image/svg+xml",
|
||||
"application/vnd.sun.xml.writer",
|
||||
"application/vnd.sun.xml.calc",
|
||||
"application/vnd.sun.xml.impress",
|
||||
"application/vnd.sun.xml.draw",
|
||||
"application/vnd.sun.xml.writer.global",
|
||||
"application/vnd.sun.xml.writer.template",
|
||||
"application/vnd.sun.xml.calc.template",
|
||||
"application/vnd.sun.xml.impress.template",
|
||||
"application/vnd.sun.xml.draw.template",
|
||||
"application/vnd.oasis.opendocument.text-master",
|
||||
"application/vnd.oasis.opendocument.text-template",
|
||||
"application/vnd.oasis.opendocument.text-master-template",
|
||||
"application/vnd.oasis.opendocument.spreadsheet-template",
|
||||
"application/vnd.oasis.opendocument.presentation-template",
|
||||
"application/vnd.oasis.opendocument.graphics-template",
|
||||
"application/vnd.ms-word.template.macroEnabled.12",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
|
||||
"application/vnd.ms-excel.template.macroEnabled.12",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.template",
|
||||
"application/vnd.ms-powerpoint.template.macroEnabled.12",
|
||||
"application/vnd.wordperfect",
|
||||
"application/x-aportisdoc",
|
||||
"application/x-hwp",
|
||||
"application/vnd.ms-works",
|
||||
"application/x-mswrite",
|
||||
"application/vnd.lotus-1-2-3",
|
||||
"image/cgm",
|
||||
"image/vnd.dxf",
|
||||
"image/x-emf",
|
||||
"image/x-wmf",
|
||||
"application/coreldraw",
|
||||
"application/vnd.visio2013",
|
||||
"application/vnd.visio",
|
||||
"application/vnd.ms-visio.drawing",
|
||||
"application/x-mspublisher",
|
||||
"application/x-sony-bbeb",
|
||||
"application/x-gnumeric",
|
||||
"application/macwriteii",
|
||||
"application/x-iwork-numbers-sffnumbers",
|
||||
"application/vnd.oasis.opendocument.text-web",
|
||||
"application/x-pagemaker",
|
||||
"application/x-fictionbook+xml",
|
||||
"application/clarisworks",
|
||||
"image/x-wpg",
|
||||
"application/x-iwork-pages-sffpages",
|
||||
"application/x-iwork-keynote-sffkey",
|
||||
"application/x-abiword",
|
||||
"image/x-freehand",
|
||||
"application/vnd.sun.xml.chart",
|
||||
"application/x-t602",
|
||||
"image/bmp",
|
||||
"image/png",
|
||||
"image/gif",
|
||||
"image/tiff",
|
||||
"image/jpg",
|
||||
"image/jpeg",
|
||||
"application/pdf",
|
||||
],
|
||||
]);
|
||||
|
||||
export interface SignedUrlGet {
|
||||
method: 'GET'|'HEAD',
|
||||
url: string,
|
||||
expires: number,
|
||||
object_name: string,
|
||||
method: "GET" | "HEAD";
|
||||
url: string;
|
||||
expires: number;
|
||||
object_name: string;
|
||||
}
|
||||
|
||||
function is_extension_editable(mimeType: string): boolean {
|
||||
return MIMES_EDIT.has(mimeType);
|
||||
return MIMES_EDIT.has(mimeType);
|
||||
}
|
||||
|
||||
function is_extension_viewable(mimeType: string): boolean {
|
||||
return MIMES_VIEW.has(mimeType);
|
||||
return MIMES_VIEW.has(mimeType);
|
||||
}
|
||||
|
||||
function build_convert_link(uuid: string) {
|
||||
return `/chill/wopi/convert/${uuid}`;
|
||||
return `/chill/wopi/convert/${uuid}`;
|
||||
}
|
||||
|
||||
function build_download_info_link(storedObject: StoredObject, atVersion: null|StoredObjectVersion): string {
|
||||
function build_download_info_link(
|
||||
storedObject: StoredObject,
|
||||
atVersion: null | StoredObjectVersion,
|
||||
): string {
|
||||
const url = `/api/1.0/doc-store/async-upload/temp_url/${storedObject.uuid}/generate/get`;
|
||||
|
||||
if (null !== atVersion) {
|
||||
const params = new URLSearchParams({version: atVersion.filename});
|
||||
const params = new URLSearchParams({ version: atVersion.filename });
|
||||
|
||||
return url + '?' + params.toString();
|
||||
return url + "?" + params.toString();
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
async function download_info_link(storedObject: StoredObject, atVersion: null|StoredObjectVersion): Promise<SignedUrlGet> {
|
||||
return makeFetch('GET', build_download_info_link(storedObject, atVersion));
|
||||
async function download_info_link(
|
||||
storedObject: StoredObject,
|
||||
atVersion: null | StoredObjectVersion,
|
||||
): Promise<SignedUrlGet> {
|
||||
return makeFetch("GET", build_download_info_link(storedObject, atVersion));
|
||||
}
|
||||
|
||||
function build_wopi_editor_link(uuid: string, returnPath?: string) {
|
||||
if (returnPath === undefined) {
|
||||
returnPath = window.location.pathname + window.location.search + window.location.hash;
|
||||
}
|
||||
if (returnPath === undefined) {
|
||||
returnPath =
|
||||
window.location.pathname +
|
||||
window.location.search +
|
||||
window.location.hash;
|
||||
}
|
||||
|
||||
return `/chill/wopi/edit/${uuid}?returnPath=` + encodeURIComponent(returnPath);
|
||||
return (
|
||||
`/chill/wopi/edit/${uuid}?returnPath=` + encodeURIComponent(returnPath)
|
||||
);
|
||||
}
|
||||
|
||||
function download_doc(url: string): Promise<Blob> {
|
||||
return window.fetch(url).then(r => {
|
||||
if (r.ok) {
|
||||
return r.blob()
|
||||
}
|
||||
return window.fetch(url).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.blob();
|
||||
}
|
||||
|
||||
throw new Error('Could not download document');
|
||||
});
|
||||
throw new Error("Could not download document");
|
||||
});
|
||||
}
|
||||
|
||||
async function download_and_decrypt_doc(storedObject: StoredObject, atVersion: null|StoredObjectVersion): Promise<Blob>
|
||||
{
|
||||
const algo = 'AES-CBC';
|
||||
async function download_and_decrypt_doc(
|
||||
storedObject: StoredObject,
|
||||
atVersion: null | StoredObjectVersion,
|
||||
): Promise<Blob> {
|
||||
const algo = "AES-CBC";
|
||||
|
||||
const atVersionToDownload = atVersion ?? storedObject.currentVersion;
|
||||
const atVersionToDownload = atVersion ?? storedObject.currentVersion;
|
||||
|
||||
if (null === atVersionToDownload) {
|
||||
throw new Error("no version associated to stored object");
|
||||
}
|
||||
|
||||
// sometimes, the downloadInfo may be embedded into the storedObject
|
||||
console.log('storedObject', storedObject);
|
||||
let downloadInfo;
|
||||
if (typeof storedObject._links !== 'undefined' && typeof storedObject._links.downloadLink !== 'undefined') {
|
||||
downloadInfo = storedObject._links.downloadLink;
|
||||
} else {
|
||||
downloadInfo = await download_info_link(storedObject, atVersionToDownload);
|
||||
if (null === atVersionToDownload) {
|
||||
throw new Error("no version associated to stored object");
|
||||
}
|
||||
|
||||
const rawResponse = await window.fetch(downloadInfo.url);
|
||||
// sometimes, the downloadInfo may be embedded into the storedObject
|
||||
console.log("storedObject", storedObject);
|
||||
let downloadInfo;
|
||||
if (
|
||||
typeof storedObject._links !== "undefined" &&
|
||||
typeof storedObject._links.downloadLink !== "undefined"
|
||||
) {
|
||||
downloadInfo = storedObject._links.downloadLink;
|
||||
} else {
|
||||
downloadInfo = await download_info_link(
|
||||
storedObject,
|
||||
atVersionToDownload,
|
||||
);
|
||||
}
|
||||
|
||||
if (!rawResponse.ok) {
|
||||
throw new Error("error while downloading raw file " + rawResponse.status + " " + rawResponse.statusText);
|
||||
}
|
||||
const rawResponse = await window.fetch(downloadInfo.url);
|
||||
|
||||
if (atVersionToDownload.iv.length === 0) {
|
||||
return rawResponse.blob();
|
||||
}
|
||||
if (!rawResponse.ok) {
|
||||
throw new Error(
|
||||
"error while downloading raw file " +
|
||||
rawResponse.status +
|
||||
" " +
|
||||
rawResponse.statusText,
|
||||
);
|
||||
}
|
||||
|
||||
const rawBuffer = await rawResponse.arrayBuffer();
|
||||
try {
|
||||
const key = await window.crypto.subtle
|
||||
.importKey('jwk', atVersionToDownload.keyInfos, { name: algo }, false, ['decrypt']);
|
||||
const iv = Uint8Array.from(atVersionToDownload.iv);
|
||||
const decrypted = await window.crypto.subtle
|
||||
.decrypt({ name: algo, iv: iv }, key, rawBuffer);
|
||||
if (atVersionToDownload.iv.length === 0) {
|
||||
return rawResponse.blob();
|
||||
}
|
||||
|
||||
return Promise.resolve(new Blob([decrypted]));
|
||||
} catch (e) {
|
||||
console.error('encounter error while keys and decrypt operations');
|
||||
console.error(e);
|
||||
const rawBuffer = await rawResponse.arrayBuffer();
|
||||
try {
|
||||
const key = await window.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
atVersionToDownload.keyInfos,
|
||||
{ name: algo },
|
||||
false,
|
||||
["decrypt"],
|
||||
);
|
||||
const iv = Uint8Array.from(atVersionToDownload.iv);
|
||||
const decrypted = await window.crypto.subtle.decrypt(
|
||||
{ name: algo, iv: iv },
|
||||
key,
|
||||
rawBuffer,
|
||||
);
|
||||
|
||||
throw e;
|
||||
}
|
||||
return Promise.resolve(new Blob([decrypted]));
|
||||
} catch (e) {
|
||||
console.error("encounter error while keys and decrypt operations");
|
||||
console.error(e);
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,14 +238,16 @@ async function download_and_decrypt_doc(storedObject: StoredObject, atVersion: n
|
||||
* If the document is already in a pdf on the server side, the document is retrieved "as is" from the usual
|
||||
* storage.
|
||||
*/
|
||||
async function download_doc_as_pdf(storedObject: StoredObject): Promise<Blob>
|
||||
{
|
||||
async function download_doc_as_pdf(storedObject: StoredObject): Promise<Blob> {
|
||||
if (null === storedObject.currentVersion) {
|
||||
throw new Error("the stored object does not count any version");
|
||||
}
|
||||
|
||||
if (storedObject.currentVersion?.type === 'application/pdf') {
|
||||
return download_and_decrypt_doc(storedObject, storedObject.currentVersion);
|
||||
if (storedObject.currentVersion?.type === "application/pdf") {
|
||||
return download_and_decrypt_doc(
|
||||
storedObject,
|
||||
storedObject.currentVersion,
|
||||
);
|
||||
}
|
||||
|
||||
const convertLink = build_convert_link(storedObject.uuid);
|
||||
@ -223,25 +260,27 @@ async function download_doc_as_pdf(storedObject: StoredObject): Promise<Blob>
|
||||
return response.blob();
|
||||
}
|
||||
|
||||
async function is_object_ready(storedObject: StoredObject): Promise<StoredObjectStatusChange>
|
||||
{
|
||||
const new_status_response = await window
|
||||
.fetch( `/api/1.0/doc-store/stored-object/${storedObject.uuid}/is-ready`);
|
||||
async function is_object_ready(
|
||||
storedObject: StoredObject,
|
||||
): Promise<StoredObjectStatusChange> {
|
||||
const new_status_response = await window.fetch(
|
||||
`/api/1.0/doc-store/stored-object/${storedObject.uuid}/is-ready`,
|
||||
);
|
||||
|
||||
if (!new_status_response.ok) {
|
||||
throw new Error("could not fetch the new status");
|
||||
throw new Error("could not fetch the new status");
|
||||
}
|
||||
|
||||
return await new_status_response.json();
|
||||
}
|
||||
|
||||
export {
|
||||
build_convert_link,
|
||||
build_wopi_editor_link,
|
||||
download_and_decrypt_doc,
|
||||
download_doc,
|
||||
download_doc_as_pdf,
|
||||
is_extension_editable,
|
||||
is_extension_viewable,
|
||||
is_object_ready,
|
||||
build_convert_link,
|
||||
build_wopi_editor_link,
|
||||
download_and_decrypt_doc,
|
||||
download_doc,
|
||||
download_doc_as_pdf,
|
||||
is_extension_editable,
|
||||
is_extension_viewable,
|
||||
is_object_ready,
|
||||
};
|
||||
|
@ -9,14 +9,18 @@
|
||||
*
|
||||
* @throws {Error} If the related entity ID is undefined.
|
||||
*/
|
||||
export const buildLinkCreate = (workflowName: string, relatedEntityClass: string, relatedEntityId: number|undefined): string => {
|
||||
if (typeof (relatedEntityId) === 'undefined') {
|
||||
export const buildLinkCreate = (
|
||||
workflowName: string,
|
||||
relatedEntityClass: string,
|
||||
relatedEntityId: number | undefined,
|
||||
): string => {
|
||||
if (typeof relatedEntityId === "undefined") {
|
||||
throw new Error("the related entity id is not set");
|
||||
}
|
||||
let params = new URLSearchParams();
|
||||
params.set('entityClass', relatedEntityClass);
|
||||
params.set('entityId', relatedEntityId.toString(10));
|
||||
params.set('workflow', workflowName);
|
||||
const params = new URLSearchParams();
|
||||
params.set("entityClass", relatedEntityClass);
|
||||
params.set("entityId", relatedEntityId.toString(10));
|
||||
params.set("workflow", workflowName);
|
||||
|
||||
return `/fr/main/workflow/create?`+params.toString();
|
||||
return `/fr/main/workflow/create?` + params.toString();
|
||||
};
|
||||
|
@ -28,11 +28,15 @@
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
import './collection.scss';
|
||||
import "./collection.scss";
|
||||
|
||||
declare global {
|
||||
interface GlobalEventHandlersEventMap {
|
||||
'show-hide-show': CustomEvent<{id: number, froms: HTMLElement[], container: HTMLElement}>,
|
||||
"show-hide-show": CustomEvent<{
|
||||
id: number;
|
||||
froms: HTMLElement[];
|
||||
container: HTMLElement;
|
||||
}>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,27 +51,31 @@ export class CollectionEventPayload {
|
||||
}
|
||||
|
||||
export const handleAdd = (button: any): void => {
|
||||
let
|
||||
form_name = button.dataset.collectionAddTarget,
|
||||
const form_name = button.dataset.collectionAddTarget,
|
||||
prototype = button.dataset.formPrototype,
|
||||
collection: HTMLUListElement | null = document.querySelector('ul[data-collection-name="' + form_name + '"]');
|
||||
collection: HTMLUListElement | null = document.querySelector(
|
||||
'ul[data-collection-name="' + form_name + '"]',
|
||||
);
|
||||
|
||||
if (collection === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let
|
||||
empty_explain: HTMLLIElement | null = collection.querySelector('li[data-collection-empty-explain]'),
|
||||
entry = document.createElement('li'),
|
||||
counter = collection.querySelectorAll('li.entry').length, // Updated counter logic
|
||||
const empty_explain: HTMLLIElement | null = collection.querySelector(
|
||||
"li[data-collection-empty-explain]",
|
||||
),
|
||||
entry = document.createElement("li"),
|
||||
counter = collection.querySelectorAll("li.entry").length, // Updated counter logic
|
||||
content = prototype.replace(/__name__/g, counter.toString()),
|
||||
event = new CustomEvent('collection-add-entry', {detail: new CollectionEventPayload(collection, entry)});
|
||||
event = new CustomEvent("collection-add-entry", {
|
||||
detail: new CollectionEventPayload(collection, entry),
|
||||
});
|
||||
|
||||
console.log(counter)
|
||||
console.log(content)
|
||||
console.log(counter);
|
||||
console.log(content);
|
||||
|
||||
entry.innerHTML = content;
|
||||
entry.classList.add('entry');
|
||||
entry.classList.add("entry");
|
||||
|
||||
if ("collectionRegular" in collection.dataset) {
|
||||
initializeRemove(collection, entry);
|
||||
@ -81,7 +89,10 @@ export const handleAdd = (button: any): void => {
|
||||
window.dispatchEvent(event);
|
||||
};
|
||||
|
||||
const initializeRemove = (collection: HTMLUListElement, entry: HTMLLIElement): void => {
|
||||
const initializeRemove = (
|
||||
collection: HTMLUListElement,
|
||||
entry: HTMLLIElement,
|
||||
): void => {
|
||||
const button = buildRemoveButton(collection, entry);
|
||||
if (null === button) {
|
||||
return;
|
||||
@ -89,21 +100,24 @@ const initializeRemove = (collection: HTMLUListElement, entry: HTMLLIElement): v
|
||||
entry.appendChild(button);
|
||||
};
|
||||
|
||||
export const buildRemoveButton = (collection: HTMLUListElement, entry: HTMLLIElement): HTMLButtonElement|null => {
|
||||
export const buildRemoveButton = (
|
||||
collection: HTMLUListElement,
|
||||
entry: HTMLLIElement,
|
||||
): HTMLButtonElement | null => {
|
||||
const button = document.createElement("button"),
|
||||
isPersisted = entry.dataset.collectionIsPersisted || "",
|
||||
content = collection.dataset.collectionButtonRemoveLabel || "",
|
||||
allowDelete = collection.dataset.collectionAllowDelete || "",
|
||||
event = new CustomEvent("collection-remove-entry", {
|
||||
detail: new CollectionEventPayload(collection, entry),
|
||||
});
|
||||
|
||||
let
|
||||
button = document.createElement('button'),
|
||||
isPersisted = entry.dataset.collectionIsPersisted || '',
|
||||
content = collection.dataset.collectionButtonRemoveLabel || '',
|
||||
allowDelete = collection.dataset.collectionAllowDelete || '',
|
||||
event = new CustomEvent('collection-remove-entry', {detail: new CollectionEventPayload(collection, entry)});
|
||||
|
||||
if (allowDelete === '0' && isPersisted === '1') {
|
||||
if (allowDelete === "0" && isPersisted === "1") {
|
||||
return null;
|
||||
}
|
||||
button.classList.add('btn', 'btn-delete', 'remove-entry');
|
||||
button.classList.add("btn", "btn-delete", "remove-entry");
|
||||
button.textContent = content;
|
||||
button.addEventListener('click', (e: Event) => {
|
||||
button.addEventListener("click", (e: Event) => {
|
||||
e.preventDefault();
|
||||
entry.remove();
|
||||
collection.dispatchEvent(event);
|
||||
@ -111,15 +125,18 @@ export const buildRemoveButton = (collection: HTMLUListElement, entry: HTMLLIEle
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
};
|
||||
|
||||
const collectionsInit = new Set<string>;
|
||||
const collectionsInit = new Set<string>();
|
||||
const buttonsInit = new Set<string>();
|
||||
|
||||
const initialize = function (target: Document|Element): void {
|
||||
let
|
||||
addButtons: NodeListOf<HTMLButtonElement> = document.querySelectorAll("button[data-collection-add-target]"),
|
||||
collections: NodeListOf<HTMLUListElement> = document.querySelectorAll("ul[data-collection-regular]");
|
||||
const initialize = function (target: Document | Element): void {
|
||||
const addButtons: NodeListOf<HTMLButtonElement> = document.querySelectorAll(
|
||||
"button[data-collection-add-target]",
|
||||
),
|
||||
collections: NodeListOf<HTMLUListElement> = document.querySelectorAll(
|
||||
"ul[data-collection-regular]",
|
||||
);
|
||||
|
||||
for (let i = 0; i < addButtons.length; i++) {
|
||||
const addButton = addButtons[i];
|
||||
@ -128,7 +145,7 @@ const initialize = function (target: Document|Element): void {
|
||||
continue;
|
||||
}
|
||||
buttonsInit.add(uniqid);
|
||||
addButton.addEventListener('click', (e: Event) => {
|
||||
addButton.addEventListener("click", (e: Event) => {
|
||||
e.preventDefault();
|
||||
handleAdd(e.target);
|
||||
});
|
||||
@ -140,7 +157,8 @@ const initialize = function (target: Document|Element): void {
|
||||
continue;
|
||||
}
|
||||
collectionsInit.add(uniqid);
|
||||
let entries: NodeListOf<HTMLLIElement> = collection.querySelectorAll(':scope > li');
|
||||
const entries: NodeListOf<HTMLLIElement> =
|
||||
collection.querySelectorAll(":scope > li");
|
||||
for (let j = 0; j < entries.length; j++) {
|
||||
if (entries[j].dataset.collectionEmptyExplain === "1") {
|
||||
continue;
|
||||
@ -150,11 +168,20 @@ const initialize = function (target: Document|Element): void {
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
initialize(document);
|
||||
});
|
||||
|
||||
window.addEventListener('show-hide-show', (event: CustomEvent<{id: number; container: HTMLElement; froms: HTMLElement[]}>) => {
|
||||
const container = event.detail.container as HTMLElement;
|
||||
initialize(container);
|
||||
})
|
||||
window.addEventListener(
|
||||
"show-hide-show",
|
||||
(
|
||||
event: CustomEvent<{
|
||||
id: number;
|
||||
container: HTMLElement;
|
||||
froms: HTMLElement[];
|
||||
}>,
|
||||
) => {
|
||||
const container = event.detail.container as HTMLElement;
|
||||
initialize(container);
|
||||
},
|
||||
);
|
||||
|
@ -64,10 +64,10 @@ export interface UserAssociatedInterface {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export type TranslatableString = {
|
||||
export interface TranslatableString {
|
||||
fr?: string;
|
||||
nl?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Postcode {
|
||||
id: number;
|
||||
@ -76,10 +76,10 @@ export interface Postcode {
|
||||
center: Point;
|
||||
}
|
||||
|
||||
export type Point = {
|
||||
export interface Point {
|
||||
type: "Point";
|
||||
coordinates: [lat: number, lon: number];
|
||||
};
|
||||
}
|
||||
|
||||
export interface Country {
|
||||
id: number;
|
||||
|
@ -1,43 +1,43 @@
|
||||
import {
|
||||
Address,
|
||||
Center,
|
||||
Civility,
|
||||
DateTime,
|
||||
User,
|
||||
WorkflowAvailable
|
||||
Address,
|
||||
Center,
|
||||
Civility,
|
||||
DateTime,
|
||||
User,
|
||||
WorkflowAvailable,
|
||||
} from "../../../ChillMainBundle/Resources/public/types";
|
||||
import {StoredObject} from "../../../ChillDocStoreBundle/Resources/public/types";
|
||||
import { StoredObject } from "../../../ChillDocStoreBundle/Resources/public/types";
|
||||
|
||||
export interface Person {
|
||||
id: number;
|
||||
type: "person";
|
||||
text: string;
|
||||
textAge: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
current_household_address: Address | null;
|
||||
birthdate: DateTime | null;
|
||||
deathdate: DateTime | null;
|
||||
age: number;
|
||||
phonenumber: string;
|
||||
mobilenumber: string;
|
||||
email: string;
|
||||
gender: "woman" | "man" | "other";
|
||||
centers: Center[];
|
||||
civility: Civility | null;
|
||||
current_household_id: number;
|
||||
current_residential_addresses: Address[];
|
||||
id: number;
|
||||
type: "person";
|
||||
text: string;
|
||||
textAge: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
current_household_address: Address | null;
|
||||
birthdate: DateTime | null;
|
||||
deathdate: DateTime | null;
|
||||
age: number;
|
||||
phonenumber: string;
|
||||
mobilenumber: string;
|
||||
email: string;
|
||||
gender: "woman" | "man" | "other";
|
||||
centers: Center[];
|
||||
civility: Civility | null;
|
||||
current_household_id: number;
|
||||
current_residential_addresses: Address[];
|
||||
}
|
||||
|
||||
export interface AccompanyingPeriodWorkEvaluationDocument {
|
||||
id: number;
|
||||
type: "accompanying_period_work_evaluation_document"
|
||||
storedObject: StoredObject;
|
||||
title: string;
|
||||
createdAt: DateTime | null;
|
||||
createdBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
workflows_availables: WorkflowAvailable[];
|
||||
workflows: object[];
|
||||
id: number;
|
||||
type: "accompanying_period_work_evaluation_document";
|
||||
storedObject: StoredObject;
|
||||
title: string;
|
||||
createdAt: DateTime | null;
|
||||
createdBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
workflows_availables: WorkflowAvailable[];
|
||||
workflows: object[];
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
import {AccompanyingPeriodWorkEvaluationDocument} from "../../types";
|
||||
import {makeFetch} from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
import { AccompanyingPeriodWorkEvaluationDocument } from "../../types";
|
||||
import { makeFetch } from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||
|
||||
export const duplicate = async (id: number): Promise<AccompanyingPeriodWorkEvaluationDocument> => {
|
||||
return makeFetch<null, AccompanyingPeriodWorkEvaluationDocument>("POST", `/api/1.0/person/accompanying-course-work-evaluation-document/${id}/duplicate`);
|
||||
}
|
||||
export const duplicate = async (
|
||||
id: number,
|
||||
): Promise<AccompanyingPeriodWorkEvaluationDocument> => {
|
||||
return makeFetch<null, AccompanyingPeriodWorkEvaluationDocument>(
|
||||
"POST",
|
||||
`/api/1.0/person/accompanying-course-work-evaluation-document/${id}/duplicate`,
|
||||
);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user