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