diff --git a/package.json b/package.json index 75d6eb8..e7071a4 100644 --- a/package.json +++ b/package.json @@ -4,52 +4,52 @@ "private": true, "dependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "@ckeditor/ckeditor5-react": "^6.1.0", - "@fortawesome/fontawesome-pro": "^6.5.0", - "@fortawesome/fontawesome-svg-core": "^6.2.1", - "@fortawesome/free-solid-svg-icons": "^6.2.1", - "@fortawesome/pro-duotone-svg-icons": "^6.5.0", - "@fortawesome/pro-light-svg-icons": "^6.5.0", - "@fortawesome/pro-regular-svg-icons": "^6.5.0", - "@fortawesome/pro-solid-svg-icons": "^6.5.0", - "@fortawesome/pro-thin-svg-icons": "^6.5.1", - "@fortawesome/react-fontawesome": "^0.2.0", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^14.0.0", - "@testing-library/user-event": "^14.4.3", - "@types/jest": "^29.5.1", + "@ckeditor/ckeditor5-react": "^10.0.0", + "@fortawesome/fontawesome-pro": "^6.7.2", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/pro-duotone-svg-icons": "^6.7.2", + "@fortawesome/pro-light-svg-icons": "^6.7.2", + "@fortawesome/pro-regular-svg-icons": "^6.7.2", + "@fortawesome/pro-solid-svg-icons": "^6.7.2", + "@fortawesome/pro-thin-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.14", "@types/js-cookie": "^3.0.6", - "@types/lodash.debounce": "^4.0.7", - "@types/react": "^18.0.17", - "@types/react-dom": "^18.0.6", - "axios": "^1.4.0", - "bootstrap": "^5.3.0-alpha3", + "@types/lodash.debounce": "^4.0.9", + "@types/react": "^18.3.27", + "@types/react-dom": "^18.3.7", + "axios": "^1.7.9", + "bootstrap": "^5.3.8", "buffer": "^6.0.3", - "ckeditor5": "^43.1.0", - "ckeditor5-premium-features": "^43.1.0", - "concurrently": "^8.2.2", + "ckeditor5": "^47.4.0", + "ckeditor5-premium-features": "^47.4.0", + "concurrently": "^9.2.1", "cross-env": "^7.0.3", - "date-fns": "^2.30.0", - "html-react-parser": "^3.0.16", - "i18next": "^22.5.1", + "date-fns": "^4.1.0", + "html-react-parser": "^5.2.15", + "i18next": "^25.8.0", "i18next-http-backend": "^3.0.2", - "joi": "^17.9.1", + "joi": "^17.13.3", "js-cookie": "^3.0.5", - "jwt-decode": "^3.1.2", + "jwt-decode": "^4.0.0", "lodash.debounce": "^4.0.8", - "nodemon": "^3.1.4", - "react": "^18.2.0", - "react-bootstrap": "^2.7.4", - "react-dom": "^18.2.0", - "react-helmet-async": "^1.3.0", - "react-i18next": "^12.3.1", - "react-router-dom": "^6.10.0", + "nodemon": "^3.1.11", + "react": "^18.3.1", + "react-bootstrap": "^2.10.8", + "react-dom": "^18.3.1", + "react-helmet-async": "^2.0.5", + "react-i18next": "^16.5.4", + "react-router-dom": "^7.13.0", "react-scripts": "^5.0.1", - "react-toastify": "^9.1.2", + "react-toastify": "^11.0.5", "react-toggle": "^4.1.3", "runtime-env-cra": "^0.2.4", - "sass": "^1.62.0", - "web-vitals": "^3.3.1" + "sass": "^1.97.3", + "web-vitals": "^5.1.0" }, "scripts": { "build-css": "sass src/Sass/global.scss public/styles.css", @@ -85,8 +85,8 @@ ] }, "devDependencies": { - "@types/node": "^20.2.3", - "@types/react-toggle": "^4.0.3", + "@types/node": "^22.13.5", + "@types/react-toggle": "^4.0.5", "i18n-unused": "^0.19.0", "i18next-parser": "^9.3.0", "react-app-rewired": "^2.2.1", diff --git a/src/components/common/CustomFieldsEditor.tsx b/src/components/common/CustomFieldsEditor.tsx index 5bfd48c..70cb26f 100644 --- a/src/components/common/CustomFieldsEditor.tsx +++ b/src/components/common/CustomFieldsEditor.tsx @@ -37,7 +37,7 @@ const CustomFieldsEditor: React.FC = ({ const columns: Column[] = useMemo( () => [{ key: "name", label: t("Name"), order: "asc" }], - [], + [t], ); const paginated: Paginated = useMemo( diff --git a/src/components/common/ckeditor/plugins/field/fieldediting.js b/src/components/common/ckeditor/plugins/field/fieldediting.js index 218f4e5..f06ffd2 100644 --- a/src/components/common/ckeditor/plugins/field/fieldediting.js +++ b/src/components/common/ckeditor/plugins/field/fieldediting.js @@ -1,119 +1,127 @@ -import { Plugin, Widget, toWidget, viewToModelPositionOutsideModelElement } from 'ckeditor5'; -import FieldCommand from './fieldcommand'; +import { + Plugin, + Widget, + toWidget, + viewToModelPositionOutsideModelElement, +} from "ckeditor5"; +import FieldCommand from "./fieldcommand"; -String.prototype.rtrim = function (s) { - if (s === undefined) - s = '\\s'; - return this.replace(new RegExp("[" + s + "]*$"), ''); +// Helper functions to avoid extending String prototype +const rtrim = (str, s) => { + if (s === undefined) s = "\\s"; + return str.replace(new RegExp("[" + s + "]*$"), ""); }; -String.prototype.ltrim = function (s) { - if (s === undefined) - s = '\\s'; - return this.replace(new RegExp("^[" + s + "]*"), ''); +const ltrim = (str, s) => { + if (s === undefined) s = "\\s"; + return str.replace(new RegExp("^[" + s + "]*"), ""); }; -export class FieldConfig{ - fields = [ ] +export class FieldConfig { + fields = []; } export default class FieldEditing extends Plugin { - static get requires() { - return [ Widget ]; - } + static get requires() { + return [Widget]; + } - init() { - this._defineSchema(); - this._defineConverters(); + init() { + this._defineSchema(); + this._defineConverters(); - this.editor.commands.add( 'field', new FieldCommand( this.editor ) ); + this.editor.commands.add("field", new FieldCommand(this.editor)); - this.editor.editing.mapper.on( - 'viewToModelPosition', - viewToModelPositionOutsideModelElement( this.editor.model, viewElement => viewElement.hasClass( 'field' ) ) - ); - this.editor.config.define( 'fieldConfig', FieldConfig ); - } + this.editor.editing.mapper.on( + "viewToModelPosition", + viewToModelPositionOutsideModelElement(this.editor.model, (viewElement) => + viewElement.hasClass("field"), + ), + ); + this.editor.config.define("fieldConfig", FieldConfig); + } - _defineSchema() { - const schema = this.editor.model.schema; + _defineSchema() { + const schema = this.editor.model.schema; - schema.register( 'field', { - // Behaves like a self-contained inline object (e.g. an inline image) - // allowed in places where $text is allowed (e.g. in paragraphs). - // The inline widget can have the same attributes as text (for example linkHref, bold). - inheritAllFrom: '$inlineObject', + schema.register("field", { + // Behaves like a self-contained inline object (e.g. an inline image) + // allowed in places where $text is allowed (e.g. in paragraphs). + // The inline widget can have the same attributes as text (for example linkHref, bold). + inheritAllFrom: "$inlineObject", - // The field can have many types, like date, name, surname, etc: - allowAttributes: [ 'field' ] - } ); - } + // The field can have many types, like date, name, surname, etc: + allowAttributes: ["field"], + }); + } - _defineConverters() { - const conversion = this.editor.conversion; + _defineConverters() { + const conversion = this.editor.conversion; - conversion.for( 'upcast' ).elementToElement( { - view: { - name: 'span', - classes: [ 'field' ] - }, - model: (viewElement, conversionApi) => { - // Extract the "name" from "{name}". - if (viewElement === undefined) { - return null; - } - - const { writer } = conversionApi; - - const name = viewElement.getChild(0)?._textData; - - const fieldtype = viewElement.getAttribute("fieldtype"); - const guid = viewElement.getAttribute("guid"); - const fieldid = viewElement.getAttribute("fieldid"); - - const field = { - name, - type: fieldtype, - guid, - fieldid - }; - - - return writer.createElement('field', { field }); - } - } ); - - conversion.for( 'editingDowncast' ).elementToElement( { - model: 'field', - view: ( modelItem, { writer: viewWriter } ) => { - const widgetElement = createfieldView( modelItem, viewWriter ); - - // Enable widget handling on a field element inside the editing view. - return toWidget( widgetElement, viewWriter ); - } - } ); - - conversion.for( 'dataDowncast' ).elementToElement( { - model: 'field', - view: ( modelItem, { writer: viewWriter } ) => createfieldView( modelItem, viewWriter ) - } ); - - // Helper method for both downcast converters. -// function createfieldView( modelItem : Element, viewWriter : DowncastWriter ) { - function createfieldView( modelItem, viewWriter ) { - const field = modelItem.getAttribute( 'field' ); //todo any is a cop out. - - const fieldView = viewWriter.createContainerElement( 'span', { - class: 'field', - fieldType: field.type, - guid: field.guid, - fieldid: (field.guid !== undefined) ? null : field.id - } ); - - // Insert the field name (as a text). - const innerText = viewWriter.createText( '{' + field.name.ltrim('{').rtrim('}') + '}' ); - viewWriter.insert( viewWriter.createPositionAt( fieldView, 0 ), innerText ); - - return fieldView; + conversion.for("upcast").elementToElement({ + view: { + name: "span", + classes: ["field"], + }, + model: (viewElement, conversionApi) => { + // Extract the "name" from "{name}". + if (viewElement === undefined) { + return null; } + + const { writer } = conversionApi; + + const name = viewElement.getChild(0)?._textData; + + const fieldtype = viewElement.getAttribute("fieldtype"); + const guid = viewElement.getAttribute("guid"); + const fieldid = viewElement.getAttribute("fieldid"); + + const field = { + name, + type: fieldtype, + guid, + fieldid, + }; + + return writer.createElement("field", { field }); + }, + }); + + conversion.for("editingDowncast").elementToElement({ + model: "field", + view: (modelItem, { writer: viewWriter }) => { + const widgetElement = createfieldView(modelItem, viewWriter); + + // Enable widget handling on a field element inside the editing view. + return toWidget(widgetElement, viewWriter); + }, + }); + + conversion.for("dataDowncast").elementToElement({ + model: "field", + view: (modelItem, { writer: viewWriter }) => + createfieldView(modelItem, viewWriter), + }); + + // Helper method for both downcast converters. + // function createfieldView( modelItem : Element, viewWriter : DowncastWriter ) { + function createfieldView(modelItem, viewWriter) { + const field = modelItem.getAttribute("field"); //todo any is a cop out. + + const fieldView = viewWriter.createContainerElement("span", { + class: "field", + fieldType: field.type, + guid: field.guid, + fieldid: field.guid !== undefined ? null : field.id, + }); + + // Insert the field name (as a text). + const innerText = viewWriter.createText( + "{" + rtrim(ltrim(field.name, "{"), "}") + "}", + ); + viewWriter.insert(viewWriter.createPositionAt(fieldView, 0), innerText); + + return fieldView; } -} \ No newline at end of file + } +} diff --git a/src/modules/blockedIPs/blockedIPs.tsx b/src/modules/blockedIPs/blockedIPs.tsx index 7160f74..d0c6f8b 100644 --- a/src/modules/blockedIPs/blockedIPs.tsx +++ b/src/modules/blockedIPs/blockedIPs.tsx @@ -46,6 +46,7 @@ export default function BlockedIPs() { useEffect(() => { loadPage(pagedData.page, pagedData.pageSize); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // initial load only const handleSort = useCallback( diff --git a/src/modules/frame/services/authenticationService.ts b/src/modules/frame/services/authenticationService.ts index 08667e6..98c57aa 100644 --- a/src/modules/frame/services/authenticationService.ts +++ b/src/modules/frame/services/authenticationService.ts @@ -1,4 +1,4 @@ -import jwt_decode from "jwt-decode"; +import { jwtDecode } from "jwt-decode"; import Cookies from "js-cookie"; import httpService from "../../../services/httpService"; import { IEmailUserAction } from "../models/IEmailUserAction"; @@ -58,7 +58,7 @@ export function hasToken(): boolean { export function tokenExpired(): boolean { const jwt = getJwt(); if (jwt) { - const decodedToken: any = jwt_decode(jwt); + const decodedToken: any = jwtDecode(jwt); const expiry: Date = new Date(decodedToken.exp * 1000); const now: Date = new Date(Date.now()); @@ -74,7 +74,7 @@ export function getCurrentUser(): JwtToken | null { try { const jwt = getJwt(); if (jwt) { - const decodedToken: any = jwt_decode(jwt); + const decodedToken: any = jwtDecode(jwt); const expiry: Date = new Date(decodedToken.exp * 1000); const now: Date = new Date(Date.now());