EN · DE · RU · FR · ES

#2751: global.js

projectforge-webapp/src/utilities/global.js Модуль JavaScript, projectforge-webapp/src/utilities/global.js 76 строк · 58 кода · 7 комментариев · 11 пустых
Назначение: React webapp: global.js. global.js является частью приложения управления проектами с открытым исходным кодом ProjectForge.

Исходный код (первые 100 строк)

import { forIn, get, set } from 'lodash/object';

// https://stackoverflow.com/a/6491621
Object.getByString = (object, multiKey) => {
    if (!multiKey) {
        return undefined;
    }
    if (!(typeof multiKey === 'string' || multiKey instanceof String)) {
        /* eslint-disable-next-line no-console */
        console.log("Предупреждение: multiKey не является строкой.", multiKey, typeof multiKey);
        return undefined;
    }
    return get(object, multiKey);
};

Object.isEmpty = (object) => Object.keys(object).length === 0;

// Не удалять отсутствующие свойства данных при слиянии:
const mergeDataProps = (src, combined) => {
    const srcData = src.data;
    const combinedData = combined.data;
    if (!combinedData) {
        return srcData;
    }
    forIn(srcData, (value, key) => {
        if (Object.prototype.hasOwnProperty.call(srcData, key)) {
            // Если свойство существует, используем его: значение может быть undefined.
            set(combinedData, key, value);
        }
    });
    return combinedData;
};

// Объединяет два объекта. Пути вида user.rights[2].value также поддерживаются в полях o2.
Object.combine = (src, obj) => {
    const combined = { ...src };
    forIn(obj, (value, key) => {
        if (key === 'data') {
            set(combined, key, mergeDataProps(obj, combined));
        } else {
            set(combined, key, value);
        }
    });
    return combined;
};

Array.findByField = (array, field, value) => array.reduce((accumulator, currentValue) => {
    if (currentValue[field] === value) {
        return currentValue;
    }

    return accumulator;
}, undefined);

// Заменяет все символы селекторов, чтобы они не появлялись в идентификаторе.
String.idify = (string) => string.replace(/[.#*, >+~/[\]=|^$:()]/g, '-');

String.truncate = (str, length) => (str?.length > length ? str.substring(0, length) : str);

Number.as2Digits = (number) => {
    if (number < 10) {
        return `0${number.toString()}`;
    }
    return number.toString();
};

Object.getResponseHeaderFilename = (contentDisposition) => {
    // attachment; filename*=UTF-8''document.pdf; filename=document.pdf
    const matches = /filename[^;=\n]*=(UTF-8(['"]*))?([^;=\n]*)*/.exec(contentDisposition);
    return matches && matches.length >= 3 && matches[3] ? decodeURI(matches[3].replace(/['"]/g, '')) : 'download';
};

Date.toIsoDateString = (date) => {
    const offset = date.getTimezoneOffset();
    return new Date(date.getTime() - (offset * 60 * 1000)).toISOString().split('T')[0];
};

История Git

407b4c9c9 Новый календарь: первый час дня теперь настраивается. Подсказки.
41907bf51 WIP: BigCalendar -> Fullcalendar
5fff1f800 global.js: удалены неиспользуемые импорты.
4a4e2086a global.js: merge/combine работали некорректно в некоторых случаях (например, плагин Merlin). AttachmentsService теперь возвращает пустой массив вместо null, если вложения не предоставлены (клиент теперь может очистить список вложений после удаления последнего вложения).
6bf735d24 global.js: объединение стало намного короче.

407b4c9c9

Новый календарь: первый час дня теперь настраивается. Подсказки.
407b4c9c917150e84635867ae2e8918629ae9636
diff --git a/projectforge-webapp/src/utilities/global.js b/projectforge-webapp/src/utilities/global.js
index aad75bcfa..bfe602d12 100644
--- a/projectforge-webapp/src/utilities/global.js
+++ b/projectforge-webapp/src/utilities/global.js
@@ -57,6 +57,13 @@ String.idify = (string) => string.replace(/[.#*, >+~/[\]=|^$:()]/g, '-');
 
 String.truncate = (str, length) => (str?.length > length ? str.substring(0, length) : str);
 
+Number.as2Digits = (number) => {
+    if (number < 10) {
+        return `0${number.toString()}`;
+    }
+    return number.toString();
+};
+
 Object.getResponseHeaderFilename = (contentDisposition) => {
     // attachment; filename*=UTF-8''document.pdf; filename=document.pdf
     const matches = /filename[^;=\n]*=(UTF-8(['"]*))?([^;=\n]*)*/.exec(contentDisposition);

41907bf51

WIP: BigCalendar -> Fullcalendar
41907bf51150c1ad7299e66b8bb3ed1bb8534c0e
diff --git a/projectforge-webapp/src/utilities/global.js b/projectforge-webapp/src/utilities/global.js
index ab0ed3509..aad75bcfa 100644
--- a/projectforge-webapp/src/utilities/global.js
+++ b/projectforge-webapp/src/utilities/global.js
@@ -62,3 +62,8 @@ Object.getResponseHeaderFilename = (contentDisposition) => {
     const matches = /filename[^;=\n]*=(UTF-8(['"]*))?([^;=\n]*)*/.exec(contentDisposition);
     return matches && matches.length >= 3 && matches[3] ? decodeURI(matches[3].replace(/['"]/g, '')) : 'download';
 };
+
+Date.toIsoDateString = (date) => {
+    const offset = date.getTimezoneOffset();
+    return new Date(date.getTime() - (offset * 60 * 1000)).toISOString().split('T')[0];
+};

5fff1f800

global.js: удалены неиспользуемые импорты.
5fff1f8001d869654577e33ec32513b63e70bca1
diff --git a/projectforge-webapp/src/utilities/global.js b/projectforge-webapp/src/utilities/global.js
index 7cbe32c7b..ab0ed3509 100644
--- a/projectforge-webapp/src/utilities/global.js
+++ b/projectforge-webapp/src/utilities/global.js
@@ -1,6 +1,4 @@
-import { forIn, get, merge, set } from 'lodash/object';
-import { mergeWith } from 'lodash';
-import { cloneDeep, isArray } from 'lodash/lang';
+import { forIn, get, set } from 'lodash/object';
 
 // https://stackoverflow.com/a/6491621
 Object.getByString = (object, multiKey) => {

4a4e2086a

global.js: merge/combine работали некорректно в некоторых случаях (например, плагин Merlin). AttachmentsService теперь возвращает пустой массив вместо null, если вложения не предоставлены (клиент теперь может очистить список вложений после удаления последнего вложения).
4a4e2086aced8e2fa6608da4b65e087028b6138a
diff --git a/projectforge-webapp/src/utilities/global.js b/projectforge-webapp/src/utilities/global.js
index 6ddc999f8..7cbe32c7b 100644
--- a/projectforge-webapp/src/utilities/global.js
+++ b/projectforge-webapp/src/utilities/global.js
@@ -1,4 +1,6 @@
-import { forIn, get, set } from 'lodash/object';
+import { forIn, get, merge, set } from 'lodash/object';
+import { mergeWith } from 'lodash';
+import { cloneDeep, isArray } from 'lodash/lang';
 
 // https://stackoverflow.com/a/6491621
 Object.getByString = (object, multiKey) => {
@@ -15,11 +17,31 @@ Object.getByString = (object, multiKey) => {
 
 Object.isEmpty = (object) => Object.keys(object).length === 0;
 
+// Не удалять отсутствующие свойства данных при слиянии:
+const mergeDataProps = (src, combined) => {
+    const srcData = src.data;
+    const combinedData = combined.data;
+    if (!combinedData) {
+        return srcData;
+    }
+    forIn(srcData, (value, key) => {
+        if (Object.prototype.hasOwnProperty.call(srcData, key)) {
+            // Если свойство существует, используем его: значение может быть undefined.
+            set(combinedData, key, value);
+        }
+    });
+    return combinedData;
+};
+
 // Объединяет два объекта. Пути вида user.rights[2].value также поддерживаются в полях o2.
-Object.combine = (o1, o2) => {
-    const combined = { ...o1 };
-    forIn(o2, (value, key) => {
-        set(combined, key, value);
+Object.combine = (src, obj) => {
+    const combined = { ...src };
+    forIn(obj, (value, key) => {
+        if (key === 'data') {
+            set(combined, key, mergeDataProps(obj, combined));
+        } else {
+            set(combined, key, value);
+        }
     });
     return combined;
 };

6bf735d24

global.js: объединение стало намного короче.
6bf735d24dd5a4f5ff8d89c7dfe714aa8753cdaa
diff --git a/projectforge-webapp/src/utilities/global.js b/projectforge-webapp/src/utilities/global.js
index d1608283f..6ddc999f8 100644
--- a/projectforge-webapp/src/utilities/global.js
+++ b/projectforge-webapp/src/utilities/global.js
@@ -1,5 +1,4 @@
-import { forIn, get, mergeWith, set } from 'lodash/object';
-import { isArray } from 'lodash/lang';
+import { forIn, get, set } from 'lodash/object';
 
 // https://stackoverflow.com/a/6491621
 Object.getByString = (object, multiKey) => {
@@ -16,34 +15,13 @@ Object.getByString = (object, multiKey) => {
 
 Object.isEmpty = (object) => Object.keys(object).length === 0;
 
-const customizer = (objValue, srcValue) => {
-    if (isArray(objValue)) {
-        // Не объединять массивы: заменять существующий массив исходным массивом.
-        return srcValue;
-    }
-    return undefined;
-};
-
 // Объединяет два объекта. Пути вида user.rights[2].value также поддерживаются в полях o2.
 Object.combine = (o1, o2) => {
-    const newValues = {};
-    const specialProperties = {};
+    const combined = { ...o1 };
     forIn(o2, (value, key) => {
-        if (key.includes('.') || key.match(/\[(\d)\]/) || value === undefined) {
-            // ключи вида user.name или user.rights[2].value или undefined значения
-            // требуют специальной обработки после слияния.
-            specialProperties[key] = value;
-        } else {
-            newValues[key] = value;
-        }
-    });
-    const newState = mergeWith(o1, newValues, customizer);
-    forIn(specialProperties, (value, key) => {
-        // Устанавливает значение нового состояния по глубокому пути свойства (например, user.name или user.rights[2].value)
-        // undefined значения также будут установлены.
-        set(newState, key, value);
+        set(combined, key, value);
     });
-    return newState;
+    return combined;
 };
 
 Array.findByField = (array, field, value) => array.reduce((accumulator, currentValue) => {