diff --git a/package-lock.json b/package-lock.json index a42d04a3..b9458e00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,8 @@ "@fontsource/roboto": "^4.5.7", "@sentry/browser": "^6.17.7", "@tinymce/tinymce-react": "^3.13.0", - "@zextras/carbonio-design-system": "^0.4.1", - "@zextras/carbonio-ui-preview": "^0.2.1", + "@zextras/carbonio-design-system": "^0.5.0", + "@zextras/carbonio-ui-preview": "^0.2.3", "darkreader": "4.9.46", "history": "^5.2.0", "i18next": "21.6.10", @@ -87,7 +87,7 @@ "prop-types": "15.8.1", "rollup": "2.66.1", "semver": "7.3.5", - "styled-components": "5.3.3", + "styled-components": "5.3.6", "webpack": "5.67.0", "webpack-cli": "4.9.2", "webpack-dev-server": "4.7.3", @@ -99,7 +99,7 @@ }, "peerDependencies": { "@reduxjs/toolkit": "^1.6.2", - "@zextras/carbonio-design-system": "^0.3.0", + "@zextras/carbonio-design-system": "^0.5.0", "core-js": "^3.19.1", "moment": "^2.29.1", "node-fetch": "^2.6.6", @@ -2237,15 +2237,17 @@ } }, "node_modules/@emotion/is-prop-valid": { - "version": "0.8.8", - "license": "MIT", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", "dependencies": { - "@emotion/memoize": "0.7.4" + "@emotion/memoize": "^0.8.0" } }, "node_modules/@emotion/memoize": { - "version": "0.7.4", - "license": "MIT" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@emotion/stylis": { "version": "0.8.5", @@ -3909,9 +3911,9 @@ "license": "Apache-2.0" }, "node_modules/@zextras/carbonio-design-system": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@zextras/carbonio-design-system/-/carbonio-design-system-0.4.1.tgz", - "integrity": "sha512-NUqEL2cfKVmKYzrJdB7/dINFBSHrT6rHjsUPkbU2Xt/0t/18bQOU0jSffIz5YvgTU9z07+QJb02G7GSO3LwDug==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@zextras/carbonio-design-system/-/carbonio-design-system-0.5.0.tgz", + "integrity": "sha512-IuW3XqxtUTI3JqChDiDBhvVxIaLkohcTf1qxJJNimlw6xGPgcawDqEB4D3sVIHXI+Z3Y8xOMpbGNB1lY4Da5Ig==", "dependencies": { "@popperjs/core": "2.11.0", "darkreader": "4.9.44", @@ -3970,19 +3972,29 @@ } }, "node_modules/@zextras/carbonio-ui-preview": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@zextras/carbonio-ui-preview/-/carbonio-ui-preview-0.2.1.tgz", - "integrity": "sha512-EBK2xsCed8Vnxz/oKTOcy4++svv7eikwrCY0hgSpdpQblPNSwlyE0ZvjtN6Tc7WtGS0kaAk/nb927JYwdr+C5A==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@zextras/carbonio-ui-preview/-/carbonio-ui-preview-0.2.3.tgz", + "integrity": "sha512-hsjY6dvEJHYUZ2E6t7wVz7ujpC0PXUkMQk93BybzleCeUwQcv0RX0VuonZlTuYvpf3APq9glPr8hgI7CR5RAVA==", "dependencies": { - "core-js": "^3.19.1", + "core-js": "^3.25.5", "react-pdf": "^5.7.2" }, "peerDependencies": { - "@zextras/carbonio-design-system": "^0.4.0", + "@zextras/carbonio-design-system": ">=0.4 <=0.5", "lodash": "^4.17.21", "react": "^17.0.2", "react-dom": "^17.0.2", - "styled-components": "^5.3.3" + "styled-components": "^5.3.6" + } + }, + "node_modules/@zextras/carbonio-ui-preview/node_modules/core-js": { + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz", + "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, "node_modules/@zextras/carbonio-ui-sdk": { @@ -5654,6 +5666,7 @@ }, "node_modules/core-js": { "version": "3.20.3", + "dev": true, "hasInstallScript": true, "license": "MIT", "funding": { @@ -13634,12 +13647,14 @@ } }, "node_modules/styled-components": { - "version": "5.3.3", - "license": "MIT", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", + "integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==", + "hasInstallScript": true, "dependencies": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", + "@emotion/is-prop-valid": "^1.1.0", "@emotion/stylis": "^0.8.4", "@emotion/unitless": "^0.7.4", "babel-plugin-styled-components": ">= 1.12.0", @@ -16520,13 +16535,17 @@ "dev": true }, "@emotion/is-prop-valid": { - "version": "0.8.8", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", "requires": { - "@emotion/memoize": "0.7.4" + "@emotion/memoize": "^0.8.0" } }, "@emotion/memoize": { - "version": "0.7.4" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "@emotion/stylis": { "version": "0.8.5" @@ -17641,9 +17660,9 @@ "version": "4.2.2" }, "@zextras/carbonio-design-system": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@zextras/carbonio-design-system/-/carbonio-design-system-0.4.1.tgz", - "integrity": "sha512-NUqEL2cfKVmKYzrJdB7/dINFBSHrT6rHjsUPkbU2Xt/0t/18bQOU0jSffIz5YvgTU9z07+QJb02G7GSO3LwDug==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@zextras/carbonio-design-system/-/carbonio-design-system-0.5.0.tgz", + "integrity": "sha512-IuW3XqxtUTI3JqChDiDBhvVxIaLkohcTf1qxJJNimlw6xGPgcawDqEB4D3sVIHXI+Z3Y8xOMpbGNB1lY4Da5Ig==", "requires": { "@popperjs/core": "2.11.0", "darkreader": "4.9.44", @@ -17690,12 +17709,19 @@ } }, "@zextras/carbonio-ui-preview": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@zextras/carbonio-ui-preview/-/carbonio-ui-preview-0.2.1.tgz", - "integrity": "sha512-EBK2xsCed8Vnxz/oKTOcy4++svv7eikwrCY0hgSpdpQblPNSwlyE0ZvjtN6Tc7WtGS0kaAk/nb927JYwdr+C5A==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@zextras/carbonio-ui-preview/-/carbonio-ui-preview-0.2.3.tgz", + "integrity": "sha512-hsjY6dvEJHYUZ2E6t7wVz7ujpC0PXUkMQk93BybzleCeUwQcv0RX0VuonZlTuYvpf3APq9glPr8hgI7CR5RAVA==", "requires": { - "core-js": "^3.19.1", + "core-js": "^3.25.5", "react-pdf": "^5.7.2" + }, + "dependencies": { + "core-js": { + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz", + "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==" + } } }, "@zextras/carbonio-ui-sdk": { @@ -18760,7 +18786,8 @@ } }, "core-js": { - "version": "3.20.3" + "version": "3.20.3", + "dev": true }, "core-js-compat": { "version": "3.20.3", @@ -23649,11 +23676,13 @@ } }, "styled-components": { - "version": "5.3.3", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", + "integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", + "@emotion/is-prop-valid": "^1.1.0", "@emotion/stylis": "^0.8.4", "@emotion/unitless": "^0.7.4", "babel-plugin-styled-components": ">= 1.12.0", diff --git a/package.json b/package.json index 582a8810..7c233a29 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "prop-types": "15.8.1", "rollup": "2.66.1", "semver": "7.3.5", - "styled-components": "5.3.3", + "styled-components": "5.3.6", "webpack": "5.67.0", "webpack-cli": "4.9.2", "webpack-dev-server": "4.7.3", @@ -99,8 +99,8 @@ "@fontsource/roboto": "^4.5.7", "@sentry/browser": "^6.17.7", "@tinymce/tinymce-react": "^3.13.0", - "@zextras/carbonio-design-system": "^0.4.1", - "@zextras/carbonio-ui-preview": "^0.2.1", + "@zextras/carbonio-design-system": "^0.5.0", + "@zextras/carbonio-ui-preview": "^0.2.3", "darkreader": "4.9.46", "history": "^5.2.0", "i18next": "21.6.10", @@ -126,7 +126,7 @@ }, "peerDependencies": { "@reduxjs/toolkit": "^1.6.2", - "@zextras/carbonio-design-system": "^0.3.0", + "@zextras/carbonio-design-system": "^0.5.0", "core-js": "^3.19.1", "moment": "^2.29.1", "node-fetch": "^2.6.6", diff --git a/src/network/fetch.ts b/src/network/fetch.ts index 835c6971..80969cf9 100644 --- a/src/network/fetch.ts +++ b/src/network/fetch.ts @@ -6,7 +6,13 @@ import { find, map, maxBy } from 'lodash'; import { goToLogin } from './go-to-login'; -import { Account, ErrorSoapResponse, SoapContext, SoapException, SoapResponse } from '../../types'; +import { + Account, + ErrorSoapBodyResponse, + ErrorSoapResponse, + SoapContext, + SoapResponse +} from '../../types'; import { userAgent } from './user-agent'; import { report } from '../reporting'; import { useAccountStore } from '../store/account'; @@ -85,7 +91,7 @@ const normalizeContext = (context: any): SoapContext => { return context; }; -const handleResponse = (api: string, res: SoapResponse): R => { +const handleResponse = (api: string, res: SoapResponse): R | ErrorSoapBodyResponse => { const { pollingInterval, noOpTimeout } = useNetworkStore.getState(); const { usedQuota } = useAccountStore.getState(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -111,8 +117,6 @@ const handleResponse = (api: string, res: SoapResponse): R => { }` ) ); - - throw new SoapException(res); } if (res.Header?.context) { const responseUsedQuota = @@ -134,9 +138,10 @@ const handleResponse = (api: string, res: SoapResponse): R => { ..._context }); } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - return res.Body[`${api}Response`] as R; + return res?.Body?.Fault ? (res.Body as ErrorSoapBodyResponse) : (res.Body[`${api}Response`] as R); }; export const getSoapFetch = (app: string) => diff --git a/src/search/search-bar.tsx b/src/search/search-bar.tsx index edbb4762..d5ad6374 100644 --- a/src/search/search-bar.tsx +++ b/src/search/search-bar.tsx @@ -70,7 +70,8 @@ export const SearchBar: FC = () => { ); const [inputTyped, setInputTyped] = useState(''); const history = useHistory(); - const { updateQuery, module, query, searchDisabled, setSearchDisabled } = useSearchStore(); + const { updateQuery, module, query, searchDisabled, setSearchDisabled, tooltip } = + useSearchStore(); // const [moduleSelection, setModuleSelection] = useState<{ // value: string; // label: string; @@ -369,10 +370,10 @@ export const SearchBar: FC = () => { diff --git a/src/search/search-store.tsx b/src/search/search-store.tsx index a0989632..e39533c4 100644 --- a/src/search/search-store.tsx +++ b/src/search/search-store.tsx @@ -11,7 +11,9 @@ import { QueryChip, SearchState } from '../../types'; export const useSearchStore = create((set, get) => ({ query: [], searchDisabled: false, - setSearchDisabled: (searchDisabled: boolean): void => set({ searchDisabled }), + tooltip: undefined, + setSearchDisabled: (searchDisabled: boolean, tooltip?: string): void => + set({ searchDisabled, tooltip }), updateQuery: (query: Array | ((q: Array) => Array)): void => set({ query: isFunction(query) ? query(get().query) : query }), updateModule: (module: string): void => set({ module }) diff --git a/src/store/integrations/composer.tsx b/src/store/integrations/composer.tsx index 592771eb..052084ff 100644 --- a/src/store/integrations/composer.tsx +++ b/src/store/integrations/composer.tsx @@ -3,8 +3,9 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import React, { FC, useCallback, useMemo } from 'react'; +import React, { FC, useCallback, useMemo, useRef } from 'react'; import { Container } from '@zextras/carbonio-design-system'; +import styled from 'styled-components'; // TinyMCE so the global var exists // eslint-disable-next-line no-unused-vars import tinymce from 'tinymce/tinymce'; @@ -44,6 +45,7 @@ import 'tinymce/plugins/directionality'; import 'tinymce/plugins/autoresize'; import { Editor } from '@tinymce/tinymce-react'; +import { useTranslation } from 'react-i18next'; import { useUserSettings } from '../account'; type ComposerProps = { @@ -57,14 +59,21 @@ type ComposerProps = { value?: string; /** The base url to append to the resource urls */ baseAssetsUrl?: string; + onFileSelect?: (arg: any) => void; }; +export const FileInput = styled.input` + display: none; +`; + const Composer: FC = ({ onEditorChange, + onFileSelect, inline = false, value, baseAssetsUrl, initialValue, + ...rest }) => { const _onEditorChange = useCallback( @@ -85,7 +94,15 @@ const Composer: FC = ({ }), [prefs] ); - + const inputRef = useRef(); + const onFileClick = useCallback(() => { + if (inputRef.current) { + inputRef.current.value = null; + inputRef.current.click(); + } + }, []); + const { t } = useTranslation(); + const inlineLabel = useMemo(() => t('label.add_inline_image', 'Add inline image'), [t]); return ( = ({ mainAlignment="flex-start" style={{ overflowY: 'hidden' }} > + { + onFileSelect && onFileSelect({ editor: tinymce, files: inputRef?.current?.files }); + }} + multiple + /> + { + if (onFileSelect) + editor.ui.registry.addMenuButton('imageSelector', { + icon: 'gallery', + tooltip: 'Select Image', + fetch: (callback: any) => { + const items = [ + { + type: 'menuitem', + text: inlineLabel, + onAction: (): void => { + onFileClick(); + } + } + ]; + callback(items); + } + }); + }, min_height: 350, + auto_focus: true, menubar: false, statusbar: false, branding: false, @@ -170,7 +217,7 @@ const Composer: FC = ({ toolbar: inline ? false : // eslint-disable-next-line max-len - 'fontselect fontsizeselect styleselect visualblocks| bold italic underline strikethrough | removeformat code | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist outdent indent | ltr rtl | insertfile image ', + 'fontselect fontsizeselect styleselect visualblocks| bold italic underline strikethrough | removeformat code | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist outdent indent | ltr rtl | insertfile image | imageSelector ', quickbars_insert_toolbar: inline ? 'bullist numlist' : '', quickbars_selection_toolbar: inline ? 'bold italic underline | forecolor backcolor | removeformat | quicklink' @@ -178,7 +225,7 @@ const Composer: FC = ({ contextmenu: inline ? '' : '', toolbar_mode: 'wrap', forced_root_block: false, - content_style: `body { color: ${defaultStyle?.color}; font-size: ${defaultStyle?.fontSize}; font-family: ${defaultStyle?.font}; }`, + content_style: `body { color: ${defaultStyle?.color}; font-size: ${defaultStyle?.fontSize}; font-family: ${defaultStyle?.font}; }`, visualblocks_default_state: false, end_container_on_empty_block: true }} diff --git a/translations/en.json b/translations/en.json index ade6145c..9c057121 100644 --- a/translations/en.json +++ b/translations/en.json @@ -32,6 +32,7 @@ "accounts_list": "Accounts list", "add_delegate": "Add delegate", "add_external_account": "Add external account", + "add_inline_image": "Add inline image", "add_new_email": "Add new e-mail address", "add_persona": "Add persona", "add_recovery_email": "Add recovery e-mail", diff --git a/translations/pl.json b/translations/pl.json index 7242fe1f..aaa5816b 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -348,7 +348,7 @@ "user_quota": { "limited": "{{quota}}% dostępnej przestrzeni zostało zapełnione", "space_full": "Wygląda na to, że cała dostępna przestrzeń jest zapełniona", - "title": "Przydział przestrzeni dla użytkownika", + "title": "Limit przestrzeni dla użytkownika", "unlimited": "Masz nieograniczoną ilość dostępnej przestrzeni" }, "module": { diff --git a/types/exports/index.d.ts b/types/exports/index.d.ts index 5c37e1b7..4a9103f6 100644 --- a/types/exports/index.d.ts +++ b/types/exports/index.d.ts @@ -30,7 +30,14 @@ import { AccountRightTarget, SoapFetch } from '../account'; -import { Mods, TagActionResponse, CreateTagResponse, SoapNotify, SoapRefresh } from '../network'; +import { + Mods, + TagActionResponse, + CreateTagResponse, + SoapNotify, + SoapRefresh, + ErrorSoapResponse +} from '../network'; import { HistoryParams, ShellModes, AccordionFolder } from '../misc'; import { Tag, Tags } from '../tags'; import { Folder, Folders } from '../folder'; @@ -123,7 +130,6 @@ export const soapFetch: SoapFetch; export const xmlSoapFetch: SoapFetch; export const report: (error: Error, hint?: unknown) => void; export const setAppContext: (obj: T) => void; -export class SoapException {} export const removeActions: (...ids: Array) => void; export const registerActions: ( diff --git a/types/network/soap.d.ts b/types/network/soap.d.ts index 219e28e0..009ea51d 100644 --- a/types/network/soap.d.ts +++ b/types/network/soap.d.ts @@ -10,10 +10,12 @@ import { BaseFolder, LinkFolderFields, SearchFolderFields } from '../misc'; export type SoapHeader = { context: SoapContext; }; + export type SuccessSoapResponse = { Body: Record; Header: SoapHeader; }; + export type SoapFault = { Detail: { Error: { @@ -25,10 +27,13 @@ export type SoapFault = { Text: string; }; }; + +export type ErrorSoapBodyResponse = { + Fault: SoapFault; +}; + export type ErrorSoapResponse = { - Body: { - Fault: SoapFault; - }; + Body: ErrorSoapBodyResponse; Header: SoapHeader; }; @@ -74,12 +79,3 @@ export type SoapNotify = { }; deleted: string[]; }; - -export class SoapException extends Error { - constructor(response: ErrorSoapResponse) { - super(response?.Body.Fault.Reason.Text); - this.response = response; - } - - response: ErrorSoapResponse; -} diff --git a/types/search/index.d.ts b/types/search/index.d.ts index aed4ca6f..5b9a5d54 100644 --- a/types/search/index.d.ts +++ b/types/search/index.d.ts @@ -11,6 +11,7 @@ export type SearchState = { query: Array; module?: string; searchDisabled: boolean; + tooltip?: string; setSearchDisabled: (searchDisabled: boolean) => void; updateQuery: (query: Array | ((q: Array) => Array)) => void; updateModule: (module: string) => void;