From b40a5b73a7bdb1254f9e4037a1ed8535dcbcd115 Mon Sep 17 00:00:00 2001 From: vhu-axelor <146069039+vhu-axelor@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:05:17 +0100 Subject: [PATCH] feat: remove attached files feature from core package --- changelogs/unreleased/88363.json | 5 + packages/core/README.md | 13 +- packages/core/src/api/attached-files-api.ts | 65 ------- .../HeaderOptionsMenu/HeaderOptionsMenu.js | 5 - .../AttachedFilesView/AttachedFilesView.js | 163 ------------------ .../core/src/components/templates/index.js | 1 - .../core/src/features/attachedFilesSlice.js | 97 ----------- packages/core/src/features/index.js | 1 - packages/core/src/header/hooks.js | 47 ----- packages/core/src/header/types.ts | 1 - packages/core/src/i18n/translations/en.json | 3 - packages/core/src/i18n/translations/fr.json | 3 - packages/core/src/navigator/drawer/Header.js | 1 - .../core/src/screens/AttachedFilesScreen.tsx | 38 ---- packages/core/src/screens/index.js | 9 - 15 files changed, 11 insertions(+), 441 deletions(-) create mode 100644 changelogs/unreleased/88363.json delete mode 100644 packages/core/src/api/attached-files-api.ts delete mode 100644 packages/core/src/components/templates/AttachedFilesView/AttachedFilesView.js delete mode 100644 packages/core/src/features/attachedFilesSlice.js delete mode 100644 packages/core/src/screens/AttachedFilesScreen.tsx diff --git a/changelogs/unreleased/88363.json b/changelogs/unreleased/88363.json new file mode 100644 index 0000000000..6fd2eeccf4 --- /dev/null +++ b/changelogs/unreleased/88363.json @@ -0,0 +1,5 @@ +{ + "title": "Attached files: remove attached files feature from core package", + "type": "feat", + "packages": "core" +} diff --git a/packages/core/README.md b/packages/core/README.md index b74a7f153f..18e03b71fa 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -19,7 +19,7 @@ It contains: - Auth module with login and user screens - Translations management system - Various helper tools : clipboard, file viewer, external app management -- Management of MailMessages and attaches files on objects +- Management of MailMessages - AOS linked components or using external libraries : Camera, Scanner, PlanningView, Stopwatch, ... - Menu management - Storage management @@ -306,13 +306,13 @@ const Colors = useThemeColor(); )} ``` -### Add MailMessages and attached files +### Add MailMessages -- Management of MailMessages and attaches files on objects +- Management of MailMessages on objects -This package provides a component to add MailMessages and file attachments functionality to the header. This component also allows to display its children if there are any as a dropdown menu. +This package provides a component to add MailMessages functionality to the header. This component also allows to display its children if there are any as a dropdown menu. -For the first two functionalities of this component, it is necessary to provide in props the name of the object model ("com.axelor.apps.stock.db.StockCorrection" for the stock corrections for example), the id of the current object, and the navigation attribute to go on the dedicated screens: +For the first functionality of this component, it is necessary to provide in props the name of the object model ("com.axelor.apps.stock.db.StockCorrection" for the stock corrections for example), the id of the current object, and the navigation attribute to go on the dedicated screens: ```typescript import {HeaderOptionsMenu} from '@axelor/aos-mobile-core'; @@ -326,8 +326,7 @@ React.useLayoutEffect(() => { + navigation={navigation}> ). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import {axiosApiProvider} from '../apiProviders'; -import {fetchFileDetails} from './metafile-api'; - -export async function fetchAttachedFiles({ - model, - modelId, -}: { - model: string; - modelId: number; -}) { - return axiosApiProvider - .get({url: `/ws/dms/attachments/${model}/${modelId}`}) - .then(response => { - if (response?.data?.data == null) { - return response; - } else { - return fetchFileDetails({ - listFiles: response?.data?.data, - isMetaFile: false, - }); - } - }); -} - -export async function countAttachments({ - model, - modelId, -}: { - model: string; - modelId: number; -}) { - return axiosApiProvider.post({ - url: '/ws/rest/com.axelor.dms.db.DMSFile/search', - data: { - data: { - _domain: - 'self.relatedModel = :name AND self.relatedId = :id ' + - 'AND COALESCE(self.isDirectory, FALSE) = FALSE', - _domainContext: { - name: model, - id: modelId, - }, - }, - fields: ['id'], - }, - }); -} diff --git a/packages/core/src/components/organisms/HeaderOptionsMenu/HeaderOptionsMenu.js b/packages/core/src/components/organisms/HeaderOptionsMenu/HeaderOptionsMenu.js index adbdc4461c..3503621ba5 100644 --- a/packages/core/src/components/organisms/HeaderOptionsMenu/HeaderOptionsMenu.js +++ b/packages/core/src/components/organisms/HeaderOptionsMenu/HeaderOptionsMenu.js @@ -34,12 +34,10 @@ const HeaderOptionsMenu = ({ disableMailMessages, disableJsonFields, disablePrint, - attachedFileScreenTitle, barcodeFieldname, }) => { const { mailMessagesAction, - attachedFilesAction, barcodeAction, printAction, jsonFieldsAction, @@ -52,7 +50,6 @@ const HeaderOptionsMenu = ({ disablePrint, barcodeFieldname, disableJsonFields, - attachedFileScreenTitle, }); const collapseMenuItems = useMemo( @@ -88,7 +85,6 @@ const HeaderOptionsMenu = ({ const allActions = useMemo( () => [ - attachedFilesAction, mailMessagesAction, printAction, barcodeAction, @@ -100,7 +96,6 @@ const HeaderOptionsMenu = ({ .sort((a, b) => a.order - b.order), [ actions, - attachedFilesAction, barcodeAction, jsonFieldsAction, mailMessagesAction, diff --git a/packages/core/src/components/templates/AttachedFilesView/AttachedFilesView.js b/packages/core/src/components/templates/AttachedFilesView/AttachedFilesView.js deleted file mode 100644 index 7e6fef619e..0000000000 --- a/packages/core/src/components/templates/AttachedFilesView/AttachedFilesView.js +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Axelor Business Solutions - * - * Copyright (C) 2024 Axelor (). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React, {useCallback, useState, useMemo, useEffect} from 'react'; -import {useSelector, useDispatch} from 'react-redux'; -import { - AttachmentCard, - ChipSelect, - File, - HeaderContainer, - Screen, - ScrollList, - useThemeColor, -} from '@axelor/aos-mobile-ui'; -import useTranslator from '../../../i18n/hooks/use-translator'; -import { - getAttachedFiles, - getAttachedFilesDetails, -} from '../../../features/attachedFilesSlice'; -import {openFileInExternalApp} from '../../../tools/FileViewer'; -import {headerActionsProvider} from '../../../header'; - -function AttachedFilesView({ - files, - model, - modelId, - isStaticList = false, - isMetaFile = false, - screenTitle, - actionList = [], - verticalActions = true, -}) { - const Colors = useThemeColor(); - const I18n = useTranslator(); - const dispatch = useDispatch(); - - const {baseUrl, token, jsessionId} = useSelector(state => state.auth); - const {loading, attachedFilesList} = useSelector( - state => state.attachedFiles, - ); - - const [selectedStatus, setSelectedStatus] = useState([]); - const [extensionList, setExtensionList] = useState([]); - - const handleShowFile = async item => { - await openFileInExternalApp( - {fileName: item.fileName, id: item.id, isMetaFile: isMetaFile}, - {baseUrl: baseUrl, token: token, jsessionId: jsessionId}, - I18n, - ); - }; - - const fetchFilesAPI = useCallback(() => { - dispatch( - isStaticList - ? getAttachedFilesDetails({ - listFiles: files, - isMetaFile: true, - }) - : getAttachedFiles({ - model, - modelId, - }), - ); - }, [dispatch, isStaticList, files, model, modelId]); - - const filterOnSelectExtension = useCallback( - list => { - if (!Array.isArray(list) || list.length === 0) { - return list; - } else if (selectedStatus.length > 0) { - return list.filter(item => - selectedStatus.find( - status => File.getFileExtension(item.fileName) === status.key, - ), - ); - } else { - return list; - } - }, - [selectedStatus], - ); - - const filteredList = useMemo( - () => filterOnSelectExtension(attachedFilesList), - [filterOnSelectExtension, attachedFilesList], - ); - - useEffect(() => { - if (screenTitle) { - headerActionsProvider.registerModel('core_attachedFiles_details', { - headerTitle: screenTitle, - }); - } - }, [screenTitle]); - - useEffect(() => { - setExtensionList( - Array.from( - new Set( - attachedFilesList?.map(item => File.getFileExtension(item.fileName)), - ), - ), - ); - }, [files, attachedFilesList]); - - return ( - - setSelectedStatus(chiplist)} - selectionItems={extensionList.map(ext => { - return { - title: `${ext}`.toUpperCase(), - color: Colors.primaryColor, - key: ext, - }; - })} - /> - } - /> - ( - handleShowFile(item)} - creationDate={item.createdOn} - translator={I18n.t} - /> - )} - fetchData={fetchFilesAPI} - filter={true} - moreLoading={false} - isListEnd={true} - translator={I18n.t} - actionList={actionList} - verticalActions={verticalActions} - /> - - ); -} - -export default AttachedFilesView; diff --git a/packages/core/src/components/templates/index.js b/packages/core/src/components/templates/index.js index d32b971a97..3b361212af 100644 --- a/packages/core/src/components/templates/index.js +++ b/packages/core/src/components/templates/index.js @@ -16,7 +16,6 @@ * along with this program. If not, see . */ -export {default as AttachedFilesView} from './AttachedFilesView/AttachedFilesView'; export {default as GlobalToolBox} from './GlobalToolBox/GlobalToolBox'; export {default as MailMessageView} from './MailMessageView/MailMessageView'; export {default as PeriodInput} from './PeriodInput/PeriodInput'; diff --git a/packages/core/src/features/attachedFilesSlice.js b/packages/core/src/features/attachedFilesSlice.js deleted file mode 100644 index 5c0d118ea7..0000000000 --- a/packages/core/src/features/attachedFilesSlice.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Axelor Business Solutions - * - * Copyright (C) 2024 Axelor (). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import {createAsyncThunk, createSlice} from '@reduxjs/toolkit'; -import {handlerApiCall} from '../apiProviders/utils'; -import {countAttachments, fetchAttachedFiles} from '../api/attached-files-api'; -import {fetchFileDetails} from '../api/metafile-api'; - -export const getAttachedFiles = createAsyncThunk( - 'attachedFiles/getAttachedFiles', - async function (data, {getState}) { - return handlerApiCall({ - fetchFunction: fetchAttachedFiles, - data: data, - action: 'Base_SliceAction_FetchAttachedFiles', - getState: getState, - responseOptions: {isArrayResponse: true}, - }); - }, -); - -export const getAttachedFilesDetails = createAsyncThunk( - 'attachedFiles/getAttachedFilesDetails', - async function (data, {getState}) { - return handlerApiCall({ - fetchFunction: fetchFileDetails, - data: data, - action: 'Base_SliceAction_FetchFilesDetails', - getState: getState, - responseOptions: {isArrayResponse: true}, - }); - }, -); - -export const countAttachmentFiles = createAsyncThunk( - 'attachedFiles/countAttachmentFiles', - async function (data, {getState}) { - return handlerApiCall({ - fetchFunction: countAttachments, - data: data, - action: 'Base_SliceAction_CountAttachedFiles', - getState: getState, - responseOptions: {isArrayResponse: true, returnTotal: true}, - }); - }, -); - -const initialState = { - loading: false, - attachedFilesList: [], - attachments: 0, -}; - -const attachedFilesSlice = createSlice({ - name: 'attachedFiles', - initialState, - extraReducers: builder => { - builder.addCase(getAttachedFiles.pending, state => { - state.loading = true; - }); - builder.addCase(getAttachedFiles.fulfilled, (state, action) => { - state.loading = false; - state.attachedFilesList = action.payload; - }); - builder.addCase(getAttachedFilesDetails.pending, state => { - state.loading = true; - }); - builder.addCase(getAttachedFilesDetails.fulfilled, (state, action) => { - state.loading = false; - state.attachedFilesList = action.payload; - }); - builder.addCase(countAttachmentFiles.pending, state => { - state.loading = true; - }); - builder.addCase(countAttachmentFiles.fulfilled, (state, action) => { - state.loading = false; - state.attachments = action.payload; - }); - }, -}); - -export const attachedFilesReducer = attachedFilesSlice.reducer; diff --git a/packages/core/src/features/index.js b/packages/core/src/features/index.js index 3146a3aa6e..0f7f45d198 100644 --- a/packages/core/src/features/index.js +++ b/packages/core/src/features/index.js @@ -17,7 +17,6 @@ */ export {appConfigReducer as appConfig} from './appConfigSlice'; -export {attachedFilesReducer as attachedFiles} from './attachedFilesSlice'; export {authReducer as auth} from './authSlice'; export {default as cameraScanner} from './cameraScannerSlice'; export {default as camera} from './cameraSlice'; diff --git a/packages/core/src/header/hooks.js b/packages/core/src/header/hooks.js index ba82a58cf1..a7d2c784c0 100644 --- a/packages/core/src/header/hooks.js +++ b/packages/core/src/header/hooks.js @@ -19,7 +19,6 @@ import {useNavigation} from '@react-navigation/native'; import {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {useDispatch, useSelector} from 'react-redux'; -import {countAttachmentFiles} from '../features/attachedFilesSlice'; import {countUnreadMailMessages} from '../features/mailMessageSlice'; import {useTranslator} from '../i18n'; import {checkNullString} from '../utils'; @@ -36,7 +35,6 @@ export const useBasicActions = ({ disableMailMessages, disablePrint, disableJsonFields = false, - attachedFileScreenTitle, barcodeFieldname = 'barCode', }) => { const navigation = useNavigation(); @@ -46,10 +44,8 @@ export const useBasicActions = ({ const isFocused = useIsFocused(); const dispatch = useDispatch(); - const {attachments} = useSelector(state => state.attachedFiles); const {unreadMessages} = useSelector(state => state.mailMessages); - const [disableAttachementFiles, setDisableAttachementFiles] = useState(true); const [disableBarcode, setDisableBarcode] = useState(true); const [disableCustomView, setDisableCustomView] = useState(true); const [disablePrinting, setDisablePrinting] = useState(true); @@ -72,24 +68,10 @@ export const useBasicActions = ({ } }, [dispatch, model, modelConfigured, modelId]); - const countAttachmentsAPI = useCallback(() => { - if (modelConfigured) { - dispatch(countAttachmentFiles({model, modelId})); - } - }, [dispatch, model, modelConfigured, modelId]); - useEffect(() => { countUnreadMessagesAPI(); }, [countUnreadMessagesAPI]); - useEffect(() => { - countAttachmentsAPI(); - }, [countAttachmentsAPI]); - - useEffect(() => { - setDisableAttachementFiles(attachments === 0); - }, [attachments]); - useEffect(() => { fetchModel({model, modelId}) .catch(() => { @@ -149,32 +131,6 @@ export const useBasicActions = ({ }; }, [I18n, disableMailMessages, model, modelId, navigation, unreadMessages]); - const attachedFilesAction = useMemo(() => { - return { - key: 'attachedFiles', - order: 10, - title: I18n.t('Base_AttachedFiles'), - iconName: 'paperclip', - indicator: attachments, - hideIf: disableAttachementFiles, - onPress: () => - navigation.navigate('AttachedFilesScreen', { - model, - modelId, - screenTitle: attachedFileScreenTitle, - }), - showInHeader: true, - }; - }, [ - I18n, - attachedFileScreenTitle, - attachments, - disableAttachementFiles, - model, - modelId, - navigation, - ]); - const barcodeAction = useMemo(() => { return { key: 'barcode', @@ -243,14 +199,12 @@ export const useBasicActions = ({ ...(modelConfigured ? { mailMessagesAction, - attachedFilesAction, printAction, barcodeAction, jsonFieldsAction, } : { mailMessagesAction: {key: 'mailMessages', hideIf: true}, - attachedFilesAction: {key: 'attachedFiles', hideIf: true}, printAction: {key: 'printTemplate', hideIf: true}, barcodeAction: {key: 'barcode', hideIf: true}, jsonFieldsAction: {key: 'metaJsonFields', hideIf: true}, @@ -259,7 +213,6 @@ export const useBasicActions = ({ }, [ modelConfigured, mailMessagesAction, - attachedFilesAction, printAction, barcodeAction, jsonFieldsAction, diff --git a/packages/core/src/header/types.ts b/packages/core/src/header/types.ts index 2a1722cf35..ce0fa19e9f 100644 --- a/packages/core/src/header/types.ts +++ b/packages/core/src/header/types.ts @@ -30,7 +30,6 @@ export interface HeaderOptions { disablePrint?: boolean; disableMailMessages?: boolean; disableJsonFields?: boolean; - attachedFileScreenTitle?: string; barcodeFieldname?: string; headerTitle?: string; actions?: ActionType[]; diff --git a/packages/core/src/i18n/translations/en.json b/packages/core/src/i18n/translations/en.json index 26d2d7b15b..d9e0332286 100644 --- a/packages/core/src/i18n/translations/en.json +++ b/packages/core/src/i18n/translations/en.json @@ -56,7 +56,6 @@ "Base_MailMessages_MarkAllAsRead": "Mark all messages as read", "Base_MailMessages_Subscribe": "Subscribe", "Base_MailMessages_Unsubscribe": "Unsubscribe", - "Base_AttachedFiles": "Attached files", "Base_Question": "Question", "Base_Unfollow_Confirmation": "Are you sure to unfollow this document?", "Base_NoConnection": "No internet connection", @@ -208,10 +207,8 @@ "Base_Print": "Print", "Base_PrintTemplate": "Print template", "Base_NoRecordsFound": "No records found", - "Base_SliceAction_FetchAttachedFiles": "fetch attached files", "Base_SliceAction_FetchFilesDetails": "fetch file details", "Base_SliceAction_FetchMetaModule": "fetch meta modules", - "Base_SliceAction_CountAttachedFiles": "count attachment files", "Base_SliceAction_FetchMailMessages": "fetch mail messages", "Base_SliceAction_PostMailMessageComment": "post mail message comment", "Base_SliceAction_FetchModelSubscribers": "fetch model subscribers", diff --git a/packages/core/src/i18n/translations/fr.json b/packages/core/src/i18n/translations/fr.json index 3697c644ce..8b03c434b8 100644 --- a/packages/core/src/i18n/translations/fr.json +++ b/packages/core/src/i18n/translations/fr.json @@ -56,7 +56,6 @@ "Base_MailMessages_MarkAllAsRead": "Marquer tous les messages comme lus", "Base_MailMessages_Subscribe": "S'abonner", "Base_MailMessages_Unsubscribe": "Se désabonner", - "Base_AttachedFiles": "Fichiers attachés", "Base_Question": "Question", "Base_Unfollow_Confirmation": "Êtes-vous sûr de vouloir vous désabonner de ce document?", "Base_NoConnection": "Pas de connexion Internet", @@ -208,10 +207,8 @@ "Base_Print": "Imprimer", "Base_PrintTemplate": "Modèle d'impression", "Base_NoRecordsFound": "Aucun enregistrement trouvé", - "Base_SliceAction_FetchAttachedFiles": "récupération des fichiers joints", "Base_SliceAction_FetchFilesDetails": "récupération des détails du fichier", "Base_SliceAction_FetchMetaModule": "récupération des modules", - "Base_SliceAction_CountAttachedFiles": "comptage des fichiers joints", "Base_SliceAction_FetchMailMessages": "récupération des mail messages", "Base_SliceAction_PostMailMessageComment": "ajout d'un mail message", "Base_SliceAction_FetchModelSubscribers": "récupération des abonnés du modèle", diff --git a/packages/core/src/navigator/drawer/Header.js b/packages/core/src/navigator/drawer/Header.js index 29c620402d..2a59cbf3cf 100644 --- a/packages/core/src/navigator/drawer/Header.js +++ b/packages/core/src/navigator/drawer/Header.js @@ -110,7 +110,6 @@ const Header = ({mainScreen, title, actionID = null, shadedHeader = true}) => { actions={options.actions} genericActions={genericHeaders} options={options.options} - attachedFileScreenTitle={options.attachedFileScreenTitle} disableMailMessages={options.disableMailMessages} disablePrint={options.disablePrint} barcodeFieldname={options.barcodeFieldname} diff --git a/packages/core/src/screens/AttachedFilesScreen.tsx b/packages/core/src/screens/AttachedFilesScreen.tsx deleted file mode 100644 index bd91d45294..0000000000 --- a/packages/core/src/screens/AttachedFilesScreen.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Axelor Business Solutions - * - * Copyright (C) 2024 Axelor (). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import {AttachedFilesView} from '../components'; - -const AttachedFilesScreen = ({route}) => { - const {files, model, modelId, screenTitle} = route.params; - const isStatic = files && files.length > 0; - - return ( - - ); -}; - -export default AttachedFilesScreen; diff --git a/packages/core/src/screens/index.js b/packages/core/src/screens/index.js index 2348c744fa..fe64c6bbdc 100644 --- a/packages/core/src/screens/index.js +++ b/packages/core/src/screens/index.js @@ -16,21 +16,12 @@ * along with this program. If not, see . */ -import AttachedFilesScreen from './AttachedFilesScreen'; import BarcodeDisplayScreen from './BarcodeDisplayScreen'; import JsonFieldScreen from './JsonFieldScreen'; import MailMessageScreen from './MailMessageScreen'; import ProcessListScreen from './ProcessListScreen'; export default { - AttachedFilesScreen: { - title: 'Base_AttachedFiles', - component: AttachedFilesScreen, - actionID: 'core_attachedFiles_details', - options: { - shadedHeader: false, - }, - }, MailMessageScreen: { title: 'Base_MailMessages', component: MailMessageScreen,